summaryrefslogtreecommitdiffstats
path: root/contrib/bind/lib/irs/dns_nw.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind/lib/irs/dns_nw.c')
-rw-r--r--contrib/bind/lib/irs/dns_nw.c153
1 files changed, 113 insertions, 40 deletions
diff --git a/contrib/bind/lib/irs/dns_nw.c b/contrib/bind/lib/irs/dns_nw.c
index 30767e7..66ef664 100644
--- a/contrib/bind/lib/irs/dns_nw.c
+++ b/contrib/bind/lib/irs/dns_nw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ * Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: dns_nw.c,v 1.13 1998/02/13 01:10:40 halley Exp $";
+static const char rcsid[] = "$Id: dns_nw.c,v 1.19 1999/10/15 19:49:10 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports. */
@@ -38,6 +38,7 @@ static const char rcsid[] = "$Id: dns_nw.c,v 1.13 1998/02/13 01:10:40 halley Exp
#include <stdlib.h>
#include <string.h>
+#include <isc/memcluster.h>
#include <irs.h>
#include "port_after.h"
@@ -51,8 +52,6 @@ static const char rcsid[] = "$Id: dns_nw.c,v 1.13 1998/02/13 01:10:40 halley Exp
# define SPRINTF(x) sprintf x
#endif
-extern int h_errno;
-
/* Definitions. */
#define MAXALIASES 35
@@ -67,6 +66,8 @@ struct pvt {
struct nwent net;
char * ali[MAXALIASES];
char buf[BUFSIZ+1];
+ struct __res_state * res;
+ void (*free_res)(void *);
};
typedef union {
@@ -84,6 +85,10 @@ static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int);
static struct nwent * nw_next(struct irs_nw *);
static void nw_rewind(struct irs_nw *);
static void nw_minimize(struct irs_nw *);
+static struct __res_state * nw_res_get(struct irs_nw *this);
+static void nw_res_set(struct irs_nw *this,
+ struct __res_state *res,
+ void (*free_res)(void *));
static struct nwent * get1101byaddr(struct irs_nw *, u_char *, int);
static struct nwent * get1101byname(struct irs_nw *, const char *);
@@ -92,9 +97,10 @@ static struct nwent * get1101answer(struct irs_nw *,
enum by_what by_what,
int af, const char *name,
const u_char *addr, int addrlen);
-static struct nwent * get1101mask(struct nwent *);
+static struct nwent * get1101mask(struct irs_nw *this, struct nwent *);
static int make1101inaddr(const u_char *, int, char *, int);
static void normalize_name(char *name);
+static int init(struct irs_nw *this);
/* Exports. */
@@ -103,13 +109,13 @@ irs_dns_nw(struct irs_acc *this) {
struct irs_nw *nw;
struct pvt *pvt;
- if (!(pvt = (struct pvt *)malloc(sizeof *pvt))) {
+ if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
}
memset(pvt, 0, sizeof *pvt);
- if (!(nw = (struct irs_nw *)malloc(sizeof *nw))) {
- free(pvt);
+ if (!(nw = memget(sizeof *nw))) {
+ memput(pvt, sizeof *pvt);
errno = ENOMEM;
return (NULL);
}
@@ -121,6 +127,8 @@ irs_dns_nw(struct irs_acc *this) {
nw->next = nw_next;
nw->rewind = nw_rewind;
nw->minimize = nw_minimize;
+ nw->res_get = nw_res_get;
+ nw->res_set = nw_res_set;
return (nw);
}
@@ -130,32 +138,47 @@ static void
nw_close(struct irs_nw *this) {
struct pvt *pvt = (struct pvt *)this->private;
- free(pvt);
- free(this);
+ nw_minimize(this);
+
+ if (pvt->res && pvt->free_res)
+ (*pvt->free_res)(pvt->res);
+
+ memput(pvt, sizeof *pvt);
+ memput(this, sizeof *this);
}
static struct nwent *
nw_byname(struct irs_nw *this, const char *name, int af) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (init(this) == -1)
+ return (NULL);
+
switch (af) {
case AF_INET:
return (get1101byname(this, name));
default:
(void)NULL;
}
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
errno = EAFNOSUPPORT;
return (NULL);
}
static struct nwent *
nw_byaddr(struct irs_nw *this, void *net, int len, int af) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (init(this) == -1)
+ return (NULL);
+
switch (af) {
case AF_INET:
return (get1101byaddr(this, net, len));
default:
(void)NULL;
}
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
errno = EAFNOSUPPORT;
return (NULL);
}
@@ -172,43 +195,80 @@ nw_rewind(struct irs_nw *this) {
static void
nw_minimize(struct irs_nw *this) {
- /* NOOP */
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (pvt->res)
+ res_nclose(pvt->res);
+}
+
+static struct __res_state *
+nw_res_get(struct irs_nw *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (!pvt->res) {
+ struct __res_state *res;
+ res = (struct __res_state *)malloc(sizeof *res);
+ if (!res) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ memset(res, 0, sizeof *res);
+ nw_res_set(this, res, free);
+ }
+
+ return (pvt->res);
+}
+
+static void
+nw_res_set(struct irs_nw *this, struct __res_state *res,
+ void (*free_res)(void *)) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (pvt->res && pvt->free_res) {
+ res_nclose(pvt->res);
+ (*pvt->free_res)(pvt->res);
+ }
+
+ pvt->res = res;
+ pvt->free_res = free_res;
}
/* Private. */
static struct nwent *
get1101byname(struct irs_nw *this, const char *name) {
+ struct pvt *pvt = (struct pvt *)this->private;
u_char ansbuf[MAXPACKET];
int anslen;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
- return (NULL);
- anslen = res_search(name, C_IN, T_PTR, ansbuf, sizeof ansbuf);
+ anslen = res_nsearch(pvt->res, name, C_IN, T_PTR,
+ ansbuf, sizeof ansbuf);
if (anslen < 0)
return (NULL);
- return (get1101mask(get1101answer(this, ansbuf, anslen, by_name,
- AF_INET, name, NULL, 0)));
+ return (get1101mask(this, get1101answer(this, ansbuf, anslen, by_name,
+ AF_INET, name, NULL, 0)));
}
static struct nwent *
get1101byaddr(struct irs_nw *this, u_char *net, int len) {
- u_char ansbuf[MAXPACKET];
+ struct pvt *pvt = (struct pvt *)this->private;
char qbuf[sizeof "255.255.255.255.in-addr.arpa"];
+ u_char ansbuf[MAXPACKET];
int anslen;
if (len < 1 || len > 32) {
errno = EINVAL;
- h_errno = NETDB_INTERNAL;
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
return (NULL);
}
if (make1101inaddr(net, len, qbuf, sizeof qbuf) < 0)
return (NULL);
- anslen = res_query(qbuf, C_IN, T_PTR, ansbuf, sizeof ansbuf);
+ anslen = res_nquery(pvt->res, qbuf, C_IN, T_PTR,
+ ansbuf, sizeof ansbuf);
if (anslen < 0)
return (NULL);
- return (get1101mask(get1101answer(this, ansbuf, anslen, by_addr,
- AF_INET, NULL, net, len)));
+ return (get1101mask(this, get1101answer(this, ansbuf, anslen, by_addr,
+ AF_INET, NULL, net, len)));
}
static struct nwent *
@@ -225,7 +285,7 @@ get1101answer(struct irs_nw *this,
/* Initialize, and parse header. */
eom = ansbuf + anslen;
if (ansbuf + HFIXEDSZ > eom) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
hp = (HEADER *)ansbuf;
@@ -235,16 +295,16 @@ get1101answer(struct irs_nw *this,
int n = dn_skipname(cp, eom);
cp += n + QFIXEDSZ;
if (n < 0 || cp > eom) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
}
ancount = ntohs(hp->ancount);
if (!ancount) {
if (hp->aa)
- h_errno = HOST_NOT_FOUND;
+ RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
else
- h_errno = TRY_AGAIN;
+ RES_SET_H_ERRNO(pvt->res, TRY_AGAIN);
return (NULL);
}
@@ -264,7 +324,7 @@ get1101answer(struct irs_nw *this,
int n = strlen(name) + 1;
if (n > buflen) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
pvt->net.n_name = strcpy(bp, name);
@@ -277,7 +337,7 @@ get1101answer(struct irs_nw *this,
int n = addrlen / 8 + ((addrlen % 8) != 0);
if (INADDRSZ > buflen) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
memset(bp, 0, INADDRSZ);
@@ -298,9 +358,9 @@ get1101answer(struct irs_nw *this,
int n = dn_expand(ansbuf, eom, cp, bp, buflen);
cp += n; /* Owner */
- if (n < 0 || !res_dnok(bp) ||
+ if (n < 0 || !maybe_dnok(pvt->res, bp) ||
cp + 3 * INT16SZ + INT32SZ > eom) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
GETSHORT(type, cp); /* Type */
@@ -311,8 +371,8 @@ get1101answer(struct irs_nw *this,
int nn;
nn = dn_expand(ansbuf, eom, cp, bp, buflen);
- if (nn < 0 || !res_hnok(bp) || nn != n) {
- h_errno = NO_RECOVERY;
+ if (nn < 0 || !maybe_hnok(pvt->res, bp) || nn != n) {
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
normalize_name(bp);
@@ -320,7 +380,7 @@ get1101answer(struct irs_nw *this,
case by_addr: {
if (pvt->net.n_name == NULL)
pvt->net.n_name = bp;
- else if (strcasecmp(pvt->net.n_name, bp) == 0)
+ else if (ns_samename(pvt->net.n_name, bp) == 1)
break;
else
*ap++ = bp;
@@ -338,7 +398,7 @@ get1101answer(struct irs_nw *this,
&b1, &b2, &b3, &b4) != 4)
break;
if (buflen < INADDRSZ) {
- h_errno = NO_RECOVERY;
+ RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
return (NULL);
}
pvt->net.n_addr = bp;
@@ -355,7 +415,7 @@ get1101answer(struct irs_nw *this,
cp += n; /* RDATA */
}
if (!haveanswer) {
- h_errno = TRY_AGAIN;
+ RES_SET_H_ERRNO(pvt->res, TRY_AGAIN);
return (NULL);
}
*ap = NULL;
@@ -364,7 +424,8 @@ get1101answer(struct irs_nw *this,
}
static struct nwent *
-get1101mask(struct nwent *nwent) {
+get1101mask(struct irs_nw *this, struct nwent *nwent) {
+ struct pvt *pvt = (struct pvt *)this->private;
char qbuf[sizeof "255.255.255.255.in-addr.arpa"], owner[MAXDNAME];
int anslen, type, class, ancount, qdcount;
u_char ansbuf[MAXPACKET], *cp, *eom;
@@ -379,7 +440,7 @@ get1101mask(struct nwent *nwent) {
}
/* Query for the A RR that would hold this network's mask. */
- anslen = res_query(qbuf, C_IN, T_A, ansbuf, sizeof ansbuf);
+ anslen = res_nquery(pvt->res, qbuf, C_IN, T_A, ansbuf, sizeof ansbuf);
if (anslen < HFIXEDSZ)
return (nwent);
@@ -400,7 +461,7 @@ get1101mask(struct nwent *nwent) {
while (--ancount >= 0 && cp < eom) {
int n = dn_expand(ansbuf, eom, cp, owner, sizeof owner);
- if (n < 0 || !res_dnok(owner))
+ if (n < 0 || !maybe_dnok(pvt->res, owner))
break;
cp += n; /* Owner */
if (cp + 3 * INT16SZ + INT32SZ > eom)
@@ -412,7 +473,7 @@ get1101mask(struct nwent *nwent) {
if (cp + n > eom)
break;
if (n == INADDRSZ && class == C_IN && type == T_A &&
- !strcasecmp(qbuf, owner)) {
+ ns_samename(qbuf, owner) == 1) {
/* This A RR indicates the actual netmask. */
int nn, mm;
@@ -485,3 +546,15 @@ normalize_name(char *name) {
while (t > name && t[-1] == '.')
*--t = '\0';
}
+
+static int
+init(struct irs_nw *this) {
+ struct pvt *pvt = (struct pvt *)this->private;
+
+ if (!pvt->res && !nw_res_get(this))
+ return (-1);
+ if (((pvt->res->options & RES_INIT) == 0) &&
+ res_ninit(pvt->res) == -1)
+ return (-1);
+ return (0);
+}
OpenPOWER on IntegriCloud