diff options
author | nectar <nectar@FreeBSD.org> | 2002-05-13 19:31:58 +0000 |
---|---|---|
committer | nectar <nectar@FreeBSD.org> | 2002-05-13 19:31:58 +0000 |
commit | e044c1fb924b46fc1bd38b298ebea9ff73ea93a8 (patch) | |
tree | ad4e7f0a2c657d90248bf0c8bd8fac9e5f66a622 /contrib/bind/lib | |
parent | ebeabb1ba32f14e308ae9aff9a2a7151265259cf (diff) | |
download | FreeBSD-src-e044c1fb924b46fc1bd38b298ebea9ff73ea93a8.zip FreeBSD-src-e044c1fb924b46fc1bd38b298ebea9ff73ea93a8.tar.gz |
Import of ISC BIND 8.3.2-T1B.
Diffstat (limited to 'contrib/bind/lib')
-rw-r--r-- | contrib/bind/lib/irs/dns_ho.c | 246 | ||||
-rw-r--r-- | contrib/bind/lib/irs/dns_nw.c | 65 | ||||
-rw-r--r-- | contrib/bind/lib/irs/getaddrinfo.c | 9 | ||||
-rw-r--r-- | contrib/bind/lib/irs/getnameinfo.c | 22 | ||||
-rw-r--r-- | contrib/bind/lib/nameser/ns_sign.c | 32 | ||||
-rw-r--r-- | contrib/bind/lib/resolv/res_findzonecut.c | 158 | ||||
-rw-r--r-- | contrib/bind/lib/resolv/res_send.c | 14 | ||||
-rw-r--r-- | contrib/bind/lib/resolv/res_update.c | 50 |
8 files changed, 380 insertions, 216 deletions
diff --git a/contrib/bind/lib/irs/dns_ho.c b/contrib/bind/lib/irs/dns_ho.c index e340f02..7d64e53 100644 --- a/contrib/bind/lib/irs/dns_ho.c +++ b/contrib/bind/lib/irs/dns_ho.c @@ -52,7 +52,7 @@ /* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns_ho.c,v 1.33 2001/10/05 04:30:21 marka Exp $"; +static const char rcsid[] = "$Id: dns_ho.c,v 1.35 2002/05/08 01:49:27 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports. */ @@ -256,47 +256,55 @@ ho_byname2(struct irs_ho *this, const char *name, int af) char tmp[NS_MAXDNAME]; const char *cp; struct addrinfo ai; - struct dns_res_target q, q2, *p; + struct dns_res_target *q, *q2, *p; int querystate = RESQRY_FAIL; if (init(this) == -1) return (NULL); - memset(&q, 0, sizeof(q2)); - memset(&q2, 0, sizeof(q2)); + q = memget(sizeof(*q)); + q2 = memget(sizeof(*q2)); + if (q == NULL || q2 == NULL) { + RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); + errno = ENOMEM; + goto cleanup; + } + memset(q, 0, sizeof(q)); + memset(q2, 0, sizeof(q2)); switch (af) { case AF_INET: size = INADDRSZ; - q.qclass = C_IN; - q.qtype = T_A; - q.answer = q.qbuf.buf; - q.anslen = sizeof(q.qbuf); - q.action = RESTGT_DOALWAYS; + q->qclass = C_IN; + q->qtype = T_A; + q->answer = q->qbuf.buf; + q->anslen = sizeof(q->qbuf); + q->action = RESTGT_DOALWAYS; break; case AF_INET6: size = IN6ADDRSZ; - q.qclass = C_IN; - q.qtype = ns_t_a6; - q.answer = q.qbuf.buf; - q.anslen = sizeof(q.qbuf); - q.next = &q2; + q->qclass = C_IN; + q->qtype = ns_t_a6; + q->answer = q->qbuf.buf; + q->anslen = sizeof(q->qbuf); + q->next = q2; #ifdef RES_USE_A6 if ((pvt->res->options & RES_USE_A6) == 0) - q.action = RESTGT_IGNORE; + q->action = RESTGT_IGNORE; else #endif - q.action = RESTGT_DOALWAYS; - q2.qclass = C_IN; - q2.qtype = T_AAAA; - q2.answer = q2.qbuf.buf; - q2.anslen = sizeof(q2.qbuf); - q2.action = RESTGT_AFTERFAILURE; + q->action = RESTGT_DOALWAYS; + q2->qclass = C_IN; + q2->qtype = T_AAAA; + q2->answer = q2->qbuf.buf; + q2->anslen = sizeof(q2->qbuf); + q2->action = RESTGT_AFTERFAILURE; break; default: RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); errno = EAFNOSUPPORT; - return (NULL); + hp = NULL; + goto cleanup; } /* @@ -308,7 +316,7 @@ ho_byname2(struct irs_ho *this, const char *name, int af) tmp, sizeof tmp))) name = cp; - for (p = &q; p; p = p->next) { + for (p = q; p; p = p->next) { switch(p->action) { case RESTGT_DOALWAYS: break; @@ -331,13 +339,18 @@ ho_byname2(struct irs_ho *this, const char *name, int af) if ((hp = gethostans(this, p->answer, n, name, p->qtype, af, size, NULL, (const struct addrinfo *)&ai)) != NULL) - return(hp); /* no more loop is necessary */ + goto cleanup; /* no more loop is necessary */ querystate = RESQRY_FAIL; continue; } - return(hp); /* should be NULL */ + cleanup: + if (q != NULL) + memput(q, sizeof(*q)); + if (q2 != NULL) + memput(q2, sizeof(*q2)); + return(hp); } static struct hostent * @@ -346,17 +359,24 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) struct pvt *pvt = (struct pvt *)this->private; const u_char *uaddr = addr; char *qp; - struct hostent *hp; + struct hostent *hp = NULL; struct addrinfo ai; - struct dns_res_target q, q2, *p; + struct dns_res_target *q, *q2, *p; int n, size; int querystate = RESQRY_FAIL; if (init(this) == -1) return (NULL); - memset(&q, 0, sizeof(q2)); - memset(&q2, 0, sizeof(q2)); + q = memget(sizeof(*q)); + q2 = memget(sizeof(*q2)); + if (q == NULL || q2 == NULL) { + RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); + errno = ENOMEM; + goto cleanup; + } + memset(q, 0, sizeof(q)); + memset(q2, 0, sizeof(q2)); if (af == AF_INET6 && len == IN6ADDRSZ && (!memcmp(uaddr, mapped, sizeof mapped) || @@ -371,45 +391,47 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) switch (af) { case AF_INET: size = INADDRSZ; - q.qclass = C_IN; - q.qtype = T_PTR; - q.answer = q.qbuf.buf; - q.anslen = sizeof(q.qbuf); - q.action = RESTGT_DOALWAYS; + q->qclass = C_IN; + q->qtype = T_PTR; + q->answer = q->qbuf.buf; + q->anslen = sizeof(q->qbuf); + q->action = RESTGT_DOALWAYS; break; case AF_INET6: size = IN6ADDRSZ; - q.qclass = C_IN; - q.qtype = T_PTR; - q.answer = q.qbuf.buf; - q.anslen = sizeof(q.qbuf); - q.next = &q2; + q->qclass = C_IN; + q->qtype = T_PTR; + q->answer = q->qbuf.buf; + q->anslen = sizeof(q->qbuf); + q->next = q2; if ((pvt->res->options & RES_NO_BITSTRING) != 0) - q.action = RESTGT_IGNORE; + q->action = RESTGT_IGNORE; else - q.action = RESTGT_DOALWAYS; - q2.qclass = C_IN; - q2.qtype = T_PTR; - q2.answer = q2.qbuf.buf; - q2.anslen = sizeof(q2.qbuf); + q->action = RESTGT_DOALWAYS; + q2->qclass = C_IN; + q2->qtype = T_PTR; + q2->answer = q2->qbuf.buf; + q2->anslen = sizeof(q2->qbuf); if ((pvt->res->options & RES_NO_NIBBLE) != 0) - q2.action = RESTGT_IGNORE; + q2->action = RESTGT_IGNORE; else - q2.action = RESTGT_AFTERFAILURE; + q2->action = RESTGT_AFTERFAILURE; break; default: errno = EAFNOSUPPORT; RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); - return (NULL); + hp = NULL; + goto cleanup; } if (size > len) { errno = EINVAL; RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); - return (NULL); + hp = NULL; + goto cleanup; } switch (af) { case AF_INET: - qp = q.qname; + qp = q->qname; (void) sprintf(qp, "%u.%u.%u.%u.in-addr.arpa", (uaddr[3] & 0xff), (uaddr[2] & 0xff), @@ -417,16 +439,16 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) (uaddr[0] & 0xff)); break; case AF_INET6: - if (q.action != RESTGT_IGNORE) { - qp = q.qname; + if (q->action != RESTGT_IGNORE) { + qp = q->qname; qp += SPRINTF((qp, "\\[x")); for (n = 0; n < IN6ADDRSZ; n++) qp += SPRINTF((qp, "%02x", uaddr[n])); SPRINTF((qp, "/128].%s", res_get_bitstringsuffix(pvt->res))); } - if (q2.action != RESTGT_IGNORE) { - qp = q2.qname; + if (q2->action != RESTGT_IGNORE) { + qp = q2->qname; for (n = IN6ADDRSZ - 1; n >= 0; n--) { qp += SPRINTF((qp, "%x.%x.", uaddr[n] & 0xf, @@ -439,7 +461,7 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) abort(); } - for (p = &q; p; p = p->next) { + for (p = q; p; p = p->next) { switch(p->action) { case RESTGT_DOALWAYS: break; @@ -477,10 +499,16 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) } RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS); - return (hp); /* no more loop is necessary. */ + goto cleanup; /* no more loop is necessary. */ } - - return(NULL); /* H_ERRNO was set by subroutines */ + hp = NULL; /* H_ERRNO was set by subroutines */ + + cleanup: + if (q != NULL) + memput(q, sizeof(*q)); + if (q2 != NULL) + memput(q2, sizeof(*q2)); + return(hp); } static struct hostent * @@ -536,74 +564,83 @@ ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai) int n; char tmp[NS_MAXDNAME]; const char *cp; - struct dns_res_target q, q2, q3, *p; + struct dns_res_target *q, *q2, *q3, *p; struct addrinfo sentinel, *cur; int querystate = RESQRY_FAIL; if (init(this) == -1) return (NULL); - memset(&q, 0, sizeof(q2)); - memset(&q2, 0, sizeof(q2)); - memset(&q3, 0, sizeof(q3)); memset(&sentinel, 0, sizeof(sentinel)); cur = &sentinel; + q = memget(sizeof(*q)); + q2 = memget(sizeof(*q2)); + q3 = memget(sizeof(*q3)); + if (q == NULL || q2 == NULL || q3 == NULL) { + RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); + errno = ENOMEM; + goto cleanup; + } + memset(q, 0, sizeof(q2)); + memset(q2, 0, sizeof(q2)); + memset(q3, 0, sizeof(q3)); + switch (pai->ai_family) { case AF_UNSPEC: /* prefer IPv6 */ - q.qclass = C_IN; - q.qtype = ns_t_a6; - q.answer = q.qbuf.buf; - q.anslen = sizeof(q.qbuf); - q.next = &q2; + q->qclass = C_IN; + q->qtype = ns_t_a6; + q->answer = q->qbuf.buf; + q->anslen = sizeof(q->qbuf); + q->next = q2; #ifdef RES_USE_A6 if ((pvt->res->options & RES_USE_A6) == 0) - q.action = RESTGT_IGNORE; + q->action = RESTGT_IGNORE; else #endif - q.action = RESTGT_DOALWAYS; - q2.qclass = C_IN; - q2.qtype = T_AAAA; - q2.answer = q2.qbuf.buf; - q2.anslen = sizeof(q2.qbuf); - q2.next = &q3; + q->action = RESTGT_DOALWAYS; + q2->qclass = C_IN; + q2->qtype = T_AAAA; + q2->answer = q2->qbuf.buf; + q2->anslen = sizeof(q2->qbuf); + q2->next = q3; /* try AAAA only when A6 query fails */ - q2.action = RESTGT_AFTERFAILURE; - q3.qclass = C_IN; - q3.qtype = T_A; - q3.answer = q3.qbuf.buf; - q3.anslen = sizeof(q3.qbuf); - q3.action = RESTGT_DOALWAYS; + q2->action = RESTGT_AFTERFAILURE; + q3->qclass = C_IN; + q3->qtype = T_A; + q3->answer = q3->qbuf.buf; + q3->anslen = sizeof(q3->qbuf); + q3->action = RESTGT_DOALWAYS; break; case AF_INET: - q.qclass = C_IN; - q.qtype = T_A; - q.answer = q.qbuf.buf; - q.anslen = sizeof(q.qbuf); - q.action = RESTGT_DOALWAYS; + q->qclass = C_IN; + q->qtype = T_A; + q->answer = q->qbuf.buf; + q->anslen = sizeof(q->qbuf); + q->action = RESTGT_DOALWAYS; break; case AF_INET6: - q.qclass = C_IN; - q.qtype = ns_t_a6; - q.answer = q.qbuf.buf; - q.anslen = sizeof(q.qbuf); - q.next = &q2; + q->qclass = C_IN; + q->qtype = ns_t_a6; + q->answer = q->qbuf.buf; + q->anslen = sizeof(q->qbuf); + q->next = q2; #ifdef RES_USE_A6 if ((pvt->res->options & RES_USE_A6) == 0) - q.action = RESTGT_IGNORE; + q->action = RESTGT_IGNORE; else #endif - q.action = RESTGT_DOALWAYS; - q2.qclass = C_IN; - q2.qtype = T_AAAA; - q2.answer = q2.qbuf.buf; - q2.anslen = sizeof(q2.qbuf); - q2.action = RESTGT_AFTERFAILURE; + q->action = RESTGT_DOALWAYS; + q2->qclass = C_IN; + q2->qtype = T_AAAA; + q2->answer = q2->qbuf.buf; + q2->anslen = sizeof(q2->qbuf); + q2->action = RESTGT_AFTERFAILURE; break; default: RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); /* better error? */ - return(NULL); + goto cleanup; } /* @@ -615,7 +652,7 @@ ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai) tmp, sizeof tmp))) name = cp; - for (p = &q; p; p = p->next) { + for (p = q; p; p = p->next) { struct addrinfo *ai; switch(p->action) { @@ -647,6 +684,13 @@ ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai) querystate = RESQRY_FAIL; } + cleanup: + if (q != NULL) + memput(q, sizeof(*q)); + if (q2 != NULL) + memput(q2, sizeof(*q2)); + if (q3 != NULL) + memput(q3, sizeof(*q3)); return(sentinel.ai_next); } @@ -1153,8 +1197,6 @@ gethostans(struct irs_ho *this, eor = cp + n; if ((qtype == T_A || qtype == T_AAAA || qtype == ns_t_a6 || qtype == T_ANY) && type == T_CNAME) { - if (ap >= &pvt->host_aliases[MAXALIASES-1]) - continue; n = dn_expand(ansbuf, eor, cp, tbuf, sizeof tbuf); if (n < 0 || !maybe_ok(pvt->res, tbuf, name_ok)) { had_error++; @@ -1162,6 +1204,8 @@ gethostans(struct irs_ho *this, } cp += n; /* Store alias. */ + if (ap >= &pvt->host_aliases[MAXALIASES-1]) + continue; *ap++ = bp; n = strlen(bp) + 1; /* for the \0 */ bp += n; diff --git a/contrib/bind/lib/irs/dns_nw.c b/contrib/bind/lib/irs/dns_nw.c index 8e0e965..fbc613f 100644 --- a/contrib/bind/lib/irs/dns_nw.c +++ b/contrib/bind/lib/irs/dns_nw.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns_nw.c,v 1.21 2001/11/30 00:36:53 marka Exp $"; +static const char rcsid[] = "$Id: dns_nw.c,v 1.22 2002/02/27 03:50:10 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports. */ @@ -240,22 +240,33 @@ nw_res_set(struct irs_nw *this, struct __res_state *res, static struct nwent * get1101byname(struct irs_nw *this, const char *name) { struct pvt *pvt = (struct pvt *)this->private; - u_char ansbuf[MAXPACKET]; + u_char *ansbuf; int anslen; + struct nwent *result; - anslen = res_nsearch(pvt->res, name, C_IN, T_PTR, - ansbuf, sizeof ansbuf); - if (anslen < 0) + ansbuf = memget(MAXPACKET); + if (ansbuf == NULL) { + errno = ENOMEM; + RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); return (NULL); - return (get1101mask(this, get1101answer(this, ansbuf, anslen, by_name, - AF_INET, name, NULL, 0))); + } + anslen = res_nsearch(pvt->res, name, C_IN, T_PTR, ansbuf, MAXPACKET); + if (anslen < 0) { + memput(ansbuf, MAXPACKET); + return (NULL); + } + result = get1101mask(this, get1101answer(this, ansbuf, anslen, by_name, + AF_INET, name, NULL, 0)); + memput(ansbuf, MAXPACKET); + return (result); } static struct nwent * get1101byaddr(struct irs_nw *this, u_char *net, int len) { struct pvt *pvt = (struct pvt *)this->private; char qbuf[sizeof "255.255.255.255.in-addr.arpa"]; - u_char ansbuf[MAXPACKET]; + struct nwent *result; + u_char *ansbuf; int anslen; if (len < 1 || len > 32) { @@ -265,12 +276,21 @@ get1101byaddr(struct irs_nw *this, u_char *net, int len) { } if (make1101inaddr(net, len, qbuf, sizeof qbuf) < 0) return (NULL); - anslen = res_nquery(pvt->res, qbuf, C_IN, T_PTR, - ansbuf, sizeof ansbuf); - if (anslen < 0) + ansbuf = memget(MAXPACKET); + if (ansbuf == NULL) { + errno = ENOMEM; + RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); + return (NULL); + } + anslen = res_nquery(pvt->res, qbuf, C_IN, T_PTR, ansbuf, MAXPACKET); + if (anslen < 0) { + memput(ansbuf, MAXPACKET); return (NULL); - return (get1101mask(this, get1101answer(this, ansbuf, anslen, by_addr, - AF_INET, NULL, net, len))); + } + result = get1101mask(this, get1101answer(this, ansbuf, anslen, by_addr, + AF_INET, NULL, net, len)); + memput(ansbuf, MAXPACKET); + return (result); } static struct nwent * @@ -430,7 +450,7 @@ 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; + u_char *ansbuf, *cp, *eom; HEADER *hp; if (!nwent) @@ -441,10 +461,18 @@ get1101mask(struct irs_nw *this, struct nwent *nwent) { return (nwent); } + ansbuf = memget(MAXPACKET); + if (ansbuf == NULL) { + errno = ENOMEM; + RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); + return (NULL); + } /* Query for the A RR that would hold this network's mask. */ - anslen = res_nquery(pvt->res, qbuf, C_IN, T_A, ansbuf, sizeof ansbuf); - if (anslen < HFIXEDSZ) + anslen = res_nquery(pvt->res, qbuf, C_IN, T_A, ansbuf, MAXPACKET); + if (anslen < HFIXEDSZ) { + memput(ansbuf, MAXPACKET); return (nwent); + } /* Initialize, and parse header. */ hp = (HEADER *)ansbuf; @@ -454,8 +482,10 @@ get1101mask(struct irs_nw *this, struct nwent *nwent) { while (qdcount-- > 0) { int n = dn_skipname(cp, eom); cp += n + QFIXEDSZ; - if (n < 0 || cp > eom) + if (n < 0 || cp > eom) { + memput(ansbuf, MAXPACKET); return (nwent); + } } ancount = ntohs(hp->ancount); @@ -489,6 +519,7 @@ get1101mask(struct irs_nw *this, struct nwent *nwent) { } cp += n; /* RDATA */ } + memput(ansbuf, MAXPACKET); return (nwent); } diff --git a/contrib/bind/lib/irs/getaddrinfo.c b/contrib/bind/lib/irs/getaddrinfo.c index f2c533d..243f106 100644 --- a/contrib/bind/lib/irs/getaddrinfo.c +++ b/contrib/bind/lib/irs/getaddrinfo.c @@ -172,13 +172,6 @@ static const struct explore explore[] = { #define PTON_MAX 16 -#define MAXPACKET (1024*64) - -typedef union { - HEADER hdr; - u_char buf[MAXPACKET]; -} querybuf; - static int str_isnumber __P((const char *)); static int explore_fqdn __P((const struct addrinfo *, const char *, const char *, struct addrinfo **)); @@ -320,7 +313,7 @@ getaddrinfo(hostname, servname, hints, res) struct addrinfo sentinel; struct addrinfo *cur; int error = 0; - struct addrinfo ai, ai0, *afai; + struct addrinfo ai, ai0, *afai = NULL; struct addrinfo *pai; const struct explore *ex; diff --git a/contrib/bind/lib/irs/getnameinfo.c b/contrib/bind/lib/irs/getnameinfo.c index 0e86cc1..9b26c64 100644 --- a/contrib/bind/lib/irs/getnameinfo.c +++ b/contrib/bind/lib/irs/getnameinfo.c @@ -105,9 +105,9 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) int family, i; const char *addr; char *p; - u_char pfx; char numserv[512]; char numaddr[512]; + const struct sockaddr_in6 *sin6; if (sa == NULL) return EAI_FAIL; @@ -157,9 +157,23 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) flags |= NI_NUMERICHOST; break; case AF_INET6: - pfx = *addr; - if (pfx == 0 || pfx == 0xfe || pfx == 0xff) - flags |= NI_NUMERICHOST; + sin6 = (const struct sockaddr_in6 *)sa; + switch (sin6->sin6_addr.s6_addr[0]) { + case 0x00: + if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) + ; + else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) + ; + else + flags |= NI_NUMERICHOST; + break; + default: + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) + flags |= NI_NUMERICHOST; + else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) + flags |= NI_NUMERICHOST; + break; + } break; } if (host == NULL || hostlen == 0) { diff --git a/contrib/bind/lib/nameser/ns_sign.c b/contrib/bind/lib/nameser/ns_sign.c index d811411..8c5fe1d 100644 --- a/contrib/bind/lib/nameser/ns_sign.c +++ b/contrib/bind/lib/nameser/ns_sign.c @@ -16,7 +16,7 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_sign.c,v 8.10 2001/05/29 05:49:39 marka Exp $"; +static const char rcsid[] = "$Id: ns_sign.c,v 8.11 2002/04/30 03:43:55 marka Exp $"; #endif /* Import. */ @@ -76,6 +76,16 @@ ns_sign(u_char *msg, int *msglen, int msgsize, int error, void *k, const u_char *querysig, int querysiglen, u_char *sig, int *siglen, time_t in_timesigned) { + return(ns_sign2(msg, msglen, msgsize, error, k, + querysig, querysiglen, sig, siglen, + in_timesigned, NULL, NULL)); +} + +int +ns_sign2(u_char *msg, int *msglen, int msgsize, int error, void *k, + const u_char *querysig, int querysiglen, u_char *sig, int *siglen, + time_t in_timesigned, u_char **dnptrs, u_char **lastdnptr) +{ HEADER *hp = (HEADER *)msg; DST_KEY *key = (DST_KEY *)k; u_char *cp = msg + *msglen, *eob = msg + msgsize; @@ -90,7 +100,7 @@ ns_sign(u_char *msg, int *msglen, int msgsize, int error, void *k, /* Name. */ if (key != NULL && error != ns_r_badsig && error != ns_r_badkey) - n = dn_comp(key->dk_key_name, cp, eob - cp, NULL, NULL); + n = dn_comp(key->dk_key_name, cp, eob - cp, dnptrs, lastdnptr); else n = dn_comp("", cp, eob - cp, NULL, NULL); if (n < 0) @@ -244,6 +254,15 @@ int ns_sign_tcp(u_char *msg, int *msglen, int msgsize, int error, ns_tcp_tsig_state *state, int done) { + return (ns_sign_tcp2(msg, msglen, msgsize, error, state, + done, NULL, NULL)); +} + +int +ns_sign_tcp2(u_char *msg, int *msglen, int msgsize, int error, + ns_tcp_tsig_state *state, int done, + u_char **dnptrs, u_char **lastdnptr) +{ u_char *cp, *eob, *lenp; u_char buf[MAXDNAME], *cp2; HEADER *hp = (HEADER *)msg; @@ -255,9 +274,10 @@ ns_sign_tcp(u_char *msg, int *msglen, int msgsize, int error, state->counter++; if (state->counter == 0) - return (ns_sign(msg, msglen, msgsize, error, state->key, - state->sig, state->siglen, - state->sig, &state->siglen, 0)); + return (ns_sign2(msg, msglen, msgsize, error, state->key, + state->sig, state->siglen, + state->sig, &state->siglen, 0, + dnptrs, lastdnptr)); if (state->siglen > 0) { u_int16_t siglen_n = htons(state->siglen); @@ -280,7 +300,7 @@ ns_sign_tcp(u_char *msg, int *msglen, int msgsize, int error, eob = msg + msgsize; /* Name. */ - n = dn_comp(state->key->dk_key_name, cp, eob - cp, NULL, NULL); + n = dn_comp(state->key->dk_key_name, cp, eob - cp, dnptrs, lastdnptr); if (n < 0) return (NS_TSIG_ERROR_NO_SPACE); cp += n; diff --git a/contrib/bind/lib/resolv/res_findzonecut.c b/contrib/bind/lib/resolv/res_findzonecut.c index 02a28da..a82c3f1 100644 --- a/contrib/bind/lib/resolv/res_findzonecut.c +++ b/contrib/bind/lib/resolv/res_findzonecut.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: res_findzonecut.c,v 8.15 2001/11/01 05:21:22 marka Exp $"; +static const char rcsid[] = "$Id: res_findzonecut.c,v 8.16 2002/04/12 06:27:46 marka Exp $"; #endif /* not lint */ /* @@ -34,7 +34,6 @@ static const char rcsid[] = "$Id: res_findzonecut.c,v 8.15 2001/11/01 05:21:22 m #include <errno.h> #include <limits.h> #include <netdb.h> -#include <resolv.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -44,35 +43,40 @@ static const char rcsid[] = "$Id: res_findzonecut.c,v 8.15 2001/11/01 05:21:22 m #include "port_after.h" +#include <resolv.h> + /* Data structures. */ typedef struct rr_a { LINK(struct rr_a) link; - struct in_addr addr; + union res_sockaddr_union addr; } rr_a; typedef LIST(rr_a) rrset_a; typedef struct rr_ns { LINK(struct rr_ns) link; const char * name; + int have_v4; + int have_v6; rrset_a addrs; } rr_ns; typedef LIST(rr_ns) rrset_ns; /* Forward. */ -static int satisfy(res_state, - const char *, rrset_ns *, struct in_addr *, int); -static int add_addrs(res_state, rr_ns *, struct in_addr *, int); -static int get_soa(res_state, const char *, ns_class, +static int satisfy(res_state, const char *, rrset_ns *, + union res_sockaddr_union *, int); +static int add_addrs(res_state, rr_ns *, + union res_sockaddr_union *, int); +static int get_soa(res_state, const char *, ns_class, int, char *, size_t, char *, size_t, rrset_ns *); -static int get_ns(res_state, const char *, ns_class, rrset_ns *); -static int get_glue(res_state, ns_class, rrset_ns *); +static int get_ns(res_state, const char *, ns_class, int, rrset_ns *); +static int get_glue(res_state, ns_class, int, rrset_ns *); static int save_ns(res_state, ns_msg *, ns_sect, - const char *, ns_class, rrset_ns *); + const char *, ns_class, int, rrset_ns *); static int save_a(res_state, ns_msg *, ns_sect, - const char *, ns_class, rrset_a *); + const char *, ns_class, int, rr_ns *); static void free_nsrrset(rrset_ns *); static void free_nsrr(rrset_ns *, rr_ns *); static rr_ns * find_ns(rrset_ns *, const char *); @@ -145,7 +149,32 @@ static void res_dprintf(const char *, ...) ISC_FORMAT_PRINTF(1, 2); int res_findzonecut(res_state statp, const char *dname, ns_class class, int opts, - char *zname, size_t zsize, struct in_addr *addrs, int naddrs) + char *zname, size_t zsize, struct in_addr *addrs, int naddrs) { + int result, i; + union res_sockaddr_union *u; + + + opts |= RES_IPV4ONLY; + opts &= ~RES_IPV6ONLY; + + u = calloc(naddrs, sizeof(*u)); + if (u == NULL) + return(-1); + + result = res_findzonecut2(statp, dname, class, opts, zname, zsize, + u, naddrs); + + for (i = 0; i < result; i++) { + addrs[i] = u[i].sin.sin_addr; + } + free(u); + return (result); +} + +int +res_findzonecut2(res_state statp, const char *dname, ns_class class, int opts, + char *zname, size_t zsize, union res_sockaddr_union *addrs, + int naddrs) { char mname[NS_MAXDNAME]; u_long save_pfcode; @@ -161,20 +190,20 @@ res_findzonecut(res_state statp, const char *dname, ns_class class, int opts, INIT_LIST(nsrrs); DPRINTF(("get the soa, and see if it has enough glue")); - if ((n = get_soa(statp, dname, class, zname, zsize, + if ((n = get_soa(statp, dname, class, opts, zname, zsize, mname, sizeof mname, &nsrrs)) < 0 || ((opts & RES_EXHAUSTIVE) == 0 && (n = satisfy(statp, mname, &nsrrs, addrs, naddrs)) > 0)) goto done; DPRINTF(("get the ns rrset and see if it has enough glue")); - if ((n = get_ns(statp, zname, class, &nsrrs)) < 0 || + if ((n = get_ns(statp, zname, class, opts, &nsrrs)) < 0 || ((opts & RES_EXHAUSTIVE) == 0 && (n = satisfy(statp, mname, &nsrrs, addrs, naddrs)) > 0)) goto done; DPRINTF(("get the missing glue and see if it's finally enough")); - if ((n = get_glue(statp, class, &nsrrs)) >= 0) + if ((n = get_glue(statp, class, opts, &nsrrs)) >= 0) n = satisfy(statp, mname, &nsrrs, addrs, naddrs); done: @@ -187,8 +216,8 @@ res_findzonecut(res_state statp, const char *dname, ns_class class, int opts, /* Private. */ static int -satisfy(res_state statp, - const char *mname, rrset_ns *nsrrsp, struct in_addr *addrs, int naddrs) +satisfy(res_state statp, const char *mname, rrset_ns *nsrrsp, + union res_sockaddr_union *addrs, int naddrs) { rr_ns *nsrr; int n, x; @@ -215,7 +244,9 @@ satisfy(res_state statp, } static int -add_addrs(res_state statp, rr_ns *nsrr, struct in_addr *addrs, int naddrs) { +add_addrs(res_state statp, rr_ns *nsrr, + union res_sockaddr_union *addrs, int naddrs) +{ rr_a *arr; int n = 0; @@ -231,7 +262,7 @@ add_addrs(res_state statp, rr_ns *nsrr, struct in_addr *addrs, int naddrs) { } static int -get_soa(res_state statp, const char *dname, ns_class class, +get_soa(res_state statp, const char *dname, ns_class class, int opts, char *zname, size_t zsize, char *mname, size_t msize, rrset_ns *nsrrsp) { @@ -332,7 +363,7 @@ get_soa(res_state statp, const char *dname, ns_class class, return (-1); } if (save_ns(statp, &msg, ns_s_ns, - zname, class, nsrrsp) < 0) { + zname, class, opts, nsrrsp) < 0) { DPRINTF(("get_soa: save_ns failed")); return (-1); } @@ -359,7 +390,9 @@ get_soa(res_state statp, const char *dname, ns_class class, } static int -get_ns(res_state statp, const char *zname, ns_class class, rrset_ns *nsrrsp) { +get_ns(res_state statp, const char *zname, ns_class class, int opts, + rrset_ns *nsrrsp) +{ u_char resp[NS_PACKETSZ]; ns_msg msg; int n; @@ -373,7 +406,7 @@ get_ns(res_state statp, const char *zname, ns_class class, rrset_ns *nsrrsp) { } /* Remember the NS RRs and associated A RRs that came back. */ - if (save_ns(statp, &msg, ns_s_an, zname, class, nsrrsp) < 0) { + if (save_ns(statp, &msg, ns_s_an, zname, class, opts, nsrrsp) < 0) { DPRINTF(("get_ns save_ns('%s', %s) failed", zname, p_class(class))); return (-1); @@ -383,7 +416,7 @@ get_ns(res_state statp, const char *zname, ns_class class, rrset_ns *nsrrsp) { } static int -get_glue(res_state statp, ns_class class, rrset_ns *nsrrsp) { +get_glue(res_state statp, ns_class class, int opts, rrset_ns *nsrrsp) { rr_ns *nsrr, *nsrr_n; /* Go and get the A RRs for each empty NS RR on our list. */ @@ -394,7 +427,7 @@ get_glue(res_state statp, ns_class class, rrset_ns *nsrrsp) { nsrr_n = NEXT(nsrr, link); - if (EMPTY(nsrr->addrs)) { + if (!nsrr->have_v4) { n = do_query(statp, nsrr->name, class, ns_t_a, resp, &msg); if (n < 0) { @@ -408,25 +441,47 @@ get_glue(res_state statp, ns_class class, rrset_ns *nsrrsp) { nsrr->name, p_class(class))); } if (save_a(statp, &msg, ns_s_an, nsrr->name, class, - &nsrr->addrs) < 0) { + opts, nsrr) < 0) { DPRINTF(("get_glue: save_r('%s', %s) failed", nsrr->name, p_class(class))); return (-1); } - /* If it's still empty, it's just chaff. */ - if (EMPTY(nsrr->addrs)) { - DPRINTF(("get_glue: removing empty '%s' NS", - nsrr->name)); - free_nsrr(nsrrsp, nsrr); + } + + if (!nsrr->have_v6) { + n = do_query(statp, nsrr->name, class, ns_t_aaaa, + resp, &msg); + if (n < 0) { + DPRINTF(("get_glue: do_query('%s', %s') failed", + nsrr->name, p_class(class))); + return (-1); + } + if (n > 0) { + DPRINTF(( + "get_glue: do_query('%s', %s') CNAME or DNAME found", + nsrr->name, p_class(class))); + } + if (save_a(statp, &msg, ns_s_an, nsrr->name, class, + opts, nsrr) < 0) { + DPRINTF(("get_glue: save_r('%s', %s) failed", + nsrr->name, p_class(class))); + return (-1); } } + + /* If it's still empty, it's just chaff. */ + if (EMPTY(nsrr->addrs)) { + DPRINTF(("get_glue: removing empty '%s' NS", + nsrr->name)); + free_nsrr(nsrrsp, nsrr); + } } return (0); } static int save_ns(res_state statp, ns_msg *msg, ns_sect sect, - const char *owner, ns_class class, + const char *owner, ns_class class, int opts, rrset_ns *nsrrsp) { int i; @@ -471,10 +526,12 @@ save_ns(res_state statp, ns_msg *msg, ns_sect sect, } INIT_LINK(nsrr, link); INIT_LIST(nsrr->addrs); + nsrr->have_v4 = 0; + nsrr->have_v6 = 0; APPEND(*nsrrsp, nsrr, link); } if (save_a(statp, msg, ns_s_ar, - nsrr->name, class, &nsrr->addrs) < 0) { + nsrr->name, class, opts, nsrr) < 0) { DPRINTF(("save_ns: save_r('%s', %s) failed", nsrr->name, p_class(class))); return (-1); @@ -485,8 +542,8 @@ save_ns(res_state statp, ns_msg *msg, ns_sect sect, static int save_a(res_state statp, ns_msg *msg, ns_sect sect, - const char *owner, ns_class class, - rrset_a *arrsp) + const char *owner, ns_class class, int opts, + rr_ns *nsrr) { int i; @@ -499,19 +556,46 @@ save_a(res_state statp, ns_msg *msg, ns_sect sect, p_section(sect, ns_o_query), i)); return (-1); } - if (ns_rr_type(rr) != ns_t_a || + if ((ns_rr_type(rr) != ns_t_a && ns_rr_type(rr) != ns_t_aaaa) || ns_rr_class(rr) != class || ns_samename(ns_rr_name(rr), owner) != 1 || ns_rr_rdlen(rr) != NS_INADDRSZ) continue; + if ((opts & RES_IPV6ONLY) != 0 && ns_rr_type(rr) != ns_t_aaaa) + continue; + if ((opts & RES_IPV4ONLY) != 0 && ns_rr_type(rr) != ns_t_a) + continue; arr = malloc(sizeof *arr); if (arr == NULL) { DPRINTF(("save_a: malloc failed")); return (-1); } INIT_LINK(arr, link); - memcpy(&arr->addr, ns_rr_rdata(rr), NS_INADDRSZ); - APPEND(*arrsp, arr, link); + memset(&arr->addr, 0, sizeof(arr->addr)); + switch (ns_rr_type(rr)) { + case ns_t_a: + arr->addr.sin.sin_family = AF_INET; +#ifdef HAVE_SA_LEN + arr->addr.sin.sin_len = sizeof(arr->addr.sin); +#endif + memcpy(&arr->addr.sin.sin_addr, ns_rr_rdata(rr), + NS_INADDRSZ); + arr->addr.sin.sin_port = htons(NAMESERVER_PORT); + nsrr->have_v4 = 1; + break; + case ns_t_aaaa: + arr->addr.sin6.sin6_family = AF_INET6; +#ifdef HAVE_SA_LEN + arr->addr.sin6.sin6_len = sizeof(arr->addr.sin6); +#endif + memcpy(&arr->addr.sin6.sin6_addr, ns_rr_rdata(rr), 16); + arr->addr.sin.sin_port = htons(NAMESERVER_PORT); + nsrr->have_v6 = 1; + break; + default: + abort(); + } + APPEND(nsrr->addrs, arr, link); } return (0); } diff --git a/contrib/bind/lib/resolv/res_send.c b/contrib/bind/lib/resolv/res_send.c index 6dfea59..6f0e430 100644 --- a/contrib/bind/lib/resolv/res_send.c +++ b/contrib/bind/lib/resolv/res_send.c @@ -70,7 +70,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_send.c,v 8.48 2001/07/03 06:27:17 marka Exp $"; +static const char rcsid[] = "$Id: res_send.c,v 8.49 2002/03/29 21:50:51 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* @@ -521,17 +521,17 @@ get_salen(sa) { #ifdef HAVE_SA_LEN - /* there are people do not set sa_len. be forgibing to them */ + /* There are people do not set sa_len. Be forgiving to them. */ if (sa->sa_len) - return sa->sa_len; + return (sa->sa_len); #endif if (sa->sa_family == AF_INET) - return sizeof(struct sockaddr_in); - else if (sa->sa_family == AF_INET) - return sizeof(struct sockaddr_in6); + return (sizeof(struct sockaddr_in)); + else if (sa->sa_family == AF_INET6) + return (sizeof(struct sockaddr_in6)); else - return 0; /* unknown, die on connect */ + return (0); /* unknown, die on connect */ } /* diff --git a/contrib/bind/lib/resolv/res_update.c b/contrib/bind/lib/resolv/res_update.c index 54d3b15..12ee326 100644 --- a/contrib/bind/lib/resolv/res_update.c +++ b/contrib/bind/lib/resolv/res_update.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: res_update.c,v 1.31 2001/11/01 05:21:23 marka Exp $"; +static const char rcsid[] = "$Id: res_update.c,v 1.34 2002/04/12 06:28:52 marka Exp $"; #endif /* not lint */ /* @@ -77,8 +77,6 @@ struct zonegrp { /* Forward. */ -static int nscopy(union res_sockaddr_union *, - const union res_sockaddr_union *, int); static void res_dprintf(const char *, ...); /* Macros. */ @@ -102,29 +100,21 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) { /* Thread all of the updates onto a list of groups. */ INIT_LIST(zgrps); + memset(&tgrp, 0, sizeof (tgrp)); for (rrecp = rrecp_in; rrecp; rrecp = LINKED(rrecp, r_link) ? NEXT(rrecp, r_link) : NULL) { - struct in_addr nsaddrs[MAXNS]; - int i; - /* XXX need to rewrite res_findzonecut */ - for (i = 0; i < MAXNS; i++) { - nsaddrs[i].s_addr = 0; - if (tgrp.z_nsaddrs[i].sin.sin_family == AF_INET) - nsaddrs[i] = tgrp.z_nsaddrs[i].sin.sin_addr; - } + int nscnt; /* Find the origin for it if there is one. */ tgrp.z_class = rrecp->r_class; - tgrp.z_nscount = - res_findzonecut(statp, rrecp->r_dname, tgrp.z_class, - RES_EXHAUSTIVE, - tgrp.z_origin, - sizeof tgrp.z_origin, - nsaddrs, MAXNS); - if (tgrp.z_nscount <= 0) { - DPRINTF(("res_findzonecut failed (%d)", - tgrp.z_nscount)); + nscnt = res_findzonecut2(statp, rrecp->r_dname, tgrp.z_class, + RES_EXHAUSTIVE, tgrp.z_origin, + sizeof tgrp.z_origin, + tgrp.z_nsaddrs, MAXNS); + if (nscnt <= 0) { + DPRINTF(("res_findzonecut failed (%d)", nscnt)); goto done; } + tgrp.z_nscount = nscnt; /* Find the group for it if there is one. */ for (zptr = HEAD(zgrps); zptr != NULL; zptr = NEXT(zptr, z_link)) if (ns_samename(tgrp.z_origin, zptr->z_origin) == 1 && @@ -166,9 +156,8 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) { goto done; /* Temporarily replace the resolver's nameserver set. */ - nscount = nscopy(nsaddrs, statp->_u._ext.ext->nsaddrs, statp->nscount); - statp->nscount = nscopy(statp->_u._ext.ext->nsaddrs, - zptr->z_nsaddrs, zptr->z_nscount); + nscount = res_getservers(statp, nsaddrs, MAXNS); + res_setservers(statp, zptr->z_nsaddrs, zptr->z_nscount); /* Send the update and remember the result. */ if (key != NULL) @@ -185,7 +174,7 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) { nzones++; /* Restore resolver's nameserver set. */ - statp->nscount = nscopy(statp->_u._ext.ext->nsaddrs, nsaddrs, nscount); + res_setservers(statp, nsaddrs, nscount); nscount = 0; } done: @@ -197,24 +186,13 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) { free(zptr); } if (nscount != 0) - statp->nscount = nscopy(statp->_u._ext.ext->nsaddrs, nsaddrs, nscount); + res_setservers(statp, nsaddrs, nscount); return (nzones); } /* Private. */ -static int -nscopy(union res_sockaddr_union *dst, const union res_sockaddr_union *src, - int n) -{ - int i; - - for (i = 0; i < n; i++) - dst[i] = src[i]; - return (n); -} - static void res_dprintf(const char *fmt, ...) { va_list ap; |