summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2013-03-31 15:32:04 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2013-03-31 18:02:46 +0900
commitb9fb15f88454d628e006f3b8240e21933341675b (patch)
tree8bb4e4b2ca6e91b125db2203eac07dec6a5a8dfe
parentf4a098754429019c356f6480238ff5cf941ed391 (diff)
Use GetAdaptersAddresses for Mingw
-rw-r--r--configure.ac3
-rw-r--r--src/AbstractCommand.cc6
-rw-r--r--src/SocketCore.cc73
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;