mirror of https://github.com/aria2/aria2
Added --async-dns-server option.
This option accepts comma separated list of DNS server address used in asynchronous DNS resolver. Usually asynchronous DNS resolver reads DNS server addresses from /etc/resolv.conf. When this option is used, it uses DNS servers specified in this option instead of ones in /etc/resolv.conf. You can specify both IPv4 and IPv6 address. This option is useful when the system does not have /etc/resolv.conf and user does not have the permission to create it.pull/1/head
parent
cf546810e4
commit
f0682a98c0
|
@ -650,7 +650,8 @@ void AbstractCommand::initAsyncNameResolver(const std::string& hostname)
|
||||||
} else {
|
} else {
|
||||||
family = AF_INET;
|
family = AF_INET;
|
||||||
}
|
}
|
||||||
asyncNameResolver_.reset(new AsyncNameResolver(family));
|
asyncNameResolver_.reset
|
||||||
|
(new AsyncNameResolver(family, e_->getAsyncDNSServers()));
|
||||||
A2_LOG_INFO(fmt(MSG_RESOLVING_HOSTNAME,
|
A2_LOG_INFO(fmt(MSG_RESOLVING_HOSTNAME,
|
||||||
getCuid(),
|
getCuid(),
|
||||||
hostname.c_str()));
|
hostname.c_str()));
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "A2STR.h"
|
#include "A2STR.h"
|
||||||
|
#include "LogFactory.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -77,12 +78,18 @@ void callback(void* arg, int status, int timeouts, struct hostent* host)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncNameResolver::AsyncNameResolver(int family):
|
AsyncNameResolver::AsyncNameResolver(int family, ares_addr_node* servers):
|
||||||
status_(STATUS_READY),
|
status_(STATUS_READY),
|
||||||
family_(family)
|
family_(family)
|
||||||
{
|
{
|
||||||
// TODO evaluate return value
|
// TODO evaluate return value
|
||||||
ares_init(&channel_);
|
ares_init(&channel_);
|
||||||
|
if(servers) {
|
||||||
|
// ares_set_servers has been added since c-ares 1.7.1
|
||||||
|
if(ares_set_servers(channel_, servers) != ARES_SUCCESS) {
|
||||||
|
A2_LOG_DEBUG("ares_set_servers failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncNameResolver::~AsyncNameResolver()
|
AsyncNameResolver::~AsyncNameResolver()
|
||||||
|
|
|
@ -70,7 +70,7 @@ private:
|
||||||
std::string error_;
|
std::string error_;
|
||||||
std::string hostname_;
|
std::string hostname_;
|
||||||
public:
|
public:
|
||||||
AsyncNameResolver(int family);
|
AsyncNameResolver(int family, ares_addr_node* servers);
|
||||||
|
|
||||||
~AsyncNameResolver();
|
~AsyncNameResolver();
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ bool DHTEntryPointNameResolveCommand::execute()
|
||||||
} else {
|
} else {
|
||||||
family = AF_INET;
|
family = AF_INET;
|
||||||
}
|
}
|
||||||
resolver_.reset(new AsyncNameResolver(family));
|
resolver_.reset(new AsyncNameResolver(family, e_->getAsyncDNSServers()));
|
||||||
}
|
}
|
||||||
#endif // ENABLE_ASYNC_DNS
|
#endif // ENABLE_ASYNC_DNS
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -95,6 +95,9 @@ DownloadEngine::DownloadEngine(const SharedHandle<EventPoll>& eventPoll)
|
||||||
#ifdef ENABLE_BITTORRENT
|
#ifdef ENABLE_BITTORRENT
|
||||||
btRegistry_(new BtRegistry()),
|
btRegistry_(new BtRegistry()),
|
||||||
#endif // ENABLE_BITTORRENT
|
#endif // ENABLE_BITTORRENT
|
||||||
|
#ifdef ENABLE_ASYNC_DNS
|
||||||
|
asyncDNSServers_(0),
|
||||||
|
#endif // ENABLE_ASYNC_DNS
|
||||||
dnsCache_(new DNSCache())
|
dnsCache_(new DNSCache())
|
||||||
{
|
{
|
||||||
unsigned char sessionId[20];
|
unsigned char sessionId[20];
|
||||||
|
@ -104,6 +107,7 @@ DownloadEngine::DownloadEngine(const SharedHandle<EventPoll>& eventPoll)
|
||||||
|
|
||||||
DownloadEngine::~DownloadEngine() {
|
DownloadEngine::~DownloadEngine() {
|
||||||
cleanQueue();
|
cleanQueue();
|
||||||
|
setAsyncDNSServers(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadEngine::cleanQueue() {
|
void DownloadEngine::cleanQueue() {
|
||||||
|
@ -560,4 +564,15 @@ void DownloadEngine::setCheckIntegrityMan
|
||||||
checkIntegrityMan_ = ciman;
|
checkIntegrityMan_ = ciman;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DownloadEngine::setAsyncDNSServers(ares_addr_node* asyncDNSServers)
|
||||||
|
{
|
||||||
|
ares_addr_node* node = asyncDNSServers_;
|
||||||
|
while(node) {
|
||||||
|
ares_addr_node* next = node->next;
|
||||||
|
delete node;
|
||||||
|
node = next;
|
||||||
|
}
|
||||||
|
asyncDNSServers_ = asyncDNSServers;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -135,6 +135,10 @@ private:
|
||||||
|
|
||||||
CUIDCounter cuidCounter_;
|
CUIDCounter cuidCounter_;
|
||||||
|
|
||||||
|
#ifdef ENABLE_ASYNC_DNS
|
||||||
|
ares_addr_node* asyncDNSServers_;
|
||||||
|
#endif // ENABLE_ASYNC_DNS
|
||||||
|
|
||||||
SharedHandle<DNSCache> dnsCache_;
|
SharedHandle<DNSCache> dnsCache_;
|
||||||
|
|
||||||
SharedHandle<AuthConfigFactory> authConfigFactory_;
|
SharedHandle<AuthConfigFactory> authConfigFactory_;
|
||||||
|
@ -326,6 +330,13 @@ public:
|
||||||
{
|
{
|
||||||
return sessionId_;
|
return sessionId_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setAsyncDNSServers(ares_addr_node* asyncDNSServers);
|
||||||
|
|
||||||
|
ares_addr_node* getAsyncDNSServers() const
|
||||||
|
{
|
||||||
|
return asyncDNSServers_;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef SharedHandle<DownloadEngine> DownloadEngineHandle;
|
typedef SharedHandle<DownloadEngine> DownloadEngineHandle;
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
#include "RequestGroupMan.h"
|
#include "RequestGroupMan.h"
|
||||||
|
@ -90,6 +91,50 @@ void handler(int signal) {
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
ares_addr_node* parseAsyncDNSServers(const std::string& serversOpt)
|
||||||
|
{
|
||||||
|
std::vector<std::string> servers;
|
||||||
|
util::split(serversOpt,
|
||||||
|
std::back_inserter(servers),
|
||||||
|
A2STR::COMMA_C,
|
||||||
|
true /* doStrip */);
|
||||||
|
ares_addr_node root;
|
||||||
|
root.next = 0;
|
||||||
|
ares_addr_node* tail = &root;
|
||||||
|
for(std::vector<std::string>::const_iterator i = servers.begin(),
|
||||||
|
eoi = servers.end(); i != eoi; ++i) {
|
||||||
|
struct addrinfo* res;
|
||||||
|
int s = callGetaddrinfo(&res, (*i).c_str(), 0, AF_UNSPEC,
|
||||||
|
0, AI_NUMERICHOST, 0);
|
||||||
|
if(s != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
WSAAPI_AUTO_DELETE<struct addrinfo*> resDeleter(res, freeaddrinfo);
|
||||||
|
if(res) {
|
||||||
|
ares_addr_node* node = new ares_addr_node();
|
||||||
|
node->next = 0;
|
||||||
|
node->family = res->ai_family;
|
||||||
|
if(node->family == AF_INET) {
|
||||||
|
struct sockaddr_in* in =
|
||||||
|
reinterpret_cast<struct sockaddr_in*>(res->ai_addr);
|
||||||
|
memcpy(&node->addr.addr4, &(in->sin_addr), 4);
|
||||||
|
} else {
|
||||||
|
struct sockaddr_in6* in =
|
||||||
|
reinterpret_cast<struct sockaddr_in6*>(res->ai_addr);
|
||||||
|
memcpy(&node->addr.addr6, &(in->sin6_addr), 16);
|
||||||
|
}
|
||||||
|
tail->next = node;
|
||||||
|
tail = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
MultiUrlRequestInfo::MultiUrlRequestInfo
|
MultiUrlRequestInfo::MultiUrlRequestInfo
|
||||||
(const std::vector<SharedHandle<RequestGroup> >& requestGroups,
|
(const std::vector<SharedHandle<RequestGroup> >& requestGroups,
|
||||||
const SharedHandle<Option>& op,
|
const SharedHandle<Option>& op,
|
||||||
|
@ -170,6 +215,10 @@ error_code::Value MultiUrlRequestInfo::execute()
|
||||||
}
|
}
|
||||||
SocketCore::setTLSContext(tlsContext);
|
SocketCore::setTLSContext(tlsContext);
|
||||||
#endif
|
#endif
|
||||||
|
ares_addr_node* asyncDNSServers =
|
||||||
|
parseAsyncDNSServers(option_->get(PREF_ASYNC_DNS_SERVER));
|
||||||
|
e->setAsyncDNSServers(asyncDNSServers);
|
||||||
|
|
||||||
if(!Timer::monotonicClock()) {
|
if(!Timer::monotonicClock()) {
|
||||||
A2_LOG_WARN("Don't change system time while aria2c is running."
|
A2_LOG_WARN("Don't change system time while aria2c is running."
|
||||||
" Doing this may make aria2c hang for long time.");
|
" Doing this may make aria2c hang for long time.");
|
||||||
|
|
|
@ -205,6 +205,14 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
|
||||||
op->addTag(TAG_ADVANCED);
|
op->addTag(TAG_ADVANCED);
|
||||||
handlers.push_back(op);
|
handlers.push_back(op);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
SharedHandle<OptionHandler> op(new DefaultOptionHandler
|
||||||
|
(PREF_ASYNC_DNS_SERVER,
|
||||||
|
TEXT_ASYNC_DNS_SERVER,
|
||||||
|
NO_DEFAULT_VALUE));
|
||||||
|
op->addTag(TAG_ADVANCED);
|
||||||
|
handlers.push_back(op);
|
||||||
|
}
|
||||||
#endif // ENABLE_ASYNC_DNS
|
#endif // ENABLE_ASYNC_DNS
|
||||||
#ifdef ENABLE_DIRECT_IO
|
#ifdef ENABLE_DIRECT_IO
|
||||||
{
|
{
|
||||||
|
|
|
@ -204,6 +204,8 @@ const std::string PREF_ENABLE_ASYNC_DNS6("enable-async-dns6");
|
||||||
const std::string PREF_MAX_DOWNLOAD_RESULT("max-download-result");
|
const std::string PREF_MAX_DOWNLOAD_RESULT("max-download-result");
|
||||||
// value: 1*digit
|
// value: 1*digit
|
||||||
const std::string PREF_RETRY_WAIT("retry-wait");
|
const std::string PREF_RETRY_WAIT("retry-wait");
|
||||||
|
// value: string
|
||||||
|
const std::string PREF_ASYNC_DNS_SERVER("async-dns-server");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FTP related preferences
|
* FTP related preferences
|
||||||
|
|
|
@ -208,6 +208,8 @@ extern const std::string PREF_ENABLE_ASYNC_DNS6;
|
||||||
extern const std::string PREF_MAX_DOWNLOAD_RESULT;
|
extern const std::string PREF_MAX_DOWNLOAD_RESULT;
|
||||||
// value: 1*digit
|
// value: 1*digit
|
||||||
extern const std::string PREF_RETRY_WAIT;
|
extern const std::string PREF_RETRY_WAIT;
|
||||||
|
// value: string
|
||||||
|
extern const std::string PREF_ASYNC_DNS_SERVER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FTP related preferences
|
* FTP related preferences
|
||||||
|
|
|
@ -753,3 +753,14 @@
|
||||||
" option may result high memory consumption after\n" \
|
" option may result high memory consumption after\n" \
|
||||||
" thousands of downloads. Specifying 0 means no\n" \
|
" thousands of downloads. Specifying 0 means no\n" \
|
||||||
" download result is kept.")
|
" download result is kept.")
|
||||||
|
#define TEXT_ASYNC_DNS_SERVER \
|
||||||
|
_(" --async-dns-server=IPADDRESS[,...] Comma separated list of DNS server address\n" \
|
||||||
|
" used in asynchronous DNS resolver. Usually\n" \
|
||||||
|
" asynchronous DNS resolver reads DNS server\n" \
|
||||||
|
" addresses from /etc/resolv.conf. When this option\n" \
|
||||||
|
" is used, it uses DNS servers specified in this\n" \
|
||||||
|
" option instead of ones in /etc/resolv.conf. You\n" \
|
||||||
|
" can specify both IPv4 and IPv6 address. This\n" \
|
||||||
|
" option is useful when the system does not have\n" \
|
||||||
|
" /etc/resolv.conf and user does not have the\n" \
|
||||||
|
" permission to create it.")
|
||||||
|
|
Loading…
Reference in New Issue