Browse Source

Use GetAdaptersAddresses for Mingw

Tatsuhiro Tsujikawa 12 năm trước cách đây
mục cha
commit
b9fb15f884
3 tập tin đã thay đổi với 79 bổ sung3 xóa
  1. 2 1
      configure.ac
  2. 6 0
      src/AbstractCommand.cc
  3. 71 2
      src/SocketCore.cc

+ 2 - 1
configure.ac

@@ -17,7 +17,7 @@ AC_CONFIG_HEADERS([config.h])
 case "$host" in
   *mingw*|*cygwin*)
     win_build=yes
-    LIBS="$LIBS -lws2_32 -lwsock32 -lgdi32 -lwinmm"
+    LIBS="$LIBS -lws2_32 -lwsock32 -lgdi32 -lwinmm -liphlpapi"
     ;;
 esac
 
@@ -341,6 +341,7 @@ case "$host" in
                                   ws2tcpip.h \
 				  mmsystem.h \
                                   io.h \
+                                  iphlpapi.h\
                                   winioctl.h \
                                   share.h], [], [],
 [[#ifdef HAVE_WINDOWS_H

+ 6 - 0
src/AbstractCommand.cc

@@ -733,6 +733,12 @@ std::string AbstractCommand::resolveHostname
         return A2STR::NIL;
       case 1:
         asyncNameResolverMan_->getResolvedAddress(addrs);
+        if(addrs.empty()) {
+          throw DL_ABORT_EX2
+            (fmt(MSG_NAME_RESOLUTION_FAILED, getCuid(), hostname.c_str(),
+                 "No address returned"),
+             error_code::NAME_RESOLVE_ERROR);
+        }
         break;
       }
     } else

+ 71 - 2
src/SocketCore.cc

@@ -34,6 +34,10 @@
 /* copyright --> */
 #include "SocketCore.h"
 
+#ifdef HAVE_IPHLPAPI_H
+# include <iphlpapi.h>
+#endif // HAVE_IPHLPAPI_H
+
 #include <unistd.h>
 #ifdef HAVE_IFADDRS_H
 # include <ifaddrs.h>
@@ -1553,8 +1557,73 @@ bool ipv6AddrConfigured = true;
 
 void checkAddrconfig()
 {
-  // TODO Use GetAdaptersAddresses() for Mingw
-#ifdef HAVE_GETIFADDRS
+#ifdef __MINGW32__
+  A2_LOG_INFO("Checking configured addresses");
+  ULONG bufsize = 15*1024;
+  ULONG retval = 0;
+  IP_ADAPTER_ADDRESSES* buf = 0;
+  int numTry = 0;
+  const int MAX_TRY = 3;
+  do {
+    buf = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(bufsize));
+    retval = GetAdaptersAddresses(AF_UNSPEC, 0, 0, buf, &bufsize);
+    if(retval == ERROR_BUFFER_OVERFLOW) {
+      free(buf);
+      buf = 0;
+    } else {
+      break;
+    }
+  } while(retval == ERROR_BUFFER_OVERFLOW && numTry < MAX_TRY);
+  if(retval != NO_ERROR) {
+    A2_LOG_INFO("GetAdaptersAddresses failed. Assume both IPv4 and IPv6 "
+                " addresses are configured.");
+    return;
+  }
+  ipv4AddrConfigured = false;
+  ipv6AddrConfigured = false;
+  char host[NI_MAXHOST];
+  sockaddr_union ad;
+  int rv;
+  for(IP_ADAPTER_ADDRESSES* p = buf; p; p = p->Next) {
+    PIP_ADAPTER_UNICAST_ADDRESS ucaddr = p->FirstUnicastAddress;
+    if(ucaddr) {
+      for(PIP_ADAPTER_UNICAST_ADDRESS i = ucaddr; i; i = i->Next) {
+        bool found = false;
+        switch(i->Address.iSockaddrLength) {
+        case sizeof(sockaddr_in):
+          memcpy(&ad.storage, i->Address.lpSockaddr,
+                 i->Address.iSockaddrLength);
+          if(ad.in.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
+            ipv4AddrConfigured = true;
+            found = true;
+          }
+          break;
+        case sizeof(sockaddr_in6):
+          memcpy(&ad.storage, i->Address.lpSockaddr,
+                 i->Address.iSockaddrLength);
+          if(!IN6_IS_ADDR_LOOPBACK(&ad.in6.sin6_addr) &&
+             !IN6_IS_ADDR_LINKLOCAL(&ad.in6.sin6_addr)) {
+            ipv6AddrConfigured = true;
+            found = true;
+          }
+          break;
+        }
+        rv = getnameinfo(i->Address.lpSockaddr, i->Address.iSockaddrLength,
+                         host, NI_MAXHOST, 0, 0, NI_NUMERICHOST);
+        if(rv == 0) {
+          if(found) {
+            A2_LOG_INFO(fmt("Found configured address: %s", host));
+          } else {
+            A2_LOG_INFO(fmt("Not considered: %s", host));
+          }
+        }
+      }
+    }
+  }
+  free(buf);
+  A2_LOG_INFO(fmt("IPv4 configured=%d, IPv6 configured=%d",
+                  ipv4AddrConfigured, ipv6AddrConfigured));
+#elif defined(HAVE_GETIFADDRS)
   A2_LOG_INFO("Checking configured addresses");
   ipv4AddrConfigured = false;
   ipv6AddrConfigured = false;