summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc/asr/asr.h4
-rw-r--r--lib/libc/asr/asr_resolver.c10
-rw-r--r--lib/libc/asr/async_resolver.318
-rw-r--r--lib/libc/asr/gethostnamadr_async.c89
-rw-r--r--lib/libc/asr/getnameinfo_async.c4
-rw-r--r--lib/libc/asr/getnetnamadr_async.c67
6 files changed, 88 insertions, 104 deletions
diff --git a/lib/libc/asr/asr.h b/lib/libc/asr/asr.h
index 2a562092326..66516331328 100644
--- a/lib/libc/asr/asr.h
+++ b/lib/libc/asr/asr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr.h,v 1.1 2012/04/14 09:24:18 eric Exp $ */
+/* $OpenBSD: asr.h,v 1.2 2012/08/19 16:17:40 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -94,11 +94,9 @@ struct async *getrrsetbyname_async(const char *, unsigned int, unsigned int,
struct async *gethostbyname_async(const char *, struct asr *);
struct async *gethostbyname2_async(const char *, int, struct asr *);
struct async *gethostbyaddr_async(const void *, socklen_t, int, struct asr *);
-void freehostent(struct hostent *);
struct async *getnetbyname_async(const char *, struct asr *);
struct async *getnetbyaddr_async(in_addr_t, int, struct asr *);
-void freenetent(struct netent *);
struct async *getaddrinfo_async(const char *, const char *,
const struct addrinfo *, struct asr *);
diff --git a/lib/libc/asr/asr_resolver.c b/lib/libc/asr/asr_resolver.c
index acebcbd6753..158f2914cfe 100644
--- a/lib/libc/asr/asr_resolver.c
+++ b/lib/libc/asr/asr_resolver.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr_resolver.c,v 1.8 2012/08/18 16:48:17 eric Exp $ */
+/* $OpenBSD: asr_resolver.c,v 1.9 2012/08/19 16:17:40 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -319,7 +319,7 @@ _gethostbyname(const char *name, int af)
return (NULL);
h = _mkstatichostent(ar.ar_hostent);
- freehostent(ar.ar_hostent);
+ free(ar.ar_hostent);
return (h);
}
@@ -357,7 +357,7 @@ gethostbyaddr(const void *addr, socklen_t len, int af)
return (NULL);
h = _mkstatichostent(ar.ar_hostent);
- freehostent(ar.ar_hostent);
+ free(ar.ar_hostent);
return (h);
}
@@ -438,7 +438,7 @@ getnetbyname(const char *name)
return (NULL);
n = _mkstaticnetent(ar.ar_netent);
- freenetent(ar.ar_netent);
+ free(ar.ar_netent);
return (n);
}
@@ -464,7 +464,7 @@ getnetbyaddr(in_addr_t net, int type)
return (NULL);
n = _mkstaticnetent(ar.ar_netent);
- freenetent(ar.ar_netent);
+ free(ar.ar_netent);
return (n);
}
diff --git a/lib/libc/asr/async_resolver.3 b/lib/libc/asr/async_resolver.3
index 81ae9f92e23..77e03a9c9bb 100644
--- a/lib/libc/asr/async_resolver.3
+++ b/lib/libc/asr/async_resolver.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: async_resolver.3,v 1.3 2012/08/18 16:48:17 eric Exp $
+.\" $OpenBSD: async_resolver.3,v 1.4 2012/08/19 16:17:40 eric Exp $
.\"
.\" Copyright (c) 2012, Eric Faurot <eric@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: August 18 2012 $
+.Dd $Mdocdate: August 19 2012 $
.Dt ASYN_RESOLVER 3
.Os
.Sh NAME
@@ -30,7 +30,6 @@
.Nm gethostbyname_async ,
.Nm gethostbyname2_async ,
.Nm gethostbyaddr_async ,
-.Nm freehostent ,
.Nm getnetbyname_async ,
.Nm getnetbyaddr_async ,
.Nm freenetent ,
@@ -61,13 +60,10 @@
.Fn gethostbyname2_async "const char *name" "int af" "struct asr *asr"
.Ft struct async*
.Fn gethostbyaddr_async "const void *addr" "socklen_t len" "int af" "struct asr *asr"
-.Ft void
-.Fn freehostent "struct hostent *h"
+.Ft struct async*
.Fn getnetbyname_async "const char *name" "struct asr *asr"
.Ft struct async*
.Fn getnetbyaddr_async "in_addr_t net" "int type" "struct asr *asr"
-.Ft void
-.Fn freenetent "struct netent *n"
.Ft struct async*
.Fn getaddrinfo_async "const char *hostname" "const char *servname" "const struct addrinfo *hints" "struct asr *asr"
.Ft struct async*
@@ -308,10 +304,8 @@ in the
.Ar ar_hostent
field.
Note that unlike their blocking counterparts, these functions always return a
-pointer to newly allocated memory.
-Therefore, the pointer must be freed through the new
-.Fn freehostent
-call.
+pointer to newly allocated memory, which must be released by the caller using
+.Xr free 3 .
.Pp
Similarly, the
.Fn getnetbyname_async
@@ -325,7 +319,7 @@ in the
.Ar ar_netent
field.
The memory there is also allocated for the request, and it must be freed by
-.Fn freenetent .
+.Xr free 3 .
.Pp
The
.Fn getaddrinfo_async
diff --git a/lib/libc/asr/gethostnamadr_async.c b/lib/libc/asr/gethostnamadr_async.c
index 47fecca10da..bc338d71776 100644
--- a/lib/libc/asr/gethostnamadr_async.c
+++ b/lib/libc/asr/gethostnamadr_async.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gethostnamadr_async.c,v 1.5 2012/07/12 13:03:34 eric Exp $ */
+/* $OpenBSD: gethostnamadr_async.c,v 1.6 2012/08/19 16:17:40 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -34,6 +34,11 @@
#define MAXALIASES 16
#define MAXADDRS 16
+#define HOSTENT_PTR(h) ((char**)(((char*)h) + sizeof (*h)))
+#define HOSTENT_POS(h) HOSTENT_PTR(h)[0]
+#define HOSTENT_STOP(h) HOSTENT_PTR(h)[1]
+#define HOSTENT_LEFT(h) (HOSTENT_STOP(h) - HOSTENT_POS(h))
+
ssize_t addr_as_fqdn(const char *, int, char *, size_t);
static int gethostnamadr_async_run(struct async *, struct async_res *);
@@ -291,7 +296,7 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar)
if (hostent_add_addr(ar->ar_hostent,
as->as.hostnamadr.addr,
as->as.hostnamadr.addrlen) == -1) {
- freehostent(ar->ar_hostent);
+ free(ar->ar_hostent);
ar->ar_errno = errno;
ar->ar_h_errno = NETDB_INTERNAL;
async_set_state(as, ASR_STATE_HALT);
@@ -305,7 +310,7 @@ gethostnamadr_async_run(struct async *as, struct async_res *ar)
*/
if (as->as_type == ASR_GETHOSTBYNAME &&
ar->ar_hostent->h_addr_list[0] == NULL) {
- freehostent(ar->ar_hostent);
+ free(ar->ar_hostent);
async_set_state(as, ASR_STATE_NEXT_DB);
break;
}
@@ -381,7 +386,7 @@ found:
goto fail;
return (h);
fail:
- freehostent(h);
+ free(h);
return (NULL);
}
@@ -454,7 +459,7 @@ hostent_from_packet(int reqtype, int family, char *pkt, size_t pktlen)
return (h);
fail:
- freehostent(h);
+ free(h);
return (NULL);
}
@@ -462,19 +467,19 @@ static struct hostent *
hostent_alloc(int family)
{
struct hostent *h;
+ size_t alloc;
- h = calloc(1, sizeof *h);
- if (h == NULL)
+ alloc = sizeof(*h) + (2 + MAXALIASES + MAXADDRS) * sizeof(char*) + 1024;
+ if ((h = calloc(1, alloc)) == NULL)
return (NULL);
- h->h_aliases = calloc(MAXALIASES, sizeof *h->h_aliases);
- h->h_addr_list = calloc(MAXADDRS, sizeof *h->h_addr_list);
- if (h->h_aliases == NULL || h->h_addr_list == NULL) {
- freehostent(h);
- return (NULL);
- }
h->h_addrtype = family;
h->h_length = (family == AF_INET) ? 4 : 16;
+ h->h_aliases = HOSTENT_PTR(h) + 2;
+ h->h_addr_list = h->h_aliases + MAXALIASES;
+
+ HOSTENT_STOP(h) = (char*)(h) + alloc;
+ HOSTENT_POS(h) = (char*)(h->h_addr_list + MAXADDRS);
return (h);
}
@@ -490,12 +495,14 @@ hostent_set_cname(struct hostent *h, const char *name, int isdname)
if (isdname) {
asr_strdname(name, buf, sizeof buf);
buf[strlen(buf) - 1] = '\0';
- h->h_name = strdup(buf);
- } else {
- h->h_name = strdup(name);
+ name = buf;
}
- if (h->h_name == NULL)
- return (-1);
+ if (strlen(name) + 1 >= HOSTENT_LEFT(h))
+ return (1);
+
+ strlcpy(HOSTENT_POS(h), name, HOSTENT_LEFT(h));
+ h->h_name = HOSTENT_POS(h);
+ HOSTENT_POS(h) += strlen(name) + 1;
return (0);
}
@@ -506,21 +513,23 @@ hostent_add_alias(struct hostent *h, const char *name, int isdname)
char buf[MAXDNAME];
size_t i;
- for (i = 0; i < MAXALIASES; i++)
+ for (i = 0; i < MAXALIASES - 1; i++)
if (h->h_aliases[i] == NULL)
break;
- if (i == MAXALIASES)
+ if (i == MAXALIASES - 1)
return (0);
if (isdname) {
asr_strdname(name, buf, sizeof buf);
buf[strlen(buf)-1] = '\0';
- h->h_aliases[i] = strdup(buf);
- } else {
- h->h_aliases[i] = strdup(name);
+ name = buf;
}
- if (h->h_aliases[i] == NULL)
- return (-1);
+ if (strlen(name) + 1 >= HOSTENT_LEFT(h))
+ return (1);
+
+ strlcpy(HOSTENT_POS(h), name, HOSTENT_LEFT(h));
+ h->h_aliases[i] = HOSTENT_POS(h);
+ HOSTENT_POS(h) += strlen(name) + 1;
return (0);
}
@@ -530,36 +539,22 @@ hostent_add_addr(struct hostent *h, const void *addr, int size)
{
int i;
- for (i = 0; i < MAXADDRS; i++)
+ for (i = 0; i < MAXADDRS - 1; i++)
if (h->h_addr_list[i] == NULL)
break;
- if (i == MAXADDRS)
+ if (i == MAXADDRS - 1)
return (0);
- h->h_addr_list[i] = malloc(size);
- if (h->h_addr_list[i] == NULL)
- return (-1);
- memmove(h->h_addr_list[i], addr, size);
+ if (size >= HOSTENT_LEFT(h))
+ return (1);
- return (0);
-}
+ memmove(HOSTENT_POS(h), addr, size);
+ h->h_addr_list[i] = HOSTENT_POS(h);
+ HOSTENT_POS(h) += size;
-void
-freehostent(struct hostent *h)
-{
- char **c;
-
- free(h->h_name);
- for (c = h->h_aliases; *c; c++)
- free(*c);
- free(h->h_aliases);
- for (c = h->h_addr_list; *c; c++)
- free(*c);
- free(h->h_addr_list);
- free(h);
+ return (0);
}
-
ssize_t
addr_as_fqdn(const char *addr, int family, char *dst, size_t max)
{
diff --git a/lib/libc/asr/getnameinfo_async.c b/lib/libc/asr/getnameinfo_async.c
index e32501f8337..4b251801896 100644
--- a/lib/libc/asr/getnameinfo_async.c
+++ b/lib/libc/asr/getnameinfo_async.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getnameinfo_async.c,v 1.3 2012/08/18 11:19:51 eric Exp $ */
+/* $OpenBSD: getnameinfo_async.c,v 1.4 2012/08/19 16:17:40 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -180,7 +180,7 @@ getnameinfo_async_run(struct async *as, struct async_res *ar)
ar->ar_gai_errno = EAI_OVERFLOW;
else
ar->ar_gai_errno = 0;
- freehostent(ar->ar_hostent);
+ free(ar->ar_hostent);
}
async_set_state(as, ASR_STATE_HALT);
diff --git a/lib/libc/asr/getnetnamadr_async.c b/lib/libc/asr/getnetnamadr_async.c
index 70efc2962f2..bc03a643166 100644
--- a/lib/libc/asr/getnetnamadr_async.c
+++ b/lib/libc/asr/getnetnamadr_async.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getnetnamadr_async.c,v 1.2 2012/07/10 17:30:38 eric Exp $ */
+/* $OpenBSD: getnetnamadr_async.c,v 1.3 2012/08/19 16:17:40 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -32,6 +32,11 @@
#define MAXALIASES 16
+#define NETENT_PTR(n) ((char**)(((char*)n) + sizeof (*n)))
+#define NETENT_POS(n) NETENT_PTR(n)[0]
+#define NETENT_STOP(n) NETENT_PTR(n)[1]
+#define NETENT_LEFT(n) (NETENT_STOP(n) - NETENT_POS(n))
+
ssize_t addr_as_fqdn(const char *, int, char *, size_t);
static int getnetnamadr_async_run(struct async *, struct async_res *);
@@ -229,7 +234,7 @@ getnetnamadr_async_run(struct async *as, struct async_res *ar)
if (as->as_type == ASR_GETNETBYNAME &&
ar->ar_netent->n_net == 0) {
/* XXX wrong */
- freenetent(ar->ar_netent);
+ free(ar->ar_netent);
async_set_state(as, ASR_STATE_NEXT_DB);
} else {
ar->ar_h_errno = NETDB_SUCCESS;
@@ -303,7 +308,7 @@ found:
e->n_net = inet_network(tokens[1]);
return (e);
fail:
- freenetent(e);
+ free(e);
return (NULL);
}
@@ -358,7 +363,7 @@ netent_from_packet(int reqtype, char *pkt, size_t pktlen)
return (n);
fail:
- freenetent(n);
+ free(n);
return (NULL);
}
@@ -366,17 +371,17 @@ static struct netent *
netent_alloc(int family)
{
struct netent *n;
+ size_t alloc;
- n = calloc(1, sizeof *n);
- if (n == NULL)
+ alloc = sizeof(*n) + (2 + MAXALIASES) * sizeof(char*) + 1024;
+ if ((n = calloc(1, alloc)) == NULL)
return (NULL);
- n->n_aliases = calloc(MAXALIASES, sizeof *n->n_aliases);
- if (n->n_aliases == NULL) {
- freenetent(n);
- return (NULL);
- }
n->n_addrtype = family;
+ n->n_aliases = NETENT_PTR(n) + 2;
+
+ NETENT_STOP(n) = (char*)(n) + alloc;
+ NETENT_POS(n) = (char *)(n->n_aliases + MAXALIASES);
return (n);
}
@@ -392,12 +397,14 @@ netent_set_cname(struct netent *n, const char *name, int isdname)
if (isdname) {
asr_strdname(name, buf, sizeof buf);
buf[strlen(buf) - 1] = '\0';
- n->n_name = strdup(buf);
- } else {
- n->n_name = strdup(name);
+ name = buf;
}
- if (n->n_name == NULL)
- return (-1);
+ if (strlen(name) + 1 >= NETENT_LEFT(n))
+ return (1);
+
+ strlcpy(NETENT_POS(n), name, NETENT_LEFT(n));
+ n->n_name = NETENT_POS(n);
+ NETENT_POS(n) += strlen(name) + 1;
return (0);
}
@@ -408,33 +415,23 @@ netent_add_alias(struct netent *n, const char *name, int isdname)
char buf[MAXDNAME];
size_t i;
- for (i = 0; i < MAXALIASES; i++)
+ for (i = 0; i < MAXALIASES - 1; i++)
if (n->n_aliases[i] == NULL)
break;
- if (i == MAXALIASES)
+ if (i == MAXALIASES - 1)
return (0);
if (isdname) {
asr_strdname(name, buf, sizeof buf);
buf[strlen(buf)-1] = '\0';
- n->n_aliases[i] = strdup(buf);
- } else {
- n->n_aliases[i] = strdup(name);
+ name = buf;
}
- if (n->n_aliases[i] == NULL)
- return (-1);
+ if (strlen(name) + 1 >= NETENT_LEFT(n))
+ return (1);
- return (0);
-}
-
-void
-freenetent(struct netent *n)
-{
- char **c;
+ strlcpy(NETENT_POS(n), name, NETENT_LEFT(n));
+ n->n_aliases[i] = NETENT_POS(n);
+ NETENT_POS(n) += strlen(name) + 1;
- free(n->n_name);
- for (c = n->n_aliases; *c; c++)
- free(*c);
- free(n->n_aliases);
- free(n);
+ return (0);
}