diff --git a/.github/workflows/macos-clang.yml b/.github/workflows/macos-clang.yml index 14bf313f..6baa1688 100644 --- a/.github/workflows/macos-clang.yml +++ b/.github/workflows/macos-clang.yml @@ -16,7 +16,9 @@ jobs: link: [ 'STATIC', 'SHARED' ] # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) build-type: ['Debug', 'Release'] - tls-provider: ['', 'openssl', 'botan'] + # Botan needs std::ranges but clang on macOS doesn't support it yet + #tls-provider: ['', 'openssl', 'botan'] + tls-provider: ['', 'openssl'] steps: - name: Install dependencies diff --git a/trantor/net/inner/AresResolver.cc b/trantor/net/inner/AresResolver.cc index 9ef19fc4..7ac0ee75 100644 --- a/trantor/net/inner/AresResolver.cc +++ b/trantor/net/inner/AresResolver.cc @@ -52,10 +52,17 @@ bool Resolver::isCAresUsed() AresResolver::LibraryInitializer::LibraryInitializer() { ares_library_init(ARES_LIB_INIT_ALL); + + hints_ = new ares_addrinfo_hints; + hints_->ai_flags = 0; + hints_->ai_family = AF_INET; + hints_->ai_socktype = 0; + hints_->ai_protocol = 0; } AresResolver::LibraryInitializer::~LibraryInitializer() { ares_library_cleanup(); + delete hints_; } AresResolver::LibraryInitializer AresResolver::libraryInitializer_; @@ -124,11 +131,12 @@ void AresResolver::resolveInLoop(const std::string& hostname, #endif init(); QueryData* queryData = new QueryData(this, cb, hostname); - ares_gethostbyname(ctx_, - hostname.c_str(), - AF_INET, - &AresResolver::ares_hostcallback_, - queryData); + ares_getaddrinfo(ctx_, + hostname.c_str(), + NULL, + libraryInitializer_.hints_, + &AresResolver::ares_hostcallback_, + queryData); struct timeval tv; struct timeval* tvp = ares_timeout(ctx_, NULL, &tv); double timeout = getSeconds(tvp); @@ -166,7 +174,7 @@ void AresResolver::onTimer() } void AresResolver::onQueryResult(int status, - struct hostent* result, + struct ares_addrinfo* result, const std::string& hostname, const ResolverResultsCallback& callback) { @@ -174,15 +182,25 @@ void AresResolver::onQueryResult(int status, auto inets_ptr = std::make_shared>(); if (result) { - auto pptr = (struct in_addr**)result->h_addr_list; - for (; *pptr != nullptr; pptr++) + auto pptr = (struct ares_addrinfo_node*)result->nodes; + for (; pptr != NULL; pptr = pptr->ai_next) { - struct sockaddr_in addr; - memset(&addr, 0, sizeof addr); - addr.sin_family = AF_INET; - addr.sin_port = 0; - addr.sin_addr = *reinterpret_cast(*pptr); - inets_ptr->emplace_back(trantor::InetAddress{addr}); + trantor::InetAddress inet; + if (pptr->ai_family == AF_INET) + { + struct sockaddr_in* addr4 = (struct sockaddr_in*)pptr->ai_addr; + inets_ptr->emplace_back(trantor::InetAddress{*addr4}); + } + else if (pptr->ai_family == AF_INET6) + { + struct sockaddr_in6* addr6 = + (struct sockaddr_in6*)pptr->ai_addr; + inets_ptr->emplace_back(trantor::InetAddress{*addr6}); + } + else + { + // TODO: Handle unknown family? + } } } if (inets_ptr->empty()) @@ -237,7 +255,7 @@ void AresResolver::onSockStateChange(int sockfd, bool read, bool write) void AresResolver::ares_hostcallback_(void* data, int status, int timeouts, - struct hostent* hostent) + struct ares_addrinfo* hostent) { (void)timeouts; QueryData* query = static_cast(data); diff --git a/trantor/net/inner/AresResolver.h b/trantor/net/inner/AresResolver.h index 753f0be1..52515771 100644 --- a/trantor/net/inner/AresResolver.h +++ b/trantor/net/inner/AresResolver.h @@ -15,8 +15,9 @@ extern "C" { - struct hostent; + struct ares_addrinfo; struct ares_channeldata; + struct ares_addrinfo_hints; using ares_channel = struct ares_channeldata*; } namespace trantor @@ -157,7 +158,7 @@ class AresResolver : public Resolver, void onRead(int sockfd); void onTimer(); void onQueryResult(int status, - struct hostent* result, + struct ares_addrinfo* result, const std::string& hostname, const ResolverResultsCallback& callback); void onSockCreate(int sockfd, int type); @@ -166,7 +167,7 @@ class AresResolver : public Resolver, static void ares_hostcallback_(void* data, int status, int timeouts, - struct hostent* hostent); + struct ares_addrinfo* hostent); #ifdef _WIN32 static int ares_sock_createcallback_(SOCKET sockfd, int type, void* data); #else @@ -184,6 +185,7 @@ class AresResolver : public Resolver, { LibraryInitializer(); ~LibraryInitializer(); + ares_addrinfo_hints* hints_; }; static LibraryInitializer libraryInitializer_; };