| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: getaddrinfo.c,v 1.115 2017/01/10 17:51:01 christos Exp $ */ | | 1 | /* $NetBSD: getaddrinfo.c,v 1.115.6.1 2017/10/25 06:56:41 snj Exp $ */ |
2 | /* $KAME: getaddrinfo.c,v 1.29 2000/08/31 17:26:57 itojun Exp $ */ | | 2 | /* $KAME: getaddrinfo.c,v 1.29 2000/08/31 17:26:57 itojun Exp $ */ |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | | 5 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -45,27 +45,27 @@ | | | @@ -45,27 +45,27 @@ |
45 | * Note: | | 45 | * Note: |
46 | * - The code filters out AFs that are not supported by the kernel, | | 46 | * - The code filters out AFs that are not supported by the kernel, |
47 | * when globbing NULL hostname (to loopback, or wildcard). Is it the right | | 47 | * when globbing NULL hostname (to loopback, or wildcard). Is it the right |
48 | * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG | | 48 | * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG |
49 | * in ai_flags? | | 49 | * in ai_flags? |
50 | * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague. | | 50 | * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague. |
51 | * (1) what should we do against numeric hostname (2) what should we do | | 51 | * (1) what should we do against numeric hostname (2) what should we do |
52 | * against NULL hostname (3) what is AI_ADDRCONFIG itself. AF not ready? | | 52 | * against NULL hostname (3) what is AI_ADDRCONFIG itself. AF not ready? |
53 | * non-loopback address configured? global address configured? | | 53 | * non-loopback address configured? global address configured? |
54 | */ | | 54 | */ |
55 | | | 55 | |
56 | #include <sys/cdefs.h> | | 56 | #include <sys/cdefs.h> |
57 | #if defined(LIBC_SCCS) && !defined(lint) | | 57 | #if defined(LIBC_SCCS) && !defined(lint) |
58 | __RCSID("$NetBSD: getaddrinfo.c,v 1.115 2017/01/10 17:51:01 christos Exp $"); | | 58 | __RCSID("$NetBSD: getaddrinfo.c,v 1.115.6.1 2017/10/25 06:56:41 snj Exp $"); |
59 | #endif /* LIBC_SCCS and not lint */ | | 59 | #endif /* LIBC_SCCS and not lint */ |
60 | | | 60 | |
61 | #ifndef RUMP_ACTION | | 61 | #ifndef RUMP_ACTION |
62 | #include "namespace.h" | | 62 | #include "namespace.h" |
63 | #endif | | 63 | #endif |
64 | #include <sys/types.h> | | 64 | #include <sys/types.h> |
65 | #include <sys/param.h> | | 65 | #include <sys/param.h> |
66 | #include <sys/socket.h> | | 66 | #include <sys/socket.h> |
67 | #include <sys/ioctl.h> | | 67 | #include <sys/ioctl.h> |
68 | #include <sys/sysctl.h> | | 68 | #include <sys/sysctl.h> |
69 | #include <net/if.h> | | 69 | #include <net/if.h> |
70 | #include <netinet/in.h> | | 70 | #include <netinet/in.h> |
71 | #include <netinet6/in6_var.h> | | 71 | #include <netinet6/in6_var.h> |
| @@ -2529,91 +2529,117 @@ _yp_getaddrinfo(void *rv, void *cb_data, | | | @@ -2529,91 +2529,117 @@ _yp_getaddrinfo(void *rv, void *cb_data, |
2529 | | | 2529 | |
2530 | /* | | 2530 | /* |
2531 | * Formulate a normal query, send, and await answer. | | 2531 | * Formulate a normal query, send, and await answer. |
2532 | * Returned answer is placed in supplied buffer "answer". | | 2532 | * Returned answer is placed in supplied buffer "answer". |
2533 | * Perform preliminary check of answer, returning success only | | 2533 | * Perform preliminary check of answer, returning success only |
2534 | * if no error is indicated and the answer count is nonzero. | | 2534 | * if no error is indicated and the answer count is nonzero. |
2535 | * Return the size of the response on success, -1 on error. | | 2535 | * Return the size of the response on success, -1 on error. |
2536 | * Error number is left in h_errno. | | 2536 | * Error number is left in h_errno. |
2537 | * | | 2537 | * |
2538 | * Caller must parse answer and determine whether it answers the question. | | 2538 | * Caller must parse answer and determine whether it answers the question. |
2539 | */ | | 2539 | */ |
2540 | static int | | 2540 | static int |
2541 | res_queryN(const char *name, /* domain name */ struct res_target *target, | | 2541 | res_queryN(const char *name, /* domain name */ struct res_target *target, |
2542 | res_state res) | | 2542 | res_state statp) |
2543 | { | | 2543 | { |
2544 | u_char buf[MAXPACKET]; | | 2544 | u_char buf[MAXPACKET]; |
2545 | HEADER *hp; | | 2545 | HEADER *hp; |
2546 | int n; | | 2546 | int n; |
2547 | struct res_target *t; | | 2547 | struct res_target *t; |
2548 | int rcode; | | 2548 | int rcode; |
| | | 2549 | u_char *rdata; |
2549 | int ancount; | | 2550 | int ancount; |
2550 | | | 2551 | |
2551 | _DIAGASSERT(name != NULL); | | 2552 | _DIAGASSERT(name != NULL); |
2552 | /* XXX: target may be NULL??? */ | | 2553 | /* XXX: target may be NULL??? */ |
2553 | | | 2554 | |
2554 | rcode = NOERROR; | | 2555 | rcode = NOERROR; |
2555 | ancount = 0; | | 2556 | ancount = 0; |
2556 | | | 2557 | |
2557 | for (t = target; t; t = t->next) { | | 2558 | for (t = target; t; t = t->next) { |
2558 | int class, type; | | 2559 | int class, type; |
2559 | u_char *answer; | | 2560 | u_char *answer; |
2560 | int anslen; | | 2561 | int anslen; |
| | | 2562 | u_int oflags; |
2561 | | | 2563 | |
2562 | hp = (HEADER *)(void *)t->answer; | | 2564 | hp = (HEADER *)(void *)t->answer; |
| | | 2565 | oflags = statp->_flags; |
| | | 2566 | |
| | | 2567 | again: |
2563 | hp->rcode = NOERROR; /* default */ | | 2568 | hp->rcode = NOERROR; /* default */ |
2564 | | | 2569 | |
2565 | /* make it easier... */ | | 2570 | /* make it easier... */ |
2566 | class = t->qclass; | | 2571 | class = t->qclass; |
2567 | type = t->qtype; | | 2572 | type = t->qtype; |
2568 | answer = t->answer; | | 2573 | answer = t->answer; |
2569 | anslen = t->anslen; | | 2574 | anslen = t->anslen; |
2570 | #ifdef DEBUG | | 2575 | #ifdef DEBUG |
2571 | if (res->options & RES_DEBUG) | | 2576 | if (statp->options & RES_DEBUG) |
2572 | printf(";; res_nquery(%s, %d, %d)\n", name, class, type); | | 2577 | printf(";; res_nquery(%s, %d, %d)\n", name, class, type); |
2573 | #endif | | 2578 | #endif |
2574 | | | 2579 | |
2575 | n = res_nmkquery(res, QUERY, name, class, type, NULL, 0, NULL, | | 2580 | n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL, |
2576 | buf, (int)sizeof(buf)); | | 2581 | buf, (int)sizeof(buf)); |
2577 | #ifdef RES_USE_EDNS0 | | 2582 | #ifdef RES_USE_EDNS0 |
2578 | if (n > 0 && (res->options & RES_USE_EDNS0) != 0) | | 2583 | if (n > 0 && (statp->_flags & RES_F_EDNS0ERR) == 0 && |
2579 | n = res_nopt(res, n, buf, (int)sizeof(buf), anslen); | | 2584 | (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) { |
| | | 2585 | n = res_nopt(statp, n, buf, (int)sizeof(buf), anslen); |
| | | 2586 | rdata = &buf[n]; |
| | | 2587 | if (n > 0 && (statp->options & RES_NSID) != 0U) { |
| | | 2588 | n = res_nopt_rdata(statp, n, buf, |
| | | 2589 | (int)sizeof(buf), |
| | | 2590 | rdata, NS_OPT_NSID, 0, NULL); |
| | | 2591 | } |
| | | 2592 | } |
2580 | #endif | | 2593 | #endif |
2581 | if (n <= 0) { | | 2594 | if (n <= 0) { |
2582 | #ifdef DEBUG | | 2595 | #ifdef DEBUG |
2583 | if (res->options & RES_DEBUG) | | 2596 | if (statp->options & RES_DEBUG) |
2584 | printf(";; res_nquery: mkquery failed\n"); | | 2597 | printf(";; res_nquery: mkquery failed\n"); |
2585 | #endif | | 2598 | #endif |
2586 | h_errno = NO_RECOVERY; | | 2599 | h_errno = NO_RECOVERY; |
2587 | return n; | | 2600 | return n; |
2588 | } | | 2601 | } |
2589 | n = res_nsend(res, buf, n, answer, anslen); | | 2602 | n = res_nsend(statp, buf, n, answer, anslen); |
2590 | #if 0 | | | |
2591 | if (n < 0) { | | 2603 | if (n < 0) { |
| | | 2604 | #ifdef RES_USE_EDNS0 |
| | | 2605 | /* if the query choked with EDNS0, retry without EDNS0 */ |
| | | 2606 | if ((statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0U && |
| | | 2607 | ((oflags ^ statp->_flags) & RES_F_EDNS0ERR) != 0) { |
| | | 2608 | statp->_flags |= RES_F_EDNS0ERR; |
| | | 2609 | if (statp->options & RES_DEBUG) |
| | | 2610 | printf(";; res_nquery: retry without EDNS0\n"); |
| | | 2611 | goto again; |
| | | 2612 | } |
| | | 2613 | #endif |
| | | 2614 | #if 0 |
2592 | #ifdef DEBUG | | 2615 | #ifdef DEBUG |
2593 | if (res->options & RES_DEBUG) | | 2616 | if (statp->options & RES_DEBUG) |
2594 | printf(";; res_query: send error\n"); | | 2617 | printf(";; res_query: send error\n"); |
2595 | #endif | | 2618 | #endif |
2596 | h_errno = TRY_AGAIN; | | 2619 | h_errno = TRY_AGAIN; |
2597 | return n; | | 2620 | return n; |
2598 | } | | | |
2599 | #endif | | 2621 | #endif |
| | | 2622 | } |
2600 | | | 2623 | |
2601 | if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { | | 2624 | if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { |
2602 | rcode = hp->rcode; /* record most recent error */ | | 2625 | rcode = hp->rcode; /* record most recent error */ |
2603 | #ifdef DEBUG | | 2626 | #ifdef DEBUG |
2604 | if (res->options & RES_DEBUG) | | 2627 | if (statp->options & RES_DEBUG) |
2605 | printf(";; rcode = %u, ancount=%u\n", hp->rcode, | | 2628 | printf(";; rcode = (%s), counts = an:%d ns:%d ar:%d\n", |
2606 | ntohs(hp->ancount)); | | 2629 | p_rcode(hp->rcode), |
| | | 2630 | ntohs(hp->ancount), |
| | | 2631 | ntohs(hp->nscount), |
| | | 2632 | ntohs(hp->arcount)); |
2607 | #endif | | 2633 | #endif |
2608 | continue; | | 2634 | continue; |
2609 | } | | 2635 | } |
2610 | | | 2636 | |
2611 | ancount += ntohs(hp->ancount); | | 2637 | ancount += ntohs(hp->ancount); |
2612 | | | 2638 | |
2613 | t->n = n; | | 2639 | t->n = n; |
2614 | } | | 2640 | } |
2615 | | | 2641 | |
2616 | if (ancount == 0) { | | 2642 | if (ancount == 0) { |
2617 | switch (rcode) { | | 2643 | switch (rcode) { |
2618 | case NXDOMAIN: | | 2644 | case NXDOMAIN: |
2619 | h_errno = HOST_NOT_FOUND; | | 2645 | h_errno = HOST_NOT_FOUND; |