1 /* Host and service name lookups using Name Service Switch modules.
2 Copyright (C) 1996-2016 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. */
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 & 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 /* Make sure that addrmem can be freed. */ \
282 if (!malloc_addrmem) \
284 if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \
286 _res.options |= old_res_options & RES_USE_INET6; \
287 result = -EAI_SYSTEM; \
288 goto free_and_return; \
291 /* The conversion uses malloc unconditionally. */ \
292 malloc_addrmem = true; \
294 if (localcanon != NULL && canon == NULL) \
295 canon = strdupa (localcanon); \
297 if (_family == AF_INET6 && *pat != NULL) \
303 typedef enum nss_status (*nss_gethostbyname4_r
)
304 (const char *name
, struct gaih_addrtuple
**pat
,
305 char *buffer
, size_t buflen
, int *errnop
,
306 int *h_errnop
, int32_t *ttlp
);
307 typedef enum nss_status (*nss_gethostbyname3_r
)
308 (const char *name
, int af
, struct hostent
*host
,
309 char *buffer
, size_t buflen
, int *errnop
,
310 int *h_errnop
, int32_t *ttlp
, char **canonp
);
311 typedef enum nss_status (*nss_getcanonname_r
)
312 (const char *name
, char *buffer
, size_t buflen
, char **result
,
313 int *errnop
, int *h_errnop
);
314 extern service_user
*__nss_hosts_database attribute_hidden
;
318 gaih_inet (const char *name
, const struct gaih_service
*service
,
319 const struct addrinfo
*req
, struct addrinfo
**pai
,
320 unsigned int *naddrs
, struct scratch_buffer
*tmpbuf
)
322 const struct gaih_typeproto
*tp
= gaih_inet_typeproto
;
323 struct gaih_servtuple
*st
= (struct gaih_servtuple
*) &nullserv
;
324 struct gaih_addrtuple
*at
= NULL
;
326 bool got_ipv6
= false;
327 const char *canon
= NULL
;
328 const char *orig_name
= name
;
330 /* Reserve stack memory for the scratch buffer in the getaddrinfo
332 size_t alloca_used
= sizeof (struct scratch_buffer
);
334 if (req
->ai_protocol
|| req
->ai_socktype
)
339 && ((req
->ai_socktype
!= 0 && req
->ai_socktype
!= tp
->socktype
)
340 || (req
->ai_protocol
!= 0
341 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
342 && req
->ai_protocol
!= tp
->protocol
)))
347 if (req
->ai_socktype
)
348 return -EAI_SOCKTYPE
;
357 if ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0)
360 if (service
->num
< 0)
364 st
= (struct gaih_servtuple
*)
365 alloca_account (sizeof (struct gaih_servtuple
), alloca_used
);
367 if ((rc
= gaih_inet_serv (service
->name
, tp
, req
, st
, tmpbuf
)))
372 struct gaih_servtuple
**pst
= &st
;
373 for (tp
++; tp
->name
[0]; tp
++)
375 struct gaih_servtuple
*newp
;
377 if ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0)
380 if (req
->ai_socktype
!= 0
381 && req
->ai_socktype
!= tp
->socktype
)
383 if (req
->ai_protocol
!= 0
384 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
385 && req
->ai_protocol
!= tp
->protocol
)
388 newp
= (struct gaih_servtuple
*)
389 alloca_account (sizeof (struct gaih_servtuple
),
392 if ((rc
= gaih_inet_serv (service
->name
,
393 tp
, req
, newp
, tmpbuf
)))
403 if (st
== (struct gaih_servtuple
*) &nullserv
)
409 port
= htons (service
->num
);
417 if (req
->ai_socktype
|| req
->ai_protocol
)
419 st
= alloca_account (sizeof (struct gaih_servtuple
), alloca_used
);
421 st
->socktype
= tp
->socktype
;
422 st
->protocol
= ((tp
->protoflag
& GAI_PROTO_PROTOANY
)
423 ? req
->ai_protocol
: tp
->protocol
);
428 /* Neither socket type nor protocol is set. Return all socket types
430 struct gaih_servtuple
**lastp
= &st
;
431 for (++tp
; tp
->name
[0]; ++tp
)
434 struct gaih_servtuple
*newp
;
436 newp
= alloca_account (sizeof (struct gaih_servtuple
),
439 newp
->socktype
= tp
->socktype
;
440 newp
->protocol
= tp
->protocol
;
449 bool malloc_name
= false;
450 bool malloc_addrmem
= false;
451 struct gaih_addrtuple
*addrmem
= NULL
;
452 bool malloc_canonbuf
= false;
453 char *canonbuf
= NULL
;
458 at
= alloca_account (sizeof (struct gaih_addrtuple
), alloca_used
);
459 at
->family
= AF_UNSPEC
;
464 if (req
->ai_flags
& AI_IDN
)
467 if (req
->ai_flags
& AI_IDN_ALLOW_UNASSIGNED
)
468 idn_flags
|= IDNA_ALLOW_UNASSIGNED
;
469 if (req
->ai_flags
& AI_IDN_USE_STD3_ASCII_RULES
)
470 idn_flags
|= IDNA_USE_STD3_ASCII_RULES
;
473 rc
= __idna_to_ascii_lz (name
, &p
, idn_flags
);
474 if (rc
!= IDNA_SUCCESS
)
476 /* No need to jump to free_and_return here. */
477 if (rc
== IDNA_MALLOC_ERROR
)
479 if (rc
== IDNA_DLOPEN_ERROR
)
481 return -EAI_IDN_ENCODE
;
483 /* In case the output string is the same as the input string
484 no new string has been allocated. */
493 if (__inet_aton (name
, (struct in_addr
*) at
->addr
) != 0)
495 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET
)
496 at
->family
= AF_INET
;
497 else if (req
->ai_family
== AF_INET6
&& (req
->ai_flags
& AI_V4MAPPED
))
499 at
->addr
[3] = at
->addr
[0];
500 at
->addr
[2] = htonl (0xffff);
503 at
->family
= AF_INET6
;
507 result
= -EAI_ADDRFAMILY
;
508 goto free_and_return
;
511 if (req
->ai_flags
& AI_CANONNAME
)
514 else if (at
->family
== AF_UNSPEC
)
516 char *scope_delim
= strchr (name
, SCOPE_DELIMITER
);
520 bool malloc_namebuf
= false;
521 char *namebuf
= (char *) name
;
523 if (__glibc_unlikely (scope_delim
!= NULL
))
529 if (__libc_use_alloca (alloca_used
530 + scope_delim
- name
+ 1))
532 namebuf
= alloca_account (scope_delim
- name
+ 1,
534 *((char *) __mempcpy (namebuf
, name
,
535 scope_delim
- name
)) = '\0';
539 namebuf
= strndup (name
, scope_delim
- name
);
542 assert (!malloc_name
);
545 malloc_namebuf
= true;
550 e
= inet_pton (AF_INET6
, namebuf
, at
->addr
);
554 else if (scope_delim
!= NULL
&& malloc_name
)
555 /* Undo what we did above. */
556 *scope_delim
= SCOPE_DELIMITER
;
560 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET6
)
561 at
->family
= AF_INET6
;
562 else if (req
->ai_family
== AF_INET
563 && IN6_IS_ADDR_V4MAPPED (at
->addr
))
565 at
->addr
[0] = at
->addr
[3];
566 at
->family
= AF_INET
;
570 result
= -EAI_ADDRFAMILY
;
571 goto free_and_return
;
574 if (scope_delim
!= NULL
575 && __inet6_scopeid_pton ((struct in6_addr
*) at
->addr
,
579 result
= -EAI_NONAME
;
580 goto free_and_return
;
583 if (req
->ai_flags
& AI_CANONNAME
)
588 if (at
->family
== AF_UNSPEC
&& (req
->ai_flags
& AI_NUMERICHOST
) == 0)
590 struct gaih_addrtuple
**pat
= &at
;
592 int no_inet6_data
= 0;
594 enum nss_status inet6_status
= NSS_STATUS_UNAVAIL
;
595 enum nss_status status
= NSS_STATUS_UNAVAIL
;
599 /* If we do not have to look for IPv6 addresses or the canonical
600 name, use the simple, old functions, which do not support
601 IPv6 scope ids, nor retrieving the canonical name. */
602 if (req
->ai_family
== AF_INET
603 && (req
->ai_flags
& AI_CANONNAME
) == 0)
612 rc
= __gethostbyname2_r (name
, AF_INET
, &th
,
613 tmpbuf
->data
, tmpbuf
->length
,
615 if (rc
!= ERANGE
|| herrno
!= NETDB_INTERNAL
)
617 if (!scratch_buffer_grow (tmpbuf
))
619 result
= -EAI_MEMORY
;
620 goto free_and_return
;
628 /* We found data, convert it. */
629 if (!convert_hostent_to_gaih_addrtuple
630 (req
, AF_INET
, h
, &addrmem
))
632 result
= -EAI_MEMORY
;
633 goto free_and_return
;
636 /* The conversion uses malloc unconditionally. */
637 malloc_addrmem
= true;
642 if (herrno
== NETDB_INTERNAL
)
644 __set_h_errno (herrno
);
645 result
= -EAI_SYSTEM
;
647 else if (herrno
== TRY_AGAIN
)
650 /* We made requests but they turned out no data.
651 The name is known, though. */
652 result
= -EAI_NODATA
;
654 goto free_and_return
;
661 if (__nss_not_use_nscd_hosts
> 0
662 && ++__nss_not_use_nscd_hosts
> NSS_NSCD_RETRY
)
663 __nss_not_use_nscd_hosts
= 0;
665 if (!__nss_not_use_nscd_hosts
666 && !__nss_database_custom
[NSS_DBSIDX_hosts
])
668 /* Try to use nscd. */
669 struct nscd_ai_result
*air
= NULL
;
671 int err
= __nscd_getai (name
, &air
, &herrno
);
674 /* Transform into gaih_addrtuple list. */
675 bool added_canon
= (req
->ai_flags
& AI_CANONNAME
) == 0;
676 char *addrs
= air
->addrs
;
678 if (__libc_use_alloca (alloca_used
679 + air
->naddrs
* sizeof (struct gaih_addrtuple
)))
680 addrmem
= alloca_account (air
->naddrs
681 * sizeof (struct gaih_addrtuple
),
685 addrmem
= malloc (air
->naddrs
686 * sizeof (struct gaih_addrtuple
));
689 result
= -EAI_MEMORY
;
690 goto free_and_return
;
692 malloc_addrmem
= true;
695 struct gaih_addrtuple
*addrfree
= addrmem
;
696 for (int i
= 0; i
< air
->naddrs
; ++i
)
698 socklen_t size
= (air
->family
[i
] == AF_INET
699 ? INADDRSZ
: IN6ADDRSZ
);
701 if (!((air
->family
[i
] == AF_INET
702 && req
->ai_family
== AF_INET6
703 && (req
->ai_flags
& AI_V4MAPPED
) != 0)
704 || req
->ai_family
== AF_UNSPEC
705 || air
->family
[i
] == req
->ai_family
))
707 /* Skip over non-matching result. */
717 uint32_t *pataddr
= (*pat
)->addr
;
719 if (added_canon
|| air
->canon
== NULL
)
721 else if (canonbuf
== NULL
)
723 size_t canonlen
= strlen (air
->canon
) + 1;
724 if ((req
->ai_flags
& AI_CANONIDN
) != 0
725 && __libc_use_alloca (alloca_used
+ canonlen
))
726 canonbuf
= alloca_account (canonlen
, alloca_used
);
729 canonbuf
= malloc (canonlen
);
730 if (canonbuf
== NULL
)
732 result
= -EAI_MEMORY
;
733 goto free_and_return
;
735 malloc_canonbuf
= true;
737 canon
= (*pat
)->name
= memcpy (canonbuf
, air
->canon
,
741 if (air
->family
[i
] == AF_INET
742 && req
->ai_family
== AF_INET6
743 && (req
->ai_flags
& AI_V4MAPPED
))
745 (*pat
)->family
= AF_INET6
;
746 pataddr
[3] = *(uint32_t *) addrs
;
747 pataddr
[2] = htonl (0xffff);
750 pat
= &((*pat
)->next
);
753 else if (req
->ai_family
== AF_UNSPEC
754 || air
->family
[i
] == req
->ai_family
)
756 (*pat
)->family
= air
->family
[i
];
757 memcpy (pataddr
, addrs
, size
);
758 pat
= &((*pat
)->next
);
760 if (air
->family
[i
] == AF_INET6
)
768 if (at
->family
== AF_UNSPEC
)
770 result
= -EAI_NONAME
;
771 goto free_and_return
;
777 /* The database contains a negative entry. */
778 goto free_and_return
;
779 else if (__nss_not_use_nscd_hosts
== 0)
781 if (herrno
== NETDB_INTERNAL
&& errno
== ENOMEM
)
782 result
= -EAI_MEMORY
;
783 else if (herrno
== TRY_AGAIN
)
786 result
= -EAI_SYSTEM
;
788 goto free_and_return
;
793 if (__nss_hosts_database
== NULL
)
794 no_more
= __nss_database_lookup ("hosts", NULL
,
795 "dns [!UNAVAIL=return] files",
796 &__nss_hosts_database
);
799 nip
= __nss_hosts_database
;
801 /* Initialize configurations. */
803 if (__res_maybe_init (&_res
, 0) == -1)
806 /* If we are looking for both IPv4 and IPv6 address we don't
807 want the lookup functions to automatically promote IPv4
808 addresses to IPv6 addresses. Currently this is decided
809 by setting the RES_USE_INET6 bit in _res.options. */
810 old_res_options
= _res
.options
;
811 _res
.options
&= ~RES_USE_INET6
;
816 nss_gethostbyname4_r fct4
= NULL
;
818 /* gethostbyname4_r sends out parallel A and AAAA queries and
819 is thus only suitable for PF_UNSPEC. */
820 if (req
->ai_family
== PF_UNSPEC
)
821 fct4
= __nss_lookup_function (nip
, "gethostbyname4_r");
830 status
= DL_CALL_FCT (fct4
, (name
, pat
,
831 tmpbuf
->data
, tmpbuf
->length
,
834 if (status
== NSS_STATUS_SUCCESS
)
836 if (status
!= NSS_STATUS_TRYAGAIN
837 || rc
!= ERANGE
|| herrno
!= NETDB_INTERNAL
)
839 if (herrno
== TRY_AGAIN
)
842 no_data
= herrno
== NO_DATA
;
846 if (!scratch_buffer_grow (tmpbuf
))
848 _res
.options
|= old_res_options
& RES_USE_INET6
;
849 result
= -EAI_MEMORY
;
850 goto free_and_return
;
854 if (status
== NSS_STATUS_SUCCESS
)
859 if ((req
->ai_flags
& AI_CANONNAME
) != 0 && canon
== NULL
)
860 canon
= (*pat
)->name
;
864 if ((*pat
)->family
== AF_INET
865 && req
->ai_family
== AF_INET6
866 && (req
->ai_flags
& AI_V4MAPPED
) != 0)
868 uint32_t *pataddr
= (*pat
)->addr
;
869 (*pat
)->family
= AF_INET6
;
870 pataddr
[3] = pataddr
[0];
871 pataddr
[2] = htonl (0xffff);
874 pat
= &((*pat
)->next
);
877 else if (req
->ai_family
== AF_UNSPEC
878 || (*pat
)->family
== req
->ai_family
)
880 pat
= &((*pat
)->next
);
883 if (req
->ai_family
== AF_INET6
)
887 *pat
= ((*pat
)->next
);
891 no_inet6_data
= no_data
;
895 nss_gethostbyname3_r fct
= NULL
;
896 if (req
->ai_flags
& AI_CANONNAME
)
897 /* No need to use this function if we do not look for
898 the canonical name. The function does not exist in
899 all NSS modules and therefore the lookup would
901 fct
= __nss_lookup_function (nip
, "gethostbyname3_r");
903 /* We are cheating here. The gethostbyname2_r
904 function does not have the same interface as
905 gethostbyname3_r but the extra arguments the
906 latter takes are added at the end. So the
907 gethostbyname2_r code will just ignore them. */
908 fct
= __nss_lookup_function (nip
, "gethostbyname2_r");
912 if (req
->ai_family
== AF_INET6
913 || req
->ai_family
== AF_UNSPEC
)
915 gethosts (AF_INET6
, struct in6_addr
);
916 no_inet6_data
= no_data
;
917 inet6_status
= status
;
919 if (req
->ai_family
== AF_INET
920 || req
->ai_family
== AF_UNSPEC
921 || (req
->ai_family
== AF_INET6
922 && (req
->ai_flags
& AI_V4MAPPED
)
923 /* Avoid generating the mapped addresses if we
924 know we are not going to need them. */
925 && ((req
->ai_flags
& AI_ALL
) || !got_ipv6
)))
927 gethosts (AF_INET
, struct in_addr
);
929 if (req
->ai_family
== AF_INET
)
931 no_inet6_data
= no_data
;
932 inet6_status
= status
;
936 /* If we found one address for AF_INET or AF_INET6,
937 don't continue the search. */
938 if (inet6_status
== NSS_STATUS_SUCCESS
939 || status
== NSS_STATUS_SUCCESS
)
941 if ((req
->ai_flags
& AI_CANONNAME
) != 0
944 /* If we need the canonical name, get it
945 from the same service as the result. */
946 nss_getcanonname_r cfct
;
949 cfct
= __nss_lookup_function (nip
,
953 const size_t max_fqdn_len
= 256;
954 if ((req
->ai_flags
& AI_CANONIDN
) != 0
955 && __libc_use_alloca (alloca_used
957 canonbuf
= alloca_account (max_fqdn_len
,
961 canonbuf
= malloc (max_fqdn_len
);
962 if (canonbuf
== NULL
)
965 |= old_res_options
& RES_USE_INET6
;
966 result
= -EAI_MEMORY
;
967 goto free_and_return
;
969 malloc_canonbuf
= true;
973 if (DL_CALL_FCT (cfct
, (at
->name
?: name
,
977 == NSS_STATUS_SUCCESS
)
981 /* If the canonical name cannot be
982 determined, use the passed in
987 malloc_canonbuf
= false;
993 status
= NSS_STATUS_SUCCESS
;
997 /* We can have different states for AF_INET and
998 AF_INET6. Try to find a useful one for both. */
999 if (inet6_status
== NSS_STATUS_TRYAGAIN
)
1000 status
= NSS_STATUS_TRYAGAIN
;
1001 else if (status
== NSS_STATUS_UNAVAIL
1002 && inet6_status
!= NSS_STATUS_UNAVAIL
)
1003 status
= inet6_status
;
1008 status
= NSS_STATUS_UNAVAIL
;
1009 /* Could not load any of the lookup functions. Indicate
1010 an internal error if the failure was due to a system
1011 error other than the file not being found. We use the
1012 errno from the last failed callback. */
1013 if (errno
!= 0 && errno
!= ENOENT
)
1014 __set_h_errno (NETDB_INTERNAL
);
1018 if (nss_next_action (nip
, status
) == NSS_ACTION_RETURN
)
1021 if (nip
->next
== NULL
)
1027 _res
.options
|= old_res_options
& RES_USE_INET6
;
1029 if (h_errno
== NETDB_INTERNAL
)
1031 result
= -EAI_SYSTEM
;
1032 goto free_and_return
;
1035 if (no_data
!= 0 && no_inet6_data
!= 0)
1037 /* If both requests timed out report this. */
1038 if (no_data
== EAI_AGAIN
&& no_inet6_data
== EAI_AGAIN
)
1039 result
= -EAI_AGAIN
;
1041 /* We made requests but they turned out no data. The name
1042 is known, though. */
1043 result
= -EAI_NODATA
;
1045 goto free_and_return
;
1050 if (at
->family
== AF_UNSPEC
)
1052 result
= -EAI_NONAME
;
1053 goto free_and_return
;
1058 struct gaih_addrtuple
*atr
;
1059 atr
= at
= alloca_account (sizeof (struct gaih_addrtuple
), alloca_used
);
1060 memset (at
, '\0', sizeof (struct gaih_addrtuple
));
1062 if (req
->ai_family
== AF_UNSPEC
)
1064 at
->next
= __alloca (sizeof (struct gaih_addrtuple
));
1065 memset (at
->next
, '\0', sizeof (struct gaih_addrtuple
));
1068 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET6
)
1070 at
->family
= AF_INET6
;
1071 if ((req
->ai_flags
& AI_PASSIVE
) == 0)
1072 memcpy (at
->addr
, &in6addr_loopback
, sizeof (struct in6_addr
));
1076 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET
)
1078 atr
->family
= AF_INET
;
1079 if ((req
->ai_flags
& AI_PASSIVE
) == 0)
1080 atr
->addr
[0] = htonl (INADDR_LOOPBACK
);
1085 struct gaih_servtuple
*st2
;
1086 struct gaih_addrtuple
*at2
= at
;
1091 buffer is the size of an unformatted IPv6 address in printable format.
1095 /* Only the first entry gets the canonical name. */
1096 if (at2
== at
&& (req
->ai_flags
& AI_CANONNAME
) != 0)
1099 /* If the canonical name cannot be determined, use
1100 the passed in string. */
1104 if (req
->ai_flags
& AI_CANONIDN
)
1107 if (req
->ai_flags
& AI_IDN_ALLOW_UNASSIGNED
)
1108 idn_flags
|= IDNA_ALLOW_UNASSIGNED
;
1109 if (req
->ai_flags
& AI_IDN_USE_STD3_ASCII_RULES
)
1110 idn_flags
|= IDNA_USE_STD3_ASCII_RULES
;
1113 int rc
= __idna_to_unicode_lzlz (canon
, &out
, idn_flags
);
1114 if (rc
!= IDNA_SUCCESS
)
1116 if (rc
== IDNA_MALLOC_ERROR
)
1117 result
= -EAI_MEMORY
;
1118 else if (rc
== IDNA_DLOPEN_ERROR
)
1119 result
= -EAI_SYSTEM
;
1121 result
= -EAI_IDN_ENCODE
;
1122 goto free_and_return
;
1124 /* In case the output string is the same as the input
1125 string no new string has been allocated and we
1137 if (malloc_canonbuf
)
1138 /* We already allocated the string using malloc. */
1139 malloc_canonbuf
= false;
1142 canon
= strdup (canon
);
1145 result
= -EAI_MEMORY
;
1146 goto free_and_return
;
1152 family
= at2
->family
;
1153 if (family
== AF_INET6
)
1155 socklen
= sizeof (struct sockaddr_in6
);
1157 /* If we looked up IPv4 mapped address discard them here if
1158 the caller isn't interested in all address and we have
1159 found at least one IPv6 address. */
1161 && (req
->ai_flags
& (AI_V4MAPPED
|AI_ALL
)) == AI_V4MAPPED
1162 && IN6_IS_ADDR_V4MAPPED (at2
->addr
))
1166 socklen
= sizeof (struct sockaddr_in
);
1168 for (st2
= st
; st2
!= NULL
; st2
= st2
->next
)
1170 struct addrinfo
*ai
;
1171 ai
= *pai
= malloc (sizeof (struct addrinfo
) + socklen
);
1174 free ((char *) canon
);
1175 result
= -EAI_MEMORY
;
1176 goto free_and_return
;
1179 ai
->ai_flags
= req
->ai_flags
;
1180 ai
->ai_family
= family
;
1181 ai
->ai_socktype
= st2
->socktype
;
1182 ai
->ai_protocol
= st2
->protocol
;
1183 ai
->ai_addrlen
= socklen
;
1184 ai
->ai_addr
= (void *) (ai
+ 1);
1186 /* We only add the canonical name once. */
1187 ai
->ai_canonname
= (char *) canon
;
1191 ai
->ai_addr
->sa_len
= socklen
;
1192 #endif /* _HAVE_SA_LEN */
1193 ai
->ai_addr
->sa_family
= family
;
1195 /* In case of an allocation error the list must be NULL
1199 if (family
== AF_INET6
)
1201 struct sockaddr_in6
*sin6p
=
1202 (struct sockaddr_in6
*) ai
->ai_addr
;
1204 sin6p
->sin6_port
= st2
->port
;
1205 sin6p
->sin6_flowinfo
= 0;
1206 memcpy (&sin6p
->sin6_addr
,
1207 at2
->addr
, sizeof (struct in6_addr
));
1208 sin6p
->sin6_scope_id
= at2
->scopeid
;
1212 struct sockaddr_in
*sinp
=
1213 (struct sockaddr_in
*) ai
->ai_addr
;
1214 sinp
->sin_port
= st2
->port
;
1215 memcpy (&sinp
->sin_addr
,
1216 at2
->addr
, sizeof (struct in_addr
));
1217 memset (sinp
->sin_zero
, '\0', sizeof (sinp
->sin_zero
));
1220 pai
= &(ai
->ai_next
);
1232 free ((char *) name
);
1235 if (malloc_canonbuf
)
1244 struct addrinfo
*dest_addr
;
1245 /* Using sockaddr_storage is for now overkill. We only support IPv4
1246 and IPv6 so far. If this changes at some point we can adjust the
1248 struct sockaddr_in6 source_addr
;
1249 uint8_t source_addr_len
;
1250 bool got_source_addr
;
1251 uint8_t source_addr_flags
;
1257 struct sort_result_combo
1259 struct sort_result
*results
;
1264 #if __BYTE_ORDER == __BIG_ENDIAN
1265 # define htonl_c(n) n
1267 # define htonl_c(n) __bswap_constant_32 (n)
1270 static const struct scopeentry
1279 } default_scopes
[] =
1281 /* Link-local addresses: scope 2. */
1282 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1283 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1284 /* Default: scope 14. */
1285 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1288 /* The label table. */
1289 static const struct scopeentry
*scopes
;
1293 get_scope (const struct sockaddr_in6
*in6
)
1296 if (in6
->sin6_family
== PF_INET6
)
1298 if (! IN6_IS_ADDR_MULTICAST (&in6
->sin6_addr
))
1300 if (IN6_IS_ADDR_LINKLOCAL (&in6
->sin6_addr
)
1301 /* RFC 4291 2.5.3 says that the loopback address is to be
1302 treated like a link-local address. */
1303 || IN6_IS_ADDR_LOOPBACK (&in6
->sin6_addr
))
1305 else if (IN6_IS_ADDR_SITELOCAL (&in6
->sin6_addr
))
1308 /* XXX Is this the correct default behavior? */
1312 scope
= in6
->sin6_addr
.s6_addr
[1] & 0xf;
1314 else if (in6
->sin6_family
== PF_INET
)
1316 const struct sockaddr_in
*in
= (const struct sockaddr_in
*) in6
;
1321 if ((in
->sin_addr
.s_addr
& scopes
[cnt
].netmask
)
1322 == scopes
[cnt
].addr32
)
1323 return scopes
[cnt
].scope
;
1330 /* XXX What is a good default? */
1339 struct in6_addr prefix
;
1345 /* The label table. */
1346 static const struct prefixentry
*labels
;
1348 /* Default labels. */
1349 static const struct prefixentry default_labels
[] =
1351 /* See RFC 3484 for the details. */
1353 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1357 = { .__u6_addr8
= { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1361 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1365 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1366 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1368 /* The next two entries differ from RFC 3484. We need to treat
1369 IPv6 site-local addresses special because they are never NATed,
1370 unlike site-locale IPv4 addresses. If this would not happen, on
1371 machines which have only IPv4 and IPv6 site-local addresses, the
1372 sorting would prefer the IPv6 site-local addresses, causing
1373 unnecessary delays when trying to connect to a global IPv6 address
1374 through a site-local IPv6 address. */
1376 = { .__u6_addr8
= { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1380 = { .__u6_addr8
= { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1383 /* Additional rule for Teredo tunnels. */
1385 = { .__u6_addr8
= { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1389 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1395 /* The precedence table. */
1396 static const struct prefixentry
*precedence
;
1398 /* The default precedences. */
1399 static const struct prefixentry default_precedence
[] =
1401 /* See RFC 3484 for the details. */
1403 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1407 = { .__u6_addr8
= { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1411 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1412 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1415 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1416 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1419 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1426 match_prefix (const struct sockaddr_in6
*in6
,
1427 const struct prefixentry
*list
, int default_val
)
1430 struct sockaddr_in6 in6_mem
;
1432 if (in6
->sin6_family
== PF_INET
)
1434 const struct sockaddr_in
*in
= (const struct sockaddr_in
*) in6
;
1436 /* Construct a V4-to-6 mapped address. */
1437 in6_mem
.sin6_family
= PF_INET6
;
1438 in6_mem
.sin6_port
= in
->sin_port
;
1439 in6_mem
.sin6_flowinfo
= 0;
1440 memset (&in6_mem
.sin6_addr
, '\0', sizeof (in6_mem
.sin6_addr
));
1441 in6_mem
.sin6_addr
.s6_addr16
[5] = 0xffff;
1442 in6_mem
.sin6_addr
.s6_addr32
[3] = in
->sin_addr
.s_addr
;
1443 in6_mem
.sin6_scope_id
= 0;
1447 else if (in6
->sin6_family
!= PF_INET6
)
1450 for (idx
= 0; ; ++idx
)
1452 unsigned int bits
= list
[idx
].bits
;
1453 const uint8_t *mask
= list
[idx
].prefix
.s6_addr
;
1454 const uint8_t *val
= in6
->sin6_addr
.s6_addr
;
1468 if ((*mask
& (0xff00 >> bits
)) == (*val
& (0xff00 >> bits
)))
1474 return list
[idx
].val
;
1479 get_label (const struct sockaddr_in6
*in6
)
1481 /* XXX What is a good default value? */
1482 return match_prefix (in6
, labels
, INT_MAX
);
1487 get_precedence (const struct sockaddr_in6
*in6
)
1489 /* XXX What is a good default value? */
1490 return match_prefix (in6
, precedence
, 0);
1494 /* Find last bit set in a word. */
1500 for (n
= 0, mask
= 1 << 31; n
< 32; mask
>>= 1, ++n
)
1501 if ((a
& mask
) != 0)
1508 rfc3484_sort (const void *p1
, const void *p2
, void *arg
)
1510 const size_t idx1
= *(const size_t *) p1
;
1511 const size_t idx2
= *(const size_t *) p2
;
1512 struct sort_result_combo
*src
= (struct sort_result_combo
*) arg
;
1513 struct sort_result
*a1
= &src
->results
[idx1
];
1514 struct sort_result
*a2
= &src
->results
[idx2
];
1516 /* Rule 1: Avoid unusable destinations.
1517 We have the got_source_addr flag set if the destination is reachable. */
1518 if (a1
->got_source_addr
&& ! a2
->got_source_addr
)
1520 if (! a1
->got_source_addr
&& a2
->got_source_addr
)
1524 /* Rule 2: Prefer matching scope. Only interesting if both
1525 destination addresses are IPv6. */
1527 = get_scope ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1530 = get_scope ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1532 if (a1
->got_source_addr
)
1534 int a1_src_scope
= get_scope (&a1
->source_addr
);
1535 int a2_src_scope
= get_scope (&a2
->source_addr
);
1537 if (a1_dst_scope
== a1_src_scope
&& a2_dst_scope
!= a2_src_scope
)
1539 if (a1_dst_scope
!= a1_src_scope
&& a2_dst_scope
== a2_src_scope
)
1544 /* Rule 3: Avoid deprecated addresses. */
1545 if (a1
->got_source_addr
)
1547 if (!(a1
->source_addr_flags
& in6ai_deprecated
)
1548 && (a2
->source_addr_flags
& in6ai_deprecated
))
1550 if ((a1
->source_addr_flags
& in6ai_deprecated
)
1551 && !(a2
->source_addr_flags
& in6ai_deprecated
))
1555 /* Rule 4: Prefer home addresses. */
1556 if (a1
->got_source_addr
)
1558 if (!(a1
->source_addr_flags
& in6ai_homeaddress
)
1559 && (a2
->source_addr_flags
& in6ai_homeaddress
))
1561 if ((a1
->source_addr_flags
& in6ai_homeaddress
)
1562 && !(a2
->source_addr_flags
& in6ai_homeaddress
))
1566 /* Rule 5: Prefer matching label. */
1567 if (a1
->got_source_addr
)
1570 = get_label ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1571 int a1_src_label
= get_label (&a1
->source_addr
);
1574 = get_label ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1575 int a2_src_label
= get_label (&a2
->source_addr
);
1577 if (a1_dst_label
== a1_src_label
&& a2_dst_label
!= a2_src_label
)
1579 if (a1_dst_label
!= a1_src_label
&& a2_dst_label
== a2_src_label
)
1584 /* Rule 6: Prefer higher precedence. */
1586 = get_precedence ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1588 = get_precedence ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1590 if (a1_prec
> a2_prec
)
1592 if (a1_prec
< a2_prec
)
1596 /* Rule 7: Prefer native transport. */
1597 if (a1
->got_source_addr
)
1599 /* The same interface index means the same interface which means
1600 there is no difference in transport. This should catch many
1602 if (a1
->index
!= a2
->index
)
1604 int a1_native
= a1
->native
;
1605 int a2_native
= a2
->native
;
1607 if (a1_native
== -1 || a2_native
== -1)
1610 if (a1_native
== -1)
1612 /* If we do not have the information use 'native' as
1615 a1_index
= a1
->index
;
1618 a1_index
= 0xffffffffu
;
1621 if (a2_native
== -1)
1623 /* If we do not have the information use 'native' as
1626 a2_index
= a2
->index
;
1629 a2_index
= 0xffffffffu
;
1631 __check_native (a1_index
, &a1_native
, a2_index
, &a2_native
);
1633 /* Fill in the results in all the records. */
1634 for (int i
= 0; i
< src
->nresults
; ++i
)
1635 if (a1_index
!= -1 && src
->results
[i
].index
== a1_index
)
1637 assert (src
->results
[i
].native
== -1
1638 || src
->results
[i
].native
== a1_native
);
1639 src
->results
[i
].native
= a1_native
;
1641 else if (a2_index
!= -1 && src
->results
[i
].index
== a2_index
)
1643 assert (src
->results
[i
].native
== -1
1644 || src
->results
[i
].native
== a2_native
);
1645 src
->results
[i
].native
= a2_native
;
1649 if (a1_native
&& !a2_native
)
1651 if (!a1_native
&& a2_native
)
1657 /* Rule 8: Prefer smaller scope. */
1658 if (a1_dst_scope
< a2_dst_scope
)
1660 if (a1_dst_scope
> a2_dst_scope
)
1664 /* Rule 9: Use longest matching prefix. */
1665 if (a1
->got_source_addr
1666 && a1
->dest_addr
->ai_family
== a2
->dest_addr
->ai_family
)
1671 if (a1
->dest_addr
->ai_family
== PF_INET
)
1673 assert (a1
->source_addr
.sin6_family
== PF_INET
);
1674 assert (a2
->source_addr
.sin6_family
== PF_INET
);
1676 /* Outside of subnets, as defined by the network masks,
1677 common address prefixes for IPv4 addresses make no sense.
1678 So, define a non-zero value only if source and
1679 destination address are on the same subnet. */
1680 struct sockaddr_in
*in1_dst
1681 = (struct sockaddr_in
*) a1
->dest_addr
->ai_addr
;
1682 in_addr_t in1_dst_addr
= ntohl (in1_dst
->sin_addr
.s_addr
);
1683 struct sockaddr_in
*in1_src
1684 = (struct sockaddr_in
*) &a1
->source_addr
;
1685 in_addr_t in1_src_addr
= ntohl (in1_src
->sin_addr
.s_addr
);
1686 in_addr_t netmask1
= 0xffffffffu
<< (32 - a1
->prefixlen
);
1688 if ((in1_src_addr
& netmask1
) == (in1_dst_addr
& netmask1
))
1689 bit1
= fls (in1_dst_addr
^ in1_src_addr
);
1691 struct sockaddr_in
*in2_dst
1692 = (struct sockaddr_in
*) a2
->dest_addr
->ai_addr
;
1693 in_addr_t in2_dst_addr
= ntohl (in2_dst
->sin_addr
.s_addr
);
1694 struct sockaddr_in
*in2_src
1695 = (struct sockaddr_in
*) &a2
->source_addr
;
1696 in_addr_t in2_src_addr
= ntohl (in2_src
->sin_addr
.s_addr
);
1697 in_addr_t netmask2
= 0xffffffffu
<< (32 - a2
->prefixlen
);
1699 if ((in2_src_addr
& netmask2
) == (in2_dst_addr
& netmask2
))
1700 bit2
= fls (in2_dst_addr
^ in2_src_addr
);
1702 else if (a1
->dest_addr
->ai_family
== PF_INET6
)
1704 assert (a1
->source_addr
.sin6_family
== PF_INET6
);
1705 assert (a2
->source_addr
.sin6_family
== PF_INET6
);
1707 struct sockaddr_in6
*in1_dst
;
1708 struct sockaddr_in6
*in1_src
;
1709 struct sockaddr_in6
*in2_dst
;
1710 struct sockaddr_in6
*in2_src
;
1712 in1_dst
= (struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
;
1713 in1_src
= (struct sockaddr_in6
*) &a1
->source_addr
;
1714 in2_dst
= (struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
;
1715 in2_src
= (struct sockaddr_in6
*) &a2
->source_addr
;
1718 for (i
= 0; i
< 4; ++i
)
1719 if (in1_dst
->sin6_addr
.s6_addr32
[i
]
1720 != in1_src
->sin6_addr
.s6_addr32
[i
]
1721 || (in2_dst
->sin6_addr
.s6_addr32
[i
]
1722 != in2_src
->sin6_addr
.s6_addr32
[i
]))
1727 bit1
= fls (ntohl (in1_dst
->sin6_addr
.s6_addr32
[i
]
1728 ^ in1_src
->sin6_addr
.s6_addr32
[i
]));
1729 bit2
= fls (ntohl (in2_dst
->sin6_addr
.s6_addr32
[i
]
1730 ^ in2_src
->sin6_addr
.s6_addr32
[i
]));
1741 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1742 compare with the value indicating the order in which the entries
1743 have been received from the services. NB: no two entries can have
1744 the same order so the test will never return zero. */
1745 return idx1
< idx2
? -1 : 1;
1750 in6aicmp (const void *p1
, const void *p2
)
1752 struct in6addrinfo
*a1
= (struct in6addrinfo
*) p1
;
1753 struct in6addrinfo
*a2
= (struct in6addrinfo
*) p2
;
1755 return memcmp (a1
->addr
, a2
->addr
, sizeof (a1
->addr
));
1759 /* Name of the config file for RFC 3484 sorting (for now). */
1760 #define GAICONF_FNAME "/etc/gai.conf"
1763 /* Non-zero if we are supposed to reload the config file automatically
1764 whenever it changed. */
1765 static int gaiconf_reload_flag
;
1767 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1768 static int gaiconf_reload_flag_ever_set
;
1770 /* Last modification time. */
1771 #ifdef _STATBUF_ST_NSEC
1773 static struct timespec gaiconf_mtime
;
1776 save_gaiconf_mtime (const struct stat64
*st
)
1778 gaiconf_mtime
= st
->st_mtim
;
1782 check_gaiconf_mtime (const struct stat64
*st
)
1784 return (st
->st_mtim
.tv_sec
== gaiconf_mtime
.tv_sec
1785 && st
->st_mtim
.tv_nsec
== gaiconf_mtime
.tv_nsec
);
1790 static time_t gaiconf_mtime
;
1793 save_gaiconf_mtime (const struct stat64
*st
)
1795 gaiconf_mtime
= st
->st_mtime
;
1799 check_gaiconf_mtime (const struct stat64
*st
)
1801 return st
->st_mtime
== gaiconf_mtime
;
1807 libc_freeres_fn(fini
)
1809 if (labels
!= default_labels
)
1811 const struct prefixentry
*old
= labels
;
1812 labels
= default_labels
;
1813 free ((void *) old
);
1816 if (precedence
!= default_precedence
)
1818 const struct prefixentry
*old
= precedence
;
1819 precedence
= default_precedence
;
1820 free ((void *) old
);
1823 if (scopes
!= default_scopes
)
1825 const struct scopeentry
*old
= scopes
;
1826 scopes
= default_scopes
;
1827 free ((void *) old
);
1834 struct prefixentry entry
;
1835 struct prefixlist
*next
;
1841 struct scopeentry entry
;
1842 struct scopelist
*next
;
1847 free_prefixlist (struct prefixlist
*list
)
1849 while (list
!= NULL
)
1851 struct prefixlist
*oldp
= list
;
1859 free_scopelist (struct scopelist
*list
)
1861 while (list
!= NULL
)
1863 struct scopelist
*oldp
= list
;
1871 prefixcmp (const void *p1
, const void *p2
)
1873 const struct prefixentry
*e1
= (const struct prefixentry
*) p1
;
1874 const struct prefixentry
*e2
= (const struct prefixentry
*) p2
;
1876 if (e1
->bits
< e2
->bits
)
1878 if (e1
->bits
== e2
->bits
)
1885 scopecmp (const void *p1
, const void *p2
)
1887 const struct scopeentry
*e1
= (const struct scopeentry
*) p1
;
1888 const struct scopeentry
*e2
= (const struct scopeentry
*) p2
;
1890 if (e1
->netmask
> e2
->netmask
)
1892 if (e1
->netmask
== e2
->netmask
)
1901 struct prefixlist
*labellist
= NULL
;
1902 size_t nlabellist
= 0;
1903 bool labellist_nullbits
= false;
1904 struct prefixlist
*precedencelist
= NULL
;
1905 size_t nprecedencelist
= 0;
1906 bool precedencelist_nullbits
= false;
1907 struct scopelist
*scopelist
= NULL
;
1908 size_t nscopelist
= 0;
1909 bool scopelist_nullbits
= false;
1911 FILE *fp
= fopen (GAICONF_FNAME
, "rce");
1915 if (__fxstat64 (_STAT_VER
, fileno (fp
), &st
) != 0)
1924 __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
1926 while (!feof_unlocked (fp
))
1928 ssize_t n
= __getline (&line
, &linelen
, fp
);
1932 /* Handle comments. No escaping possible so this is easy. */
1933 char *cp
= strchr (line
, '#');
1938 while (isspace (*cp
))
1942 while (*cp
!= '\0' && !isspace (*cp
))
1944 size_t cmdlen
= cp
- cmd
;
1948 while (isspace (*cp
))
1952 while (*cp
!= '\0' && !isspace (*cp
))
1954 size_t val1len
= cp
- cmd
;
1956 /* We always need at least two values. */
1962 while (isspace (*cp
))
1966 while (*cp
!= '\0' && !isspace (*cp
))
1969 /* Ignore the rest of the line. */
1972 struct prefixlist
**listp
;
1978 if (strcmp (cmd
, "label") == 0)
1980 struct in6_addr prefix
;
1981 unsigned long int bits
;
1982 unsigned long int val
;
1987 nullbitsp
= &labellist_nullbits
;
1992 cp
= strchr (val1
, '/');
1995 if (inet_pton (AF_INET6
, val1
, &prefix
)
1997 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
2001 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
2006 struct prefixlist
*newp
= malloc (sizeof (*newp
));
2014 memcpy (&newp
->entry
.prefix
, &prefix
, sizeof (prefix
));
2015 newp
->entry
.bits
= bits
;
2016 newp
->entry
.val
= val
;
2017 newp
->next
= *listp
;
2020 *nullbitsp
|= bits
== 0;
2026 if (strcmp (cmd
, "reload") == 0)
2028 gaiconf_reload_flag
= strcmp (val1
, "yes") == 0;
2029 if (gaiconf_reload_flag
)
2030 gaiconf_reload_flag_ever_set
= 1;
2035 if (strcmp (cmd
, "scopev4") == 0)
2037 struct in6_addr prefix
;
2038 unsigned long int bits
;
2039 unsigned long int val
;
2044 cp
= strchr (val1
, '/');
2047 if (inet_pton (AF_INET6
, val1
, &prefix
))
2050 if (IN6_IS_ADDR_V4MAPPED (&prefix
)
2052 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
2057 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
2062 struct scopelist
*newp
;
2064 newp
= malloc (sizeof (*newp
));
2072 newp
->entry
.netmask
= htonl (bits
!= 96
2076 newp
->entry
.addr32
= (prefix
.s6_addr32
[3]
2077 & newp
->entry
.netmask
);
2078 newp
->entry
.scope
= val
;
2079 newp
->next
= scopelist
;
2082 scopelist_nullbits
|= bits
== 96;
2085 else if (inet_pton (AF_INET
, val1
, &prefix
.s6_addr32
[3])
2087 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
2091 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
2103 if (strcmp (cmd
, "precedence") == 0)
2105 listp
= &precedencelist
;
2106 lenp
= &nprecedencelist
;
2107 nullbitsp
= &precedencelist_nullbits
;
2118 /* Create the array for the labels. */
2119 struct prefixentry
*new_labels
;
2122 if (!labellist_nullbits
)
2124 new_labels
= malloc (nlabellist
* sizeof (*new_labels
));
2125 if (new_labels
== NULL
)
2129 if (!labellist_nullbits
)
2132 memset (&new_labels
[i
].prefix
, '\0', sizeof (struct in6_addr
));
2133 new_labels
[i
].bits
= 0;
2134 new_labels
[i
].val
= 1;
2137 struct prefixlist
*l
= labellist
;
2140 new_labels
[i
] = l
->entry
;
2143 free_prefixlist (labellist
);
2145 /* Sort the entries so that the most specific ones are at
2147 qsort (new_labels
, nlabellist
, sizeof (*new_labels
), prefixcmp
);
2150 new_labels
= (struct prefixentry
*) default_labels
;
2152 struct prefixentry
*new_precedence
;
2153 if (nprecedencelist
> 0)
2155 if (!precedencelist_nullbits
)
2157 new_precedence
= malloc (nprecedencelist
* sizeof (*new_precedence
));
2158 if (new_precedence
== NULL
)
2160 if (new_labels
!= default_labels
)
2165 int i
= nprecedencelist
;
2166 if (!precedencelist_nullbits
)
2169 memset (&new_precedence
[i
].prefix
, '\0',
2170 sizeof (struct in6_addr
));
2171 new_precedence
[i
].bits
= 0;
2172 new_precedence
[i
].val
= 40;
2175 struct prefixlist
*l
= precedencelist
;
2178 new_precedence
[i
] = l
->entry
;
2181 free_prefixlist (precedencelist
);
2183 /* Sort the entries so that the most specific ones are at
2185 qsort (new_precedence
, nprecedencelist
, sizeof (*new_precedence
),
2189 new_precedence
= (struct prefixentry
*) default_precedence
;
2191 struct scopeentry
*new_scopes
;
2194 if (!scopelist_nullbits
)
2196 new_scopes
= malloc (nscopelist
* sizeof (*new_scopes
));
2197 if (new_scopes
== NULL
)
2199 if (new_labels
!= default_labels
)
2201 if (new_precedence
!= default_precedence
)
2202 free (new_precedence
);
2207 if (!scopelist_nullbits
)
2210 new_scopes
[i
].addr32
= 0;
2211 new_scopes
[i
].netmask
= 0;
2212 new_scopes
[i
].scope
= 14;
2215 struct scopelist
*l
= scopelist
;
2218 new_scopes
[i
] = l
->entry
;
2221 free_scopelist (scopelist
);
2223 /* Sort the entries so that the most specific ones are at
2225 qsort (new_scopes
, nscopelist
, sizeof (*new_scopes
),
2229 new_scopes
= (struct scopeentry
*) default_scopes
;
2231 /* Now we are ready to replace the values. */
2232 const struct prefixentry
*old
= labels
;
2233 labels
= new_labels
;
2234 if (old
!= default_labels
)
2235 free ((void *) old
);
2238 precedence
= new_precedence
;
2239 if (old
!= default_precedence
)
2240 free ((void *) old
);
2242 const struct scopeentry
*oldscope
= scopes
;
2243 scopes
= new_scopes
;
2244 if (oldscope
!= default_scopes
)
2245 free ((void *) oldscope
);
2247 save_gaiconf_mtime (&st
);
2252 free_prefixlist (labellist
);
2253 free_prefixlist (precedencelist
);
2254 free_scopelist (scopelist
);
2256 /* If we previously read the file but it is gone now, free the
2257 old data and use the builtin one. Leave the reload flag
2265 gaiconf_reload (void)
2268 if (__xstat64 (_STAT_VER
, GAICONF_FNAME
, &st
) != 0
2269 || !check_gaiconf_mtime (&st
))
2275 getaddrinfo (const char *name
, const char *service
,
2276 const struct addrinfo
*hints
, struct addrinfo
**pai
)
2278 int i
= 0, last_i
= 0;
2280 struct addrinfo
*p
= NULL
;
2281 struct gaih_service gaih_service
, *pservice
;
2282 struct addrinfo local_hints
;
2284 if (name
!= NULL
&& name
[0] == '*' && name
[1] == 0)
2287 if (service
!= NULL
&& service
[0] == '*' && service
[1] == 0)
2290 if (name
== NULL
&& service
== NULL
)
2294 hints
= &default_hints
;
2297 & ~(AI_PASSIVE
|AI_CANONNAME
|AI_NUMERICHOST
|AI_ADDRCONFIG
|AI_V4MAPPED
2299 |AI_IDN
|AI_CANONIDN
|AI_IDN_ALLOW_UNASSIGNED
2300 |AI_IDN_USE_STD3_ASCII_RULES
2302 |AI_NUMERICSERV
|AI_ALL
))
2303 return EAI_BADFLAGS
;
2305 if ((hints
->ai_flags
& AI_CANONNAME
) && name
== NULL
)
2306 return EAI_BADFLAGS
;
2308 struct in6addrinfo
*in6ai
= NULL
;
2309 size_t in6ailen
= 0;
2310 bool seen_ipv4
= false;
2311 bool seen_ipv6
= false;
2312 bool check_pf_called
= false;
2314 if (hints
->ai_flags
& AI_ADDRCONFIG
)
2316 /* We might need information about what interfaces are available.
2317 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2318 cannot cache the results since new interfaces could be added at
2320 __check_pf (&seen_ipv4
, &seen_ipv6
, &in6ai
, &in6ailen
);
2321 check_pf_called
= true;
2323 /* Now make a decision on what we return, if anything. */
2324 if (hints
->ai_family
== PF_UNSPEC
&& (seen_ipv4
|| seen_ipv6
))
2326 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2327 narrow down the search. */
2328 if ((! seen_ipv4
|| ! seen_ipv6
) && (seen_ipv4
|| seen_ipv6
))
2330 local_hints
= *hints
;
2331 local_hints
.ai_family
= seen_ipv4
? PF_INET
: PF_INET6
;
2332 hints
= &local_hints
;
2335 else if ((hints
->ai_family
== PF_INET
&& ! seen_ipv4
)
2336 || (hints
->ai_family
== PF_INET6
&& ! seen_ipv6
))
2338 /* We cannot possibly return a valid answer. */
2339 __free_in6ai (in6ai
);
2344 if (service
&& service
[0])
2347 gaih_service
.name
= service
;
2348 gaih_service
.num
= strtoul (gaih_service
.name
, &c
, 10);
2351 if (hints
->ai_flags
& AI_NUMERICSERV
)
2353 __free_in6ai (in6ai
);
2357 gaih_service
.num
= -1;
2360 pservice
= &gaih_service
;
2365 struct addrinfo
**end
= &p
;
2367 unsigned int naddrs
= 0;
2368 if (hints
->ai_family
== AF_UNSPEC
|| hints
->ai_family
== AF_INET
2369 || hints
->ai_family
== AF_INET6
)
2371 struct scratch_buffer tmpbuf
;
2372 scratch_buffer_init (&tmpbuf
);
2373 last_i
= gaih_inet (name
, pservice
, hints
, end
, &naddrs
, &tmpbuf
);
2374 scratch_buffer_free (&tmpbuf
);
2379 __free_in6ai (in6ai
);
2385 end
= &((*end
)->ai_next
);
2391 __free_in6ai (in6ai
);
2397 /* Read the config file. */
2398 __libc_once_define (static, once
);
2399 __typeof (once
) old_once
= once
;
2400 __libc_once (once
, gaiconf_init
);
2401 /* Sort results according to RFC 3484. */
2402 struct sort_result
*results
;
2405 struct addrinfo
*last
= NULL
;
2406 char *canonname
= NULL
;
2407 bool malloc_results
;
2408 size_t alloc_size
= nresults
* (sizeof (*results
) + sizeof (size_t));
2411 = !__libc_use_alloca (alloc_size
);
2414 results
= malloc (alloc_size
);
2415 if (results
== NULL
)
2417 __free_in6ai (in6ai
);
2422 results
= alloca (alloc_size
);
2423 order
= (size_t *) (results
+ nresults
);
2425 /* Now we definitely need the interface information. */
2426 if (! check_pf_called
)
2427 __check_pf (&seen_ipv4
, &seen_ipv6
, &in6ai
, &in6ailen
);
2429 /* If we have information about deprecated and temporary addresses
2430 sort the array now. */
2432 qsort (in6ai
, in6ailen
, sizeof (*in6ai
), in6aicmp
);
2437 for (i
= 0, q
= p
; q
!= NULL
; ++i
, last
= q
, q
= q
->ai_next
)
2439 results
[i
].dest_addr
= q
;
2440 results
[i
].native
= -1;
2443 /* If we just looked up the address for a different
2444 protocol, reuse the result. */
2445 if (last
!= NULL
&& last
->ai_addrlen
== q
->ai_addrlen
2446 && memcmp (last
->ai_addr
, q
->ai_addr
, q
->ai_addrlen
) == 0)
2448 memcpy (&results
[i
].source_addr
, &results
[i
- 1].source_addr
,
2449 results
[i
- 1].source_addr_len
);
2450 results
[i
].source_addr_len
= results
[i
- 1].source_addr_len
;
2451 results
[i
].got_source_addr
= results
[i
- 1].got_source_addr
;
2452 results
[i
].source_addr_flags
= results
[i
- 1].source_addr_flags
;
2453 results
[i
].prefixlen
= results
[i
- 1].prefixlen
;
2454 results
[i
].index
= results
[i
- 1].index
;
2458 results
[i
].got_source_addr
= false;
2459 results
[i
].source_addr_flags
= 0;
2460 results
[i
].prefixlen
= 0;
2461 results
[i
].index
= 0xffffffffu
;
2463 /* We overwrite the type with SOCK_DGRAM since we do not
2464 want connect() to connect to the other side. If we
2465 cannot determine the source address remember this
2467 if (fd
== -1 || (af
== AF_INET
&& q
->ai_family
== AF_INET6
))
2471 close_not_cancel_no_status (fd
);
2473 fd
= __socket (af
, SOCK_DGRAM
, IPPROTO_IP
);
2477 /* Reset the connection. */
2478 struct sockaddr sa
= { .sa_family
= AF_UNSPEC
};
2479 __connect (fd
, &sa
, sizeof (sa
));
2482 socklen_t sl
= sizeof (results
[i
].source_addr
);
2484 && __connect (fd
, q
->ai_addr
, q
->ai_addrlen
) == 0
2485 && __getsockname (fd
,
2486 (struct sockaddr
*) &results
[i
].source_addr
,
2489 results
[i
].source_addr_len
= sl
;
2490 results
[i
].got_source_addr
= true;
2494 /* See whether the source address is on the list of
2495 deprecated or temporary addresses. */
2496 struct in6addrinfo tmp
;
2498 if (q
->ai_family
== AF_INET
&& af
== AF_INET
)
2500 struct sockaddr_in
*sinp
2501 = (struct sockaddr_in
*) &results
[i
].source_addr
;
2504 tmp
.addr
[2] = htonl (0xffff);
2505 /* Special case for lo interface, the source address
2506 being possibly different than the interface
2508 if ((ntohl(sinp
->sin_addr
.s_addr
) & 0xff000000)
2510 tmp
.addr
[3] = htonl(0x7f000001);
2512 tmp
.addr
[3] = sinp
->sin_addr
.s_addr
;
2516 struct sockaddr_in6
*sin6p
2517 = (struct sockaddr_in6
*) &results
[i
].source_addr
;
2518 memcpy (tmp
.addr
, &sin6p
->sin6_addr
, IN6ADDRSZ
);
2521 struct in6addrinfo
*found
2522 = bsearch (&tmp
, in6ai
, in6ailen
, sizeof (*in6ai
),
2526 results
[i
].source_addr_flags
= found
->flags
;
2527 results
[i
].prefixlen
= found
->prefixlen
;
2528 results
[i
].index
= found
->index
;
2532 if (q
->ai_family
== AF_INET
&& af
== AF_INET6
)
2534 /* We have to convert the address. The socket is
2535 IPv6 and the request is for IPv4. */
2536 struct sockaddr_in6
*sin6
2537 = (struct sockaddr_in6
*) &results
[i
].source_addr
;
2538 struct sockaddr_in
*sin
2539 = (struct sockaddr_in
*) &results
[i
].source_addr
;
2540 assert (IN6_IS_ADDR_V4MAPPED (sin6
->sin6_addr
.s6_addr32
));
2541 sin
->sin_family
= AF_INET
;
2542 /* We do not have to initialize sin_port since this
2543 fields has the same position and size in the IPv6
2545 assert (offsetof (struct sockaddr_in
, sin_port
)
2546 == offsetof (struct sockaddr_in6
, sin6_port
));
2547 assert (sizeof (sin
->sin_port
)
2548 == sizeof (sin6
->sin6_port
));
2549 memcpy (&sin
->sin_addr
,
2550 &sin6
->sin6_addr
.s6_addr32
[3], INADDRSZ
);
2551 results
[i
].source_addr_len
= sizeof (struct sockaddr_in
);
2554 else if (errno
== EAFNOSUPPORT
&& af
== AF_INET6
2555 && q
->ai_family
== AF_INET
)
2556 /* This could mean IPv6 sockets are IPv6-only. */
2559 /* Just make sure that if we have to process the same
2560 address again we do not copy any memory. */
2561 results
[i
].source_addr_len
= 0;
2564 /* Remember the canonical name. */
2565 if (q
->ai_canonname
!= NULL
)
2567 assert (canonname
== NULL
);
2568 canonname
= q
->ai_canonname
;
2569 q
->ai_canonname
= NULL
;
2574 close_not_cancel_no_status (fd
);
2576 /* We got all the source addresses we can get, now sort using
2578 struct sort_result_combo src
2579 = { .results
= results
, .nresults
= nresults
};
2580 if (__glibc_unlikely (gaiconf_reload_flag_ever_set
))
2582 __libc_lock_define_initialized (static, lock
);
2584 __libc_lock_lock (lock
);
2585 if (__libc_once_get (old_once
) && gaiconf_reload_flag
)
2587 __qsort_r (order
, nresults
, sizeof (order
[0]), rfc3484_sort
, &src
);
2588 __libc_lock_unlock (lock
);
2591 __qsort_r (order
, nresults
, sizeof (order
[0]), rfc3484_sort
, &src
);
2593 /* Queue the results up as they come out of sorting. */
2594 q
= p
= results
[order
[0]].dest_addr
;
2595 for (i
= 1; i
< nresults
; ++i
)
2596 q
= q
->ai_next
= results
[order
[i
]].dest_addr
;
2599 /* Fill in the canonical name into the new first entry. */
2600 p
->ai_canonname
= canonname
;
2606 __free_in6ai (in6ai
);
2614 return last_i
? -last_i
: EAI_NONAME
;
2616 libc_hidden_def (getaddrinfo
)
2618 nss_interface_function (getaddrinfo
)
2621 freeaddrinfo (struct addrinfo
*ai
)
2629 free (p
->ai_canonname
);
2633 libc_hidden_def (freeaddrinfo
)