Parcourir la source

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.
Tatsuhiro Tsujikawa il y a 13 ans
Parent
commit
36051cca5e
2 fichiers modifiés avec 37 ajouts et 19 suppressions
  1. 15 1
      configure.ac
  2. 22 18
      src/SocketCore.cc

+ 15 - 1
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 <netinet/in.h>]])
+                [[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+]])
+
+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 <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+]])
 
 # Check struct option.name is assignable from const char*.  struct
 # option.name in opensolaris is of type char*. In Linux, it is const

+ 22 - 18
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<const sockaddr*>(&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<const sockaddr*>(&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<addrinfo*> 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<sockaddr_union*>(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<sockaddr_union*>(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;