summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authoritojun <>2000-06-22 07:31:18 +0000
committeritojun <>2000-06-22 07:31:18 +0000
commitdd1a6930a8ee9dd3edcff14d2150a70fc6d51e86 (patch)
treec6a39f3eeb22abb41739d82a54da3d4c17484cd9 /src/lib
parent0c46311aa0ede7c2ecc84546afb32e1328e9607b (diff)
downloadopenbsd-dd1a6930a8ee9dd3edcff14d2150a70fc6d51e86.tar.gz
openbsd-dd1a6930a8ee9dd3edcff14d2150a70fc6d51e86.tar.bz2
openbsd-dd1a6930a8ee9dd3edcff14d2150a70fc6d51e86.zip
ipv6 support in resolver. "nameserver" line in /etc/resolv.conf now takes
ipv6 address.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libc/net/res_init.c115
-rw-r--r--src/lib/libc/net/res_send.c202
2 files changed, 270 insertions, 47 deletions
diff --git a/src/lib/libc/net/res_init.c b/src/lib/libc/net/res_init.c
index fd8d279cf0..ac75a4babb 100644
--- a/src/lib/libc/net/res_init.c
+++ b/src/lib/libc/net/res_init.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: res_init.c,v 1.18 1999/09/03 21:14:51 deraadt Exp $ */ 1/* $OpenBSD: res_init.c,v 1.19 2000/06/22 07:31:18 itojun Exp $ */
2 2
3/* 3/*
4 * ++Copyright++ 1985, 1989, 1993 4 * ++Copyright++ 1985, 1989, 1993
@@ -55,12 +55,16 @@
55 * --Copyright-- 55 * --Copyright--
56 */ 56 */
57 57
58#ifndef INET6
59#define INET6
60#endif
61
58#if defined(LIBC_SCCS) && !defined(lint) 62#if defined(LIBC_SCCS) && !defined(lint)
59#if 0 63#if 0
60static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; 64static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
61static char rcsid[] = "$From: res_init.c,v 8.7 1996/09/28 06:51:07 vixie Exp $"; 65static char rcsid[] = "$From: res_init.c,v 8.7 1996/09/28 06:51:07 vixie Exp $";
62#else 66#else
63static char rcsid[] = "$OpenBSD: res_init.c,v 1.18 1999/09/03 21:14:51 deraadt Exp $"; 67static char rcsid[] = "$OpenBSD: res_init.c,v 1.19 2000/06/22 07:31:18 itojun Exp $";
64#endif 68#endif
65#endif /* LIBC_SCCS and not lint */ 69#endif /* LIBC_SCCS and not lint */
66 70
@@ -78,6 +82,9 @@ static char rcsid[] = "$OpenBSD: res_init.c,v 1.18 1999/09/03 21:14:51 deraadt E
78#include <unistd.h> 82#include <unistd.h>
79#include <stdlib.h> 83#include <stdlib.h>
80#include <string.h> 84#include <string.h>
85#ifdef INET6
86#include <netdb.h>
87#endif /* INET6 */
81 88
82/*-------------------------------------- info about "sortlist" -------------- 89/*-------------------------------------- info about "sortlist" --------------
83 * Marc Majka 1994/04/16 90 * Marc Majka 1994/04/16
@@ -119,6 +126,9 @@ struct __res_state _res
119 = { RES_TIMEOUT, } /* Motorola, et al. */ 126 = { RES_TIMEOUT, } /* Motorola, et al. */
120# endif 127# endif
121 ; 128 ;
129#ifdef INET6
130struct __res_state_ext _res_ext;
131#endif /* INET6 */
122 132
123/* 133/*
124 * Set up default settings. If the configuration file exist, the values 134 * Set up default settings. If the configuration file exist, the values
@@ -193,6 +203,11 @@ res_init()
193#endif 203#endif
194 _res.nsaddr.sin_family = AF_INET; 204 _res.nsaddr.sin_family = AF_INET;
195 _res.nsaddr.sin_port = htons(NAMESERVER_PORT); 205 _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
206 _res.nsaddr.sin_len = sizeof(struct sockaddr_in);
207#ifdef INET6
208 if (sizeof(_res_ext.nsaddr) >= _res.nsaddr.sin_len)
209 memcpy(&_res_ext.nsaddr, &_res.nsaddr, _res.nsaddr.sin_len);
210#endif
196 _res.nscount = 1; 211 _res.nscount = 1;
197 _res.ndots = 1; 212 _res.ndots = 1;
198 _res.pfcode = 0; 213 _res.pfcode = 0;
@@ -336,23 +351,69 @@ res_init()
336 } 351 }
337 /* read nameservers to query */ 352 /* read nameservers to query */
338 if (MATCH(buf, "nameserver") && nserv < MAXNS) { 353 if (MATCH(buf, "nameserver") && nserv < MAXNS) {
354#ifdef INET6
355 char *q;
356 struct addrinfo hints, *res;
357 char pbuf[NI_MAXSERV];
358#else
339 struct in_addr a; 359 struct in_addr a;
360#endif /* INET6 */
340 361
341 cp = buf + sizeof("nameserver") - 1; 362 cp = buf + sizeof("nameserver") - 1;
342 while (*cp == ' ' || *cp == '\t') 363 while (*cp == ' ' || *cp == '\t')
343 cp++; 364 cp++;
365#ifdef INET6
366 if ((*cp == '\0') || (*cp == '\n'))
367 continue;
368 for (q = cp; *q; q++) {
369 if (isspace(*q)) {
370 *q = '\0';
371 break;
372 }
373 }
374 memset(&hints, 0, sizeof(hints));
375 hints.ai_flags = AI_NUMERICHOST;
376 hints.ai_socktype = SOCK_DGRAM;
377 snprintf(pbuf, sizeof(pbuf), "%d", NAMESERVER_PORT);
378 if (getaddrinfo(cp, pbuf, &hints, &res) == 0 &&
379 res->ai_next == NULL) {
380 if (res->ai_addrlen <= sizeof(_res_ext.nsaddr_list[nserv])) {
381 memcpy(&_res_ext.nsaddr_list[nserv], res->ai_addr,
382 res->ai_addrlen);
383 } else {
384 memset(&_res_ext.nsaddr_list[nserv], 0,
385 sizeof(_res_ext.nsaddr_list[nserv]));
386 }
387 if (res->ai_addrlen <= sizeof(_res.nsaddr_list[nserv])) {
388 memcpy(&_res.nsaddr_list[nserv], res->ai_addr,
389 res->ai_addrlen);
390 } else {
391 memset(&_res.nsaddr_list[nserv], 0,
392 sizeof(_res.nsaddr_list[nserv]));
393 }
394 nserv++;
395 }
396#else /* INET6 */
344 if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) { 397 if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
345 _res.nsaddr_list[nserv].sin_addr = a; 398 _res.nsaddr_list[nserv].sin_addr = a;
346 _res.nsaddr_list[nserv].sin_family = AF_INET; 399 _res.nsaddr_list[nserv].sin_family = AF_INET;
347 _res.nsaddr_list[nserv].sin_port = 400 _res.nsaddr_list[nserv].sin_port =
348 htons(NAMESERVER_PORT); 401 htons(NAMESERVER_PORT);
402 _res.nsaddr_list[nserv].sin_len =
403 sizeof(struct sockaddr_in);
349 nserv++; 404 nserv++;
350 } 405 }
406#endif /* INET6 */
351 continue; 407 continue;
352 } 408 }
353#ifdef RESOLVSORT 409#ifdef RESOLVSORT
354 if (MATCH(buf, "sortlist")) { 410 if (MATCH(buf, "sortlist")) {
355 struct in_addr a; 411 struct in_addr a;
412#ifdef INET6
413 struct in6_addr a6;
414 int m, i;
415 u_char *u;
416#endif /* INET6 */
356 417
357 cp = buf + sizeof("sortlist") - 1; 418 cp = buf + sizeof("sortlist") - 1;
358 while (nsort < MAXRESOLVSORT) { 419 while (nsort < MAXRESOLVSORT) {
@@ -386,8 +447,58 @@ res_init()
386 _res.sort_list[nsort].mask = 447 _res.sort_list[nsort].mask =
387 net_mask(_res.sort_list[nsort].addr); 448 net_mask(_res.sort_list[nsort].addr);
388 } 449 }
450#ifdef INET6
451 _res_ext.sort_list[nsort].af = AF_INET;
452 _res_ext.sort_list[nsort].addr.ina =
453 _res.sort_list[nsort].addr;
454 _res_ext.sort_list[nsort].mask.ina.s_addr =
455 _res.sort_list[nsort].mask;
456#endif /* INET6 */
457 nsort++;
458 }
459#ifdef INET6
460 else if (inet_pton(AF_INET6, net, &a6) == 1) {
461 _res_ext.sort_list[nsort].af = AF_INET6;
462 _res_ext.sort_list[nsort].addr.in6a = a6;
463 u = (u_char *)&_res_ext.sort_list[nsort].mask.in6a;
464 *cp++ = n;
465 net = cp;
466 while (*cp && *cp != ';' &&
467 isascii(*cp) && !isspace(*cp))
468 cp++;
469 m = n;
470 n = *cp;
471 *cp = 0;
472 switch (m) {
473 case '/':
474 m = atoi(net);
475 break;
476 case '&':
477 if (inet_pton(AF_INET6, net, u) == 1) {
478 m = -1;
479 break;
480 }
481 /*FALLTHRU*/
482 default:
483 m = sizeof(struct in6_addr) * NBBY;
484 break;
485 }
486 if (m >= 0) {
487 for (i = 0; i < sizeof(struct in6_addr); i++) {
488 if (m <= 0) {
489 *u = 0;
490 } else {
491 m -= NBBY;
492 *u = (u_char)~0;
493 if (m < 0)
494 *u <<= -m;
495 }
496 u++;
497 }
498 }
389 nsort++; 499 nsort++;
390 } 500 }
501#endif /* INET6 */
391 *cp = n; 502 *cp = n;
392 } 503 }
393 continue; 504 continue;
diff --git a/src/lib/libc/net/res_send.c b/src/lib/libc/net/res_send.c
index 0cda3510eb..d0f17af8ed 100644
--- a/src/lib/libc/net/res_send.c
+++ b/src/lib/libc/net/res_send.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: res_send.c,v 1.8 1998/03/19 00:30:08 millert Exp $ */ 1/* $OpenBSD: res_send.c,v 1.9 2000/06/22 07:31:18 itojun Exp $ */
2 2
3/* 3/*
4 * ++Copyright++ 1985, 1989, 1993 4 * ++Copyright++ 1985, 1989, 1993
@@ -55,12 +55,16 @@
55 * --Copyright-- 55 * --Copyright--
56 */ 56 */
57 57
58#ifndef INET6
59#define INET6
60#endif
61
58#if defined(LIBC_SCCS) && !defined(lint) 62#if defined(LIBC_SCCS) && !defined(lint)
59#if 0 63#if 0
60static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; 64static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_send.c,v 8.12 1996/10/08 04:51:06 vixie Exp $"; 65static char rcsid[] = "$From: res_send.c,v 8.12 1996/10/08 04:51:06 vixie Exp $";
62#else 66#else
63static char rcsid[] = "$OpenBSD: res_send.c,v 1.8 1998/03/19 00:30:08 millert Exp $"; 67static char rcsid[] = "$OpenBSD: res_send.c,v 1.9 2000/06/22 07:31:18 itojun Exp $";
64#endif 68#endif
65#endif /* LIBC_SCCS and not lint */ 69#endif /* LIBC_SCCS and not lint */
66 70
@@ -95,6 +99,7 @@ static char rcsid[] = "$OpenBSD: res_send.c,v 1.8 1998/03/19 00:30:08 millert Ex
95static int s = -1; /* socket used for communications */ 99static int s = -1; /* socket used for communications */
96static int connected = 0; /* is the socket connected */ 100static int connected = 0; /* is the socket connected */
97static int vc = 0; /* is the socket a virtual ciruit? */ 101static int vc = 0; /* is the socket a virtual ciruit? */
102static int af = 0; /* address family of socket */
98 103
99#ifndef FD_SET 104#ifndef FD_SET
100/* XXX - should be in portability.h */ 105/* XXX - should be in portability.h */
@@ -119,21 +124,29 @@ static int vc = 0; /* is the socket a virtual ciruit? */
119 fprintf args;\ 124 fprintf args;\
120 __fp_nquery(query, size, stdout);\ 125 __fp_nquery(query, size, stdout);\
121 } else {} 126 } else {}
127static char abuf[NI_MAXHOST];
128static char pbuf[NI_MAXSERV];
129static void Aerror __P((FILE *, char *, int, struct sockaddr *));
130static void Perror __P((FILE *, char *, int));
131
122 static void 132 static void
123 Aerror(file, string, error, address) 133 Aerror(file, string, error, address)
124 FILE *file; 134 FILE *file;
125 char *string; 135 char *string;
126 int error; 136 int error;
127 struct sockaddr_in address; 137 struct sockaddr *address;
128 { 138 {
129 int save = errno; 139 int save = errno;
130 140
131 if (_res.options & RES_DEBUG) { 141 if (_res.options & RES_DEBUG) {
132 fprintf(file, "res_send: %s ([%s].%u): %s\n", 142 if (getnameinfo(address, address->sa_len, abuf, sizeof(abuf),
133 string, 143 pbuf, sizeof(pbuf),
134 inet_ntoa(address.sin_addr), 144 NI_NUMERICHOST|NI_NUMERICSERV|NI_WITHSCOPEID) != 0) {
135 ntohs(address.sin_port), 145 strncpy(abuf, "?", sizeof(abuf));
136 strerror(error)); 146 strncpy(pbuf, "?", sizeof(pbuf));
147 }
148 fprintf(file, "res_send: %s ([%s].%s): %s\n",
149 string, abuf, pbuf, strerror(error));
137 } 150 }
138 errno = save; 151 errno = save;
139 } 152 }
@@ -172,6 +185,37 @@ res_send_setrhook(hook)
172 Rhook = hook; 185 Rhook = hook;
173} 186}
174 187
188#ifdef INET6
189static struct sockaddr * get_nsaddr __P((size_t));
190
191/*
192 * pick appropriate nsaddr_list for use. see res_init() for initialization.
193 */
194static struct sockaddr *
195get_nsaddr(n)
196 size_t n;
197{
198
199 if (!_res.nsaddr_list[n].sin_family) {
200 /*
201 * - _res_ext.nsaddr_list[n] holds an address that is larger
202 * than struct sockaddr, and
203 * - user code did not update _res.nsaddr_list[n].
204 */
205 return (struct sockaddr *)&_res_ext.nsaddr_list[n];
206 } else {
207 /*
208 * - user code updated _res.nsaddr_list[n], or
209 * - _res.nsaddr_list[n] has the same content as
210 * _res_ext.nsaddr_list[n].
211 */
212 return (struct sockaddr *)&_res.nsaddr_list[n];
213 }
214}
215#else
216#define get_nsaddr(n) ((struct sockaddr *)&_res.nsaddr_list[(n)])
217#endif
218
175/* int 219/* int
176 * res_isourserver(ina) 220 * res_isourserver(ina)
177 * looks up "ina" in _res.ns_addr_list[] 221 * looks up "ina" in _res.ns_addr_list[]
@@ -185,21 +229,43 @@ int
185res_isourserver(inp) 229res_isourserver(inp)
186 const struct sockaddr_in *inp; 230 const struct sockaddr_in *inp;
187{ 231{
188 struct sockaddr_in ina; 232#ifdef INET6
189 register int ns, ret; 233 const struct sockaddr_in6 *in6p = (const struct sockaddr_in6 *)inp;
234 const struct sockaddr_in6 *srv6;
235#endif
236 const struct sockaddr_in *srv;
237 int ns, ret;
190 238
191 ina = *inp;
192 ret = 0; 239 ret = 0;
193 for (ns = 0; ns < _res.nscount; ns++) { 240 switch (inp->sin_family) {
194 register const struct sockaddr_in *srv = &_res.nsaddr_list[ns]; 241#ifdef INET6
195 242 case AF_INET6:
196 if (srv->sin_family == ina.sin_family && 243 for (ns = 0; ns < _res.nscount; ns++) {
197 srv->sin_port == ina.sin_port && 244 srv6 = (struct sockaddr_in6 *)get_nsaddr(ns);
198 (srv->sin_addr.s_addr == INADDR_ANY || 245 if (srv6->sin6_family == in6p->sin6_family &&
199 srv->sin_addr.s_addr == ina.sin_addr.s_addr)) { 246 srv6->sin6_port == in6p->sin6_port &&
200 ret++; 247 srv6->sin6_scope_id == in6p->sin6_scope_id &&
201 break; 248 (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
249 IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr,
250 &in6p->sin6_addr))) {
251 ret++;
252 break;
253 }
254 }
255 break;
256#endif
257 case AF_INET:
258 for (ns = 0; ns < _res.nscount; ns++) {
259 srv = (struct sockaddr_in *)get_nsaddr(ns);
260 if (srv->sin_family == inp->sin_family &&
261 srv->sin_port == inp->sin_port &&
262 (srv->sin_addr.s_addr == INADDR_ANY ||
263 srv->sin_addr.s_addr == inp->sin_addr.s_addr)) {
264 ret++;
265 break;
266 }
202 } 267 }
268 break;
203 } 269 }
204 return (ret); 270 return (ret);
205} 271}
@@ -308,7 +374,20 @@ res_send(buf, buflen, ans, anssiz)
308 */ 374 */
309 for (try = 0; try < _res.retry; try++) { 375 for (try = 0; try < _res.retry; try++) {
310 for (ns = 0; ns < _res.nscount; ns++) { 376 for (ns = 0; ns < _res.nscount; ns++) {
311 struct sockaddr_in *nsap = &_res.nsaddr_list[ns]; 377 struct sockaddr *nsap = get_nsaddr(ns);
378 socklen_t salen;
379
380 if (nsap->sa_len)
381 salen = nsap->sa_len;
382#ifdef INET6
383 else if (nsap->sa_family == AF_INET6)
384 salen = sizeof(struct sockaddr_in6);
385#endif
386 else if (nsap->sa_family == AF_INET)
387 salen = sizeof(struct sockaddr_in);
388 else
389 salen = 0; /*unknown, die on connect*/
390
312 same_ns: 391 same_ns:
313 if (badns & (1 << ns)) { 392 if (badns & (1 << ns)) {
314 res_close(); 393 res_close();
@@ -321,7 +400,8 @@ res_send(buf, buflen, ans, anssiz)
321 do { 400 do {
322 res_sendhookact act; 401 res_sendhookact act;
323 402
324 act = (*Qhook)(&nsap, &buf, &buflen, 403 act = (*Qhook)((struct sockaddr_in **)&nsap,
404 &buf, &buflen,
325 ans, anssiz, &resplen); 405 ans, anssiz, &resplen);
326 switch (act) { 406 switch (act) {
327 case res_goahead: 407 case res_goahead:
@@ -345,9 +425,11 @@ res_send(buf, buflen, ans, anssiz)
345 } while (!done); 425 } while (!done);
346 } 426 }
347 427
348 Dprint(_res.options & RES_DEBUG, 428 Dprint((_res.options & RES_DEBUG) &&
429 getnameinfo(nsap, salen, abuf, sizeof(abuf),
430 NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID) == 0,
349 (stdout, ";; Querying server (# %d) address = %s\n", 431 (stdout, ";; Querying server (# %d) address = %s\n",
350 ns + 1, inet_ntoa(nsap->sin_addr))); 432 ns + 1, abuf));
351 433
352 if (v_circuit) { 434 if (v_circuit) {
353 int truncated; 435 int truncated;
@@ -361,22 +443,28 @@ res_send(buf, buflen, ans, anssiz)
361 */ 443 */
362 try = _res.retry; 444 try = _res.retry;
363 truncated = 0; 445 truncated = 0;
364 if ((s < 0) || (!vc)) { 446 if ((s < 0) || (!vc) || (af != nsap->sa_family)) {
365 if (s >= 0) 447 if (s >= 0)
366 res_close(); 448 res_close();
367 449
368 s = socket(PF_INET, SOCK_STREAM, 0); 450 af = nsap->sa_family;
451 s = socket(af, SOCK_STREAM, 0);
369 if (s < 0) { 452 if (s < 0) {
370 terrno = errno; 453 terrno = errno;
371 Perror(stderr, "socket(vc)", errno); 454 Perror(stderr, "socket(vc)", errno);
455#if 0
372 return (-1); 456 return (-1);
457#else
458 badns |= (1 << ns);
459 res_close();
460 goto next_ns;
461#endif
373 } 462 }
374 errno = 0; 463 errno = 0;
375 if (connect(s, (struct sockaddr *)nsap, 464 if (connect(s, nsap, salen) < 0) {
376 sizeof(struct sockaddr)) < 0) {
377 terrno = errno; 465 terrno = errno;
378 Aerror(stderr, "connect/vc", 466 Aerror(stderr, "connect/vc",
379 errno, *nsap); 467 errno, nsap);
380 badns |= (1 << ns); 468 badns |= (1 << ns);
381 res_close(); 469 res_close();
382 goto next_ns; 470 goto next_ns;
@@ -490,21 +578,36 @@ read_len:
490 */ 578 */
491 struct timeval timeout; 579 struct timeval timeout;
492 fd_set *dsmaskp; 580 fd_set *dsmaskp;
493 struct sockaddr_in from; 581 struct sockaddr_storage from;
494 int fromlen; 582 int fromlen;
495 583
496 if ((s < 0) || vc) { 584 if ((s < 0) || vc || (af != nsap->sa_family)) {
497 if (vc) 585 if (vc)
498 res_close(); 586 res_close();
499 s = socket(PF_INET, SOCK_DGRAM, 0); 587 af = nsap->sa_family;
588 s = socket(af, SOCK_DGRAM, 0);
500 if (s < 0) { 589 if (s < 0) {
501#if !CAN_RECONNECT 590#if !CAN_RECONNECT
502 bad_dg_sock: 591 bad_dg_sock:
503#endif 592#endif
504 terrno = errno; 593 terrno = errno;
505 Perror(stderr, "socket(dg)", errno); 594 Perror(stderr, "socket(dg)", errno);
595#if 0
506 return (-1); 596 return (-1);
597#else
598 badns |= (1 << ns);
599 res_close();
600 goto next_ns;
601#endif
602 }
603#ifdef IPV6_MINMTU
604 if (af == AF_INET6) {
605 const int yes = 1;
606 (void)setsockopt(s, IPPROTO_IPV6,
607 IPV6_USE_MIN_MTU, &yes,
608 sizeof(yes));
507 } 609 }
610#endif
508 connected = 0; 611 connected = 0;
509 } 612 }
510 /* 613 /*
@@ -528,12 +631,10 @@ read_len:
528 * receive a response from another server. 631 * receive a response from another server.
529 */ 632 */
530 if (!connected) { 633 if (!connected) {
531 if (connect(s, (struct sockaddr *)nsap, 634 if (connect(s, nsap, salen) < 0) {
532 sizeof(struct sockaddr)
533 ) < 0) {
534 Aerror(stderr, 635 Aerror(stderr,
535 "connect(dg)", 636 "connect(dg)",
536 errno, *nsap); 637 errno, nsap);
537 badns |= (1 << ns); 638 badns |= (1 << ns);
538 res_close(); 639 res_close();
539 goto next_ns; 640 goto next_ns;
@@ -553,6 +654,9 @@ read_len:
553 */ 654 */
554 if (connected) { 655 if (connected) {
555#if CAN_RECONNECT 656#if CAN_RECONNECT
657#ifdef INET6
658 /* XXX: any errornous address */
659#endif /* INET6 */
556 struct sockaddr_in no_addr; 660 struct sockaddr_in no_addr;
557 661
558 no_addr.sin_family = AF_INET; 662 no_addr.sin_family = AF_INET;
@@ -563,7 +667,7 @@ read_len:
563 &no_addr, 667 &no_addr,
564 sizeof(no_addr)); 668 sizeof(no_addr));
565#else 669#else
566 int s1 = socket(PF_INET, SOCK_DGRAM,0); 670 int s1 = socket(af, SOCK_DGRAM,0);
567 if (s1 < 0) 671 if (s1 < 0)
568 goto bad_dg_sock; 672 goto bad_dg_sock;
569 (void) dup2(s1, s); 673 (void) dup2(s1, s);
@@ -571,14 +675,20 @@ read_len:
571 Dprint(_res.options & RES_DEBUG, 675 Dprint(_res.options & RES_DEBUG,
572 (stdout, ";; new DG socket\n")) 676 (stdout, ";; new DG socket\n"))
573#endif 677#endif
678#ifdef IPV6_MINMTU
679 if (af == AF_INET6) {
680 const int yes = 1;
681 (void)setsockopt(s, IPPROTO_IPV6,
682 IPV6_USE_MIN_MTU, &yes,
683 sizeof(yes));
684 }
685#endif
574 connected = 0; 686 connected = 0;
575 errno = 0; 687 errno = 0;
576 } 688 }
577 if (sendto(s, (char*)buf, buflen, 0, 689 if (sendto(s, (char*)buf, buflen, 0,
578 (struct sockaddr *)nsap, 690 nsap, salen) != buflen) {
579 sizeof(struct sockaddr)) 691 Aerror(stderr, "sendto", errno, nsap);
580 != buflen) {
581 Aerror(stderr, "sendto", errno, *nsap);
582 badns |= (1 << ns); 692 badns |= (1 << ns);
583 res_close(); 693 res_close();
584 goto next_ns; 694 goto next_ns;
@@ -623,7 +733,7 @@ read_len:
623 goto next_ns; 733 goto next_ns;
624 } 734 }
625 errno = 0; 735 errno = 0;
626 fromlen = sizeof(struct sockaddr_in); 736 fromlen = sizeof(from);
627 resplen = recvfrom(s, (char*)ans, anssiz, 0, 737 resplen = recvfrom(s, (char*)ans, anssiz, 0,
628 (struct sockaddr *)&from, &fromlen); 738 (struct sockaddr *)&from, &fromlen);
629 if (resplen <= 0) { 739 if (resplen <= 0) {
@@ -646,7 +756,7 @@ read_len:
646 } 756 }
647#if CHECK_SRVR_ADDR 757#if CHECK_SRVR_ADDR
648 if (!(_res.options & RES_INSECURE1) && 758 if (!(_res.options & RES_INSECURE1) &&
649 !res_isourserver(&from)) { 759 !res_isourserver((struct sockaddr_in *)&from)) {
650 /* 760 /*
651 * response from wrong server? ignore it. 761 * response from wrong server? ignore it.
652 * XXX - potential security hazard could 762 * XXX - potential security hazard could
@@ -703,7 +813,7 @@ read_len:
703 (stdout, ";; got answer:\n")); 813 (stdout, ";; got answer:\n"));
704 DprintQ((_res.options & RES_DEBUG) || 814 DprintQ((_res.options & RES_DEBUG) ||
705 (_res.pfcode & RES_PRF_REPLY), 815 (_res.pfcode & RES_PRF_REPLY),
706 (stdout, ""), 816 (stdout, "%s", ""),
707 ans, (resplen>anssiz)?anssiz:resplen); 817 ans, (resplen>anssiz)?anssiz:resplen);
708 /* 818 /*
709 * If using virtual circuits, we assume that the first server 819 * If using virtual circuits, we assume that the first server
@@ -723,7 +833,8 @@ read_len:
723 do { 833 do {
724 res_sendhookact act; 834 res_sendhookact act;
725 835
726 act = (*Rhook)(nsap, buf, buflen, 836 act = (*Rhook)((struct sockaddr_in *)nsap,
837 buf, buflen,
727 ans, anssiz, &resplen); 838 ans, anssiz, &resplen);
728 switch (act) { 839 switch (act) {
729 case res_goahead: 840 case res_goahead:
@@ -776,5 +887,6 @@ res_close()
776 s = -1; 887 s = -1;
777 connected = 0; 888 connected = 0;
778 vc = 0; 889 vc = 0;
890 af = 0;
779 } 891 }
780} 892}