diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2013-03-31 15:32:04 +0900 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2013-03-31 18:02:46 +0900 |
| commit | b9fb15f88454d628e006f3b8240e21933341675b (patch) | |
| tree | 8bb4e4b2ca6e91b125db2203eac07dec6a5a8dfe | |
| parent | f4a098754429019c356f6480238ff5cf941ed391 (diff) | |
Use GetAdaptersAddresses for Mingw
| -rw-r--r-- | configure.ac | 3 | ||||
| -rw-r--r-- | src/AbstractCommand.cc | 6 | ||||
| -rw-r--r-- | src/SocketCore.cc | 73 |
3 files changed, 79 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac index b31fde2b..f2525283 100644 --- a/configure.ac +++ b/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 diff --git a/src/AbstractCommand.cc b/src/AbstractCommand.cc index 478dbf33..916e9fe8 100644 --- a/src/AbstractCommand.cc +++ b/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 diff --git a/src/SocketCore.cc b/src/SocketCore.cc index 11781aee..e090e27a 100644 --- a/src/SocketCore.cc +++ b/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; |
