diff options
Diffstat (limited to 'src')
-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; |