summaryrefslogtreecommitdiff
path: root/src/SocketCore.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2013-03-31 00:57:33 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2013-03-31 18:02:45 +0900
commitf4a098754429019c356f6480238ff5cf941ed391 (patch)
tree7fa5afe019475d3c2c1e4fe09ffaee9ff36ce6b4 /src/SocketCore.cc
parent56fac58b4d05e1fc97ac37195c7a8cbacb08fb07 (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.cc80
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