]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
doh: allocate state struct on demand
authorDaniel Stenberg <daniel@haxx.se>
Tue, 19 Jan 2021 14:57:24 +0000 (15:57 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 20 Jan 2021 08:02:24 +0000 (09:02 +0100)
... 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

lib/doh.c
lib/url.c
lib/urldata.h

index c6377fef4c05f6de71963cf9bd15c269155923ca..f9feabacc064b0b6cffa62feb83fbe0ede78c657 100644 (file)
--- a/lib/doh.c
+++ b/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)
 {
   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! */
-  data->req.doh.pending--;
-  infof(data, "a DOH request is completed, %u to go\n", data->req.doh.pending);
+  dohp->pending--;
+  infof(data, "a DOH request is completed, %u to go\n", dohp->pending);
   if(result)
     infof(data, "DOH request %s\n", curl_easy_strerror(result));
 
-  if(!data->req.doh.pending) {
+  if(!dohp->pending) {
     /* DOH completed */
-    curl_slist_free_all(data->req.doh.headers);
-    data->req.doh.headers = NULL;
+    curl_slist_free_all(dohp->headers);
+    dohp->headers = NULL;
     Curl_expire(data, 0, EXPIRE_RUN_NOW);
   }
   return 0;
@@ -386,50 +387,56 @@ struct Curl_addrinfo *Curl_doh(struct connectdata *conn,
   struct Curl_easy *data = conn->data;
   CURLcode result = CURLE_OK;
   int slot;
+  struct dohdata *dohp;
   *waitp = TRUE; /* this never returns synchronously */
   (void)conn;
   (void)hostname;
   (void)port;
 
+  DEBUGASSERT(!data->req.doh);
+
   /* 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;
-  data->req.doh.host = hostname;
-  data->req.doh.port = port;
-  data->req.doh.headers =
+  dohp->host = hostname;
+  dohp->port = port;
+  dohp->headers =
     curl_slist_append(NULL,
                       "Content-Type: application/dns-message");
-  if(!data->req.doh.headers)
+  if(!dohp->headers)
     goto error;
 
   if(conn->ip_version != CURL_IPRESOLVE_V6) {
     /* 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],
-                      data->multi, data->req.doh.headers);
+                      data->multi, dohp->headers);
     if(result)
       goto error;
-    data->req.doh.pending++;
+    dohp->pending++;
   }
 
   if(conn->ip_version != CURL_IPRESOLVE_V4) {
     /* 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],
-                      data->multi, data->req.doh.headers);
+                      data->multi, dohp->headers);
     if(result)
       goto error;
-    data->req.doh.pending++;
+    dohp->pending++;
   }
   return NULL;
 
   error:
-  curl_slist_free_all(data->req.doh.headers);
-  data->req.doh.headers = NULL;
+  curl_slist_free_all(dohp->headers);
+  data->req.doh->headers = NULL;
   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;
 }
 
@@ -909,15 +916,16 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
 {
   CURLcode result;
   struct Curl_easy *data = conn->data;
+  struct dohdata *dohp = data->req.doh;
   *dnsp = NULL; /* defaults to no response */
 
-  if(!data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V4].easy &&
-     !data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V6].easy) {
+  if(!dohp->probe[DOH_PROBE_SLOT_IPADDR_V4].easy &&
+     !dohp->probe[DOH_PROBE_SLOT_IPADDR_V6].easy) {
     failf(data, "Could not DOH-resolve: %s", conn->async.hostname);
     return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
       CURLE_COULDNT_RESOLVE_HOST;
   }
-  else if(!data->req.doh.pending) {
+  else if(!dohp->pending) {
     DOHcode rc[DOH_PROBE_SLOTS] = {
       DOH_OK, DOH_OK
     };
@@ -925,13 +933,13 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
     int slot;
     /* remove DOH handles from multi handle and close them */
     for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
-      curl_multi_remove_handle(data->multi, data->req.doh.probe[slot].easy);
-      Curl_close(&data->req.doh.probe[slot].easy);
+      curl_multi_remove_handle(data->multi, dohp->probe[slot].easy);
+      Curl_close(&dohp->probe[slot].easy);
     }
     /* parse the responses, create the struct and return it! */
     de_init(&de);
     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)
         continue;
       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);
       if(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 */
 
@@ -951,10 +959,10 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
       struct Curl_dns_entry *dns;
       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);
 
-      ai = doh2ai(&de, data->req.doh.host, data->req.doh.port);
+      ai = doh2ai(&de, dohp->host, dohp->port);
       if(!ai) {
         de_cleanup(&de);
         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);
 
       /* 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)
         Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
@@ -984,9 +992,10 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
 
     /* All done */
     de_cleanup(&de);
+    Curl_safefree(data->req.doh);
     return result;
 
-  } /* !data->req.doh.pending */
+  } /* !dohp->pending */
 
   /* else wait for pending DOH transactions to complete */
   return CURLE_OK;
index 4a145b028e6cd5c77b71d6afebfcacef97ffd0e1..fe6c9a1f27cddc6d8523e6d95bd1bdfc517f21c8 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -451,9 +451,12 @@ CURLcode Curl_close(struct Curl_easy **datap)
   Curl_safefree(data->state.aptr.rtsp_transport);
 
 #ifndef CURL_DISABLE_DOH
-  Curl_dyn_free(&data->req.doh.probe[0].serverdoh);
-  Curl_dyn_free(&data->req.doh.probe[1].serverdoh);
-  curl_slist_free_all(data->req.doh.headers);
+  if(data->req.doh) {
+    Curl_dyn_free(&data->req.doh->probe[0].serverdoh);
+    Curl_dyn_free(&data->req.doh->probe[1].serverdoh);
+    curl_slist_free_all(data->req.doh->headers);
+    Curl_safefree(data->req.doh);
+  }
 #endif
 
   /* 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);
 
 #ifndef CURL_DISABLE_DOH
-  Curl_close(&data->req.doh.probe[0].easy);
-  Curl_close(&data->req.doh.probe[1].easy);
+  if(data->req.doh) {
+    Curl_close(&data->req.doh->probe[0].easy);
+    Curl_close(&data->req.doh->probe[1].easy);
+  }
 #endif
 }
 
index 0038e580aa1aa140d51615d358c3eec80aa7691f..f482f1c8a1185300f94bf192a9fe46fa8ea0bb06 100644 (file)
@@ -682,7 +682,7 @@ struct SingleRequest {
     struct TELNET *telnet;
   } p;
 #ifndef CURL_DISABLE_DOH
-  struct dohdata doh; /* DoH specific data for this request */
+  struct dohdata *doh; /* DoH specific data for this request */
 #endif
   BIT(header);       /* incoming data has HTTP header */
   BIT(content_range); /* set TRUE if Content-Range: was found */