mirror of
https://github.com/curl/curl.git
synced 2026-04-15 05:01:42 +03:00
https-rr: implementation improvements
- 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
This commit is contained in:
parent
db72b8d4d0
commit
1b710381ca
12 changed files with 174 additions and 103 deletions
131
lib/httpsrr.c
131
lib/httpsrr.c
|
|
@ -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;
|
||||
}
|
||||
|
||||
CURLcode Curl_httpsrr_set(struct Curl_easy *data,
|
||||
struct Curl_https_rrinfo *hi,
|
||||
uint16_t rrkey, const uint8_t *val, size_t vlen)
|
||||
{
|
||||
switch(rrkey) {
|
||||
case HTTPS_RR_CODE_ALPN: /* str_list */
|
||||
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:
|
||||
hi->no_def_alpn = TRUE;
|
||||
CURL_TRC_DNS(data, "HTTPS RR no-def-alpn");
|
||||
break;
|
||||
case HTTPS_RR_CODE_IPV4: /* addr4 list */
|
||||
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:
|
||||
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 */
|
||||
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:
|
||||
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:
|
||||
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 void httpsrr_opt(struct Curl_easy *data,
|
||||
const ares_dns_rr_t *rr,
|
||||
ares_dns_rr_key_t key, size_t idx)
|
||||
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);
|
||||
|
||||
switch(code) {
|
||||
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]);
|
||||
break;
|
||||
case HTTPS_RR_CODE_NO_DEF_ALPN:
|
||||
infof(data, "HTTPS RR no-def-alpn");
|
||||
break;
|
||||
case HTTPS_RR_CODE_IPV4: /* addr4 list */
|
||||
infof(data, "HTTPS RR IPv4");
|
||||
break;
|
||||
case HTTPS_RR_CODE_ECH:
|
||||
infof(data, "HTTPS RR ECH");
|
||||
break;
|
||||
case HTTPS_RR_CODE_IPV6: /* addr6 list */
|
||||
infof(data, "HTTPS RR IPv6");
|
||||
break;
|
||||
case HTTPS_RR_CODE_PORT:
|
||||
infof(data, "HTTPS RR port");
|
||||
break;
|
||||
default:
|
||||
infof(data, "HTTPS RR unknown code");
|
||||
break;
|
||||
}
|
||||
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 */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue