teach IPv6 to async DNS resolver in ypserv:

- query AAAA RR on ipnodes.byname query.
- query .ip6.arpa. on ipnodes.byaddr query.
This commit is contained in:
Hajimu UMEMOTO 2005-05-02 09:34:07 +00:00
parent 7c6523affc
commit 4e5a7758f6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=145792
3 changed files with 61 additions and 27 deletions

View File

@ -69,12 +69,15 @@ parse(struct hostent *hp)
{
static char result[MAXHOSTNAMELEN * 2];
int len,i;
struct in_addr addr;
char addr[46];
if (hp == NULL)
return(NULL);
len = 16 + strlen(hp->h_name);
if (inet_ntop(hp->h_addrtype, hp->h_addr, addr, sizeof(addr)) == NULL)
return(NULL);
len = strlen(addr) + 1 + strlen(hp->h_name);
for (i = 0; hp->h_aliases[i]; i++)
len += strlen(hp->h_aliases[i]) + 1;
len++;
@ -83,10 +86,7 @@ parse(struct hostent *hp)
return(NULL);
bzero(result, sizeof(result));
bcopy(hp->h_addr, &addr, sizeof(struct in_addr));
snprintf(result, sizeof(result), "%s %s", inet_ntoa(addr), hp->h_name);
snprintf(result, sizeof(result), "%s %s", addr, hp->h_name);
for (i = 0; hp->h_aliases[i]; i++) {
strcat(result, " ");
strcat(result, hp->h_aliases[i]);
@ -95,7 +95,7 @@ parse(struct hostent *hp)
return ((char *)&result);
}
#define MAXPACKET 1024
#define MAXPACKET (64*1024)
#define DEF_TTL 50
#define BY_DNS_ID 1
@ -116,7 +116,9 @@ struct circleq_dnsentry {
unsigned short prot_type;
char **domain;
char *name;
struct in_addr addr;
int addrtype;
int addrlen;
uint32_t addr[4]; /* IPv4 or IPv6 */
TAILQ_ENTRY(circleq_dnsentry) links;
};
@ -386,8 +388,9 @@ yp_run_dnsq(void)
if (hent != NULL) {
if (q->type == T_PTR) {
hent->h_addr = (char *)&q->addr.s_addr;
hent->h_length = sizeof(struct in_addr);
hent->h_addr = (char *)q->addr;
hent->h_addrtype = q->addrtype;
hent->h_length = q->addrlen;
}
}
@ -408,7 +411,7 @@ yp_run_dnsq(void)
* Queue and transmit an asynchronous DNS hostname lookup.
*/
ypstat
yp_async_lookup_name(struct svc_req *rqstp, char *name)
yp_async_lookup_name(struct svc_req *rqstp, char *name, int af)
{
register struct circleq_dnsentry *q;
socklen_t len;
@ -431,7 +434,7 @@ yp_async_lookup_name(struct svc_req *rqstp, char *name)
if ((q = yp_malloc_dnsent()) == NULL)
return(YP_YPERR);
q->type = T_A;
q->type = (af == AF_INET) ? T_A : T_AAAA;
q->ttl = DEF_TTL;
q->xprt = rqstp->rq_xprt;
q->ypvers = rqstp->rq_vers;
@ -463,13 +466,14 @@ yp_async_lookup_name(struct svc_req *rqstp, char *name)
* Queue and transmit an asynchronous DNS IP address lookup.
*/
ypstat
yp_async_lookup_addr(struct svc_req *rqstp, char *addr)
yp_async_lookup_addr(struct svc_req *rqstp, char *addr, int af)
{
register struct circleq_dnsentry *q;
char buf[MAXHOSTNAMELEN];
char buf[MAXHOSTNAMELEN], *qp;
uint32_t abuf[4]; /* IPv4 or IPv6 */
u_char *uaddr = (u_char *)abuf;
socklen_t len;
int a, b, c, d;
int type;
int type, n;
/* Check for SOCK_DGRAM or SOCK_STREAM -- we need to know later */
type = -1;
@ -488,10 +492,29 @@ yp_async_lookup_addr(struct svc_req *rqstp, char *addr)
if ((q = yp_malloc_dnsent()) == NULL)
return(YP_YPERR);
if (sscanf(addr, "%d.%d.%d.%d", &a, &b, &c, &d) != 4)
return(YP_NOKEY);
snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa", d, c, b, a);
switch (af) {
case AF_INET:
if (inet_aton(addr, (struct in_addr *)uaddr) != 1)
return(YP_NOKEY);
snprintf(buf, sizeof(buf), "%u.%u.%u.%u.in-addr.arpa",
(uaddr[3] & 0xff), (uaddr[2] & 0xff),
(uaddr[1] & 0xff), (uaddr[0] & 0xff));
len = INADDRSZ;
break;
case AF_INET6:
if (inet_pton(af, addr, uaddr) != 1)
return(YP_NOKEY);
qp = buf;
for (n = IN6ADDRSZ - 1; n >= 0; n--) {
qp += (size_t)sprintf(qp, "%x.%x.", uaddr[n] & 0xf,
(uaddr[n] >> 4) & 0xf);
}
strlcat(buf, "ip6.arpa", sizeof(buf));
len = IN6ADDRSZ;
break;
default:
return(YP_YPERR);
}
if (debug)
yp_error("DNS address is: %s", buf);
@ -513,7 +536,9 @@ yp_async_lookup_addr(struct svc_req *rqstp, char *addr)
return(YP_YPERR);
}
inet_aton(addr, &q->addr);
memcpy(q->addr, uaddr, len);
q->addrlen = len;
q->addrtype = af;
q->name = strdup(buf);
TAILQ_INSERT_HEAD(&qhead, q, links);
pending++;

View File

@ -111,5 +111,5 @@ extern unsigned long svcudp_get_xid(SVCXPRT *);
extern int yp_init_resolver(void);
extern void yp_run_dnsq(void);
extern void yp_prune_dnsq(void);
extern ypstat yp_async_lookup_name(struct svc_req *, char *);
extern ypstat yp_async_lookup_addr(struct svc_req *, char *);
extern ypstat yp_async_lookup_name(struct svc_req *, char *, int);
extern ypstat yp_async_lookup_addr(struct svc_req *, char *, int);

View File

@ -166,9 +166,10 @@ ypproc_match_2_svc(ypreq_key *argp, struct svc_req *rqstp)
#ifdef DB_CACHE
if (result.stat != YP_TRUE &&
(yp_testflag(argp->map, argp->domain, YP_INTERDOMAIN) ||
(strstr(argp->map, "hosts") && do_dns))) {
((strstr(argp->map, "hosts") || strstr(argp->map, "ipnode")) && do_dns))) {
#else
if (do_dns && result.stat != YP_TRUE && strstr(argp->map, "hosts")) {
if (do_dns && result.stat != YP_TRUE &&
(strstr(argp->map, "hosts") || strstr(argp->map, "ipnode"))) {
#endif
char nbuf[YPMAXRECORD];
@ -180,9 +181,17 @@ ypproc_match_2_svc(ypreq_key *argp, struct svc_req *rqstp)
yp_error("doing DNS lookup of %s", nbuf);
if (!strcmp(argp->map, "hosts.byname"))
result.stat = yp_async_lookup_name(rqstp, nbuf);
result.stat = yp_async_lookup_name(rqstp, nbuf,
AF_INET);
else if (!strcmp(argp->map, "hosts.byaddr"))
result.stat = yp_async_lookup_addr(rqstp, nbuf);
result.stat = yp_async_lookup_addr(rqstp, nbuf,
AF_INET);
else if (!strcmp(argp->map, "ipnodes.byname"))
result.stat = yp_async_lookup_name(rqstp, nbuf,
AF_INET6);
else if (!strcmp(argp->map, "ipnodes.byaddr"))
result.stat = yp_async_lookup_addr(rqstp, nbuf,
AF_INET6);
if (result.stat == YP_TRUE)
return(NULL);