]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
httpsrr: send HTTPS query to the right target
authorDaniel Stenberg <daniel@haxx.se>
Sat, 1 Nov 2025 19:21:25 +0000 (20:21 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Sat, 1 Nov 2025 22:13:30 +0000 (23:13 +0100)
When the target host is on a different port than 443, the name
"_[port]._https.[name]" shall be used.

Fixes #19301
Reported-by: Gunni on github
Closes #19324

lib/asyn-ares.c
lib/asyn-thrdd.c
lib/httpsrr.c
lib/httpsrr.h
tests/data/test2100

index 094d703ec0c0ea00b2396b7c1db27e3b562521df..09c94f97b8f13e7624214594aee2aed3e865bde3 100644 (file)
@@ -730,6 +730,9 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
                                              int *waitp)
 {
   struct async_ares_ctx *ares = &data->state.async.ares;
+#ifdef USE_HTTPSRR
+  char *rrname = NULL;
+#endif
   *waitp = 0; /* default to synchronous response */
 
   if(async_ares_init_lazy(data))
@@ -742,6 +745,15 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
   data->state.async.hostname = strdup(hostname);
   if(!data->state.async.hostname)
     return NULL;
+#ifdef USE_HTTPSRR
+  if(port != 443) {
+    rrname = curl_maprintf("_%d_.https.%s", port, hostname);
+    if(!rrname) {
+      free(data->state.async.hostname);
+      return NULL;
+    }
+  }
+#endif
 
   /* initial status - failed */
   ares->ares_status = ARES_ENOTFOUND;
@@ -814,11 +826,14 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
 #endif
 #ifdef USE_HTTPSRR
   {
-    CURL_TRC_DNS(data, "asyn-ares: fire off query for HTTPSRR");
+    CURL_TRC_DNS(data, "asyn-ares: fire off query for HTTPSRR: %s",
+                 rrname ? rrname : data->state.async.hostname);
     memset(&ares->hinfo, 0, sizeof(ares->hinfo));
     ares->hinfo.port = -1;
+    ares->hinfo.rrname = rrname;
     ares->num_pending++; /* one more */
-    ares_query_dnsrec(ares->channel, data->state.async.hostname,
+    ares_query_dnsrec(ares->channel,
+                      rrname ? rrname : data->state.async.hostname,
                       ARES_CLASS_IN, ARES_REC_TYPE_HTTPS,
                       async_ares_rr_done, data, NULL);
   }
index cb19f8645254c3b4a73b6aa0816a5bd7fec9081f..da83cca87a76c98c6bf906996bf41e4f525ffbd7 100644 (file)
@@ -361,12 +361,18 @@ static void async_thrdd_rr_done(void *user_data, ares_status_t status,
   thrdd->rr.result = Curl_httpsrr_from_ares(data, dnsrec, &thrdd->rr.hinfo);
 }
 
-static CURLcode async_rr_start(struct Curl_easy *data)
+static CURLcode async_rr_start(struct Curl_easy *data, int port)
 {
   struct async_thrdd_ctx *thrdd = &data->state.async.thrdd;
   int status;
+  char *rrname = NULL;
 
   DEBUGASSERT(!thrdd->rr.channel);
+  if(port != 443) {
+    rrname = curl_maprintf("_%d_.https.%s", port, data->conn->host.name);
+    if(!rrname)
+      return CURLE_OUT_OF_MEMORY;
+  }
   status = ares_init_options(&thrdd->rr.channel, NULL, 0);
   if(status != ARES_SUCCESS) {
     thrdd->rr.channel = NULL;
@@ -383,8 +389,9 @@ static CURLcode async_rr_start(struct Curl_easy *data)
 
   memset(&thrdd->rr.hinfo, 0, sizeof(thrdd->rr.hinfo));
   thrdd->rr.hinfo.port = -1;
+  thrdd->rr.hinfo.rrname = rrname;
   ares_query_dnsrec(thrdd->rr.channel,
-                    data->conn->host.name, ARES_CLASS_IN,
+                    rrname ? rrname : data->conn->host.name, ARES_CLASS_IN,
                     ARES_REC_TYPE_HTTPS,
                     async_thrdd_rr_done, data, NULL);
   CURL_TRC_DNS(data, "Issued HTTPS-RR request for %s", data->conn->host.name);
@@ -454,7 +461,7 @@ static bool async_thrdd_init(struct Curl_easy *data,
   }
 
 #ifdef USE_HTTPSRR_ARES
-  if(async_rr_start(data))
+  if(async_rr_start(data, port))
     infof(data, "Failed HTTPS RR operation");
 #endif
   CURL_TRC_DNS(data, "resolve thread started for of %s:%d", hostname, port);
index ae2c106bcef298dafacc0b9126bb82d2442c32a0..f0d7ea14f141044a00bb0240ad3051272b8ee36a 100644 (file)
@@ -152,6 +152,7 @@ void Curl_httpsrr_cleanup(struct Curl_https_rrinfo *rrinfo)
   Curl_safefree(rrinfo->echconfiglist);
   Curl_safefree(rrinfo->ipv4hints);
   Curl_safefree(rrinfo->ipv6hints);
+  Curl_safefree(rrinfo->rrname);
 }
 
 
@@ -206,6 +207,7 @@ CURLcode Curl_httpsrr_from_ares(struct Curl_easy *data,
     }
   }
 out:
+  Curl_safefree(hinfo->rrname);
   return result;
 }
 
index 563d1c8e515bc4215d2d8f9138df2bc4a54a5d9c..9b7831f75cbcb522ef141172b1815c66fde04986 100644 (file)
@@ -38,6 +38,7 @@
 struct Curl_easy;
 
 struct Curl_https_rrinfo {
+  char *rrname; /* if NULL, the same as the URL hostname */
   /*
    * Fields from HTTPS RR. The only mandatory fields are priority and target.
    * See https://datatracker.ietf.org/doc/html/rfc9460#section-14.3.2
index a5e809c6eff3ab13d6df9848960b31db74968908..9d75e72b8176c3cfa1e0410f8b56c5ba8b773107 100644 (file)
@@ -4,6 +4,7 @@
 HTTP
 HTTP GET
 DOH
+httpsrr
 </keywords>
 </info>