diff --git a/ChangeLog b/ChangeLog index f7895edb..9c3c6caa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-01-06 Tatsuhiro Tsujikawa + + Find pooled socket using all cached addresses. + * src/DNSCache.h + * src/DownloadEngine.cc + * src/DownloadEngine.h + * src/InitiateConnectionCommand.cc + 2010-01-06 Tatsuhiro Tsujikawa Updated copyright year. diff --git a/src/DNSCache.h b/src/DNSCache.h index 71d8dcfa..da6dfa45 100644 --- a/src/DNSCache.h +++ b/src/DNSCache.h @@ -107,6 +107,17 @@ private: return A2STR::NIL; } + template + void getAllGoodAddrs(OutputIterator out) const + { + for(std::vector::const_iterator i = _addrEntries.begin(); + i != _addrEntries.end(); ++i) { + if((*i)._good) { + *out++ = (*i)._addr; + } + } + } + void markBad(const std::string& addr) { std::vector::iterator i = find(addr); @@ -143,6 +154,18 @@ public: } return A2STR::NIL; } + + template + void findAll + (OutputIterator out, const std::string& hostname, uint16_t port) const + { + CacheEntry target(hostname, port); + std::deque::const_iterator i = + std::lower_bound(_entries.begin(), _entries.end(), target); + if(i != _entries.end() && (*i) == target) { + (*i).getAllGoodAddrs(out); + } + } void put (const std::string& hostname, const std::string& ipaddr, uint16_t port) diff --git a/src/DownloadEngine.cc b/src/DownloadEngine.cc index ebd784c3..011ff4c0 100644 --- a/src/DownloadEngine.cc +++ b/src/DownloadEngine.cc @@ -57,7 +57,6 @@ #include "ServerStatMan.h" #include "CookieStorage.h" #include "A2STR.h" -#include "DNSCache.h" #include "AuthConfigFactory.h" #include "AuthConfig.h" #include "Request.h" diff --git a/src/DownloadEngine.h b/src/DownloadEngine.h index a4f8aaca..8c9fc591 100644 --- a/src/DownloadEngine.h +++ b/src/DownloadEngine.h @@ -51,6 +51,7 @@ #include "CUIDCounter.h" #include "FileAllocationMan.h" #include "CheckIntegrityMan.h" +#include "DNSCache.h" namespace aria2 { @@ -60,7 +61,6 @@ class RequestGroupMan; class StatCalc; class SocketCore; class CookieStorage; -class DNSCache; class AuthConfigFactory; class Request; class EventPoll; @@ -251,6 +251,13 @@ public: const std::string& findCachedIPAddress (const std::string& hostname, uint16_t port) const; + template + void findAllCachedIPAddresses + (OutputIterator out, const std::string& hostname, uint16_t port) const + { + _dnsCache->findAll(out, hostname, port); + } + void cacheIPAddress (const std::string& hostname, const std::string& ipaddr, uint16_t port); diff --git a/src/InitiateConnectionCommand.cc b/src/InitiateConnectionCommand.cc index 22d873a9..8045e549 100644 --- a/src/InitiateConnectionCommand.cc +++ b/src/InitiateConnectionCommand.cc @@ -80,8 +80,9 @@ bool InitiateConnectionCommand::executeInternal() { port = proxyRequest->getPort(); } std::deque addrs; - std::string ipaddr = e->findCachedIPAddress(hostname, port); - if(ipaddr.empty()) { + e->findAllCachedIPAddresses(std::back_inserter(addrs), hostname, port); + std::string ipaddr; + if(addrs.empty()) { #ifdef ENABLE_ASYNC_DNS if(getOption()->getAsBool(PREF_ASYNC_DNS)) { if(!isAsyncNameResolverInitialized()) { @@ -105,15 +106,16 @@ bool InitiateConnectionCommand::executeInternal() { } logger->info(MSG_NAME_RESOLUTION_COMPLETE, cuid, hostname.c_str(), - strjoin(addrs.begin(), addrs.end(), ",").c_str()); + strjoin(addrs.begin(), addrs.end(), ", ").c_str()); for(std::deque::const_iterator i = addrs.begin(); i != addrs.end(); ++i) { e->cacheIPAddress(hostname, *i, port); } ipaddr = e->findCachedIPAddress(hostname, port); } else { - logger->info(MSG_DNS_CACHE_HIT, cuid, hostname.c_str(), ipaddr.c_str()); - addrs.push_back(ipaddr); + ipaddr = addrs.front(); + logger->info(MSG_DNS_CACHE_HIT, cuid, hostname.c_str(), + strjoin(addrs.begin(), addrs.end(), ", ").c_str()); } try { Command* command = createNextCommand(hostname, ipaddr, port, @@ -123,6 +125,8 @@ bool InitiateConnectionCommand::executeInternal() { } catch(RecoverableException& ex) { // Catch exception and retry another address. // See also AbstractCommand::checkIfConnectionEstablished + + // TODO ipaddr might not be used if pooled sockt was found. e->markBadIPAddress(hostname, ipaddr, port); if(!e->findCachedIPAddress(hostname, port).empty()) { logger->info(EX_EXCEPTION_CAUGHT, ex);