From 81a9fe4e92e263621c2117fdeb1603fe576006ad Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 10 Feb 2019 00:10:18 +0100 Subject: hostip: make create_hostcache_id avoid alloc + free Closes #3544 --- lib/hostip.c | 93 ++++++++++++++++-------------------------------------------- 1 file changed, 24 insertions(+), 69 deletions(-) (limited to 'lib') diff --git a/lib/hostip.c b/lib/hostip.c index 8a62a34ec..0c6615986 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -73,6 +73,8 @@ #define USE_ALARM_TIMEOUT #endif +#define MAX_HOSTCACHE_LEN (255 + 7) /* max FQDN + colon + port number + zero */ + /* * hostip.c explained * ================== @@ -198,23 +200,19 @@ Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize) } /* - * Return a hostcache id string for the provided host + port, to be used by - * the DNS caching. + * Create a hostcache id string for the provided host + port, to be used by + * the DNS caching. Without alloc. */ -static char * -create_hostcache_id(const char *name, int port) +static void +create_hostcache_id(const char *name, int port, char *ptr, size_t buflen) { - /* create and return the new allocated entry */ - char *id = aprintf("%s:%d", name, port); - char *ptr = id; - if(ptr) { - /* lower case the name part */ - while(*ptr && (*ptr != ':')) { - *ptr = (char)TOLOWER(*ptr); - ptr++; - } - } - return id; + size_t len = strlen(name); + if(len > (buflen - 7)) + len = buflen - 7; + /* store and lower case the name */ + while(len--) + *ptr++ = (char)TOLOWER(*name++); + msnprintf(ptr, 7, ":%u", port); } struct hostcache_prune_data { @@ -296,17 +294,13 @@ fetch_addr(struct connectdata *conn, const char *hostname, int port) { - char *entry_id = NULL; struct Curl_dns_entry *dns = NULL; size_t entry_len; struct Curl_easy *data = conn->data; + char entry_id[MAX_HOSTCACHE_LEN]; /* Create an entry id, based upon the hostname and port */ - entry_id = create_hostcache_id(hostname, port); - /* If we can't create the entry id, fail */ - if(!entry_id) - return dns; - + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); entry_len = strlen(entry_id); /* See if its already in our dns cache */ @@ -314,18 +308,7 @@ fetch_addr(struct connectdata *conn, /* No entry found in cache, check if we might have a wildcard entry */ if(!dns && data->change.wildcard_resolve) { - /* - * Free the previous entry_id before requesting a new one to avoid leaking - * memory - */ - free(entry_id); - - entry_id = create_hostcache_id("*", port); - - /* If we can't create the entry id, fail */ - if(!entry_id) - return dns; - + create_hostcache_id("*", port, entry_id, sizeof(entry_id)); entry_len = strlen(entry_id); /* See if it's already in our dns cache */ @@ -346,9 +329,6 @@ fetch_addr(struct connectdata *conn, } } - /* free the allocated entry_id again */ - free(entry_id); - return dns; } @@ -471,7 +451,7 @@ Curl_cache_addr(struct Curl_easy *data, const char *hostname, int port) { - char *entry_id; + char entry_id[MAX_HOSTCACHE_LEN]; size_t entry_len; struct Curl_dns_entry *dns; struct Curl_dns_entry *dns2; @@ -483,20 +463,16 @@ Curl_cache_addr(struct Curl_easy *data, return NULL; } - /* Create an entry id, based upon the hostname and port */ - entry_id = create_hostcache_id(hostname, port); - /* If we can't create the entry id, fail */ - if(!entry_id) - return NULL; - entry_len = strlen(entry_id); - /* Create a new cache entry */ dns = calloc(1, sizeof(struct Curl_dns_entry)); if(!dns) { - free(entry_id); return NULL; } + /* Create an entry id, based upon the hostname and port */ + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); + entry_len = strlen(entry_id); + dns->inuse = 1; /* the cache has the first reference */ dns->addr = addr; /* this is the address(es) */ time(&dns->timestamp); @@ -508,16 +484,11 @@ Curl_cache_addr(struct Curl_easy *data, (void *)dns); if(!dns2) { free(dns); - free(entry_id); return NULL; } dns = dns2; dns->inuse++; /* mark entry as in-use */ - - /* free the allocated entry_id */ - free(entry_id); - return dns; } @@ -900,10 +871,10 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) data->change.wildcard_resolve = false; for(hostp = data->change.resolve; hostp; hostp = hostp->next) { + char entry_id[MAX_HOSTCACHE_LEN]; if(!hostp->data) continue; if(hostp->data[0] == '-') { - char *entry_id; size_t entry_len; if(2 != sscanf(hostp->data + 1, "%255[^:]:%d", hostname, &port)) { @@ -913,12 +884,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) } /* Create an entry id, based upon the hostname and port */ - entry_id = create_hostcache_id(hostname, port); - /* If we can't create the entry id, fail */ - if(!entry_id) { - return CURLE_OUT_OF_MEMORY; - } - + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); entry_len = strlen(entry_id); if(data->share) @@ -929,14 +895,10 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) if(data->share) Curl_share_unlock(data, CURL_LOCK_DATA_DNS); - - /* free the allocated entry_id again */ - free(entry_id); } else { struct Curl_dns_entry *dns; Curl_addrinfo *head = NULL, *tail = NULL; - char *entry_id; size_t entry_len; char address[64]; #if !defined(CURL_DISABLE_VERBOSE_STRINGS) @@ -1032,12 +994,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) } /* Create an entry id, based upon the hostname and port */ - entry_id = create_hostcache_id(hostname, port); - /* If we can't create the entry id, fail */ - if(!entry_id) { - Curl_freeaddrinfo(head); - return CURLE_OUT_OF_MEMORY; - } + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); entry_len = strlen(entry_id); if(data->share) @@ -1058,8 +1015,6 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1); } - /* free the allocated entry_id again */ - free(entry_id); /* put this new host in the cache */ dns = Curl_cache_addr(data, head, hostname, port); -- cgit v1.2.3