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 | d8cffe661c28e3bb884e152ac50e534f88ae46fd (patch) | |
tree | 8122194080cd713ef54baa64fce62ade7a63be7e /contrib | |
parent | 825bd47b27b5e67e7c938d70c4dde11e68fde1a5 (diff) | |
parent | e044c1fb924b46fc1bd38b298ebea9ff73ea93a8 (diff) | |
download | FreeBSD-src-d8cffe661c28e3bb884e152ac50e534f88ae46fd.zip FreeBSD-src-d8cffe661c28e3bb884e152ac50e534f88ae46fd.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r96536,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib')
35 files changed, 1296 insertions, 612 deletions
diff --git a/contrib/bind/CHANGES b/contrib/bind/CHANGES index 80fb7bc..768e601 100644 --- a/contrib/bind/CHANGES +++ b/contrib/bind/CHANGES @@ -1,6 +1,92 @@ + --- 8.3.2-T1B released --- (Tue May 7 18:49:58 PDT 2002) + +1263. [bug] gethostans() could get out of sync parsing the + response if there was a very long CNAME chain. + +1262. [bug] winnt: dumpdb and stats should now work reliably. + +1261. [bug] using a valid TSIG with a compressed ownername could + result a INSIST() failure. + +1260. [func] "notify explicit;" from BIND 9. + +1259. [misc] leave the verification of the OPT options to the + caller. + +1258. [func] accept SOA MNAME field as legitimate additional + data. + +1257. [bug] malformed response to query w/ tsig + edns. + +1256. [port] darwin: probe for IPv6 support. + +1255. [bug] xfers_running could become out of sync if a zone + was removed while it was being transfered. + +1254. [func] nsupdate can now update IPv6 servers. + +1253. [func] host now accepts IPv6 addresses. + +1253. [bug] reserve space for the signature when performing a + zone transfer. + +1252. [func] dnsquery now accepts IPv6 addresses. + +1251. [bug] win32: it was possible to call RegCloseKey() on a + invalid key. + +1250 [func] nslookup now accepts IPv6 addresses. + +1249. [func] dig now accepts IPv6 addresses. + +1248. [doc] correct some typos in named.conf.5 and corresponding + html. + +1247. [bug] get_salen() IPv6 support was broken for OSs w/o sa_len. + +1246. [support] add highly dangerous compile time option + NXDOMAIN_ON_DENIAL. it should not be used + except in testing. + +1245. [bug] if we don't have enough file descriptors to open + a socket attempt to close a idle tcp client. + +1244. [port] bsdi: 4.3 has struct sockaddr_storage. + +1243. [bug] SERVFAIL can have too many other causes to be used + say whether a server supports EDNS or not. + +1242. [port] 64k answer buffers were causing stack space to be + exceeded for certian OS. Use heap space instead. + +1241. [bug] getnameinfo() failed to lookup IPv4 mapped / + compatible addresses. + +1340. [bug] reference after free for included conf file name. + +1339. [bug] doaddinfo would not always attempt to fetch missing + glue when it should have. + +1338. [bug] an IPv6 only nameserver could generate spurious + sysquery errors. + +1337. [port] linux: IN6ADDR_LOOPBACK_INIT, IN6ADDR_ANY_INIT and + sockaddr_storage not declared by early kernels. + +1336. [bug] getaddrinfo() could call freeaddrinfo() with an + invalid pointer. + +1335. [bug] res_nupdate() failed to update the name servers + addresses before sending the update. + +1334. [bug] A6 is expected in the additional section. + --- 8.3.1-REL released --- (Thu Jan 31 21:28:59 PST 2002) +1333. [bug] cached NXDOMAIN/NODATA responses were being ignored + when when fetching missing additional data. + 1332. [func] "allow-query" is now supported for forward zones. #define FORWARD_ALLOWS in bin/named/named.h to enable. @@ -24,10 +110,6 @@ 1324. [bug] certian bad delegations could result in a DNS storm. -1323. [bug] cached NXDOMAIN/NODATA responses were being ignored - when when fetching missing additional data. - - --- 8.3.0-REL released --- (Fri Jan 11 04:00:00 PST 2002) 1323. [bug] don't assume statp->_u._ext.ext is valid unless diff --git a/contrib/bind/README b/contrib/bind/README index 45f37a4..344a3ef 100644 --- a/contrib/bind/README +++ b/contrib/bind/README @@ -10,6 +10,9 @@ artifacts including BIND, INN, and DHCP. Note that BIND 8 is in "end-of-life", having been replaced by BIND 9. See http://www.isc.org/ for more details. +BIND 8.3.2 Highlights + dig, nslookup, host and nsupdate have improved IPv6 support. + BIND 8.3.1 Highlights Critical bug fix to prevent DNS storms. If you have BIND 8.3.0 you need to upgrade. diff --git a/contrib/bind/Version b/contrib/bind/Version index 067312ac..96227ce 100644 --- a/contrib/bind/Version +++ b/contrib/bind/Version @@ -1 +1 @@ -8.3.1-REL +8.3.2-T1B diff --git a/contrib/bind/bin/dig/dig.c b/contrib/bind/bin/dig/dig.c index 037a495..2054258 100644 --- a/contrib/bind/bin/dig/dig.c +++ b/contrib/bind/bin/dig/dig.c @@ -1,5 +1,5 @@ #ifndef lint -static const char rcsid[] = "$Id: dig.c,v 8.51 2001/12/19 02:25:17 marka Exp $"; +static const char rcsid[] = "$Id: dig.c,v 8.54 2002/04/24 00:38:08 marka Exp $"; #endif /* @@ -172,7 +172,6 @@ static const char rcsid[] = "$Id: dig.c,v 8.51 2001/12/19 02:25:17 marka Exp $"; #include <errno.h> #include <fcntl.h> #include <netdb.h> -#include <resolv.h> #include <setjmp.h> #include <stdio.h> #include <stdlib.h> @@ -181,6 +180,8 @@ static const char rcsid[] = "$Id: dig.c,v 8.51 2001/12/19 02:25:17 marka Exp $"; #include "port_after.h" +#include <resolv.h> + #include "../nslookup/res.h" /* Global. */ @@ -209,9 +210,10 @@ static int eecode = 0; static FILE * qfp; static char *defsrv, *srvmsg; static char defbuf[40] = "default -- "; -static char srvbuf[60]; +static char srvbuf[1024]; static char myhostname[MAXHOSTNAMELEN]; static struct sockaddr_in myaddress; +static struct sockaddr_in6 myaddress6; static u_int32_t ixfr_serial; /* stuff for nslookup modules */ @@ -248,8 +250,8 @@ static void stackarg(char *, char **); int main(int argc, char **argv) { - struct hostent *hp; short port = htons(NAMESERVER_PORT); + short lport; /* Wierd stuff for SPARC alignment, hurts nothing else. */ union { HEADER header_; @@ -302,6 +304,14 @@ main(int argc, char **argv) { myaddress.sin_family = AF_INET; myaddress.sin_addr.s_addr = INADDR_ANY; myaddress.sin_port = 0; /*INPORT_ANY*/; + +#ifdef HAVE_SA_LEN + myaddress6.sin6_len = sizeof(struct sockaddr_in6); +#endif + myaddress6.sin6_family = AF_INET6; + myaddress6.sin6_addr = in6addr_any; + myaddress6.sin6_port = 0; /*INPORT_ANY*/; + defsrv = strcat(defbuf, inet_ntoa(res.nsaddr.sin_addr)); res_x = res; @@ -498,7 +508,7 @@ main(int argc, char **argv) { break; case 'p': if (argv[0][2] != '\0') - port = ntohs(atoi(argv[0]+2)); + port = htons(atoi(argv[0]+2)); else if (*++argv == NULL) printf("; no arg for -p?\n"); else @@ -530,14 +540,19 @@ main(int argc, char **argv) { a = *argv; if ((p = strchr(a, ':')) != NULL) { *p++ = '\0'; - myaddress.sin_port = - ntohs(atoi(p)); - } - if (!inet_aton(a,&myaddress.sin_addr)){ + lport = htons(atoi(p)); + } else + lport = htons(0); + if (inet_pton(AF_INET6, a, + &myaddress6.sin6_addr) == 1) { + myaddress6.sin6_port = lport; + } else if (!inet_aton(a, + &myaddress.sin_addr)) { fprintf(stderr, ";; bad -b addr\n"); exit(1); - } + } else + myaddress.sin_port = lport; } break; case 'k': @@ -749,82 +764,113 @@ main(int argc, char **argv) { srvbuf[0] = 0; srvmsg = defsrv; if (srv != NULL) { - struct in_addr addr; - - if (inet_aton(srv, &addr)) { - res.nscount = 1; - res.nsaddr.sin_addr = addr; - srvmsg = strcat(srvbuf, srv); - } else { - res_t = res; - res_ninit(&res); - res.pfcode = 0; - res.options = RES_DEFAULT; - hp = gethostbyname(srv); + int nscount = 0; + union res_sockaddr_union u[MAXNS]; + struct addrinfo *answer = NULL; + struct addrinfo *cur = NULL; + struct addrinfo hint; + + memset(u, 0, sizeof(u)); + res_t = res; + res_ninit(&res); + res.pfcode = 0; + res.options = RES_DEFAULT; + memset(&hint, 0, sizeof(hint)); + hint.ai_socktype = SOCK_DGRAM; + if (!getaddrinfo(srv, NULL, &hint, &answer)) { res = res_t; - if (hp == NULL - || hp->h_addr_list == NULL - || *hp->h_addr_list == NULL) { - fflush(stdout); - fprintf(stderr, - "; Bad server: %s -- using default server and timer opts\n", - srv); - fflush(stderr); - srvmsg = defsrv; - srv = NULL; - } else { - u_int32_t **addr; - - res.nscount = 0; - for (addr = (u_int32_t**)hp->h_addr_list; - *addr && (res.nscount < MAXNS); - addr++) { - res.nsaddr_list[ - res.nscount++ - ].sin_addr.s_addr = **addr; + cur = answer; + for (cur = answer; + cur != NULL; + cur = cur->ai_next) { + if (nscount == MAXNS) + break; + switch (cur->ai_addr->sa_family) { + case AF_INET6: + u[nscount].sin6 = + *(struct sockaddr_in6*)cur->ai_addr; + u[nscount++].sin6.sin6_port = + port; + break; + case AF_INET: + u[nscount].sin = + *(struct sockaddr_in*)cur->ai_addr; + u[nscount++].sin6.sin6_port = + port; + break; } - - srvmsg = strcat(srvbuf,srv); + } + if (nscount != 0) { + char buf[80]; + res_setservers(&res, u, nscount); + srvmsg = strcat(srvbuf, srv); strcat(srvbuf, " "); - strcat(srvmsg, - inet_ntoa(res.nsaddr.sin_addr)); + buf[0] = '\0'; + switch (u[0].sin.sin_family) { + case AF_INET: + inet_ntop(AF_INET, + &u[0].sin.sin_addr, + buf, sizeof(buf)); + break; + case AF_INET6: + inet_ntop(AF_INET, + &u[0].sin6.sin6_addr, + buf, sizeof(buf)); + break; + } + strcat(srvbuf, buf); } + freeaddrinfo(answer); + } else { + res = res_t; + fflush(stdout); + fprintf(stderr, + "; Bad server: %s -- using default server and timer opts\n", + srv); + fflush(stderr); + srvmsg = defsrv; + srv = NULL; } printf("; (%d server%s found)\n", res.nscount, (res.nscount==1)?"":"s"); res.id += res.retry; } - { - int i; - - for (i = 0; i < res.nscount; i++) { - res.nsaddr_list[i].sin_family = AF_INET; - res.nsaddr_list[i].sin_port = port; - } - res.id += res.retry; - } - if (ns_t_xfr_p(xfr)) { int i; - + int nscount; + union res_sockaddr_union u[MAXNS]; + nscount = res_getservers(&res, u, MAXNS); for (i = 0; i < res.nscount; i++) { int x; if (keyfile) x = printZone(xfr, domain, - &res.nsaddr_list[i], + &u[i].sin, &key); else x = printZone(xfr, domain, - &res.nsaddr_list[i], + &u[i].sin, NULL); if (res.pfcode & RES_PRF_STATS) { + char buf[80]; exectime = time(NULL); + buf[0] = '\0'; + switch (u[i].sin.sin_family) { + case AF_INET: + inet_ntop(AF_INET, + &u[i].sin.sin_addr, + buf, sizeof(buf)); + break; + case AF_INET6: + inet_ntop(AF_INET6, + &u[i].sin6.sin6_addr, + buf, sizeof(buf)); + break; + } printf(";; FROM: %s to SERVER: %s\n", myhostname, - inet_ntoa(res.nsaddr_list[i] - .sin_addr)); + buf); printf(";; WHEN: %s", ctime(&exectime)); } if (!x) @@ -984,7 +1030,7 @@ where: server,\n\ fputs("\ notes: defname and search don't work; use fully-qualified names.\n\ this is DiG version " VSTRING "\n\ - $Id: dig.c,v 8.51 2001/12/19 02:25:17 marka Exp $\n\ + $Id: dig.c,v 8.54 2002/04/24 00:38:08 marka Exp $\n\ ", stderr); } @@ -1322,24 +1368,56 @@ printZone(ns_type xfr, const char *zone, const struct sockaddr_in *sin, perror(";; socket"); return (e); } - if (bind(sockFD, (struct sockaddr *)&myaddress, sizeof myaddress) < 0){ - int e = errno; + + switch (sin->sin_family) { + case AF_INET: + if (bind(sockFD, (struct sockaddr *)&myaddress, + sizeof myaddress) < 0){ + int e = errno; - fprintf(stderr, ";; bind(%s:%u): %s\n", - inet_ntoa(myaddress.sin_addr), - ntohs(myaddress.sin_port), - strerror(e)); - (void) close(sockFD); - sockFD = -1; - return (e); - } - if (connect(sockFD, (const struct sockaddr *)sin, sizeof *sin) < 0) { - int e = errno; + fprintf(stderr, ";; bind(%s:%u): %s\n", + inet_ntoa(myaddress.sin_addr), + ntohs(myaddress.sin_port), + strerror(e)); + (void) close(sockFD); + sockFD = -1; + return (e); + } + if (connect(sockFD, (const struct sockaddr *)sin, + sizeof *sin) < 0) { + int e = errno; - perror(";; connect"); - (void) close(sockFD); - sockFD = -1; - return (e); + perror(";; connect"); + (void) close(sockFD); + sockFD = -1; + return (e); + } + break; + case AF_INET6: + if (bind(sockFD, (struct sockaddr *)&myaddress6, + sizeof myaddress6) < 0){ + int e = errno; + char buf[80]; + + fprintf(stderr, ";; bind(%s:%u): %s\n", + inet_ntop(AF_INET6, &myaddress6.sin6_addr, + buf, sizeof(buf)), + ntohs(myaddress6.sin6_port), + strerror(e)); + (void) close(sockFD); + sockFD = -1; + return (e); + } + if (connect(sockFD, (const struct sockaddr *)sin, + sizeof(struct sockaddr_in6)) < 0) { + int e = errno; + + perror(";; connect"); + (void) close(sockFD); + sockFD = -1; + return (e); + } + break; } /* diff --git a/contrib/bind/bin/dnsquery/dnsquery.c b/contrib/bind/bin/dnsquery/dnsquery.c index c9fed3c..cbc1e85 100644 --- a/contrib/bind/bin/dnsquery/dnsquery.c +++ b/contrib/bind/bin/dnsquery/dnsquery.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: dnsquery.c,v 8.16 2001/09/25 04:50:15 marka Exp $"; +static const char rcsid[] = "$Id: dnsquery.c,v 8.19 2002/04/12 03:03:48 marka Exp $"; #endif /* not lint */ /* @@ -30,7 +30,6 @@ static const char rcsid[] = "$Id: dnsquery.c,v 8.16 2001/09/25 04:50:15 marka Ex #include <errno.h> #include <netdb.h> -#include <resolv.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -38,21 +37,54 @@ static const char rcsid[] = "$Id: dnsquery.c,v 8.16 2001/09/25 04:50:15 marka Ex #include "port_after.h" +#include <resolv.h> + extern int errno; extern int h_errno; extern char *h_errlist[]; struct __res_state res; +static int +newserver(char *srv, union res_sockaddr_union *u, int ns, int max) { + struct addrinfo *answer = NULL; + struct addrinfo *cur = NULL; + struct addrinfo hint; + short port = htons(NAMESERVER_PORT); + + memset(&hint, 0, sizeof(hint)); + hint.ai_socktype = SOCK_DGRAM; + if (!getaddrinfo(srv, NULL, &hint, &answer)) { + for (cur = answer; cur != NULL; cur = cur->ai_next) { + if (ns >= max) + break; + switch (cur->ai_addr->sa_family) { + case AF_INET6: + u[ns].sin6 = + *(struct sockaddr_in6*)cur->ai_addr; + u[ns++].sin6.sin6_port = port; + break; + case AF_INET: + u[ns].sin = *(struct sockaddr_in*)cur->ai_addr; + u[ns++].sin6.sin6_port = port; + break; + } + } + freeaddrinfo(answer); + } else { + fprintf(stderr, "Bad nameserver (%s)\n", srv); + exit(1); + } + return (ns); +} + int main(int argc, char *argv[]) { char name[MAXDNAME]; u_char answer[8*1024]; - int c, n, i = 0; - u_int32_t ul; + int c, n; int nameservers = 0, class, type, len; - struct in_addr q_nsaddr[MAXNS]; - struct hostent *q_nsname; + union res_sockaddr_union q_nsaddr[MAXNS]; extern int optind, opterr; extern char *optarg; int stream = 0, debug = 0; @@ -137,23 +169,8 @@ main(int argc, char *argv[]) { ); exit(1); } - if (nameservers >= MAXNS) break; - (void) inet_aton(optarg, - &q_nsaddr[nameservers]); - if (!inet_aton(optarg, (struct in_addr *)&ul)){ - q_nsname = gethostbyname(optarg); - if (q_nsname == 0) { - fprintf(stderr, - "Bad nameserver (%s)\n", - optarg); - exit(1); - } - memcpy(&q_nsaddr[nameservers], - q_nsname->h_addr, INADDRSZ); - } - else - q_nsaddr[nameservers].s_addr = ul; - nameservers++; + nameservers = newserver(optarg, q_nsaddr, + nameservers, MAXNS); break; default : fprintf(stderr, @@ -189,14 +206,8 @@ main(int argc, char *argv[]) { res.options |= RES_USEVC; /* if the -n flag was used, add them to the resolver's list */ - if (nameservers != 0) { - res.nscount = nameservers; - for (i = nameservers - 1; i >= 0; i--) { - res.nsaddr_list[i].sin_addr.s_addr = q_nsaddr[i].s_addr; - res.nsaddr_list[i].sin_family = AF_INET; - res.nsaddr_list[i].sin_port = htons(NAMESERVER_PORT); - } - } + if (nameservers != 0) + res_setservers(&res, q_nsaddr, nameservers); /* * if the -h arg is fully-qualified, use res_query() since diff --git a/contrib/bind/bin/host/host.c b/contrib/bind/bin/host/host.c index eb28564..84b3621 100644 --- a/contrib/bind/bin/host/host.c +++ b/contrib/bind/bin/host/host.c @@ -1,5 +1,5 @@ #ifndef lint -static const char rcsid[] = "$Id: host.c,v 8.49 2001/12/17 04:24:37 marka Exp $"; +static const char rcsid[] = "$Id: host.c,v 8.52 2002/04/28 01:34:52 marka Exp $"; #endif /* not lint */ /* @@ -100,7 +100,6 @@ static const char copyright[] = #include <ctype.h> #include <netdb.h> -#include <resolv.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -113,6 +112,8 @@ static const char copyright[] = #include "port_after.h" +#include <resolv.h> + /* Global. */ #ifndef PATH_SEP @@ -185,9 +186,8 @@ static char getdomain[NS_MAXDNAME]; static int parsetype(const char *s); static int parseclass(const char *s); -static void printanswer(const struct hostent *hp); static void hperror(int errnum); -static int addrinfo(struct in_addr addr); +static int addrinfo(struct sockaddr_storage *addr); static int gethostinfo(char *name); static int getdomaininfo(const char *name, const char *domain); static int getinfo(const char *name, const char *domain, @@ -225,12 +225,16 @@ Usage: %s [-adlrwv] [-t querytype] [-c class] host [server]\n\ int main(int argc, char **argv) { - struct in_addr addr; + struct sockaddr_storage addr; struct hostent *hp; char *s; int waitmode = 0; int ncnames, ch; int nkeychains; + struct addrinfo *answer = NULL; + struct addrinfo *cur = NULL; + struct addrinfo hint; + int ip = 0; dst_init(); @@ -292,33 +296,93 @@ main(int argc, char **argv) { if (argc > 1) usage("extra undefined arguments"); if (argc == 1) { + union res_sockaddr_union u[MAXNS]; + int nscount; + s = *argv++; argc--; server_specified++; + memset(&hint, 0, sizeof(hint)); + hint.ai_flags = AI_CANONNAME; + hint.ai_family = PF_UNSPEC; + hint.ai_socktype = SOCK_DGRAM; - if (!inet_aton(s, &addr)) { - hp = gethostbyname(s); - if (hp == NULL) { - fprintf(stderr, - "Error in looking up server name:\n"); - hperror(res.res_h_errno); - exit(1); + if (!getaddrinfo(s, NULL, &hint, &answer)) { + nscount = 0; + if (answer->ai_canonname != NULL) { + printf("Using domain server:\n"); + printf("Name: %s\n", answer->ai_canonname); + printf("Addresses:"); + } else + printf("Using domain server"); + + for (cur = answer; cur != NULL; cur = cur->ai_next) { + char buf[80]; + struct sockaddr_in6 *sin6; + struct sockaddr_in *sin; + + switch (cur->ai_addr->sa_family) { + case AF_INET6: + sin6 = + (struct sockaddr_in6 *)cur->ai_addr; + inet_ntop(cur->ai_addr->sa_family, + &sin6->sin6_addr, + buf, sizeof(buf)); + printf(" %s", buf); + if (nscount >= MAXNS) + break; + u[nscount].sin6 = *sin6; + u[nscount++].sin6.sin6_port = + htons(NAMESERVER_PORT); + break; + case AF_INET: + sin = + (struct sockaddr_in*)cur->ai_addr; + inet_ntop(cur->ai_addr->sa_family, + &sin->sin_addr, + buf, sizeof(buf)); + printf(" %s", buf); + if (nscount >= MAXNS) + break; + u[nscount].sin = *sin; + u[nscount++].sin6.sin6_port = + htons(NAMESERVER_PORT); + break; + } } - memcpy(&res.nsaddr.sin_addr, hp->h_addr, NS_INADDRSZ); - printf("Using domain server:\n"); - printanswer(hp); + if (nscount != 0) { + res_setservers(&res, u, nscount); + } + if (answer->ai_canonname != NULL) + printf("\n\n"); + else + printf(":\n\n"); + freeaddrinfo(answer); } else { - res.nsaddr.sin_family = AF_INET; - res.nsaddr.sin_addr = addr; - res.nsaddr.sin_port = htons(NAMESERVER_PORT); - printf("Using domain server %s:\n", - inet_ntoa(res.nsaddr.sin_addr)); + fprintf(stderr, "Error in looking up server name:\n"); + exit(1); } - res.nscount = 1; res.retry = 2; } - if (strcmp(getdomain, ".") == 0 || !inet_aton(getdomain, &addr)) - addr.s_addr = INADDR_NONE; + memset(&hint, 0, sizeof(hint)); + hint.ai_flags = AI_NUMERICHOST; + hint.ai_socktype = SOCK_DGRAM; + if(!getaddrinfo(getdomain, NULL, &hint, &answer)) { + memset(&addr, 0, sizeof(addr)); + switch (answer->ai_family) { + case AF_INET: + memcpy(&addr, answer->ai_addr, + sizeof(struct sockaddr_in)); + ip = 1; + break; + case AF_INET6: + memcpy(&addr, answer->ai_addr, + sizeof(struct sockaddr_in6)); + ip = 1; + break; + } + freeaddrinfo(answer); + } hp = NULL; res.res_h_errno = TRY_AGAIN; /* @@ -330,7 +394,7 @@ main(int argc, char **argv) { exit(ListHosts(getdomain, querytype ? querytype : ns_t_a)); ncnames = 5; nkeychains = 18; while (hp == NULL && res.res_h_errno == TRY_AGAIN) { - if (addr.s_addr == INADDR_NONE) { + if (!ip) { cname = NULL; hp = (struct hostent *)gethostinfo(getdomain); getdomain[0] = 0; /* clear this query */ @@ -378,7 +442,7 @@ main(int argc, char **argv) { continue; } } else { - if (addrinfo(addr) == 0) + if (addrinfo(&addr) == 0) hp = NULL; else hp = (struct hostent *)1; /* XXX */ @@ -428,21 +492,6 @@ parseclass(const char *s) { } static void -printanswer(const struct hostent *hp) { - struct in_addr **hptr; - char **cp; - - printf("Name: %s\n", hp->h_name); - printf("Address:"); - for (hptr = (struct in_addr **)hp->h_addr_list; *hptr; hptr++) - printf(" %s", inet_ntoa(**hptr)); - printf("\nAliases:"); - for (cp = hp->h_aliases; cp && *cp && **cp; cp++) - printf(" %s", *cp); - printf("\n\n"); -} - -static void hperror(int errnum) { switch(errnum) { case HOST_NOT_FOUND: @@ -525,15 +574,50 @@ hperror(int errnum) { } static int -addrinfo(struct in_addr addr) { - u_int32_t ha = ntohl(addr.s_addr); +addrinfo(struct sockaddr_storage *addr) { char name[NS_MAXDNAME]; - - sprintf(name, "%u.%u.%u.%u.IN-ADDR.ARPA.", - (ha) & 0xff, - (ha >> 8) & 0xff, - (ha >> 16) & 0xff, - (ha >> 24) & 0xff); + unsigned char *p; + struct in6_addr *addr6; + + switch(addr->ss_family) { + case AF_INET: + p = (unsigned char*)&((struct sockaddr_in *)addr)->sin_addr; + mapped: + sprintf(name, "%u.%u.%u.%u.IN-ADDR.ARPA.", + p[3], p[2], p[1], p[0]); + break; + case AF_INET6: + addr6 = &((struct sockaddr_in6 *)addr)->sin6_addr; + p = (unsigned char *)addr6; + if (IN6_IS_ADDR_V4MAPPED(addr6) || + IN6_IS_ADDR_V4COMPAT(addr6)) { + p += 12; + goto mapped; + } + sprintf(name, + "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x." + "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x." + "IP6.ARPA", + p[15] & 0xf, (p[15] >> 4) & 0xf, + p[14] & 0xf, (p[14] >> 4) & 0xf, + p[13] & 0xf, (p[13] >> 4) & 0xf, + p[12] & 0xf, (p[12] >> 4) & 0xf, + p[11] & 0xf, (p[11] >> 4) & 0xf, + p[10] & 0xf, (p[10] >> 4) & 0xf, + p[9] & 0xf, (p[9] >> 4) & 0xf, + p[8] & 0xf, (p[8] >> 4) & 0xf, + p[7] & 0xf, (p[7] >> 4) & 0xf, + p[6] & 0xf, (p[6] >> 4) & 0xf, + p[5] & 0xf, (p[5] >> 4) & 0xf, + p[4] & 0xf, (p[4] >> 4) & 0xf, + p[3] & 0xf, (p[3] >> 4) & 0xf, + p[2] & 0xf, (p[2] >> 4) & 0xf, + p[1] & 0xf, (p[1] >> 4) & 0xf, + p[0] & 0xf, (p[0] >> 4) & 0xf); + break; + default: + abort(); + } return (getinfo(name, NULL, ns_t_ptr)); } @@ -1552,12 +1636,44 @@ pr_cdname(const u_char *cp, const u_char *msg, char *name, int namelen) { return (cp + n); } +static void +add(union res_sockaddr_union *u, int type, void *p) { + memset(u, 0, sizeof(*u)); + switch (type) { + case ns_t_a: + memcpy(&u->sin.sin_addr, p, NS_INADDRSZ); + u->sin.sin_family = AF_INET; + u->sin.sin_port = htons(NAMESERVER_PORT); +#ifdef HAVE_SA_LEN + u->sin.sin_len = sizeof(u->sin); +#endif + break; + + case ns_t_aaaa: + memcpy(&u->sin6.sin6_addr, p, 16); + u->sin6.sin6_family = AF_INET6; + u->sin6.sin6_port = htons(NAMESERVER_PORT); +#ifdef HAVE_SA_LEN + u->sin6.sin6_len = sizeof(u->sin6); +#endif + break; + } +} + +static int +salen(union res_sockaddr_union *u) { + switch (u->sin.sin_family) { + case AF_INET6: return (sizeof(u->sin6)); + case AF_INET: return (sizeof(u->sin)); + } + return (0); +} + static int ListHosts(char *namePtr, int queryType) { querybuf buf, answer; struct sockaddr_in sin; const HEADER *headerPtr; - const struct hostent *hp; enum { NO_ERRORS, ERR_READING_LEN, ERR_READING_MSG, ERR_PRINTING } error = NO_ERRORS; @@ -1570,7 +1686,7 @@ ListHosts(char *namePtr, int queryType) { /* Names and addresses of name servers to try. */ char nsname[NUMNS][NS_MAXDNAME]; int nshaveaddr[NUMNS]; - struct in_addr nsipaddr[NUMNSADDR]; + union res_sockaddr_union nsipaddr[NUMNSADDR]; int numns, numnsaddr, thisns; int qdcount, ancount; @@ -1582,10 +1698,9 @@ ListHosts(char *namePtr, int queryType) { if (namePtr[i-1] == '.') namePtr[i-1] = 0; - if (server_specified) { - memcpy(&nsipaddr[0], &res.nsaddr.sin_addr, NS_INADDRSZ); - numnsaddr = 1; - } else { + if (server_specified) + numnsaddr = res_getservers(&res, nsipaddr, NUMNSADDR); + else { /* * First we have to find out where to look. This needs a NS * query, possibly followed by looking up addresses for some @@ -1703,20 +1818,17 @@ ListHosts(char *namePtr, int queryType) { } } } - } else if (type == ns_t_a) { - if (numnsaddr < NUMNSADDR) - for (i = 0; i < numns; i++) { - if (ns_samename(nsname[i], + } else if ((type == ns_t_a || type == ns_t_aaaa) && + numnsaddr < NUMNSADDR) { + for (i = 0; i < numns; i++) { + if (ns_samename(nsname[i], (char *)domain) - == 1) { - nshaveaddr[i]++; - memcpy( - &nsipaddr[numnsaddr], - cp, NS_INADDRSZ); - numnsaddr++; - break; - } - } + != 1) + continue; + nshaveaddr[i]++; + add(&nsipaddr[numnsaddr++], type, cp); + break; + } } cp += dlen; } @@ -1728,28 +1840,50 @@ ListHosts(char *namePtr, int queryType) { */ for (i = 0; i < numns; i++) { - if (nshaveaddr[i] == 0) { - struct in_addr **hptr; - int numaddrs = 0; + struct addrinfo *answer = NULL; + struct addrinfo *cur = NULL; + struct addrinfo hint; - hp = gethostbyname(nsname[i]); - if (hp) { - for (hptr = (struct in_addr **) - hp->h_addr_list; - *hptr != NULL; - hptr++) - if (numnsaddr < NUMNSADDR) { - memcpy( - &nsipaddr[numnsaddr], - *hptr, NS_INADDRSZ); - numnsaddr++; - numaddrs++; - } + memset(&hint, 0, sizeof(hint)); + hint.ai_family = PF_UNSPEC; + hint.ai_socktype = SOCK_STREAM; + + if (nshaveaddr[i] == 0 && + !getaddrinfo(nsname[i], NULL, &hint, &answer)) { + int numaddrs = 0; + for (cur = answer; + cur != NULL; + cur = cur->ai_next) { + union res_sockaddr_union *u; + + if (numnsaddr >= NUMNSADDR) + break; + + u = &nsipaddr[numnsaddr]; + switch (cur->ai_addr->sa_family) { + case AF_INET6: + u->sin6 = + *(struct sockaddr_in6 *)cur->ai_addr; + u->sin6.sin6_port = + htons(NAMESERVER_PORT); + numnsaddr++; + numaddrs++; + break; + case AF_INET: + u->sin = + *(struct sockaddr_in*)cur->ai_addr; + u->sin6.sin6_port = + htons(NAMESERVER_PORT); + numnsaddr++; + numaddrs++; + break; + } } if (res.options & RES_DEBUG || verbose) printf( "Found %d addresses for %s by extra query\n", numaddrs, nsname[i]); + freeaddrinfo(answer); } else if (res.options & RES_DEBUG || verbose) printf("Found %d addresses for %s\n", nshaveaddr[i], nsname[i]); @@ -1786,14 +1920,31 @@ ListHosts(char *namePtr, int queryType) { */ for ((void)NULL; thisns < numnsaddr; thisns++) { - if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + if ((sockFD = socket(nsipaddr[thisns].sin.sin_family, + SOCK_STREAM, 0)) < 0) { + if (errno == EPROTONOSUPPORT) + continue; perror("ListHosts"); return (ERROR); } - memcpy(&sin.sin_addr, &nsipaddr[thisns], NS_INADDRSZ); - if (res.options & RES_DEBUG || verbose) - printf("Trying %s\n", inet_ntoa(sin.sin_addr)); - if (connect(sockFD, (struct sockaddr *)&sin, sizeof(sin)) >= 0) + if (res.options & RES_DEBUG || verbose) { + char buf[80]; + switch (nsipaddr[thisns].sin.sin_family) { + case AF_INET: + inet_ntop(nsipaddr[thisns].sin.sin_family, + &nsipaddr[thisns].sin.sin_addr, + buf, sizeof(buf)); + break; + case AF_INET6: + inet_ntop(nsipaddr[thisns].sin6.sin6_family, + &nsipaddr[thisns].sin6.sin6_addr, + buf, sizeof(buf)); + break; + } + printf("Trying %s\n", buf); + } + if (connect(sockFD, (struct sockaddr *)&nsipaddr[thisns], + salen(&nsipaddr[thisns])) >= 0) break; if (verbose) perror("Connection failed, trying next server"); diff --git a/contrib/bind/bin/named/named.conf b/contrib/bind/bin/named/named.conf index 08ef27d..d0d2996 100644 --- a/contrib/bind/bin/named/named.conf +++ b/contrib/bind/bin/named/named.conf @@ -52,6 +52,8 @@ options { // notify on a zone-by-zone // basis in the "zone" statement // see (below) + // notify explicit; // only sent the notifies to the + // also-notify list serial-queries 4; // number of parallel SOA queries // we can have outstanding for master // zone change testing purposes @@ -193,6 +195,8 @@ zone "master.demo.zone" { // zone? The global option is used // if "notify" is not specified // here. + // notify explicit; // only sent the notifies to the + // also-notify list also-notify { }; // don't notify any nameservers other // than those on the NS list for this // zone diff --git a/contrib/bind/bin/named/named.h b/contrib/bind/bin/named/named.h index 023767c..a9d6088 100644 --- a/contrib/bind/bin/named/named.h +++ b/contrib/bind/bin/named/named.h @@ -16,10 +16,11 @@ */ /* - * $Id: named.h,v 8.31 2002/02/01 00:05:38 marka Exp $ + * $Id: named.h,v 8.32 2002/03/15 00:58:16 vixie Exp $ */ /* Options. Change them at your peril. */ +#undef NXDOMAIN_ON_DENIAL #define DEBUG #define ADDAUTH #define STUBS diff --git a/contrib/bind/bin/named/ns_config.c b/contrib/bind/bin/named/ns_config.c index 2d59a62..1680d91 100644 --- a/contrib/bind/bin/named/ns_config.c +++ b/contrib/bind/bin/named/ns_config.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_config.c,v 8.133 2002/02/01 00:05:39 marka Exp $"; +static const char rcsid[] = "$Id: ns_config.c,v 8.134 2002/04/25 05:27:04 marka Exp $"; #endif /* not lint */ /* @@ -317,7 +317,7 @@ validate_zone(struct zoneinfo *zp) { #ifdef BIND_NOTIFY /* Check notify */ - if (zp->z_notify != znotify_use_default) { + if (zp->z_notify != notify_use_default) { if (zp->z_type != z_master && zp->z_type != z_slave) { ns_error(ns_log_config, "'notify' given for non-master, non-slave zone '%s'", @@ -872,7 +872,7 @@ set_zone_dialup(zone_config zh, int value) { if (value) { zp->z_dialup = zdialup_yes; #ifdef BIND_NOTIFY - zp->z_notify = znotify_yes; + zp->z_notify = notify_yes; #endif } else zp->z_dialup = zdialup_no; @@ -881,17 +881,14 @@ set_zone_dialup(zone_config zh, int value) { } int -set_zone_notify(zone_config zh, int value) { +set_zone_notify(zone_config zh, enum notify value) { #ifdef BIND_NOTIFY struct zoneinfo *zp; zp = zh.opaque; INSIST(zp != NULL); - if (value) - zp->z_notify = znotify_yes; - else - zp->z_notify = znotify_no; + zp->z_notify = value; #endif return (1); } @@ -1150,6 +1147,9 @@ new_options() { op->max_log_size_ixfr = 0; op->minroots = MINROOTS; op->preferred_glue = 0; +#ifdef BIND_NOTIFY + op->notify = notify_yes; +#endif return (op); } @@ -1210,7 +1210,6 @@ set_boolean_option(u_int *op_flags, int bool_opt, int value) { case OPTION_NOFETCHGLUE: case OPTION_FORWARD_ONLY: case OPTION_FAKE_IQUERY: - case OPTION_NONOTIFY: case OPTION_SUPNOTIFY_INITIAL: case OPTION_NONAUTH_NXDOMAIN: case OPTION_MULTIPLE_CNAMES: diff --git a/contrib/bind/bin/named/ns_defs.h b/contrib/bind/bin/named/ns_defs.h index 86a81b6..3474550 100644 --- a/contrib/bind/bin/named/ns_defs.h +++ b/contrib/bind/bin/named/ns_defs.h @@ -1,6 +1,6 @@ /* * from ns.h 4.33 (Berkeley) 8/23/90 - * $Id: ns_defs.h,v 8.115 2002/01/29 03:59:35 marka Exp $ + * $Id: ns_defs.h,v 8.118 2002/04/25 05:27:06 marka Exp $ */ /* @@ -170,10 +170,11 @@ typedef enum need { main_need_qrylog, /* toggle_qrylog() needed. */ main_need_debug, /* use_desired_debug() needed. */ main_need_restart, /* exec() needed. */ - main_need_reap, /* need to reap dead children */ - main_need_noexpired, /* ns_reconfig() needed w/ noexpired set */ + main_need_reap, /* need to reap dead children. */ + main_need_noexpired, /* ns_reconfig() needed w/ noexpired set. */ main_need_num, /* number of needs, used for array bound. */ - main_need_tick /* tick every second to poll for cleanup (NT)*/ + main_need_tick, /* tick every second to poll for cleanup (NT) */ + main_need_tryxfer /* attemt to start a zone transfer. */ } main_need; /* What global options are set? */ @@ -182,7 +183,7 @@ typedef enum need { #define OPTION_FORWARD_ONLY 0x00000004 /* Don't use NS RR's, just forward. */ #define OPTION_FAKE_IQUERY 0x00000008 /* Fake up bogus response to IQUERY. */ #ifdef BIND_NOTIFY -#define OPTION_NONOTIFY 0x00000010 /* Turn off notify */ +/* #define OPTION_NONOTIFY 0x00000010 */ /* Turn off notify */ #define OPTION_SUPNOTIFY_INITIAL 0x00000020 /* Supress initial notify */ #endif #define OPTION_NONAUTH_NXDOMAIN 0x00000040 /* Generate non-auth NXDOMAINs? */ @@ -272,7 +273,7 @@ typedef enum need { enum severity { ignore, warn, fail, not_set }; #ifdef BIND_NOTIFY -enum znotify { znotify_use_default=0, znotify_yes, znotify_no }; +enum notify { notify_use_default=0, notify_yes, notify_no, notify_explicit }; #endif enum zdialup { zdialup_use_default=0, zdialup_yes, zdialup_no }; @@ -368,7 +369,7 @@ struct zoneinfo { from us */ long z_max_transfer_time_in; /* max num seconds for AXFR */ #ifdef BIND_NOTIFY - enum znotify z_notify; /* Notify mode */ + enum notify z_notify; /* Notify mode */ struct in_addr *z_also_notify; /* More nameservers to notify */ int z_notify_count; #endif @@ -496,7 +497,7 @@ struct qinfo { u_int16_t q_class; /* class of query */ u_int16_t q_type; /* type of query */ #ifdef BIND_NOTIFY - int q_notifyzone; /* zone which needs another znotify() + int q_notifyzone; /* zone which needs another notify() * when the reply to this comes in. */ #endif @@ -610,6 +611,8 @@ struct qstream { ns_tcp_tsig_state *tsig_state; /* used by ns_sign_tcp */ int tsig_skip; /* skip calling ns_sign_tcp * during the next flush */ + int tsig_size; /* need to reserve this space + * for the tsig. */ struct qs_x_lev { /* decompose the recursion. */ enum {sxl_ns, sxl_all, sxl_sub} state; /* what's this level doing? */ @@ -790,6 +793,7 @@ typedef struct options { u_int lame_ttl; int minroots; u_int16_t preferred_glue; + enum notify notify; } *options; typedef struct key_list_element { diff --git a/contrib/bind/bin/named/ns_forw.c b/contrib/bind/bin/named/ns_forw.c index f62ba20..494a96a 100644 --- a/contrib/bind/bin/named/ns_forw.c +++ b/contrib/bind/bin/named/ns_forw.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)ns_forw.c 4.32 (Berkeley) 3/3/91"; -static const char rcsid[] = "$Id: ns_forw.c,v 8.89 2002/01/29 03:59:36 marka Exp $"; +static const char rcsid[] = "$Id: ns_forw.c,v 8.90 2002/02/22 05:12:35 marka Exp $"; #endif /* not lint */ /* @@ -467,6 +467,7 @@ nslookup(struct databuf *nsp[], struct qinfo *qp, const char *fname; int oldn, naddr, class, found_arr, potential_ns, lame_ns; time_t curtime; + int found_auth6; ns_debug(ns_log_default, 3, "nslookup(nsp=%p, qp=%p, \"%s\", d=%d)", nsp, qp, syslogdname, qp->q_distance); @@ -503,19 +504,17 @@ nslookup(struct databuf *nsp[], struct qinfo *qp, } } + found_arr = 0; + found_auth6 = 0; tmphtp = ((nsdp->d_flags & DB_F_HINT) ?fcachetab :hashtab); np = nlookup(dname, &tmphtp, &fname, 0); if (np == NULL) { ns_debug(ns_log_default, 3, "%s: not found %s %p", dname, fname, np); - found_arr = 0; goto need_sysquery; } - if (fname != dname) { - found_arr = 0; + if (fname != dname) goto need_sysquery; - } - found_arr = 0; oldn = n; /* look for name server addresses */ @@ -534,6 +533,13 @@ nslookup(struct databuf *nsp[], struct qinfo *qp, } if (dp->d_rcode == NXDOMAIN && dp->d_class == class) goto skipserver; + if (dp->d_class == class && + (dp->d_type == T_AAAA || dp->d_type == ns_t_a6) && + (zones[dp->d_zone].z_type == z_master || + zones[dp->d_zone].z_type == z_slave)) { + found_auth6++; + continue; + } if (dp->d_type != T_A || dp->d_class != class) continue; if (dp->d_rcode) { @@ -683,7 +689,7 @@ nslookup(struct databuf *nsp[], struct qinfo *qp, } ns_debug(ns_log_default, 8, "nslookup: %d ns addrs", n); need_sysquery: - if (found_arr == 0) { + if (found_arr == 0 && found_auth6 == 0) { potential_ns++; if (qp->q_distance < NS_MAX_DISTANCE) (void) sysquery(dname, class, T_A, NULL, NULL, diff --git a/contrib/bind/bin/named/ns_func.h b/contrib/bind/bin/named/ns_func.h index 501aa01..e035d93 100644 --- a/contrib/bind/bin/named/ns_func.h +++ b/contrib/bind/bin/named/ns_func.h @@ -90,7 +90,7 @@ /* ns_func.h - declarations for ns_*.c's externally visible functions * - * $Id: ns_func.h,v 8.115 2002/01/29 03:59:38 marka Exp $ + * $Id: ns_func.h,v 8.117 2002/04/25 05:27:07 marka Exp $ */ /* ++from ns_glue.c++ */ @@ -313,6 +313,7 @@ void qserial_answer(struct qinfo *); void printzoneinfo(int, int, int); #endif void endxfer(void); +void tryxfer(void); void addxfer(struct zoneinfo *); void ns_zreload(void); void ns_reload(void); @@ -421,7 +422,7 @@ int set_zone_type(zone_config, int); int set_zone_filename(zone_config, char *); int set_zone_checknames(zone_config, enum severity); #ifdef BIND_NOTIFY -int set_zone_notify(zone_config, int value); +int set_zone_notify(zone_config, enum notify value); #endif int set_zone_maintain_ixfr_base(zone_config, int value); int set_zone_update_acl(zone_config, ip_match_list); diff --git a/contrib/bind/bin/named/ns_lexer.c b/contrib/bind/bin/named/ns_lexer.c index 4a6f820..b10219a 100644 --- a/contrib/bind/bin/named/ns_lexer.c +++ b/contrib/bind/bin/named/ns_lexer.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_lexer.c,v 8.28 2001/12/28 04:07:47 marka Exp $"; +static const char rcsid[] = "$Id: ns_lexer.c,v 8.30 2002/04/25 05:27:08 marka Exp $"; #endif /* not lint */ /* @@ -57,7 +57,7 @@ typedef enum lexer_state { #define LEXER_MAX_PUSHBACK 2 typedef struct lexer_file_context { - const char * name; + char * name; FILE * stream; int line_number; LexerState state; @@ -251,6 +251,7 @@ static struct keyword keywords[] = { {"directory", T_DIRECTORY}, {"dump-file", T_DUMP_FILE}, {"dynamic", T_DYNAMIC}, + {"explicit", T_EXPLICIT}, {"fail", T_FAIL}, {"fake-iquery", T_FAKE_IQUERY}, {"false", T_FALSE}, @@ -400,7 +401,7 @@ lexer_begin_file(const char *filename, FILE *stream) { panic("memget failed in lexer_begin_file", NULL); INSIST(stream != NULL); lf->stream = stream; - lf->name = filename; /* note copy by reference */ + lf->name = savestr(filename, 1); lf->line_number = 1; lf->state = scan; lf->flags = 0; @@ -419,6 +420,7 @@ lexer_end_file(void) { lf = current_file; current_file = lf->next; fclose(lf->stream); + freestr(lf->name); memput(lf, sizeof *lf); } diff --git a/contrib/bind/bin/named/ns_main.c b/contrib/bind/bin/named/ns_main.c index 23cf249..d839387 100644 --- a/contrib/bind/bin/named/ns_main.c +++ b/contrib/bind/bin/named/ns_main.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)ns_main.c 4.55 (Berkeley) 7/1/91"; -static const char rcsid[] = "$Id: ns_main.c,v 8.155 2001/11/16 05:37:27 marka Exp $"; +static const char rcsid[] = "$Id: ns_main.c,v 8.157 2002/04/13 23:26:16 marka Exp $"; #endif /* not lint */ /* @@ -570,18 +570,46 @@ main(int argc, char *argv[]) { } static int +sq_closeone(void) { + struct qstream *sp, *nextsp; + struct qstream *candidate = NULL; + time_t lasttime, maxctime = 0; + int result = 0; + + gettime(&tt); + + for (sp = streamq; sp; sp = nextsp) { + nextsp = sp->s_next; + if (sp->s_refcnt) + continue; + lasttime = tt.tv_sec - sp->s_time; + if (lasttime >= VQEXPIRY) { + sq_remove(sp); + result = 1; + } else if (lasttime > maxctime) { + candidate = sp; + maxctime = lasttime; + } + } + if (candidate) { + sq_remove(candidate); + result = 1; + } + return (result); +} + +static int ns_socket(int domain, int type, int protocol) { - int fd; + int fd, tmp; + again: fd = socket(domain, type, protocol); - if (fd == -1) - return (-1); #ifdef F_DUPFD /* XXX */ /* * Leave a space for stdio to work in. */ if (fd >= 0 && fd <= 20) { - int new, tmp; + int new; if ((new = fcntl(fd, F_DUPFD, 20)) == -1) ns_notice(ns_log_default, "fcntl(fd, F_DUPFD, 20): %s", strerror(errno)); @@ -591,6 +619,11 @@ ns_socket(int domain, int type, int protocol) { fd = new; } #endif + tmp = errno; + if (errno == EMFILE) + if (sq_closeone()) + goto again; + errno = tmp; return (fd); } @@ -680,25 +713,7 @@ stream_accept(evContext lev, void *uap, int rfd, * eventlib which will call us right back. */ if (streamq) { - struct qstream *nextsp; - struct qstream *candidate = NULL; - time_t lasttime, maxctime = 0; - - for (sp = streamq; sp; sp = nextsp) { - nextsp = sp->s_next; - if (sp->s_refcnt) - continue; - gettime(&tt); - lasttime = tt.tv_sec - sp->s_time; - if (lasttime >= VQEXPIRY) - sq_remove(sp); - else if (lasttime > maxctime) { - candidate = sp; - maxctime = lasttime; - } - } - if (candidate) - sq_remove(candidate); + (void)sq_closeone(); return; } /* fall through */ @@ -808,19 +823,20 @@ tcp_send(struct qinfo *qp) { struct qstream *sp; struct sockaddr_in src; int on = 1, n; + int fd; ns_debug(ns_log_default, 1, "tcp_send"); - if ((sp = sq_add()) == NULL) { + if ((fd = ns_socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) == -1) return (SERVFAIL); - } - if ((sp->s_rfd = ns_socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) == -1) { - sq_remove(sp); + if (fd > evHighestFD(ev)) { + close(fd); return (SERVFAIL); } - if (sp->s_rfd > evHighestFD(ev)) { - sq_remove(sp); + if ((sp = sq_add()) == NULL) { + close(fd); return (SERVFAIL); } + sp->s_rfd = fd; if (setsockopt(sp->s_rfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) < 0) ns_info(ns_log_default, @@ -2837,6 +2853,7 @@ init_needs(void) { handlers[main_need_restart] = ns_restart; handlers[main_need_reap] = reapchild; handlers[main_need_noexpired] = ns_noexpired; + handlers[main_need_tryxfer] = tryxfer; } static void diff --git a/contrib/bind/bin/named/ns_maint.c b/contrib/bind/bin/named/ns_maint.c index 0408936..82df685 100644 --- a/contrib/bind/bin/named/ns_maint.c +++ b/contrib/bind/bin/named/ns_maint.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)ns_maint.c 4.39 (Berkeley) 3/2/91"; -static const char rcsid[] = "$Id: ns_maint.c,v 8.131 2001/11/12 04:49:32 marka Exp $"; +static const char rcsid[] = "$Id: ns_maint.c,v 8.135 2002/04/25 05:27:10 marka Exp $"; #endif /* not lint */ /* @@ -132,7 +132,6 @@ static int nxfers(struct zoneinfo *), static void startxfer(struct zoneinfo *), abortxfer(struct zoneinfo *), - tryxfer(void), purge_z_2(struct hashbuf *, int); static int purge_nonglue_2(const char *, struct hashbuf *, int, int, int); @@ -453,9 +452,10 @@ ns_heartbeat(evContext ctx, void *uap, struct timespec due, * Trigger a refresh query while the link is up by * sending a notify. */ - if (((zp->z_notify == znotify_yes) || - ((zp->z_notify == znotify_use_default) && - !NS_OPTION_P(OPTION_NONOTIFY))) && + if (((zp->z_notify == notify_yes) || + (zp->z_notify == notify_explicit) || + ((zp->z_notify == notify_use_default) && + server_options->notify != notify_no)) && (zt == z_master || zt == z_slave) && !loading && ((zp->z_flags & Z_AUTH) != 0)) ns_notify(zp->z_origin, zp->z_class, ns_t_soa); @@ -1199,6 +1199,22 @@ remove_zone(struct zoneinfo *zp, const char *verb) { xfers_deferred--; } ns_stopxfrs(zp); + if ((zp->z_flags & Z_XFER_RUNNING) != 0) { + int i; + /* Kill and abandon the current transfer. */ + for (i = 0; i < MAX_XFERS_RUNNING; i++) { + if (xferstatus[i].xfer_pid == zp->z_xferpid) { + xferstatus[i].xfer_pid = 0; + xferstatus[i].xfer_state = XFER_IDLE; + xfers_running--; + break; + } + } + (void)kill(zp->z_xferpid, SIGTERM); + zp->z_flags &= ~(Z_XFER_RUNNING|Z_XFER_ABORTED|Z_XFER_GONE); + zp->z_xferpid = 0; + ns_need(main_need_tryxfer); + } do_reload(zp->z_origin, zp->z_type, zp->z_class, 1); ns_notice(ns_log_config, "%s zone \"%s\" (%s) %s", zoneTypeString(zp->z_type), zp->z_origin, @@ -1692,7 +1708,7 @@ endxfer() { /* * Try to start some xfers - new "fair scheduler" by Bob Halley @DEC (1995) */ -static void +void tryxfer() { static struct zoneinfo *zp = NULL; static struct zoneinfo *lastzones = NULL; diff --git a/contrib/bind/bin/named/ns_notify.c b/contrib/bind/bin/named/ns_notify.c index cde636a..286b3eb 100644 --- a/contrib/bind/bin/named/ns_notify.c +++ b/contrib/bind/bin/named/ns_notify.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_notify.c,v 8.18 2001/11/12 04:49:33 marka Exp $"; +static const char rcsid[] = "$Id: ns_notify.c,v 8.20 2002/04/25 05:27:12 marka Exp $"; #endif /* not lint */ /* @@ -56,12 +56,12 @@ static const char rcsid[] = "$Id: ns_notify.c,v 8.18 2001/11/12 04:49:33 marka E /* Types. */ -struct notify { +struct pnotify { char * name; ns_class class; ns_type type; evTimerID timer; - LINK(struct notify) link; + LINK(struct pnotify) link; }; /* Forward. */ @@ -71,14 +71,14 @@ static void sysnotify_slaves(const char *, const char *, ns_class, ns_type, int, int *, int *); static void sysnotify_ns(const char *, const char *, ns_class, ns_type, int, int *, int *); -static void free_notify(struct notify *); +static void free_notify(struct pnotify *); static void notify_timer(evContext, void *, struct timespec, struct timespec); /* Local. */ -static LIST(struct notify) pending_notifies; -static LIST(struct notify) loading_notifies; +static LIST(struct pnotify) pending_notifies; +static LIST(struct pnotify) loading_notifies; /* Public. */ @@ -91,7 +91,7 @@ ns_notify(const char *dname, ns_class class, ns_type type) { static const char no_room[] = "%s failed, cannot notify for zone %s"; int delay, max_delay; struct zoneinfo *zp; - struct notify *ni; + struct pnotify *ni; zp = find_auth_zone(dname, class); if (zp == NULL) { @@ -162,7 +162,7 @@ ns_notify(const char *dname, ns_class class, ns_type type) { void notify_afterload() { - struct notify *ni; + struct pnotify *ni; INSIST(loading == 0); while ((ni = HEAD(loading_notifies)) != NULL) { @@ -180,7 +180,7 @@ notify_afterload() { void ns_unnotify(void) { while (!EMPTY(pending_notifies)) { - struct notify *ni = HEAD(pending_notifies); + struct pnotify *ni = HEAD(pending_notifies); INSIST(LINKED(ni, link)); UNLINK(pending_notifies, ni, link); @@ -194,7 +194,7 @@ ns_unnotify(void) { */ void ns_stopnotify(const char *dname, ns_class class) { - struct notify *ni; + struct pnotify *ni; ni = HEAD(pending_notifies); while (ni != NULL && @@ -235,9 +235,9 @@ sysnotify(const char *dname, ns_class class, ns_type type) { dname); return; } - if (zp->z_notify == znotify_no || - (zp->z_notify == znotify_use_default && - NS_OPTION_P(OPTION_NONOTIFY))) + if (zp->z_notify == notify_no || + (zp->z_notify == notify_use_default && + server_options->notify == notify_no)) return; if (zp->z_type != z_master && zp->z_type != z_slave) { ns_warning(ns_log_notify, "sysnotify: %s not master or slave", @@ -247,7 +247,11 @@ sysnotify(const char *dname, ns_class class, ns_type type) { zname = zp->z_origin; zserial = zp->z_serial; nns = na = 0; - sysnotify_slaves(dname, zname, class, type, zp - zones, &nns, &na); + if (zp->z_notify == notify_yes || + (zp->z_notify == notify_use_default && + server_options->notify == notify_yes)) + sysnotify_slaves(dname, zname, class, type, + zp - zones, &nns, &na); /* * Handle any global or zone-specific also-notify clauses @@ -351,18 +355,26 @@ sysnotify_ns(const char *dname, const char *aname, const char *fname; struct in_addr nss[NSMAX]; struct hashbuf *htp; - int is_us, nsc; + int is_us, nsc, auth6, neg; int cname = 0; htp = hashtab; anp = nlookup(aname, &htp, &fname, 0); nsc = 0; is_us = 0; + auth6 = 0; + neg = 0; if (anp != NULL) for (adp = anp->n_data; adp; adp = adp->d_next) { struct in_addr ina; - if (match(adp, class, T_CNAME)) { + if (adp->d_class != class) + continue; + if (adp->d_rcode == NXDOMAIN) { + neg = 1; + break; + } + if (adp->d_type == T_CNAME && adp->d_rcode == 0) { cname = 1; ns_error(ns_log_notify, "NS '%s' for '%s/%s' is a CNAME", @@ -371,8 +383,18 @@ sysnotify_ns(const char *dname, const char *aname, p_class(class)); break; } + if ((adp->d_type == T_AAAA || adp->d_type == ns_t_a6) && + (zones[adp->d_class].z_type == z_master || + zones[adp->d_class].z_type == z_slave)) { + auth6 = 1; + continue; + } if (!match(adp, class, T_A)) continue; + if (adp->d_rcode) { + neg = 1; + continue; + } if (adp->d_type == ns_t_sig) continue; ina = ina_get(adp->d_data); @@ -384,7 +406,8 @@ sysnotify_ns(const char *dname, const char *aname, nss[nsc++] = ina; } /*next A*/ if (nsc == 0) { - if (!is_us && !cname && !NS_OPTION_P(OPTION_NOFETCHGLUE)) { + if (!is_us && !cname && !auth6 && !neg && + !NS_OPTION_P(OPTION_NOFETCHGLUE)) { struct qinfo *qp; qp = sysquery(aname, class, ns_t_a, NULL, NULL, 0, @@ -400,7 +423,7 @@ sysnotify_ns(const char *dname, const char *aname, } static void -free_notify(struct notify *ni) { +free_notify(struct pnotify *ni) { struct zoneinfo *zp; INSIST(!LINKED(ni, link)); @@ -422,7 +445,7 @@ notify_timer(evContext ctx, void *uap, struct timespec due, struct timespec inter) { - struct notify *ni = uap; + struct pnotify *ni = uap; UNUSED(ctx); UNUSED(due); diff --git a/contrib/bind/bin/named/ns_parser.y b/contrib/bind/bin/named/ns_parser.y index 0fe9dc7..8e62962 100644 --- a/contrib/bind/bin/named/ns_parser.y +++ b/contrib/bind/bin/named/ns_parser.y @@ -1,6 +1,6 @@ %{ #if !defined(lint) && !defined(SABER) -static char rcsid[] = "$Id: ns_parser.y,v 8.78 2001/12/28 04:07:48 marka Exp $"; +static char rcsid[] = "$Id: ns_parser.y,v 8.79 2002/04/25 05:27:13 marka Exp $"; #endif /* not lint */ /* @@ -150,7 +150,7 @@ int yyparse(); %token T_TRANSFER_FORMAT T_MAX_TRANSFER_TIME_IN %token T_SERIAL_QUERIES T_ONE_ANSWER T_MANY_ANSWERS %type <axfr_fmt> transfer_format -%token T_NOTIFY T_NOTIFY_INITIAL T_AUTH_NXDOMAIN +%token T_NOTIFY T_EXPLICIT T_NOTIFY_INITIAL T_AUTH_NXDOMAIN %token T_MULTIPLE_CNAMES T_USE_IXFR T_MAINTAIN_IXFR_BASE %token T_CLEAN_INTERVAL T_INTERFACE_INTERVAL T_STATS_INTERVAL %token T_MAX_LOG_SIZE_IXFR @@ -374,10 +374,16 @@ option: /* Empty */ set_global_boolean_option(current_options, OPTION_HITCOUNT, $2); } + | T_NOTIFY T_EXPLICIT + { + current_options->notify = notify_explicit; + } | T_NOTIFY yea_or_nay { - set_global_boolean_option(current_options, - OPTION_NONOTIFY, !$2); + if ($2) + current_options->notify = notify_yes; + else + current_options->notify = notify_no; } | T_NOTIFY_INITIAL yea_or_nay { @@ -1681,9 +1687,16 @@ zone_option: T_TYPE zone_type { set_zone_max_log_size_ixfr(current_zone, $2); } + | T_NOTIFY T_EXPLICIT + { + set_zone_notify(current_zone, notify_explicit); + } | T_NOTIFY yea_or_nay { - set_zone_notify(current_zone, $2); + if ($2) + set_zone_notify(current_zone, notify_yes); + else + set_zone_notify(current_zone, notify_no); } | T_MAINTAIN_IXFR_BASE yea_or_nay { diff --git a/contrib/bind/bin/named/ns_req.c b/contrib/bind/bin/named/ns_req.c index 6695881..1a1d756 100644 --- a/contrib/bind/bin/named/ns_req.c +++ b/contrib/bind/bin/named/ns_req.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)ns_req.c 4.47 (Berkeley) 7/1/91"; -static const char rcsid[] = "$Id: ns_req.c,v 8.162 2002/02/01 00:05:36 marka Exp $"; +static const char rcsid[] = "$Id: ns_req.c,v 8.168 2002/04/30 03:43:52 marka Exp $"; #endif /* not lint */ /* @@ -231,24 +231,10 @@ ns_get_opt(u_char *msg, u_char *eom, version = *cp++; GETSHORT(flags, cp); GETSHORT(rdlen, cp); - /* ensure options are well formed */ + if (cp + rdlen > eom) + return (-1); options = cp; optsize = rdlen; - while (rdlen != 0) { - u_int16_t code; - u_int16_t len; - - if (rdlen < 4) - return (-1); - GETSHORT(code, cp); - GETSHORT(len, cp); - rdlen -= 4; - if (len > rdlen) - return (-1); - cp += len; - rdlen -= len; - } - /* Everything checks out. */ if (versionp != NULL) *versionp = version; if (rcodep != NULL) @@ -315,6 +301,7 @@ ns_req(u_char *msg, int msglen, int buflen, struct qstream *qsp, u_int16_t rcode = ns_r_noerror; u_int16_t udpsize = 0; int drop; + int tsig_adjust = 0; #ifdef DEBUG if (debug > 3) { @@ -332,9 +319,18 @@ ns_req(u_char *msg, int msglen, int buflen, struct qstream *qsp, has_tsig = 0; else { char buf[MAXDNAME]; + u_char tmp[NS_MAXCDNAME]; has_tsig = 1; - n = dn_expand(msg, msg + msglen, tsigstart, buf, sizeof buf); + n = ns_name_unpack(msg, msg + msglen, tsigstart, + tmp, sizeof tmp); + if (n > 0) { + tsig_adjust = dn_skipname(tmp, tmp + sizeof(tmp)) - n; + if (ns_name_ntop(tmp, buf, sizeof buf) == -1) + n = -1; + else if (buf[0] == '.') + buf[0] = '\0'; + } if (n < 0) { ns_debug(ns_log_default, 1, "ns_req: bad TSIG key name"); @@ -395,7 +391,8 @@ ns_req(u_char *msg, int msglen, int buflen, struct qstream *qsp, in_tsig->siglen = siglen; memcpy(in_tsig->sig, sig, siglen); tsig_size = msglen_orig - msglen; - in_tsig->tsig_size = tsig_size; + /* AXFR/IXFR need the uncompressed tsig size. */ + in_tsig->tsig_size = tsig_size + tsig_adjust; } else if (has_tsig) { action = Finish; in_tsig = memget(sizeof(struct tsig_record)); @@ -576,8 +573,9 @@ ns_req(u_char *msg, int msglen, int buflen, struct qstream *qsp, sig2len = sizeof sig2; msglen = cp - msg; buflen = buflen_orig - msglen; - n = ns_sign(msg, &msglen, msglen + buflen, error, key, - sig, siglen, sig2, &sig2len, tsig_time); + n = ns_sign2(msg, &msglen, msglen + buflen, error, key, + sig, siglen, sig2, &sig2len, tsig_time, + dnptrs, dnptrs_end); if (n == NS_TSIG_ERROR_NO_SPACE && ntohs(hp->qdcount) != 0) { hp->qdcount = htons(0); @@ -609,12 +607,14 @@ ns_req(u_char *msg, int msglen, int buflen, struct qstream *qsp, INSIST(n > 0); cp += n; buflen -= n; + msglen += n; } if (has_tsig > 0) { buflen += tsig_size; sig2len = sizeof sig2; - n = ns_sign(msg, &msglen, msglen + buflen, error, key, - sig, siglen, sig2, &sig2len, tsig_time); + n = ns_sign2(msg, &msglen, msglen + buflen, error, key, + sig, siglen, sig2, &sig2len, tsig_time, + dnptrs, dnptrs_end); if (n != 0) { INSIST(0); } @@ -1218,12 +1218,17 @@ req_query(HEADER *hp, u_char **cpp, u_char *eom, struct qstream *qsp, goto fetchns; } } +#ifdef NXDOMAIN_ON_DENIAL + hp->rcode = ns_r_nxdomain; + return (Finish); +#else ns_notice(ns_log_security, "denied query from %s for \"%s\" %s/%s", sin_ntoa(from), *dname ? dname : ".", p_type(type), p_class(class)); nameserIncr(from.sin_addr, nssRcvdUQ); return (Refuse); +#endif } } else { ip_match_list transfer_acl; @@ -2315,7 +2320,10 @@ doaddinfo(HEADER *hp, u_char *msg, int msglen) { cp = msg; loop: for (ap = addinfo, i = 0; i < addcount; ap++, i++) { - int foundany = 0, + int auth = 0, + founda = 0, + foundaaaa = 0, + founda6 = 0, foundcname = 0, save_count = count, save_msglen = msglen; @@ -2340,16 +2348,27 @@ loop: /* look for the data */ (void)delete_stale(np); for (dp = np->n_data; dp != NULL; dp = dp->d_next) { + if (dp->d_class != ap->a_class) + continue; if (dp->d_rcode == NXDOMAIN) { - if (dp->d_class == ap->a_class) - foundany++; + founda = founda6 = foundaaaa = 1; continue; } - if ((match(dp, (int)ap->a_class, T_CNAME) && - dp->d_type == T_CNAME)) { + switch (dp->d_type) { + case ns_t_a: founda = 1; break; + case ns_t_a6: founda6 = 1; break; + case ns_t_aaaa: foundaaaa = 1; break; + } + if (!dp->d_rcode && dp->d_type == T_CNAME) { foundcname++; break; } + if (auth == 0 && ap->a_type == T_A && + (dp->d_type == ns_t_a || dp->d_type == ns_t_a6 || + dp->d_type == ns_t_aaaa) && + (zones[dp->d_zone].z_type == z_master || + zones[dp->d_zone].z_type == z_slave)) + auth = 1; if (pass == 0 && ap->a_type == T_A && server_options->preferred_glue != 0 && !match(dp, (int)ap->a_class, @@ -2374,8 +2393,6 @@ loop: if (ap->a_type == T_SRV && !match(dp, (int)ap->a_class, T_SRV)) continue; - - foundany++; if (dp->d_rcode) continue; /* @@ -2417,12 +2434,20 @@ loop: } next_rr: if (!NS_OPTION_P(OPTION_NOFETCHGLUE) && - !foundcname && !foundany && - (ap->a_type == T_A || ap->a_type == T_AAAA)) { + !foundcname && ap->a_type == T_A) { /* ask a real server for this info */ - (void) sysquery(ap->a_dname, (int)ap->a_class, - ap->a_type, NULL, NULL, 0, ns_port, - QUERY, 0); + if (!founda && !auth) + (void) sysquery(ap->a_dname, (int)ap->a_class, + ns_t_a, NULL, NULL, 0, ns_port, + QUERY, 0); + if (!foundaaaa && !auth) + (void) sysquery(ap->a_dname, (int)ap->a_class, + ns_t_aaaa, NULL, NULL, 0, + ns_port, QUERY, 0); + if (!founda6 && !auth) + (void) sysquery(ap->a_dname, (int)ap->a_class, + ns_t_a6, NULL, NULL, 0, ns_port, + QUERY, 0); } if (foundcname) { if (!haveComplained(nhash(ap->a_dname), diff --git a/contrib/bind/bin/named/ns_resp.c b/contrib/bind/bin/named/ns_resp.c index ea62674..5be0038 100644 --- a/contrib/bind/bin/named/ns_resp.c +++ b/contrib/bind/bin/named/ns_resp.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static const char sccsid[] = "@(#)ns_resp.c 4.65 (Berkeley) 3/3/91"; -static const char rcsid[] = "$Id: ns_resp.c,v 8.172 2002/01/31 00:06:41 marka Exp $"; +static const char rcsid[] = "$Id: ns_resp.c,v 8.176 2002/04/17 07:10:10 marka Exp $"; #endif /* not lint */ /* @@ -182,7 +182,8 @@ static int rrsetcmp(char *, struct db_list *, struct hashbuf *), struct sockaddr_in, char **); static void mark_bad(struct qinfo *qp, struct sockaddr_in from); static void mark_lame(struct qinfo *qp, struct sockaddr_in from); -static int mark_noedns(struct qinfo *qp, struct sockaddr_in from); +static int mark_noedns(struct qinfo *qp, struct sockaddr_in from, + int cache); static void fast_retry(struct qinfo *qp, struct sockaddr_in from, int samehost); static void add_related_additional(char *); @@ -417,15 +418,15 @@ ns_resp(u_char *msg, int msglen, struct sockaddr_in from, struct qstream *qsp) switch (hp->rcode) { case SERVFAIL: nameserIncr(from.sin_addr, nssRcvdFail); - noedns = mark_noedns(qp, from); + noedns = mark_noedns(qp, from, 0); break; case FORMERR: nameserIncr(from.sin_addr, nssRcvdFErr); - noedns = mark_noedns(qp, from); + noedns = mark_noedns(qp, from, 1); break; case NOTIMP: nameserIncr(from.sin_addr, nssRcvdErr); - noedns = mark_noedns(qp, from); + noedns = mark_noedns(qp, from, 1); break; default: nameserIncr(from.sin_addr, nssRcvdErr); @@ -1059,6 +1060,7 @@ tcp_retry: /* Additional section. */ switch (type) { case T_A: + case ns_t_a6: case T_AAAA: case T_SRV: if (externalcname || @@ -1778,6 +1780,7 @@ rrextract(u_char *msg, int msglen, u_char *rrp, struct databuf **dpp, case T_LOC: case T_KEY: case ns_t_cert: + case ns_t_opt: cp1 = cp; n = dlen; cp += n; @@ -1859,6 +1862,8 @@ rrextract(u_char *msg, int msglen, u_char *rrp, struct databuf **dpp, } n = cp1 - data; cp1 = data; + if (tnamep != NULL && type == T_SOA) + *tnamep = savestr((char *)cp1, 1); break; case T_NAPTR: @@ -3933,14 +3938,14 @@ trunc_adjust(u_char *msg, int msglen, int outlen) { * mark the server "from" bad in the qp structure so it won't be retried. */ static int -mark_noedns(struct qinfo *qp, struct sockaddr_in from) { +mark_noedns(struct qinfo *qp, struct sockaddr_in from, int cache) { int i; for (i = 0; i < (int)qp->q_naddr; i++) if (ina_equal(qp->q_addr[i].ns_addr.sin_addr, from.sin_addr)) { if (qp->q_addr[i].noedns) return (1); - if (qp->q_addr[i].nsdata) + if (qp->q_addr[i].nsdata && cache) qp->q_addr[i].nsdata->d_noedns = 1; qp->q_addr[i].noedns = 1; break; diff --git a/contrib/bind/bin/named/ns_xfr.c b/contrib/bind/bin/named/ns_xfr.c index ab23b6b..d7a8505 100644 --- a/contrib/bind/bin/named/ns_xfr.c +++ b/contrib/bind/bin/named/ns_xfr.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_xfr.c,v 8.67 2001/07/10 05:06:50 marka Exp $"; +static const char rcsid[] = "$Id: ns_xfr.c,v 8.68 2002/04/11 05:19:06 marka Exp $"; #endif /* not lint */ /* @@ -180,13 +180,15 @@ ns_xfr(struct qstream *qsp, struct namebuf *znp, qsp->xfr.transfer_format = si->transfer_format; else qsp->xfr.transfer_format = server_options->transfer_format; - if (in_tsig == NULL) + if (in_tsig == NULL) { qsp->xfr.tsig_state = NULL; - else { + qsp->xfr.tsig_size = 0; + } else { qsp->xfr.tsig_state = memget(sizeof(ns_tcp_tsig_state)); ns_sign_tcp_init(in_tsig->key, in_tsig->sig, in_tsig->siglen, qsp->xfr.tsig_state); qsp->xfr.tsig_skip = 0; + qsp->xfr.tsig_size = in_tsig->tsig_size; } if (type == ns_t_ixfr) { @@ -393,14 +395,15 @@ sx_addrr(struct qstream *qsp, const char *dname, struct databuf *dp) { } } - n = make_rr(dname, dp, qsp->xfr.cp, qsp->xfr.eom - qsp->xfr.cp, - 0, qsp->xfr.ptrs, edp, 0); + n = make_rr(dname, dp, qsp->xfr.cp, qsp->xfr.eom - qsp->xfr.cp - + qsp->xfr.tsig_size, 0, qsp->xfr.ptrs, edp, 0); if (n < 0) { if (sx_flush(qsp) < 0) return (-1); if (qsp->xfr.cp == NULL) sx_newmsg(qsp); - n = make_rr(dname, dp, qsp->xfr.cp, qsp->xfr.eom - qsp->xfr.cp, + n = make_rr(dname, dp, qsp->xfr.cp, qsp->xfr.eom - + qsp->xfr.cp - qsp->xfr.tsig_size, 0, qsp->xfr.ptrs, edp, 0); INSIST(n >= 0); } diff --git a/contrib/bind/bin/nslookup/list.c b/contrib/bind/bin/nslookup/list.c index c910230..3255a19 100644 --- a/contrib/bind/bin/nslookup/list.c +++ b/contrib/bind/bin/nslookup/list.c @@ -53,7 +53,7 @@ #ifndef lint static const char sccsid[] = "@(#)list.c 5.23 (Berkeley) 3/21/91"; -static const char rcsid[] = "$Id: list.c,v 8.26 2001/06/18 14:43:38 marka Exp $"; +static const char rcsid[] = "$Id: list.c,v 8.27 2002/04/09 05:55:17 marka Exp $"; #endif /* not lint */ /* @@ -258,7 +258,9 @@ ListSubr(int qtype, char *domain, char *cmd) { ns_msg handle; querybuf buf; - struct sockaddr_in sin; + struct sockaddr_storage sa; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; HEADER *headerPtr; int msglen, amtToRead, numRead, soacnt; u_int len; @@ -269,6 +271,8 @@ ListSubr(int qtype, char *domain, char *cmd) { enum { NO_ERRORS, ERR_READING_LEN, ERR_READING_MSG, ERR_PRINTING } error = NO_ERRORS; struct iovec iov[2]; + AddrInfo *AddrPtr; + int salen = 0; /* * Create a query packet for the requested domain name. @@ -281,10 +285,6 @@ ListSubr(int qtype, char *domain, char *cmd) { return (ERROR); } - memset(&sin, 0, sizeof sin); - sin.sin_family = AF_INET; - sin.sin_port = htons(nsport); - /* * Check to see if we have the address of the server or the * address of a server who knows about this domain. @@ -293,20 +293,44 @@ ListSubr(int qtype, char *domain, char *cmd) { */ if (defaultPtr->addrList != NULL) - sin.sin_addr = *(struct in_addr *) defaultPtr->addrList[0]; + AddrPtr = defaultPtr->addrList[0]; else - sin.sin_addr = *(struct in_addr *) - defaultPtr->servers[0]->addrList[0]; + AddrPtr = defaultPtr->servers[0]->addrList[0]; + + memset(&sa, 0, sizeof sa); + switch (AddrPtr->addrType) { + case AF_INET: + sin = (struct sockaddr_in *)&sa; + sin->sin_family = AddrPtr->addrType; + sin->sin_port = htons(nsport); + memcpy(&sin->sin_addr, AddrPtr->addr, AddrPtr->addrLen); +#ifdef HAVE_SA_LEN + sin->sin_len = sizeof(*sin); +#endif + salen = sizeof(struct sockaddr_in); + break; + + case AF_INET6: + sin6 = (struct sockaddr_in6 *)&sa; + sin6->sin6_family = AddrPtr->addrType; + sin6->sin6_port = htons(nsport); + memcpy(&sin6->sin6_addr, AddrPtr->addr, AddrPtr->addrLen); +#ifdef HAVE_SA_LEN + sin6->sin6_len = sizeof(*sin6); +#endif + salen = sizeof(struct sockaddr_in6); + break; + } /* * Set up a virtual circuit to the server. */ - sockFD = socket(AF_INET, SOCK_STREAM, 0); + sockFD = socket(AddrPtr->addrType, SOCK_STREAM, 0); if (sockFD < 0) { perror("ls: socket"); return (ERROR); } - if (connect(sockFD, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + if (connect(sockFD, (struct sockaddr *)&sa, salen) < 0) { int e; if (errno == ECONNREFUSED) @@ -530,13 +554,16 @@ Finger(string, putToFile) int putToFile; { struct servent *sp; - struct sockaddr_in sin; + struct sockaddr_storage sa; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; FILE *f; int c; int lastc; char name[NAME_LEN]; char file[PATH_MAX]; int i; + int salen = 0; /* * We need a valid current host info to get an inet address. @@ -573,23 +600,45 @@ Finger(string, putToFile) return (ERROR); } - memset(&sin, 0, sizeof sin); - sin.sin_family = curHostInfo.addrType; - sin.sin_port = sp->s_port; - memcpy(&sin.sin_addr, curHostInfo.addrList[0], curHostInfo.addrLen); + memset(&sa, 0, sizeof sa); + switch (curHostInfo.addrList[0]->addrType) { + case AF_INET: + sin = (struct sockaddr_in *)&sa; + sin->sin_family = curHostInfo.addrList[0]->addrType; + sin->sin_port = sp->s_port; + memcpy(&sin->sin_addr, curHostInfo.addrList[0]->addr, + curHostInfo.addrList[0]->addrLen); +#ifdef HAVE_SA_LEN + sin->sin_len = sizeof(*sin); +#endif + salen = sizeof(struct sockaddr_in); + break; + + case AF_INET6: + sin6 = (struct sockaddr_in6 *)&sa; + sin6->sin6_family = curHostInfo.addrList[0]->addrType; + sin6->sin6_port = sp->s_port; + memcpy(&sin6->sin6_addr, curHostInfo.addrList[0]->addr, + curHostInfo.addrList[0]->addrLen); +#ifdef HAVE_SA_LEN + sin6->sin6_len = sizeof(*sin6); +#endif + salen = sizeof(struct sockaddr_in6); + break; + } /* * Set up a virtual circuit to the host. */ - sockFD = socket(curHostInfo.addrType, SOCK_STREAM, 0); + sockFD = socket(curHostInfo.addrList[0]->addrType, SOCK_STREAM, 0); if (sockFD < 0) { fflush(stdout); perror("finger: socket"); return (ERROR); } - if (connect(sockFD, (struct sockaddr *)&sin, sizeof (sin)) < 0) { + if (connect(sockFD, (struct sockaddr *)&sa, salen) < 0) { fflush(stdout); perror("finger: connect"); close(sockFD); diff --git a/contrib/bind/bin/nslookup/res.h b/contrib/bind/bin/nslookup/res.h index 79f8633..fe9241d 100644 --- a/contrib/bind/bin/nslookup/res.h +++ b/contrib/bind/bin/nslookup/res.h @@ -55,7 +55,7 @@ /* * @(#)res.h 5.10 (Berkeley) 6/1/90 - * $Id: res.h,v 8.9 2001/06/20 12:30:34 marka Exp $ + * $Id: res.h,v 8.10 2002/04/09 05:55:22 marka Exp $ */ /* @@ -131,18 +131,22 @@ typedef int Boolean; * for use in system calls)." */ +typedef struct { + int addrType; + int addrLen; + char *addr; +} AddrInfo; + typedef struct { char *name; /* official name of host */ char **domains; /* domains it serves */ - char **addrList; /* list of addresses from name server */ + AddrInfo **addrList; /* list of addresses from name server */ } ServerInfo; typedef struct { char *name; /* official name of host */ char **aliases; /* alias list */ - char **addrList; /* list of addresses from name server */ - int addrType; /* host address type */ - int addrLen; /* length of address */ + AddrInfo **addrList; /* list of addresses from name server */ ServerInfo **servers; } HostInfo; @@ -188,15 +192,14 @@ extern void PrintHostInfo(); extern void FreeHostInfoPtr(); extern FILE *OpenFile(); extern int pickString(const char *, char *, size_t); -extern int GetHostInfoByName(struct in_addr *, int, int, const char *, - HostInfo *, Boolean); -extern int GetHostInfoByAddr(); -extern int GetHostDomain(struct in_addr *, int, int, const char *, char *, - HostInfo *, Boolean); +extern int GetHostInfoByName(union res_sockaddr_union *, int, int, + const char *, HostInfo *, Boolean, Boolean); +extern int GetHostDomain(union res_sockaddr_union *, int, int, + const char *, char *, HostInfo *, Boolean, Boolean); extern int matchString(const char *, const char *); extern int StringToType(char *, int, FILE *); extern int StringToClass(char *, int, FILE *); -extern int SendRequest(struct in_addr *, const u_char *, int, +extern int SendRequest(union res_sockaddr_union *, const u_char *, int, u_char *, u_int, int *); extern void SendRequest_close(void); extern int SetDefaultServer(char *, Boolean); @@ -217,7 +220,8 @@ SIG_FN IntrHandler(int); int ListSubr(int, char *, char *); void FreeHostInfoPtr(HostInfo *); unsigned char * res_skip(unsigned char *, int, unsigned char *); -extern Boolean IsAddr(const char *, struct in_addr *); +extern Boolean IsAddr(const char *, union res_sockaddr_union *); void PrintHelp(void); -int GetHostInfoByAddr(struct in_addr *, struct in_addr *, HostInfo *); +int GetHostInfoByAddr(union res_sockaddr_union *, union res_sockaddr_union *, + HostInfo *); diff --git a/contrib/bind/bin/nslookup/send.c b/contrib/bind/bin/nslookup/send.c index ecbd75d..de60d21 100644 --- a/contrib/bind/bin/nslookup/send.c +++ b/contrib/bind/bin/nslookup/send.c @@ -53,7 +53,7 @@ #ifndef lint static const char sccsid[] = "@(#)send.c 5.18 (Berkeley) 3/2/91"; -static const char rcsid[] = "$Id: send.c,v 8.12 2001/07/03 06:27:12 marka Exp $"; +static const char rcsid[] = "$Id: send.c,v 8.13 2002/04/09 05:55:23 marka Exp $"; #endif /* not lint */ /* @@ -120,8 +120,8 @@ unsigned short nsport = NAMESERVER_PORT; */ int -SendRequest(struct in_addr *nsAddrPtr, const u_char *buf, int buflen, - u_char *answer, u_int anslen, int *trueLenPtr) +SendRequest(union res_sockaddr_union *nsAddrPtr, const u_char *buf, + int buflen, u_char *answer, u_int anslen, int *trueLenPtr) { int n, try, v_circuit, resplen; ISC_SOCKLEN_T salen; @@ -136,15 +136,15 @@ SendRequest(struct in_addr *nsAddrPtr, const u_char *buf, int buflen, struct iovec iov[2]; int terrno = ETIMEDOUT; char junk[512]; - struct sockaddr_in sin, sa; + struct sockaddr_storage sa; + int family = nsAddrPtr->sin.sin_family; + int clen = (family == AF_INET) ? sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6); if (res.options & RES_DEBUG2) { printf("------------\nSendRequest(), len %d\n", buflen); Print_query(buf, buf + buflen, 1); } - sin.sin_family = AF_INET; - sin.sin_port = htons(nsport); - sin.sin_addr = *nsAddrPtr; v_circuit = (res.options & RES_USEVC) || buflen > PACKETSZ; id = hp->id; /* @@ -161,15 +161,15 @@ SendRequest(struct in_addr *nsAddrPtr, const u_char *buf, int buflen, */ try = res.retry; if (s < 0) { - s = socket(AF_INET, SOCK_STREAM, 0); + s = socket(family, SOCK_STREAM, 0); if (s < 0) { terrno = errno; if (res.options & RES_DEBUG) perror("socket (vc) failed"); continue; } - if (connect(s, (struct sockaddr *)&sin, - sizeof(struct sockaddr)) < 0) { + if (connect(s, (struct sockaddr *)nsAddrPtr, + clen) < 0) { terrno = errno; if (res.options & RES_DEBUG) perror("connect failed"); @@ -266,7 +266,7 @@ SendRequest(struct in_addr *nsAddrPtr, const u_char *buf, int buflen, * Use datagrams. */ if (s < 0) { - s = socket(AF_INET, SOCK_DGRAM, 0); + s = socket(family, SOCK_DGRAM, 0); if (s < 0) { terrno = errno; if (res.options & RES_DEBUG) @@ -276,8 +276,8 @@ SendRequest(struct in_addr *nsAddrPtr, const u_char *buf, int buflen, } #if BSD >= 43 if (connected == 0) { - if (connect(s, (struct sockaddr *)&sin, - sizeof sin) < 0) { + if (connect(s, (struct sockaddr *)nsAddrPtr, + clen) < 0) { if (res.options & RES_DEBUG) perror("connect"); continue; @@ -291,8 +291,8 @@ SendRequest(struct in_addr *nsAddrPtr, const u_char *buf, int buflen, } #else /* BSD */ if (sendto(s, (const char *)buf, buflen, 0, - (struct sockaddr *) &sin, - sizeof sin) != buflen) { + (struct sockaddr *) &nsAddrPtr, + clen) != buflen) { if (res.options & RES_DEBUG) perror("sendto"); continue; diff --git a/contrib/bind/bin/nslookup/subr.c b/contrib/bind/bin/nslookup/subr.c index 854e090..ff9f1e9 100644 --- a/contrib/bind/bin/nslookup/subr.c +++ b/contrib/bind/bin/nslookup/subr.c @@ -53,7 +53,7 @@ #ifndef lint static const char sccsid[] = "@(#)subr.c 5.24 (Berkeley) 3/2/91"; -static const char rcsid[] = "$Id: subr.c,v 8.15 2001/06/18 14:43:45 marka Exp $"; +static const char rcsid[] = "$Id: subr.c,v 8.16 2002/04/09 05:55:24 marka Exp $"; #endif /* not lint */ /* @@ -238,10 +238,12 @@ PrintHostInfo(file, title, hp) const char *title; register HostInfo *hp; { + register AddrInfo **ap; register char **cp; register ServerInfo **sp; char comma; int i; + char buf[80]; fprintf(file, "%-7s %s", title, hp->name); @@ -253,14 +255,18 @@ PrintHostInfo(file, title, hp) } comma = ' '; i = 0; - for (cp = hp->addrList; cp && *cp; cp++) { + for (ap = hp->addrList; ap && *ap; ap++) { i++; if (i > 4) { fprintf(file, "\n\t"); comma = ' '; i = 0; } - fprintf(file,"%c %s", comma, inet_ntoa(*(struct in_addr *)*cp)); + if (inet_ntop((*ap)->addrType, (*ap)->addr, + buf, sizeof(buf)) != NULL) { + fprintf(file,"%c %s", comma, buf); + } else + fprintf(file,"%c <UNKNOWN>", comma); comma = ','; } } @@ -289,15 +295,18 @@ PrintHostInfo(file, title, hp) comma = ' '; i = 0; - for (cp = (*sp)->addrList; cp && *cp && **cp; cp++) { + for (ap = (*sp)->addrList; ap && *ap; ap++) { i++; if (i > 4) { fprintf(file, "\n\t"); comma = ' '; i = 0; } - fprintf(file, - "%c %s", comma, inet_ntoa(*(struct in_addr *)*cp)); + if (inet_ntop((*ap)->addrType, (*ap)->addr, + buf, sizeof(buf)) != NULL) + fprintf(file,"%c %s", comma, buf); + else + fprintf(file,"%c <UNKNOWN>", comma); comma = ','; } fprintf(file, "\n\t"); diff --git a/contrib/bind/include/arpa/nameser.h b/contrib/bind/include/arpa/nameser.h index 955719a..58bc702 100644 --- a/contrib/bind/include/arpa/nameser.h +++ b/contrib/bind/include/arpa/nameser.h @@ -49,7 +49,7 @@ */ /* - * $Id: nameser.h,v 8.46 2001/11/16 05:37:33 marka Exp $ + * $Id: nameser.h,v 8.47 2002/04/30 03:43:53 marka Exp $ */ #ifndef _ARPA_NAMESER_H_ @@ -497,7 +497,9 @@ typedef enum __ns_cert_types { #define ns_name_skip __ns_name_skip #define ns_name_rollback __ns_name_rollback #define ns_sign __ns_sign +#define ns_sign2 __ns_sign2 #define ns_sign_tcp __ns_sign_tcp +#define ns_sign_tcp2 __ns_sign_tcp2 #define ns_sign_tcp_init __ns_sign_tcp_init #define ns_find_tsig __ns_find_tsig #define ns_verify __ns_verify @@ -542,8 +544,14 @@ void ns_name_rollback __P((const u_char *, const u_char **, const u_char **)); int ns_sign __P((u_char *, int *, int, int, void *, const u_char *, int, u_char *, int *, time_t)); +int ns_sign2 __P((u_char *, int *, int, int, void *, + const u_char *, int, u_char *, int *, time_t, + u_char **, u_char **)); int ns_sign_tcp __P((u_char *, int *, int, int, ns_tcp_tsig_state *, int)); +int ns_sign_tcp2 __P((u_char *, int *, int, int, + ns_tcp_tsig_state *, int, + u_char **, u_char **)); int ns_sign_tcp_init __P((void *, const u_char *, int, ns_tcp_tsig_state *)); u_char *ns_find_tsig __P((u_char *, u_char *)); diff --git a/contrib/bind/include/resolv.h b/contrib/bind/include/resolv.h index fb5185e..ff3c01f 100644 --- a/contrib/bind/include/resolv.h +++ b/contrib/bind/include/resolv.h @@ -50,7 +50,7 @@ /* * @(#)resolv.h 8.1 (Berkeley) 6/2/93 - * $Id: resolv.h,v 8.44 2001/12/19 01:44:19 marka Exp $ + * $Id: resolv.h,v 8.45 2002/04/12 06:27:48 marka Exp $ */ #ifndef _RESOLV_H_ @@ -211,8 +211,10 @@ union res_sockaddr_union { #define RES_F_CONN 0x00000002 /* socket is connected */ #define RES_F_EDNS0ERR 0x00000004 /* EDNS0 caused errors */ -/* res_findzonecut() options */ +/* res_findzonecut2() options */ #define RES_EXHAUSTIVE 0x00000001 /* always do all queries */ +#define RES_IPV4ONLY 0x00000002 /* IPv4 only */ +#define RES_IPV6ONLY 0x00000004 /* IPv6 only */ /* * Resolver options (keep these in synch with res_debug.c, please) @@ -353,6 +355,7 @@ extern const struct res_sym __p_rcode_syms[]; #define putshort __putshort #define res_dnok __res_dnok #define res_findzonecut __res_findzonecut +#define res_findzonecut2 __res_findzonecut2 #define res_hnok __res_hnok #define res_hostalias __res_hostalias #define res_mailok __res_mailok @@ -443,6 +446,9 @@ int res_nsendsigned __P((res_state, const u_char *, int, ns_tsig_key *, u_char *, int)); int res_findzonecut __P((res_state, const char *, ns_class, int, char *, size_t, struct in_addr *, int)); +int res_findzonecut2 __P((res_state, const char *, ns_class, int, + char *, size_t, + union res_sockaddr_union *, int)); void res_nclose __P((res_state)); int res_nopt __P((res_state, int, u_char *, int, int)); void res_send_setqhook __P((res_send_qhook hook)); 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; diff --git a/contrib/bind/port/freebsd/Makefile.set b/contrib/bind/port/freebsd/Makefile.set index c1c9bcf..acf7a56 100644 --- a/contrib/bind/port/freebsd/Makefile.set +++ b/contrib/bind/port/freebsd/Makefile.set @@ -1,5 +1,5 @@ 'CC=cc' -'CDEBUG=-O2 -g -W -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings -Wformat' +'CDEBUG=-O2 -g -W -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings -Wformat -DMEMCLUSTER_RECORD=1' 'DESTBIN=/usr/bin' 'DESTSBIN=/usr/sbin' 'DESTEXEC=/usr/libexec' |