From 3a35cf50ce106490470580dcdfc1a85766efe1f5 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Fri, 1 Aug 2014 10:56:45 +0100 Subject: [PATCH] IPv6 support --- include/tr/remote_data.h | 8 ++--- include/tr/socket.h | 68 +++++++++++++++++++++++++++++--------- src/remote_data.c | 9 +++-- src/remote_data_set_data.c | 5 ++- src/socket.c | 18 ++++++---- src/socket_accept.c | 6 ++-- src/socket_init.c | 11 ++++-- src/tcp_socket.c | 1 + src/udp_socket.c | 5 +-- 9 files changed, 92 insertions(+), 39 deletions(-) diff --git a/include/tr/remote_data.h b/include/tr/remote_data.h index 9576f44..bf26c86 100644 --- a/include/tr/remote_data.h +++ b/include/tr/remote_data.h @@ -30,12 +30,12 @@ #include #include "trbase.h" +#include "tr/socket.h" TR_CLASS(TR_RemoteData) { - unsigned char * data; - size_t ndata; - struct sockaddr_in addr; // for now... should be more generic - socklen_t addrlen; + unsigned char * data; + size_t ndata; + TR_Socket socket; }; TR_INSTANCE_INIT(TR_RemoteData); diff --git a/include/tr/socket.h b/include/tr/socket.h index 1079fd7..af12cc6 100644 --- a/include/tr/socket.h +++ b/include/tr/socket.h @@ -34,7 +34,7 @@ //#include // for in_port_t #include "trbase.h" -#include "tr/interface/socket.h" +//#include "tr/interface/socket.h" #include "tr/logger.h" typedef enum TR_e_socket_fin { @@ -44,18 +44,25 @@ typedef enum TR_e_socket_fin { TR_FIN_RDWR = 3 } TR_SocketFin; +#define TR_MAX_HOST 256 +#define TR_MAX_CNAME 512 + TR_CLASS(TR_Socket) { - TR_Logger log; - int flags; - int type; - char * host; - char * cname; - int port; - time_t ttl; - struct sockaddr_in addr; // for now... should be more generic. - socklen_t addrlen; - int handle; - TR_SocketFin fin_state; + TR_Logger log; + int flags; + int type; + char host[TR_MAX_HOST]; + char cname[TR_MAX_CNAME]; + int port; + time_t ttl; + union { + struct sockaddr info; + struct sockaddr_in in; + struct sockaddr_in6 in6; + } addr; + socklen_t addrlen; + int handle; + TR_SocketFin fin_state; }; TR_INSTANCE_INIT(TR_Socket); @@ -67,7 +74,14 @@ TR_INSTANCE_INIT(TR_Socket); #define TR_socketPort(socket) (((TR_Socket)(socket))->port) #define TR_socketCname(socket) (((TR_Socket)(socket))->cname) #define TR_socketTtl(socket) (((TR_Socket)(socket))->ttl) -#define TR_socketAddr(socket) (((TR_Socket)(socket))->addr) + +#define TR_socketAddr(socket) \ + (((TR_Socket)(socket))->addr.info.sa_family == AF_INET \ + ? ((TR_Socket)(socket))->addr.in \ + : ((TR_Socket)(socket))->addr.info.sa_family == AF_INET6 \ + ? ((TR_Socket)(socket))->addr.in6 \ + : NULL) + #define TR_socketAddrlen(socket) (((TR_Socket)(socket))->addrlen) #define TR_socketHandle(socket) (((TR_Socket)(socket))->handle) #define TR_socketFinState(socket) (((TR_Socket)(socket))->fin_state) @@ -75,8 +89,32 @@ TR_INSTANCE_INIT(TR_Socket); #define TR_socketFinWr(socket) ((TR_socketFinState((socket)) & 2) == 2) #define TR_socketFinRdWr(socket) ((TR_socketFinState((socket)) & 3) == 3) -#define TR_socketGetIp(socket) (TR_socketAddr(socket).sin_addr.s_addr) -#define TR_socketGetIpStr(socket) (inet_ntoa(TR_socketGetIp(socket))) +#define TR_socketAddrPort(socket) \ + (((TR_Socket)(socket))->addr.info.sa_family == AF_INET \ + ? ((TR_Socket)(socket))->addr.in.sin_port \ + : ((TR_Socket)(socket))->addr.info.sa_family == AF_INET6 \ + ? ((TR_Socket)(socket))->addr.in6.sin6_port \ + : -1) + +#define TR_socketAddrIp(socket) \ + (((TR_Socket)(socket))->addr.info.sa_family == AF_INET \ + ? ((TR_Socket)(socket))->addr.in.sin_addr.s_addr \ + : ((TR_Socket)(socket))->addr.info.sa_family == AF_INET6 \ + ? ((TR_Socket)(socket))->addr.in6.sin6_addr.s6_addr \ + : NULL) + +#define TR_socketAddrIpStr(socket, buffer, nbuffer) \ + (((TR_Socket)(socket))->addr.info.sa_family == AF_INET \ + ? inet_ntop( \ + ((TR_Socket)(socket))->addr.info.sa_family, \ + &((TR_Socket)(socket))->addr.in.sin_addr.s_addr, \ + buffer, nbuffer) \ + : ((TR_Socket)(socket))->addr.info.sa_family == AF_INET6 \ + ? inet_ntop( \ + ((TR_Socket)(socket))->addr.info.sa_family, \ + ((TR_Socket)(socket))->addr.in6.sin6_addr.s6_addr, \ + buffer, nbuffer) \ + : NULL) TR_CLASS(TR_TcpSocket) { TR_EXTENDS(TR_Socket); diff --git a/src/remote_data.c b/src/remote_data.c index f7fa475..dcb0661 100644 --- a/src/remote_data.c +++ b/src/remote_data.c @@ -30,18 +30,17 @@ #include #include -#include "tr/remote_data.h" #include "trbase.h" +#include "tr/remote_data.h" +#include "tr/socket.h" static int remoteDataCtor(void * _this, va_list * params) { - TR_RemoteData this = _this; - struct sockaddr * addr_ptr = va_arg(*params, struct sockaddr *); + TR_RemoteData this = _this; - this->addrlen = va_arg(*params, socklen_t); - memcpy(&(this->addr), addr_ptr, this->addrlen); + this->socket = va_arg(*params, TR_Socket); this->data = NULL; this->ndata = 0; diff --git a/src/remote_data_set_data.c b/src/remote_data_set_data.c index d2862e0..cc9cfdb 100644 --- a/src/remote_data_set_data.c +++ b/src/remote_data_set_data.c @@ -35,7 +35,10 @@ TR_remoteDataSetData(TR_RemoteData this, unsigned char * data, size_t size) TR_MEM_FREE(this->data); } - this->data = TR_malloc(size); + if (! this->data) { + this->data = TR_malloc(size); + } + this->ndata = size; memcpy(this->data, data, size); } diff --git a/src/socket.c b/src/socket.c index aa3796e..2bf1db7 100644 --- a/src/socket.c +++ b/src/socket.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,7 @@ #include "tr/remote_data.h" #include "tr/socket.h" +#include "tr/interface/socket.h" #include "tr/logger.h" #include "trbase.h" @@ -39,16 +41,21 @@ static int socketCtor(void * _this, va_list * params) { - TR_Socket this = _this; + TR_Socket this = _this; + char * host; - this->type = 0; + this->type = AF_UNSPEC; this->handle = -1; this->log = va_arg(*params, TR_Logger); - this->host = TR_strdup(va_arg(*params, char*)); + host = va_arg(*params, char*); this->port = va_arg(*params, int); this->flags = va_arg(*params, int); this->fin_state = TR_FIN_RDWR; + if (host) { + strncpy(this->host, host, TR_MAX_HOST); + } + return 0; } @@ -58,9 +65,6 @@ socketDtor(void * _this) { TR_Socket this = _this; - TR_MEM_FREE(this->host); - TR_MEM_FREE(this->cname); - if (STDERR_FILENO < this->handle) { TR_socketClose(this); } @@ -73,7 +77,7 @@ socketBind(void * _this) TR_Socket this = _this; int state; - state = bind(this->handle, (struct sockaddr *)&(this->addr), this->addrlen); + state = bind(this->handle, &(this->addr.info), this->addrlen); if (-1 == state) { perror("bind"); diff --git a/src/socket_accept.c b/src/socket_accept.c index 2582128..6f2d747 100644 --- a/src/socket_accept.c +++ b/src/socket_accept.c @@ -46,7 +46,7 @@ TR_socketAccept(TR_TcpSocket this) remote->addrlen = ((TR_Socket)this)->addrlen; remote->handle = accept( TR_socketHandle(this), - (struct sockaddr *)&(remote->addr), + &(remote->addr.info), &(remote->addrlen)); //flags = fcntl(remote->handle, F_GETFL, 0); @@ -56,8 +56,8 @@ TR_socketAccept(TR_TcpSocket this) perror("accept"); TR_delete(remote); } else { - remote->host = TR_strdup(inet_ntoa(remote->addr.sin_addr)); - remote->port = ntohs(remote->addr.sin_port); + TR_socketAddrIpStr(remote, remote->host, TR_MAX_HOST); + remote->port = TR_socketAddrPort(remote); remote->type = TR_socketType(this); remote->flags = TR_socketFlags(this); } diff --git a/src/socket_init.c b/src/socket_init.c index 5400084..dca23d7 100644 --- a/src/socket_init.c +++ b/src/socket_init.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,7 @@ TR_socketInit(TR_Socket this, TR_socketAction_fptr action) struct addrinfo hint; struct addrinfo * info, * current_info; char port_str[6]; + int code; hint.ai_socktype = this->type; hint.ai_flags = this->flags; @@ -52,8 +54,11 @@ TR_socketInit(TR_Socket this, TR_socketAction_fptr action) hint.ai_next = NULL; sprintf(port_str, "%u", this->port); - if (0 != getaddrinfo(this->host, port_str, &hint, &info)) { + code = getaddrinfo(this->host, port_str, &hint, &info); + if (0 != code) { // TODO error handling... + puts(gai_strerror(code)); + return FALSE; } @@ -88,7 +93,9 @@ TR_socketInit(TR_Socket this, TR_socketAction_fptr action) //int flags = fcntl(this->handle, F_GETFL, 0); //fcntl(this->handle, F_SETFL, flags | O_NONBLOCK); - this->cname = TR_strdup(current_info->ai_canonname); + if (current_info->ai_canonname) { + strncpy(this->cname, current_info->ai_canonname, TR_MAX_CNAME); + } this->fin_state = TR_FIN_NO; //! Make the socket REUSE a TIME_WAIT socket diff --git a/src/tcp_socket.c b/src/tcp_socket.c index 35bbc3f..056c229 100644 --- a/src/tcp_socket.c +++ b/src/tcp_socket.c @@ -30,6 +30,7 @@ #include #include "tr/socket.h" +#include "tr/interface/socket.h" #include "tr/logger.h" #include "trbase.h" diff --git a/src/udp_socket.c b/src/udp_socket.c index 6f02fd5..4cd97a7 100644 --- a/src/udp_socket.c +++ b/src/udp_socket.c @@ -30,6 +30,7 @@ #include #include "tr/socket.h" +#include "tr/interface/socket.h" #include "tr/logger.h" #include "trbase.h" @@ -85,8 +86,8 @@ udpSocketSend(TR_Socket this, TR_RemoteData data) data->data, data->ndata, this->flags, - (struct sockaddr *)&(data->addr), - data->addrlen); + &(data->socket->addr.info), + data->socket->addrlen); if (-1 == send) { perror("sendto");