]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
https-rr: implementation improvements
authorStefan Eissing <stefan@eissing.org>
Thu, 30 Jan 2025 14:31:16 +0000 (15:31 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 18 Feb 2025 15:12:26 +0000 (16:12 +0100)
- fold DoH and async HTTPS-RR handling into common code.
  have common cleanups, etc. Have a CURLcode result in async
  handling to allow HTTPS RR parsing to fail.
- keep target, ipv4hints, ipv6hints, port and echconfig also
  when resolving via cares. We need to know `target` and `port`
  when evaluating possible ALPN candidates to not go astray.
- add CURL_TRC_DNS for tracing DNS operations
- replace DoH specific tracing with DNS, use doh as alias
  for dns in curl_global_tracea()

Closes #16132

12 files changed:
docs/libcurl/curl_global_trace.md
lib/asyn-ares.c
lib/asyn-thread.c
lib/asyn.h
lib/curl_trc.c
lib/curl_trc.h
lib/doh.c
lib/doh.h
lib/hostip.c
lib/httpsrr.c
lib/httpsrr.h
scripts/singleuse.pl

index 87edb8ecf08f0f398218a3fcbca52642c92eb914..acf966f3ce2014c0b8b818b37e90ea61bd97f2ec 100644 (file)
@@ -97,9 +97,13 @@ In order to find out all components involved in a transfer, run it with "all"
 configured. You can then see all names involved in your libcurl version in the
 trace.
 
+## `dns`
+
+Tracing of DNS operations to resolve hostnames and HTTPS records.
+
 ## `doh`
 
-Tracing of DNS-over-HTTP operations to resolve hostnames.
+Former name for DNS-over-HTTP operations. Now an alias for `dns`.
 
 ## `read`
 
index 50f3bc74188365017b8bb5cd53650bdfa2d7a911..86cd983414fcc758d0e67aa0c4058d9869bf15da 100644 (file)
@@ -419,14 +419,14 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
        them */
     res->temp_ai = NULL;
 
+    result = res->result;
     if(!data->state.async.dns)
       result = Curl_resolver_error(data);
-    else {
+    if(!result) {
       *dns = data->state.async.dns;
 #ifdef USE_HTTPSRR_ARES
       {
-        struct Curl_https_rrinfo *lhrr =
-          Curl_memdup(&res->hinfo, sizeof(struct Curl_https_rrinfo));
+        struct Curl_https_rrinfo *lhrr = Curl_httpsrr_dup_move(&res->hinfo);
         if(!lhrr)
           result = CURLE_OUT_OF_MEMORY;
         else
index 8a938c425ab94c0434d1d000d052066ca0307b54..de056c672f83597712463621960d8e4512d98499 100644 (file)
@@ -585,17 +585,19 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
   Curl_mutex_release(&td->tsd.mutx);
 
   if(done) {
+    CURLcode result = td->result;
     getaddrinfo_complete(data);
 
-    if(!data->state.async.dns) {
-      CURLcode result = Curl_resolver_error(data);
+    if(!result && !data->state.async.dns)
+      result = Curl_resolver_error(data);
+
+    if(result) {
       destroy_async_data(data);
       return result;
     }
 #ifdef USE_HTTPSRR_ARES
     {
-      struct Curl_https_rrinfo *lhrr =
-        Curl_memdup(&td->hinfo, sizeof(struct Curl_https_rrinfo));
+      struct Curl_https_rrinfo *lhrr = Curl_httpsrr_dup_move(&td->hinfo);
       if(!lhrr) {
         destroy_async_data(data);
         return CURLE_OUT_OF_MEMORY;
index 6e8e2debde70335a62353ca2abce55b4e4e83c28..d70bc86aaf3d46448c1b5346fe4b230685c8ef50 100644 (file)
@@ -60,6 +60,7 @@ struct thread_data {
   timediff_t interval_end;
   struct curltime start;
   struct thread_sync_data tsd;
+  CURLcode result; /* CURLE_OK or error handling response */
 #if defined(USE_HTTPSRR) && defined(USE_ARES)
   struct Curl_https_rrinfo hinfo;
   ares_channel channel;
@@ -74,6 +75,7 @@ struct thread_data {
   struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
                                     parts */
   int last_status;
+  CURLcode result; /* CURLE_OK or error handling response */
 #ifndef HAVE_CARES_GETADDRINFO
   struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
 #endif
index e5f9b517dc5e94bcd2efebce6f726505757b52b8..fb3654e53bbf2c906acf7a1a8e3217e66d1775e8 100644 (file)
@@ -176,6 +176,11 @@ struct curl_trc_feat Curl_trc_feat_write = {
   "WRITE",
   CURL_LOG_LVL_NONE,
 };
+struct curl_trc_feat Curl_trc_feat_dns = {
+  "DNS",
+  CURL_LOG_LVL_NONE,
+};
+
 
 void Curl_trc_read(struct Curl_easy *data, const char *fmt, ...)
 {
@@ -199,6 +204,17 @@ void Curl_trc_write(struct Curl_easy *data, const char *fmt, ...)
   }
 }
 
+void Curl_trc_dns(struct Curl_easy *data, const char *fmt, ...)
+{
+  DEBUGASSERT(!strchr(fmt, '\n'));
+  if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_dns)) {
+    va_list ap;
+    va_start(ap, fmt);
+    trc_infof(data, &Curl_trc_feat_dns, fmt, ap);
+    va_end(ap);
+  }
+}
+
 #ifndef CURL_DISABLE_FTP
 struct curl_trc_feat Curl_trc_feat_ftp = {
   "FTP",
@@ -284,11 +300,11 @@ struct trc_feat_def {
 static struct trc_feat_def trc_feats[] = {
   { &Curl_trc_feat_read,      TRC_CT_NONE },
   { &Curl_trc_feat_write,     TRC_CT_NONE },
+  { &Curl_trc_feat_dns,       TRC_CT_NETWORK },
 #ifndef CURL_DISABLE_FTP
   { &Curl_trc_feat_ftp,       TRC_CT_PROTOCOL },
 #endif
 #ifndef CURL_DISABLE_DOH
-  { &Curl_doh_trc,            TRC_CT_NETWORK },
 #endif
 #ifndef CURL_DISABLE_SMTP
   { &Curl_trc_feat_smtp,      TRC_CT_PROTOCOL },
@@ -395,6 +411,10 @@ static CURLcode trc_opt(const char *config)
       trc_apply_level_by_category(TRC_CT_NETWORK, lvl);
     else if(Curl_str_casecompare(&out, "proxy"))
       trc_apply_level_by_category(TRC_CT_PROXY, lvl);
+    else if(Curl_str_casecompare(&out, "doh")) {
+      struct Curl_str dns = { "dns", 3 };
+      trc_apply_level_by_name(&dns, lvl);
+    }
     else
       trc_apply_level_by_name(&out, lvl);
 
index 9b4e36eef993037d71be1ad3030fe228ee032561..5412c7a5f885706cecf5b99bbe12fff3097d8569 100644 (file)
@@ -86,6 +86,8 @@ void Curl_trc_write(struct Curl_easy *data,
                     const char *fmt, ...) CURL_PRINTF(2, 3);
 void Curl_trc_read(struct Curl_easy *data,
                    const char *fmt, ...) CURL_PRINTF(2, 3);
+void Curl_trc_dns(struct Curl_easy *data,
+                  const char *fmt, ...) CURL_PRINTF(2, 3);
 
 #ifndef CURL_DISABLE_FTP
 extern struct curl_trc_feat Curl_trc_feat_ftp;
@@ -121,6 +123,9 @@ void Curl_trc_ws(struct Curl_easy *data,
 #define CURL_TRC_READ(data, ...) \
   do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_read)) \
          Curl_trc_read(data, __VA_ARGS__); } while(0)
+#define CURL_TRC_DNS(data, ...) \
+  do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_dns)) \
+         Curl_trc_dns(data, __VA_ARGS__); } while(0)
 
 #ifndef CURL_DISABLE_FTP
 #define CURL_TRC_FTP(data, ...) \
@@ -149,6 +154,7 @@ void Curl_trc_ws(struct Curl_easy *data,
 #define CURL_TRC_CF Curl_trc_cf_infof
 #define CURL_TRC_WRITE Curl_trc_write
 #define CURL_TRC_READ  Curl_trc_read
+#define CURL_TRC_DNS   Curl_trc_dns
 
 #ifndef CURL_DISABLE_FTP
 #define CURL_TRC_FTP   Curl_trc_ftp
@@ -174,6 +180,7 @@ struct curl_trc_feat {
 };
 extern struct curl_trc_feat Curl_trc_feat_read;
 extern struct curl_trc_feat Curl_trc_feat_write;
+extern struct curl_trc_feat Curl_trc_feat_dns;
 
 #define Curl_trc_is_verbose(data) \
             ((data) && (data)->set.verbose && \
index eca071138055d8bc80c006562baa136a198f28d5..f1d2bbe47eb6004500fbc1dda24a6374b771b88b 100644 (file)
--- a/lib/doh.c
+++ b/lib/doh.c
@@ -71,10 +71,6 @@ static const char *doh_strerror(DOHcode code)
   return "bad error code";
 }
 
-struct curl_trc_feat Curl_doh_trc = {
-  "DoH",
-  CURL_LOG_LVL_NONE,
-};
 #endif /* !CURL_DISABLE_VERBOSE_STRINGS */
 
 /* @unittest 1655
@@ -281,7 +277,7 @@ static CURLcode doh_run_probe(struct Curl_easy *data,
      the gcc typecheck helpers */
   doh->state.internal = TRUE;
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
-  doh->state.feat = &Curl_doh_trc;
+  doh->state.feat = &Curl_trc_feat_dns;
 #endif
   ERROR_CHECK_SETOPT(CURLOPT_URL, url);
   ERROR_CHECK_SETOPT(CURLOPT_DEFAULT_PROTOCOL, "https");
@@ -305,7 +301,7 @@ static CURLcode doh_run_probe(struct Curl_easy *data,
   ERROR_CHECK_SETOPT(CURLOPT_SHARE, (CURLSH *)data->share);
   if(data->set.err && data->set.err != stderr)
     ERROR_CHECK_SETOPT(CURLOPT_STDERR, data->set.err);
-  if(Curl_trc_ft_is_verbose(data, &Curl_doh_trc))
+  if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_dns))
     ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L);
   if(data->set.no_signal)
     ERROR_CHECK_SETOPT(CURLOPT_NOSIGNAL, 1L);
@@ -1087,12 +1083,14 @@ static CURLcode doh_test_alpn_escapes(void)
 }
 #endif
 
-static CURLcode doh_resp_decode_httpsrr(unsigned char *cp, size_t len,
+static CURLcode doh_resp_decode_httpsrr(struct Curl_easy *data,
+                                        unsigned char *cp, size_t len,
                                         struct Curl_https_rrinfo **hrr)
 {
   uint16_t pcode = 0, plen = 0;
   struct Curl_https_rrinfo *lhrr = NULL;
   char *dnsname = NULL;
+  CURLcode result = CURLE_OUT_OF_MEMORY;
 
 #ifdef DEBUGBUILD
   /* a few tests of escaping, should not be here but ok for now */
@@ -1116,44 +1114,9 @@ static CURLcode doh_resp_decode_httpsrr(unsigned char *cp, size_t len,
     plen = doh_get16bit(cp, 2);
     cp += 4;
     len -= 4;
-    switch(pcode) {
-    case HTTPS_RR_CODE_ALPN:
-      if(Curl_httpsrr_decode_alpn(cp, plen, lhrr->alpns) != CURLE_OK)
-        goto err;
-      break;
-    case HTTPS_RR_CODE_NO_DEF_ALPN:
-      lhrr->no_def_alpn = TRUE;
-      break;
-    case HTTPS_RR_CODE_IPV4:
-      if(!plen)
-        goto err;
-      lhrr->ipv4hints = Curl_memdup(cp, plen);
-      if(!lhrr->ipv4hints)
-        goto err;
-      lhrr->ipv4hints_len = (size_t)plen;
-      break;
-    case HTTPS_RR_CODE_ECH:
-      if(!plen)
-        goto err;
-      lhrr->echconfiglist = Curl_memdup(cp, plen);
-      if(!lhrr->echconfiglist)
-        goto err;
-      lhrr->echconfiglist_len = (size_t)plen;
-      break;
-    case HTTPS_RR_CODE_IPV6:
-      if(!plen)
-        goto err;
-      lhrr->ipv6hints = Curl_memdup(cp, plen);
-      if(!lhrr->ipv6hints)
-        goto err;
-      lhrr->ipv6hints_len = (size_t)plen;
-      break;
-    case HTTPS_RR_CODE_PORT:
-      lhrr->port = doh_get16bit(cp, 0);
-      break;
-    default:
-      break;
-    }
+    result = Curl_httpsrr_set(data, lhrr, pcode, cp, plen);
+    if(result)
+      goto err;
     if(plen > 0 && plen <= len) {
       cp += plen;
       len -= plen;
@@ -1163,10 +1126,9 @@ static CURLcode doh_resp_decode_httpsrr(unsigned char *cp, size_t len,
   *hrr = lhrr;
   return CURLE_OK;
 err:
-  Curl_safefree(lhrr->target);
-  Curl_safefree(lhrr->echconfiglist);
+  Curl_httpsrr_cleanup(lhrr);
   Curl_safefree(lhrr);
-  return CURLE_OUT_OF_MEMORY;
+  return result;
 }
 
 # ifdef DEBUGBUILD
@@ -1256,8 +1218,8 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
       struct Curl_addrinfo *ai;
 
 
-      if(Curl_trc_ft_is_verbose(data, &Curl_doh_trc)) {
-        infof(data, "[DoH] hostname: %s", dohp->host);
+      if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_dns)) {
+        CURL_TRC_DNS(data, "hostname: %s", dohp->host);
         doh_show(data, &de);
       }
 
@@ -1291,8 +1253,8 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
 #ifdef USE_HTTPSRR
     if(de.numhttps_rrs > 0 && result == CURLE_OK && *dnsp) {
       struct Curl_https_rrinfo *hrr = NULL;
-      result = doh_resp_decode_httpsrr(de.https_rrs->val, de.https_rrs->len,
-                                       &hrr);
+      result = doh_resp_decode_httpsrr(data, de.https_rrs->val,
+                                       de.https_rrs->len, &hrr);
       if(result) {
         infof(data, "Failed to decode HTTPS RR");
         return result;
index 53644863e6f5b035e2891cdf6eda6881ae40c93b..9c41ed818eaac3f3fe6d737f8d4841a4aebb7a11 100644 (file)
--- a/lib/doh.h
+++ b/lib/doh.h
@@ -167,8 +167,6 @@ UNITTEST void de_init(struct dohentry *d);
 UNITTEST void de_cleanup(struct dohentry *d);
 #endif
 
-extern struct curl_trc_feat Curl_doh_trc;
-
 #else /* if DoH is disabled */
 #define Curl_doh(a,b,c,d) NULL
 #define Curl_doh_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
index 17d335564f75febdcd8af69a0d87113d325ab215..9d0dd104041b87df6255082f1a2f392f4745c334 100644 (file)
@@ -1081,10 +1081,7 @@ static void hostcache_unlink_entry(void *entry)
     Curl_freeaddrinfo(dns->addr);
 #ifdef USE_HTTPSRR
     if(dns->hinfo) {
-      free(dns->hinfo->target);
-      free(dns->hinfo->ipv4hints);
-      free(dns->hinfo->echconfiglist);
-      free(dns->hinfo->ipv6hints);
+      Curl_httpsrr_cleanup(dns->hinfo);
       free(dns->hinfo);
     }
 #endif
index 3072f60bb1d0996290b7f59b8ca2b7b354c2d603..7a2ecdbe4dc2fcf8d0d678a5de523548bc3b65c6 100644 (file)
@@ -31,6 +31,7 @@
 #include "httpsrr.h"
 #include "connect.h"
 #include "sendf.h"
+#include "strdup.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -91,44 +92,92 @@ err:
   return CURLE_BAD_CONTENT_ENCODING;
 }
 
-#ifdef USE_ARES
-
-static void httpsrr_opt(struct Curl_easy *data,
-                        const ares_dns_rr_t *rr,
-                        ares_dns_rr_key_t key, size_t idx)
+CURLcode Curl_httpsrr_set(struct Curl_easy *data,
+                          struct Curl_https_rrinfo *hi,
+                          uint16_t rrkey, const uint8_t *val, size_t vlen)
 {
-  size_t len = 0;
-  const unsigned char *val = NULL;
-  unsigned short code;
-  struct thread_data *res = &data->state.async.thdata;
-  struct Curl_https_rrinfo *hi = &res->hinfo;
-  code  = ares_dns_rr_get_opt(rr, key, idx, &val, &len);
-
-  switch(code) {
+  switch(rrkey) {
   case HTTPS_RR_CODE_ALPN: /* str_list */
-    Curl_httpsrr_decode_alpn(val, len, hi->alpns);
-    infof(data, "HTTPS RR ALPN: %u %u %u %u",
-          hi->alpns[0], hi->alpns[1], hi->alpns[2], hi->alpns[3]);
+    Curl_httpsrr_decode_alpn(val, vlen, hi->alpns);
+    CURL_TRC_DNS(data, "HTTPS RR ALPN: %u %u %u %u",
+                 hi->alpns[0], hi->alpns[1], hi->alpns[2], hi->alpns[3]);
     break;
   case HTTPS_RR_CODE_NO_DEF_ALPN:
-    infof(data, "HTTPS RR no-def-alpn");
+    hi->no_def_alpn = TRUE;
+    CURL_TRC_DNS(data, "HTTPS RR no-def-alpn");
     break;
   case HTTPS_RR_CODE_IPV4: /* addr4 list */
-    infof(data, "HTTPS RR IPv4");
+    if(!vlen)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    hi->ipv4hints = Curl_memdup(val, vlen);
+    if(!hi->ipv4hints)
+      return CURLE_OUT_OF_MEMORY;
+    hi->ipv4hints_len = vlen;
+    CURL_TRC_DNS(data, "HTTPS RR IPv4");
     break;
   case HTTPS_RR_CODE_ECH:
-    infof(data, "HTTPS RR ECH");
+    if(!vlen)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    hi->echconfiglist = Curl_memdup(val, vlen);
+    if(!hi->echconfiglist)
+      return CURLE_OUT_OF_MEMORY;
+    hi->echconfiglist_len = vlen;
+    CURL_TRC_DNS(data, "HTTPS RR ECH");
     break;
   case HTTPS_RR_CODE_IPV6: /* addr6 list */
-    infof(data, "HTTPS RR IPv6");
+    if(!vlen)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    hi->ipv6hints = Curl_memdup(val, vlen);
+    if(!hi->ipv6hints)
+      return CURLE_OUT_OF_MEMORY;
+    hi->ipv6hints_len = vlen;
+    CURL_TRC_DNS(data, "HTTPS RR IPv6");
     break;
   case HTTPS_RR_CODE_PORT:
-    infof(data, "HTTPS RR port");
+    if(vlen != 2)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    hi->port = (unsigned short)((val[0] << 8) | val[1]);
+    CURL_TRC_DNS(data, "HTTPS RR port %u", hi->port);
     break;
   default:
-    infof(data, "HTTPS RR unknown code");
+    CURL_TRC_DNS(data, "HTTPS RR unknown code");
     break;
   }
+  return CURLE_OK;
+}
+
+struct Curl_https_rrinfo *
+Curl_httpsrr_dup_move(struct Curl_https_rrinfo *rrinfo)
+{
+  struct Curl_https_rrinfo *dup = Curl_memdup(rrinfo, sizeof(*rrinfo));
+  if(dup)
+    memset(rrinfo, 0, sizeof(*rrinfo));
+  return dup;
+}
+
+void Curl_httpsrr_cleanup(struct Curl_https_rrinfo *rrinfo)
+{
+  Curl_safefree(rrinfo->target);
+  Curl_safefree(rrinfo->echconfiglist);
+  Curl_safefree(rrinfo->ipv4hints);
+  Curl_safefree(rrinfo->ipv6hints);
+}
+
+
+#ifdef USE_ARES
+
+static CURLcode httpsrr_opt(struct Curl_easy *data,
+                            const ares_dns_rr_t *rr,
+                            ares_dns_rr_key_t key, size_t idx)
+{
+  size_t len = 0;
+  const unsigned char *val = NULL;
+  unsigned short code;
+  struct thread_data *res = &data->state.async.thdata;
+  struct Curl_https_rrinfo *hi = &res->hinfo;
+
+  code  = ares_dns_rr_get_opt(rr, key, idx, &val, &len);
+  return Curl_httpsrr_set(data, hi, code, val, len);
 }
 
 void Curl_dnsrec_done_cb(void *arg, ares_status_t status,
@@ -136,6 +185,7 @@ void Curl_dnsrec_done_cb(void *arg, ares_status_t status,
                          const ares_dns_record_t *dnsrec)
 {
   struct Curl_easy *data = arg;
+  CURLcode result = CURLE_OK;
   size_t i;
 #ifdef CURLRES_ARES
   struct thread_data *res = &data->state.async.thdata;
@@ -147,6 +197,7 @@ void Curl_dnsrec_done_cb(void *arg, ares_status_t status,
     return;
 
   for(i = 0; i < ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); i++) {
+    const char *target;
     size_t opt;
     const ares_dns_rr_t *rr =
       ares_dns_record_rr_get_const(dnsrec, ARES_SECTION_ANSWER, i);
@@ -154,12 +205,26 @@ void Curl_dnsrec_done_cb(void *arg, ares_status_t status,
       continue;
     /* When SvcPriority is 0, the SVCB record is in AliasMode. Otherwise, it
        is in ServiceMode */
-    infof(data, "HTTPS RR priority: %u",
-          ares_dns_rr_get_u16(rr, ARES_RR_HTTPS_PRIORITY));
+    target = ares_dns_rr_get_str(rr, ARES_RR_HTTPS_TARGET);
+    if(target && target[0]) {
+      res->hinfo.target = strdup(target);
+      if(!res->hinfo.target) {
+        result = CURLE_OUT_OF_MEMORY;
+        goto out;
+      }
+      CURL_TRC_DNS(data, "HTTPS RR target: %s", res->hinfo.target);
+    }
+    CURL_TRC_DNS(data, "HTTPS RR priority: %u",
+                 ares_dns_rr_get_u16(rr, ARES_RR_HTTPS_PRIORITY));
     for(opt = 0; opt < ares_dns_rr_get_opt_cnt(rr, ARES_RR_HTTPS_PARAMS);
-        opt++)
-      httpsrr_opt(data, rr, ARES_RR_HTTPS_PARAMS, opt);
+        opt++) {
+      result = httpsrr_opt(data, rr, ARES_RR_HTTPS_PARAMS, opt);
+      if(result)
+        break;
+    }
   }
+out:
+  res->result = result;
 }
 
 #endif /* USE_ARES */
index ade2126f0f1dcb82aee445f37abaf83149ace9bb..847aa9abf637fc8c5962fee756592f96d2884e9a 100644 (file)
@@ -35,6 +35,8 @@
 #define CURL_MAXLEN_host_name 253
 #define MAX_HTTPSRR_ALPNS 4
 
+struct Curl_easy;
+
 struct Curl_https_rrinfo {
   /*
    * Fields from HTTPS RR. The only mandatory fields are priority and target.
@@ -53,7 +55,15 @@ struct Curl_https_rrinfo {
   uint16_t priority;
   bool no_def_alpn; /* keytag = 2 */
 };
-#endif
+
+CURLcode Curl_httpsrr_set(struct Curl_easy *data,
+                          struct Curl_https_rrinfo *hi,
+                          uint16_t rrkey, const uint8_t *val, size_t vlen);
+
+struct Curl_https_rrinfo *
+Curl_httpsrr_dup_move(struct Curl_https_rrinfo *rrinfo);
+
+void Curl_httpsrr_cleanup(struct Curl_https_rrinfo *rrinfo);
 
 /*
  * Code points for DNS wire format SvcParams as per RFC 9460
@@ -68,9 +78,12 @@ struct Curl_https_rrinfo {
 CURLcode Curl_httpsrr_decode_alpn(const unsigned char *cp, size_t len,
                                   unsigned char *alpns);
 
-#if defined(USE_ARES) && defined(USE_HTTPSRR)
+#if defined(USE_ARES)
 void Curl_dnsrec_done_cb(void *arg, ares_status_t status,
                          size_t timeouts,
                          const ares_dns_record_t *dnsrec);
-#endif
+
+#endif /* USE_ARES */
+#endif /* USE_HTTPSRR */
+
 #endif /* HEADER_CURL_HTTPSRR_H */
index 06cf8b56e046d437bddc0239bb53d9f832bfe4a3..7732387226cc0fb38f8155e7e64b78f6d6ecbc67 100755 (executable)
@@ -47,6 +47,7 @@ my %wl = (
     'Curl_creader_def_close' => 'internal api',
     'Curl_creader_def_read' => 'internal api',
     'Curl_creader_def_total_length' => 'internal api',
+    'Curl_trc_dns' => 'internal api',
 );
 
 my %api = (