This commit was generated by cvs2svn to compensate for changes in r96536,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Jacques Vidrine 2002-05-13 19:31:58 +00:00
commit 0f9cfbb030
35 changed files with 1297 additions and 613 deletions

View File

@ -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

View File

@ -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.

View File

@ -1 +1 @@
8.3.1-REL
8.3.2-T1B

View File

@ -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;
int nscount = 0;
union res_sockaddr_union u[MAXNS];
struct addrinfo *answer = NULL;
struct addrinfo *cur = NULL;
struct addrinfo hint;
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);
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,
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;
}
}
if (nscount != 0) {
char buf[80];
res_setservers(&res, u, nscount);
srvmsg = strcat(srvbuf, srv);
strcat(srvbuf, " ");
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;
} 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;
}
srvmsg = strcat(srvbuf,srv);
strcat(srvbuf, " ");
strcat(srvmsg,
inet_ntoa(res.nsaddr.sin_addr));
}
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;
}
/*

View File

@ -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

View File

@ -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 */
@ -427,21 +491,6 @@ parseclass(const char *s) {
/*NOTREACHED*/
}
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) {
@ -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];
unsigned char *p;
struct in6_addr *addr6;
sprintf(name, "%u.%u.%u.%u.IN-ADDR.ARPA.",
(ha) & 0xff,
(ha >> 8) & 0xff,
(ha >> 16) & 0xff,
(ha >> 24) & 0xff);
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");

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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 {

View File

@ -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,

View File

@ -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);

View File

@ -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);
}

View File

@ -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
ns_socket(int domain, int type, int protocol) {
int fd;
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, 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 ((fd = ns_socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) == -1)
return (SERVFAIL);
if (fd > evHighestFD(ev)) {
close(fd);
return (SERVFAIL);
}
if ((sp = sq_add()) == NULL) {
close(fd);
return (SERVFAIL);
}
if ((sp->s_rfd = ns_socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) == -1) {
sq_remove(sp);
return (SERVFAIL);
}
if (sp->s_rfd > evHighestFD(ev)) {
sq_remove(sp);
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

View File

@ -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;

View File

@ -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);

View File

@ -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
{

View File

@ -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 @@ doaddinfo(HEADER *hp, u_char *msg, int msglen) {
/* 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 @@ doaddinfo(HEADER *hp, u_char *msg, int msglen) {
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 @@ doaddinfo(HEADER *hp, u_char *msg, int msglen) {
}
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),

View File

@ -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 @@ ns_resp(u_char *msg, int msglen, struct sockaddr_in from, struct qstream *qsp)
/* 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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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 *);

View File

@ -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;

View File

@ -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");

View File

@ -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 *));

View File

@ -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));

View File

@ -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. */
}
hp = NULL; /* H_ERRNO was set by subroutines */
return(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;

View File

@ -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);
return (get1101mask(this, get1101answer(this, ansbuf, anslen, by_addr,
AF_INET, NULL, net, len)));
}
anslen = res_nquery(pvt->res, qbuf, C_IN, T_PTR, ansbuf, MAXPACKET);
if (anslen < 0) {
memput(ansbuf, MAXPACKET);
return (NULL);
}
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);
}

View File

@ -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;

View File

@ -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) {

View File

@ -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. */
@ -75,6 +75,16 @@ int
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;
@ -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)
@ -243,6 +253,15 @@ ns_sign_tcp_init(void *k, const u_char *querysig, int querysiglen,
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;
@ -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;

View File

@ -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,17 +441,39 @@ 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);
@ -426,7 +481,7 @@ get_glue(res_state statp, ns_class class, rrset_ns *nsrrsp) {
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);
}

View File

@ -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 */
}
/*

View File

@ -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;

View File

@ -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'