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_->increaseStreamCommand();
|
||||||
requestGroup_->increaseNumCommand();
|
requestGroup_->increaseNumCommand();
|
||||||
#ifdef ENABLE_ASYNC_DNS
|
#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);
|
asyncNameResolverMan_->setIPv6(false);
|
||||||
}
|
}
|
||||||
#endif // ENABLE_ASYNC_DNS
|
#endif // ENABLE_ASYNC_DNS
|
||||||
|
|
|
@ -69,14 +69,16 @@ void AsyncNameResolverMan::startAsync(const std::string& hostname,
|
||||||
Command* command)
|
Command* command)
|
||||||
{
|
{
|
||||||
numResolver_ = 0;
|
numResolver_ = 0;
|
||||||
if(ipv4_) {
|
// Set IPv6 resolver first, so that we can push IPv6 address in
|
||||||
startAsyncFamily(hostname, AF_INET, e, command);
|
// front of IPv6 address in getResolvedAddress().
|
||||||
++numResolver_;
|
|
||||||
}
|
|
||||||
if(ipv6_) {
|
if(ipv6_) {
|
||||||
startAsyncFamily(hostname, AF_INET6, e, command);
|
startAsyncFamily(hostname, AF_INET6, e, command);
|
||||||
++numResolver_;
|
++numResolver_;
|
||||||
}
|
}
|
||||||
|
if(ipv4_) {
|
||||||
|
startAsyncFamily(hostname, AF_INET, e, command);
|
||||||
|
++numResolver_;
|
||||||
|
}
|
||||||
A2_LOG_INFO(fmt(MSG_RESOLVING_HOSTNAME, command->getCuid(),
|
A2_LOG_INFO(fmt(MSG_RESOLVING_HOSTNAME, command->getCuid(),
|
||||||
hostname.c_str()));
|
hostname.c_str()));
|
||||||
}
|
}
|
||||||
|
@ -150,11 +152,13 @@ void AsyncNameResolverMan::disableNameResolverCheck(size_t index,
|
||||||
|
|
||||||
int AsyncNameResolverMan::getStatus() const
|
int AsyncNameResolverMan::getStatus() const
|
||||||
{
|
{
|
||||||
|
size_t success = 0;
|
||||||
size_t error = 0;
|
size_t error = 0;
|
||||||
for(size_t i = 0; i < numResolver_; ++i) {
|
for(size_t i = 0; i < numResolver_; ++i) {
|
||||||
switch(asyncNameResolver_[i]->getStatus()) {
|
switch(asyncNameResolver_[i]->getStatus()) {
|
||||||
case AsyncNameResolver::STATUS_SUCCESS:
|
case AsyncNameResolver::STATUS_SUCCESS:
|
||||||
return 1;
|
++success;
|
||||||
|
break;
|
||||||
case AsyncNameResolver::STATUS_ERROR:
|
case AsyncNameResolver::STATUS_ERROR:
|
||||||
++error;
|
++error;
|
||||||
break;
|
break;
|
||||||
|
@ -162,7 +166,13 @@ int AsyncNameResolverMan::getStatus() const
|
||||||
break;
|
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
|
const std::string& AsyncNameResolverMan::getLastError() const
|
||||||
|
|
|
@ -1546,6 +1546,86 @@ bool verifyHostname(const std::string& hostname,
|
||||||
return false;
|
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 net
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -401,6 +401,12 @@ bool verifyHostname(const std::string& hostname,
|
||||||
const std::vector<std::string>& dnsNames,
|
const std::vector<std::string>& dnsNames,
|
||||||
const std::vector<std::string>& ipAddrs,
|
const std::vector<std::string>& ipAddrs,
|
||||||
const std::string& commonName);
|
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
|
} // namespace net
|
||||||
|
|
||||||
|
|
|
@ -208,6 +208,7 @@ error_code::Value main(int argc, char* argv[])
|
||||||
// when none of network interface has IPv4 address.
|
// when none of network interface has IPv4 address.
|
||||||
setDefaultAIFlags(0);
|
setDefaultAIFlags(0);
|
||||||
}
|
}
|
||||||
|
net::checkAddrconfig();
|
||||||
// Bind interface
|
// Bind interface
|
||||||
if(!op->get(PREF_INTERFACE).empty()) {
|
if(!op->get(PREF_INTERFACE).empty()) {
|
||||||
std::string iface = op->get(PREF_INTERFACE);
|
std::string iface = op->get(PREF_INTERFACE);
|
||||||
|
|
Loading…
Reference in New Issue