|
|
| 829 |
} |
829 |
} |
| 830 |
} |
830 |
} |
| 831 |
|
831 |
|
|
|
832 |
/* AI_ADDRCONFIG determines whether or not we should suppress any |
| 833 |
* hostname lookups. If the local host has only IPv4 interfaces, |
| 834 |
* then suppress lookups for IPv6 addresses, and vice versa; if |
| 835 |
* the local host has only IPv6 interfaces, suppress any lookups |
| 836 |
* for IPv4 addresses.. |
| 837 |
* |
| 838 |
* Link-local IPv6 addresses and loopback addresses of either |
| 839 |
* family are ignored when determining whether or not the host has |
| 840 |
* an interface of the given address family, cf. __check_pf(). |
| 841 |
* |
| 842 |
* This logic is only applied for AF_UNSPEC. If the caller |
| 843 |
* explicitly requested an address family, give him what he asked |
| 844 |
* for. |
| 845 |
* |
| 846 |
* If we didn't find any interfaces of either address family, |
| 847 |
* we ignore AI_ADDRCONFIG and return all available resutlts. */ |
| 848 |
int suppress_af = 0; |
| 849 |
if (req->ai_family == AF_UNSPEC && req->ai_flags & AI_ADDRCONFIG) |
| 850 |
{ |
| 851 |
struct in6addrinfo *in6ai = NULL; |
| 852 |
size_t in6ailen = 0; |
| 853 |
bool seen_ipv4 = false; |
| 854 |
bool seen_ipv6 = false; |
| 855 |
__check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen); |
| 856 |
__free_in6ai (in6ai); |
| 857 |
|
| 858 |
if(seen_ipv4 && !seen_ipv6) |
| 859 |
suppress_af = AF_INET6; |
| 860 |
else if(seen_ipv6 && !seen_ipv4) |
| 861 |
suppress_af = AF_INET; |
| 862 |
} |
| 863 |
|
| 832 |
while (!no_more) |
864 |
while (!no_more) |
| 833 |
{ |
865 |
{ |
| 834 |
no_data = 0; |
866 |
no_data = 0; |
| 835 |
nss_gethostbyname4_r fct4 = NULL; |
867 |
nss_gethostbyname4_r fct4 = NULL; |
| 836 |
|
868 |
|
| 837 |
/* gethostbyname4_r sends out parallel A and AAAA queries and |
869 |
/* gethostbyname4_r sends out parallel A and AAAA queries and |
| 838 |
is thus only suitable for PF_UNSPEC. */ |
870 |
is thus only suitable for PF_UNSPEC, and only if we're not |
| 839 |
if (req->ai_family == PF_UNSPEC) |
871 |
suppressing lookups for IPv4 or IPv6 addresses. */ |
|
|
872 |
if (req->ai_family == PF_UNSPEC && !suppress_af) |
| 840 |
fct4 = __nss_lookup_function (nip, "gethostbyname4_r"); |
873 |
fct4 = __nss_lookup_function (nip, "gethostbyname4_r"); |
| 841 |
|
874 |
|
| 842 |
if (fct4 != NULL) |
875 |
if (fct4 != NULL) |
|
|
| 941 |
|
974 |
|
| 942 |
if (fct != NULL) |
975 |
if (fct != NULL) |
| 943 |
{ |
976 |
{ |
| 944 |
if (req->ai_family == AF_INET6 |
977 |
if ((req->ai_family == AF_INET6 |
| 945 |
|| req->ai_family == AF_UNSPEC) |
978 |
|| req->ai_family == AF_UNSPEC) |
|
|
979 |
&& suppress_af != AF_INET6) |
| 946 |
{ |
980 |
{ |
| 947 |
gethosts (AF_INET6, struct in6_addr); |
981 |
gethosts (AF_INET6, struct in6_addr); |
| 948 |
no_inet6_data = no_data; |
982 |
no_inet6_data = no_data; |
| 949 |
inet6_status = status; |
983 |
inet6_status = status; |
| 950 |
} |
984 |
} |
| 951 |
if (req->ai_family == AF_INET |
985 |
if ((req->ai_family == AF_INET |
| 952 |
|| req->ai_family == AF_UNSPEC |
986 |
|| req->ai_family == AF_UNSPEC |
| 953 |
|| (req->ai_family == AF_INET6 |
987 |
|| (req->ai_family == AF_INET6 |
| 954 |
&& (req->ai_flags & AI_V4MAPPED) |
988 |
&& (req->ai_flags & AI_V4MAPPED) |
| 955 |
/* Avoid generating the mapped addresses if we |
989 |
/* Avoid generating the mapped addresses if we |
| 956 |
know we are not going to need them. */ |
990 |
know we are not going to need them. */ |
| 957 |
&& ((req->ai_flags & AI_ALL) || !got_ipv6))) |
991 |
&& ((req->ai_flags & AI_ALL) || !got_ipv6))) |
|
|
992 |
&& suppress_af != AF_INET) |
| 958 |
{ |
993 |
{ |
| 959 |
gethosts (AF_INET, struct in_addr); |
994 |
gethosts (AF_INET, struct in_addr); |
| 960 |
|
995 |
|
|
|
| 2373 |
int nresults = 0; |
2408 |
int nresults = 0; |
| 2374 |
struct addrinfo *p = NULL; |
2409 |
struct addrinfo *p = NULL; |
| 2375 |
struct gaih_service gaih_service, *pservice; |
2410 |
struct gaih_service gaih_service, *pservice; |
| 2376 |
struct addrinfo local_hints; |
|
|
| 2377 |
|
2411 |
|
| 2378 |
if (name != NULL && name[0] == '*' && name[1] == 0) |
2412 |
if (name != NULL && name[0] == '*' && name[1] == 0) |
| 2379 |
name = NULL; |
2413 |
name = NULL; |
|
|
| 2399 |
if ((hints->ai_flags & AI_CANONNAME) && name == NULL) |
2433 |
if ((hints->ai_flags & AI_CANONNAME) && name == NULL) |
| 2400 |
return EAI_BADFLAGS; |
2434 |
return EAI_BADFLAGS; |
| 2401 |
|
2435 |
|
| 2402 |
struct in6addrinfo *in6ai = NULL; |
|
|
| 2403 |
size_t in6ailen = 0; |
| 2404 |
bool seen_ipv4 = false; |
| 2405 |
bool seen_ipv6 = false; |
| 2406 |
bool check_pf_called = false; |
| 2407 |
|
| 2408 |
if (hints->ai_flags & AI_ADDRCONFIG) |
| 2409 |
{ |
| 2410 |
/* We might need information about what interfaces are available. |
| 2411 |
Also determine whether we have IPv4 or IPv6 interfaces or both. We |
| 2412 |
cannot cache the results since new interfaces could be added at |
| 2413 |
any time. */ |
| 2414 |
__check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen); |
| 2415 |
check_pf_called = true; |
| 2416 |
|
| 2417 |
/* Now make a decision on what we return, if anything. */ |
| 2418 |
if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6)) |
| 2419 |
{ |
| 2420 |
/* If we haven't seen both IPv4 and IPv6 interfaces we can |
| 2421 |
narrow down the search. */ |
| 2422 |
if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6)) |
| 2423 |
{ |
| 2424 |
local_hints = *hints; |
| 2425 |
local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6; |
| 2426 |
hints = &local_hints; |
| 2427 |
} |
| 2428 |
} |
| 2429 |
else if ((hints->ai_family == PF_INET && ! seen_ipv4) |
| 2430 |
|| (hints->ai_family == PF_INET6 && ! seen_ipv6)) |
| 2431 |
{ |
| 2432 |
/* We cannot possibly return a valid answer. */ |
| 2433 |
__free_in6ai (in6ai); |
| 2434 |
return EAI_NONAME; |
| 2435 |
} |
| 2436 |
} |
| 2437 |
|
| 2438 |
if (service && service[0]) |
2436 |
if (service && service[0]) |
| 2439 |
{ |
2437 |
{ |
| 2440 |
char *c; |
2438 |
char *c; |
|
|
| 2443 |
if (*c != '\0') |
2441 |
if (*c != '\0') |
| 2444 |
{ |
2442 |
{ |
| 2445 |
if (hints->ai_flags & AI_NUMERICSERV) |
2443 |
if (hints->ai_flags & AI_NUMERICSERV) |
| 2446 |
{ |
|
|
| 2447 |
__free_in6ai (in6ai); |
| 2448 |
return EAI_NONAME; |
2444 |
return EAI_NONAME; |
| 2449 |
} |
|
|
| 2450 |
|
2445 |
|
| 2451 |
gaih_service.num = -1; |
2446 |
gaih_service.num = -1; |
| 2452 |
} |
2447 |
} |
|
|
| 2466 |
if (last_i != 0) |
2461 |
if (last_i != 0) |
| 2467 |
{ |
2462 |
{ |
| 2468 |
freeaddrinfo (p); |
2463 |
freeaddrinfo (p); |
| 2469 |
__free_in6ai (in6ai); |
|
|
| 2470 |
|
2464 |
|
| 2471 |
return -(last_i & GAIH_EAI); |
2465 |
return -(last_i & GAIH_EAI); |
| 2472 |
} |
2466 |
} |
|
|
| 2477 |
} |
2471 |
} |
| 2478 |
} |
2472 |
} |
| 2479 |
else |
2473 |
else |
| 2480 |
{ |
|
|
| 2481 |
__free_in6ai (in6ai); |
| 2482 |
return EAI_FAMILY; |
2474 |
return EAI_FAMILY; |
| 2483 |
} |
|
|
| 2484 |
|
2475 |
|
| 2485 |
if (naddrs > 1) |
2476 |
if (naddrs > 1) |
| 2486 |
{ |
2477 |
{ |
|
|
| 2495 |
struct addrinfo *last = NULL; |
2486 |
struct addrinfo *last = NULL; |
| 2496 |
char *canonname = NULL; |
2487 |
char *canonname = NULL; |
| 2497 |
|
2488 |
|
| 2498 |
/* Now we definitely need the interface information. */ |
2489 |
/* Now we need the interface information. */ |
| 2499 |
if (! check_pf_called) |
2490 |
struct in6addrinfo *in6ai = NULL; |
| 2500 |
__check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen); |
2491 |
size_t in6ailen = 0; |
|
|
2492 |
bool seen_ipv4 = false; |
| 2493 |
bool seen_ipv6 = false; |
| 2494 |
__check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen); |
| 2501 |
|
2495 |
|
| 2502 |
/* If we have information about deprecated and temporary addresses |
2496 |
/* If we have information about deprecated and temporary addresses |
| 2503 |
sort the array now. */ |
2497 |
sort the array now. */ |
|
|
| 2664 |
|
2658 |
|
| 2665 |
/* Fill in the canonical name into the new first entry. */ |
2659 |
/* Fill in the canonical name into the new first entry. */ |
| 2666 |
p->ai_canonname = canonname; |
2660 |
p->ai_canonname = canonname; |
| 2667 |
} |
|
|
| 2668 |
|
2661 |
|
| 2669 |
__free_in6ai (in6ai); |
2662 |
__free_in6ai (in6ai); |
|
|
2663 |
} |
| 2670 |
|
2664 |
|
| 2671 |
if (p) |
2665 |
if (p) |
| 2672 |
{ |
2666 |
{ |