Commit 2caa454d authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

resolve: don't leak pre-populated dns entries

CURLOPT_RESOLVE populates the DNS cache with entries that are marked as
eternally in use. Those entries need to be taken care of when the cache
is killed off.

Bug: http://curl.haxx.se/bug/view.cgi?id=3463121
Reported by: "tw84452852"
parent 3e4181f8
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -721,4 +721,25 @@ struct curl_hash *Curl_mk_dnscache(void)
  return Curl_hash_alloc(7, Curl_hash_str, Curl_str_key_compare, freednsentry);
}

static int hostcache_inuse(void *data, void *hc)
{
  struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc;

  if(c->inuse == 1)
    Curl_resolv_unlock(data, c);

  return 1; /* free all entries */
}

void Curl_hostcache_destroy(struct SessionHandle *data)
{
  /* Entries added to the hostcache with the CURLOPT_RESOLVE function are
   * still present in the cache with the inuse counter set to 1. Detect them
   * and cleanup!
   */
  Curl_hash_clean_with_criterium(data->dns.hostcache, data, hostcache_inuse);

  Curl_hash_destroy(data->dns.hostcache);
  data->dns.hostcachetype = HCACHE_NONE;
  data->dns.hostcache = NULL;
}
+5 −0
Original line number Diff line number Diff line
@@ -200,4 +200,9 @@ extern sigjmp_buf curl_jmpenv;
 */
CURLcode Curl_set_dns_servers(struct SessionHandle *data, char *servers);

/*
 * Destroy the hostcache of this handle.
 */
void Curl_hostcache_destroy(struct SessionHandle *data);

#endif /* HEADER_CURL_HOSTIP_H */
+3 −12
Original line number Diff line number Diff line
@@ -467,11 +467,8 @@ CURLcode Curl_close(struct SessionHandle *data)
    return CURLE_OK;
  }

  if(data->dns.hostcachetype == HCACHE_PRIVATE) {
    Curl_hash_destroy(data->dns.hostcache);
    data->dns.hostcachetype = HCACHE_NONE;
    data->dns.hostcache = NULL;
  }
  if(data->dns.hostcachetype == HCACHE_PRIVATE)
    Curl_hostcache_destroy(data);

  if(data->state.rangestringalloc)
    free(data->state.range);
@@ -2131,7 +2128,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
      if(data->share->hostcache) {
        /* use shared host cache, first free the private one if any */
        if(data->dns.hostcachetype == HCACHE_PRIVATE)
          Curl_hash_destroy(data->dns.hostcache);
          Curl_hostcache_destroy(data);

        data->dns.hostcache = data->share->hostcache;
        data->dns.hostcachetype = HCACHE_SHARED;
@@ -2626,12 +2623,6 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
    conn->dns_entry = NULL;
  }

#if defined(DEBUGBUILD) && defined(AGGRESIVE_TEST)
  /* scan for DNS cache entries still marked as in use */
  Curl_hash_apply(data->hostcache,
                  NULL, Curl_scan_cache_used);
#endif

  Curl_hostcache_prune(data); /* kill old DNS cache entries */

  {