From b5a6c39262a3adeba1c04eee7b6ef29913081c28 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Mon, 1 Apr 2013 01:24:18 +0900 Subject: [PATCH] Use AsyncNameResolverMan in DHTEntryPointNameResolveCommand --- src/AbstractCommand.cc | 8 +- src/AsyncNameResolverMan.cc | 26 ++++- src/AsyncNameResolverMan.h | 6 ++ src/DHTEntryPointNameResolveCommand.cc | 131 +++++++++++-------------- src/DHTEntryPointNameResolveCommand.h | 13 +-- 5 files changed, 93 insertions(+), 91 deletions(-) diff --git a/src/AbstractCommand.cc b/src/AbstractCommand.cc index 8b311fcb..99250108 100644 --- a/src/AbstractCommand.cc +++ b/src/AbstractCommand.cc @@ -107,13 +107,7 @@ AbstractCommand::AbstractCommand requestGroup_->increaseStreamCommand(); requestGroup_->increaseNumCommand(); #ifdef ENABLE_ASYNC_DNS - if(!net::getIPv4AddrConfigured()) { - asyncNameResolverMan_->setIPv4(false); - } - if(!net::getIPv6AddrConfigured() || - e_->getOption()->getAsBool(PREF_DISABLE_IPV6)) { - asyncNameResolverMan_->setIPv6(false); - } + configureAsyncNameResolverMan(asyncNameResolverMan_.get(), e_->getOption()); #endif // ENABLE_ASYNC_DNS } diff --git a/src/AsyncNameResolverMan.cc b/src/AsyncNameResolverMan.cc index 4e66cce1..2b418394 100644 --- a/src/AsyncNameResolverMan.cc +++ b/src/AsyncNameResolverMan.cc @@ -39,6 +39,9 @@ #include "message.h" #include "fmt.h" #include "LogFactory.h" +#include "Option.h" +#include "SocketCore.h" +#include "prefs.h" namespace aria2 { @@ -186,5 +189,26 @@ const std::string& AsyncNameResolverMan::getLastError() const return A2STR::NIL; } -} // namespace aria2 +void AsyncNameResolverMan::reset(DownloadEngine* e, Command* command) +{ + disableNameResolverCheck(e, command); + assert(resolverCheck_ == 0); + for(size_t i = 0; i < numResolver_; ++i) { + asyncNameResolver_[i].reset(); + } + numResolver_ = 0; +} +void configureAsyncNameResolverMan(AsyncNameResolverMan* asyncNameResolverMan, + Option* option) +{ + if(!net::getIPv4AddrConfigured()) { + asyncNameResolverMan->setIPv4(false); + } + if(!net::getIPv6AddrConfigured() || + option->getAsBool(PREF_DISABLE_IPV6)) { + asyncNameResolverMan->setIPv6(false); + } +} + +} // namespace aria2 diff --git a/src/AsyncNameResolverMan.h b/src/AsyncNameResolverMan.h index 2e049a6e..ef1dd599 100644 --- a/src/AsyncNameResolverMan.h +++ b/src/AsyncNameResolverMan.h @@ -47,6 +47,7 @@ namespace aria2 { class AsyncNameResolver; class DownloadEngine; class Command; +class Option; class AsyncNameResolverMan { public: @@ -85,6 +86,8 @@ public: int getStatus() const; // Returns last error string const std::string& getLastError() const; + // Resets state. Also removes resolvers from DownloadEngine. + void reset(DownloadEngine* e, Command* command); private: void startAsyncFamily(const std::string& hostname, int family, @@ -101,6 +104,9 @@ private: bool ipv6_; }; +void configureAsyncNameResolverMan(AsyncNameResolverMan* asyncNameResolverMan, + Option* option); + } // namespace aria2 #endif // D_ASYNC_NAME_RESOLVER_MAN_H diff --git a/src/DHTEntryPointNameResolveCommand.cc b/src/DHTEntryPointNameResolveCommand.cc index 87d3e3b6..347589f7 100644 --- a/src/DHTEntryPointNameResolveCommand.cc +++ b/src/DHTEntryPointNameResolveCommand.cc @@ -49,8 +49,9 @@ #include "Logger.h" #include "LogFactory.h" #include "fmt.h" +#include "SocketCore.h" #ifdef ENABLE_ASYNC_DNS -#include "AsyncNameResolver.h" +#include "AsyncNameResolverMan.h" #endif // ENABLE_ASYNC_DNS namespace aria2 { @@ -60,14 +61,20 @@ DHTEntryPointNameResolveCommand::DHTEntryPointNameResolveCommand const std::vector >& entryPoints): Command(cuid), e_(e), + asyncNameResolverMan_(new AsyncNameResolverMan()), entryPoints_(entryPoints.begin(), entryPoints.end()), + numSuccess_(0), bootstrapEnabled_(false) -{} +{ +#ifdef ENABLE_ASYNC_DNS + configureAsyncNameResolverMan(asyncNameResolverMan_.get(), e_->getOption()); +#endif // ENABLE_ASYNC_DNS +} DHTEntryPointNameResolveCommand::~DHTEntryPointNameResolveCommand() { #ifdef ENABLE_ASYNC_DNS - disableNameResolverCheck(resolver_); + asyncNameResolverMan_->disableNameResolverCheck(e_, this); #endif // ENABLE_ASYNC_DNS } @@ -76,46 +83,42 @@ bool DHTEntryPointNameResolveCommand::execute() if(e_->getRequestGroupMan()->downloadFinished() || e_->isHaltRequested()) { return true; } -#ifdef ENABLE_ASYNC_DNS - if(!resolver_) { - int family; - if(e_->getOption()->getAsBool(PREF_ENABLE_ASYNC_DNS6)) { - family = AF_UNSPEC; - } else { - family = AF_INET; - } - resolver_.reset(new AsyncNameResolver(family -#ifdef HAVE_ARES_ADDR_NODE - , e_->getAsyncDNSServers() -#endif // HAVE_ARES_ADDR_NODE - )); - } -#endif // ENABLE_ASYNC_DNS try { #ifdef ENABLE_ASYNC_DNS if(e_->getOption()->getAsBool(PREF_ASYNC_DNS)) { while(!entryPoints_.empty()) { std::string hostname = entryPoints_.front().first; - try { - if(util::isNumericHost(hostname)) { - std::pair p - (hostname, entryPoints_.front().second); - resolvedEntryPoints_.push_back(p); - addPingTask(p); - } else if(resolveHostname(hostname, resolver_)) { - hostname = resolver_->getResolvedAddresses().front(); - std::pair p(hostname, - entryPoints_.front().second); - resolvedEntryPoints_.push_back(p); - addPingTask(p); - } else { - e_->addCommand(this); - return false; + if(util::isNumericHost(hostname)) { + ++numSuccess_; + std::pair p(hostname, + entryPoints_.front().second); + addPingTask(p); + } else { + try { + if(resolveHostname(hostname)) { + std::vector addrs; + asyncNameResolverMan_->getResolvedAddress(addrs); + if(addrs.empty()) { + A2_LOG_ERROR(fmt("No address returned for %s", + hostname.c_str())); + } else { + A2_LOG_INFO(fmt(MSG_NAME_RESOLUTION_COMPLETE, + getCuid(), hostname.c_str(), + addrs.front().c_str())); + ++numSuccess_; + std::pair p + (addrs.front(), entryPoints_.front().second); + addPingTask(p); + } + } else { + e_->addCommand(this); + return false; + } + } catch(RecoverableException& e) { + A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e); } - } catch(RecoverableException& e) { - A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e); + asyncNameResolverMan_->reset(e_, this); } - resolver_->reset(); entryPoints_.pop_front(); } } else @@ -129,9 +132,9 @@ bool DHTEntryPointNameResolveCommand::execute() std::vector addrs; res.resolve(addrs, hostname); + ++numSuccess_; std::pair p(addrs.front(), entryPoints_.front().second); - resolvedEntryPoints_.push_back(p); addPingTask(p); } catch(RecoverableException& e) { A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e); @@ -139,7 +142,7 @@ bool DHTEntryPointNameResolveCommand::execute() entryPoints_.pop_front(); } } - if(bootstrapEnabled_ && resolvedEntryPoints_.size()) { + if(bootstrapEnabled_ && numSuccess_) { taskQueue_->addPeriodicTask1(taskFactory_->createNodeLookupTask (localNode_->getID())); taskQueue_->addPeriodicTask1(taskFactory_->createBucketRefreshTask()); @@ -163,46 +166,26 @@ void DHTEntryPointNameResolveCommand::addPingTask #ifdef ENABLE_ASYNC_DNS bool DHTEntryPointNameResolveCommand::resolveHostname -(const std::string& hostname, - const SharedHandle& resolver) +(const std::string& hostname) { - switch(resolver->getStatus()) { - case AsyncNameResolver::STATUS_READY: - A2_LOG_INFO(fmt(MSG_RESOLVING_HOSTNAME, - getCuid(), - hostname.c_str())); - resolver->resolve(hostname); - setNameResolverCheck(resolver); - return false; - case AsyncNameResolver::STATUS_SUCCESS: - A2_LOG_INFO(fmt(MSG_NAME_RESOLUTION_COMPLETE, - getCuid(), - resolver->getHostname().c_str(), - resolver->getResolvedAddresses().front().c_str())); - return true; - break; - case AsyncNameResolver::STATUS_ERROR: - throw DL_ABORT_EX - (fmt(MSG_NAME_RESOLUTION_FAILED, - getCuid(), - hostname.c_str(), - resolver->getError().c_str())); - default: - return false; + if(!asyncNameResolverMan_->started()) { + asyncNameResolverMan_->startAsync(hostname, e_, this); + } else { + switch(asyncNameResolverMan_->getStatus()) { + case -1: + throw DL_ABORT_EX2 + (fmt(MSG_NAME_RESOLUTION_FAILED, getCuid(), hostname.c_str(), + asyncNameResolverMan_->getLastError().c_str()), + error_code::NAME_RESOLVE_ERROR); + case 0: + return false; + case 1: + return true; + } } + return false; } -void DHTEntryPointNameResolveCommand::setNameResolverCheck -(const SharedHandle& resolver) -{ - e_->addNameResolverCheck(resolver, this); -} - -void DHTEntryPointNameResolveCommand::disableNameResolverCheck -(const SharedHandle& resolver) -{ - e_->deleteNameResolverCheck(resolver, this); -} #endif // ENABLE_ASYNC_DNS void DHTEntryPointNameResolveCommand::setBootstrapEnabled(bool f) diff --git a/src/DHTEntryPointNameResolveCommand.h b/src/DHTEntryPointNameResolveCommand.h index 79c1b8c7..5886f981 100644 --- a/src/DHTEntryPointNameResolveCommand.h +++ b/src/DHTEntryPointNameResolveCommand.h @@ -52,7 +52,7 @@ class DHTRoutingTable; class DHTNode; class DownloadEngine; #ifdef ENABLE_ASYNC_DNS -class AsyncNameResolver; +class AsyncNameResolverMan; #endif // ENABLE_ASYNC_DNS class DHTEntryPointNameResolveCommand:public Command { @@ -60,7 +60,7 @@ private: DownloadEngine* e_; #ifdef ENABLE_ASYNC_DNS - SharedHandle resolver_; + SharedHandle asyncNameResolverMan_; #endif // ENABLE_ASYNC_DNS SharedHandle taskQueue_; @@ -73,19 +73,14 @@ private: std::deque > entryPoints_; - std::vector > resolvedEntryPoints_; + int numSuccess_; bool bootstrapEnabled_; void addPingTask(const std::pair& addr); #ifdef ENABLE_ASYNC_DNS - bool resolveHostname(const std::string& hostname, - const SharedHandle& resolver); - - void setNameResolverCheck(const SharedHandle& resolver); - - void disableNameResolverCheck(const SharedHandle& resolver); + bool resolveHostname(const std::string& hostname); #endif // ENABLE_ASYNC_DNS public: