diff options
author | Xavier Roche <xroche@users.noreply.github.com> | 2014-05-18 09:49:24 +0000 |
---|---|---|
committer | Xavier Roche <xroche@users.noreply.github.com> | 2014-05-18 09:49:24 +0000 |
commit | 6c8b76e53168dd1fc9c4b88cc42819903fd2eabc (patch) | |
tree | 4614e8e46de7c84fe734513eee2114e150b47452 /src/htsnet.h | |
parent | 66c8cc32aa6f8b385b8d7c3871e83df79e2a5d66 (diff) |
Cleanup in socket handling (less ugly casts!)
Diffstat (limited to 'src/htsnet.h')
-rw-r--r-- | src/htsnet.h | 250 |
1 files changed, 110 insertions, 140 deletions
diff --git a/src/htsnet.h b/src/htsnet.h index f0d8496..d8bdf2c 100644 --- a/src/htsnet.h +++ b/src/htsnet.h @@ -38,6 +38,7 @@ Please visit our Website: http://www.httrack.com /* basic net definitions */ #include "htsglobal.h" #include "htsbasenet.h" +#include "htssafe.h" #include <ctype.h> #ifdef _WIN32 @@ -45,6 +46,8 @@ Please visit our Website: http://www.httrack.com #include <io.h> // pour FindFirstFile #include <winbase.h> +typedef USHORT in_port_t; +typedef ADDRESS_FAMILY sa_family_t; #else //typedef int T_SOC; #define INVALID_SOCKET -1 @@ -70,13 +73,12 @@ typedef unsigned long in_addr_t; #endif #endif -/* - ** ipV4 ** -*/ -#if HTS_INET6==0 - /* Ipv4 structures */ +#if HTS_INET6 != 0 +typedef struct in6_addr INaddr; +#else typedef struct in_addr INaddr; +#endif /* This should handle all cases */ #ifndef HTS_DEF_FWSTRUCT_SOCaddr @@ -86,167 +88,135 @@ typedef struct SOCaddr SOCaddr; struct SOCaddr { union { struct sockaddr_in in; +#if HTS_INET6 != 0 + struct sockaddr_in6 in6; +#endif + /* For network functions such as getnameinfo */ struct sockaddr sa; - unsigned char v4data[4]; - unsigned char v6data[16]; - unsigned char pad[128]; } m_addr; + socklen_t size; }; -/* Ipv4 structure members */ -#define SOCaddr_sinaddr(server) ((server).m_addr.in.sin_addr) -#define SOCaddr_sinfamily(server) ((server).m_addr.in.sin_family) -#define SOCaddr_sinport(server) ((server).m_addr.in.sin_port) - -/* AF_xx */ -#define AFinet AF_INET - -/* Set port to sockaddr structure */ -#define SOCaddr_initport(server, port) do { \ - SOCaddr_sinport(server) = htons((unsigned short int) (port)); \ -} while(0) - -#define SOCaddr_initany(server, server_len) do { \ - SOCaddr_sinfamily(server) = AF_INET; \ - memset(&SOCaddr_sinaddr(server), 0, sizeof(struct sockaddr_in)); \ - server_len=sizeof(struct sockaddr_in); \ -} while(0) - -/* Copy sockaddr to another one */ -#define SOCaddr_copyaddr(server, server_len, hpaddr, hpsize) do { \ -if (hpsize == sizeof(struct sockaddr_in)) { \ - server_len=sizeof(struct sockaddr_in); \ - SOCaddr_sinfamily(server) = (*(struct sockaddr_in*)(hpaddr)).sin_family; \ - SOCaddr_sinport(server) = (*(struct sockaddr_in*)(hpaddr)).sin_port; \ - memcpy(&SOCaddr_sinaddr(server), &(*(struct sockaddr_in*)(hpaddr)).sin_addr, sizeof(SOCaddr_sinaddr(server))); \ -} else if (hpsize == 4) {\ - server_len=sizeof(struct sockaddr_in); \ - SOCaddr_sinfamily(server) = AF_INET; \ - SOCaddr_sinport(server) = 0; \ - memcpy(&SOCaddr_sinaddr(server), (hpaddr), sizeof(SOCaddr_sinaddr(server))); \ -} else if ((hpsize > 0) && (hpsize <= sizeof(server))) { \ - server_len=hpsize; \ - memcpy(&(server), hpaddr, hpsize); \ -} else { \ - server_len=0; \ -} \ -} while(0) - -/* Get dotted address */ -#define SOCaddr_inetntoa(namebuf, namebuflen, ss, sslen) do { \ -char* dot = (char*) inet_ntoa(SOCaddr_sinaddr(ss)); \ -(namebuf)[0]='\0'; \ -if (dot) { \ -strcpy(namebuf, dot); \ -} \ -} while(0) - -/* Get protocol ID */ -#define SOCaddr_getproto(ss, sslen) ('1') - -/* - ** ipV6 ** -*/ -#else - -/* Ipv4 structures */ -typedef struct in6_addr INaddr; +static HTS_INLINE HTS_UNUSED in_port_t* SOCaddr_sinport_(SOCaddr *const addr) { +#if HTS_INET6 != 0 + if (addr->size == sizeof(struct sockaddr_in6)) { + return &addr->m_addr.in6.sin6_port; + } else { +#endif + assertf(addr->size == sizeof(struct sockaddr_in)); + return &addr->m_addr.in.sin_port; +#if HTS_INET6 != 0 + } +#endif +} -/* This should handle all cases */ -#ifndef HTS_DEF_FWSTRUCT_SOCaddr -#define HTS_DEF_FWSTRUCT_SOCaddr -typedef struct SOCaddr SOCaddr; +static HTS_INLINE HTS_UNUSED sa_family_t* SOCaddr_sinfamily_(SOCaddr *const addr) { +#if HTS_INET6 != 0 + if (addr->size == sizeof(struct sockaddr_in6)) { + return (sa_family_t*) &addr->m_addr.in6.sin6_family; + } else { #endif -struct SOCaddr { - union { - struct sockaddr_in6 in6; - struct sockaddr_in in; - struct sockaddr sa; - unsigned char v4data[4]; - unsigned char v6data[16]; - unsigned char pad[128]; - } m_addr; -}; + assertf(addr->size == sizeof(struct sockaddr_in)); + return (sa_family_t*) &addr->m_addr.in.sin_family; +#if HTS_INET6 != 0 + } +#endif +} -/* Ipv4 structure members */ -#define SOCaddr_sinaddr(server) ((server).m_addr.in6.sin6_addr) -#define SOCaddr_sinfamily(server) ((server).m_addr.in6.sin6_family) -#define SOCaddr_sinport(server) ((server).m_addr.in6.sin6_port) -#define SOCaddr_sinflowinfo(server) ((server).m_addr.in6.sin6_flowinfo) -/* #define SOCaddr_sinscopeid(a) ((a).m_addr.in6.sin6_scope_id) */ +/* Ipv4/6 structure members */ +#define SOCaddr_sinfamily(server) (*SOCaddr_sinfamily_(&(server))) +#define SOCaddr_sinport(server) (*SOCaddr_sinport_(&(server))) /* AF_xx */ +#if HTS_INET6 != 0 #define AFinet AF_INET6 +#else +#define AFinet AF_INET +#endif /* Set port to sockaddr structure */ #define SOCaddr_initport(server, port) do { \ - SOCaddr_sinport(server) = htons((unsigned short int) (port)); \ + SOCaddr_sinport(server) = htons((in_port_t) (port)); \ } while(0) +static HTS_INLINE HTS_UNUSED socklen_t SOCaddr_initany_(SOCaddr*const addr) { + addr->size = sizeof(struct sockaddr_in); + memset(&addr->m_addr.in, 0, sizeof(addr->m_addr.in)); + addr->m_addr.in.sin_family = AF_INET; + return addr->size; +} + #define SOCaddr_initany(server, server_len) do { \ - SOCaddr_sinfamily(server) = AF_INET; \ - memset(&SOCaddr_sinaddr(server), 0, sizeof(struct sockaddr_in)); \ - server_len=sizeof(struct sockaddr_in); \ + server_len = (int) SOCaddr_initany_(&(server)); \ } while(0) /* - Copy sockaddr to SOCaddr - - Note; - The '> sizeof(struct sockaddr_in6)' hack if for the VC6 structure which - lacks the scope id + Copy sockaddr_in/sockaddr_in6/raw IPv4/raw IPv6 to our opaque SOCaddr */ +static HTS_UNUSED socklen_t SOCaddr_copyaddr_(SOCaddr*const server, + const void *data, const size_t data_size, + const char *file, const int line) { + assertf_(server != NULL, file, line); + assertf_(data != NULL, file, line); + + if (data_size == sizeof(struct sockaddr_in)) { + memcpy(&server->m_addr.in, data, sizeof(struct sockaddr_in)); + server->size = sizeof(struct sockaddr_in); +#if HTS_INET6 != 0 + } else if (data_size == sizeof(struct sockaddr_in6)) { + memcpy(&server->m_addr.in6, data, sizeof(struct sockaddr_in6)); + server->size = sizeof(struct sockaddr_in6); +#endif + } else if (data_size == 4) { + memset(&server->m_addr.in, 0, sizeof(server->m_addr.in)); + server->m_addr.in.sin_family = AF_INET; + server->m_addr.in.sin_port = 0; + memcpy(&server->m_addr.in.sin_addr, data, 4); + server->size = sizeof(struct sockaddr_in); +#if HTS_INET6 != 0 + } else if (data_size == 16) { + memset(&server->m_addr.in6, 0, sizeof(server->m_addr.in6)); + server->m_addr.in6.sin6_family = AF_INET6; + server->m_addr.in6.sin6_port = 0; + memcpy(&server->m_addr.in6.sin6_addr, data, 16); + server->size = sizeof(struct sockaddr_in6); +#endif + } else { + server->size = 0; /* Error */ + } + return server->size; +} + #define SOCaddr_copyaddr(server, server_len, hpaddr, hpsize) do { \ -if (hpsize == sizeof(struct sockaddr_in6)) { \ - server_len=sizeof(struct sockaddr_in6); \ - SOCaddr_sinfamily(server) = (*(struct sockaddr_in6*)(hpaddr)).sin6_family; \ - SOCaddr_sinport(server) = (*(struct sockaddr_in6*)(hpaddr)).sin6_port; \ - SOCaddr_sinflowinfo(server) = (*(struct sockaddr_in6*)(hpaddr)).sin6_flowinfo; \ - memcpy(&SOCaddr_sinaddr(server), &(*(struct sockaddr_in6*)(hpaddr)).sin6_addr, sizeof(SOCaddr_sinaddr(server))); \ -} else if (hpsize > sizeof(struct sockaddr_in6)) { \ - server_len=hpsize; \ - SOCaddr_sinport(server) = 0; \ - memcpy(&(server), hpaddr, hpsize); \ -} else if (hpsize == sizeof(struct sockaddr_in)) { \ - server_len=sizeof(struct sockaddr_in); \ - (*(struct sockaddr_in*)(&server)).sin_family = AF_INET; \ - SOCaddr_sinport(server) = (*(struct sockaddr_in*)(hpaddr)).sin_port; \ - memcpy(&(*(struct sockaddr_in*)&(server)).sin_addr, &(*(struct sockaddr_in*)(hpaddr)).sin_addr, sizeof((*(struct sockaddr_in*)(hpaddr)).sin_addr)); \ -} else if (hpsize == 4) {\ - server_len=sizeof(struct sockaddr_in); \ - (*(struct sockaddr_in*)(&server)).sin_family = AF_INET; \ - SOCaddr_sinport(server) = 0; \ - memcpy(&(*(struct sockaddr_in*)&(server)).sin_addr, hpaddr, 4); \ -} else if (hpsize == 16) {\ - server_len=sizeof(struct sockaddr_in6); \ - SOCaddr_sinfamily(server) = AF_INET6; \ - SOCaddr_sinport(server) = 0; \ - memcpy(&SOCaddr_sinaddr(server), (hpaddr), 16); \ -} else if ((hpsize > 0) && (hpsize <= sizeof(server))) { \ - server_len=hpsize; \ - memcpy(&(server), hpaddr, hpsize); \ -} else { \ - server_len=0; \ -} \ + server_len = (int) SOCaddr_copyaddr_(&(server), hpaddr, hpsize, __FILE__, __LINE__); \ } while(0) /* Get dotted address */ -#define SOCaddr_inetntoa(namebuf, namebuflen, ss, sslen) do { \ - char *pos_; \ - (namebuf)[0]='\0'; \ - getnameinfo((struct sockaddr *)&(ss), sslen, \ - (namebuf), namebuflen, NULL, 0, NI_NUMERICHOST); \ - /* remove scope id */ \ - pos_ = strrchr(namebuf, '%'); \ - if (pos_ != NULL) { \ - *pos_ = '\0'; \ - } \ -} while(0) -/* Get protocol ID */ -#define SOCaddr_getproto(ss, sslen) ((sslen == sizeof(struct sockaddr_in6))?('2'):('1')) +static HTS_UNUSED void SOCaddr_inetntoa_(char *namebuf, size_t namebuflen, + SOCaddr *const ss, + const char *file, const int line) { + assertf_(namebuf != NULL, file, line); + assertf_(ss != NULL, file, line); + if (getnameinfo(&ss->m_addr.sa, ss->size, + namebuf, namebuflen, + NULL, 0, + NI_NUMERICHOST) == 0) { + /* remove scope id(s) */ + char *const pos = strchr(namebuf, '%'); + if (pos != NULL) { + *pos = '\0'; + } + } else { + namebuf[0] = '\0'; + } +} + +#define SOCaddr_inetntoa(namebuf, namebuflen, ss, sslen) \ + SOCaddr_inetntoa_(namebuf, namebuflen, &(ss), __FILE__, __LINE__) -#endif +/* Get protocol ID */ +#define SOCaddr_getproto(ss, sslen) ( (sslen) == sizeof(struct sockaddr_in) ? '1' : '2') /* Socket length type */ typedef socklen_t SOClen; |