diff options
| -rw-r--r-- | src/network/freeaddrinfo.c | 11 | ||||
| -rw-r--r-- | src/network/getaddrinfo.c | 10 | ||||
| -rw-r--r-- | src/network/lookup.h | 12 | 
3 files changed, 25 insertions, 8 deletions
diff --git a/src/network/freeaddrinfo.c b/src/network/freeaddrinfo.c index df3798ae..62241c23 100644 --- a/src/network/freeaddrinfo.c +++ b/src/network/freeaddrinfo.c @@ -1,7 +1,16 @@  #include <stdlib.h> +#include <stddef.h>  #include <netdb.h> +#include "lookup.h" +#include "lock.h"  void freeaddrinfo(struct addrinfo *p)  { -	free(p); +	size_t cnt; +	for (cnt=1; p->ai_next; cnt++, p=p->ai_next); +	struct aibuf *b = (void *)((char *)p - offsetof(struct aibuf, ai)); +	b -= b->slot; +	LOCK(b->lock); +	if (!(b->ref -= cnt)) free(b); +	else UNLOCK(b->lock);  } diff --git a/src/network/getaddrinfo.c b/src/network/getaddrinfo.c index e33bfa28..5ae8cbfb 100644 --- a/src/network/getaddrinfo.c +++ b/src/network/getaddrinfo.c @@ -16,13 +16,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru  	char canon[256], *outcanon;  	int nservs, naddrs, nais, canon_len, i, j, k;  	int family = AF_UNSPEC, flags = 0, proto = 0, socktype = 0; -	struct aibuf { -		struct addrinfo ai; -		union sa { -			struct sockaddr_in sin; -			struct sockaddr_in6 sin6; -		} sa; -	} *out; +	struct aibuf *out;  	if (!host && !serv) return EAI_NONAME; @@ -110,6 +104,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru  	}  	for (k=i=0; i<naddrs; i++) for (j=0; j<nservs; j++, k++) { +		out[k].slot = i;  		out[k].ai = (struct addrinfo){  			.ai_family = addrs[i].family,  			.ai_socktype = ports[j].socktype, @@ -134,6 +129,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru  			break;			  		}  	} +	out[0].ref = nais;  	out[nais-1].ai.ai_next = 0;  	*res = &out->ai;  	return 0; diff --git a/src/network/lookup.h b/src/network/lookup.h index f1952af5..ef662725 100644 --- a/src/network/lookup.h +++ b/src/network/lookup.h @@ -4,6 +4,18 @@  #include <stdint.h>  #include <stddef.h>  #include <features.h> +#include <netinet/in.h> +#include <netdb.h> + +struct aibuf { +	struct addrinfo ai; +	union sa { +		struct sockaddr_in sin; +		struct sockaddr_in6 sin6; +	} sa; +	volatile int lock[1]; +	short slot, ref; +};  struct address {  	int family;  | 
