mirror of
https://gitlab.alpinelinux.org/alpine/aports.git
synced 2025-08-19 05:21:31 +02:00
164 lines
6.2 KiB
Diff
164 lines
6.2 KiB
Diff
From 8b04c25a494abc62572b2092dc6980e7196f27a8 Mon Sep 17 00:00:00 2001
|
|
From: Kefu Chai <kefu.chai@scylladb.com>
|
|
Date: Tue, 23 Apr 2024 18:10:59 +0800
|
|
Subject: [PATCH] dns: use undeprecated c-ares APIs
|
|
|
|
c-ares marked some APIs deprecated in 1.28.1.
|
|
|
|
in this change, we conditionally use the undeprecated APIs when
|
|
they are available. please note, we don't specify the minimal
|
|
supported c-ares version in our building system.
|
|
|
|
in which, ares_fds() and ares_process() are not changed yet, because
|
|
we need to change the way how to poll the events for name resolution.
|
|
this would need more thoughts before moving forward.
|
|
|
|
Refs #2197
|
|
Signed-off-by: Kefu Chai <kefu.chai@scylladb.com>
|
|
---
|
|
src/net/dns.cc | 103 ++++++++++++++++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 102 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/src/net/dns.cc b/src/net/dns.cc
|
|
index 09aee14486d..79d51ad9355 100644
|
|
--- a/src/net/dns.cc
|
|
+++ b/src/net/dns.cc
|
|
@@ -262,6 +262,32 @@ class net::dns_resolver::impl
|
|
// The following pragma is needed to work around a false-positive warning
|
|
// in Gcc 11 (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96003).
|
|
#pragma GCC diagnostic ignored "-Wnonnull"
|
|
+#if ARES_VERSION >= 0x011000
|
|
+
|
|
+ ares_addrinfo_hints hints = {
|
|
+ .ai_flags = ARES_AI_CANONNAME,
|
|
+ .ai_family = af,
|
|
+ .ai_socktype = 0,
|
|
+ .ai_protocol = 0,
|
|
+ };
|
|
+ ares_getaddrinfo(_channel, p->name.c_str(), nullptr, &hints, [](void* arg, int status, int timeouts, ares_addrinfo* addrinfo) {
|
|
+ // we do potentially allocating operations below, so wrap the pointer in a
|
|
+ // unique here.
|
|
+ std::unique_ptr<promise_wrap> p(reinterpret_cast<promise_wrap *>(arg));
|
|
+
|
|
+ switch (status) {
|
|
+ default:
|
|
+ dns_log.debug("Query failed: {}", status);
|
|
+ p->set_exception(std::system_error(status, ares_errorc, p->name));
|
|
+ break;
|
|
+ case ARES_SUCCESS:
|
|
+ p->set_value(make_hostent(addrinfo));
|
|
+ break;
|
|
+ }
|
|
+ ares_freeaddrinfo(addrinfo);
|
|
+
|
|
+ }, reinterpret_cast<void *>(p));
|
|
+#else
|
|
ares_gethostbyname(_channel, p->name.c_str(), af, [](void* arg, int status, int timeouts, ::hostent* host) {
|
|
// we do potentially allocating operations below, so wrap the pointer in a
|
|
// unique here.
|
|
@@ -278,7 +304,7 @@ class net::dns_resolver::impl
|
|
}
|
|
|
|
}, reinterpret_cast<void *>(p));
|
|
-
|
|
+#endif
|
|
|
|
poll_sockets();
|
|
|
|
@@ -343,6 +369,47 @@ class net::dns_resolver::impl
|
|
|
|
dns_call call(*this);
|
|
|
|
+#if ARES_VERSION >= 0x011c00
|
|
+ ares_query_dnsrec(_channel, query.c_str(), ARES_CLASS_IN, ARES_REC_TYPE_SRV,
|
|
+ [](void* arg, ares_status_t status, size_t timeouts,
|
|
+ const ares_dns_record *dnsrec) {
|
|
+ auto p = std::unique_ptr<promise<srv_records>>(
|
|
+ reinterpret_cast<promise<srv_records> *>(arg));
|
|
+ if (status != ARES_SUCCESS) {
|
|
+ dns_log.debug("Query failed: {}", fmt::underlying(status));
|
|
+ p->set_exception(std::system_error(status, ares_errorc));
|
|
+ return;
|
|
+ }
|
|
+ const size_t rr_count = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER);
|
|
+ srv_records replies;
|
|
+ for (size_t i = 0; i < rr_count; i++) {
|
|
+ const ares_dns_rr_t* rr = ares_dns_record_rr_get(
|
|
+ const_cast<ares_dns_record*>(dnsrec),
|
|
+ ARES_SECTION_ANSWER, i);
|
|
+ if (!rr) {
|
|
+ // not likely, but still..
|
|
+ status = ARES_EBADRESP;
|
|
+ break;
|
|
+ }
|
|
+ if (ares_dns_rr_get_class(rr) != ARES_CLASS_IN ||
|
|
+ ares_dns_rr_get_type(rr) != ARES_REC_TYPE_SRV) {
|
|
+ continue;
|
|
+ }
|
|
+ replies.push_back({
|
|
+ ares_dns_rr_get_u16(rr, ARES_RR_SRV_PRIORITY),
|
|
+ ares_dns_rr_get_u16(rr, ARES_RR_SRV_WEIGHT),
|
|
+ ares_dns_rr_get_u16(rr, ARES_RR_SRV_PORT),
|
|
+ sstring{ares_dns_rr_get_str(rr, ARES_RR_SRV_TARGET)}
|
|
+ });
|
|
+ }
|
|
+ if (status != ARES_SUCCESS) {
|
|
+ dns_log.debug("Parse failed: {}", fmt::underlying(status));
|
|
+ p->set_exception(std::system_error(status, ares_errorc));
|
|
+ return;
|
|
+ }
|
|
+ p->set_value(std::move(replies));
|
|
+ }, reinterpret_cast<void *>(p.release()), nullptr);
|
|
+#else
|
|
ares_query(_channel, query.c_str(), ns_c_in, ns_t_srv,
|
|
[](void* arg, int status, int timeouts,
|
|
unsigned char* buf, int len) {
|
|
@@ -367,6 +434,7 @@ class net::dns_resolver::impl
|
|
}
|
|
ares_free_data(start);
|
|
}, reinterpret_cast<void *>(p.release()));
|
|
+#endif
|
|
|
|
|
|
poll_sockets();
|
|
@@ -482,6 +550,39 @@ class net::dns_resolver::impl
|
|
return records;
|
|
}
|
|
|
|
+#if ARES_VERSION >= 0x011000
|
|
+ static hostent make_hostent(const ares_addrinfo* ai) {
|
|
+ hostent e;
|
|
+ if (!ai) {
|
|
+ return e;
|
|
+ }
|
|
+ if (ai->cnames) {
|
|
+ e.names.emplace_back(ai->cnames->name);
|
|
+ } else {
|
|
+ e.names.emplace_back(ai->name);
|
|
+ }
|
|
+ for (auto cname = ai->cnames; cname != nullptr; cname = cname->next) {
|
|
+ if (cname->alias == nullptr) {
|
|
+ continue;
|
|
+ }
|
|
+ e.names.emplace_back(cname->alias);
|
|
+ }
|
|
+ for (auto node = ai->nodes; node != nullptr; node = node->ai_next) {
|
|
+ switch (node->ai_family) {
|
|
+ case AF_INET:
|
|
+ e.addr_list.emplace_back(reinterpret_cast<const sockaddr_in*>(node->ai_addr)->sin_addr);
|
|
+ break;
|
|
+ case AF_INET6:
|
|
+ e.addr_list.emplace_back(reinterpret_cast<const sockaddr_in6*>(node->ai_addr)->sin6_addr);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ dns_log.debug("Query success: {}/{}", e.names.front(), e.addr_list.front());
|
|
+
|
|
+ return e;
|
|
+ }
|
|
+#endif
|
|
static hostent make_hostent(const ::hostent& host) {
|
|
hostent e;
|
|
e.names.emplace_back(host.h_name);
|