From ce924463fef1159f0ed7f0077aea473f355584a0 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Mon, 29 Nov 2010 00:03:24 +0000 Subject: added length field to udp_endpoint_t replaced inet_ntop with getnameinfo at udp_endpoint_to_string --- src/uanytun.c | 7 ++++--- src/udp.c | 66 ++++++++++++++++++++++------------------------------------- src/udp.h | 5 ++++- 3 files changed, 32 insertions(+), 46 deletions(-) diff --git a/src/uanytun.c b/src/uanytun.c index 53acbaf..be67d77 100644 --- a/src/uanytun.c +++ b/src/uanytun.c @@ -147,7 +147,8 @@ int process_sock_data(tun_device_t* dev, int fd, udp_t* sock, options_t* opt, pl encrypted_packet_set_length(encrypted_packet, -1); udp_endpoint_t remote; - memset(&remote, 0, sizeof(udp_endpoint_t)); + memset(&(remote.addr_), 0, sizeof(remote.addr_)); + remote.len_ = sizeof(remote.addr_); 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)); @@ -182,8 +183,8 @@ int process_sock_data(tun_device_t* dev, int fd, udp_t* sock, options_t* opt, pl } udp_set_active_sock(sock, fd); - if(memcmp(&remote, &(sock->remote_end_), sizeof(remote))) { - memcpy(&(sock->remote_end_), &remote, sizeof(remote)); + if(remote.len_ != sock->remote_end_.len_ || memcmp(&(remote.addr_), &(sock->remote_end_.addr_), remote.len_)) { + memcpy(&(sock->remote_end_.addr_), &(remote.addr_), remote.len_); sock->remote_end_set_ = 1; char* addrstring = udp_endpoint_to_string(remote); log_printf(NOTICE, "autodetected remote host changed %s", addrstring); diff --git a/src/udp.c b/src/udp.c index 8d9bf52..e6865bd 100644 --- a/src/udp.c +++ b/src/udp.c @@ -56,7 +56,8 @@ int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_ sock->socks_ = NULL; sock->active_sock_ = NULL; - memset(&(sock->remote_end_), 0, sizeof(sock->remote_end_)); + memset(&(sock->remote_end_.addr_), 0, sizeof(sock->remote_end_.addr_)); + sock->remote_end_.len_ = sizeof(sock->remote_end_.addr_); sock->remote_end_set_ = 0; struct addrinfo hints, *res; @@ -94,7 +95,8 @@ int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_ udp_close(sock); return -2; } - memset(&(new_sock->local_end_), 0, sizeof(new_sock->local_end_)); + memset(&(new_sock->local_end_.addr_), 0, sizeof(new_sock->local_end_.addr_)); + new_sock->local_end_.len_ = sizeof(new_sock->local_end_.addr_); new_sock->next_ = NULL; if(!sock->socks_) { @@ -106,8 +108,9 @@ int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_ 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); + memcpy(&(new_sock->local_end_.addr_), r->ai_addr, r->ai_addrlen); + new_sock->local_end_.len_ = r->ai_addrlen; + new_sock->fd_ = socket(new_sock->local_end_.addr_.ss_family, SOCK_DGRAM, 0); if(new_sock->fd_ < 0) { log_printf(ERROR, "Error on opening udp socket: %s", strerror(errno)); freeaddrinfo(res); @@ -121,7 +124,7 @@ int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_ log_printf(ERROR, "Error on setting IPV6_V6ONLY socket option: %s", strerror(errno)); } - errcode = bind(new_sock->fd_, r->ai_addr, r->ai_addrlen); + errcode = bind(new_sock->fd_, (struct sockaddr*)&(new_sock->local_end_.addr_), new_sock->local_end_.len_); if(errcode) { log_printf(ERROR, "Error on binding udp socket: %s", strerror(errno)); freeaddrinfo(res); @@ -183,13 +186,14 @@ int udp_set_remote(udp_t* sock, const char* remote_addr, const char* port, resol log_printf(ERROR, "getaddrinfo returned no address for %s:%s", remote_addr, port); return -1; } - memcpy(&(sock->remote_end_), res->ai_addr, res->ai_addrlen); + memcpy(&(sock->remote_end_.addr_), res->ai_addr, res->ai_addrlen); + sock->remote_end_.len_ = 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) { + if(s->local_end_.addr_.ss_family == res->ai_family) { sock->active_sock_ = s; break; } @@ -236,36 +240,21 @@ void udp_close(udp_t* sock) char* udp_endpoint_to_string(udp_endpoint_t e) { - void* ptr; - u_int16_t port; size_t addrstr_len = 0; - char* addrstr, *ret; + char addrstr[INET6_ADDRSTRLEN + 1], portstr[6], *ret; char addrport_sep = ':'; - - switch (((struct sockaddr *)&e)->sa_family) + + switch(e.addr_.ss_family) { - case AF_INET: - ptr = &((struct sockaddr_in *)&e)->sin_addr; - port = ntohs(((struct sockaddr_in *)&e)->sin_port); - addrstr_len = INET_ADDRSTRLEN + 1; - addrport_sep = ':'; - break; - case AF_INET6: - ptr = &((struct sockaddr_in6 *)&e)->sin6_addr; - port = ntohs(((struct sockaddr_in6 *)&e)->sin6_port); - addrstr_len = INET6_ADDRSTRLEN + 1; - addrport_sep = '.'; - break; - default: - asprintf(&ret, "unknown address type"); - return ret; + case AF_INET: addrport_sep = ':'; break; + case AF_INET6: addrport_sep = '.'; break; + case AF_UNSPEC: return NULL; + default: asprintf(&ret, "unknown address type"); return ret; } - addrstr = malloc(addrstr_len); - if(!addrstr) - return NULL; - inet_ntop (((struct sockaddr *)&e)->sa_family, ptr, addrstr, addrstr_len); - asprintf(&ret, "%s%c%d", addrstr, addrport_sep ,port); - free(addrstr); + + int errcode = getnameinfo((struct sockaddr *)&(e.addr_), e.len_, addrstr, sizeof(addrstr), portstr, sizeof(portstr), NI_NUMERICHOST | NI_NUMERICSERV); + if (errcode != 0) return NULL; + asprintf(&ret, "%s%c%s", addrstr, addrport_sep ,portstr); return ret; } @@ -282,8 +271,7 @@ int udp_read(udp_t* sock, int fd, u_int8_t* buf, u_int32_t len, udp_endpoint_t* if(!sock || !remote_end) return -1; - socklen_t socklen = sizeof(*remote_end); - return recvfrom(fd, buf, len, 0, (struct sockaddr *)remote_end, &socklen); + return recvfrom(fd, buf, len, 0, (struct sockaddr *)&(remote_end->addr_), &(remote_end->len_)); } int udp_write(udp_t* sock, u_int8_t* buf, u_int32_t len) @@ -291,12 +279,6 @@ int udp_write(udp_t* sock, u_int8_t* buf, u_int32_t len) if(!sock || !sock->remote_end_set_ || !sock->active_sock_) return 0; - socklen_t socklen = sizeof(sock->remote_end_); - if((((struct sockaddr *)&sock->active_sock_->local_end_)->sa_family) == AF_INET) - socklen = sizeof(struct sockaddr_in); - else if ((((struct sockaddr *)&sock->active_sock_->local_end_)->sa_family) == AF_INET6) - socklen = sizeof(struct sockaddr_in6); - - return sendto(sock->active_sock_->fd_, buf, len, 0, (struct sockaddr *)&(sock->remote_end_), socklen); + return sendto(sock->active_sock_->fd_, buf, len, 0, (struct sockaddr *)&(sock->remote_end_.addr_), sock->remote_end_.len_); } diff --git a/src/udp.h b/src/udp.h index edf0160..4c5fdc8 100644 --- a/src/udp.h +++ b/src/udp.h @@ -41,7 +41,10 @@ #include #include -typedef struct sockaddr_storage udp_endpoint_t; +typedef struct { + socklen_t len_; + struct sockaddr_storage addr_; +} udp_endpoint_t; struct udp_socket_struct { int fd_; -- cgit v1.2.3