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>
63 #include <resolv/resolv_context.h>
64 #include <resolv/res_use_inet6.h>
67 #include <stdio_ext.h>
71 #include <arpa/inet.h>
73 #include <netinet/in.h>
74 #include <sys/socket.h>
76 #include <sys/types.h>
78 #include <sys/utsname.h>
81 #include <libc-lock.h>
82 #include <not-cancel.h>
83 #include <nscd/nscd-client.h>
84 #include <nscd/nscd_proto.h>
85 #include <scratch_buffer.h>
86 #include <inet/net-internal.h>
89 extern int __idna_to_ascii_lz (const char *input
, char **output
, int flags
);
90 extern int __idna_to_unicode_lzlz (const char *input
, char **output
,
92 # include <libidn/idna.h>
101 struct gaih_servtuple
103 struct gaih_servtuple
*next
;
109 static const struct gaih_servtuple nullserv
;
112 struct gaih_typeproto
121 /* Values for `protoflag'. */
122 #define GAI_PROTO_NOSERVICE 1
123 #define GAI_PROTO_PROTOANY 2
125 static const struct gaih_typeproto gaih_inet_typeproto
[] =
127 { 0, 0, 0, false, "" },
128 { SOCK_STREAM
, IPPROTO_TCP
, 0, true, "tcp" },
129 { SOCK_DGRAM
, IPPROTO_UDP
, 0, true, "udp" },
130 #if defined SOCK_DCCP && defined IPPROTO_DCCP
131 { SOCK_DCCP
, IPPROTO_DCCP
, 0, false, "dccp" },
133 #ifdef IPPROTO_UDPLITE
134 { SOCK_DGRAM
, IPPROTO_UDPLITE
, 0, false, "udplite" },
137 { SOCK_STREAM
, IPPROTO_SCTP
, 0, false, "sctp" },
138 { SOCK_SEQPACKET
, IPPROTO_SCTP
, 0, false, "sctp" },
140 { SOCK_RAW
, 0, GAI_PROTO_PROTOANY
|GAI_PROTO_NOSERVICE
, true, "raw" },
141 { 0, 0, 0, false, "" }
144 static const struct addrinfo default_hints
=
146 .ai_flags
= AI_DEFAULT
,
147 .ai_family
= PF_UNSPEC
,
152 .ai_canonname
= NULL
,
158 gaih_inet_serv (const char *servicename
, const struct gaih_typeproto
*tp
,
159 const struct addrinfo
*req
, struct gaih_servtuple
*st
,
160 struct scratch_buffer
*tmpbuf
)
168 r
= __getservbyname_r (servicename
, tp
->name
, &ts
,
169 tmpbuf
->data
, tmpbuf
->length
, &s
);
170 if (r
!= 0 || s
== NULL
)
174 if (!scratch_buffer_grow (tmpbuf
))
184 st
->socktype
= tp
->socktype
;
185 st
->protocol
= ((tp
->protoflag
& GAI_PROTO_PROTOANY
)
186 ? req
->ai_protocol
: tp
->protocol
);
187 st
->port
= s
->s_port
;
192 /* Convert struct hostent to a list of struct gaih_addrtuple objects.
193 h_name is not copied, and the struct hostent object must not be
194 deallocated prematurely. *RESULT must be NULL or a pointer to a
195 linked-list. The new addresses are appended at the end. */
197 convert_hostent_to_gaih_addrtuple (const struct addrinfo
*req
,
200 struct gaih_addrtuple
**result
)
203 result
= &(*result
)->next
;
205 /* Count the number of addresses in h->h_addr_list. */
207 for (char **p
= h
->h_addr_list
; *p
!= NULL
; ++p
)
210 /* Report no data if no addresses are available, or if the incoming
211 address size is larger than what we can store. */
212 if (count
== 0 || h
->h_length
> sizeof (((struct gaih_addrtuple
) {}).addr
))
215 struct gaih_addrtuple
*array
= calloc (count
, sizeof (*array
));
219 for (size_t i
= 0; i
< count
; ++i
)
221 if (family
== AF_INET
&& req
->ai_family
== AF_INET6
)
223 /* Perform address mapping. */
224 array
[i
].family
= AF_INET6
;
225 memcpy(array
[i
].addr
+ 3, h
->h_addr_list
[i
], sizeof (uint32_t));
226 array
[i
].addr
[2] = htonl (0xffff);
230 array
[i
].family
= family
;
231 memcpy (array
[i
].addr
, h
->h_addr_list
[i
], h
->h_length
);
233 array
[i
].next
= array
+ i
+ 1;
235 array
[0].name
= h
->h_name
;
236 array
[count
- 1].next
= NULL
;
242 #define gethosts(_family, _type) \
246 char *localcanon = NULL; \
249 status = DL_CALL_FCT (fct, (name, _family, &th, \
250 tmpbuf->data, tmpbuf->length, \
251 &errno, &h_errno, NULL, &localcanon)); \
252 if (errno != ERANGE || h_errno != NETDB_INTERNAL) \
254 if (!scratch_buffer_grow (tmpbuf)) \
256 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
257 __resolv_context_put (res_ctx); \
258 result = -EAI_MEMORY; \
259 goto free_and_return; \
262 if (status == NSS_STATUS_SUCCESS && errno == 0) \
268 if (h_errno == NETDB_INTERNAL) \
270 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
271 __resolv_context_put (res_ctx); \
272 result = -EAI_SYSTEM; \
273 goto free_and_return; \
275 if (h_errno == TRY_AGAIN) \
276 no_data = EAI_AGAIN; \
278 no_data = h_errno == NO_DATA; \
280 else if (h != NULL) \
282 if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \
284 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
285 __resolv_context_put (res_ctx); \
286 result = -EAI_SYSTEM; \
287 goto free_and_return; \
291 if (localcanon != NULL && canon == NULL) \
293 canonbuf = __strdup (localcanon); \
294 if (canonbuf == NULL) \
296 result = -EAI_SYSTEM; \
297 goto free_and_return; \
301 if (_family == AF_INET6 && *pat != NULL) \
307 typedef enum nss_status (*nss_gethostbyname4_r
)
308 (const char *name
, struct gaih_addrtuple
**pat
,
309 char *buffer
, size_t buflen
, int *errnop
,
310 int *h_errnop
, int32_t *ttlp
);
311 typedef enum nss_status (*nss_gethostbyname3_r
)
312 (const char *name
, int af
, struct hostent
*host
,
313 char *buffer
, size_t buflen
, int *errnop
,
314 int *h_errnop
, int32_t *ttlp
, char **canonp
);
315 typedef enum nss_status (*nss_getcanonname_r
)
316 (const char *name
, char *buffer
, size_t buflen
, char **result
,
317 int *errnop
, int *h_errnop
);
319 /* This function is called if a canonical name is requested, but if
320 the service function did not provide it. It tries to obtain the
321 name using getcanonname_r from the same service NIP. If the name
322 cannot be canonicalized, return a copy of NAME. Return NULL on
323 memory allocation failure. The returned string is allocated on the
324 heap; the caller has to free it. */
326 getcanonname (service_user
*nip
, struct gaih_addrtuple
*at
, const char *name
)
328 nss_getcanonname_r cfct
= __nss_lookup_function (nip
, "getcanonname_r");
329 char *s
= (char *) name
;
333 if (DL_CALL_FCT (cfct
, (at
->name
?: name
, buf
, sizeof (buf
),
334 &s
, &errno
, &h_errno
)) != NSS_STATUS_SUCCESS
)
335 /* If the canonical name cannot be determined, use the passed
339 return __strdup (name
);
343 gaih_inet (const char *name
, const struct gaih_service
*service
,
344 const struct addrinfo
*req
, struct addrinfo
**pai
,
345 unsigned int *naddrs
, struct scratch_buffer
*tmpbuf
)
347 const struct gaih_typeproto
*tp
= gaih_inet_typeproto
;
348 struct gaih_servtuple
*st
= (struct gaih_servtuple
*) &nullserv
;
349 struct gaih_addrtuple
*at
= NULL
;
350 bool got_ipv6
= false;
351 const char *canon
= NULL
;
352 const char *orig_name
= name
;
354 /* Reserve stack memory for the scratch buffer in the getaddrinfo
356 size_t alloca_used
= sizeof (struct scratch_buffer
);
358 if (req
->ai_protocol
|| req
->ai_socktype
)
363 && ((req
->ai_socktype
!= 0 && req
->ai_socktype
!= tp
->socktype
)
364 || (req
->ai_protocol
!= 0
365 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
366 && req
->ai_protocol
!= tp
->protocol
)))
371 if (req
->ai_socktype
)
372 return -EAI_SOCKTYPE
;
381 if ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0)
384 if (service
->num
< 0)
388 st
= (struct gaih_servtuple
*)
389 alloca_account (sizeof (struct gaih_servtuple
), alloca_used
);
391 int rc
= gaih_inet_serv (service
->name
, tp
, req
, st
, tmpbuf
);
392 if (__glibc_unlikely (rc
!= 0))
397 struct gaih_servtuple
**pst
= &st
;
398 for (tp
++; tp
->name
[0]; tp
++)
400 struct gaih_servtuple
*newp
;
402 if ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0)
405 if (req
->ai_socktype
!= 0
406 && req
->ai_socktype
!= tp
->socktype
)
408 if (req
->ai_protocol
!= 0
409 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
410 && req
->ai_protocol
!= tp
->protocol
)
413 newp
= (struct gaih_servtuple
*)
414 alloca_account (sizeof (struct gaih_servtuple
),
417 if (gaih_inet_serv (service
->name
,
418 tp
, req
, newp
, tmpbuf
) != 0)
424 if (st
== (struct gaih_servtuple
*) &nullserv
)
430 port
= htons (service
->num
);
438 if (req
->ai_socktype
|| req
->ai_protocol
)
440 st
= alloca_account (sizeof (struct gaih_servtuple
), alloca_used
);
442 st
->socktype
= tp
->socktype
;
443 st
->protocol
= ((tp
->protoflag
& GAI_PROTO_PROTOANY
)
444 ? req
->ai_protocol
: tp
->protocol
);
449 /* Neither socket type nor protocol is set. Return all socket types
451 struct gaih_servtuple
**lastp
= &st
;
452 for (++tp
; tp
->name
[0]; ++tp
)
455 struct gaih_servtuple
*newp
;
457 newp
= alloca_account (sizeof (struct gaih_servtuple
),
460 newp
->socktype
= tp
->socktype
;
461 newp
->protocol
= tp
->protocol
;
470 bool malloc_name
= false;
471 struct gaih_addrtuple
*addrmem
= NULL
;
472 char *canonbuf
= NULL
;
477 at
= alloca_account (sizeof (struct gaih_addrtuple
), alloca_used
);
478 at
->family
= AF_UNSPEC
;
483 if (req
->ai_flags
& AI_IDN
)
486 if (req
->ai_flags
& AI_IDN_ALLOW_UNASSIGNED
)
487 idn_flags
|= IDNA_ALLOW_UNASSIGNED
;
488 if (req
->ai_flags
& AI_IDN_USE_STD3_ASCII_RULES
)
489 idn_flags
|= IDNA_USE_STD3_ASCII_RULES
;
492 int rc
= __idna_to_ascii_lz (name
, &p
, idn_flags
);
493 if (rc
!= IDNA_SUCCESS
)
495 /* No need to jump to free_and_return here. */
496 if (rc
== IDNA_MALLOC_ERROR
)
498 if (rc
== IDNA_DLOPEN_ERROR
)
500 return -EAI_IDN_ENCODE
;
502 /* In case the output string is the same as the input string
503 no new string has been allocated. */
512 if (__inet_aton (name
, (struct in_addr
*) at
->addr
) != 0)
514 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET
)
515 at
->family
= AF_INET
;
516 else if (req
->ai_family
== AF_INET6
&& (req
->ai_flags
& AI_V4MAPPED
))
518 at
->addr
[3] = at
->addr
[0];
519 at
->addr
[2] = htonl (0xffff);
522 at
->family
= AF_INET6
;
526 result
= -EAI_ADDRFAMILY
;
527 goto free_and_return
;
530 if (req
->ai_flags
& AI_CANONNAME
)
533 else if (at
->family
== AF_UNSPEC
)
535 char *scope_delim
= strchr (name
, SCOPE_DELIMITER
);
537 if (scope_delim
== NULL
)
538 e
= inet_pton (AF_INET6
, name
, at
->addr
);
540 e
= __inet_pton_length (AF_INET6
, name
, scope_delim
- name
,
544 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET6
)
545 at
->family
= AF_INET6
;
546 else if (req
->ai_family
== AF_INET
547 && IN6_IS_ADDR_V4MAPPED (at
->addr
))
549 at
->addr
[0] = at
->addr
[3];
550 at
->family
= AF_INET
;
554 result
= -EAI_ADDRFAMILY
;
555 goto free_and_return
;
558 if (scope_delim
!= NULL
559 && __inet6_scopeid_pton ((struct in6_addr
*) at
->addr
,
563 result
= -EAI_NONAME
;
564 goto free_and_return
;
567 if (req
->ai_flags
& AI_CANONNAME
)
572 if (at
->family
== AF_UNSPEC
&& (req
->ai_flags
& AI_NUMERICHOST
) == 0)
574 struct gaih_addrtuple
**pat
= &at
;
576 int no_inet6_data
= 0;
578 enum nss_status inet6_status
= NSS_STATUS_UNAVAIL
;
579 enum nss_status status
= NSS_STATUS_UNAVAIL
;
581 struct resolv_context
*res_ctx
= NULL
;
582 bool res_enable_inet6
= false;
584 /* If we do not have to look for IPv6 addresses or the canonical
585 name, use the simple, old functions, which do not support
586 IPv6 scope ids, nor retrieving the canonical name. */
587 if (req
->ai_family
== AF_INET
588 && (req
->ai_flags
& AI_CANONNAME
) == 0)
596 rc
= __gethostbyname2_r (name
, AF_INET
, &th
,
597 tmpbuf
->data
, tmpbuf
->length
,
599 if (rc
!= ERANGE
|| h_errno
!= NETDB_INTERNAL
)
601 if (!scratch_buffer_grow (tmpbuf
))
603 result
= -EAI_MEMORY
;
604 goto free_and_return
;
612 /* We found data, convert it. */
613 if (!convert_hostent_to_gaih_addrtuple
614 (req
, AF_INET
, h
, &addrmem
))
616 result
= -EAI_MEMORY
;
617 goto free_and_return
;
624 if (h_errno
== NETDB_INTERNAL
)
625 result
= -EAI_SYSTEM
;
626 else if (h_errno
== TRY_AGAIN
)
629 /* We made requests but they turned out no data.
630 The name is known, though. */
631 result
= -EAI_NODATA
;
633 goto free_and_return
;
640 if (__nss_not_use_nscd_hosts
> 0
641 && ++__nss_not_use_nscd_hosts
> NSS_NSCD_RETRY
)
642 __nss_not_use_nscd_hosts
= 0;
644 if (!__nss_not_use_nscd_hosts
645 && !__nss_database_custom
[NSS_DBSIDX_hosts
])
647 /* Try to use nscd. */
648 struct nscd_ai_result
*air
= NULL
;
649 int err
= __nscd_getai (name
, &air
, &h_errno
);
652 /* Transform into gaih_addrtuple list. */
653 bool added_canon
= (req
->ai_flags
& AI_CANONNAME
) == 0;
654 char *addrs
= air
->addrs
;
656 addrmem
= calloc (air
->naddrs
, sizeof (*addrmem
));
659 result
= -EAI_MEMORY
;
660 goto free_and_return
;
663 struct gaih_addrtuple
*addrfree
= addrmem
;
664 for (int i
= 0; i
< air
->naddrs
; ++i
)
666 socklen_t size
= (air
->family
[i
] == AF_INET
667 ? INADDRSZ
: IN6ADDRSZ
);
669 if (!((air
->family
[i
] == AF_INET
670 && req
->ai_family
== AF_INET6
671 && (req
->ai_flags
& AI_V4MAPPED
) != 0)
672 || req
->ai_family
== AF_UNSPEC
673 || air
->family
[i
] == req
->ai_family
))
675 /* Skip over non-matching result. */
685 uint32_t *pataddr
= (*pat
)->addr
;
687 if (added_canon
|| air
->canon
== NULL
)
689 else if (canonbuf
== NULL
)
691 canonbuf
= __strdup (air
->canon
);
692 if (canonbuf
== NULL
)
694 result
= -EAI_MEMORY
;
695 goto free_and_return
;
697 canon
= (*pat
)->name
= canonbuf
;
700 if (air
->family
[i
] == AF_INET
701 && req
->ai_family
== AF_INET6
702 && (req
->ai_flags
& AI_V4MAPPED
))
704 (*pat
)->family
= AF_INET6
;
705 pataddr
[3] = *(uint32_t *) addrs
;
706 pataddr
[2] = htonl (0xffff);
709 pat
= &((*pat
)->next
);
712 else if (req
->ai_family
== AF_UNSPEC
713 || air
->family
[i
] == req
->ai_family
)
715 (*pat
)->family
= air
->family
[i
];
716 memcpy (pataddr
, addrs
, size
);
717 pat
= &((*pat
)->next
);
719 if (air
->family
[i
] == AF_INET6
)
727 if (at
->family
== AF_UNSPEC
)
729 result
= -EAI_NONAME
;
730 goto free_and_return
;
736 /* The database contains a negative entry. */
737 goto free_and_return
;
738 else if (__nss_not_use_nscd_hosts
== 0)
740 if (h_errno
== NETDB_INTERNAL
&& errno
== ENOMEM
)
741 result
= -EAI_MEMORY
;
742 else if (h_errno
== TRY_AGAIN
)
745 result
= -EAI_SYSTEM
;
747 goto free_and_return
;
752 if (__nss_hosts_database
== NULL
)
753 no_more
= __nss_database_lookup ("hosts", NULL
,
754 "dns [!UNAVAIL=return] files",
755 &__nss_hosts_database
);
758 nip
= __nss_hosts_database
;
760 /* If we are looking for both IPv4 and IPv6 address we don't
761 want the lookup functions to automatically promote IPv4
762 addresses to IPv6 addresses, so we use the no_inet6
764 res_ctx
= __resolv_context_get ();
765 res_enable_inet6
= __resolv_context_disable_inet6 (res_ctx
);
772 nss_gethostbyname4_r fct4
= NULL
;
774 /* gethostbyname4_r sends out parallel A and AAAA queries and
775 is thus only suitable for PF_UNSPEC. */
776 if (req
->ai_family
== PF_UNSPEC
)
777 fct4
= __nss_lookup_function (nip
, "gethostbyname4_r");
783 status
= DL_CALL_FCT (fct4
, (name
, pat
,
784 tmpbuf
->data
, tmpbuf
->length
,
787 if (status
== NSS_STATUS_SUCCESS
)
789 if (status
!= NSS_STATUS_TRYAGAIN
790 || errno
!= ERANGE
|| h_errno
!= NETDB_INTERNAL
)
792 if (h_errno
== TRY_AGAIN
)
795 no_data
= h_errno
== NO_DATA
;
799 if (!scratch_buffer_grow (tmpbuf
))
801 __resolv_context_enable_inet6
802 (res_ctx
, res_enable_inet6
);
803 __resolv_context_put (res_ctx
);
804 result
= -EAI_MEMORY
;
805 goto free_and_return
;
809 if (status
== NSS_STATUS_SUCCESS
)
814 if ((req
->ai_flags
& AI_CANONNAME
) != 0 && canon
== NULL
)
815 canon
= (*pat
)->name
;
819 if ((*pat
)->family
== AF_INET
820 && req
->ai_family
== AF_INET6
821 && (req
->ai_flags
& AI_V4MAPPED
) != 0)
823 uint32_t *pataddr
= (*pat
)->addr
;
824 (*pat
)->family
= AF_INET6
;
825 pataddr
[3] = pataddr
[0];
826 pataddr
[2] = htonl (0xffff);
829 pat
= &((*pat
)->next
);
832 else if (req
->ai_family
== AF_UNSPEC
833 || (*pat
)->family
== req
->ai_family
)
835 pat
= &((*pat
)->next
);
838 if (req
->ai_family
== AF_INET6
)
842 *pat
= ((*pat
)->next
);
846 no_inet6_data
= no_data
;
850 nss_gethostbyname3_r fct
= NULL
;
851 if (req
->ai_flags
& AI_CANONNAME
)
852 /* No need to use this function if we do not look for
853 the canonical name. The function does not exist in
854 all NSS modules and therefore the lookup would
856 fct
= __nss_lookup_function (nip
, "gethostbyname3_r");
858 /* We are cheating here. The gethostbyname2_r
859 function does not have the same interface as
860 gethostbyname3_r but the extra arguments the
861 latter takes are added at the end. So the
862 gethostbyname2_r code will just ignore them. */
863 fct
= __nss_lookup_function (nip
, "gethostbyname2_r");
867 if (req
->ai_family
== AF_INET6
868 || req
->ai_family
== AF_UNSPEC
)
870 gethosts (AF_INET6
, struct in6_addr
);
871 no_inet6_data
= no_data
;
872 inet6_status
= status
;
874 if (req
->ai_family
== AF_INET
875 || req
->ai_family
== AF_UNSPEC
876 || (req
->ai_family
== AF_INET6
877 && (req
->ai_flags
& AI_V4MAPPED
)
878 /* Avoid generating the mapped addresses if we
879 know we are not going to need them. */
880 && ((req
->ai_flags
& AI_ALL
) || !got_ipv6
)))
882 gethosts (AF_INET
, struct in_addr
);
884 if (req
->ai_family
== AF_INET
)
886 no_inet6_data
= no_data
;
887 inet6_status
= status
;
891 /* If we found one address for AF_INET or AF_INET6,
892 don't continue the search. */
893 if (inet6_status
== NSS_STATUS_SUCCESS
894 || status
== NSS_STATUS_SUCCESS
)
896 if ((req
->ai_flags
& AI_CANONNAME
) != 0
899 canonbuf
= getcanonname (nip
, at
, name
);
900 if (canonbuf
== NULL
)
902 __resolv_context_enable_inet6
903 (res_ctx
, res_enable_inet6
);
904 __resolv_context_put (res_ctx
);
905 result
= -EAI_MEMORY
;
906 goto free_and_return
;
910 status
= NSS_STATUS_SUCCESS
;
914 /* We can have different states for AF_INET and
915 AF_INET6. Try to find a useful one for both. */
916 if (inet6_status
== NSS_STATUS_TRYAGAIN
)
917 status
= NSS_STATUS_TRYAGAIN
;
918 else if (status
== NSS_STATUS_UNAVAIL
919 && inet6_status
!= NSS_STATUS_UNAVAIL
)
920 status
= inet6_status
;
925 status
= NSS_STATUS_UNAVAIL
;
926 /* Could not load any of the lookup functions. Indicate
927 an internal error if the failure was due to a system
928 error other than the file not being found. We use the
929 errno from the last failed callback. */
930 if (errno
!= 0 && errno
!= ENOENT
)
931 __set_h_errno (NETDB_INTERNAL
);
935 if (nss_next_action (nip
, status
) == NSS_ACTION_RETURN
)
938 if (nip
->next
== NULL
)
944 __resolv_context_enable_inet6 (res_ctx
, res_enable_inet6
);
945 __resolv_context_put (res_ctx
);
947 if (h_errno
== NETDB_INTERNAL
)
949 result
= -EAI_SYSTEM
;
950 goto free_and_return
;
953 if (no_data
!= 0 && no_inet6_data
!= 0)
955 /* If both requests timed out report this. */
956 if (no_data
== EAI_AGAIN
&& no_inet6_data
== EAI_AGAIN
)
959 /* We made requests but they turned out no data. The name
961 result
= -EAI_NODATA
;
963 goto free_and_return
;
968 if (at
->family
== AF_UNSPEC
)
970 result
= -EAI_NONAME
;
971 goto free_and_return
;
976 struct gaih_addrtuple
*atr
;
977 atr
= at
= alloca_account (sizeof (struct gaih_addrtuple
), alloca_used
);
978 memset (at
, '\0', sizeof (struct gaih_addrtuple
));
980 if (req
->ai_family
== AF_UNSPEC
)
982 at
->next
= __alloca (sizeof (struct gaih_addrtuple
));
983 memset (at
->next
, '\0', sizeof (struct gaih_addrtuple
));
986 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET6
)
988 at
->family
= AF_INET6
;
989 if ((req
->ai_flags
& AI_PASSIVE
) == 0)
990 memcpy (at
->addr
, &in6addr_loopback
, sizeof (struct in6_addr
));
994 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET
)
996 atr
->family
= AF_INET
;
997 if ((req
->ai_flags
& AI_PASSIVE
) == 0)
998 atr
->addr
[0] = htonl (INADDR_LOOPBACK
);
1003 struct gaih_servtuple
*st2
;
1004 struct gaih_addrtuple
*at2
= at
;
1009 buffer is the size of an unformatted IPv6 address in printable format.
1013 /* Only the first entry gets the canonical name. */
1014 if (at2
== at
&& (req
->ai_flags
& AI_CANONNAME
) != 0)
1017 /* If the canonical name cannot be determined, use
1018 the passed in string. */
1022 if (req
->ai_flags
& AI_CANONIDN
)
1025 if (req
->ai_flags
& AI_IDN_ALLOW_UNASSIGNED
)
1026 idn_flags
|= IDNA_ALLOW_UNASSIGNED
;
1027 if (req
->ai_flags
& AI_IDN_USE_STD3_ASCII_RULES
)
1028 idn_flags
|= IDNA_USE_STD3_ASCII_RULES
;
1031 int rc
= __idna_to_unicode_lzlz (canon
, &out
, idn_flags
);
1032 if (rc
!= IDNA_SUCCESS
)
1034 if (rc
== IDNA_MALLOC_ERROR
)
1035 result
= -EAI_MEMORY
;
1036 else if (rc
== IDNA_DLOPEN_ERROR
)
1037 result
= -EAI_SYSTEM
;
1039 result
= -EAI_IDN_ENCODE
;
1040 goto free_and_return
;
1042 /* In case the output string is the same as the input
1043 string no new string has been allocated and we
1055 if (canonbuf
!= NULL
)
1056 /* We already allocated the string using malloc, but
1057 the buffer is now owned by canon. */
1061 canon
= __strdup (canon
);
1064 result
= -EAI_MEMORY
;
1065 goto free_and_return
;
1071 family
= at2
->family
;
1072 if (family
== AF_INET6
)
1074 socklen
= sizeof (struct sockaddr_in6
);
1076 /* If we looked up IPv4 mapped address discard them here if
1077 the caller isn't interested in all address and we have
1078 found at least one IPv6 address. */
1080 && (req
->ai_flags
& (AI_V4MAPPED
|AI_ALL
)) == AI_V4MAPPED
1081 && IN6_IS_ADDR_V4MAPPED (at2
->addr
))
1085 socklen
= sizeof (struct sockaddr_in
);
1087 for (st2
= st
; st2
!= NULL
; st2
= st2
->next
)
1089 struct addrinfo
*ai
;
1090 ai
= *pai
= malloc (sizeof (struct addrinfo
) + socklen
);
1093 free ((char *) canon
);
1094 result
= -EAI_MEMORY
;
1095 goto free_and_return
;
1098 ai
->ai_flags
= req
->ai_flags
;
1099 ai
->ai_family
= family
;
1100 ai
->ai_socktype
= st2
->socktype
;
1101 ai
->ai_protocol
= st2
->protocol
;
1102 ai
->ai_addrlen
= socklen
;
1103 ai
->ai_addr
= (void *) (ai
+ 1);
1105 /* We only add the canonical name once. */
1106 ai
->ai_canonname
= (char *) canon
;
1110 ai
->ai_addr
->sa_len
= socklen
;
1111 #endif /* _HAVE_SA_LEN */
1112 ai
->ai_addr
->sa_family
= family
;
1114 /* In case of an allocation error the list must be NULL
1118 if (family
== AF_INET6
)
1120 struct sockaddr_in6
*sin6p
=
1121 (struct sockaddr_in6
*) ai
->ai_addr
;
1123 sin6p
->sin6_port
= st2
->port
;
1124 sin6p
->sin6_flowinfo
= 0;
1125 memcpy (&sin6p
->sin6_addr
,
1126 at2
->addr
, sizeof (struct in6_addr
));
1127 sin6p
->sin6_scope_id
= at2
->scopeid
;
1131 struct sockaddr_in
*sinp
=
1132 (struct sockaddr_in
*) ai
->ai_addr
;
1133 sinp
->sin_port
= st2
->port
;
1134 memcpy (&sinp
->sin_addr
,
1135 at2
->addr
, sizeof (struct in_addr
));
1136 memset (sinp
->sin_zero
, '\0', sizeof (sinp
->sin_zero
));
1139 pai
= &(ai
->ai_next
);
1151 free ((char *) name
);
1161 struct addrinfo
*dest_addr
;
1162 /* Using sockaddr_storage is for now overkill. We only support IPv4
1163 and IPv6 so far. If this changes at some point we can adjust the
1165 struct sockaddr_in6 source_addr
;
1166 uint8_t source_addr_len
;
1167 bool got_source_addr
;
1168 uint8_t source_addr_flags
;
1174 struct sort_result_combo
1176 struct sort_result
*results
;
1181 #if __BYTE_ORDER == __BIG_ENDIAN
1182 # define htonl_c(n) n
1184 # define htonl_c(n) __bswap_constant_32 (n)
1187 static const struct scopeentry
1196 } default_scopes
[] =
1198 /* Link-local addresses: scope 2. */
1199 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1200 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1201 /* Default: scope 14. */
1202 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1205 /* The label table. */
1206 static const struct scopeentry
*scopes
;
1210 get_scope (const struct sockaddr_in6
*in6
)
1213 if (in6
->sin6_family
== PF_INET6
)
1215 if (! IN6_IS_ADDR_MULTICAST (&in6
->sin6_addr
))
1217 if (IN6_IS_ADDR_LINKLOCAL (&in6
->sin6_addr
)
1218 /* RFC 4291 2.5.3 says that the loopback address is to be
1219 treated like a link-local address. */
1220 || IN6_IS_ADDR_LOOPBACK (&in6
->sin6_addr
))
1222 else if (IN6_IS_ADDR_SITELOCAL (&in6
->sin6_addr
))
1225 /* XXX Is this the correct default behavior? */
1229 scope
= in6
->sin6_addr
.s6_addr
[1] & 0xf;
1231 else if (in6
->sin6_family
== PF_INET
)
1233 const struct sockaddr_in
*in
= (const struct sockaddr_in
*) in6
;
1238 if ((in
->sin_addr
.s_addr
& scopes
[cnt
].netmask
)
1239 == scopes
[cnt
].addr32
)
1240 return scopes
[cnt
].scope
;
1247 /* XXX What is a good default? */
1256 struct in6_addr prefix
;
1262 /* The label table. */
1263 static const struct prefixentry
*labels
;
1265 /* Default labels. */
1266 static const struct prefixentry default_labels
[] =
1268 /* See RFC 3484 for the details. */
1270 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1274 = { .__u6_addr8
= { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1278 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1279 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1282 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1283 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1285 /* The next two entries differ from RFC 3484. We need to treat
1286 IPv6 site-local addresses special because they are never NATed,
1287 unlike site-locale IPv4 addresses. If this would not happen, on
1288 machines which have only IPv4 and IPv6 site-local addresses, the
1289 sorting would prefer the IPv6 site-local addresses, causing
1290 unnecessary delays when trying to connect to a global IPv6 address
1291 through a site-local IPv6 address. */
1293 = { .__u6_addr8
= { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1297 = { .__u6_addr8
= { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1300 /* Additional rule for Teredo tunnels. */
1302 = { .__u6_addr8
= { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1306 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1312 /* The precedence table. */
1313 static const struct prefixentry
*precedence
;
1315 /* The default precedences. */
1316 static const struct prefixentry default_precedence
[] =
1318 /* See RFC 3484 for the details. */
1320 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1324 = { .__u6_addr8
= { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1328 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1332 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1333 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1336 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1343 match_prefix (const struct sockaddr_in6
*in6
,
1344 const struct prefixentry
*list
, int default_val
)
1347 struct sockaddr_in6 in6_mem
;
1349 if (in6
->sin6_family
== PF_INET
)
1351 const struct sockaddr_in
*in
= (const struct sockaddr_in
*) in6
;
1353 /* Construct a V4-to-6 mapped address. */
1354 in6_mem
.sin6_family
= PF_INET6
;
1355 in6_mem
.sin6_port
= in
->sin_port
;
1356 in6_mem
.sin6_flowinfo
= 0;
1357 memset (&in6_mem
.sin6_addr
, '\0', sizeof (in6_mem
.sin6_addr
));
1358 in6_mem
.sin6_addr
.s6_addr16
[5] = 0xffff;
1359 in6_mem
.sin6_addr
.s6_addr32
[3] = in
->sin_addr
.s_addr
;
1360 in6_mem
.sin6_scope_id
= 0;
1364 else if (in6
->sin6_family
!= PF_INET6
)
1367 for (idx
= 0; ; ++idx
)
1369 unsigned int bits
= list
[idx
].bits
;
1370 const uint8_t *mask
= list
[idx
].prefix
.s6_addr
;
1371 const uint8_t *val
= in6
->sin6_addr
.s6_addr
;
1385 if ((*mask
& (0xff00 >> bits
)) == (*val
& (0xff00 >> bits
)))
1391 return list
[idx
].val
;
1396 get_label (const struct sockaddr_in6
*in6
)
1398 /* XXX What is a good default value? */
1399 return match_prefix (in6
, labels
, INT_MAX
);
1404 get_precedence (const struct sockaddr_in6
*in6
)
1406 /* XXX What is a good default value? */
1407 return match_prefix (in6
, precedence
, 0);
1411 /* Find last bit set in a word. */
1417 for (n
= 0, mask
= 1 << 31; n
< 32; mask
>>= 1, ++n
)
1418 if ((a
& mask
) != 0)
1425 rfc3484_sort (const void *p1
, const void *p2
, void *arg
)
1427 const size_t idx1
= *(const size_t *) p1
;
1428 const size_t idx2
= *(const size_t *) p2
;
1429 struct sort_result_combo
*src
= (struct sort_result_combo
*) arg
;
1430 struct sort_result
*a1
= &src
->results
[idx1
];
1431 struct sort_result
*a2
= &src
->results
[idx2
];
1433 /* Rule 1: Avoid unusable destinations.
1434 We have the got_source_addr flag set if the destination is reachable. */
1435 if (a1
->got_source_addr
&& ! a2
->got_source_addr
)
1437 if (! a1
->got_source_addr
&& a2
->got_source_addr
)
1441 /* Rule 2: Prefer matching scope. Only interesting if both
1442 destination addresses are IPv6. */
1444 = get_scope ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1447 = get_scope ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1449 if (a1
->got_source_addr
)
1451 int a1_src_scope
= get_scope (&a1
->source_addr
);
1452 int a2_src_scope
= get_scope (&a2
->source_addr
);
1454 if (a1_dst_scope
== a1_src_scope
&& a2_dst_scope
!= a2_src_scope
)
1456 if (a1_dst_scope
!= a1_src_scope
&& a2_dst_scope
== a2_src_scope
)
1461 /* Rule 3: Avoid deprecated addresses. */
1462 if (a1
->got_source_addr
)
1464 if (!(a1
->source_addr_flags
& in6ai_deprecated
)
1465 && (a2
->source_addr_flags
& in6ai_deprecated
))
1467 if ((a1
->source_addr_flags
& in6ai_deprecated
)
1468 && !(a2
->source_addr_flags
& in6ai_deprecated
))
1472 /* Rule 4: Prefer home addresses. */
1473 if (a1
->got_source_addr
)
1475 if (!(a1
->source_addr_flags
& in6ai_homeaddress
)
1476 && (a2
->source_addr_flags
& in6ai_homeaddress
))
1478 if ((a1
->source_addr_flags
& in6ai_homeaddress
)
1479 && !(a2
->source_addr_flags
& in6ai_homeaddress
))
1483 /* Rule 5: Prefer matching label. */
1484 if (a1
->got_source_addr
)
1487 = get_label ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1488 int a1_src_label
= get_label (&a1
->source_addr
);
1491 = get_label ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1492 int a2_src_label
= get_label (&a2
->source_addr
);
1494 if (a1_dst_label
== a1_src_label
&& a2_dst_label
!= a2_src_label
)
1496 if (a1_dst_label
!= a1_src_label
&& a2_dst_label
== a2_src_label
)
1501 /* Rule 6: Prefer higher precedence. */
1503 = get_precedence ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1505 = get_precedence ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1507 if (a1_prec
> a2_prec
)
1509 if (a1_prec
< a2_prec
)
1513 /* Rule 7: Prefer native transport. */
1514 if (a1
->got_source_addr
)
1516 /* The same interface index means the same interface which means
1517 there is no difference in transport. This should catch many
1519 if (a1
->index
!= a2
->index
)
1521 int a1_native
= a1
->native
;
1522 int a2_native
= a2
->native
;
1524 if (a1_native
== -1 || a2_native
== -1)
1527 if (a1_native
== -1)
1529 /* If we do not have the information use 'native' as
1532 a1_index
= a1
->index
;
1535 a1_index
= 0xffffffffu
;
1538 if (a2_native
== -1)
1540 /* If we do not have the information use 'native' as
1543 a2_index
= a2
->index
;
1546 a2_index
= 0xffffffffu
;
1548 __check_native (a1_index
, &a1_native
, a2_index
, &a2_native
);
1550 /* Fill in the results in all the records. */
1551 for (int i
= 0; i
< src
->nresults
; ++i
)
1552 if (a1_index
!= -1 && src
->results
[i
].index
== a1_index
)
1554 assert (src
->results
[i
].native
== -1
1555 || src
->results
[i
].native
== a1_native
);
1556 src
->results
[i
].native
= a1_native
;
1558 else if (a2_index
!= -1 && src
->results
[i
].index
== a2_index
)
1560 assert (src
->results
[i
].native
== -1
1561 || src
->results
[i
].native
== a2_native
);
1562 src
->results
[i
].native
= a2_native
;
1566 if (a1_native
&& !a2_native
)
1568 if (!a1_native
&& a2_native
)
1574 /* Rule 8: Prefer smaller scope. */
1575 if (a1_dst_scope
< a2_dst_scope
)
1577 if (a1_dst_scope
> a2_dst_scope
)
1581 /* Rule 9: Use longest matching prefix. */
1582 if (a1
->got_source_addr
1583 && a1
->dest_addr
->ai_family
== a2
->dest_addr
->ai_family
)
1588 if (a1
->dest_addr
->ai_family
== PF_INET
)
1590 assert (a1
->source_addr
.sin6_family
== PF_INET
);
1591 assert (a2
->source_addr
.sin6_family
== PF_INET
);
1593 /* Outside of subnets, as defined by the network masks,
1594 common address prefixes for IPv4 addresses make no sense.
1595 So, define a non-zero value only if source and
1596 destination address are on the same subnet. */
1597 struct sockaddr_in
*in1_dst
1598 = (struct sockaddr_in
*) a1
->dest_addr
->ai_addr
;
1599 in_addr_t in1_dst_addr
= ntohl (in1_dst
->sin_addr
.s_addr
);
1600 struct sockaddr_in
*in1_src
1601 = (struct sockaddr_in
*) &a1
->source_addr
;
1602 in_addr_t in1_src_addr
= ntohl (in1_src
->sin_addr
.s_addr
);
1603 in_addr_t netmask1
= 0xffffffffu
<< (32 - a1
->prefixlen
);
1605 if ((in1_src_addr
& netmask1
) == (in1_dst_addr
& netmask1
))
1606 bit1
= fls (in1_dst_addr
^ in1_src_addr
);
1608 struct sockaddr_in
*in2_dst
1609 = (struct sockaddr_in
*) a2
->dest_addr
->ai_addr
;
1610 in_addr_t in2_dst_addr
= ntohl (in2_dst
->sin_addr
.s_addr
);
1611 struct sockaddr_in
*in2_src
1612 = (struct sockaddr_in
*) &a2
->source_addr
;
1613 in_addr_t in2_src_addr
= ntohl (in2_src
->sin_addr
.s_addr
);
1614 in_addr_t netmask2
= 0xffffffffu
<< (32 - a2
->prefixlen
);
1616 if ((in2_src_addr
& netmask2
) == (in2_dst_addr
& netmask2
))
1617 bit2
= fls (in2_dst_addr
^ in2_src_addr
);
1619 else if (a1
->dest_addr
->ai_family
== PF_INET6
)
1621 assert (a1
->source_addr
.sin6_family
== PF_INET6
);
1622 assert (a2
->source_addr
.sin6_family
== PF_INET6
);
1624 struct sockaddr_in6
*in1_dst
;
1625 struct sockaddr_in6
*in1_src
;
1626 struct sockaddr_in6
*in2_dst
;
1627 struct sockaddr_in6
*in2_src
;
1629 in1_dst
= (struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
;
1630 in1_src
= (struct sockaddr_in6
*) &a1
->source_addr
;
1631 in2_dst
= (struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
;
1632 in2_src
= (struct sockaddr_in6
*) &a2
->source_addr
;
1635 for (i
= 0; i
< 4; ++i
)
1636 if (in1_dst
->sin6_addr
.s6_addr32
[i
]
1637 != in1_src
->sin6_addr
.s6_addr32
[i
]
1638 || (in2_dst
->sin6_addr
.s6_addr32
[i
]
1639 != in2_src
->sin6_addr
.s6_addr32
[i
]))
1644 bit1
= fls (ntohl (in1_dst
->sin6_addr
.s6_addr32
[i
]
1645 ^ in1_src
->sin6_addr
.s6_addr32
[i
]));
1646 bit2
= fls (ntohl (in2_dst
->sin6_addr
.s6_addr32
[i
]
1647 ^ in2_src
->sin6_addr
.s6_addr32
[i
]));
1658 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1659 compare with the value indicating the order in which the entries
1660 have been received from the services. NB: no two entries can have
1661 the same order so the test will never return zero. */
1662 return idx1
< idx2
? -1 : 1;
1667 in6aicmp (const void *p1
, const void *p2
)
1669 struct in6addrinfo
*a1
= (struct in6addrinfo
*) p1
;
1670 struct in6addrinfo
*a2
= (struct in6addrinfo
*) p2
;
1672 return memcmp (a1
->addr
, a2
->addr
, sizeof (a1
->addr
));
1676 /* Name of the config file for RFC 3484 sorting (for now). */
1677 #define GAICONF_FNAME "/etc/gai.conf"
1680 /* Non-zero if we are supposed to reload the config file automatically
1681 whenever it changed. */
1682 static int gaiconf_reload_flag
;
1684 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1685 static int gaiconf_reload_flag_ever_set
;
1687 /* Last modification time. */
1688 #ifdef _STATBUF_ST_NSEC
1690 static struct timespec gaiconf_mtime
;
1693 save_gaiconf_mtime (const struct stat64
*st
)
1695 gaiconf_mtime
= st
->st_mtim
;
1699 check_gaiconf_mtime (const struct stat64
*st
)
1701 return (st
->st_mtim
.tv_sec
== gaiconf_mtime
.tv_sec
1702 && st
->st_mtim
.tv_nsec
== gaiconf_mtime
.tv_nsec
);
1707 static time_t gaiconf_mtime
;
1710 save_gaiconf_mtime (const struct stat64
*st
)
1712 gaiconf_mtime
= st
->st_mtime
;
1716 check_gaiconf_mtime (const struct stat64
*st
)
1718 return st
->st_mtime
== gaiconf_mtime
;
1724 libc_freeres_fn(fini
)
1726 if (labels
!= default_labels
)
1728 const struct prefixentry
*old
= labels
;
1729 labels
= default_labels
;
1730 free ((void *) old
);
1733 if (precedence
!= default_precedence
)
1735 const struct prefixentry
*old
= precedence
;
1736 precedence
= default_precedence
;
1737 free ((void *) old
);
1740 if (scopes
!= default_scopes
)
1742 const struct scopeentry
*old
= scopes
;
1743 scopes
= default_scopes
;
1744 free ((void *) old
);
1751 struct prefixentry entry
;
1752 struct prefixlist
*next
;
1758 struct scopeentry entry
;
1759 struct scopelist
*next
;
1764 free_prefixlist (struct prefixlist
*list
)
1766 while (list
!= NULL
)
1768 struct prefixlist
*oldp
= list
;
1776 free_scopelist (struct scopelist
*list
)
1778 while (list
!= NULL
)
1780 struct scopelist
*oldp
= list
;
1788 prefixcmp (const void *p1
, const void *p2
)
1790 const struct prefixentry
*e1
= (const struct prefixentry
*) p1
;
1791 const struct prefixentry
*e2
= (const struct prefixentry
*) p2
;
1793 if (e1
->bits
< e2
->bits
)
1795 if (e1
->bits
== e2
->bits
)
1802 scopecmp (const void *p1
, const void *p2
)
1804 const struct scopeentry
*e1
= (const struct scopeentry
*) p1
;
1805 const struct scopeentry
*e2
= (const struct scopeentry
*) p2
;
1807 if (e1
->netmask
> e2
->netmask
)
1809 if (e1
->netmask
== e2
->netmask
)
1818 struct prefixlist
*labellist
= NULL
;
1819 size_t nlabellist
= 0;
1820 bool labellist_nullbits
= false;
1821 struct prefixlist
*precedencelist
= NULL
;
1822 size_t nprecedencelist
= 0;
1823 bool precedencelist_nullbits
= false;
1824 struct scopelist
*scopelist
= NULL
;
1825 size_t nscopelist
= 0;
1826 bool scopelist_nullbits
= false;
1828 FILE *fp
= fopen (GAICONF_FNAME
, "rce");
1832 if (__fxstat64 (_STAT_VER
, fileno (fp
), &st
) != 0)
1841 __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
1843 while (!feof_unlocked (fp
))
1845 ssize_t n
= __getline (&line
, &linelen
, fp
);
1849 /* Handle comments. No escaping possible so this is easy. */
1850 char *cp
= strchr (line
, '#');
1855 while (isspace (*cp
))
1859 while (*cp
!= '\0' && !isspace (*cp
))
1861 size_t cmdlen
= cp
- cmd
;
1865 while (isspace (*cp
))
1869 while (*cp
!= '\0' && !isspace (*cp
))
1871 size_t val1len
= cp
- cmd
;
1873 /* We always need at least two values. */
1879 while (isspace (*cp
))
1883 while (*cp
!= '\0' && !isspace (*cp
))
1886 /* Ignore the rest of the line. */
1889 struct prefixlist
**listp
;
1895 if (strcmp (cmd
, "label") == 0)
1897 struct in6_addr prefix
;
1898 unsigned long int bits
;
1899 unsigned long int val
;
1904 nullbitsp
= &labellist_nullbits
;
1909 cp
= strchr (val1
, '/');
1912 if (inet_pton (AF_INET6
, val1
, &prefix
)
1914 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
1918 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
1923 struct prefixlist
*newp
= malloc (sizeof (*newp
));
1931 memcpy (&newp
->entry
.prefix
, &prefix
, sizeof (prefix
));
1932 newp
->entry
.bits
= bits
;
1933 newp
->entry
.val
= val
;
1934 newp
->next
= *listp
;
1937 *nullbitsp
|= bits
== 0;
1943 if (strcmp (cmd
, "reload") == 0)
1945 gaiconf_reload_flag
= strcmp (val1
, "yes") == 0;
1946 if (gaiconf_reload_flag
)
1947 gaiconf_reload_flag_ever_set
= 1;
1952 if (strcmp (cmd
, "scopev4") == 0)
1954 struct in6_addr prefix
;
1955 unsigned long int bits
;
1956 unsigned long int val
;
1961 cp
= strchr (val1
, '/');
1964 if (inet_pton (AF_INET6
, val1
, &prefix
))
1967 if (IN6_IS_ADDR_V4MAPPED (&prefix
)
1969 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
1974 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
1979 struct scopelist
*newp
;
1981 newp
= malloc (sizeof (*newp
));
1989 newp
->entry
.netmask
= htonl (bits
!= 96
1993 newp
->entry
.addr32
= (prefix
.s6_addr32
[3]
1994 & newp
->entry
.netmask
);
1995 newp
->entry
.scope
= val
;
1996 newp
->next
= scopelist
;
1999 scopelist_nullbits
|= bits
== 96;
2002 else if (inet_pton (AF_INET
, val1
, &prefix
.s6_addr32
[3])
2004 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
2008 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
2020 if (strcmp (cmd
, "precedence") == 0)
2022 listp
= &precedencelist
;
2023 lenp
= &nprecedencelist
;
2024 nullbitsp
= &precedencelist_nullbits
;
2035 /* Create the array for the labels. */
2036 struct prefixentry
*new_labels
;
2039 if (!labellist_nullbits
)
2041 new_labels
= malloc (nlabellist
* sizeof (*new_labels
));
2042 if (new_labels
== NULL
)
2046 if (!labellist_nullbits
)
2049 memset (&new_labels
[i
].prefix
, '\0', sizeof (struct in6_addr
));
2050 new_labels
[i
].bits
= 0;
2051 new_labels
[i
].val
= 1;
2054 struct prefixlist
*l
= labellist
;
2057 new_labels
[i
] = l
->entry
;
2060 free_prefixlist (labellist
);
2062 /* Sort the entries so that the most specific ones are at
2064 qsort (new_labels
, nlabellist
, sizeof (*new_labels
), prefixcmp
);
2067 new_labels
= (struct prefixentry
*) default_labels
;
2069 struct prefixentry
*new_precedence
;
2070 if (nprecedencelist
> 0)
2072 if (!precedencelist_nullbits
)
2074 new_precedence
= malloc (nprecedencelist
* sizeof (*new_precedence
));
2075 if (new_precedence
== NULL
)
2077 if (new_labels
!= default_labels
)
2082 int i
= nprecedencelist
;
2083 if (!precedencelist_nullbits
)
2086 memset (&new_precedence
[i
].prefix
, '\0',
2087 sizeof (struct in6_addr
));
2088 new_precedence
[i
].bits
= 0;
2089 new_precedence
[i
].val
= 40;
2092 struct prefixlist
*l
= precedencelist
;
2095 new_precedence
[i
] = l
->entry
;
2098 free_prefixlist (precedencelist
);
2100 /* Sort the entries so that the most specific ones are at
2102 qsort (new_precedence
, nprecedencelist
, sizeof (*new_precedence
),
2106 new_precedence
= (struct prefixentry
*) default_precedence
;
2108 struct scopeentry
*new_scopes
;
2111 if (!scopelist_nullbits
)
2113 new_scopes
= malloc (nscopelist
* sizeof (*new_scopes
));
2114 if (new_scopes
== NULL
)
2116 if (new_labels
!= default_labels
)
2118 if (new_precedence
!= default_precedence
)
2119 free (new_precedence
);
2124 if (!scopelist_nullbits
)
2127 new_scopes
[i
].addr32
= 0;
2128 new_scopes
[i
].netmask
= 0;
2129 new_scopes
[i
].scope
= 14;
2132 struct scopelist
*l
= scopelist
;
2135 new_scopes
[i
] = l
->entry
;
2138 free_scopelist (scopelist
);
2140 /* Sort the entries so that the most specific ones are at
2142 qsort (new_scopes
, nscopelist
, sizeof (*new_scopes
),
2146 new_scopes
= (struct scopeentry
*) default_scopes
;
2148 /* Now we are ready to replace the values. */
2149 const struct prefixentry
*old
= labels
;
2150 labels
= new_labels
;
2151 if (old
!= default_labels
)
2152 free ((void *) old
);
2155 precedence
= new_precedence
;
2156 if (old
!= default_precedence
)
2157 free ((void *) old
);
2159 const struct scopeentry
*oldscope
= scopes
;
2160 scopes
= new_scopes
;
2161 if (oldscope
!= default_scopes
)
2162 free ((void *) oldscope
);
2164 save_gaiconf_mtime (&st
);
2169 free_prefixlist (labellist
);
2170 free_prefixlist (precedencelist
);
2171 free_scopelist (scopelist
);
2173 /* If we previously read the file but it is gone now, free the
2174 old data and use the builtin one. Leave the reload flag
2182 gaiconf_reload (void)
2185 if (__xstat64 (_STAT_VER
, GAICONF_FNAME
, &st
) != 0
2186 || !check_gaiconf_mtime (&st
))
2192 getaddrinfo (const char *name
, const char *service
,
2193 const struct addrinfo
*hints
, struct addrinfo
**pai
)
2195 int i
= 0, last_i
= 0;
2197 struct addrinfo
*p
= NULL
;
2198 struct gaih_service gaih_service
, *pservice
;
2199 struct addrinfo local_hints
;
2201 if (name
!= NULL
&& name
[0] == '*' && name
[1] == 0)
2204 if (service
!= NULL
&& service
[0] == '*' && service
[1] == 0)
2207 if (name
== NULL
&& service
== NULL
)
2211 hints
= &default_hints
;
2214 & ~(AI_PASSIVE
|AI_CANONNAME
|AI_NUMERICHOST
|AI_ADDRCONFIG
|AI_V4MAPPED
2216 |AI_IDN
|AI_CANONIDN
|AI_IDN_ALLOW_UNASSIGNED
2217 |AI_IDN_USE_STD3_ASCII_RULES
2219 |AI_NUMERICSERV
|AI_ALL
))
2220 return EAI_BADFLAGS
;
2222 if ((hints
->ai_flags
& AI_CANONNAME
) && name
== NULL
)
2223 return EAI_BADFLAGS
;
2225 struct in6addrinfo
*in6ai
= NULL
;
2226 size_t in6ailen
= 0;
2227 bool seen_ipv4
= false;
2228 bool seen_ipv6
= false;
2229 bool check_pf_called
= false;
2231 if (hints
->ai_flags
& AI_ADDRCONFIG
)
2233 /* We might need information about what interfaces are available.
2234 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2235 cannot cache the results since new interfaces could be added at
2237 __check_pf (&seen_ipv4
, &seen_ipv6
, &in6ai
, &in6ailen
);
2238 check_pf_called
= true;
2240 /* Now make a decision on what we return, if anything. */
2241 if (hints
->ai_family
== PF_UNSPEC
&& (seen_ipv4
|| seen_ipv6
))
2243 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2244 narrow down the search. */
2245 if ((! seen_ipv4
|| ! seen_ipv6
) && (seen_ipv4
|| seen_ipv6
))
2247 local_hints
= *hints
;
2248 local_hints
.ai_family
= seen_ipv4
? PF_INET
: PF_INET6
;
2249 hints
= &local_hints
;
2252 else if ((hints
->ai_family
== PF_INET
&& ! seen_ipv4
)
2253 || (hints
->ai_family
== PF_INET6
&& ! seen_ipv6
))
2255 /* We cannot possibly return a valid answer. */
2256 __free_in6ai (in6ai
);
2261 if (service
&& service
[0])
2264 gaih_service
.name
= service
;
2265 gaih_service
.num
= strtoul (gaih_service
.name
, &c
, 10);
2268 if (hints
->ai_flags
& AI_NUMERICSERV
)
2270 __free_in6ai (in6ai
);
2274 gaih_service
.num
= -1;
2277 pservice
= &gaih_service
;
2282 struct addrinfo
**end
= &p
;
2284 unsigned int naddrs
= 0;
2285 if (hints
->ai_family
== AF_UNSPEC
|| hints
->ai_family
== AF_INET
2286 || hints
->ai_family
== AF_INET6
)
2288 struct scratch_buffer tmpbuf
;
2289 scratch_buffer_init (&tmpbuf
);
2290 last_i
= gaih_inet (name
, pservice
, hints
, end
, &naddrs
, &tmpbuf
);
2291 scratch_buffer_free (&tmpbuf
);
2296 __free_in6ai (in6ai
);
2302 end
= &((*end
)->ai_next
);
2308 __free_in6ai (in6ai
);
2314 /* Read the config file. */
2315 __libc_once_define (static, once
);
2316 __typeof (once
) old_once
= once
;
2317 __libc_once (once
, gaiconf_init
);
2318 /* Sort results according to RFC 3484. */
2319 struct sort_result
*results
;
2322 struct addrinfo
*last
= NULL
;
2323 char *canonname
= NULL
;
2324 bool malloc_results
;
2325 size_t alloc_size
= nresults
* (sizeof (*results
) + sizeof (size_t));
2328 = !__libc_use_alloca (alloc_size
);
2331 results
= malloc (alloc_size
);
2332 if (results
== NULL
)
2334 __free_in6ai (in6ai
);
2339 results
= alloca (alloc_size
);
2340 order
= (size_t *) (results
+ nresults
);
2342 /* Now we definitely need the interface information. */
2343 if (! check_pf_called
)
2344 __check_pf (&seen_ipv4
, &seen_ipv6
, &in6ai
, &in6ailen
);
2346 /* If we have information about deprecated and temporary addresses
2347 sort the array now. */
2349 qsort (in6ai
, in6ailen
, sizeof (*in6ai
), in6aicmp
);
2354 for (i
= 0, q
= p
; q
!= NULL
; ++i
, last
= q
, q
= q
->ai_next
)
2356 results
[i
].dest_addr
= q
;
2357 results
[i
].native
= -1;
2360 /* If we just looked up the address for a different
2361 protocol, reuse the result. */
2362 if (last
!= NULL
&& last
->ai_addrlen
== q
->ai_addrlen
2363 && memcmp (last
->ai_addr
, q
->ai_addr
, q
->ai_addrlen
) == 0)
2365 memcpy (&results
[i
].source_addr
, &results
[i
- 1].source_addr
,
2366 results
[i
- 1].source_addr_len
);
2367 results
[i
].source_addr_len
= results
[i
- 1].source_addr_len
;
2368 results
[i
].got_source_addr
= results
[i
- 1].got_source_addr
;
2369 results
[i
].source_addr_flags
= results
[i
- 1].source_addr_flags
;
2370 results
[i
].prefixlen
= results
[i
- 1].prefixlen
;
2371 results
[i
].index
= results
[i
- 1].index
;
2375 results
[i
].got_source_addr
= false;
2376 results
[i
].source_addr_flags
= 0;
2377 results
[i
].prefixlen
= 0;
2378 results
[i
].index
= 0xffffffffu
;
2380 /* We overwrite the type with SOCK_DGRAM since we do not
2381 want connect() to connect to the other side. If we
2382 cannot determine the source address remember this
2384 if (fd
== -1 || (af
== AF_INET
&& q
->ai_family
== AF_INET6
))
2388 __close_nocancel_nostatus (fd
);
2390 fd
= __socket (af
, SOCK_DGRAM
| SOCK_CLOEXEC
, IPPROTO_IP
);
2394 /* Reset the connection. */
2395 struct sockaddr sa
= { .sa_family
= AF_UNSPEC
};
2396 __connect (fd
, &sa
, sizeof (sa
));
2399 socklen_t sl
= sizeof (results
[i
].source_addr
);
2401 && __connect (fd
, q
->ai_addr
, q
->ai_addrlen
) == 0
2402 && __getsockname (fd
,
2403 (struct sockaddr
*) &results
[i
].source_addr
,
2406 results
[i
].source_addr_len
= sl
;
2407 results
[i
].got_source_addr
= true;
2411 /* See whether the source address is on the list of
2412 deprecated or temporary addresses. */
2413 struct in6addrinfo tmp
;
2415 if (q
->ai_family
== AF_INET
&& af
== AF_INET
)
2417 struct sockaddr_in
*sinp
2418 = (struct sockaddr_in
*) &results
[i
].source_addr
;
2421 tmp
.addr
[2] = htonl (0xffff);
2422 /* Special case for lo interface, the source address
2423 being possibly different than the interface
2425 if ((ntohl(sinp
->sin_addr
.s_addr
) & 0xff000000)
2427 tmp
.addr
[3] = htonl(0x7f000001);
2429 tmp
.addr
[3] = sinp
->sin_addr
.s_addr
;
2433 struct sockaddr_in6
*sin6p
2434 = (struct sockaddr_in6
*) &results
[i
].source_addr
;
2435 memcpy (tmp
.addr
, &sin6p
->sin6_addr
, IN6ADDRSZ
);
2438 struct in6addrinfo
*found
2439 = bsearch (&tmp
, in6ai
, in6ailen
, sizeof (*in6ai
),
2443 results
[i
].source_addr_flags
= found
->flags
;
2444 results
[i
].prefixlen
= found
->prefixlen
;
2445 results
[i
].index
= found
->index
;
2449 if (q
->ai_family
== AF_INET
&& af
== AF_INET6
)
2451 /* We have to convert the address. The socket is
2452 IPv6 and the request is for IPv4. */
2453 struct sockaddr_in6
*sin6
2454 = (struct sockaddr_in6
*) &results
[i
].source_addr
;
2455 struct sockaddr_in
*sin
2456 = (struct sockaddr_in
*) &results
[i
].source_addr
;
2457 assert (IN6_IS_ADDR_V4MAPPED (sin6
->sin6_addr
.s6_addr32
));
2458 sin
->sin_family
= AF_INET
;
2459 /* We do not have to initialize sin_port since this
2460 fields has the same position and size in the IPv6
2462 assert (offsetof (struct sockaddr_in
, sin_port
)
2463 == offsetof (struct sockaddr_in6
, sin6_port
));
2464 assert (sizeof (sin
->sin_port
)
2465 == sizeof (sin6
->sin6_port
));
2466 memcpy (&sin
->sin_addr
,
2467 &sin6
->sin6_addr
.s6_addr32
[3], INADDRSZ
);
2468 results
[i
].source_addr_len
= sizeof (struct sockaddr_in
);
2471 else if (errno
== EAFNOSUPPORT
&& af
== AF_INET6
2472 && q
->ai_family
== AF_INET
)
2473 /* This could mean IPv6 sockets are IPv6-only. */
2476 /* Just make sure that if we have to process the same
2477 address again we do not copy any memory. */
2478 results
[i
].source_addr_len
= 0;
2481 /* Remember the canonical name. */
2482 if (q
->ai_canonname
!= NULL
)
2484 assert (canonname
== NULL
);
2485 canonname
= q
->ai_canonname
;
2486 q
->ai_canonname
= NULL
;
2491 __close_nocancel_nostatus (fd
);
2493 /* We got all the source addresses we can get, now sort using
2495 struct sort_result_combo src
2496 = { .results
= results
, .nresults
= nresults
};
2497 if (__glibc_unlikely (gaiconf_reload_flag_ever_set
))
2499 __libc_lock_define_initialized (static, lock
);
2501 __libc_lock_lock (lock
);
2502 if (__libc_once_get (old_once
) && gaiconf_reload_flag
)
2504 __qsort_r (order
, nresults
, sizeof (order
[0]), rfc3484_sort
, &src
);
2505 __libc_lock_unlock (lock
);
2508 __qsort_r (order
, nresults
, sizeof (order
[0]), rfc3484_sort
, &src
);
2510 /* Queue the results up as they come out of sorting. */
2511 q
= p
= results
[order
[0]].dest_addr
;
2512 for (i
= 1; i
< nresults
; ++i
)
2513 q
= q
->ai_next
= results
[order
[i
]].dest_addr
;
2516 /* Fill in the canonical name into the new first entry. */
2517 p
->ai_canonname
= canonname
;
2523 __free_in6ai (in6ai
);
2531 return last_i
? -last_i
: EAI_NONAME
;
2533 libc_hidden_def (getaddrinfo
)
2535 nss_interface_function (getaddrinfo
)
2538 freeaddrinfo (struct addrinfo
*ai
)
2546 free (p
->ai_canonname
);
2550 libc_hidden_def (freeaddrinfo
)