mirror of
https://github.com/moparisthebest/curl
synced 2024-12-23 08:38:49 -05:00
Curl_addrinfo: use one malloc instead of three
To reduce the amount of allocations needed for creating a Curl_addrinfo struct, make a single larger malloc instead of three separate smaller ones. Closes #5533
This commit is contained in:
parent
5277775462
commit
54d3769761
@ -83,11 +83,8 @@ Curl_freeaddrinfo(struct Curl_addrinfo *cahead)
|
||||
struct Curl_addrinfo *vqualifier canext;
|
||||
struct Curl_addrinfo *ca;
|
||||
|
||||
for(ca = cahead; ca != NULL; ca = canext) {
|
||||
free(ca->ai_addr);
|
||||
free(ca->ai_canonname);
|
||||
for(ca = cahead; ca; ca = canext) {
|
||||
canext = ca->ai_next;
|
||||
|
||||
free(ca);
|
||||
}
|
||||
}
|
||||
@ -131,7 +128,7 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
/* traverse the addrinfo list */
|
||||
|
||||
for(ai = aihead; ai != NULL; ai = ai->ai_next) {
|
||||
|
||||
size_t namelen = ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0;
|
||||
/* ignore elements with unsupported address family, */
|
||||
/* settle family-specific sockaddr structure size. */
|
||||
if(ai->ai_family == AF_INET)
|
||||
@ -151,7 +148,7 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
if((size_t)ai->ai_addrlen < ss_size)
|
||||
continue;
|
||||
|
||||
ca = malloc(sizeof(struct Curl_addrinfo));
|
||||
ca = malloc(sizeof(struct Curl_addrinfo) + ss_size + namelen);
|
||||
if(!ca) {
|
||||
error = EAI_MEMORY;
|
||||
break;
|
||||
@ -169,22 +166,12 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
ca->ai_canonname = NULL;
|
||||
ca->ai_next = NULL;
|
||||
|
||||
ca->ai_addr = malloc(ss_size);
|
||||
if(!ca->ai_addr) {
|
||||
error = EAI_MEMORY;
|
||||
free(ca);
|
||||
break;
|
||||
}
|
||||
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
|
||||
memcpy(ca->ai_addr, ai->ai_addr, ss_size);
|
||||
|
||||
if(ai->ai_canonname != NULL) {
|
||||
ca->ai_canonname = strdup(ai->ai_canonname);
|
||||
if(!ca->ai_canonname) {
|
||||
error = EAI_MEMORY;
|
||||
free(ca->ai_addr);
|
||||
free(ca);
|
||||
break;
|
||||
}
|
||||
if(namelen) {
|
||||
ca->ai_canonname = (void *)((char *)ca->ai_addr + ss_size);
|
||||
memcpy(ca->ai_canonname, ai->ai_canonname, namelen);
|
||||
}
|
||||
|
||||
/* if the return list is empty, this becomes the first element */
|
||||
@ -289,8 +276,8 @@ Curl_he2ai(const struct hostent *he, int port)
|
||||
DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));
|
||||
|
||||
for(i = 0; (curr = he->h_addr_list[i]) != NULL; i++) {
|
||||
|
||||
size_t ss_size;
|
||||
size_t namelen = strlen(he->h_name) + 1; /* include zero termination */
|
||||
#ifdef ENABLE_IPV6
|
||||
if(he->h_addrtype == AF_INET6)
|
||||
ss_size = sizeof(struct sockaddr_in6);
|
||||
@ -298,24 +285,17 @@ Curl_he2ai(const struct hostent *he, int port)
|
||||
#endif
|
||||
ss_size = sizeof(struct sockaddr_in);
|
||||
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo));
|
||||
/* allocate memory to told the struct, the address and the name */
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo) + ss_size + namelen);
|
||||
if(!ai) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
ai->ai_canonname = strdup(he->h_name);
|
||||
if(!ai->ai_canonname) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
ai->ai_addr = calloc(1, ss_size);
|
||||
if(!ai->ai_addr) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai->ai_canonname);
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
/* put the address after the struct */
|
||||
ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
|
||||
/* then put the name after the address */
|
||||
ai->ai_canonname = (char *)ai->ai_addr + ss_size;
|
||||
memcpy(ai->ai_canonname, he->h_name, namelen);
|
||||
|
||||
if(!firstai)
|
||||
/* store the pointer we want to return from this function */
|
||||
@ -496,14 +476,10 @@ struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
|
||||
|
||||
*longpath = FALSE;
|
||||
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo));
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo) + sizeof(struct sockaddr_un));
|
||||
if(!ai)
|
||||
return NULL;
|
||||
ai->ai_addr = calloc(1, sizeof(struct sockaddr_un));
|
||||
if(!ai->ai_addr) {
|
||||
free(ai);
|
||||
return NULL;
|
||||
}
|
||||
ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
|
||||
|
||||
sa_un = (void *) ai->ai_addr;
|
||||
sa_un->sun_family = AF_UNIX;
|
||||
@ -511,7 +487,6 @@ struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
|
||||
/* sun_path must be able to store the NUL-terminated path */
|
||||
path_len = strlen(path) + 1;
|
||||
if(path_len > sizeof(sa_un->sun_path)) {
|
||||
free(ai->ai_addr);
|
||||
free(ai);
|
||||
*longpath = TRUE;
|
||||
return NULL;
|
||||
|
19
lib/doh.c
19
lib/doh.c
@ -803,6 +803,7 @@ doh2ai(const struct dohentry *de, const char *hostname, int port)
|
||||
#endif
|
||||
CURLcode result = CURLE_OK;
|
||||
int i;
|
||||
size_t hostlen = strlen(hostname) + 1; /* include zero terminator */
|
||||
|
||||
if(!de)
|
||||
/* no input == no output! */
|
||||
@ -825,24 +826,14 @@ doh2ai(const struct dohentry *de, const char *hostname, int port)
|
||||
addrtype = AF_INET;
|
||||
}
|
||||
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo));
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo) + ss_size + hostlen);
|
||||
if(!ai) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
ai->ai_canonname = strdup(hostname);
|
||||
if(!ai->ai_canonname) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
ai->ai_addr = calloc(1, ss_size);
|
||||
if(!ai->ai_addr) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai->ai_canonname);
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
|
||||
ai->ai_canonname = (void *)((char *)ai->ai_addr + ss_size);
|
||||
memcpy(ai->ai_canonname, hostname, hostlen);
|
||||
|
||||
if(!firstai)
|
||||
/* store the pointer we want to return from this function */
|
||||
|
@ -76,23 +76,18 @@ static void unit_stop(void)
|
||||
static struct Curl_addrinfo *fake_ai(void)
|
||||
{
|
||||
static struct Curl_addrinfo *ai;
|
||||
static const char dummy[]="dummy";
|
||||
size_t namelen = sizeof(dummy); /* including the zero terminator */
|
||||
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo));
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo) + sizeof(struct sockaddr_in) +
|
||||
namelen);
|
||||
if(!ai)
|
||||
return NULL;
|
||||
|
||||
ai->ai_canonname = strdup("dummy");
|
||||
if(!ai->ai_canonname) {
|
||||
free(ai);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ai->ai_addr = calloc(1, sizeof(struct sockaddr_in));
|
||||
if(!ai->ai_addr) {
|
||||
free(ai->ai_canonname);
|
||||
free(ai);
|
||||
return NULL;
|
||||
}
|
||||
ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
|
||||
ai->ai_canonname = (void *)((char *)ai->ai_addr +
|
||||
sizeof(struct sockaddr_in));
|
||||
memcpy(ai->ai_canonname, dummy, namelen);
|
||||
|
||||
ai->ai_family = AF_INET;
|
||||
ai->ai_addrlen = sizeof(struct sockaddr_in);
|
||||
|
Loading…
Reference in New Issue
Block a user