From b107b10c4ef70bdf74d6d6ac57ff5ab2698b9cb2 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Fri, 14 Jan 2011 16:00:22 +0100 Subject: [PATCH] Use threads for UDP sockets. --- src/net.h | 4 +++- src/net_packet.c | 51 ++++++++++++++++++++++++++---------------------- src/net_setup.c | 9 +++------ src/net_socket.c | 22 --------------------- src/threads.h | 9 ++------- 5 files changed, 36 insertions(+), 59 deletions(-) diff --git a/src/net.h b/src/net.h index 9b625a0..a6d5cb9 100644 --- a/src/net.h +++ b/src/net.h @@ -24,6 +24,7 @@ #include "ipv6.h" #include "cipher.h" #include "digest.h" +#include "threads.h" #ifdef ENABLE_JUMBOGRAMS #define MTU 9018 /* 9000 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ @@ -88,6 +89,7 @@ typedef struct listen_socket_t { struct event ev_udp; int tcp; int udp; + thread_t udp_thread; sockaddr_t sa; } listen_socket_t; @@ -125,7 +127,7 @@ extern int contradicting_del_edge; #include "node.h" extern void retry_outgoing(outgoing_t *); -extern void handle_incoming_vpn_data(int, short, void *); +extern void handle_incoming_vpn_data(void *); extern void finish_connecting(struct connection_t *); extern void do_outgoing_connection(struct connection_t *); extern void handle_new_meta_connection(int, short, void *); diff --git a/src/net_packet.c b/src/net_packet.c index 7be4662..61a9f48 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -576,7 +576,8 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { return found; } -void handle_incoming_vpn_data(int sock, short events, void *data) { +void handle_incoming_vpn_data(void *arg) { + listen_socket_t *l = arg; vpn_packet_t pkt; char *hostname; sockaddr_t from; @@ -584,35 +585,39 @@ void handle_incoming_vpn_data(int sock, short events, void *data) { node_t *n; int len; - len = recvfrom(sock, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen); + while(true) { + len = recvfrom(l->udp, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen); - if(len <= 0 || len > MAXSIZE) { - if(!sockwouldblock(sockerrno)) - logger(LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); - return; - } + if(len <= 0 || len > MAXSIZE) { + if(!sockwouldblock(sockerrno)) { + logger(LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno)); + return; + } + continue; + } - pkt.len = len; + pkt.len = len; - sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */ + sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */ - n = lookup_node_udp(&from); + n = lookup_node_udp(&from); - if(!n) { - n = try_harder(&from, &pkt); - if(n) - update_node_udp(n, &from); - else ifdebug(PROTOCOL) { - hostname = sockaddr2hostname(&from); - logger(LOG_WARNING, "Received UDP packet from unknown source %s", hostname); - free(hostname); - return; + if(!n) { + n = try_harder(&from, &pkt); + if(n) + update_node_udp(n, &from); + else ifdebug(PROTOCOL) { + hostname = sockaddr2hostname(&from); + logger(LOG_WARNING, "Received UDP packet from unknown source %s", hostname); + free(hostname); + continue; + } + else + continue; } - else - return; - } - receive_udppacket(n, &pkt); + receive_udppacket(n, &pkt); + } } void handle_device_data(int sock, short events, void *data) { diff --git a/src/net_setup.c b/src/net_setup.c index b31bed7..dc1d665 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -529,12 +529,8 @@ bool setup_myself(void) { abort(); } - event_set(&listen_socket[listen_sockets].ev_udp, - listen_socket[listen_sockets].udp, - EV_READ|EV_PERSIST, - handle_incoming_vpn_data, NULL); - if(event_add(&listen_socket[listen_sockets].ev_udp, NULL) < 0) { - logger(LOG_ERR, "event_add failed: %s", strerror(errno)); + if(!thread_create(&listen_socket[listen_sockets].udp_thread, handle_incoming_vpn_data, &listen_socket[listen_sockets])) { + logger(LOG_ERR, "thread_create failed: %s", strerror(errno)); abort(); } @@ -625,6 +621,7 @@ void close_network_connections(void) { event_del(&listen_socket[i].ev_udp); close(listen_socket[i].tcp); close(listen_socket[i].udp); + thread_destroy(&listen_socket[i].udp_thread); } xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); diff --git a/src/net_socket.c b/src/net_socket.c index e20076f..7c4463e 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -237,28 +237,6 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { return -1; } -#ifdef O_NONBLOCK - { - int flags = fcntl(nfd, F_GETFL); - - if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) { - closesocket(nfd); - logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", - strerror(errno)); - return -1; - } - } -#elif defined(WIN32) - { - unsigned long arg = 1; - if(ioctlsocket(nfd, FIONBIO, &arg) != 0) { - closesocket(nfd); - logger(LOG_ERR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno)); - return -1; - } - } -#endif - option = 1; setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof option); diff --git a/src/threads.h b/src/threads.h index 3243907..d2ef4a6 100644 --- a/src/threads.h +++ b/src/threads.h @@ -1,11 +1,6 @@ #ifndef __THREADS_H__ #define __THREADS_H__ -typedef struct event { - int foo; -} event_t; - - #ifdef HAVE_MINGW typedef HANDLE thread_t; typedef CRITICAL_SECTION mutex_t; @@ -33,11 +28,11 @@ static inline void mutex_unlock(mutex_t *mutex) { typedef pthread_t thread_t; typedef pthread_mutex_t mutex_t; -static inline void thread_create(thread_t *tid, void (*func)(void *), void *arg) { +static inline bool thread_create(thread_t *tid, void (*func)(void *), void *arg) { return !pthread_create(tid, NULL, (void *(*)(void *))func, arg); } static inline void thread_destroy(thread_t *tid) { - pthread_join(tid); + pthread_join(*tid, NULL); } static inline void mutex_create(mutex_t *mutex) { pthread_mutex_init(mutex, NULL); -- 2.25.1