From: Daniel Stenberg Date: Sat, 1 Nov 2025 19:21:25 +0000 (+0100) Subject: httpsrr: send HTTPS query to the right target X-Git-Tag: curl-8_17_0~36 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8d0bfe74fba1e8394e73d2577c8a30b65f86b86f;p=thirdparty%2Fcurl.git httpsrr: send HTTPS query to the right target 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 --- diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c index 094d703ec0..09c94f97b8 100644 --- a/lib/asyn-ares.c +++ b/lib/asyn-ares.c @@ -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); } diff --git a/lib/asyn-thrdd.c b/lib/asyn-thrdd.c index cb19f86452..da83cca87a 100644 --- a/lib/asyn-thrdd.c +++ b/lib/asyn-thrdd.c @@ -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); diff --git a/lib/httpsrr.c b/lib/httpsrr.c index ae2c106bce..f0d7ea14f1 100644 --- a/lib/httpsrr.c +++ b/lib/httpsrr.c @@ -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; } diff --git a/lib/httpsrr.h b/lib/httpsrr.h index 563d1c8e51..9b7831f75c 100644 --- a/lib/httpsrr.h +++ b/lib/httpsrr.h @@ -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 diff --git a/tests/data/test2100 b/tests/data/test2100 index a5e809c6ef..9d75e72b81 100644 --- a/tests/data/test2100 +++ b/tests/data/test2100 @@ -4,6 +4,7 @@ HTTP HTTP GET DOH +httpsrr