diff options
author | Christian Pointner <equinox@spreadspace.org> | 2010-11-27 06:50:41 +0000 |
---|---|---|
committer | Christian Pointner <equinox@spreadspace.org> | 2010-11-27 06:50:41 +0000 |
commit | dcf62b0ecc7c3459badd4a67c85d328220a95d31 (patch) | |
tree | 6456dfe8b93fa2dfb4631191519c510c5b3975af | |
parent | added initial (not working) version of client list (diff) |
one side of cleint connections works for recv
git-svn-id: https://svn.spreadspace.org/tcpproxy/trunk@11 e61f0598-a718-4e21-a8f0-0aadfa62ad6b
-rw-r--r-- | src/clients.c | 112 | ||||
-rw-r--r-- | src/clients.h | 7 | ||||
-rw-r--r-- | src/listener.c | 7 | ||||
-rw-r--r-- | src/listener.h | 3 | ||||
-rw-r--r-- | src/tcpproxy.c | 13 |
5 files changed, 103 insertions, 39 deletions
diff --git a/src/clients.c b/src/clients.c index ab82e28..a4b58b3 100644 --- a/src/clients.c +++ b/src/clients.c @@ -32,12 +32,9 @@ #include <unistd.h> #include <string.h> #include <stdio.h> -/* #include <netdb.h> */ -/* #include <sys/types.h> */ -/* #include <sys/socket.h> */ -/* #include <arpa/inet.h> */ -/* #include <netinet/in.h> */ -/* #include <sys/select.h> */ +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/select.h> #include "clients.h" #include "tcp.h" @@ -49,7 +46,8 @@ void clients_delete_element(void* e) return; client_t* element = (client_t*)e; - close(element->fd_); + close(element->fd_[0]); +// close(element->fd_[1]); free(e); } @@ -64,16 +62,31 @@ void clients_clear(clients_t* list) slist_clear(list); } -int clients_add(clients_t* list, int fd, tcp_endpoint_t remote_end) +int clients_add(clients_t* list, int fd, const tcp_endpoint_t* remote_end) { + if(!list) return -1; - int ret = 0; + client_t* element = malloc(sizeof(client_t)); + if(!element) { + close(fd); + return -2; + } -// TODO: connect to remote end and setup write buffers + element->fd_[0] = fd; + element->fd_[1] = 0; +// TODO: open new socket +// element->fd_[1] = socket(...); - return ret; + if(slist_add(list, element) == NULL) { + close(element->fd_[0]); +// close(element->fd_[1]); + free(element); + return -2; + } + + return 0; } void clients_remove(clients_t* list, int fd) @@ -88,9 +101,9 @@ client_t* clients_find(clients_t* list, int fd) slist_element_t* tmp = list->first_; while(tmp) { - client_t* l = (client_t*)tmp->data_; - if(l && l->fd_ == fd) - return l; + client_t* c = (client_t*)tmp->data_; + if(c && (c->fd_[0] == fd || c->fd_[1] == fd)) + return c; tmp = tmp->next_; } @@ -104,10 +117,10 @@ void clients_print(clients_t* list) slist_element_t* tmp = list->first_; while(tmp) { - client_t* l = (client_t*)tmp->data_; - if(l) { + client_t* c = (client_t*)tmp->data_; + if(c) { // print useful info - printf("clients #%d: tba...\n", l->fd_); + printf("client %d <-> %d: tba...\n", c->fd_[0], c->fd_[1]); } tmp = tmp->next_; } @@ -120,10 +133,12 @@ void clients_read_fds(clients_t* list, fd_set* set, int* max_fd) slist_element_t* tmp = list->first_; while(tmp) { - client_t* l = (client_t*)tmp->data_; - if(l) { - FD_SET(l->fd_, set); - *max_fd = *max_fd > l->fd_ ? *max_fd : l->fd_; + client_t* c = (client_t*)tmp->data_; + if(c) { + FD_SET(c->fd_[0], set); +// FD_SET(c->fd_[1], set); + *max_fd = *max_fd > c->fd_[0] ? *max_fd : c->fd_[0]; +// *max_fd = *max_fd > c->fd_[1] ? *max_fd : c->fd_[1]; } tmp = tmp->next_; } @@ -135,13 +150,50 @@ void clients_write_fds(clients_t* list, fd_set* set, int* max_fd) return; // TODO: add all clients with pending data -/* slist_element_t* tmp = list->first_; */ -/* while(tmp) { */ -/* client_t* l = (client_t*)tmp->data_; */ -/* if(l) { */ -/* FD_SET(l->fd_, set); */ -/* *max_fd = *max_fd > l->fd_ ? *max_fd : l->fd_; */ -/* } */ -/* tmp = tmp->next_; */ -/* } */ +} + +int clients_read(clients_t* list, fd_set* set) +{ + if(!list) + return -1; + + slist_element_t* tmp = list->first_; + while(tmp) { + client_t* c = (client_t*)tmp->data_; + tmp = tmp->next_; + if(c) { + int in, out; + if(FD_ISSET(c->fd_[0], set)) { + in = 0; + out = 1; + } + else if(FD_ISSET(c->fd_[1], set)) { + in = 1; + out = 0; + } + else continue; + + u_int8_t* buffer[1024]; + int len = recv(c->fd_[in], buffer, sizeof(buffer), 0); + if(len < 0) { + log_printf(INFO, "Error on recv(): %s, removing client %d", strerror(errno), c->fd_[0]); + slist_remove(list, c); + } + else if(!len) { + log_printf(INFO, "client %d closed connection", c->fd_[0]); + slist_remove(list, c); + } + else { + log_printf(INFO, "client %d: read %d bytes", c->fd_[0], len); + // TODO: add data to write buffer of l->fd_[out] + } + } + } + + return 0; +} + +int clients_write(clients_t* list, fd_set* set) +{ + return 0; } diff --git a/src/clients.h b/src/clients.h index ced5f16..9ab8f0c 100644 --- a/src/clients.h +++ b/src/clients.h @@ -34,7 +34,7 @@ #include "tcp.h" typedef struct { - int fd_; + int fd_[2]; // TODO: add info for each client and write buffers } client_t; @@ -44,7 +44,7 @@ typedef slist_t clients_t; int clients_init(clients_t* list); void clients_clear(clients_t* list); -int clients_add(clients_t* list, int fd, tcp_endpoint_t remote_end); +int clients_add(clients_t* list, int fd, const tcp_endpoint_t* remote_end); void clients_remove(clients_t* list, int fd); client_t* clients_find(clients_t* list, int fd); void clients_print(clients_t* list); @@ -52,4 +52,7 @@ void clients_print(clients_t* list); void clients_read_fds(clients_t* list, fd_set* set, int* max_fd); void clients_write_fds(clients_t* list, fd_set* set, int* max_fd); +int clients_read(clients_t* list, fd_set* set); +int clients_write(clients_t* list, fd_set* set); + #endif diff --git a/src/listener.c b/src/listener.c index 0f92990..e649bf8 100644 --- a/src/listener.c +++ b/src/listener.c @@ -43,6 +43,8 @@ #include "tcp.h" #include "log.h" +#include "clients.h" + void listener_delete_element(void* e) { if(!e) @@ -208,7 +210,7 @@ void listener_read_fds(listeners_t* list, fd_set* set, int* max_fd) } } -int listener_handle_accept(listeners_t* list, fd_set* set) +int listener_handle_accept(listeners_t* list, clients_t* clients, fd_set* set) { if(!list) return -1; @@ -229,8 +231,7 @@ int listener_handle_accept(listeners_t* list, fd_set* set) if(rs) free(rs); FD_CLR(l->fd_, set); - // TODO add client to client list - close(new_client); + clients_add(clients, new_client, &(l->remote_end_)); } tmp = tmp->next_; } diff --git a/src/listener.h b/src/listener.h index 475af83..8e87e96 100644 --- a/src/listener.h +++ b/src/listener.h @@ -32,6 +32,7 @@ #include "slist.h" #include "tcp.h" +#include "clients.h" typedef struct { int fd_; @@ -51,6 +52,6 @@ listener_t* listener_find(listeners_t* list, int fd); void listener_print(listeners_t* list); void listener_read_fds(listeners_t* list, fd_set* set, int* max_fd); -int listener_handle_accept(listeners_t* list, fd_set* set); +int listener_handle_accept(listeners_t* list, clients_t* clients, fd_set* set); #endif diff --git a/src/tcpproxy.c b/src/tcpproxy.c index d82b057..fce2e2c 100644 --- a/src/tcpproxy.c +++ b/src/tcpproxy.c @@ -38,15 +38,18 @@ #include "daemon.h" #include "listener.h" +#include "clients.h" int main_loop(options_t* opt, listeners_t* listeners) { log_printf(INFO, "entering main loop"); - int return_value = 0; int sig_fd = signal_init(); if(sig_fd < 0) - return_value -1; + return -1; + + clients_t clients; + int return_value = clients_init(&clients); while(!return_value) { fd_set readfds; @@ -54,6 +57,7 @@ int main_loop(options_t* opt, listeners_t* listeners) FD_SET(sig_fd, &readfds); int nfds = sig_fd; listener_read_fds(listeners, &readfds, &nfds); + clients_read_fds(&clients, &readfds, &nfds); int ret = select(nfds + 1, &readfds, NULL, NULL, NULL); if(ret == -1 && errno != EINTR) { log_printf(ERROR, "select returned with error: %s", strerror(errno)); @@ -70,10 +74,13 @@ int main_loop(options_t* opt, listeners_t* listeners) } } - return_value = listener_handle_accept(listeners, &readfds); + return_value = listener_handle_accept(listeners, &clients, &readfds); if(return_value) break; + + return_value = clients_read(&clients, &readfds); } + clients_clear(&clients); signal_stop(); return return_value; } |