1 /* Host and service name lookups using Name Service Switch modules.
2 Copyright (C) 1996-2017 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 /* The Inner Net License, Version 2.00
21 The author(s) grant permission for redistribution and use in source and
22 binary forms, with or without modification, of the software and documentation
23 provided that the following conditions are met:
25 0. If you receive a version of the software that is specifically labelled
26 as not being for redistribution (check the version message and/or README),
27 you are not permitted to redistribute that version of the software in any
29 1. All terms of the all other applicable copyrights and licenses must be
31 2. Redistributions of source code must retain the authors' copyright
32 notice(s), this list of conditions, and the following disclaimer.
33 3. Redistributions in binary form must reproduce the authors' copyright
34 notice(s), this list of conditions, and the following disclaimer in the
35 documentation and/or other materials provided with the distribution.
36 4. [The copyright holder has authorized the removal of this clause.]
37 5. Neither the name(s) of the author(s) nor the names of its contributors
38 may be used to endorse or promote products derived from this software
39 without specific prior written permission.
41 THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS ``AS IS'' AND ANY
42 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44 DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
45 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
48 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 If these license terms cause you a real problem, contact the author. */
54 /* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */
62 #include <resolv/resolv-internal.h>
65 #include <stdio_ext.h>
69 #include <arpa/inet.h>
71 #include <netinet/in.h>
72 #include <sys/socket.h>
74 #include <sys/types.h>
76 #include <sys/utsname.h>
79 #include <libc-lock.h>
80 #include <not-cancel.h>
81 #include <nscd/nscd-client.h>
82 #include <nscd/nscd_proto.h>
83 #include <resolv/res_hconf.h>
84 #include <scratch_buffer.h>
85 #include <inet/net-internal.h>
88 extern int __idna_to_ascii_lz (const char *input
, char **output
, int flags
);
89 extern int __idna_to_unicode_lzlz (const char *input
, char **output
,
91 # include <libidn/idna.h>
100 struct gaih_servtuple
102 struct gaih_servtuple
*next
;
108 static const struct gaih_servtuple nullserv
;
111 struct gaih_typeproto
120 /* Values for `protoflag'. */
121 #define GAI_PROTO_NOSERVICE 1
122 #define GAI_PROTO_PROTOANY 2
124 static const struct gaih_typeproto gaih_inet_typeproto
[] =
126 { 0, 0, 0, false, "" },
127 { SOCK_STREAM
, IPPROTO_TCP
, 0, true, "tcp" },
128 { SOCK_DGRAM
, IPPROTO_UDP
, 0, true, "udp" },
129 #if defined SOCK_DCCP && defined IPPROTO_DCCP
130 { SOCK_DCCP
, IPPROTO_DCCP
, 0, false, "dccp" },
132 #ifdef IPPROTO_UDPLITE
133 { SOCK_DGRAM
, IPPROTO_UDPLITE
, 0, false, "udplite" },
136 { SOCK_STREAM
, IPPROTO_SCTP
, 0, false, "sctp" },
137 { SOCK_SEQPACKET
, IPPROTO_SCTP
, 0, false, "sctp" },
139 { SOCK_RAW
, 0, GAI_PROTO_PROTOANY
|GAI_PROTO_NOSERVICE
, true, "raw" },
140 { 0, 0, 0, false, "" }
143 static const struct addrinfo default_hints
=
145 .ai_flags
= AI_DEFAULT
,
146 .ai_family
= PF_UNSPEC
,
151 .ai_canonname
= NULL
,
157 gaih_inet_serv (const char *servicename
, const struct gaih_typeproto
*tp
,
158 const struct addrinfo
*req
, struct gaih_servtuple
*st
,
159 struct scratch_buffer
*tmpbuf
)
167 r
= __getservbyname_r (servicename
, tp
->name
, &ts
,
168 tmpbuf
->data
, tmpbuf
->length
, &s
);
169 if (r
!= 0 || s
== NULL
)
173 if (!scratch_buffer_grow (tmpbuf
))
183 st
->socktype
= tp
->socktype
;
184 st
->protocol
= ((tp
->protoflag
& GAI_PROTO_PROTOANY
)
185 ? req
->ai_protocol
: tp
->protocol
);
186 st
->port
= s
->s_port
;
191 /* Convert struct hostent to a list of struct gaih_addrtuple objects.
192 h_name is not copied, and the struct hostent object must not be
193 deallocated prematurely. *RESULT must be NULL or a pointer to an
194 object allocated using malloc, which is freed. */
196 convert_hostent_to_gaih_addrtuple (const struct addrinfo
*req
,
199 struct gaih_addrtuple
**result
)
204 /* Count the number of addresses in h->h_addr_list. */
206 for (char **p
= h
->h_addr_list
; *p
!= NULL
; ++p
)
209 /* Report no data if no addresses are available, or if the incoming
210 address size is larger than what we can store. */
211 if (count
== 0 || h
->h_length
> sizeof (((struct gaih_addrtuple
) {}).addr
))
214 struct gaih_addrtuple
*array
= calloc (count
, sizeof (*array
));
218 for (size_t i
= 0; i
< count
; ++i
)
220 if (family
== AF_INET
&& req
->ai_family
== AF_INET6
)
222 /* Perform address mapping. */
223 array
[i
].family
= AF_INET6
;
224 memcpy(array
[i
].addr
+ 3, h
->h_addr_list
[i
], sizeof (uint32_t));
225 array
[i
].addr
[2] = htonl (0xffff);
229 array
[i
].family
= family
;
230 memcpy (array
[i
].addr
, h
->h_addr_list
[i
], h
->h_length
);
232 array
[i
].next
= array
+ i
+ 1;
234 array
[0].name
= h
->h_name
;
235 array
[count
- 1].next
= NULL
;
241 #define gethosts(_family, _type) \
246 char *localcanon = NULL; \
250 status = DL_CALL_FCT (fct, (name, _family, &th, \
251 tmpbuf->data, tmpbuf->length, \
252 &rc, &herrno, NULL, &localcanon)); \
253 if (rc != ERANGE || herrno != NETDB_INTERNAL) \
255 if (!scratch_buffer_grow (tmpbuf)) \
257 result = -EAI_MEMORY; \
258 goto free_and_return; \
261 if (status == NSS_STATUS_SUCCESS && rc == 0) \
267 if (herrno == NETDB_INTERNAL) \
269 __set_h_errno (herrno); \
270 _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; \
271 result = -EAI_SYSTEM; \
272 goto free_and_return; \
274 if (herrno == TRY_AGAIN) \
275 no_data = EAI_AGAIN; \
277 no_data = herrno == NO_DATA; \
279 else if (h != NULL) \
281 if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \
283 _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; \
284 result = -EAI_SYSTEM; \
285 goto free_and_return; \
289 if (localcanon != NULL && canon == NULL) \
291 canonbuf = __strdup (localcanon); \
292 if (canonbuf == NULL) \
294 result = -EAI_SYSTEM; \
295 goto free_and_return; \
299 if (_family == AF_INET6 && *pat != NULL) \
305 typedef enum nss_status (*nss_gethostbyname4_r
)
306 (const char *name
, struct gaih_addrtuple
**pat
,
307 char *buffer
, size_t buflen
, int *errnop
,
308 int *h_errnop
, int32_t *ttlp
);
309 typedef enum nss_status (*nss_gethostbyname3_r
)
310 (const char *name
, int af
, struct hostent
*host
,
311 char *buffer
, size_t buflen
, int *errnop
,
312 int *h_errnop
, int32_t *ttlp
, char **canonp
);
313 typedef enum nss_status (*nss_getcanonname_r
)
314 (const char *name
, char *buffer
, size_t buflen
, char **result
,
315 int *errnop
, int *h_errnop
);
316 extern service_user
*__nss_hosts_database attribute_hidden
;
318 /* This function is called if a canonical name is requested, but if
319 the service function did not provide it. It tries to obtain the
320 name using getcanonname_r from the same service NIP. If the name
321 cannot be canonicalized, return a copy of NAME. Return NULL on
322 memory allocation failure. The returned string is allocated on the
323 heap; the caller has to free it. */
325 getcanonname (service_user
*nip
, struct gaih_addrtuple
*at
, const char *name
)
327 nss_getcanonname_r cfct
= __nss_lookup_function (nip
, "getcanonname_r");
328 char *s
= (char *) name
;
334 if (DL_CALL_FCT (cfct
, (at
->name
?: name
, buf
, sizeof (buf
),
335 &s
, &rc
, &herrno
)) != NSS_STATUS_SUCCESS
)
336 /* If the canonical name cannot be determined, use the passed
340 return __strdup (name
);
344 gaih_inet (const char *name
, const struct gaih_service
*service
,
345 const struct addrinfo
*req
, struct addrinfo
**pai
,
346 unsigned int *naddrs
, struct scratch_buffer
*tmpbuf
)
348 const struct gaih_typeproto
*tp
= gaih_inet_typeproto
;
349 struct gaih_servtuple
*st
= (struct gaih_servtuple
*) &nullserv
;
350 struct gaih_addrtuple
*at
= NULL
;
352 bool got_ipv6
= false;
353 const char *canon
= NULL
;
354 const char *orig_name
= name
;
356 /* Reserve stack memory for the scratch buffer in the getaddrinfo
358 size_t alloca_used
= sizeof (struct scratch_buffer
);
360 if (req
->ai_protocol
|| req
->ai_socktype
)
365 && ((req
->ai_socktype
!= 0 && req
->ai_socktype
!= tp
->socktype
)
366 || (req
->ai_protocol
!= 0
367 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
368 && req
->ai_protocol
!= tp
->protocol
)))
373 if (req
->ai_socktype
)
374 return -EAI_SOCKTYPE
;
383 if ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0)
386 if (service
->num
< 0)
390 st
= (struct gaih_servtuple
*)
391 alloca_account (sizeof (struct gaih_servtuple
), alloca_used
);
393 if ((rc
= gaih_inet_serv (service
->name
, tp
, req
, st
, tmpbuf
)))
398 struct gaih_servtuple
**pst
= &st
;
399 for (tp
++; tp
->name
[0]; tp
++)
401 struct gaih_servtuple
*newp
;
403 if ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0)
406 if (req
->ai_socktype
!= 0
407 && req
->ai_socktype
!= tp
->socktype
)
409 if (req
->ai_protocol
!= 0
410 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
411 && req
->ai_protocol
!= tp
->protocol
)
414 newp
= (struct gaih_servtuple
*)
415 alloca_account (sizeof (struct gaih_servtuple
),
418 if ((rc
= gaih_inet_serv (service
->name
,
419 tp
, req
, newp
, tmpbuf
)))
429 if (st
== (struct gaih_servtuple
*) &nullserv
)
435 port
= htons (service
->num
);
443 if (req
->ai_socktype
|| req
->ai_protocol
)
445 st
= alloca_account (sizeof (struct gaih_servtuple
), alloca_used
);
447 st
->socktype
= tp
->socktype
;
448 st
->protocol
= ((tp
->protoflag
& GAI_PROTO_PROTOANY
)
449 ? req
->ai_protocol
: tp
->protocol
);
454 /* Neither socket type nor protocol is set. Return all socket types
456 struct gaih_servtuple
**lastp
= &st
;
457 for (++tp
; tp
->name
[0]; ++tp
)
460 struct gaih_servtuple
*newp
;
462 newp
= alloca_account (sizeof (struct gaih_servtuple
),
465 newp
->socktype
= tp
->socktype
;
466 newp
->protocol
= tp
->protocol
;
475 bool malloc_name
= false;
476 struct gaih_addrtuple
*addrmem
= NULL
;
477 char *canonbuf
= NULL
;
482 at
= alloca_account (sizeof (struct gaih_addrtuple
), alloca_used
);
483 at
->family
= AF_UNSPEC
;
488 if (req
->ai_flags
& AI_IDN
)
491 if (req
->ai_flags
& AI_IDN_ALLOW_UNASSIGNED
)
492 idn_flags
|= IDNA_ALLOW_UNASSIGNED
;
493 if (req
->ai_flags
& AI_IDN_USE_STD3_ASCII_RULES
)
494 idn_flags
|= IDNA_USE_STD3_ASCII_RULES
;
497 rc
= __idna_to_ascii_lz (name
, &p
, idn_flags
);
498 if (rc
!= IDNA_SUCCESS
)
500 /* No need to jump to free_and_return here. */
501 if (rc
== IDNA_MALLOC_ERROR
)
503 if (rc
== IDNA_DLOPEN_ERROR
)
505 return -EAI_IDN_ENCODE
;
507 /* In case the output string is the same as the input string
508 no new string has been allocated. */
517 if (__inet_aton (name
, (struct in_addr
*) at
->addr
) != 0)
519 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET
)
520 at
->family
= AF_INET
;
521 else if (req
->ai_family
== AF_INET6
&& (req
->ai_flags
& AI_V4MAPPED
))
523 at
->addr
[3] = at
->addr
[0];
524 at
->addr
[2] = htonl (0xffff);
527 at
->family
= AF_INET6
;
531 result
= -EAI_ADDRFAMILY
;
532 goto free_and_return
;
535 if (req
->ai_flags
& AI_CANONNAME
)
538 else if (at
->family
== AF_UNSPEC
)
540 char *scope_delim
= strchr (name
, SCOPE_DELIMITER
);
544 bool malloc_namebuf
= false;
545 char *namebuf
= (char *) name
;
547 if (__glibc_unlikely (scope_delim
!= NULL
))
553 if (__libc_use_alloca (alloca_used
554 + scope_delim
- name
+ 1))
556 namebuf
= alloca_account (scope_delim
- name
+ 1,
558 *((char *) __mempcpy (namebuf
, name
,
559 scope_delim
- name
)) = '\0';
563 namebuf
= __strndup (name
, scope_delim
- name
);
566 assert (!malloc_name
);
569 malloc_namebuf
= true;
574 e
= inet_pton (AF_INET6
, namebuf
, at
->addr
);
578 else if (scope_delim
!= NULL
&& malloc_name
)
579 /* Undo what we did above. */
580 *scope_delim
= SCOPE_DELIMITER
;
584 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET6
)
585 at
->family
= AF_INET6
;
586 else if (req
->ai_family
== AF_INET
587 && IN6_IS_ADDR_V4MAPPED (at
->addr
))
589 at
->addr
[0] = at
->addr
[3];
590 at
->family
= AF_INET
;
594 result
= -EAI_ADDRFAMILY
;
595 goto free_and_return
;
598 if (scope_delim
!= NULL
599 && __inet6_scopeid_pton ((struct in6_addr
*) at
->addr
,
603 result
= -EAI_NONAME
;
604 goto free_and_return
;
607 if (req
->ai_flags
& AI_CANONNAME
)
612 if (at
->family
== AF_UNSPEC
&& (req
->ai_flags
& AI_NUMERICHOST
) == 0)
614 struct gaih_addrtuple
**pat
= &at
;
616 int no_inet6_data
= 0;
618 enum nss_status inet6_status
= NSS_STATUS_UNAVAIL
;
619 enum nss_status status
= NSS_STATUS_UNAVAIL
;
623 /* If we do not have to look for IPv6 addresses or the canonical
624 name, use the simple, old functions, which do not support
625 IPv6 scope ids, nor retrieving the canonical name. */
626 if (req
->ai_family
== AF_INET
627 && (req
->ai_flags
& AI_CANONNAME
) == 0)
636 rc
= __gethostbyname2_r (name
, AF_INET
, &th
,
637 tmpbuf
->data
, tmpbuf
->length
,
639 if (rc
!= ERANGE
|| herrno
!= NETDB_INTERNAL
)
641 if (!scratch_buffer_grow (tmpbuf
))
643 result
= -EAI_MEMORY
;
644 goto free_and_return
;
652 /* We found data, convert it. */
653 if (!convert_hostent_to_gaih_addrtuple
654 (req
, AF_INET
, h
, &addrmem
))
656 result
= -EAI_MEMORY
;
657 goto free_and_return
;
664 if (herrno
== NETDB_INTERNAL
)
666 __set_h_errno (herrno
);
667 result
= -EAI_SYSTEM
;
669 else if (herrno
== TRY_AGAIN
)
672 /* We made requests but they turned out no data.
673 The name is known, though. */
674 result
= -EAI_NODATA
;
676 goto free_and_return
;
683 if (__nss_not_use_nscd_hosts
> 0
684 && ++__nss_not_use_nscd_hosts
> NSS_NSCD_RETRY
)
685 __nss_not_use_nscd_hosts
= 0;
687 if (!__nss_not_use_nscd_hosts
688 && !__nss_database_custom
[NSS_DBSIDX_hosts
])
690 /* Try to use nscd. */
691 struct nscd_ai_result
*air
= NULL
;
693 int err
= __nscd_getai (name
, &air
, &herrno
);
696 /* Transform into gaih_addrtuple list. */
697 bool added_canon
= (req
->ai_flags
& AI_CANONNAME
) == 0;
698 char *addrs
= air
->addrs
;
700 addrmem
= calloc (air
->naddrs
, sizeof (*addrmem
));
703 result
= -EAI_MEMORY
;
704 goto free_and_return
;
707 struct gaih_addrtuple
*addrfree
= addrmem
;
708 for (int i
= 0; i
< air
->naddrs
; ++i
)
710 socklen_t size
= (air
->family
[i
] == AF_INET
711 ? INADDRSZ
: IN6ADDRSZ
);
713 if (!((air
->family
[i
] == AF_INET
714 && req
->ai_family
== AF_INET6
715 && (req
->ai_flags
& AI_V4MAPPED
) != 0)
716 || req
->ai_family
== AF_UNSPEC
717 || air
->family
[i
] == req
->ai_family
))
719 /* Skip over non-matching result. */
729 uint32_t *pataddr
= (*pat
)->addr
;
731 if (added_canon
|| air
->canon
== NULL
)
733 else if (canonbuf
== NULL
)
735 canonbuf
= strdup (air
->canon
);
736 if (canonbuf
== NULL
)
738 result
= -EAI_MEMORY
;
739 goto free_and_return
;
741 canon
= (*pat
)->name
= canonbuf
;
744 if (air
->family
[i
] == AF_INET
745 && req
->ai_family
== AF_INET6
746 && (req
->ai_flags
& AI_V4MAPPED
))
748 (*pat
)->family
= AF_INET6
;
749 pataddr
[3] = *(uint32_t *) addrs
;
750 pataddr
[2] = htonl (0xffff);
753 pat
= &((*pat
)->next
);
756 else if (req
->ai_family
== AF_UNSPEC
757 || air
->family
[i
] == req
->ai_family
)
759 (*pat
)->family
= air
->family
[i
];
760 memcpy (pataddr
, addrs
, size
);
761 pat
= &((*pat
)->next
);
763 if (air
->family
[i
] == AF_INET6
)
771 if (at
->family
== AF_UNSPEC
)
773 result
= -EAI_NONAME
;
774 goto free_and_return
;
780 /* The database contains a negative entry. */
781 goto free_and_return
;
782 else if (__nss_not_use_nscd_hosts
== 0)
784 if (herrno
== NETDB_INTERNAL
&& errno
== ENOMEM
)
785 result
= -EAI_MEMORY
;
786 else if (herrno
== TRY_AGAIN
)
789 result
= -EAI_SYSTEM
;
791 goto free_and_return
;
796 if (__nss_hosts_database
== NULL
)
797 no_more
= __nss_database_lookup ("hosts", NULL
,
798 "dns [!UNAVAIL=return] files",
799 &__nss_hosts_database
);
802 nip
= __nss_hosts_database
;
804 /* Initialize configurations. */
806 if (__res_maybe_init (&_res
, 0) == -1)
809 /* If we are looking for both IPv4 and IPv6 address we don't
810 want the lookup functions to automatically promote IPv4
811 addresses to IPv6 addresses. Currently this is decided
812 by setting the RES_USE_INET6 bit in _res.options. */
813 old_res_options
= _res
.options
;
814 _res
.options
&= ~DEPRECATED_RES_USE_INET6
;
819 nss_gethostbyname4_r fct4
= NULL
;
821 /* gethostbyname4_r sends out parallel A and AAAA queries and
822 is thus only suitable for PF_UNSPEC. */
823 if (req
->ai_family
== PF_UNSPEC
)
824 fct4
= __nss_lookup_function (nip
, "gethostbyname4_r");
833 status
= DL_CALL_FCT (fct4
, (name
, pat
,
834 tmpbuf
->data
, tmpbuf
->length
,
837 if (status
== NSS_STATUS_SUCCESS
)
839 if (status
!= NSS_STATUS_TRYAGAIN
840 || rc
!= ERANGE
|| herrno
!= NETDB_INTERNAL
)
842 if (herrno
== TRY_AGAIN
)
845 no_data
= herrno
== NO_DATA
;
849 if (!scratch_buffer_grow (tmpbuf
))
852 |= old_res_options
& DEPRECATED_RES_USE_INET6
;
853 result
= -EAI_MEMORY
;
854 goto free_and_return
;
858 if (status
== NSS_STATUS_SUCCESS
)
863 if ((req
->ai_flags
& AI_CANONNAME
) != 0 && canon
== NULL
)
864 canon
= (*pat
)->name
;
868 if ((*pat
)->family
== AF_INET
869 && req
->ai_family
== AF_INET6
870 && (req
->ai_flags
& AI_V4MAPPED
) != 0)
872 uint32_t *pataddr
= (*pat
)->addr
;
873 (*pat
)->family
= AF_INET6
;
874 pataddr
[3] = pataddr
[0];
875 pataddr
[2] = htonl (0xffff);
878 pat
= &((*pat
)->next
);
881 else if (req
->ai_family
== AF_UNSPEC
882 || (*pat
)->family
== req
->ai_family
)
884 pat
= &((*pat
)->next
);
887 if (req
->ai_family
== AF_INET6
)
891 *pat
= ((*pat
)->next
);
895 no_inet6_data
= no_data
;
899 nss_gethostbyname3_r fct
= NULL
;
900 if (req
->ai_flags
& AI_CANONNAME
)
901 /* No need to use this function if we do not look for
902 the canonical name. The function does not exist in
903 all NSS modules and therefore the lookup would
905 fct
= __nss_lookup_function (nip
, "gethostbyname3_r");
907 /* We are cheating here. The gethostbyname2_r
908 function does not have the same interface as
909 gethostbyname3_r but the extra arguments the
910 latter takes are added at the end. So the
911 gethostbyname2_r code will just ignore them. */
912 fct
= __nss_lookup_function (nip
, "gethostbyname2_r");
916 if (req
->ai_family
== AF_INET6
917 || req
->ai_family
== AF_UNSPEC
)
919 gethosts (AF_INET6
, struct in6_addr
);
920 no_inet6_data
= no_data
;
921 inet6_status
= status
;
923 if (req
->ai_family
== AF_INET
924 || req
->ai_family
== AF_UNSPEC
925 || (req
->ai_family
== AF_INET6
926 && (req
->ai_flags
& AI_V4MAPPED
)
927 /* Avoid generating the mapped addresses if we
928 know we are not going to need them. */
929 && ((req
->ai_flags
& AI_ALL
) || !got_ipv6
)))
931 gethosts (AF_INET
, struct in_addr
);
933 if (req
->ai_family
== AF_INET
)
935 no_inet6_data
= no_data
;
936 inet6_status
= status
;
940 /* If we found one address for AF_INET or AF_INET6,
941 don't continue the search. */
942 if (inet6_status
== NSS_STATUS_SUCCESS
943 || status
== NSS_STATUS_SUCCESS
)
945 if ((req
->ai_flags
& AI_CANONNAME
) != 0
948 canonbuf
= getcanonname (nip
, at
, name
);
949 if (canonbuf
== NULL
)
953 & DEPRECATED_RES_USE_INET6
;
954 result
= -EAI_MEMORY
;
955 goto free_and_return
;
959 status
= NSS_STATUS_SUCCESS
;
963 /* We can have different states for AF_INET and
964 AF_INET6. Try to find a useful one for both. */
965 if (inet6_status
== NSS_STATUS_TRYAGAIN
)
966 status
= NSS_STATUS_TRYAGAIN
;
967 else if (status
== NSS_STATUS_UNAVAIL
968 && inet6_status
!= NSS_STATUS_UNAVAIL
)
969 status
= inet6_status
;
974 status
= NSS_STATUS_UNAVAIL
;
975 /* Could not load any of the lookup functions. Indicate
976 an internal error if the failure was due to a system
977 error other than the file not being found. We use the
978 errno from the last failed callback. */
979 if (errno
!= 0 && errno
!= ENOENT
)
980 __set_h_errno (NETDB_INTERNAL
);
984 if (nss_next_action (nip
, status
) == NSS_ACTION_RETURN
)
987 if (nip
->next
== NULL
)
993 _res
.options
|= old_res_options
& DEPRECATED_RES_USE_INET6
;
995 if (h_errno
== NETDB_INTERNAL
)
997 result
= -EAI_SYSTEM
;
998 goto free_and_return
;
1001 if (no_data
!= 0 && no_inet6_data
!= 0)
1003 /* If both requests timed out report this. */
1004 if (no_data
== EAI_AGAIN
&& no_inet6_data
== EAI_AGAIN
)
1005 result
= -EAI_AGAIN
;
1007 /* We made requests but they turned out no data. The name
1008 is known, though. */
1009 result
= -EAI_NODATA
;
1011 goto free_and_return
;
1016 if (at
->family
== AF_UNSPEC
)
1018 result
= -EAI_NONAME
;
1019 goto free_and_return
;
1024 struct gaih_addrtuple
*atr
;
1025 atr
= at
= alloca_account (sizeof (struct gaih_addrtuple
), alloca_used
);
1026 memset (at
, '\0', sizeof (struct gaih_addrtuple
));
1028 if (req
->ai_family
== AF_UNSPEC
)
1030 at
->next
= __alloca (sizeof (struct gaih_addrtuple
));
1031 memset (at
->next
, '\0', sizeof (struct gaih_addrtuple
));
1034 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET6
)
1036 at
->family
= AF_INET6
;
1037 if ((req
->ai_flags
& AI_PASSIVE
) == 0)
1038 memcpy (at
->addr
, &in6addr_loopback
, sizeof (struct in6_addr
));
1042 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET
)
1044 atr
->family
= AF_INET
;
1045 if ((req
->ai_flags
& AI_PASSIVE
) == 0)
1046 atr
->addr
[0] = htonl (INADDR_LOOPBACK
);
1051 struct gaih_servtuple
*st2
;
1052 struct gaih_addrtuple
*at2
= at
;
1057 buffer is the size of an unformatted IPv6 address in printable format.
1061 /* Only the first entry gets the canonical name. */
1062 if (at2
== at
&& (req
->ai_flags
& AI_CANONNAME
) != 0)
1065 /* If the canonical name cannot be determined, use
1066 the passed in string. */
1070 if (req
->ai_flags
& AI_CANONIDN
)
1073 if (req
->ai_flags
& AI_IDN_ALLOW_UNASSIGNED
)
1074 idn_flags
|= IDNA_ALLOW_UNASSIGNED
;
1075 if (req
->ai_flags
& AI_IDN_USE_STD3_ASCII_RULES
)
1076 idn_flags
|= IDNA_USE_STD3_ASCII_RULES
;
1079 int rc
= __idna_to_unicode_lzlz (canon
, &out
, idn_flags
);
1080 if (rc
!= IDNA_SUCCESS
)
1082 if (rc
== IDNA_MALLOC_ERROR
)
1083 result
= -EAI_MEMORY
;
1084 else if (rc
== IDNA_DLOPEN_ERROR
)
1085 result
= -EAI_SYSTEM
;
1087 result
= -EAI_IDN_ENCODE
;
1088 goto free_and_return
;
1090 /* In case the output string is the same as the input
1091 string no new string has been allocated and we
1103 if (canonbuf
!= NULL
)
1104 /* We already allocated the string using malloc, but
1105 the buffer is now owned by canon. */
1109 canon
= __strdup (canon
);
1112 result
= -EAI_MEMORY
;
1113 goto free_and_return
;
1119 family
= at2
->family
;
1120 if (family
== AF_INET6
)
1122 socklen
= sizeof (struct sockaddr_in6
);
1124 /* If we looked up IPv4 mapped address discard them here if
1125 the caller isn't interested in all address and we have
1126 found at least one IPv6 address. */
1128 && (req
->ai_flags
& (AI_V4MAPPED
|AI_ALL
)) == AI_V4MAPPED
1129 && IN6_IS_ADDR_V4MAPPED (at2
->addr
))
1133 socklen
= sizeof (struct sockaddr_in
);
1135 for (st2
= st
; st2
!= NULL
; st2
= st2
->next
)
1137 struct addrinfo
*ai
;
1138 ai
= *pai
= malloc (sizeof (struct addrinfo
) + socklen
);
1141 free ((char *) canon
);
1142 result
= -EAI_MEMORY
;
1143 goto free_and_return
;
1146 ai
->ai_flags
= req
->ai_flags
;
1147 ai
->ai_family
= family
;
1148 ai
->ai_socktype
= st2
->socktype
;
1149 ai
->ai_protocol
= st2
->protocol
;
1150 ai
->ai_addrlen
= socklen
;
1151 ai
->ai_addr
= (void *) (ai
+ 1);
1153 /* We only add the canonical name once. */
1154 ai
->ai_canonname
= (char *) canon
;
1158 ai
->ai_addr
->sa_len
= socklen
;
1159 #endif /* _HAVE_SA_LEN */
1160 ai
->ai_addr
->sa_family
= family
;
1162 /* In case of an allocation error the list must be NULL
1166 if (family
== AF_INET6
)
1168 struct sockaddr_in6
*sin6p
=
1169 (struct sockaddr_in6
*) ai
->ai_addr
;
1171 sin6p
->sin6_port
= st2
->port
;
1172 sin6p
->sin6_flowinfo
= 0;
1173 memcpy (&sin6p
->sin6_addr
,
1174 at2
->addr
, sizeof (struct in6_addr
));
1175 sin6p
->sin6_scope_id
= at2
->scopeid
;
1179 struct sockaddr_in
*sinp
=
1180 (struct sockaddr_in
*) ai
->ai_addr
;
1181 sinp
->sin_port
= st2
->port
;
1182 memcpy (&sinp
->sin_addr
,
1183 at2
->addr
, sizeof (struct in_addr
));
1184 memset (sinp
->sin_zero
, '\0', sizeof (sinp
->sin_zero
));
1187 pai
= &(ai
->ai_next
);
1199 free ((char *) name
);
1209 struct addrinfo
*dest_addr
;
1210 /* Using sockaddr_storage is for now overkill. We only support IPv4
1211 and IPv6 so far. If this changes at some point we can adjust the
1213 struct sockaddr_in6 source_addr
;
1214 uint8_t source_addr_len
;
1215 bool got_source_addr
;
1216 uint8_t source_addr_flags
;
1222 struct sort_result_combo
1224 struct sort_result
*results
;
1229 #if __BYTE_ORDER == __BIG_ENDIAN
1230 # define htonl_c(n) n
1232 # define htonl_c(n) __bswap_constant_32 (n)
1235 static const struct scopeentry
1244 } default_scopes
[] =
1246 /* Link-local addresses: scope 2. */
1247 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1248 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1249 /* Default: scope 14. */
1250 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1253 /* The label table. */
1254 static const struct scopeentry
*scopes
;
1258 get_scope (const struct sockaddr_in6
*in6
)
1261 if (in6
->sin6_family
== PF_INET6
)
1263 if (! IN6_IS_ADDR_MULTICAST (&in6
->sin6_addr
))
1265 if (IN6_IS_ADDR_LINKLOCAL (&in6
->sin6_addr
)
1266 /* RFC 4291 2.5.3 says that the loopback address is to be
1267 treated like a link-local address. */
1268 || IN6_IS_ADDR_LOOPBACK (&in6
->sin6_addr
))
1270 else if (IN6_IS_ADDR_SITELOCAL (&in6
->sin6_addr
))
1273 /* XXX Is this the correct default behavior? */
1277 scope
= in6
->sin6_addr
.s6_addr
[1] & 0xf;
1279 else if (in6
->sin6_family
== PF_INET
)
1281 const struct sockaddr_in
*in
= (const struct sockaddr_in
*) in6
;
1286 if ((in
->sin_addr
.s_addr
& scopes
[cnt
].netmask
)
1287 == scopes
[cnt
].addr32
)
1288 return scopes
[cnt
].scope
;
1295 /* XXX What is a good default? */
1304 struct in6_addr prefix
;
1310 /* The label table. */
1311 static const struct prefixentry
*labels
;
1313 /* Default labels. */
1314 static const struct prefixentry default_labels
[] =
1316 /* See RFC 3484 for the details. */
1318 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1322 = { .__u6_addr8
= { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1326 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1330 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1331 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1333 /* The next two entries differ from RFC 3484. We need to treat
1334 IPv6 site-local addresses special because they are never NATed,
1335 unlike site-locale IPv4 addresses. If this would not happen, on
1336 machines which have only IPv4 and IPv6 site-local addresses, the
1337 sorting would prefer the IPv6 site-local addresses, causing
1338 unnecessary delays when trying to connect to a global IPv6 address
1339 through a site-local IPv6 address. */
1341 = { .__u6_addr8
= { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1345 = { .__u6_addr8
= { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1348 /* Additional rule for Teredo tunnels. */
1350 = { .__u6_addr8
= { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1354 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1360 /* The precedence table. */
1361 static const struct prefixentry
*precedence
;
1363 /* The default precedences. */
1364 static const struct prefixentry default_precedence
[] =
1366 /* See RFC 3484 for the details. */
1368 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1372 = { .__u6_addr8
= { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1376 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1380 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1381 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1384 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1391 match_prefix (const struct sockaddr_in6
*in6
,
1392 const struct prefixentry
*list
, int default_val
)
1395 struct sockaddr_in6 in6_mem
;
1397 if (in6
->sin6_family
== PF_INET
)
1399 const struct sockaddr_in
*in
= (const struct sockaddr_in
*) in6
;
1401 /* Construct a V4-to-6 mapped address. */
1402 in6_mem
.sin6_family
= PF_INET6
;
1403 in6_mem
.sin6_port
= in
->sin_port
;
1404 in6_mem
.sin6_flowinfo
= 0;
1405 memset (&in6_mem
.sin6_addr
, '\0', sizeof (in6_mem
.sin6_addr
));
1406 in6_mem
.sin6_addr
.s6_addr16
[5] = 0xffff;
1407 in6_mem
.sin6_addr
.s6_addr32
[3] = in
->sin_addr
.s_addr
;
1408 in6_mem
.sin6_scope_id
= 0;
1412 else if (in6
->sin6_family
!= PF_INET6
)
1415 for (idx
= 0; ; ++idx
)
1417 unsigned int bits
= list
[idx
].bits
;
1418 const uint8_t *mask
= list
[idx
].prefix
.s6_addr
;
1419 const uint8_t *val
= in6
->sin6_addr
.s6_addr
;
1433 if ((*mask
& (0xff00 >> bits
)) == (*val
& (0xff00 >> bits
)))
1439 return list
[idx
].val
;
1444 get_label (const struct sockaddr_in6
*in6
)
1446 /* XXX What is a good default value? */
1447 return match_prefix (in6
, labels
, INT_MAX
);
1452 get_precedence (const struct sockaddr_in6
*in6
)
1454 /* XXX What is a good default value? */
1455 return match_prefix (in6
, precedence
, 0);
1459 /* Find last bit set in a word. */
1465 for (n
= 0, mask
= 1 << 31; n
< 32; mask
>>= 1, ++n
)
1466 if ((a
& mask
) != 0)
1473 rfc3484_sort (const void *p1
, const void *p2
, void *arg
)
1475 const size_t idx1
= *(const size_t *) p1
;
1476 const size_t idx2
= *(const size_t *) p2
;
1477 struct sort_result_combo
*src
= (struct sort_result_combo
*) arg
;
1478 struct sort_result
*a1
= &src
->results
[idx1
];
1479 struct sort_result
*a2
= &src
->results
[idx2
];
1481 /* Rule 1: Avoid unusable destinations.
1482 We have the got_source_addr flag set if the destination is reachable. */
1483 if (a1
->got_source_addr
&& ! a2
->got_source_addr
)
1485 if (! a1
->got_source_addr
&& a2
->got_source_addr
)
1489 /* Rule 2: Prefer matching scope. Only interesting if both
1490 destination addresses are IPv6. */
1492 = get_scope ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1495 = get_scope ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1497 if (a1
->got_source_addr
)
1499 int a1_src_scope
= get_scope (&a1
->source_addr
);
1500 int a2_src_scope
= get_scope (&a2
->source_addr
);
1502 if (a1_dst_scope
== a1_src_scope
&& a2_dst_scope
!= a2_src_scope
)
1504 if (a1_dst_scope
!= a1_src_scope
&& a2_dst_scope
== a2_src_scope
)
1509 /* Rule 3: Avoid deprecated addresses. */
1510 if (a1
->got_source_addr
)
1512 if (!(a1
->source_addr_flags
& in6ai_deprecated
)
1513 && (a2
->source_addr_flags
& in6ai_deprecated
))
1515 if ((a1
->source_addr_flags
& in6ai_deprecated
)
1516 && !(a2
->source_addr_flags
& in6ai_deprecated
))
1520 /* Rule 4: Prefer home addresses. */
1521 if (a1
->got_source_addr
)
1523 if (!(a1
->source_addr_flags
& in6ai_homeaddress
)
1524 && (a2
->source_addr_flags
& in6ai_homeaddress
))
1526 if ((a1
->source_addr_flags
& in6ai_homeaddress
)
1527 && !(a2
->source_addr_flags
& in6ai_homeaddress
))
1531 /* Rule 5: Prefer matching label. */
1532 if (a1
->got_source_addr
)
1535 = get_label ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1536 int a1_src_label
= get_label (&a1
->source_addr
);
1539 = get_label ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1540 int a2_src_label
= get_label (&a2
->source_addr
);
1542 if (a1_dst_label
== a1_src_label
&& a2_dst_label
!= a2_src_label
)
1544 if (a1_dst_label
!= a1_src_label
&& a2_dst_label
== a2_src_label
)
1549 /* Rule 6: Prefer higher precedence. */
1551 = get_precedence ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1553 = get_precedence ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1555 if (a1_prec
> a2_prec
)
1557 if (a1_prec
< a2_prec
)
1561 /* Rule 7: Prefer native transport. */
1562 if (a1
->got_source_addr
)
1564 /* The same interface index means the same interface which means
1565 there is no difference in transport. This should catch many
1567 if (a1
->index
!= a2
->index
)
1569 int a1_native
= a1
->native
;
1570 int a2_native
= a2
->native
;
1572 if (a1_native
== -1 || a2_native
== -1)
1575 if (a1_native
== -1)
1577 /* If we do not have the information use 'native' as
1580 a1_index
= a1
->index
;
1583 a1_index
= 0xffffffffu
;
1586 if (a2_native
== -1)
1588 /* If we do not have the information use 'native' as
1591 a2_index
= a2
->index
;
1594 a2_index
= 0xffffffffu
;
1596 __check_native (a1_index
, &a1_native
, a2_index
, &a2_native
);
1598 /* Fill in the results in all the records. */
1599 for (int i
= 0; i
< src
->nresults
; ++i
)
1600 if (a1_index
!= -1 && src
->results
[i
].index
== a1_index
)
1602 assert (src
->results
[i
].native
== -1
1603 || src
->results
[i
].native
== a1_native
);
1604 src
->results
[i
].native
= a1_native
;
1606 else if (a2_index
!= -1 && src
->results
[i
].index
== a2_index
)
1608 assert (src
->results
[i
].native
== -1
1609 || src
->results
[i
].native
== a2_native
);
1610 src
->results
[i
].native
= a2_native
;
1614 if (a1_native
&& !a2_native
)
1616 if (!a1_native
&& a2_native
)
1622 /* Rule 8: Prefer smaller scope. */
1623 if (a1_dst_scope
< a2_dst_scope
)
1625 if (a1_dst_scope
> a2_dst_scope
)
1629 /* Rule 9: Use longest matching prefix. */
1630 if (a1
->got_source_addr
1631 && a1
->dest_addr
->ai_family
== a2
->dest_addr
->ai_family
)
1636 if (a1
->dest_addr
->ai_family
== PF_INET
)
1638 assert (a1
->source_addr
.sin6_family
== PF_INET
);
1639 assert (a2
->source_addr
.sin6_family
== PF_INET
);
1641 /* Outside of subnets, as defined by the network masks,
1642 common address prefixes for IPv4 addresses make no sense.
1643 So, define a non-zero value only if source and
1644 destination address are on the same subnet. */
1645 struct sockaddr_in
*in1_dst
1646 = (struct sockaddr_in
*) a1
->dest_addr
->ai_addr
;
1647 in_addr_t in1_dst_addr
= ntohl (in1_dst
->sin_addr
.s_addr
);
1648 struct sockaddr_in
*in1_src
1649 = (struct sockaddr_in
*) &a1
->source_addr
;
1650 in_addr_t in1_src_addr
= ntohl (in1_src
->sin_addr
.s_addr
);
1651 in_addr_t netmask1
= 0xffffffffu
<< (32 - a1
->prefixlen
);
1653 if ((in1_src_addr
& netmask1
) == (in1_dst_addr
& netmask1
))
1654 bit1
= fls (in1_dst_addr
^ in1_src_addr
);
1656 struct sockaddr_in
*in2_dst
1657 = (struct sockaddr_in
*) a2
->dest_addr
->ai_addr
;
1658 in_addr_t in2_dst_addr
= ntohl (in2_dst
->sin_addr
.s_addr
);
1659 struct sockaddr_in
*in2_src
1660 = (struct sockaddr_in
*) &a2
->source_addr
;
1661 in_addr_t in2_src_addr
= ntohl (in2_src
->sin_addr
.s_addr
);
1662 in_addr_t netmask2
= 0xffffffffu
<< (32 - a2
->prefixlen
);
1664 if ((in2_src_addr
& netmask2
) == (in2_dst_addr
& netmask2
))
1665 bit2
= fls (in2_dst_addr
^ in2_src_addr
);
1667 else if (a1
->dest_addr
->ai_family
== PF_INET6
)
1669 assert (a1
->source_addr
.sin6_family
== PF_INET6
);
1670 assert (a2
->source_addr
.sin6_family
== PF_INET6
);
1672 struct sockaddr_in6
*in1_dst
;
1673 struct sockaddr_in6
*in1_src
;
1674 struct sockaddr_in6
*in2_dst
;
1675 struct sockaddr_in6
*in2_src
;
1677 in1_dst
= (struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
;
1678 in1_src
= (struct sockaddr_in6
*) &a1
->source_addr
;
1679 in2_dst
= (struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
;
1680 in2_src
= (struct sockaddr_in6
*) &a2
->source_addr
;
1683 for (i
= 0; i
< 4; ++i
)
1684 if (in1_dst
->sin6_addr
.s6_addr32
[i
]
1685 != in1_src
->sin6_addr
.s6_addr32
[i
]
1686 || (in2_dst
->sin6_addr
.s6_addr32
[i
]
1687 != in2_src
->sin6_addr
.s6_addr32
[i
]))
1692 bit1
= fls (ntohl (in1_dst
->sin6_addr
.s6_addr32
[i
]
1693 ^ in1_src
->sin6_addr
.s6_addr32
[i
]));
1694 bit2
= fls (ntohl (in2_dst
->sin6_addr
.s6_addr32
[i
]
1695 ^ in2_src
->sin6_addr
.s6_addr32
[i
]));
1706 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1707 compare with the value indicating the order in which the entries
1708 have been received from the services. NB: no two entries can have
1709 the same order so the test will never return zero. */
1710 return idx1
< idx2
? -1 : 1;
1715 in6aicmp (const void *p1
, const void *p2
)
1717 struct in6addrinfo
*a1
= (struct in6addrinfo
*) p1
;
1718 struct in6addrinfo
*a2
= (struct in6addrinfo
*) p2
;
1720 return memcmp (a1
->addr
, a2
->addr
, sizeof (a1
->addr
));
1724 /* Name of the config file for RFC 3484 sorting (for now). */
1725 #define GAICONF_FNAME "/etc/gai.conf"
1728 /* Non-zero if we are supposed to reload the config file automatically
1729 whenever it changed. */
1730 static int gaiconf_reload_flag
;
1732 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1733 static int gaiconf_reload_flag_ever_set
;
1735 /* Last modification time. */
1736 #ifdef _STATBUF_ST_NSEC
1738 static struct timespec gaiconf_mtime
;
1741 save_gaiconf_mtime (const struct stat64
*st
)
1743 gaiconf_mtime
= st
->st_mtim
;
1747 check_gaiconf_mtime (const struct stat64
*st
)
1749 return (st
->st_mtim
.tv_sec
== gaiconf_mtime
.tv_sec
1750 && st
->st_mtim
.tv_nsec
== gaiconf_mtime
.tv_nsec
);
1755 static time_t gaiconf_mtime
;
1758 save_gaiconf_mtime (const struct stat64
*st
)
1760 gaiconf_mtime
= st
->st_mtime
;
1764 check_gaiconf_mtime (const struct stat64
*st
)
1766 return st
->st_mtime
== gaiconf_mtime
;
1772 libc_freeres_fn(fini
)
1774 if (labels
!= default_labels
)
1776 const struct prefixentry
*old
= labels
;
1777 labels
= default_labels
;
1778 free ((void *) old
);
1781 if (precedence
!= default_precedence
)
1783 const struct prefixentry
*old
= precedence
;
1784 precedence
= default_precedence
;
1785 free ((void *) old
);
1788 if (scopes
!= default_scopes
)
1790 const struct scopeentry
*old
= scopes
;
1791 scopes
= default_scopes
;
1792 free ((void *) old
);
1799 struct prefixentry entry
;
1800 struct prefixlist
*next
;
1806 struct scopeentry entry
;
1807 struct scopelist
*next
;
1812 free_prefixlist (struct prefixlist
*list
)
1814 while (list
!= NULL
)
1816 struct prefixlist
*oldp
= list
;
1824 free_scopelist (struct scopelist
*list
)
1826 while (list
!= NULL
)
1828 struct scopelist
*oldp
= list
;
1836 prefixcmp (const void *p1
, const void *p2
)
1838 const struct prefixentry
*e1
= (const struct prefixentry
*) p1
;
1839 const struct prefixentry
*e2
= (const struct prefixentry
*) p2
;
1841 if (e1
->bits
< e2
->bits
)
1843 if (e1
->bits
== e2
->bits
)
1850 scopecmp (const void *p1
, const void *p2
)
1852 const struct scopeentry
*e1
= (const struct scopeentry
*) p1
;
1853 const struct scopeentry
*e2
= (const struct scopeentry
*) p2
;
1855 if (e1
->netmask
> e2
->netmask
)
1857 if (e1
->netmask
== e2
->netmask
)
1866 struct prefixlist
*labellist
= NULL
;
1867 size_t nlabellist
= 0;
1868 bool labellist_nullbits
= false;
1869 struct prefixlist
*precedencelist
= NULL
;
1870 size_t nprecedencelist
= 0;
1871 bool precedencelist_nullbits
= false;
1872 struct scopelist
*scopelist
= NULL
;
1873 size_t nscopelist
= 0;
1874 bool scopelist_nullbits
= false;
1876 FILE *fp
= fopen (GAICONF_FNAME
, "rce");
1880 if (__fxstat64 (_STAT_VER
, fileno (fp
), &st
) != 0)
1889 __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
1891 while (!feof_unlocked (fp
))
1893 ssize_t n
= __getline (&line
, &linelen
, fp
);
1897 /* Handle comments. No escaping possible so this is easy. */
1898 char *cp
= strchr (line
, '#');
1903 while (isspace (*cp
))
1907 while (*cp
!= '\0' && !isspace (*cp
))
1909 size_t cmdlen
= cp
- cmd
;
1913 while (isspace (*cp
))
1917 while (*cp
!= '\0' && !isspace (*cp
))
1919 size_t val1len
= cp
- cmd
;
1921 /* We always need at least two values. */
1927 while (isspace (*cp
))
1931 while (*cp
!= '\0' && !isspace (*cp
))
1934 /* Ignore the rest of the line. */
1937 struct prefixlist
**listp
;
1943 if (strcmp (cmd
, "label") == 0)
1945 struct in6_addr prefix
;
1946 unsigned long int bits
;
1947 unsigned long int val
;
1952 nullbitsp
= &labellist_nullbits
;
1957 cp
= strchr (val1
, '/');
1960 if (inet_pton (AF_INET6
, val1
, &prefix
)
1962 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
1966 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
1971 struct prefixlist
*newp
= malloc (sizeof (*newp
));
1979 memcpy (&newp
->entry
.prefix
, &prefix
, sizeof (prefix
));
1980 newp
->entry
.bits
= bits
;
1981 newp
->entry
.val
= val
;
1982 newp
->next
= *listp
;
1985 *nullbitsp
|= bits
== 0;
1991 if (strcmp (cmd
, "reload") == 0)
1993 gaiconf_reload_flag
= strcmp (val1
, "yes") == 0;
1994 if (gaiconf_reload_flag
)
1995 gaiconf_reload_flag_ever_set
= 1;
2000 if (strcmp (cmd
, "scopev4") == 0)
2002 struct in6_addr prefix
;
2003 unsigned long int bits
;
2004 unsigned long int val
;
2009 cp
= strchr (val1
, '/');
2012 if (inet_pton (AF_INET6
, val1
, &prefix
))
2015 if (IN6_IS_ADDR_V4MAPPED (&prefix
)
2017 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
2022 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
2027 struct scopelist
*newp
;
2029 newp
= malloc (sizeof (*newp
));
2037 newp
->entry
.netmask
= htonl (bits
!= 96
2041 newp
->entry
.addr32
= (prefix
.s6_addr32
[3]
2042 & newp
->entry
.netmask
);
2043 newp
->entry
.scope
= val
;
2044 newp
->next
= scopelist
;
2047 scopelist_nullbits
|= bits
== 96;
2050 else if (inet_pton (AF_INET
, val1
, &prefix
.s6_addr32
[3])
2052 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
2056 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
2068 if (strcmp (cmd
, "precedence") == 0)
2070 listp
= &precedencelist
;
2071 lenp
= &nprecedencelist
;
2072 nullbitsp
= &precedencelist_nullbits
;
2083 /* Create the array for the labels. */
2084 struct prefixentry
*new_labels
;
2087 if (!labellist_nullbits
)
2089 new_labels
= malloc (nlabellist
* sizeof (*new_labels
));
2090 if (new_labels
== NULL
)
2094 if (!labellist_nullbits
)
2097 memset (&new_labels
[i
].prefix
, '\0', sizeof (struct in6_addr
));
2098 new_labels
[i
].bits
= 0;
2099 new_labels
[i
].val
= 1;
2102 struct prefixlist
*l
= labellist
;
2105 new_labels
[i
] = l
->entry
;
2108 free_prefixlist (labellist
);
2110 /* Sort the entries so that the most specific ones are at
2112 qsort (new_labels
, nlabellist
, sizeof (*new_labels
), prefixcmp
);
2115 new_labels
= (struct prefixentry
*) default_labels
;
2117 struct prefixentry
*new_precedence
;
2118 if (nprecedencelist
> 0)
2120 if (!precedencelist_nullbits
)
2122 new_precedence
= malloc (nprecedencelist
* sizeof (*new_precedence
));
2123 if (new_precedence
== NULL
)
2125 if (new_labels
!= default_labels
)
2130 int i
= nprecedencelist
;
2131 if (!precedencelist_nullbits
)
2134 memset (&new_precedence
[i
].prefix
, '\0',
2135 sizeof (struct in6_addr
));
2136 new_precedence
[i
].bits
= 0;
2137 new_precedence
[i
].val
= 40;
2140 struct prefixlist
*l
= precedencelist
;
2143 new_precedence
[i
] = l
->entry
;
2146 free_prefixlist (precedencelist
);
2148 /* Sort the entries so that the most specific ones are at
2150 qsort (new_precedence
, nprecedencelist
, sizeof (*new_precedence
),
2154 new_precedence
= (struct prefixentry
*) default_precedence
;
2156 struct scopeentry
*new_scopes
;
2159 if (!scopelist_nullbits
)
2161 new_scopes
= malloc (nscopelist
* sizeof (*new_scopes
));
2162 if (new_scopes
== NULL
)
2164 if (new_labels
!= default_labels
)
2166 if (new_precedence
!= default_precedence
)
2167 free (new_precedence
);
2172 if (!scopelist_nullbits
)
2175 new_scopes
[i
].addr32
= 0;
2176 new_scopes
[i
].netmask
= 0;
2177 new_scopes
[i
].scope
= 14;
2180 struct scopelist
*l
= scopelist
;
2183 new_scopes
[i
] = l
->entry
;
2186 free_scopelist (scopelist
);
2188 /* Sort the entries so that the most specific ones are at
2190 qsort (new_scopes
, nscopelist
, sizeof (*new_scopes
),
2194 new_scopes
= (struct scopeentry
*) default_scopes
;
2196 /* Now we are ready to replace the values. */
2197 const struct prefixentry
*old
= labels
;
2198 labels
= new_labels
;
2199 if (old
!= default_labels
)
2200 free ((void *) old
);
2203 precedence
= new_precedence
;
2204 if (old
!= default_precedence
)
2205 free ((void *) old
);
2207 const struct scopeentry
*oldscope
= scopes
;
2208 scopes
= new_scopes
;
2209 if (oldscope
!= default_scopes
)
2210 free ((void *) oldscope
);
2212 save_gaiconf_mtime (&st
);
2217 free_prefixlist (labellist
);
2218 free_prefixlist (precedencelist
);
2219 free_scopelist (scopelist
);
2221 /* If we previously read the file but it is gone now, free the
2222 old data and use the builtin one. Leave the reload flag
2230 gaiconf_reload (void)
2233 if (__xstat64 (_STAT_VER
, GAICONF_FNAME
, &st
) != 0
2234 || !check_gaiconf_mtime (&st
))
2240 getaddrinfo (const char *name
, const char *service
,
2241 const struct addrinfo
*hints
, struct addrinfo
**pai
)
2243 int i
= 0, last_i
= 0;
2245 struct addrinfo
*p
= NULL
;
2246 struct gaih_service gaih_service
, *pservice
;
2247 struct addrinfo local_hints
;
2249 if (name
!= NULL
&& name
[0] == '*' && name
[1] == 0)
2252 if (service
!= NULL
&& service
[0] == '*' && service
[1] == 0)
2255 if (name
== NULL
&& service
== NULL
)
2259 hints
= &default_hints
;
2262 & ~(AI_PASSIVE
|AI_CANONNAME
|AI_NUMERICHOST
|AI_ADDRCONFIG
|AI_V4MAPPED
2264 |AI_IDN
|AI_CANONIDN
|AI_IDN_ALLOW_UNASSIGNED
2265 |AI_IDN_USE_STD3_ASCII_RULES
2267 |AI_NUMERICSERV
|AI_ALL
))
2268 return EAI_BADFLAGS
;
2270 if ((hints
->ai_flags
& AI_CANONNAME
) && name
== NULL
)
2271 return EAI_BADFLAGS
;
2273 struct in6addrinfo
*in6ai
= NULL
;
2274 size_t in6ailen
= 0;
2275 bool seen_ipv4
= false;
2276 bool seen_ipv6
= false;
2277 bool check_pf_called
= false;
2279 if (hints
->ai_flags
& AI_ADDRCONFIG
)
2281 /* We might need information about what interfaces are available.
2282 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2283 cannot cache the results since new interfaces could be added at
2285 __check_pf (&seen_ipv4
, &seen_ipv6
, &in6ai
, &in6ailen
);
2286 check_pf_called
= true;
2288 /* Now make a decision on what we return, if anything. */
2289 if (hints
->ai_family
== PF_UNSPEC
&& (seen_ipv4
|| seen_ipv6
))
2291 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2292 narrow down the search. */
2293 if ((! seen_ipv4
|| ! seen_ipv6
) && (seen_ipv4
|| seen_ipv6
))
2295 local_hints
= *hints
;
2296 local_hints
.ai_family
= seen_ipv4
? PF_INET
: PF_INET6
;
2297 hints
= &local_hints
;
2300 else if ((hints
->ai_family
== PF_INET
&& ! seen_ipv4
)
2301 || (hints
->ai_family
== PF_INET6
&& ! seen_ipv6
))
2303 /* We cannot possibly return a valid answer. */
2304 __free_in6ai (in6ai
);
2309 if (service
&& service
[0])
2312 gaih_service
.name
= service
;
2313 gaih_service
.num
= strtoul (gaih_service
.name
, &c
, 10);
2316 if (hints
->ai_flags
& AI_NUMERICSERV
)
2318 __free_in6ai (in6ai
);
2322 gaih_service
.num
= -1;
2325 pservice
= &gaih_service
;
2330 struct addrinfo
**end
= &p
;
2332 unsigned int naddrs
= 0;
2333 if (hints
->ai_family
== AF_UNSPEC
|| hints
->ai_family
== AF_INET
2334 || hints
->ai_family
== AF_INET6
)
2336 struct scratch_buffer tmpbuf
;
2337 scratch_buffer_init (&tmpbuf
);
2338 last_i
= gaih_inet (name
, pservice
, hints
, end
, &naddrs
, &tmpbuf
);
2339 scratch_buffer_free (&tmpbuf
);
2344 __free_in6ai (in6ai
);
2350 end
= &((*end
)->ai_next
);
2356 __free_in6ai (in6ai
);
2362 /* Read the config file. */
2363 __libc_once_define (static, once
);
2364 __typeof (once
) old_once
= once
;
2365 __libc_once (once
, gaiconf_init
);
2366 /* Sort results according to RFC 3484. */
2367 struct sort_result
*results
;
2370 struct addrinfo
*last
= NULL
;
2371 char *canonname
= NULL
;
2372 bool malloc_results
;
2373 size_t alloc_size
= nresults
* (sizeof (*results
) + sizeof (size_t));
2376 = !__libc_use_alloca (alloc_size
);
2379 results
= malloc (alloc_size
);
2380 if (results
== NULL
)
2382 __free_in6ai (in6ai
);
2387 results
= alloca (alloc_size
);
2388 order
= (size_t *) (results
+ nresults
);
2390 /* Now we definitely need the interface information. */
2391 if (! check_pf_called
)
2392 __check_pf (&seen_ipv4
, &seen_ipv6
, &in6ai
, &in6ailen
);
2394 /* If we have information about deprecated and temporary addresses
2395 sort the array now. */
2397 qsort (in6ai
, in6ailen
, sizeof (*in6ai
), in6aicmp
);
2402 for (i
= 0, q
= p
; q
!= NULL
; ++i
, last
= q
, q
= q
->ai_next
)
2404 results
[i
].dest_addr
= q
;
2405 results
[i
].native
= -1;
2408 /* If we just looked up the address for a different
2409 protocol, reuse the result. */
2410 if (last
!= NULL
&& last
->ai_addrlen
== q
->ai_addrlen
2411 && memcmp (last
->ai_addr
, q
->ai_addr
, q
->ai_addrlen
) == 0)
2413 memcpy (&results
[i
].source_addr
, &results
[i
- 1].source_addr
,
2414 results
[i
- 1].source_addr_len
);
2415 results
[i
].source_addr_len
= results
[i
- 1].source_addr_len
;
2416 results
[i
].got_source_addr
= results
[i
- 1].got_source_addr
;
2417 results
[i
].source_addr_flags
= results
[i
- 1].source_addr_flags
;
2418 results
[i
].prefixlen
= results
[i
- 1].prefixlen
;
2419 results
[i
].index
= results
[i
- 1].index
;
2423 results
[i
].got_source_addr
= false;
2424 results
[i
].source_addr_flags
= 0;
2425 results
[i
].prefixlen
= 0;
2426 results
[i
].index
= 0xffffffffu
;
2428 /* We overwrite the type with SOCK_DGRAM since we do not
2429 want connect() to connect to the other side. If we
2430 cannot determine the source address remember this
2432 if (fd
== -1 || (af
== AF_INET
&& q
->ai_family
== AF_INET6
))
2436 close_not_cancel_no_status (fd
);
2438 fd
= __socket (af
, SOCK_DGRAM
| SOCK_CLOEXEC
, IPPROTO_IP
);
2442 /* Reset the connection. */
2443 struct sockaddr sa
= { .sa_family
= AF_UNSPEC
};
2444 __connect (fd
, &sa
, sizeof (sa
));
2447 socklen_t sl
= sizeof (results
[i
].source_addr
);
2449 && __connect (fd
, q
->ai_addr
, q
->ai_addrlen
) == 0
2450 && __getsockname (fd
,
2451 (struct sockaddr
*) &results
[i
].source_addr
,
2454 results
[i
].source_addr_len
= sl
;
2455 results
[i
].got_source_addr
= true;
2459 /* See whether the source address is on the list of
2460 deprecated or temporary addresses. */
2461 struct in6addrinfo tmp
;
2463 if (q
->ai_family
== AF_INET
&& af
== AF_INET
)
2465 struct sockaddr_in
*sinp
2466 = (struct sockaddr_in
*) &results
[i
].source_addr
;
2469 tmp
.addr
[2] = htonl (0xffff);
2470 /* Special case for lo interface, the source address
2471 being possibly different than the interface
2473 if ((ntohl(sinp
->sin_addr
.s_addr
) & 0xff000000)
2475 tmp
.addr
[3] = htonl(0x7f000001);
2477 tmp
.addr
[3] = sinp
->sin_addr
.s_addr
;
2481 struct sockaddr_in6
*sin6p
2482 = (struct sockaddr_in6
*) &results
[i
].source_addr
;
2483 memcpy (tmp
.addr
, &sin6p
->sin6_addr
, IN6ADDRSZ
);
2486 struct in6addrinfo
*found
2487 = bsearch (&tmp
, in6ai
, in6ailen
, sizeof (*in6ai
),
2491 results
[i
].source_addr_flags
= found
->flags
;
2492 results
[i
].prefixlen
= found
->prefixlen
;
2493 results
[i
].index
= found
->index
;
2497 if (q
->ai_family
== AF_INET
&& af
== AF_INET6
)
2499 /* We have to convert the address. The socket is
2500 IPv6 and the request is for IPv4. */
2501 struct sockaddr_in6
*sin6
2502 = (struct sockaddr_in6
*) &results
[i
].source_addr
;
2503 struct sockaddr_in
*sin
2504 = (struct sockaddr_in
*) &results
[i
].source_addr
;
2505 assert (IN6_IS_ADDR_V4MAPPED (sin6
->sin6_addr
.s6_addr32
));
2506 sin
->sin_family
= AF_INET
;
2507 /* We do not have to initialize sin_port since this
2508 fields has the same position and size in the IPv6
2510 assert (offsetof (struct sockaddr_in
, sin_port
)
2511 == offsetof (struct sockaddr_in6
, sin6_port
));
2512 assert (sizeof (sin
->sin_port
)
2513 == sizeof (sin6
->sin6_port
));
2514 memcpy (&sin
->sin_addr
,
2515 &sin6
->sin6_addr
.s6_addr32
[3], INADDRSZ
);
2516 results
[i
].source_addr_len
= sizeof (struct sockaddr_in
);
2519 else if (errno
== EAFNOSUPPORT
&& af
== AF_INET6
2520 && q
->ai_family
== AF_INET
)
2521 /* This could mean IPv6 sockets are IPv6-only. */
2524 /* Just make sure that if we have to process the same
2525 address again we do not copy any memory. */
2526 results
[i
].source_addr_len
= 0;
2529 /* Remember the canonical name. */
2530 if (q
->ai_canonname
!= NULL
)
2532 assert (canonname
== NULL
);
2533 canonname
= q
->ai_canonname
;
2534 q
->ai_canonname
= NULL
;
2539 close_not_cancel_no_status (fd
);
2541 /* We got all the source addresses we can get, now sort using
2543 struct sort_result_combo src
2544 = { .results
= results
, .nresults
= nresults
};
2545 if (__glibc_unlikely (gaiconf_reload_flag_ever_set
))
2547 __libc_lock_define_initialized (static, lock
);
2549 __libc_lock_lock (lock
);
2550 if (__libc_once_get (old_once
) && gaiconf_reload_flag
)
2552 __qsort_r (order
, nresults
, sizeof (order
[0]), rfc3484_sort
, &src
);
2553 __libc_lock_unlock (lock
);
2556 __qsort_r (order
, nresults
, sizeof (order
[0]), rfc3484_sort
, &src
);
2558 /* Queue the results up as they come out of sorting. */
2559 q
= p
= results
[order
[0]].dest_addr
;
2560 for (i
= 1; i
< nresults
; ++i
)
2561 q
= q
->ai_next
= results
[order
[i
]].dest_addr
;
2564 /* Fill in the canonical name into the new first entry. */
2565 p
->ai_canonname
= canonname
;
2571 __free_in6ai (in6ai
);
2579 return last_i
? -last_i
: EAI_NONAME
;
2581 libc_hidden_def (getaddrinfo
)
2583 nss_interface_function (getaddrinfo
)
2586 freeaddrinfo (struct addrinfo
*ai
)
2594 free (p
->ai_canonname
);
2598 libc_hidden_def (freeaddrinfo
)