mirror of
https://github.com/curl/curl.git
synced 2024-12-15 06:40:09 +08:00
doh: allocate state struct on demand
... instead of having it static within the Curl_easy struct. This takes away 1176 bytes (18%) from the Curl_easy struct that aren't used very often and instead makes the code allocate it when needed. Closes #6492
This commit is contained in:
parent
d0688dcbdf
commit
6246a1d8c6
69
lib/doh.c
69
lib/doh.c
@ -190,16 +190,17 @@ doh_write_cb(const void *contents, size_t size, size_t nmemb, void *userp)
|
|||||||
static int doh_done(struct Curl_easy *doh, CURLcode result)
|
static int doh_done(struct Curl_easy *doh, CURLcode result)
|
||||||
{
|
{
|
||||||
struct Curl_easy *data = doh->set.dohfor;
|
struct Curl_easy *data = doh->set.dohfor;
|
||||||
|
struct dohdata *dohp = data->req.doh;
|
||||||
/* so one of the DOH request done for the 'data' transfer is now complete! */
|
/* so one of the DOH request done for the 'data' transfer is now complete! */
|
||||||
data->req.doh.pending--;
|
dohp->pending--;
|
||||||
infof(data, "a DOH request is completed, %u to go\n", data->req.doh.pending);
|
infof(data, "a DOH request is completed, %u to go\n", dohp->pending);
|
||||||
if(result)
|
if(result)
|
||||||
infof(data, "DOH request %s\n", curl_easy_strerror(result));
|
infof(data, "DOH request %s\n", curl_easy_strerror(result));
|
||||||
|
|
||||||
if(!data->req.doh.pending) {
|
if(!dohp->pending) {
|
||||||
/* DOH completed */
|
/* DOH completed */
|
||||||
curl_slist_free_all(data->req.doh.headers);
|
curl_slist_free_all(dohp->headers);
|
||||||
data->req.doh.headers = NULL;
|
dohp->headers = NULL;
|
||||||
Curl_expire(data, 0, EXPIRE_RUN_NOW);
|
Curl_expire(data, 0, EXPIRE_RUN_NOW);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -386,50 +387,56 @@ struct Curl_addrinfo *Curl_doh(struct connectdata *conn,
|
|||||||
struct Curl_easy *data = conn->data;
|
struct Curl_easy *data = conn->data;
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
int slot;
|
int slot;
|
||||||
|
struct dohdata *dohp;
|
||||||
*waitp = TRUE; /* this never returns synchronously */
|
*waitp = TRUE; /* this never returns synchronously */
|
||||||
(void)conn;
|
(void)conn;
|
||||||
(void)hostname;
|
(void)hostname;
|
||||||
(void)port;
|
(void)port;
|
||||||
|
|
||||||
|
DEBUGASSERT(!data->req.doh);
|
||||||
|
|
||||||
/* start clean, consider allocating this struct on demand */
|
/* start clean, consider allocating this struct on demand */
|
||||||
memset(&data->req.doh, 0, sizeof(struct dohdata));
|
dohp = data->req.doh = calloc(sizeof(struct dohdata), 1);
|
||||||
|
if(!dohp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
conn->bits.doh = TRUE;
|
conn->bits.doh = TRUE;
|
||||||
data->req.doh.host = hostname;
|
dohp->host = hostname;
|
||||||
data->req.doh.port = port;
|
dohp->port = port;
|
||||||
data->req.doh.headers =
|
dohp->headers =
|
||||||
curl_slist_append(NULL,
|
curl_slist_append(NULL,
|
||||||
"Content-Type: application/dns-message");
|
"Content-Type: application/dns-message");
|
||||||
if(!data->req.doh.headers)
|
if(!dohp->headers)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if(conn->ip_version != CURL_IPRESOLVE_V6) {
|
if(conn->ip_version != CURL_IPRESOLVE_V6) {
|
||||||
/* create IPv4 DOH request */
|
/* create IPv4 DOH request */
|
||||||
result = dohprobe(data, &data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V4],
|
result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V4],
|
||||||
DNS_TYPE_A, hostname, data->set.str[STRING_DOH],
|
DNS_TYPE_A, hostname, data->set.str[STRING_DOH],
|
||||||
data->multi, data->req.doh.headers);
|
data->multi, dohp->headers);
|
||||||
if(result)
|
if(result)
|
||||||
goto error;
|
goto error;
|
||||||
data->req.doh.pending++;
|
dohp->pending++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conn->ip_version != CURL_IPRESOLVE_V4) {
|
if(conn->ip_version != CURL_IPRESOLVE_V4) {
|
||||||
/* create IPv6 DOH request */
|
/* create IPv6 DOH request */
|
||||||
result = dohprobe(data, &data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V6],
|
result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V6],
|
||||||
DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH],
|
DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH],
|
||||||
data->multi, data->req.doh.headers);
|
data->multi, dohp->headers);
|
||||||
if(result)
|
if(result)
|
||||||
goto error;
|
goto error;
|
||||||
data->req.doh.pending++;
|
dohp->pending++;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
curl_slist_free_all(data->req.doh.headers);
|
curl_slist_free_all(dohp->headers);
|
||||||
data->req.doh.headers = NULL;
|
data->req.doh->headers = NULL;
|
||||||
for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
|
for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
|
||||||
Curl_close(&data->req.doh.probe[slot].easy);
|
Curl_close(&dohp->probe[slot].easy);
|
||||||
}
|
}
|
||||||
|
Curl_safefree(data->req.doh);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -909,15 +916,16 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
struct Curl_easy *data = conn->data;
|
struct Curl_easy *data = conn->data;
|
||||||
|
struct dohdata *dohp = data->req.doh;
|
||||||
*dnsp = NULL; /* defaults to no response */
|
*dnsp = NULL; /* defaults to no response */
|
||||||
|
|
||||||
if(!data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V4].easy &&
|
if(!dohp->probe[DOH_PROBE_SLOT_IPADDR_V4].easy &&
|
||||||
!data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V6].easy) {
|
!dohp->probe[DOH_PROBE_SLOT_IPADDR_V6].easy) {
|
||||||
failf(data, "Could not DOH-resolve: %s", conn->async.hostname);
|
failf(data, "Could not DOH-resolve: %s", conn->async.hostname);
|
||||||
return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
|
return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
|
||||||
CURLE_COULDNT_RESOLVE_HOST;
|
CURLE_COULDNT_RESOLVE_HOST;
|
||||||
}
|
}
|
||||||
else if(!data->req.doh.pending) {
|
else if(!dohp->pending) {
|
||||||
DOHcode rc[DOH_PROBE_SLOTS] = {
|
DOHcode rc[DOH_PROBE_SLOTS] = {
|
||||||
DOH_OK, DOH_OK
|
DOH_OK, DOH_OK
|
||||||
};
|
};
|
||||||
@ -925,13 +933,13 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
|||||||
int slot;
|
int slot;
|
||||||
/* remove DOH handles from multi handle and close them */
|
/* remove DOH handles from multi handle and close them */
|
||||||
for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
|
for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
|
||||||
curl_multi_remove_handle(data->multi, data->req.doh.probe[slot].easy);
|
curl_multi_remove_handle(data->multi, dohp->probe[slot].easy);
|
||||||
Curl_close(&data->req.doh.probe[slot].easy);
|
Curl_close(&dohp->probe[slot].easy);
|
||||||
}
|
}
|
||||||
/* parse the responses, create the struct and return it! */
|
/* parse the responses, create the struct and return it! */
|
||||||
de_init(&de);
|
de_init(&de);
|
||||||
for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
|
for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
|
||||||
struct dnsprobe *p = &data->req.doh.probe[slot];
|
struct dnsprobe *p = &dohp->probe[slot];
|
||||||
if(!p->dnstype)
|
if(!p->dnstype)
|
||||||
continue;
|
continue;
|
||||||
rc[slot] = doh_decode(Curl_dyn_uptr(&p->serverdoh),
|
rc[slot] = doh_decode(Curl_dyn_uptr(&p->serverdoh),
|
||||||
@ -941,7 +949,7 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
|||||||
Curl_dyn_free(&p->serverdoh);
|
Curl_dyn_free(&p->serverdoh);
|
||||||
if(rc[slot]) {
|
if(rc[slot]) {
|
||||||
infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc[slot]),
|
infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc[slot]),
|
||||||
type2name(p->dnstype), data->req.doh.host);
|
type2name(p->dnstype), dohp->host);
|
||||||
}
|
}
|
||||||
} /* next slot */
|
} /* next slot */
|
||||||
|
|
||||||
@ -951,10 +959,10 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
|||||||
struct Curl_dns_entry *dns;
|
struct Curl_dns_entry *dns;
|
||||||
struct Curl_addrinfo *ai;
|
struct Curl_addrinfo *ai;
|
||||||
|
|
||||||
infof(data, "DOH Host name: %s\n", data->req.doh.host);
|
infof(data, "DOH Host name: %s\n", dohp->host);
|
||||||
showdoh(data, &de);
|
showdoh(data, &de);
|
||||||
|
|
||||||
ai = doh2ai(&de, data->req.doh.host, data->req.doh.port);
|
ai = doh2ai(&de, dohp->host, dohp->port);
|
||||||
if(!ai) {
|
if(!ai) {
|
||||||
de_cleanup(&de);
|
de_cleanup(&de);
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
@ -964,7 +972,7 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
|||||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||||
|
|
||||||
/* we got a response, store it in the cache */
|
/* we got a response, store it in the cache */
|
||||||
dns = Curl_cache_addr(data, ai, data->req.doh.host, data->req.doh.port);
|
dns = Curl_cache_addr(data, ai, dohp->host, dohp->port);
|
||||||
|
|
||||||
if(data->share)
|
if(data->share)
|
||||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||||
@ -984,9 +992,10 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
|||||||
|
|
||||||
/* All done */
|
/* All done */
|
||||||
de_cleanup(&de);
|
de_cleanup(&de);
|
||||||
|
Curl_safefree(data->req.doh);
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
} /* !data->req.doh.pending */
|
} /* !dohp->pending */
|
||||||
|
|
||||||
/* else wait for pending DOH transactions to complete */
|
/* else wait for pending DOH transactions to complete */
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
15
lib/url.c
15
lib/url.c
@ -451,9 +451,12 @@ CURLcode Curl_close(struct Curl_easy **datap)
|
|||||||
Curl_safefree(data->state.aptr.rtsp_transport);
|
Curl_safefree(data->state.aptr.rtsp_transport);
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_DOH
|
#ifndef CURL_DISABLE_DOH
|
||||||
Curl_dyn_free(&data->req.doh.probe[0].serverdoh);
|
if(data->req.doh) {
|
||||||
Curl_dyn_free(&data->req.doh.probe[1].serverdoh);
|
Curl_dyn_free(&data->req.doh->probe[0].serverdoh);
|
||||||
curl_slist_free_all(data->req.doh.headers);
|
Curl_dyn_free(&data->req.doh->probe[1].serverdoh);
|
||||||
|
curl_slist_free_all(data->req.doh->headers);
|
||||||
|
Curl_safefree(data->req.doh);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* destruct wildcard structures if it is needed */
|
/* destruct wildcard structures if it is needed */
|
||||||
@ -2138,8 +2141,10 @@ void Curl_free_request_state(struct Curl_easy *data)
|
|||||||
Curl_safefree(data->req.newurl);
|
Curl_safefree(data->req.newurl);
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_DOH
|
#ifndef CURL_DISABLE_DOH
|
||||||
Curl_close(&data->req.doh.probe[0].easy);
|
if(data->req.doh) {
|
||||||
Curl_close(&data->req.doh.probe[1].easy);
|
Curl_close(&data->req.doh->probe[0].easy);
|
||||||
|
Curl_close(&data->req.doh->probe[1].easy);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,7 +682,7 @@ struct SingleRequest {
|
|||||||
struct TELNET *telnet;
|
struct TELNET *telnet;
|
||||||
} p;
|
} p;
|
||||||
#ifndef CURL_DISABLE_DOH
|
#ifndef CURL_DISABLE_DOH
|
||||||
struct dohdata doh; /* DoH specific data for this request */
|
struct dohdata *doh; /* DoH specific data for this request */
|
||||||
#endif
|
#endif
|
||||||
BIT(header); /* incoming data has HTTP header */
|
BIT(header); /* incoming data has HTTP header */
|
||||||
BIT(content_range); /* set TRUE if Content-Range: was found */
|
BIT(content_range); /* set TRUE if Content-Range: was found */
|
||||||
|
Loading…
Reference in New Issue
Block a user