From 21203e393c36d9c079491fb0644b9bce32f71758 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sun, 28 Nov 2010 21:49:51 +0000 Subject: first minial version working git-svn-id: https://svn.spreadspace.org/tcpproxy/trunk@12 e61f0598-a718-4e21-a8f0-0aadfa62ad6b --- src/clients.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 15 deletions(-) (limited to 'src/clients.c') diff --git a/src/clients.c b/src/clients.c index a4b58b3..9e5c9fc 100644 --- a/src/clients.c +++ b/src/clients.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "clients.h" #include "tcp.h" @@ -47,7 +48,7 @@ void clients_delete_element(void* e) client_t* element = (client_t*)e; close(element->fd_[0]); -// close(element->fd_[1]); + close(element->fd_[1]); free(e); } @@ -74,14 +75,35 @@ int clients_add(clients_t* list, int fd, const tcp_endpoint_t* remote_end) return -2; } + element->write_buf_len_[0] = 0; + element->write_buf_len_[1] = 0; element->fd_[0] = fd; - element->fd_[1] = 0; -// TODO: open new socket -// element->fd_[1] = socket(...); + + element->fd_[1] = socket(remote_end->ss_family, SOCK_STREAM, 0); + if(element->fd_[1] < 0) { + log_printf(INFO, "Error on socket(): %s, not adding client %d", strerror(errno), element->fd_[0]); + close(element->fd_[0]); + free(element); + return -1; + } + + socklen_t socklen = sizeof(*remote_end); + if(remote_end->ss_family == AF_INET) + socklen = sizeof(struct sockaddr_in); + else if (remote_end->ss_family == AF_INET6) + socklen = sizeof(struct sockaddr_in6); + + if(connect(element->fd_[1], (struct sockaddr *)remote_end, socklen)==-1) { + log_printf(INFO, "Error on connect(): %s, not adding client %d", strerror(errno), element->fd_[0]); + close(element->fd_[0]); + close(element->fd_[1]); + free(element); + return -1; + } if(slist_add(list, element) == NULL) { close(element->fd_[0]); -// close(element->fd_[1]); + close(element->fd_[1]); free(element); return -2; } @@ -136,9 +158,9 @@ void clients_read_fds(clients_t* list, fd_set* set, int* max_fd) client_t* c = (client_t*)tmp->data_; if(c) { FD_SET(c->fd_[0], set); -// FD_SET(c->fd_[1], 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]; + *max_fd = *max_fd > c->fd_[1] ? *max_fd : c->fd_[1]; } tmp = tmp->next_; } @@ -149,7 +171,21 @@ void clients_write_fds(clients_t* list, fd_set* set, int* max_fd) if(!list) return; - // TODO: add all clients with pending data + slist_element_t* tmp = list->first_; + while(tmp) { + client_t* c = (client_t*)tmp->data_; + if(c) { + if(c->write_buf_len_[0]) { + FD_SET(c->fd_[0], set); + *max_fd = *max_fd > c->fd_[0] ? *max_fd : c->fd_[0]; + } + if(c->write_buf_len_[1]) { + FD_SET(c->fd_[1], set); + *max_fd = *max_fd > c->fd_[1] ? *max_fd : c->fd_[1]; + } + } + tmp = tmp->next_; + } } int clients_read(clients_t* list, fd_set* set) @@ -173,20 +209,18 @@ int clients_read(clients_t* list, fd_set* set) } else continue; - u_int8_t* buffer[1024]; - int len = recv(c->fd_[in], buffer, sizeof(buffer), 0); + // TODO: what when buffer is full? + int len = recv(c->fd_[in], &(c->write_buf_[out][c->write_buf_len_[out]]), BUFFER_LENGTH - c->write_buf_len_[out], 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]); + log_printf(INFO, "client %d closed connection, removing it", 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] - } + else + c->write_buf_len_[out] += len; } } @@ -195,5 +229,34 @@ int clients_read(clients_t* list, fd_set* set) int clients_write(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 i; + for(i=0; i<2; ++i) { + if(FD_ISSET(c->fd_[i], set)) { + int len = send(c->fd_[i], c->write_buf_[i], c->write_buf_len_[i], 0); + if(len < 0) { + log_printf(INFO, "Error on send(): %s, removing client %d", strerror(errno), c->fd_[0]); + slist_remove(list, c); + } + else { + if(c->write_buf_len_[i] > len) { + memmove(c->write_buf_[i], &c->write_buf_[i][len], c->write_buf_len_[i] - len); + c->write_buf_len_[i] -= len; + } + else + c->write_buf_len_[i] = 0; + } + } + } + } + } + return 0; } -- cgit v1.2.3