mirror of https://github.com/aria2/aria2
Merge branch 'aria2:master' into master
commit
00627619bd
|
@ -18,7 +18,7 @@ jobs:
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: Build
|
- name: Build
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
file: Dockerfile.android
|
file: Dockerfile.android
|
||||||
context: .
|
context: .
|
||||||
|
|
|
@ -28,12 +28,12 @@ jobs:
|
||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-22.04, macos-11]
|
os: [ubuntu-22.04, macos-14]
|
||||||
compiler: [gcc, clang]
|
compiler: [gcc, clang]
|
||||||
crypto: [openssl, gnutls]
|
crypto: [openssl, gnutls]
|
||||||
bittorrent: [with-bt, without-bt]
|
bittorrent: [with-bt, without-bt]
|
||||||
exclude:
|
exclude:
|
||||||
- os: macos-11
|
- os: macos-14
|
||||||
crypto: gnutls
|
crypto: gnutls
|
||||||
- crypto: openssl
|
- crypto: openssl
|
||||||
bittorrent: without-bt
|
bittorrent: without-bt
|
||||||
|
|
10
configure.ac
10
configure.ac
|
@ -503,18 +503,10 @@ fi
|
||||||
|
|
||||||
have_libcares=no
|
have_libcares=no
|
||||||
if test "x$with_libcares" = "xyes"; then
|
if test "x$with_libcares" = "xyes"; then
|
||||||
PKG_CHECK_MODULES([LIBCARES], [libcares >= 1.7.0], [have_libcares=yes],
|
PKG_CHECK_MODULES([LIBCARES], [libcares >= 1.16.0], [have_libcares=yes],
|
||||||
[have_libcares=no])
|
[have_libcares=no])
|
||||||
if test "x$have_libcares" = "xyes"; then
|
if test "x$have_libcares" = "xyes"; then
|
||||||
AC_DEFINE([HAVE_LIBCARES], [1], [Define to 1 if you have libcares.])
|
AC_DEFINE([HAVE_LIBCARES], [1], [Define to 1 if you have libcares.])
|
||||||
save_LIBS=$LIBS
|
|
||||||
save_CPPFLAGS=$CPPFLAGS
|
|
||||||
LIBS="$LIBCARES_LIBS $LIBS"
|
|
||||||
CPPFLAGS="$LIBCARES_CFLAGS $CPPFLAGS"
|
|
||||||
AC_CHECK_TYPES([ares_addr_node], [], [], [[#include <ares.h>]])
|
|
||||||
AC_CHECK_FUNCS([ares_set_servers])
|
|
||||||
LIBS=$save_LIBS
|
|
||||||
CPPFLAGS=$save_CPPFLAGS
|
|
||||||
|
|
||||||
# -DCARES_STATICLIB is appended by pkg-config file libcares.pc
|
# -DCARES_STATICLIB is appended by pkg-config file libcares.pc
|
||||||
else
|
else
|
||||||
|
|
|
@ -40,10 +40,11 @@
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
#include "SocketCore.h"
|
#include "SocketCore.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "EventPoll.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
void callback(void* arg, int status, int timeouts, struct hostent* host)
|
void callback(void* arg, int status, int timeouts, ares_addrinfo* result)
|
||||||
{
|
{
|
||||||
AsyncNameResolver* resolverPtr = reinterpret_cast<AsyncNameResolver*>(arg);
|
AsyncNameResolver* resolverPtr = reinterpret_cast<AsyncNameResolver*>(arg);
|
||||||
if (status != ARES_SUCCESS) {
|
if (status != ARES_SUCCESS) {
|
||||||
|
@ -51,12 +52,15 @@ void callback(void* arg, int status, int timeouts, struct hostent* host)
|
||||||
resolverPtr->status_ = AsyncNameResolver::STATUS_ERROR;
|
resolverPtr->status_ = AsyncNameResolver::STATUS_ERROR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (char** ap = host->h_addr_list; *ap; ++ap) {
|
for (auto ap = result->nodes; ap; ap = ap->ai_next) {
|
||||||
char addrstring[NI_MAXHOST];
|
char addrstring[NI_MAXHOST];
|
||||||
if (inetNtop(host->h_addrtype, *ap, addrstring, sizeof(addrstring)) == 0) {
|
auto rv = getnameinfo(ap->ai_addr, ap->ai_addrlen, addrstring,
|
||||||
|
sizeof(addrstring), nullptr, 0, NI_NUMERICHOST);
|
||||||
|
if (rv == 0) {
|
||||||
resolverPtr->resolvedAddresses_.push_back(addrstring);
|
resolverPtr->resolvedAddresses_.push_back(addrstring);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ares_freeaddrinfo(result);
|
||||||
if (resolverPtr->resolvedAddresses_.empty()) {
|
if (resolverPtr->resolvedAddresses_.empty()) {
|
||||||
resolverPtr->error_ = "no address returned or address conversion failed";
|
resolverPtr->error_ = "no address returned or address conversion failed";
|
||||||
resolverPtr->status_ = AsyncNameResolver::STATUS_ERROR;
|
resolverPtr->status_ = AsyncNameResolver::STATUS_ERROR;
|
||||||
|
@ -66,24 +70,63 @@ void callback(void* arg, int status, int timeouts, struct hostent* host)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncNameResolver::AsyncNameResolver(int family
|
namespace {
|
||||||
#ifdef HAVE_ARES_ADDR_NODE
|
void sock_state_cb(void* arg, ares_socket_t fd, int read, int write)
|
||||||
,
|
{
|
||||||
ares_addr_node* servers
|
auto resolver = static_cast<AsyncNameResolver*>(arg);
|
||||||
#endif // HAVE_ARES_ADDR_NODE
|
|
||||||
)
|
resolver->handle_sock_state(fd, read, write);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void AsyncNameResolver::handle_sock_state(ares_socket_t fd, int read, int write)
|
||||||
|
{
|
||||||
|
int events = 0;
|
||||||
|
|
||||||
|
if (read) {
|
||||||
|
events |= EventPoll::EVENT_READ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write) {
|
||||||
|
events |= EventPoll::EVENT_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = std::find_if(
|
||||||
|
std::begin(socks_), std::end(socks_),
|
||||||
|
[fd](const AsyncNameResolverSocketEntry& ent) { return ent.fd == fd; });
|
||||||
|
if (it == std::end(socks_)) {
|
||||||
|
if (!events) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
socks_.emplace_back(AsyncNameResolverSocketEntry{fd, events});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!events) {
|
||||||
|
socks_.erase(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*it).events = events;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncNameResolver::AsyncNameResolver(int family, const std::string& servers)
|
||||||
: status_(STATUS_READY), family_(family)
|
: status_(STATUS_READY), family_(family)
|
||||||
{
|
{
|
||||||
|
ares_options opts{};
|
||||||
|
opts.sock_state_cb = sock_state_cb;
|
||||||
|
opts.sock_state_cb_data = this;
|
||||||
|
|
||||||
// TODO evaluate return value
|
// TODO evaluate return value
|
||||||
ares_init(&channel_);
|
ares_init_options(&channel_, &opts, ARES_OPT_SOCK_STATE_CB);
|
||||||
#if defined(HAVE_ARES_SET_SERVERS) && defined(HAVE_ARES_ADDR_NODE)
|
|
||||||
if (servers) {
|
if (!servers.empty()) {
|
||||||
// ares_set_servers has been added since c-ares 1.7.1
|
if (ares_set_servers_csv(channel_, servers.c_str()) != ARES_SUCCESS) {
|
||||||
if (ares_set_servers(channel_, servers) != ARES_SUCCESS) {
|
A2_LOG_DEBUG("ares_set_servers_csv failed");
|
||||||
A2_LOG_DEBUG("ares_set_servers failed");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // HAVE_ARES_SET_SERVERS && HAVE_ARES_ADDR_NODE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncNameResolver::~AsyncNameResolver() { ares_destroy(channel_); }
|
AsyncNameResolver::~AsyncNameResolver() { ares_destroy(channel_); }
|
||||||
|
@ -92,25 +135,58 @@ void AsyncNameResolver::resolve(const std::string& name)
|
||||||
{
|
{
|
||||||
hostname_ = name;
|
hostname_ = name;
|
||||||
status_ = STATUS_QUERYING;
|
status_ = STATUS_QUERYING;
|
||||||
ares_gethostbyname(channel_, name.c_str(), family_, callback, this);
|
|
||||||
|
ares_addrinfo_hints hints{};
|
||||||
|
hints.ai_family = family_;
|
||||||
|
|
||||||
|
ares_getaddrinfo(channel_, name.c_str(), nullptr, &hints, callback, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AsyncNameResolver::getFds(fd_set* rfdsPtr, fd_set* wfdsPtr) const
|
ares_socket_t AsyncNameResolver::getFds(fd_set* rfdsPtr, fd_set* wfdsPtr) const
|
||||||
{
|
{
|
||||||
return ares_fds(channel_, rfdsPtr, wfdsPtr);
|
ares_socket_t nfds = 0;
|
||||||
|
|
||||||
|
for (const auto& ent : socks_) {
|
||||||
|
if (ent.events & EventPoll::EVENT_READ) {
|
||||||
|
FD_SET(ent.fd, rfdsPtr);
|
||||||
|
nfds = std::max(nfds, ent.fd + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ent.events & EventPoll::EVENT_WRITE) {
|
||||||
|
FD_SET(ent.fd, wfdsPtr);
|
||||||
|
nfds = std::max(nfds, ent.fd + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nfds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncNameResolver::process(fd_set* rfdsPtr, fd_set* wfdsPtr)
|
void AsyncNameResolver::process(fd_set* rfdsPtr, fd_set* wfdsPtr)
|
||||||
{
|
{
|
||||||
ares_process(channel_, rfdsPtr, wfdsPtr);
|
for (const auto& ent : socks_) {
|
||||||
|
ares_socket_t readfd = ARES_SOCKET_BAD;
|
||||||
|
ares_socket_t writefd = ARES_SOCKET_BAD;
|
||||||
|
|
||||||
|
if (FD_ISSET(ent.fd, rfdsPtr) && (ent.events & EventPoll::EVENT_READ)) {
|
||||||
|
readfd = ent.fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FD_ISSET(ent.fd, wfdsPtr) && (ent.events & EventPoll::EVENT_WRITE)) {
|
||||||
|
writefd = ent.fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readfd != ARES_SOCKET_BAD || writefd != ARES_SOCKET_BAD) {
|
||||||
|
process(readfd, writefd);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBCARES
|
#ifdef HAVE_LIBCARES
|
||||||
|
|
||||||
int AsyncNameResolver::getsock(sock_t* sockets) const
|
const std::vector<AsyncNameResolverSocketEntry>&
|
||||||
|
AsyncNameResolver::getsock() const
|
||||||
{
|
{
|
||||||
return ares_getsock(channel_, reinterpret_cast<ares_socket_t*>(sockets),
|
return socks_;
|
||||||
ARES_GETSOCK_MAXNUM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncNameResolver::process(ares_socket_t readfd, ares_socket_t writefd)
|
void AsyncNameResolver::process(ares_socket_t readfd, ares_socket_t writefd)
|
||||||
|
@ -125,41 +201,4 @@ bool AsyncNameResolver::operator==(const AsyncNameResolver& resolver) const
|
||||||
return this == &resolver;
|
return this == &resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncNameResolver::reset()
|
|
||||||
{
|
|
||||||
hostname_ = A2STR::NIL;
|
|
||||||
resolvedAddresses_.clear();
|
|
||||||
status_ = STATUS_READY;
|
|
||||||
ares_destroy(channel_);
|
|
||||||
// TODO evaluate return value
|
|
||||||
ares_init(&channel_);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_ARES_ADDR_NODE
|
|
||||||
|
|
||||||
ares_addr_node* parseAsyncDNSServers(const std::string& serversOpt)
|
|
||||||
{
|
|
||||||
std::vector<std::string> servers;
|
|
||||||
util::split(std::begin(serversOpt), std::end(serversOpt),
|
|
||||||
std::back_inserter(servers), ',', true /* doStrip */);
|
|
||||||
ares_addr_node root;
|
|
||||||
root.next = nullptr;
|
|
||||||
ares_addr_node* tail = &root;
|
|
||||||
for (const auto& s : servers) {
|
|
||||||
auto node = make_unique<ares_addr_node>();
|
|
||||||
|
|
||||||
size_t len = net::getBinAddr(&node->addr, s.c_str());
|
|
||||||
if (len != 0) {
|
|
||||||
node->next = nullptr;
|
|
||||||
node->family = (len == 4 ? AF_INET : AF_INET6);
|
|
||||||
tail->next = node.release();
|
|
||||||
tail = tail->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return root.next;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // HAVE_ARES_ADDR_NODE
|
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -46,9 +46,14 @@
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
struct AsyncNameResolverSocketEntry {
|
||||||
|
ares_socket_t fd;
|
||||||
|
int events;
|
||||||
|
};
|
||||||
|
|
||||||
class AsyncNameResolver {
|
class AsyncNameResolver {
|
||||||
friend void callback(void* arg, int status, int timeouts,
|
friend void callback(void* arg, int status, int timeouts,
|
||||||
struct hostent* host);
|
ares_addrinfo* result);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum STATUS {
|
enum STATUS {
|
||||||
|
@ -59,6 +64,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::vector<AsyncNameResolverSocketEntry> socks_;
|
||||||
STATUS status_;
|
STATUS status_;
|
||||||
int family_;
|
int family_;
|
||||||
ares_channel channel_;
|
ares_channel channel_;
|
||||||
|
@ -68,12 +74,7 @@ private:
|
||||||
std::string hostname_;
|
std::string hostname_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AsyncNameResolver(int family
|
AsyncNameResolver(int family, const std::string& servers);
|
||||||
#ifdef HAVE_ARES_ADDR_NODE
|
|
||||||
,
|
|
||||||
ares_addr_node* servers
|
|
||||||
#endif // HAVE_ARES_ADDR_NODE
|
|
||||||
);
|
|
||||||
|
|
||||||
~AsyncNameResolver();
|
~AsyncNameResolver();
|
||||||
|
|
||||||
|
@ -88,14 +89,14 @@ public:
|
||||||
|
|
||||||
STATUS getStatus() const { return status_; }
|
STATUS getStatus() const { return status_; }
|
||||||
|
|
||||||
int getFds(fd_set* rfdsPtr, fd_set* wfdsPtr) const;
|
ares_socket_t getFds(fd_set* rfdsPtr, fd_set* wfdsPtr) const;
|
||||||
|
|
||||||
void process(fd_set* rfdsPtr, fd_set* wfdsPtr);
|
void process(fd_set* rfdsPtr, fd_set* wfdsPtr);
|
||||||
|
|
||||||
int getFamily() const { return family_; }
|
int getFamily() const { return family_; }
|
||||||
#ifdef HAVE_LIBCARES
|
#ifdef HAVE_LIBCARES
|
||||||
|
|
||||||
int getsock(sock_t* sockets) const;
|
const std::vector<AsyncNameResolverSocketEntry>& getsock() const;
|
||||||
|
|
||||||
void process(ares_socket_t readfd, ares_socket_t writefd);
|
void process(ares_socket_t readfd, ares_socket_t writefd);
|
||||||
|
|
||||||
|
@ -105,17 +106,11 @@ public:
|
||||||
|
|
||||||
void setAddr(const std::string& addrString);
|
void setAddr(const std::string& addrString);
|
||||||
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
const std::string& getHostname() const { return hostname_; }
|
const std::string& getHostname() const { return hostname_; }
|
||||||
|
|
||||||
|
void handle_sock_state(ares_socket_t sock, int read, int write);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_ARES_ADDR_NODE
|
|
||||||
|
|
||||||
ares_addr_node* parseAsyncDNSServers(const std::string& serversOpt);
|
|
||||||
|
|
||||||
#endif // HAVE_ARES_ADDR_NODE
|
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
||||||
#endif // D_ASYNC_NAME_RESOLVER_H
|
#endif // D_ASYNC_NAME_RESOLVER_H
|
||||||
|
|
|
@ -88,12 +88,7 @@ void AsyncNameResolverMan::startAsyncFamily(const std::string& hostname,
|
||||||
Command* command)
|
Command* command)
|
||||||
{
|
{
|
||||||
asyncNameResolver_[numResolver_] =
|
asyncNameResolver_[numResolver_] =
|
||||||
std::make_shared<AsyncNameResolver>(family
|
std::make_shared<AsyncNameResolver>(family, servers_);
|
||||||
#ifdef HAVE_ARES_ADDR_NODE
|
|
||||||
,
|
|
||||||
e->getAsyncDNSServers()
|
|
||||||
#endif // HAVE_ARES_ADDR_NODE
|
|
||||||
);
|
|
||||||
asyncNameResolver_[numResolver_]->resolve(hostname);
|
asyncNameResolver_[numResolver_]->resolve(hostname);
|
||||||
setNameResolverCheck(numResolver_, e, command);
|
setNameResolverCheck(numResolver_, e, command);
|
||||||
}
|
}
|
||||||
|
@ -222,6 +217,7 @@ void configureAsyncNameResolverMan(AsyncNameResolverMan* asyncNameResolverMan,
|
||||||
if (!net::getIPv6AddrConfigured() || option->getAsBool(PREF_DISABLE_IPV6)) {
|
if (!net::getIPv6AddrConfigured() || option->getAsBool(PREF_DISABLE_IPV6)) {
|
||||||
asyncNameResolverMan->setIPv6(false);
|
asyncNameResolverMan->setIPv6(false);
|
||||||
}
|
}
|
||||||
|
asyncNameResolverMan->setServers(option->get(PREF_ASYNC_DNS_SERVER));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -79,6 +79,8 @@ public:
|
||||||
// Resets state. Also removes resolvers from DownloadEngine.
|
// Resets state. Also removes resolvers from DownloadEngine.
|
||||||
void reset(DownloadEngine* e, Command* command);
|
void reset(DownloadEngine* e, Command* command);
|
||||||
|
|
||||||
|
void setServers(std::string servers) { servers_ = std::move(servers); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startAsyncFamily(const std::string& hostname, int family,
|
void startAsyncFamily(const std::string& hostname, int family,
|
||||||
DownloadEngine* e, Command* command);
|
DownloadEngine* e, Command* command);
|
||||||
|
@ -88,6 +90,7 @@ private:
|
||||||
Command* command);
|
Command* command);
|
||||||
|
|
||||||
std::shared_ptr<AsyncNameResolver> asyncNameResolver_[2];
|
std::shared_ptr<AsyncNameResolver> asyncNameResolver_[2];
|
||||||
|
std::string servers_;
|
||||||
size_t numResolver_;
|
size_t numResolver_;
|
||||||
int resolverCheck_;
|
int resolverCheck_;
|
||||||
bool ipv4_;
|
bool ipv4_;
|
||||||
|
|
|
@ -104,9 +104,6 @@ DownloadEngine::DownloadEngine(std::unique_ptr<EventPoll> eventPoll)
|
||||||
#ifdef ENABLE_BITTORRENT
|
#ifdef ENABLE_BITTORRENT
|
||||||
btRegistry_(make_unique<BtRegistry>()),
|
btRegistry_(make_unique<BtRegistry>()),
|
||||||
#endif // ENABLE_BITTORRENT
|
#endif // ENABLE_BITTORRENT
|
||||||
#ifdef HAVE_ARES_ADDR_NODE
|
|
||||||
asyncDNSServers_(nullptr),
|
|
||||||
#endif // HAVE_ARES_ADDR_NODE
|
|
||||||
dnsCache_(make_unique<DNSCache>()),
|
dnsCache_(make_unique<DNSCache>()),
|
||||||
option_(nullptr)
|
option_(nullptr)
|
||||||
{
|
{
|
||||||
|
@ -115,12 +112,7 @@ DownloadEngine::DownloadEngine(std::unique_ptr<EventPoll> eventPoll)
|
||||||
sessionId_.assign(&sessionId[0], &sessionId[sizeof(sessionId)]);
|
sessionId_.assign(&sessionId[0], &sessionId[sizeof(sessionId)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadEngine::~DownloadEngine()
|
DownloadEngine::~DownloadEngine() {}
|
||||||
{
|
|
||||||
#ifdef HAVE_ARES_ADDR_NODE
|
|
||||||
setAsyncDNSServers(nullptr);
|
|
||||||
#endif // HAVE_ARES_ADDR_NODE
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void executeCommand(std::deque<std::unique_ptr<Command>>& commands,
|
void executeCommand(std::deque<std::unique_ptr<Command>>& commands,
|
||||||
|
@ -612,19 +604,6 @@ void DownloadEngine::setCheckIntegrityMan(
|
||||||
checkIntegrityMan_ = std::move(ciman);
|
checkIntegrityMan_ = std::move(ciman);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_ARES_ADDR_NODE
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
#endif // HAVE_ARES_ADDR_NODE
|
|
||||||
|
|
||||||
#ifdef ENABLE_WEBSOCKET
|
#ifdef ENABLE_WEBSOCKET
|
||||||
void DownloadEngine::setWebSocketSessionMan(
|
void DownloadEngine::setWebSocketSessionMan(
|
||||||
std::unique_ptr<rpc::WebSocketSessionMan> wsman)
|
std::unique_ptr<rpc::WebSocketSessionMan> wsman)
|
||||||
|
|
|
@ -137,10 +137,6 @@ private:
|
||||||
|
|
||||||
CUIDCounter cuidCounter_;
|
CUIDCounter cuidCounter_;
|
||||||
|
|
||||||
#ifdef HAVE_ARES_ADDR_NODE
|
|
||||||
ares_addr_node* asyncDNSServers_;
|
|
||||||
#endif // HAVE_ARES_ADDR_NODE
|
|
||||||
|
|
||||||
std::unique_ptr<DNSCache> dnsCache_;
|
std::unique_ptr<DNSCache> dnsCache_;
|
||||||
|
|
||||||
std::unique_ptr<AuthConfigFactory> authConfigFactory_;
|
std::unique_ptr<AuthConfigFactory> authConfigFactory_;
|
||||||
|
@ -326,12 +322,6 @@ public:
|
||||||
|
|
||||||
const std::string getSessionId() const { return sessionId_; }
|
const std::string getSessionId() const { return sessionId_; }
|
||||||
|
|
||||||
#ifdef HAVE_ARES_ADDR_NODE
|
|
||||||
void setAsyncDNSServers(ares_addr_node* asyncDNSServers);
|
|
||||||
|
|
||||||
ares_addr_node* getAsyncDNSServers() const { return asyncDNSServers_; }
|
|
||||||
#endif // HAVE_ARES_ADDR_NODE
|
|
||||||
|
|
||||||
#ifdef ENABLE_WEBSOCKET
|
#ifdef ENABLE_WEBSOCKET
|
||||||
void setWebSocketSessionMan(std::unique_ptr<rpc::WebSocketSessionMan> wsman);
|
void setWebSocketSessionMan(std::unique_ptr<rpc::WebSocketSessionMan> wsman);
|
||||||
const std::unique_ptr<rpc::WebSocketSessionMan>&
|
const std::unique_ptr<rpc::WebSocketSessionMan>&
|
||||||
|
|
36
src/Event.h
36
src/Event.h
|
@ -293,16 +293,12 @@ private:
|
||||||
|
|
||||||
Command* command_;
|
Command* command_;
|
||||||
|
|
||||||
size_t socketsSize_;
|
std::vector<sock_t> sockets_;
|
||||||
|
|
||||||
sock_t sockets_[ARES_GETSOCK_MAXNUM];
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AsyncNameResolverEntry(std::shared_ptr<AsyncNameResolver> nameResolver,
|
AsyncNameResolverEntry(std::shared_ptr<AsyncNameResolver> nameResolver,
|
||||||
Command* command)
|
Command* command)
|
||||||
: nameResolver_(std::move(nameResolver)),
|
: nameResolver_(std::move(nameResolver)), command_(command)
|
||||||
command_(command),
|
|
||||||
socketsSize_(0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,33 +319,27 @@ public:
|
||||||
|
|
||||||
void addSocketEvents(EventPoll* e)
|
void addSocketEvents(EventPoll* e)
|
||||||
{
|
{
|
||||||
socketsSize_ = 0;
|
const auto& socks = nameResolver_->getsock();
|
||||||
int mask = nameResolver_->getsock(sockets_);
|
sockets_.resize(socks.size());
|
||||||
if (mask == 0) {
|
auto sock_it = std::begin(sockets_);
|
||||||
return;
|
|
||||||
}
|
for (const auto& ent : socks) {
|
||||||
size_t i;
|
|
||||||
for (i = 0; i < ARES_GETSOCK_MAXNUM; ++i) {
|
|
||||||
int events = 0;
|
int events = 0;
|
||||||
if (ARES_GETSOCK_READABLE(mask, i)) {
|
if (ent.events & EventPoll::EVENT_READ) {
|
||||||
events |= EventPoll::IEV_READ;
|
events |= EventPoll::IEV_READ;
|
||||||
}
|
}
|
||||||
if (ARES_GETSOCK_WRITABLE(mask, i)) {
|
if (ent.events & EventPoll::EVENT_WRITE) {
|
||||||
events |= EventPoll::IEV_WRITE;
|
events |= EventPoll::IEV_WRITE;
|
||||||
}
|
}
|
||||||
if (events == 0) {
|
e->addEvents(ent.fd, command_, events, nameResolver_);
|
||||||
// assume no further sockets are returned.
|
*sock_it++ = ent.fd;
|
||||||
break;
|
|
||||||
}
|
|
||||||
e->addEvents(sockets_[i], command_, events, nameResolver_);
|
|
||||||
}
|
}
|
||||||
socketsSize_ = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeSocketEvents(EventPoll* e)
|
void removeSocketEvents(EventPoll* e)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < socketsSize_; ++i) {
|
for (auto fd : sockets_) {
|
||||||
e->deleteEvents(sockets_[i], command_, nameResolver_);
|
e->deleteEvents(fd, command_, nameResolver_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ void DHKeyExchange::init(const unsigned char* prime, size_t primeBits,
|
||||||
if (pr.empty()) {
|
if (pr.empty()) {
|
||||||
throw DL_ABORT_EX("No valid prime supplied");
|
throw DL_ABORT_EX("No valid prime supplied");
|
||||||
}
|
}
|
||||||
prime_ = n(pr.c_str(), pr.length());
|
prime_ = n(reinterpret_cast<const unsigned char*>(pr.c_str()), pr.length());
|
||||||
|
|
||||||
std::string gen = reinterpret_cast<const char*>(generator);
|
std::string gen = reinterpret_cast<const char*>(generator);
|
||||||
if (gen.length() % 2) {
|
if (gen.length() % 2) {
|
||||||
|
@ -65,12 +65,13 @@ void DHKeyExchange::init(const unsigned char* prime, size_t primeBits,
|
||||||
if (gen.empty()) {
|
if (gen.empty()) {
|
||||||
throw DL_ABORT_EX("No valid generator supplied");
|
throw DL_ABORT_EX("No valid generator supplied");
|
||||||
}
|
}
|
||||||
generator_ = n(gen.c_str(), gen.length());
|
generator_ =
|
||||||
|
n(reinterpret_cast<const unsigned char*>(gen.c_str()), gen.length());
|
||||||
|
|
||||||
size_t pbytes = (privateKeyBits + 7) / 8;
|
size_t pbytes = (privateKeyBits + 7) / 8;
|
||||||
unsigned char buf[pbytes];
|
unsigned char buf[pbytes];
|
||||||
util::generateRandomData(buf, pbytes);
|
util::generateRandomData(buf, pbytes);
|
||||||
privateKey_ = n(reinterpret_cast<char*>(buf), pbytes);
|
privateKey_ = n(buf, pbytes);
|
||||||
|
|
||||||
keyLength_ = (primeBits + 7) / 8;
|
keyLength_ = (primeBits + 7) / 8;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +89,7 @@ size_t DHKeyExchange::getPublicKey(unsigned char* out, size_t outLength) const
|
||||||
static_cast<unsigned long>(keyLength_),
|
static_cast<unsigned long>(keyLength_),
|
||||||
static_cast<unsigned long>(outLength)));
|
static_cast<unsigned long>(outLength)));
|
||||||
}
|
}
|
||||||
publicKey_.binary(reinterpret_cast<char*>(out), outLength);
|
publicKey_.binary(out, outLength);
|
||||||
return keyLength_;
|
return keyLength_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,10 +115,9 @@ size_t DHKeyExchange::computeSecret(unsigned char* out, size_t outLength,
|
||||||
static_cast<unsigned long>(peerPublicKeyLength)));
|
static_cast<unsigned long>(peerPublicKeyLength)));
|
||||||
}
|
}
|
||||||
|
|
||||||
n peerKey(reinterpret_cast<const char*>(peerPublicKeyData),
|
n peerKey(peerPublicKeyData, peerPublicKeyLength);
|
||||||
peerPublicKeyLength);
|
|
||||||
n secret = peerKey.mul_mod(privateKey_, prime_);
|
n secret = peerKey.mul_mod(privateKey_, prime_);
|
||||||
secret.binary(reinterpret_cast<char*>(out), outLength);
|
secret.binary(out, outLength);
|
||||||
|
|
||||||
return outLength;
|
return outLength;
|
||||||
}
|
}
|
||||||
|
|
|
@ -272,11 +272,6 @@ int MultiUrlRequestInfo::prepare()
|
||||||
clTlsContext->setVerifyPeer(option_->getAsBool(PREF_CHECK_CERTIFICATE));
|
clTlsContext->setVerifyPeer(option_->getAsBool(PREF_CHECK_CERTIFICATE));
|
||||||
SocketCore::setClientTLSContext(clTlsContext);
|
SocketCore::setClientTLSContext(clTlsContext);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_ARES_ADDR_NODE
|
|
||||||
ares_addr_node* asyncDNSServers =
|
|
||||||
parseAsyncDNSServers(option_->get(PREF_ASYNC_DNS_SERVER));
|
|
||||||
e_->setAsyncDNSServers(asyncDNSServers);
|
|
||||||
#endif // HAVE_ARES_ADDR_NODE
|
|
||||||
|
|
||||||
std::string serverStatIf = option_->get(PREF_SERVER_STAT_IF);
|
std::string serverStatIf = option_->get(PREF_SERVER_STAT_IF);
|
||||||
if (!serverStatIf.empty()) {
|
if (!serverStatIf.empty()) {
|
||||||
|
|
|
@ -99,15 +99,13 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
|
||||||
op->setChangeOptionForReserved(true);
|
op->setChangeOptionForReserved(true);
|
||||||
handlers.push_back(op);
|
handlers.push_back(op);
|
||||||
}
|
}
|
||||||
# if defined(HAVE_ARES_SET_SERVERS) && defined(HAVE_ARES_ADDR_NODE)
|
|
||||||
{
|
{
|
||||||
OptionHandler* op(new DefaultOptionHandler(
|
OptionHandler* op(new DefaultOptionHandler(
|
||||||
PREF_ASYNC_DNS_SERVER, TEXT_ASYNC_DNS_SERVER, NO_DEFAULT_VALUE));
|
PREF_ASYNC_DNS_SERVER, TEXT_ASYNC_DNS_SERVER, NO_DEFAULT_VALUE));
|
||||||
op->addTag(TAG_ADVANCED);
|
op->addTag(TAG_ADVANCED);
|
||||||
handlers.push_back(op);
|
handlers.push_back(op);
|
||||||
}
|
}
|
||||||
# endif // HAVE_ARES_SET_SERVERS && HAVE_ARES_ADDR_NODE
|
#endif // ENABLE_ASYNC_DNS
|
||||||
#endif // ENABLE_ASYNC_DNS
|
|
||||||
{
|
{
|
||||||
OptionHandler* op(new BooleanOptionHandler(
|
OptionHandler* op(new BooleanOptionHandler(
|
||||||
PREF_AUTO_FILE_RENAMING, TEXT_AUTO_FILE_RENAMING, A2_V_TRUE,
|
PREF_AUTO_FILE_RENAMING, TEXT_AUTO_FILE_RENAMING, A2_V_TRUE,
|
||||||
|
|
|
@ -143,7 +143,7 @@ int SSHSession::checkDirection()
|
||||||
|
|
||||||
ssize_t SSHSession::writeData(const void* data, size_t len)
|
ssize_t SSHSession::writeData(const void* data, size_t len)
|
||||||
{
|
{
|
||||||
// net implemented yet
|
// not implemented yet
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,8 +129,8 @@ SelectEventPoll::AsyncNameResolverEntry::AsyncNameResolverEntry(
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SelectEventPoll::AsyncNameResolverEntry::getFds(fd_set* rfdsPtr,
|
ares_socket_t SelectEventPoll::AsyncNameResolverEntry::getFds(fd_set* rfdsPtr,
|
||||||
fd_set* wfdsPtr)
|
fd_set* wfdsPtr)
|
||||||
{
|
{
|
||||||
return nameResolver_->getFds(rfdsPtr, wfdsPtr);
|
return nameResolver_->getFds(rfdsPtr, wfdsPtr);
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@ void SelectEventPoll::poll(const struct timeval& tv)
|
||||||
|
|
||||||
for (auto& i : nameResolverEntries_) {
|
for (auto& i : nameResolverEntries_) {
|
||||||
auto& entry = i.second;
|
auto& entry = i.second;
|
||||||
int fd = entry.getFds(&rfds, &wfds);
|
auto fd = entry.getFds(&rfds, &wfds);
|
||||||
// TODO force error if fd == 0
|
// TODO force error if fd == 0
|
||||||
if (fdmax_ < fd) {
|
if (fdmax_ < fd) {
|
||||||
fdmax_ = fd;
|
fdmax_ = fd;
|
||||||
|
|
|
@ -142,7 +142,7 @@ private:
|
||||||
command_ < entry.command_);
|
command_ < entry.command_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getFds(fd_set* rfdsPtr, fd_set* wfdsPtr);
|
ares_socket_t getFds(fd_set* rfdsPtr, fd_set* wfdsPtr);
|
||||||
|
|
||||||
void process(fd_set* rfdsPtr, fd_set* wfdsPtr);
|
void process(fd_set* rfdsPtr, fd_set* wfdsPtr);
|
||||||
};
|
};
|
||||||
|
|
40
src/bignum.h
40
src/bignum.h
|
@ -30,20 +30,20 @@ public:
|
||||||
typedef std::make_unsigned<char_t>::type uchar_t;
|
typedef std::make_unsigned<char_t>::type uchar_t;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<char_t[]> buf_;
|
std::unique_ptr<uchar_t[]> buf_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline ulong() : buf_(aria2::make_unique<char_t[]>(dim)) {}
|
inline ulong() : buf_(aria2::make_unique<uchar_t[]>(dim)) {}
|
||||||
inline ulong(size_t t) : buf_(aria2::make_unique<char_t[]>(dim))
|
inline ulong(size_t t) : buf_(aria2::make_unique<uchar_t[]>(dim))
|
||||||
{
|
{
|
||||||
memcpy(buf_.get(), (char_t*)&t, sizeof(t));
|
memcpy(buf_.get(), (uchar_t*)&t, sizeof(t));
|
||||||
}
|
}
|
||||||
inline ulong(const ulong<dim>& rhs) : buf_(aria2::make_unique<char_t[]>(dim))
|
inline ulong(const ulong<dim>& rhs) : buf_(aria2::make_unique<uchar_t[]>(dim))
|
||||||
{
|
{
|
||||||
memcpy(buf_.get(), rhs.buf_.get(), dim);
|
memcpy(buf_.get(), rhs.buf_.get(), dim);
|
||||||
}
|
}
|
||||||
explicit inline ulong(const char_t* data, size_t size)
|
explicit inline ulong(const uchar_t* data, size_t size)
|
||||||
: buf_(aria2::make_unique<char_t[]>(dim))
|
: buf_(aria2::make_unique<uchar_t[]>(dim))
|
||||||
{
|
{
|
||||||
if (size > dim) {
|
if (size > dim) {
|
||||||
throw std::bad_alloc();
|
throw std::bad_alloc();
|
||||||
|
@ -73,8 +73,8 @@ public:
|
||||||
const auto b2 = rhs.buf_.get();
|
const auto b2 = rhs.buf_.get();
|
||||||
for (ssize_t i = dim - 1; i >= 0; --i) {
|
for (ssize_t i = dim - 1; i >= 0; --i) {
|
||||||
for (ssize_t j = 1; j >= 0; --j) {
|
for (ssize_t j = 1; j >= 0; --j) {
|
||||||
char_t t = ((uchar_t)(b1[i] << 4 * (1 - j))) >> 4;
|
uchar_t t = ((uchar_t)(b1[i] << 4 * (1 - j))) >> 4;
|
||||||
char_t r = ((uchar_t)(b2[i] << 4 * (1 - j))) >> 4;
|
uchar_t r = ((uchar_t)(b2[i] << 4 * (1 - j))) >> 4;
|
||||||
if (t != r) {
|
if (t != r) {
|
||||||
return t > r;
|
return t > r;
|
||||||
}
|
}
|
||||||
|
@ -101,8 +101,8 @@ public:
|
||||||
bool base = false;
|
bool base = false;
|
||||||
for (size_t i = 0; i < dim; ++i) {
|
for (size_t i = 0; i < dim; ++i) {
|
||||||
for (ssize_t j = 0; j < 2; ++j) {
|
for (ssize_t j = 0; j < 2; ++j) {
|
||||||
char_t t = ((uchar_t)(b1[i] << 4 * (1 - j))) >> 4;
|
uchar_t t = ((uchar_t)(b1[i] << 4 * (1 - j))) >> 4;
|
||||||
char_t r = ((uchar_t)(b2[i] << 4 * (1 - j))) >> 4;
|
uchar_t r = ((uchar_t)(b2[i] << 4 * (1 - j))) >> 4;
|
||||||
if (base) {
|
if (base) {
|
||||||
t++;
|
t++;
|
||||||
}
|
}
|
||||||
|
@ -144,8 +144,8 @@ public:
|
||||||
bool base = false;
|
bool base = false;
|
||||||
for (size_t i = 0; i < dim; ++i) {
|
for (size_t i = 0; i < dim; ++i) {
|
||||||
for (ssize_t j = 0; j < 2; ++j) {
|
for (ssize_t j = 0; j < 2; ++j) {
|
||||||
char_t t = ((uchar_t)(b1[i] << 4 * (1 - j))) >> 4;
|
uchar_t t = ((uchar_t)(b1[i] << 4 * (1 - j))) >> 4;
|
||||||
char_t r = ((uchar_t)(b2[i] << 4 * (1 - j))) >> 4;
|
uchar_t r = ((uchar_t)(b2[i] << 4 * (1 - j))) >> 4;
|
||||||
if (base) {
|
if (base) {
|
||||||
t--;
|
t--;
|
||||||
}
|
}
|
||||||
|
@ -238,14 +238,14 @@ public:
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<char_t[]> binary() const
|
std::unique_ptr<uchar_t[]> binary() const
|
||||||
{
|
{
|
||||||
ulong<dim> c = *this;
|
ulong<dim> c = *this;
|
||||||
std::unique_ptr<char_t[]> rv;
|
std::unique_ptr<uchar_t[]> rv;
|
||||||
rv.swap(c.buf_);
|
rv.swap(c.buf_);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
void binary(char_t* buf, size_t len) const
|
void binary(uchar_t* buf, size_t len) const
|
||||||
{
|
{
|
||||||
memcpy(buf, buf_.get(), std::min(dim, len));
|
memcpy(buf, buf_.get(), std::min(dim, len));
|
||||||
}
|
}
|
||||||
|
@ -258,8 +258,8 @@ private:
|
||||||
size_t rv = dim * 2;
|
size_t rv = dim * 2;
|
||||||
const auto b = buf_.get();
|
const auto b = buf_.get();
|
||||||
for (ssize_t i = dim - 1; i >= 0; --i) {
|
for (ssize_t i = dim - 1; i >= 0; --i) {
|
||||||
char_t f = b[i] >> 4;
|
uchar_t f = b[i] >> 4;
|
||||||
char_t s = (b[i] << 4) >> 4;
|
uchar_t s = (b[i] << 4) >> 4;
|
||||||
if (!f && !s) {
|
if (!f && !s) {
|
||||||
rv -= 2;
|
rv -= 2;
|
||||||
continue;
|
continue;
|
||||||
|
@ -282,8 +282,8 @@ private:
|
||||||
const size_t d2 = digits / 2;
|
const size_t d2 = digits / 2;
|
||||||
for (size_t i = d2; i < dim; ++i) {
|
for (size_t i = d2; i < dim; ++i) {
|
||||||
for (size_t j = 0; j < 2; ++j) {
|
for (size_t j = 0; j < 2; ++j) {
|
||||||
char_t c = ((uchar_t)(bt[(dim - 1) - i] << 4 * (1 - j))) >> 4;
|
uchar_t c = ((uchar_t)(bt[(dim - 1) - i] << 4 * (1 - j))) >> 4;
|
||||||
char_t r = c << (npar * (1 - j) * 4 + (1 - npar) * j * 4);
|
uchar_t r = c << (npar * (1 - j) * 4 + (1 - npar) * j * 4);
|
||||||
ssize_t idx = i - d2 - npar * j;
|
ssize_t idx = i - d2 - npar * j;
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
b[(dim - 1) - idx] += r;
|
b[(dim - 1) - idx] += r;
|
||||||
|
|
|
@ -103,10 +103,10 @@ int levenshtein(const char* a, const char* b, int swapcost, int subcost,
|
||||||
int blen = strlen(b);
|
int blen = strlen(b);
|
||||||
std::vector<std::vector<int>> dp(3, std::vector<int>(blen + 1));
|
std::vector<std::vector<int>> dp(3, std::vector<int>(blen + 1));
|
||||||
for (int i = 0; i <= blen; ++i) {
|
for (int i = 0; i <= blen; ++i) {
|
||||||
dp[1][i] = i;
|
dp[1][i] = i * addcost;
|
||||||
}
|
}
|
||||||
for (int i = 1; i <= alen; ++i) {
|
for (int i = 1; i <= alen; ++i) {
|
||||||
dp[0][0] = i;
|
dp[0][0] = i * delcost;
|
||||||
for (int j = 1; j <= blen; ++j) {
|
for (int j = 1; j <= blen; ++j) {
|
||||||
dp[0][j] = dp[1][j - 1] + (a[i - 1] == b[j - 1] ? 0 : subcost);
|
dp[0][j] = dp[1][j - 1] + (a[i - 1] == b[j - 1] ? 0 : subcost);
|
||||||
if (i >= 2 && j >= 2 && a[i - 1] != b[j - 1] && a[i - 2] == b[j - 1] &&
|
if (i >= 2 && j >= 2 && a[i - 1] != b[j - 1] && a[i - 2] == b[j - 1] &&
|
||||||
|
@ -148,7 +148,7 @@ void showCandidates(const std::string& unknownOption,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// cost values are borrowed from git, help.c.
|
// cost values are borrowed from git, help.c.
|
||||||
int sim = levenshtein(optstr, pref->k, 0, 2, 1, 4);
|
int sim = levenshtein(optstr, pref->k, 0, 2, 1, 3);
|
||||||
cands.push_back(std::make_pair(sim, pref));
|
cands.push_back(std::make_pair(sim, pref));
|
||||||
}
|
}
|
||||||
if (cands.empty()) {
|
if (cands.empty()) {
|
||||||
|
|
|
@ -11,43 +11,14 @@ namespace aria2 {
|
||||||
class AsyncNameResolverTest : public CppUnit::TestFixture {
|
class AsyncNameResolverTest : public CppUnit::TestFixture {
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE(AsyncNameResolverTest);
|
CPPUNIT_TEST_SUITE(AsyncNameResolverTest);
|
||||||
CPPUNIT_TEST(testParseAsyncDNSServers);
|
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setUp() {}
|
void setUp() {}
|
||||||
|
|
||||||
void tearDown() {}
|
void tearDown() {}
|
||||||
|
|
||||||
void testParseAsyncDNSServers();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION(AsyncNameResolverTest);
|
CPPUNIT_TEST_SUITE_REGISTRATION(AsyncNameResolverTest);
|
||||||
|
|
||||||
void AsyncNameResolverTest::testParseAsyncDNSServers()
|
|
||||||
{
|
|
||||||
#ifdef HAVE_ARES_ADDR_NODE
|
|
||||||
in_addr ans4;
|
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)4, net::getBinAddr(&ans4, "192.168.0.1"));
|
|
||||||
in6_addr ans6;
|
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)16, net::getBinAddr(&ans6, "2001:db8::2:1"));
|
|
||||||
|
|
||||||
ares_addr_node* root;
|
|
||||||
root = parseAsyncDNSServers("192.168.0.1,2001:db8::2:1");
|
|
||||||
ares_addr_node* node = root;
|
|
||||||
CPPUNIT_ASSERT(node);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(AF_INET, node->family);
|
|
||||||
CPPUNIT_ASSERT(memcmp(&ans4, &node->addr, sizeof(ans4)) == 0);
|
|
||||||
node = node->next;
|
|
||||||
CPPUNIT_ASSERT(node);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(AF_INET6, node->family);
|
|
||||||
CPPUNIT_ASSERT(memcmp(&ans6, &node->addr, sizeof(ans6)) == 0);
|
|
||||||
for (node = root; node;) {
|
|
||||||
ares_addr_node* nextNode = node->next;
|
|
||||||
delete node;
|
|
||||||
node = nextNode;
|
|
||||||
}
|
|
||||||
#endif // HAVE_ARES_ADDR_NODE
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
Loading…
Reference in New Issue