aports/testing/seastar/10-c-ares.patch
2024-05-19 09:57:56 +00:00

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