Use AsyncNameResolverMan in DHTEntryPointNameResolveCommand

pull/60/head
Tatsuhiro Tsujikawa 2013-04-01 01:24:18 +09:00
parent 597e1a5c1b
commit b5a6c39262
5 changed files with 93 additions and 91 deletions

View File

@ -107,13 +107,7 @@ AbstractCommand::AbstractCommand
requestGroup_->increaseStreamCommand(); requestGroup_->increaseStreamCommand();
requestGroup_->increaseNumCommand(); requestGroup_->increaseNumCommand();
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
if(!net::getIPv4AddrConfigured()) { configureAsyncNameResolverMan(asyncNameResolverMan_.get(), e_->getOption());
asyncNameResolverMan_->setIPv4(false);
}
if(!net::getIPv6AddrConfigured() ||
e_->getOption()->getAsBool(PREF_DISABLE_IPV6)) {
asyncNameResolverMan_->setIPv6(false);
}
#endif // ENABLE_ASYNC_DNS #endif // ENABLE_ASYNC_DNS
} }

View File

@ -39,6 +39,9 @@
#include "message.h" #include "message.h"
#include "fmt.h" #include "fmt.h"
#include "LogFactory.h" #include "LogFactory.h"
#include "Option.h"
#include "SocketCore.h"
#include "prefs.h"
namespace aria2 { namespace aria2 {
@ -186,5 +189,26 @@ const std::string& AsyncNameResolverMan::getLastError() const
return A2STR::NIL; 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

View File

@ -47,6 +47,7 @@ namespace aria2 {
class AsyncNameResolver; class AsyncNameResolver;
class DownloadEngine; class DownloadEngine;
class Command; class Command;
class Option;
class AsyncNameResolverMan { class AsyncNameResolverMan {
public: public:
@ -85,6 +86,8 @@ public:
int getStatus() const; int getStatus() const;
// Returns last error string // Returns last error string
const std::string& getLastError() const; const std::string& getLastError() const;
// Resets state. Also removes resolvers from DownloadEngine.
void reset(DownloadEngine* e, Command* command);
private: private:
void startAsyncFamily(const std::string& hostname, void startAsyncFamily(const std::string& hostname,
int family, int family,
@ -101,6 +104,9 @@ private:
bool ipv6_; bool ipv6_;
}; };
void configureAsyncNameResolverMan(AsyncNameResolverMan* asyncNameResolverMan,
Option* option);
} // namespace aria2 } // namespace aria2
#endif // D_ASYNC_NAME_RESOLVER_MAN_H #endif // D_ASYNC_NAME_RESOLVER_MAN_H

View File

@ -49,8 +49,9 @@
#include "Logger.h" #include "Logger.h"
#include "LogFactory.h" #include "LogFactory.h"
#include "fmt.h" #include "fmt.h"
#include "SocketCore.h"
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
#include "AsyncNameResolver.h" #include "AsyncNameResolverMan.h"
#endif // ENABLE_ASYNC_DNS #endif // ENABLE_ASYNC_DNS
namespace aria2 { namespace aria2 {
@ -60,14 +61,20 @@ DHTEntryPointNameResolveCommand::DHTEntryPointNameResolveCommand
const std::vector<std::pair<std::string, uint16_t> >& entryPoints): const std::vector<std::pair<std::string, uint16_t> >& entryPoints):
Command(cuid), Command(cuid),
e_(e), e_(e),
asyncNameResolverMan_(new AsyncNameResolverMan()),
entryPoints_(entryPoints.begin(), entryPoints.end()), entryPoints_(entryPoints.begin(), entryPoints.end()),
numSuccess_(0),
bootstrapEnabled_(false) bootstrapEnabled_(false)
{} {
#ifdef ENABLE_ASYNC_DNS
configureAsyncNameResolverMan(asyncNameResolverMan_.get(), e_->getOption());
#endif // ENABLE_ASYNC_DNS
}
DHTEntryPointNameResolveCommand::~DHTEntryPointNameResolveCommand() DHTEntryPointNameResolveCommand::~DHTEntryPointNameResolveCommand()
{ {
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
disableNameResolverCheck(resolver_); asyncNameResolverMan_->disableNameResolverCheck(e_, this);
#endif // ENABLE_ASYNC_DNS #endif // ENABLE_ASYNC_DNS
} }
@ -76,46 +83,42 @@ bool DHTEntryPointNameResolveCommand::execute()
if(e_->getRequestGroupMan()->downloadFinished() || e_->isHaltRequested()) { if(e_->getRequestGroupMan()->downloadFinished() || e_->isHaltRequested()) {
return true; 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 { try {
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
if(e_->getOption()->getAsBool(PREF_ASYNC_DNS)) { if(e_->getOption()->getAsBool(PREF_ASYNC_DNS)) {
while(!entryPoints_.empty()) { while(!entryPoints_.empty()) {
std::string hostname = entryPoints_.front().first; std::string hostname = entryPoints_.front().first;
try { if(util::isNumericHost(hostname)) {
if(util::isNumericHost(hostname)) { ++numSuccess_;
std::pair<std::string, uint16_t> p std::pair<std::string, uint16_t> p(hostname,
(hostname, entryPoints_.front().second); entryPoints_.front().second);
resolvedEntryPoints_.push_back(p); addPingTask(p);
addPingTask(p); } else {
} else if(resolveHostname(hostname, resolver_)) { try {
hostname = resolver_->getResolvedAddresses().front(); if(resolveHostname(hostname)) {
std::pair<std::string, uint16_t> p(hostname, std::vector<std::string> addrs;
entryPoints_.front().second); asyncNameResolverMan_->getResolvedAddress(addrs);
resolvedEntryPoints_.push_back(p); if(addrs.empty()) {
addPingTask(p); A2_LOG_ERROR(fmt("No address returned for %s",
} else { hostname.c_str()));
e_->addCommand(this); } else {
return false; A2_LOG_INFO(fmt(MSG_NAME_RESOLUTION_COMPLETE,
getCuid(), hostname.c_str(),
addrs.front().c_str()));
++numSuccess_;
std::pair<std::string, uint16_t> 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) { asyncNameResolverMan_->reset(e_, this);
A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e);
} }
resolver_->reset();
entryPoints_.pop_front(); entryPoints_.pop_front();
} }
} else } else
@ -129,9 +132,9 @@ bool DHTEntryPointNameResolveCommand::execute()
std::vector<std::string> addrs; std::vector<std::string> addrs;
res.resolve(addrs, hostname); res.resolve(addrs, hostname);
++numSuccess_;
std::pair<std::string, uint16_t> p(addrs.front(), std::pair<std::string, uint16_t> p(addrs.front(),
entryPoints_.front().second); entryPoints_.front().second);
resolvedEntryPoints_.push_back(p);
addPingTask(p); addPingTask(p);
} catch(RecoverableException& e) { } catch(RecoverableException& e) {
A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e); A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e);
@ -139,7 +142,7 @@ bool DHTEntryPointNameResolveCommand::execute()
entryPoints_.pop_front(); entryPoints_.pop_front();
} }
} }
if(bootstrapEnabled_ && resolvedEntryPoints_.size()) { if(bootstrapEnabled_ && numSuccess_) {
taskQueue_->addPeriodicTask1(taskFactory_->createNodeLookupTask taskQueue_->addPeriodicTask1(taskFactory_->createNodeLookupTask
(localNode_->getID())); (localNode_->getID()));
taskQueue_->addPeriodicTask1(taskFactory_->createBucketRefreshTask()); taskQueue_->addPeriodicTask1(taskFactory_->createBucketRefreshTask());
@ -163,46 +166,26 @@ void DHTEntryPointNameResolveCommand::addPingTask
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
bool DHTEntryPointNameResolveCommand::resolveHostname bool DHTEntryPointNameResolveCommand::resolveHostname
(const std::string& hostname, (const std::string& hostname)
const SharedHandle<AsyncNameResolver>& resolver)
{ {
switch(resolver->getStatus()) { if(!asyncNameResolverMan_->started()) {
case AsyncNameResolver::STATUS_READY: asyncNameResolverMan_->startAsync(hostname, e_, this);
A2_LOG_INFO(fmt(MSG_RESOLVING_HOSTNAME, } else {
getCuid(), switch(asyncNameResolverMan_->getStatus()) {
hostname.c_str())); case -1:
resolver->resolve(hostname); throw DL_ABORT_EX2
setNameResolverCheck(resolver); (fmt(MSG_NAME_RESOLUTION_FAILED, getCuid(), hostname.c_str(),
return false; asyncNameResolverMan_->getLastError().c_str()),
case AsyncNameResolver::STATUS_SUCCESS: error_code::NAME_RESOLVE_ERROR);
A2_LOG_INFO(fmt(MSG_NAME_RESOLUTION_COMPLETE, case 0:
getCuid(), return false;
resolver->getHostname().c_str(), case 1:
resolver->getResolvedAddresses().front().c_str())); return true;
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;
} }
return false;
} }
void DHTEntryPointNameResolveCommand::setNameResolverCheck
(const SharedHandle<AsyncNameResolver>& resolver)
{
e_->addNameResolverCheck(resolver, this);
}
void DHTEntryPointNameResolveCommand::disableNameResolverCheck
(const SharedHandle<AsyncNameResolver>& resolver)
{
e_->deleteNameResolverCheck(resolver, this);
}
#endif // ENABLE_ASYNC_DNS #endif // ENABLE_ASYNC_DNS
void DHTEntryPointNameResolveCommand::setBootstrapEnabled(bool f) void DHTEntryPointNameResolveCommand::setBootstrapEnabled(bool f)

View File

@ -52,7 +52,7 @@ class DHTRoutingTable;
class DHTNode; class DHTNode;
class DownloadEngine; class DownloadEngine;
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
class AsyncNameResolver; class AsyncNameResolverMan;
#endif // ENABLE_ASYNC_DNS #endif // ENABLE_ASYNC_DNS
class DHTEntryPointNameResolveCommand:public Command { class DHTEntryPointNameResolveCommand:public Command {
@ -60,7 +60,7 @@ private:
DownloadEngine* e_; DownloadEngine* e_;
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
SharedHandle<AsyncNameResolver> resolver_; SharedHandle<AsyncNameResolverMan> asyncNameResolverMan_;
#endif // ENABLE_ASYNC_DNS #endif // ENABLE_ASYNC_DNS
SharedHandle<DHTTaskQueue> taskQueue_; SharedHandle<DHTTaskQueue> taskQueue_;
@ -73,19 +73,14 @@ private:
std::deque<std::pair<std::string, uint16_t> > entryPoints_; std::deque<std::pair<std::string, uint16_t> > entryPoints_;
std::vector<std::pair<std::string, uint16_t> > resolvedEntryPoints_; int numSuccess_;
bool bootstrapEnabled_; bool bootstrapEnabled_;
void addPingTask(const std::pair<std::string, uint16_t>& addr); void addPingTask(const std::pair<std::string, uint16_t>& addr);
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
bool resolveHostname(const std::string& hostname, bool resolveHostname(const std::string& hostname);
const SharedHandle<AsyncNameResolver>& resolver);
void setNameResolverCheck(const SharedHandle<AsyncNameResolver>& resolver);
void disableNameResolverCheck(const SharedHandle<AsyncNameResolver>& resolver);
#endif // ENABLE_ASYNC_DNS #endif // ENABLE_ASYNC_DNS
public: public: