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_->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
}

View File

@ -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

View File

@ -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

View File

@ -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<std::pair<std::string, uint16_t> >& 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<std::string, uint16_t> p
(hostname, entryPoints_.front().second);
resolvedEntryPoints_.push_back(p);
addPingTask(p);
} else if(resolveHostname(hostname, resolver_)) {
hostname = resolver_->getResolvedAddresses().front();
std::pair<std::string, uint16_t> p(hostname,
entryPoints_.front().second);
resolvedEntryPoints_.push_back(p);
addPingTask(p);
} else {
e_->addCommand(this);
return false;
if(util::isNumericHost(hostname)) {
++numSuccess_;
std::pair<std::string, uint16_t> p(hostname,
entryPoints_.front().second);
addPingTask(p);
} else {
try {
if(resolveHostname(hostname)) {
std::vector<std::string> 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<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) {
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<std::string> addrs;
res.resolve(addrs, hostname);
++numSuccess_;
std::pair<std::string, uint16_t> 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<AsyncNameResolver>& 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<AsyncNameResolver>& resolver)
{
e_->addNameResolverCheck(resolver, this);
}
void DHTEntryPointNameResolveCommand::disableNameResolverCheck
(const SharedHandle<AsyncNameResolver>& resolver)
{
e_->deleteNameResolverCheck(resolver, this);
}
#endif // ENABLE_ASYNC_DNS
void DHTEntryPointNameResolveCommand::setBootstrapEnabled(bool f)

View File

@ -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<AsyncNameResolver> resolver_;
SharedHandle<AsyncNameResolverMan> asyncNameResolverMan_;
#endif // ENABLE_ASYNC_DNS
SharedHandle<DHTTaskQueue> taskQueue_;
@ -73,19 +73,14 @@ private:
std::deque<std::pair<std::string, uint16_t> > entryPoints_;
std::vector<std::pair<std::string, uint16_t> > resolvedEntryPoints_;
int numSuccess_;
bool bootstrapEnabled_;
void addPingTask(const std::pair<std::string, uint16_t>& addr);
#ifdef ENABLE_ASYNC_DNS
bool resolveHostname(const std::string& hostname,
const SharedHandle<AsyncNameResolver>& resolver);
void setNameResolverCheck(const SharedHandle<AsyncNameResolver>& resolver);
void disableNameResolverCheck(const SharedHandle<AsyncNameResolver>& resolver);
bool resolveHostname(const std::string& hostname);
#endif // ENABLE_ASYNC_DNS
public: