diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2013-03-31 00:57:33 +0900 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2013-03-31 18:02:45 +0900 |
| commit | f4a098754429019c356f6480238ff5cf941ed391 (patch) | |
| tree | 7fa5afe019475d3c2c1e4fe09ffaee9ff36ce6b4 /src/SocketCore.cc | |
| parent | 56fac58b4d05e1fc97ac37195c7a8cbacb08fb07 (diff) | |
Check non-loopback (and non-linklocak for IPv6) address is configured
Issue A record query only when non-loopback IPv4 address is
configured. Likewise, issue AAA record query only when non-loopback
and non-linklocak IPv6 address is configured.
Diffstat (limited to 'src/SocketCore.cc')
| -rw-r--r-- | src/SocketCore.cc | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/SocketCore.cc b/src/SocketCore.cc index 619002be..11781aee 100644 --- a/src/SocketCore.cc +++ b/src/SocketCore.cc @@ -1546,6 +1546,86 @@ bool verifyHostname(const std::string& hostname, return false; } +namespace { +bool ipv4AddrConfigured = true; +bool ipv6AddrConfigured = true; +} // namespace + +void checkAddrconfig() +{ + // TODO Use GetAdaptersAddresses() for Mingw +#ifdef HAVE_GETIFADDRS + A2_LOG_INFO("Checking configured addresses"); + ipv4AddrConfigured = false; + ipv6AddrConfigured = false; + ifaddrs* ifaddr = 0; + int rv; + rv = getifaddrs(&ifaddr); + if(rv == -1) { + int errNum = SOCKET_ERRNO; + A2_LOG_INFO(fmt("getifaddrs failed. Cause: %s", errorMsg(errNum).c_str())); + return; + } + auto_delete<ifaddrs*> ifaddrDeleter(ifaddr, freeifaddrs); + char host[NI_MAXHOST]; + sockaddr_union ad; + for(ifaddrs* ifa = ifaddr; ifa; ifa = ifa->ifa_next) { + if(!ifa->ifa_addr) { + continue; + } + bool found = false; + size_t addrlen = 0; + switch(ifa->ifa_addr->sa_family) { + case AF_INET: { + addrlen = sizeof(sockaddr_in); + memcpy(&ad.storage, ifa->ifa_addr, addrlen); + if(ad.in.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) { + ipv4AddrConfigured = true; + found = true; + } + break; + } + case AF_INET6: { + addrlen = sizeof(sockaddr_in6); + memcpy(&ad.storage, ifa->ifa_addr, addrlen); + if(!IN6_IS_ADDR_LOOPBACK(&ad.in6.sin6_addr) && + !IN6_IS_ADDR_LINKLOCAL(&ad.in6.sin6_addr)) { + ipv6AddrConfigured = true; + found = true; + } + break; + } + default: + continue; + } + rv = getnameinfo(ifa->ifa_addr, addrlen, 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)); + } + } + } + A2_LOG_INFO(fmt("IPv4 configured=%d, IPv6 configured=%d", + ipv4AddrConfigured, ipv6AddrConfigured)); +#else // !HAVE_GETIFADDRS + A2_LOG_INFO("getifaddrs is not available. Assume IPv4 and IPv6 addresses" + " are configured."); +#endif // !HAVE_GETIFADDRS +} + +bool getIPv4AddrConfigured() +{ + return ipv4AddrConfigured; +} + +bool getIPv6AddrConfigured() +{ + return ipv6AddrConfigured; +} + } // namespace net } // namespace aria2 |
