From 8a61f8075aeee4cbdc9fa9e56e4a28c47a3f5187 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sat, 16 Jan 2010 06:16:11 +0000 Subject: multi sockets work now --- src/uanytun.c | 21 +++++++++++++-------- src/udp.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- src/udp.h | 5 ++++- 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/src/uanytun.c b/src/uanytun.c index 0d1a137..5da3c21 100644 --- a/src/uanytun.c +++ b/src/uanytun.c @@ -140,7 +140,7 @@ int process_tun_data(tun_device_t* dev, udp_t* sock, options_t* opt, plain_packe return 0; } -int process_sock_data(tun_device_t* dev, udp_t* sock, options_t* opt, plain_packet_t* plain_packet, encrypted_packet_t* encrypted_packet, +int process_sock_data(tun_device_t* dev, int fd, udp_t* sock, options_t* opt, plain_packet_t* plain_packet, encrypted_packet_t* encrypted_packet, cipher_t* c, auth_algo_t* aa, key_derivation_t* kd, seq_win_t* seq_win) { plain_packet_set_payload_length(plain_packet, -1); @@ -148,7 +148,7 @@ int process_sock_data(tun_device_t* dev, udp_t* sock, options_t* opt, plain_pack udp_endpoint_t remote; memset(&remote, 0, sizeof(udp_endpoint_t)); - int len = udp_read(sock, encrypted_packet_get_packet(encrypted_packet), encrypted_packet_get_length(encrypted_packet), &remote); + int len = udp_read(sock, fd, encrypted_packet_get_packet(encrypted_packet), encrypted_packet_get_length(encrypted_packet), &remote); if(len == -1) { log_printf(ERROR, "error on receiving udp packet: %s", strerror(errno)); return 0; @@ -181,6 +181,7 @@ int process_sock_data(tun_device_t* dev, udp_t* sock, options_t* opt, plain_pack return -2; } + udp_set_active_sock(sock, fd); if(memcmp(&remote, &(sock->remote_end_), sizeof(remote))) { memcpy(&(sock->remote_end_), &remote, sizeof(remote)); sock->remote_end_set_ = 1; @@ -228,8 +229,8 @@ int main_loop(tun_device_t* dev, udp_t* sock, options_t* opt) FD_ZERO(&readfds); FD_SET(dev->fd_, &readfds); - FD_SET(sock->socks_->fd_, &readfds); - int nfds = dev->fd_ > sock->socks_->fd_ ? dev->fd_ : sock->socks_->fd_; + int nfds = udp_init_fd_set(sock, &readfds); + nfds = dev->fd_ > nfds ? dev->fd_ : nfds; int return_value = 0; int sig_fd = signal_init(); @@ -264,10 +265,14 @@ int main_loop(tun_device_t* dev, udp_t* sock, options_t* opt) break; } - if(FD_ISSET(sock->socks_->fd_, &readyfds)) { - return_value = process_sock_data(dev, sock, opt, &plain_packet, &encrypted_packet, &c, &aa, &kd, &seq_win); - if(return_value) - break; + udp_socket_t* s = sock->socks_; + while(s) { + if(FD_ISSET(s->fd_, &readyfds)) { + return_value = process_sock_data(dev, s->fd_, sock, opt, &plain_packet, &encrypted_packet, &c, &aa, &kd, &seq_win); + if(return_value) + break; + } + s = s->next_; } } diff --git a/src/udp.c b/src/udp.c index 425fe0f..aadf595 100644 --- a/src/udp.c +++ b/src/udp.c @@ -55,6 +55,7 @@ int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_ return -1; sock->socks_ = NULL; + sock->active_sock_ = NULL; memset(&(sock->remote_end_), 0, sizeof(sock->remote_end_)); sock->remote_end_set_ = 0; @@ -142,6 +143,20 @@ int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_ return 0; } +int udp_init_fd_set(udp_t* sock, fd_set* set) +{ + int max_fd = 0; + + udp_socket_t* s = sock->socks_; + while(s) { + FD_SET(s->fd_, set); + max_fd = s->fd_ > max_fd ? s->fd_ : max_fd; + s = s->next_; + } + + return max_fd; +} + int udp_set_remote(udp_t* sock, const char* remote_addr, const char* port, resolv_addr_type_t resolv_type) { if(!sock || !remote_addr || !port) @@ -170,11 +185,38 @@ int udp_set_remote(udp_t* sock, const char* remote_addr, const char* port, resol } memcpy(&(sock->remote_end_), res->ai_addr, res->ai_addrlen); sock->remote_end_set_ = 1; + + if(!sock->active_sock_) { + udp_socket_t* s = sock->socks_; + while(s) { + if((((struct sockaddr *)&s->local_end_)->sa_family) == res->ai_family) { + sock->active_sock_ = s; + break; + } + s = s->next_; + } + } + freeaddrinfo(res); return 0; } +void udp_set_active_sock(udp_t* sock, int fd) +{ + if(!sock || (sock->active_sock_ && sock->active_sock_->fd_ == fd)) + return; + + udp_socket_t* s = sock->socks_; + while(s) { + if(s->fd_ == fd) { + sock->active_sock_ = s; + return; + } + s = s->next_; + } +} + void udp_close(udp_t* sock) { if(!sock) @@ -235,27 +277,26 @@ char* udp_get_remote_end_string(udp_t* sock) return udp_endpoint_to_string(sock->remote_end_); } -int udp_read(udp_t* sock, u_int8_t* buf, u_int32_t len, udp_endpoint_t* remote_end) +int udp_read(udp_t* sock, int fd, u_int8_t* buf, u_int32_t len, udp_endpoint_t* remote_end) { if(!sock || !remote_end) return -1; socklen_t socklen = sizeof(*remote_end); - return recvfrom(sock->socks_->fd_, buf, len, 0, (struct sockaddr *)remote_end, &socklen); + return recvfrom(fd, buf, len, 0, (struct sockaddr *)remote_end, &socklen); } int udp_write(udp_t* sock, u_int8_t* buf, u_int32_t len) { - if(!sock || !sock->remote_end_set_) - return -1; + if(!sock || !sock->remote_end_set_ || !sock->active_sock_) + return 0; socklen_t socklen = sizeof(sock->remote_end_); -#ifdef NO_V4MAPPED - if((((struct sockaddr *)&sock->socks_->local_end_)->sa_family) == AF_INET) + if((((struct sockaddr *)&sock->active_sock_->local_end_)->sa_family) == AF_INET) socklen = sizeof(struct sockaddr_in); - else if ((((struct sockaddr *)&sock->socks_->local_end_)->sa_family) == AF_INET6) + else if ((((struct sockaddr *)&sock->active_sock_->local_end_)->sa_family) == AF_INET6) socklen = sizeof(struct sockaddr_in6); -#endif - return sendto(sock->socks_->fd_, buf, len, 0, (struct sockaddr *)&(sock->remote_end_), socklen);; + + return sendto(sock->active_sock_->fd_, buf, len, 0, (struct sockaddr *)&(sock->remote_end_), socklen); } diff --git a/src/udp.h b/src/udp.h index 5530d12..6abdca1 100644 --- a/src/udp.h +++ b/src/udp.h @@ -52,19 +52,22 @@ typedef struct udp_socket_struct udp_socket_t; struct udp_struct { udp_socket_t* socks_; + udp_socket_t* active_sock_; udp_endpoint_t remote_end_; int remote_end_set_; }; typedef struct udp_struct udp_t; int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_type_t resolv_type); +int udp_init_fd_set(udp_t* sock, fd_set* set); int udp_set_remote(udp_t* sock, const char* remote_addr, const char* port, resolv_addr_type_t resolv_type); +void udp_set_active_sock(udp_t* sock, int fd); void udp_close(udp_t* sock); char* udp_endpoint_to_string(udp_endpoint_t e); char* udp_get_remote_end_string(udp_t* sock); -int udp_read(udp_t* sock, u_int8_t* buf, u_int32_t len, udp_endpoint_t* remote_end); +int udp_read(udp_t* sock, int fd, u_int8_t* buf, u_int32_t len, udp_endpoint_t* remote_end); int udp_write(udp_t* sock, u_int8_t* buf, u_int32_t len); #endif -- cgit v1.2.3