From ec68257329262971a025c49942570f5e33babfba Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sat, 16 Jan 2010 04:33:53 +0000 Subject: listening on multiple sockets now --- src/uanytun.c | 6 ---- src/udp.c | 110 +++++++++++++++++++++++++++++++++------------------------- src/udp.h | 1 - 3 files changed, 62 insertions(+), 55 deletions(-) diff --git a/src/uanytun.c b/src/uanytun.c index 81d3724..0d1a137 100644 --- a/src/uanytun.c +++ b/src/uanytun.c @@ -379,12 +379,6 @@ int main(int argc, char* argv[]) log_close(); exit(ret); } - char* local_string = udp_get_local_end_string(&sock); - if(local_string) { - log_printf(NOTICE, "listening on: %s", local_string); - free(local_string); - } - if(opt.remote_addr_) { if(!udp_set_remote(&sock, opt.remote_addr_, opt.remote_port_, opt.resolv_addr_type_)) { diff --git a/src/udp.c b/src/udp.c index 5e436dc..425fe0f 100644 --- a/src/udp.c +++ b/src/udp.c @@ -54,16 +54,7 @@ int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_ if(!sock || !port) return -1; - sock->socks_ = malloc(sizeof(udp_socket_t)); - if(!sock->socks_) { - log_printf(ERROR, "memory error at udp_init"); - return -2; - } - - sock->socks_->next_ = NULL; - sock->socks_->fd_ = 0; - memset(&(sock->socks_->local_end_), 0, sizeof(sock->socks_->local_end_)); - + sock->socks_ = NULL; memset(&(sock->remote_end_), 0, sizeof(sock->remote_end_)); sock->remote_end_set_ = 0; @@ -86,40 +77,66 @@ int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_ udp_close(sock); return -1; } - if(!res) { udp_close(sock); log_printf(ERROR, "getaddrinfo returned no address for %s:%s", local_addr, port); return -1; } - memcpy(&(sock->socks_->local_end_), res->ai_addr, res->ai_addrlen); + struct addrinfo* r = res; + udp_socket_t* prev_sock = NULL; + while(r) { + udp_socket_t* new_sock = malloc(sizeof(udp_socket_t)); + if(!new_sock) { + log_printf(ERROR, "memory error at udp_init"); + freeaddrinfo(res); + udp_close(sock); + return -2; + } + memset(&(new_sock->local_end_), 0, sizeof(new_sock->local_end_)); + new_sock->next_ = NULL; + + if(!sock->socks_) { + sock->socks_ = new_sock; + prev_sock = new_sock; + } + else { + prev_sock->next_ = new_sock; + prev_sock = new_sock; + } + + memcpy(&(new_sock->local_end_), r->ai_addr, r->ai_addrlen); + new_sock->fd_ = socket(r->ai_family, SOCK_DGRAM, 0); + if(new_sock->fd_ < 0) { + log_printf(ERROR, "Error on opening udp socket: %s", strerror(errno)); + freeaddrinfo(res); + udp_close(sock); + return -1; + } + + if(r->ai_family == AF_INET6) { + int on = 1; + if(setsockopt(new_sock->fd_, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on))) + log_printf(ERROR, "Error on setting IPV6_V6ONLY socket option: %s", strerror(errno)); + } + + errcode = bind(new_sock->fd_, r->ai_addr, r->ai_addrlen); + if(errcode) { + log_printf(ERROR, "Error on binding udp socket: %s", strerror(errno)); + freeaddrinfo(res); + udp_close(sock); + return -1; + } + + char* local_string = udp_endpoint_to_string(new_sock->local_end_); + if(local_string) { + log_printf(NOTICE, "listening on: %s", local_string); + free(local_string); + } - sock->socks_->fd_ = socket(res->ai_family, SOCK_DGRAM, 0); - if(sock->socks_->fd_ < 0) { - log_printf(ERROR, "Error on opening udp socket: %s", strerror(errno)); - freeaddrinfo(res); - udp_close(sock); - return -1; + r = r->ai_next; } - errcode = bind(sock->socks_->fd_, res->ai_addr, res->ai_addrlen); - if(errcode) { - log_printf(ERROR, "Error on binding udp socket: %s", strerror(errno)); - freeaddrinfo(res); - udp_close(sock); - return -1; - } - -/* this doesn't work on linux ?? */ -/* #ifdef NO_V4MAPPED */ -/* if(res->ai_family == AF_INET6) { */ -/* log_printf(NOTICE, "disabling V4-Mapped addresses"); */ -/* int on = 1; */ -/* if(setsockopt(sock->fd_, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on))) */ -/* log_printf(ERROR, "Error on setting IPV6_V6ONLY socket option: %s", strerror(errno)); */ -/* } */ -/* #endif */ freeaddrinfo(res); return 0; @@ -163,11 +180,16 @@ void udp_close(udp_t* sock) if(!sock) return; - if(sock->socks_->fd_ > 0) - close(sock->socks_->fd_); - - if(sock->socks_) - free(sock->socks_); + while(sock->socks_) { + if(sock->socks_->fd_ > 0) + close(sock->socks_->fd_); + + udp_socket_t*s = sock->socks_; + sock->socks_ = sock->socks_->next_; + + free(s); + } + sock->socks_ = NULL; } char* udp_endpoint_to_string(udp_endpoint_t e) @@ -205,14 +227,6 @@ char* udp_endpoint_to_string(udp_endpoint_t e) return ret; } -char* udp_get_local_end_string(udp_t* sock) -{ - if(!sock) - return NULL; - - return udp_endpoint_to_string(sock->socks_->local_end_); -} - char* udp_get_remote_end_string(udp_t* sock) { if(!sock || !sock->remote_end_set_) diff --git a/src/udp.h b/src/udp.h index e74e2cd..5530d12 100644 --- a/src/udp.h +++ b/src/udp.h @@ -62,7 +62,6 @@ int udp_set_remote(udp_t* sock, const char* remote_addr, const char* port, resol void udp_close(udp_t* sock); char* udp_endpoint_to_string(udp_endpoint_t e); -char* udp_get_local_end_string(udp_t* sock); 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); -- cgit v1.2.3