From 36051cca5e03c6268c62a5eca1f756b14435a29d Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Wed, 16 May 2012 22:43:25 +0900 Subject: [PATCH] Handle sockaddr_in.sin_len and sockaddr_in6.sin6_len Check sockaddr_in.sin_len and sockaddr_in6.sin6_len are available and assign values to them properly. This change fixes unit test error and most error related to getnameinfo() on netbsd. --- configure.ac | 16 +++++++++++++++- src/SocketCore.cc | 40 ++++++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/configure.ac b/configure.ac index 671a1b0b..458ca4c5 100644 --- a/configure.ac +++ b/configure.ac @@ -541,7 +541,21 @@ AC_CHECK_MEMBER([struct sockaddr_in.sin_len], [AC_DEFINE([HAVE_SOCKADDR_IN_SIN_LEN],[1], [Define to 1 if struct sockaddr_in has sin_len member.])], [], - [[#include ]]) + [[ +#include +#include +#include +]]) + +AC_CHECK_MEMBER([struct sockaddr_in6.sin6_len], + [AC_DEFINE([HAVE_SOCKADDR_IN6_SIN6_LEN],[1], + [Define to 1 if struct sockaddr_in6 has sin6_len member.])], + [], + [[ +#include +#include +#include +]]) # Check struct option.name is assignable from const char*. struct # option.name in opensolaris is of type char*. In Linux, it is const diff --git a/src/SocketCore.cc b/src/SocketCore.cc index 7c3c1da6..17feeec8 100644 --- a/src/SocketCore.cc +++ b/src/SocketCore.cc @@ -1282,19 +1282,23 @@ int callGetaddrinfo int inetNtop(int af, const void* src, char* dst, socklen_t size) { int s; + sockaddr_union su; + memset(&su, 0, sizeof(su)); if(af == AF_INET) { - sockaddr_in sa; - memset(&sa, 0, sizeof(sa)); - sa.sin_family = AF_INET; - memcpy(&sa.sin_addr, src, sizeof(in_addr)); - s = getnameinfo(reinterpret_cast(&sa), sizeof(sa), + su.in.sin_family = AF_INET; +#ifdef HAVE_SOCKADDR_IN_SIN_LEN + su.in.sin_len = sizeof(su.in); +#endif // HAVE_SOCKADDR_IN_SIN_LEN + memcpy(&su.in.sin_addr, src, sizeof(su.in.sin_addr)); + s = getnameinfo(&su.sa, sizeof(su.in), dst, size, 0, 0, NI_NUMERICHOST); } else if(af == AF_INET6) { - sockaddr_in6 sa; - memset(&sa, 0, sizeof(sa)); - sa.sin6_family = AF_INET6; - memcpy(&sa.sin6_addr, src, sizeof(in6_addr)); - s = getnameinfo(reinterpret_cast(&sa), sizeof(sa), + su.in6.sin6_family = AF_INET6; +#ifdef HAVE_SOCKADDR_IN6_SIN6_LEN + su.in6.sin6_len = sizeof(su.in6); +#endif // HAVE_SOCKADDR_IN6_SIN6_LEN + memcpy(&su.in6.sin6_addr, src, sizeof(su.in6.sin6_addr)); + s = getnameinfo(&su.sa, sizeof(su.in6), dst, size, 0, 0, NI_NUMERICHOST); } else { s = EAI_FAMILY; @@ -1339,16 +1343,16 @@ size_t getBinAddr(void* dest, const std::string& ip) } WSAAPI_AUTO_DELETE resDeleter(res, freeaddrinfo); for(addrinfo* rp = res; rp; rp = rp->ai_next) { + sockaddr_union su; + memcpy(&su, rp->ai_addr, rp->ai_addrlen); if(rp->ai_family == AF_INET) { - sockaddr_in* addr = &reinterpret_cast(rp->ai_addr)->in; - len = 4; - memcpy(dest, &(addr->sin_addr), len); - return len; + len = sizeof(in_addr); + memcpy(dest, &(su.in.sin_addr), len); + break; } else if(rp->ai_family == AF_INET6) { - sockaddr_in6* addr = &reinterpret_cast(rp->ai_addr)->in6; - len = 16; - memcpy(dest, &(addr->sin6_addr), len); - return len; + len = sizeof(in6_addr); + memcpy(dest, &(su.in6.sin6_addr), len); + break; } } return len;