mirror of https://github.com/aria2/aria2
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.pull/60/head
parent
56fac58b4d
commit
f4a0987544
|
@ -107,7 +107,11 @@ AbstractCommand::AbstractCommand
|
|||
requestGroup_->increaseStreamCommand();
|
||||
requestGroup_->increaseNumCommand();
|
||||
#ifdef ENABLE_ASYNC_DNS
|
||||
if(e_->getOption()->getAsBool(PREF_DISABLE_IPV6)) {
|
||||
if(!net::getIPv4AddrConfigured()) {
|
||||
asyncNameResolverMan_->setIPv4(false);
|
||||
}
|
||||
if(!net::getIPv6AddrConfigured() ||
|
||||
e_->getOption()->getAsBool(PREF_DISABLE_IPV6)) {
|
||||
asyncNameResolverMan_->setIPv6(false);
|
||||
}
|
||||
#endif // ENABLE_ASYNC_DNS
|
||||
|
|
|
@ -69,14 +69,16 @@ void AsyncNameResolverMan::startAsync(const std::string& hostname,
|
|||
Command* command)
|
||||
{
|
||||
numResolver_ = 0;
|
||||
if(ipv4_) {
|
||||
startAsyncFamily(hostname, AF_INET, e, command);
|
||||
++numResolver_;
|
||||
}
|
||||
// Set IPv6 resolver first, so that we can push IPv6 address in
|
||||
// front of IPv6 address in getResolvedAddress().
|
||||
if(ipv6_) {
|
||||
startAsyncFamily(hostname, AF_INET6, e, command);
|
||||
++numResolver_;
|
||||
}
|
||||
if(ipv4_) {
|
||||
startAsyncFamily(hostname, AF_INET, e, command);
|
||||
++numResolver_;
|
||||
}
|
||||
A2_LOG_INFO(fmt(MSG_RESOLVING_HOSTNAME, command->getCuid(),
|
||||
hostname.c_str()));
|
||||
}
|
||||
|
@ -150,11 +152,13 @@ void AsyncNameResolverMan::disableNameResolverCheck(size_t index,
|
|||
|
||||
int AsyncNameResolverMan::getStatus() const
|
||||
{
|
||||
size_t success = 0;
|
||||
size_t error = 0;
|
||||
for(size_t i = 0; i < numResolver_; ++i) {
|
||||
switch(asyncNameResolver_[i]->getStatus()) {
|
||||
case AsyncNameResolver::STATUS_SUCCESS:
|
||||
return 1;
|
||||
++success;
|
||||
break;
|
||||
case AsyncNameResolver::STATUS_ERROR:
|
||||
++error;
|
||||
break;
|
||||
|
@ -162,7 +166,13 @@ int AsyncNameResolverMan::getStatus() const
|
|||
break;
|
||||
}
|
||||
}
|
||||
return error == numResolver_ ? -1 : 0;
|
||||
if(success == numResolver_) {
|
||||
return 1;
|
||||
} else if(error == numResolver_) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& AsyncNameResolverMan::getLastError() const
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -401,6 +401,12 @@ bool verifyHostname(const std::string& hostname,
|
|||
const std::vector<std::string>& dnsNames,
|
||||
const std::vector<std::string>& ipAddrs,
|
||||
const std::string& commonName);
|
||||
// Checks public IP address are configured for each family: IPv4 and
|
||||
// IPv6. The result can be obtained using getIpv4AddrConfigured() and
|
||||
// getIpv6AddrConfigured() respectively.
|
||||
void checkAddrconfig();
|
||||
bool getIPv4AddrConfigured();
|
||||
bool getIPv6AddrConfigured();
|
||||
|
||||
} // namespace net
|
||||
|
||||
|
|
|
@ -208,6 +208,7 @@ error_code::Value main(int argc, char* argv[])
|
|||
// when none of network interface has IPv4 address.
|
||||
setDefaultAIFlags(0);
|
||||
}
|
||||
net::checkAddrconfig();
|
||||
// Bind interface
|
||||
if(!op->get(PREF_INTERFACE).empty()) {
|
||||
std::string iface = op->get(PREF_INTERFACE);
|
||||
|
|
Loading…
Reference in New Issue