Skip to content

Commit

Permalink
Merge branch 'aria2:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
wenbingzhang authored Aug 13, 2024
2 parents bdf72a4 + b519ce0 commit 8bfcc46
Show file tree
Hide file tree
Showing 18 changed files with 169 additions and 221 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ jobs:
build:
strategy:
matrix:
os: [ubuntu-22.04, macos-11]
os: [ubuntu-22.04, macos-14]
compiler: [gcc, clang]
crypto: [openssl, gnutls]
bittorrent: [with-bt, without-bt]
exclude:
- os: macos-11
- os: macos-14
crypto: gnutls
- crypto: openssl
bittorrent: without-bt
Expand Down
10 changes: 1 addition & 9 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -503,18 +503,10 @@ fi

have_libcares=no
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])
if test "x$have_libcares" = "xyes"; then
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
else
Expand Down
159 changes: 99 additions & 60 deletions src/AsyncNameResolver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,27 @@
#include "LogFactory.h"
#include "SocketCore.h"
#include "util.h"
#include "EventPoll.h"

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);
if (status != ARES_SUCCESS) {
resolverPtr->error_ = ares_strerror(status);
resolverPtr->status_ = AsyncNameResolver::STATUS_ERROR;
return;
}
for (char** ap = host->h_addr_list; *ap; ++ap) {
for (auto ap = result->nodes; ap; ap = ap->ai_next) {
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);
}
}
ares_freeaddrinfo(result);
if (resolverPtr->resolvedAddresses_.empty()) {
resolverPtr->error_ = "no address returned or address conversion failed";
resolverPtr->status_ = AsyncNameResolver::STATUS_ERROR;
Expand All @@ -66,24 +70,63 @@ void callback(void* arg, int status, int timeouts, struct hostent* host)
}
}

AsyncNameResolver::AsyncNameResolver(int family
#ifdef HAVE_ARES_ADDR_NODE
,
ares_addr_node* servers
#endif // HAVE_ARES_ADDR_NODE
)
namespace {
void sock_state_cb(void* arg, ares_socket_t fd, int read, int write)
{
auto resolver = static_cast<AsyncNameResolver*>(arg);

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)
{
ares_options opts{};
opts.sock_state_cb = sock_state_cb;
opts.sock_state_cb_data = this;

// TODO evaluate return value
ares_init(&channel_);
#if defined(HAVE_ARES_SET_SERVERS) && defined(HAVE_ARES_ADDR_NODE)
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");
ares_init_options(&channel_, &opts, ARES_OPT_SOCK_STATE_CB);

if (!servers.empty()) {
if (ares_set_servers_csv(channel_, servers.c_str()) != ARES_SUCCESS) {
A2_LOG_DEBUG("ares_set_servers_csv failed");
}
}
#endif // HAVE_ARES_SET_SERVERS && HAVE_ARES_ADDR_NODE
}

AsyncNameResolver::~AsyncNameResolver() { ares_destroy(channel_); }
Expand All @@ -92,25 +135,58 @@ void AsyncNameResolver::resolve(const std::string& name)
{
hostname_ = name;
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)
{
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

int AsyncNameResolver::getsock(sock_t* sockets) const
const std::vector<AsyncNameResolverSocketEntry>&
AsyncNameResolver::getsock() const
{
return ares_getsock(channel_, reinterpret_cast<ares_socket_t*>(sockets),
ARES_GETSOCK_MAXNUM);
return socks_;
}

void AsyncNameResolver::process(ares_socket_t readfd, ares_socket_t writefd)
Expand All @@ -125,41 +201,4 @@ bool AsyncNameResolver::operator==(const AsyncNameResolver& resolver) const
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
29 changes: 12 additions & 17 deletions src/AsyncNameResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,14 @@

namespace aria2 {

struct AsyncNameResolverSocketEntry {
ares_socket_t fd;
int events;
};

class AsyncNameResolver {
friend void callback(void* arg, int status, int timeouts,
struct hostent* host);
ares_addrinfo* result);

public:
enum STATUS {
Expand All @@ -59,6 +64,7 @@ class AsyncNameResolver {
};

private:
std::vector<AsyncNameResolverSocketEntry> socks_;
STATUS status_;
int family_;
ares_channel channel_;
Expand All @@ -68,12 +74,7 @@ class AsyncNameResolver {
std::string hostname_;

public:
AsyncNameResolver(int family
#ifdef HAVE_ARES_ADDR_NODE
,
ares_addr_node* servers
#endif // HAVE_ARES_ADDR_NODE
);
AsyncNameResolver(int family, const std::string& servers);

~AsyncNameResolver();

Expand All @@ -88,14 +89,14 @@ class AsyncNameResolver {

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);

int getFamily() const { return family_; }
#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);

Expand All @@ -105,16 +106,10 @@ class AsyncNameResolver {

void setAddr(const std::string& addrString);

void reset();

const std::string& getHostname() const { return hostname_; }
};

#ifdef HAVE_ARES_ADDR_NODE

ares_addr_node* parseAsyncDNSServers(const std::string& serversOpt);

#endif // HAVE_ARES_ADDR_NODE
void handle_sock_state(ares_socket_t sock, int read, int write);
};

} // namespace aria2

Expand Down
8 changes: 2 additions & 6 deletions src/AsyncNameResolverMan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,7 @@ void AsyncNameResolverMan::startAsyncFamily(const std::string& hostname,
Command* command)
{
asyncNameResolver_[numResolver_] =
std::make_shared<AsyncNameResolver>(family
#ifdef HAVE_ARES_ADDR_NODE
,
e->getAsyncDNSServers()
#endif // HAVE_ARES_ADDR_NODE
);
std::make_shared<AsyncNameResolver>(family, servers_);
asyncNameResolver_[numResolver_]->resolve(hostname);
setNameResolverCheck(numResolver_, e, command);
}
Expand Down Expand Up @@ -222,6 +217,7 @@ void configureAsyncNameResolverMan(AsyncNameResolverMan* asyncNameResolverMan,
if (!net::getIPv6AddrConfigured() || option->getAsBool(PREF_DISABLE_IPV6)) {
asyncNameResolverMan->setIPv6(false);
}
asyncNameResolverMan->setServers(option->get(PREF_ASYNC_DNS_SERVER));
}

} // namespace aria2
3 changes: 3 additions & 0 deletions src/AsyncNameResolverMan.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ class AsyncNameResolverMan {
// Resets state. Also removes resolvers from DownloadEngine.
void reset(DownloadEngine* e, Command* command);

void setServers(std::string servers) { servers_ = std::move(servers); }

private:
void startAsyncFamily(const std::string& hostname, int family,
DownloadEngine* e, Command* command);
Expand All @@ -88,6 +90,7 @@ class AsyncNameResolverMan {
Command* command);

std::shared_ptr<AsyncNameResolver> asyncNameResolver_[2];
std::string servers_;
size_t numResolver_;
int resolverCheck_;
bool ipv4_;
Expand Down
Loading

0 comments on commit 8bfcc46

Please sign in to comment.