summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/asr/asr.c8
-rw-r--r--lib/libc/asr/asr_debug.c4
-rw-r--r--lib/libc/asr/asr_private.h11
-rw-r--r--lib/libc/asr/gethostnamadr_async.c70
-rw-r--r--lib/libc/asr/getnetnamadr_async.c428
5 files changed, 79 insertions, 442 deletions
diff --git a/lib/libc/asr/asr.c b/lib/libc/asr/asr.c
index d7546512a46..4c39785fecf 100644
--- a/lib/libc/asr/asr.c
+++ b/lib/libc/asr/asr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr.c,v 1.59 2018/03/13 12:25:34 jca Exp $ */
+/* $OpenBSD: asr.c,v 1.60 2018/04/28 15:16:49 schwarze Exp $ */
/*
* Copyright (c) 2010-2012 Eric Faurot <eric@openbsd.org>
*
@@ -282,12 +282,6 @@ _asr_async_free(struct asr_query *as)
free(as->as.hostnamadr.name);
break;
- case ASR_GETNETBYNAME:
- case ASR_GETNETBYADDR:
- if (as->as.netnamadr.name)
- free(as->as.netnamadr.name);
- break;
-
case ASR_GETADDRINFO:
if (as->as.ai.aifirst)
freeaddrinfo(as->as.ai.aifirst);
diff --git a/lib/libc/asr/asr_debug.c b/lib/libc/asr/asr_debug.c
index 1591bd204c1..141517b8360 100644
--- a/lib/libc/asr/asr_debug.c
+++ b/lib/libc/asr/asr_debug.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr_debug.c,v 1.24 2017/02/27 11:31:01 jca Exp $ */
+/* $OpenBSD: asr_debug.c,v 1.25 2018/04/28 15:16:49 schwarze Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -338,8 +338,6 @@ _asr_querystr(int type)
CASE(ASR_GETRRSETBYNAME);
CASE(ASR_GETHOSTBYNAME);
CASE(ASR_GETHOSTBYADDR);
- CASE(ASR_GETNETBYNAME);
- CASE(ASR_GETNETBYADDR);
CASE(ASR_GETADDRINFO);
CASE(ASR_GETNAMEINFO);
default:
diff --git a/lib/libc/asr/asr_private.h b/lib/libc/asr/asr_private.h
index e922017df24..49123a3c246 100644
--- a/lib/libc/asr/asr_private.h
+++ b/lib/libc/asr/asr_private.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr_private.h,v 1.46 2017/02/27 11:38:08 jca Exp $ */
+/* $OpenBSD: asr_private.h,v 1.47 2018/04/28 15:16:49 schwarze Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -113,8 +113,6 @@ enum async_type {
ASR_GETRRSETBYNAME,
ASR_GETHOSTBYNAME,
ASR_GETHOSTBYADDR,
- ASR_GETNETBYNAME,
- ASR_GETNETBYADDR,
ASR_GETADDRINFO,
ASR_GETNAMEINFO,
};
@@ -158,6 +156,7 @@ struct asr {
#define ASYNC_NODATA 0x00000100
#define ASYNC_AGAIN 0x00000200
+#define ASYNC_GETNET 0x00001000
#define ASYNC_EXTOBUF 0x00002000
#define ASYNC_NO_INET 0x00010000
@@ -230,12 +229,6 @@ struct asr_query {
} hostnamadr;
struct {
- char *name;
- int family;
- in_addr_t addr;
- } netnamadr;
-
- struct {
char *hostname;
char *servname;
int port_tcp;
diff --git a/lib/libc/asr/gethostnamadr_async.c b/lib/libc/asr/gethostnamadr_async.c
index ae882c5d78a..1c30c08a0df 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.43 2017/02/23 17:04:02 eric Exp $ */
+/* $OpenBSD: gethostnamadr_async.c,v 1.44 2018/04/28 15:16:49 schwarze Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -44,6 +44,13 @@ struct hostent_ext {
char *pos;
};
+struct netent_ext {
+ struct netent n;
+ char *aliases[MAXALIASES + 1];
+ char *end;
+ char *pos;
+};
+
static int gethostnamadr_async_run(struct asr_query *, struct asr_result *);
static struct hostent_ext *hostent_alloc(int);
static int hostent_set_cname(struct hostent_ext *, const char *, int);
@@ -53,6 +60,7 @@ static struct hostent_ext *hostent_from_addr(int, const char *, const char *);
static struct hostent_ext *hostent_file_match(FILE *, int, int, const char *,
int);
static struct hostent_ext *hostent_from_packet(int, int, char *, size_t);
+static void netent_from_hostent(struct asr_result *ar);
struct asr_query *
gethostbyname_async(const char *name, void *asr)
@@ -344,9 +352,13 @@ gethostnamadr_async_run(struct asr_query *as, struct asr_result *ar)
break;
case ASR_STATE_HALT:
- if (ar->ar_h_errno)
+ if (ar->ar_h_errno == NETDB_SUCCESS &&
+ as->as_flags & ASYNC_GETNET)
+ netent_from_hostent(ar);
+ if (ar->ar_h_errno) {
ar->ar_hostent = NULL;
- else
+ ar->ar_netent = NULL;
+ } else
ar->ar_errno = 0;
return (ASYNC_DONE);
@@ -607,3 +619,55 @@ hostent_add_addr(struct hostent_ext *h, const void *addr, size_t size)
h->pos += size;
return (0);
}
+
+static void
+netent_from_hostent(struct asr_result *ar)
+{
+ struct in_addr *addr;
+ struct netent_ext *n;
+ struct hostent_ext *h;
+ char **na, **ha;
+ size_t sz;
+
+ /* Allocate and initialize the output. */
+ if ((n = calloc(1, sizeof(*n) + 1024)) == NULL) {
+ ar->ar_h_errno = NETDB_INTERNAL;
+ ar->ar_errno = errno;
+ goto out;
+ }
+ n->pos = (char *)(n) + sizeof(*n);
+ n->end = n->pos + 1024;
+ n->n.n_name = n->pos;
+ n->n.n_aliases = n->aliases;
+
+ /* Copy the fixed-size data. */
+ h = (struct hostent_ext *)ar->ar_hostent;
+ addr = (struct in_addr *)h->h.h_addr;
+ n->n.n_net = ntohl(addr->s_addr);
+ n->n.n_addrtype = h->h.h_addrtype;
+
+ /* Copy the network name. */
+ sz = strlen(h->h.h_name) + 1;
+ memcpy(n->pos, h->h.h_name, sz);
+ n->pos += sz;
+
+ /*
+ * Copy the aliases.
+ * No overflow check is needed because we are merely copying
+ * a part of the data from a structure of the same size.
+ */
+ na = n->aliases;
+ for (ha = h->aliases; *ha != NULL; ha++) {
+ sz = strlen(*ha) + 1;
+ memcpy(n->pos, *ha, sz);
+ *na++ = n->pos;
+ n->pos += sz;
+ }
+ *na = NULL;
+
+ /* Handle the return values. */
+ ar->ar_netent = &n->n;
+out:
+ free(ar->ar_hostent);
+ ar->ar_hostent = NULL;
+}
diff --git a/lib/libc/asr/getnetnamadr_async.c b/lib/libc/asr/getnetnamadr_async.c
index 0b8adc944b9..0b1604d2b21 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.25 2017/02/23 17:04:02 eric Exp $ */
+/* $OpenBSD: getnetnamadr_async.c,v 1.26 2018/04/28 15:16:49 schwarze Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -17,446 +17,34 @@
#include <sys/types.h>
#include <sys/socket.h>
-#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <netdb.h>
-
#include <asr.h>
-#include <errno.h>
-#include <resolv.h> /* for res_hnok */
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
#include "asr_private.h"
-#define MAXALIASES 16
-
-struct netent_ext {
- struct netent n;
- char *aliases[MAXALIASES + 1];
- char *end;
- char *pos;
-};
-
-static int getnetnamadr_async_run(struct asr_query *, struct asr_result *);
-static struct netent_ext *netent_alloc(int);
-static int netent_set_cname(struct netent_ext *, const char *, int);
-static int netent_add_alias(struct netent_ext *, const char *, int);
-static struct netent_ext *netent_file_match(FILE *, int, const char *);
-static struct netent_ext *netent_from_packet(int, char *, size_t);
-
struct asr_query *
getnetbyname_async(const char *name, void *asr)
{
- struct asr_ctx *ac;
struct asr_query *as;
- /* The current resolver segfaults. */
- if (name == NULL) {
- errno = EINVAL;
- return (NULL);
- }
-
- ac = _asr_use_resolver(asr);
- if ((as = _asr_async_new(ac, ASR_GETNETBYNAME)) == NULL)
- goto abort; /* errno set */
- as->as_run = getnetnamadr_async_run;
-
- as->as.netnamadr.family = AF_INET;
- as->as.netnamadr.name = strdup(name);
- if (as->as.netnamadr.name == NULL)
- goto abort; /* errno set */
-
- _asr_ctx_unref(ac);
+ if ((as = gethostbyname_async(name, asr)) != NULL)
+ as->as_flags |= ASYNC_GETNET;
return (as);
-
- abort:
- if (as)
- _asr_async_free(as);
- _asr_ctx_unref(ac);
- return (NULL);
}
DEF_WEAK(getnetbyname_async);
struct asr_query *
getnetbyaddr_async(in_addr_t net, int family, void *asr)
{
- struct asr_ctx *ac;
+ struct in_addr in;
struct asr_query *as;
- ac = _asr_use_resolver(asr);
- if ((as = _asr_async_new(ac, ASR_GETNETBYADDR)) == NULL)
- goto abort; /* errno set */
- as->as_run = getnetnamadr_async_run;
-
- as->as.netnamadr.family = family;
- as->as.netnamadr.addr = net;
-
- _asr_ctx_unref(ac);
+ in.s_addr = htonl(net);
+ as = gethostbyaddr_async(&in, sizeof(in), family, asr);
+ if (as != NULL)
+ as->as_flags |= ASYNC_GETNET;
return (as);
-
- abort:
- if (as)
- _asr_async_free(as);
- _asr_ctx_unref(ac);
- return (NULL);
}
DEF_WEAK(getnetbyaddr_async);
-
-static int
-getnetnamadr_async_run(struct asr_query *as, struct asr_result *ar)
-{
- struct netent_ext *n;
- int r, type, saved_errno;
- FILE *f;
- char dname[MAXDNAME], *name, *data;
- in_addr_t in;
-
- next:
- switch (as->as_state) {
-
- case ASR_STATE_INIT:
-
- if (as->as.netnamadr.family != AF_INET) {
- ar->ar_h_errno = NETDB_INTERNAL;
- ar->ar_errno = EAFNOSUPPORT;
- async_set_state(as, ASR_STATE_HALT);
- break;
- }
-
- if (as->as_type == ASR_GETNETBYNAME &&
- as->as.netnamadr.name[0] == '\0') {
- ar->ar_h_errno = NO_DATA;
- async_set_state(as, ASR_STATE_HALT);
- break;
- }
-
- async_set_state(as, ASR_STATE_NEXT_DB);
- break;
-
- case ASR_STATE_NEXT_DB:
-
- if (_asr_iter_db(as) == -1) {
- async_set_state(as, ASR_STATE_NOT_FOUND);
- break;
- }
-
- switch (AS_DB(as)) {
- case ASR_DB_DNS:
-
- if (as->as_type == ASR_GETNETBYNAME) {
- type = T_A;
- /*
- * I think we want to do the former, but our
- * resolver is doing the following, so let's
- * preserve bugward-compatibility there.
- */
- type = T_PTR;
- name = as->as.netnamadr.name;
- as->as_subq = _res_search_async_ctx(
- name, C_IN, type, as->as_ctx);
- } else {
- type = T_PTR;
- name = dname;
-
- in = htonl(as->as.netnamadr.addr);
- _asr_addr_as_fqdn((char *)&in,
- as->as.netnamadr.family,
- dname, sizeof(dname));
- as->as_subq = _res_query_async_ctx(
- name, C_IN, type, as->as_ctx);
- }
-
- if (as->as_subq == NULL) {
- ar->ar_errno = errno;
- ar->ar_h_errno = NETDB_INTERNAL;
- async_set_state(as, ASR_STATE_HALT);
- break;
- }
- async_set_state(as, ASR_STATE_SUBQUERY);
- break;
-
- case ASR_DB_FILE:
-
- if ((f = fopen(_PATH_NETWORKS, "re")) == NULL)
- break;
-
- if (as->as_type == ASR_GETNETBYNAME)
- data = as->as.netnamadr.name;
- else
- data = (void *)&as->as.netnamadr.addr;
-
- n = netent_file_match(f, as->as_type, data);
- saved_errno = errno;
- fclose(f);
- errno = saved_errno;
- if (n == NULL) {
- if (errno) {
- ar->ar_errno = errno;
- ar->ar_h_errno = NETDB_INTERNAL;
- async_set_state(as, ASR_STATE_HALT);
- }
- /* otherwise not found */
- break;
- }
-
- ar->ar_netent = &n->n;
- ar->ar_h_errno = NETDB_SUCCESS;
- async_set_state(as, ASR_STATE_HALT);
- break;
- }
- break;
-
- case ASR_STATE_SUBQUERY:
-
- if ((r = asr_run(as->as_subq, ar)) == ASYNC_COND)
- return (ASYNC_COND);
- as->as_subq = NULL;
-
- if (ar->ar_datalen == -1) {
- async_set_state(as, ASR_STATE_NEXT_DB);
- break;
- }
-
- /* Got packet, but no answer */
- if (ar->ar_count == 0) {
- free(ar->ar_data);
- async_set_state(as, ASR_STATE_NEXT_DB);
- break;
- }
-
- n = netent_from_packet(as->as_type, ar->ar_data,
- ar->ar_datalen);
- free(ar->ar_data);
- if (n == NULL) {
- ar->ar_errno = errno;
- ar->ar_h_errno = NETDB_INTERNAL;
- async_set_state(as, ASR_STATE_HALT);
- break;
- }
-
- if (as->as_type == ASR_GETNETBYADDR)
- n->n.n_net = as->as.netnamadr.addr;
-
- /*
- * No valid hostname or address found in the dns packet.
- * Ignore it.
- */
- if ((as->as_type == ASR_GETNETBYNAME && n->n.n_net == 0) ||
- n->n.n_name == NULL) {
- free(n);
- async_set_state(as, ASR_STATE_NEXT_DB);
- break;
- }
-
- ar->ar_netent = &n->n;
- ar->ar_h_errno = NETDB_SUCCESS;
- async_set_state(as, ASR_STATE_HALT);
- break;
-
- case ASR_STATE_NOT_FOUND:
-
- ar->ar_errno = 0;
- ar->ar_h_errno = HOST_NOT_FOUND;
- async_set_state(as, ASR_STATE_HALT);
- break;
-
- case ASR_STATE_HALT:
-
- if (ar->ar_h_errno)
- ar->ar_netent = NULL;
- else
- ar->ar_errno = 0;
- return (ASYNC_DONE);
-
- default:
- ar->ar_errno = EOPNOTSUPP;
- ar->ar_h_errno = NETDB_INTERNAL;
- ar->ar_gai_errno = EAI_SYSTEM;
- async_set_state(as, ASR_STATE_HALT);
- break;
- }
- goto next;
-}
-
-static struct netent_ext *
-netent_file_match(FILE *f, int reqtype, const char *data)
-{
- struct netent_ext *e;
- char *tokens[MAXTOKEN], buf[BUFSIZ + 1];
- int n, i;
- in_addr_t net;
-
- for (;;) {
- n = _asr_parse_namedb_line(f, tokens, MAXTOKEN, buf, sizeof(buf));
- if (n == -1) {
- errno = 0; /* ignore errors reading the file */
- return (NULL);
- }
-
- /* there must be an address and at least one name */
- if (n < 2)
- continue;
-
- if (reqtype == ASR_GETNETBYADDR) {
- net = inet_network(tokens[1]);
- if (memcmp(&net, data, sizeof net) == 0)
- goto found;
- } else {
- for (i = 0; i < n; i++) {
- if (i == 1)
- continue;
- if (strcasecmp(data, tokens[i]))
- continue;
- goto found;
- }
- }
- }
-
-found:
- if ((e = netent_alloc(AF_INET)) == NULL)
- return (NULL);
- if (netent_set_cname(e, tokens[0], 0) == -1)
- goto fail;
- for (i = 2; i < n; i ++)
- if (netent_add_alias(e, tokens[i], 0) == -1)
- goto fail;
- e->n.n_net = inet_network(tokens[1]);
- return (e);
-fail:
- free(e);
- return (NULL);
-}
-
-static struct netent_ext *
-netent_from_packet(int reqtype, char *pkt, size_t pktlen)
-{
- struct netent_ext *n;
- struct asr_unpack p;
- struct asr_dns_header hdr;
- struct asr_dns_query q;
- struct asr_dns_rr rr;
-
- if ((n = netent_alloc(AF_INET)) == NULL)
- return (NULL);
-
- _asr_unpack_init(&p, pkt, pktlen);
- _asr_unpack_header(&p, &hdr);
- for (; hdr.qdcount; hdr.qdcount--)
- _asr_unpack_query(&p, &q);
- for (; hdr.ancount; hdr.ancount--) {
- _asr_unpack_rr(&p, &rr);
- if (rr.rr_class != C_IN)
- continue;
- switch (rr.rr_type) {
- case T_CNAME:
- if (reqtype == ASR_GETNETBYNAME) {
- if (netent_add_alias(n, rr.rr_dname, 1) == -1)
- goto fail;
- } else {
- if (netent_set_cname(n, rr.rr_dname, 1) == -1)
- goto fail;
- }
- break;
-
- case T_PTR:
- if (reqtype != ASR_GETNETBYADDR)
- continue;
- if (netent_set_cname(n, rr.rr.ptr.ptrname, 1) == -1)
- goto fail;
- /* XXX See if we need to have MULTI_PTRS_ARE_ALIASES */
- break;
-
- case T_A:
- if (n->n.n_addrtype != AF_INET)
- break;
- if (netent_set_cname(n, rr.rr_dname, 1) == -1)
- goto fail;
- n->n.n_net = ntohl(rr.rr.in_a.addr.s_addr);
- break;
- }
- }
-
- return (n);
-fail:
- free(n);
- return (NULL);
-}
-
-static struct netent_ext *
-netent_alloc(int family)
-{
- struct netent_ext *n;
- size_t alloc;
-
- alloc = sizeof(*n) + 1024;
- if ((n = calloc(1, alloc)) == NULL)
- return (NULL);
-
- n->n.n_addrtype = family;
- n->n.n_aliases = n->aliases;
- n->pos = (char *)(n) + sizeof(*n);
- n->end = n->pos + 1024;
-
- return (n);
-}
-
-static int
-netent_set_cname(struct netent_ext *n, const char *name, int isdname)
-{
- char buf[MAXDNAME];
- size_t l;
-
- if (n->n.n_name)
- return (-1);
-
- if (isdname) {
- _asr_strdname(name, buf, sizeof buf);
- buf[strlen(buf) - 1] = '\0';
- if (!res_hnok(buf))
- return (-1);
- name = buf;
- }
-
- l = strlen(name) + 1;
- if (n->pos + l >= n->end)
- return (-1);
-
- n->n.n_name = n->pos;
- memmove(n->pos, name, l);
- n->pos += l;
-
- return (0);
-}
-
-static int
-netent_add_alias(struct netent_ext *n, const char *name, int isdname)
-{
- char buf[MAXDNAME];
- size_t i, l;
-
- for (i = 0; i < MAXALIASES; i++)
- if (n->aliases[i] == NULL)
- break;
- if (i == MAXALIASES)
- return (-1);
-
- if (isdname) {
- _asr_strdname(name, buf, sizeof buf);
- buf[strlen(buf)-1] = '\0';
- if (!res_hnok(buf))
- return (-1);
- name = buf;
- }
-
- l = strlen(name) + 1;
- if (n->pos + l >= n->end)
- return (-1);
-
- n->aliases[i] = n->pos;
- memmove(n->pos, name, l);
- n->pos += l;
- return (0);
-}