summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2010-11-27 06:50:41 +0000
committerChristian Pointner <equinox@spreadspace.org>2010-11-27 06:50:41 +0000
commitdcf62b0ecc7c3459badd4a67c85d328220a95d31 (patch)
tree6456dfe8b93fa2dfb4631191519c510c5b3975af
parentadded 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.c112
-rw-r--r--src/clients.h7
-rw-r--r--src/listener.c7
-rw-r--r--src/listener.h3
-rw-r--r--src/tcpproxy.c13
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;
}