1 /* Host and service name lookups using Name Service Switch modules.
2 Copyright (C) 1996-2023 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 <https://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>
66 #include <stdio_ext.h>
70 #include <arpa/inet.h>
72 #include <netinet/in.h>
73 #include <sys/socket.h>
75 #include <sys/types.h>
77 #include <sys/utsname.h>
80 #include <libc-lock.h>
81 #include <not-cancel.h>
82 #include <nscd/nscd-client.h>
83 #include <nscd/nscd_proto.h>
84 #include <scratch_buffer.h>
85 #include <inet/net-internal.h>
87 /* Former AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES
88 flags, now ignored. */
89 #define DEPRECATED_AI_IDN 0x300
92 # define feof_unlocked(fp) __feof_unlocked (fp)
101 struct gaih_servtuple
110 struct gaih_typeproto
121 struct gaih_addrtuple
*at
;
127 /* Values for `protoflag'. */
128 #define GAI_PROTO_NOSERVICE 1
129 #define GAI_PROTO_PROTOANY 2
131 static const struct gaih_typeproto gaih_inet_typeproto
[] =
133 { 0, 0, 0, false, "" },
134 { SOCK_STREAM
, IPPROTO_TCP
, 0, true, "tcp" },
135 { SOCK_DGRAM
, IPPROTO_UDP
, 0, true, "udp" },
136 #if defined SOCK_DCCP && defined IPPROTO_DCCP
137 { SOCK_DCCP
, IPPROTO_DCCP
, 0, false, "dccp" },
139 #ifdef IPPROTO_UDPLITE
140 { SOCK_DGRAM
, IPPROTO_UDPLITE
, 0, false, "udplite" },
143 { SOCK_STREAM
, IPPROTO_SCTP
, 0, false, "sctp" },
144 { SOCK_SEQPACKET
, IPPROTO_SCTP
, 0, false, "sctp" },
146 { SOCK_RAW
, 0, GAI_PROTO_PROTOANY
|GAI_PROTO_NOSERVICE
, true, "raw" },
147 { 0, 0, 0, false, "" }
150 static const struct addrinfo default_hints
=
152 .ai_flags
= AI_DEFAULT
,
153 .ai_family
= PF_UNSPEC
,
158 .ai_canonname
= NULL
,
163 gaih_result_reset (struct gaih_result
*res
)
168 memset (res
, 0, sizeof (*res
));
172 gaih_inet_serv (const char *servicename
, const struct gaih_typeproto
*tp
,
173 const struct addrinfo
*req
, struct gaih_servtuple
*st
,
174 struct scratch_buffer
*tmpbuf
)
182 r
= __getservbyname_r (servicename
, tp
->name
, &ts
,
183 tmpbuf
->data
, tmpbuf
->length
, &s
);
184 if (r
!= 0 || s
== NULL
)
188 if (!scratch_buffer_grow (tmpbuf
))
197 st
->socktype
= tp
->socktype
;
198 st
->protocol
= ((tp
->protoflag
& GAI_PROTO_PROTOANY
)
199 ? req
->ai_protocol
: tp
->protocol
);
200 st
->port
= s
->s_port
;
206 /* Convert struct hostent to a list of struct gaih_addrtuple objects. h_name
207 is not copied, and the struct hostent object must not be deallocated
208 prematurely. The new addresses are appended to the tuple array in RES. */
210 convert_hostent_to_gaih_addrtuple (const struct addrinfo
*req
, int family
,
211 struct hostent
*h
, struct gaih_result
*res
)
213 /* Count the number of addresses in h->h_addr_list. */
215 for (char **p
= h
->h_addr_list
; *p
!= NULL
; ++p
)
218 /* Report no data if no addresses are available, or if the incoming
219 address size is larger than what we can store. */
220 if (count
== 0 || h
->h_length
> sizeof (((struct gaih_addrtuple
) {}).addr
))
223 struct gaih_addrtuple
*array
= res
->at
;
226 while (array
!= NULL
)
232 array
= realloc (res
->at
, (old
+ count
) * sizeof (*array
));
237 res
->got_ipv6
= family
== AF_INET6
;
241 /* Update the next pointers on reallocation. */
242 for (size_t i
= 0; i
< old
; i
++)
243 array
[i
].next
= array
+ i
+ 1;
247 memset (array
, 0, count
* sizeof (*array
));
249 for (size_t i
= 0; i
< count
; ++i
)
251 if (family
== AF_INET
&& req
->ai_family
== AF_INET6
)
253 /* Perform address mapping. */
254 array
[i
].family
= AF_INET6
;
255 memcpy(array
[i
].addr
+ 3, h
->h_addr_list
[i
], sizeof (uint32_t));
256 array
[i
].addr
[2] = htonl (0xffff);
260 array
[i
].family
= family
;
261 memcpy (array
[i
].addr
, h
->h_addr_list
[i
], h
->h_length
);
263 array
[i
].next
= array
+ i
+ 1;
265 array
[0].name
= h
->h_name
;
266 array
[count
- 1].next
= NULL
;
272 gethosts (nss_gethostbyname3_r fct
, int family
, const char *name
,
273 const struct addrinfo
*req
, struct scratch_buffer
*tmpbuf
,
274 struct gaih_result
*res
, enum nss_status
*statusp
, int *no_datap
)
277 char *localcanon
= NULL
;
278 enum nss_status status
;
283 *statusp
= status
= DL_CALL_FCT (fct
, (name
, family
, &th
,
284 tmpbuf
->data
, tmpbuf
->length
,
285 &errno
, &h_errno
, NULL
,
287 if (status
!= NSS_STATUS_TRYAGAIN
|| h_errno
!= NETDB_INTERNAL
290 if (!scratch_buffer_grow (tmpbuf
))
293 if (status
== NSS_STATUS_NOTFOUND
294 || status
== NSS_STATUS_TRYAGAIN
|| status
== NSS_STATUS_UNAVAIL
)
296 if (h_errno
== NETDB_INTERNAL
)
298 if (h_errno
== TRY_AGAIN
)
299 *no_datap
= EAI_AGAIN
;
301 *no_datap
= h_errno
== NO_DATA
;
303 else if (status
== NSS_STATUS_SUCCESS
)
305 if (!convert_hostent_to_gaih_addrtuple (req
, family
, &th
, res
))
308 if (localcanon
!= NULL
&& res
->canon
== NULL
)
310 char *canonbuf
= __strdup (localcanon
);
311 if (canonbuf
== NULL
)
313 res
->canon
= canonbuf
;
320 /* This function is called if a canonical name is requested, but if
321 the service function did not provide it. It tries to obtain the
322 name using getcanonname_r from the same service NIP. If the name
323 cannot be canonicalized, return a copy of NAME. Return NULL on
324 memory allocation failure. The returned string is allocated on the
325 heap; the caller has to free it. */
327 getcanonname (nss_action_list nip
, struct gaih_addrtuple
*at
, const char *name
)
329 nss_getcanonname_r
*cfct
= __nss_lookup_function (nip
, "getcanonname_r");
330 char *s
= (char *) name
;
334 if (DL_CALL_FCT (cfct
, (at
->name
?: name
, buf
, sizeof (buf
),
335 &s
, &errno
, &h_errno
)) != NSS_STATUS_SUCCESS
)
336 /* If the canonical name cannot be determined, use the passed
340 return __strdup (name
);
343 /* Process looked up canonical name and if necessary, decode to IDNA. Result
344 is a new string written to CANONP and the earlier string is freed. */
347 process_canonname (const struct addrinfo
*req
, const char *orig_name
,
348 struct gaih_result
*res
)
350 char *canon
= res
->canon
;
352 if ((req
->ai_flags
& AI_CANONNAME
) != 0)
354 bool do_idn
= req
->ai_flags
& AI_CANONIDN
;
358 int rc
= __idna_from_dns_encoding (canon
?: orig_name
, &out
);
364 else if (rc
== EAI_IDN_ENCODE
)
365 /* Use the punycode name as a fallback. */
370 if (!do_idn
&& canon
== NULL
&& (canon
= __strdup (orig_name
)) == NULL
)
379 get_servtuples (const struct gaih_service
*service
, const struct addrinfo
*req
,
380 struct gaih_servtuple
*st
, struct scratch_buffer
*tmpbuf
)
383 const struct gaih_typeproto
*tp
= gaih_inet_typeproto
;
385 if (req
->ai_protocol
|| req
->ai_socktype
)
390 && ((req
->ai_socktype
!= 0 && req
->ai_socktype
!= tp
->socktype
)
391 || (req
->ai_protocol
!= 0
392 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
393 && req
->ai_protocol
!= tp
->protocol
)))
398 if (req
->ai_socktype
)
399 return -EAI_SOCKTYPE
;
405 if (service
!= NULL
&& (tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0)
408 if (service
== NULL
|| service
->num
>= 0)
410 int port
= service
!= NULL
? htons (service
->num
) : 0;
412 if (req
->ai_socktype
|| req
->ai_protocol
)
414 st
[0].socktype
= tp
->socktype
;
415 st
[0].protocol
= ((tp
->protoflag
& GAI_PROTO_PROTOANY
)
416 ? req
->ai_protocol
: tp
->protocol
);
423 /* Neither socket type nor protocol is set. Return all socket types
425 for (i
= 0, ++tp
; tp
->name
[0]; ++tp
)
428 st
[i
].socktype
= tp
->socktype
;
429 st
[i
].protocol
= tp
->protocol
;
438 return gaih_inet_serv (service
->name
, tp
, req
, st
, tmpbuf
);
440 for (i
= 0, tp
++; tp
->name
[0]; tp
++)
442 if ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0)
445 if (req
->ai_socktype
!= 0
446 && req
->ai_socktype
!= tp
->socktype
)
448 if (req
->ai_protocol
!= 0
449 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
450 && req
->ai_protocol
!= tp
->protocol
)
453 if (gaih_inet_serv (service
->name
,
454 tp
, req
, &st
[i
], tmpbuf
) != 0)
467 /* Query addresses from nscd cache, returning a non-zero value on error.
468 RES members have the lookup result; RES->AT is NULL if there were no errors
469 but also no results. */
472 get_nscd_addresses (const char *name
, const struct addrinfo
*req
,
473 struct gaih_result
*res
)
475 if (__nss_not_use_nscd_hosts
> 0
476 && ++__nss_not_use_nscd_hosts
> NSS_NSCD_RETRY
)
477 __nss_not_use_nscd_hosts
= 0;
481 if (__nss_not_use_nscd_hosts
|| __nss_database_custom
[NSS_DBSIDX_hosts
])
484 /* Try to use nscd. */
485 struct nscd_ai_result
*air
= NULL
;
486 int err
= __nscd_getai (name
, &air
, &h_errno
);
488 if (__glibc_unlikely (air
== NULL
))
490 /* The database contains a negative entry. */
493 if (__nss_not_use_nscd_hosts
== 0)
495 if (h_errno
== NETDB_INTERNAL
&& errno
== ENOMEM
)
497 if (h_errno
== TRY_AGAIN
)
504 /* Transform into gaih_addrtuple list. */
506 char *addrs
= air
->addrs
;
508 struct gaih_addrtuple
*addrfree
= calloc (air
->naddrs
, sizeof (*addrfree
));
509 struct gaih_addrtuple
*at
= calloc (air
->naddrs
, sizeof (*at
));
512 result
= -EAI_MEMORY
;
519 for (int i
= 0; i
< air
->naddrs
; ++i
)
521 socklen_t size
= (air
->family
[i
] == AF_INET
522 ? INADDRSZ
: IN6ADDRSZ
);
524 if (!((air
->family
[i
] == AF_INET
525 && req
->ai_family
== AF_INET6
526 && (req
->ai_flags
& AI_V4MAPPED
) != 0)
527 || req
->ai_family
== AF_UNSPEC
528 || air
->family
[i
] == req
->ai_family
))
530 /* Skip over non-matching result. */
535 if (air
->family
[i
] == AF_INET
&& req
->ai_family
== AF_INET6
536 && (req
->ai_flags
& AI_V4MAPPED
))
538 at
[count
].family
= AF_INET6
;
539 at
[count
].addr
[3] = *(uint32_t *) addrs
;
540 at
[count
].addr
[2] = htonl (0xffff);
542 else if (req
->ai_family
== AF_UNSPEC
543 || air
->family
[i
] == req
->ai_family
)
545 at
[count
].family
= air
->family
[i
];
546 memcpy (at
[count
].addr
, addrs
, size
);
547 if (air
->family
[i
] == AF_INET6
)
548 res
->got_ipv6
= true;
550 at
[count
].next
= at
+ count
+ 1;
555 if ((req
->ai_flags
& AI_CANONNAME
) && air
->canon
!= NULL
)
557 char *canonbuf
= __strdup (air
->canon
);
558 if (canonbuf
== NULL
)
560 result
= -EAI_MEMORY
;
563 res
->canon
= canonbuf
;
568 result
= -EAI_NONAME
;
572 at
[count
- 1].next
= NULL
;
581 res
->free_at
= false;
589 get_nss_addresses (const char *name
, const struct addrinfo
*req
,
590 struct scratch_buffer
*tmpbuf
, struct gaih_result
*res
)
593 int no_inet6_data
= 0;
595 enum nss_status inet6_status
= NSS_STATUS_UNAVAIL
;
596 enum nss_status status
= NSS_STATUS_UNAVAIL
;
598 struct resolv_context
*res_ctx
= NULL
;
599 bool do_merge
= false;
602 no_more
= !__nss_database_get (nss_database_hosts
, &nip
);
604 /* If we are looking for both IPv4 and IPv6 address we don't
605 want the lookup functions to automatically promote IPv4
606 addresses to IPv6 addresses, so we use the no_inet6
608 res_ctx
= __resolv_context_get ();
614 /* Always start afresh; continue should discard previous results
615 and the hosts database does not support merge. */
616 gaih_result_reset (res
);
620 __set_h_errno (NETDB_INTERNAL
);
626 nss_gethostbyname4_r
*fct4
= NULL
;
628 /* gethostbyname4_r sends out parallel A and AAAA queries and
629 is thus only suitable for PF_UNSPEC. */
630 if (req
->ai_family
== PF_UNSPEC
)
631 fct4
= __nss_lookup_function (nip
, "gethostbyname4_r");
637 status
= DL_CALL_FCT (fct4
, (name
, &res
->at
,
638 tmpbuf
->data
, tmpbuf
->length
,
641 if (status
== NSS_STATUS_SUCCESS
)
643 /* gethostbyname4_r may write into AT, so reset it. */
645 if (status
!= NSS_STATUS_TRYAGAIN
646 || errno
!= ERANGE
|| h_errno
!= NETDB_INTERNAL
)
648 if (h_errno
== TRY_AGAIN
)
651 no_data
= h_errno
== NO_DATA
;
655 if (!scratch_buffer_grow (tmpbuf
))
657 __resolv_context_put (res_ctx
);
658 result
= -EAI_MEMORY
;
663 if (status
== NSS_STATUS_SUCCESS
)
668 if ((req
->ai_flags
& AI_CANONNAME
) != 0 && res
->canon
== NULL
)
670 char *canonbuf
= __strdup (res
->at
->name
);
671 if (canonbuf
== NULL
)
673 __resolv_context_put (res_ctx
);
674 result
= -EAI_MEMORY
;
677 res
->canon
= canonbuf
;
680 struct gaih_addrtuple
**pat
= &res
->at
;
684 if ((*pat
)->family
== AF_INET
685 && req
->ai_family
== AF_INET6
686 && (req
->ai_flags
& AI_V4MAPPED
) != 0)
688 uint32_t *pataddr
= (*pat
)->addr
;
689 (*pat
)->family
= AF_INET6
;
690 pataddr
[3] = pataddr
[0];
691 pataddr
[2] = htonl (0xffff);
694 pat
= &((*pat
)->next
);
697 else if (req
->ai_family
== AF_UNSPEC
698 || (*pat
)->family
== req
->ai_family
)
700 pat
= &((*pat
)->next
);
703 if (req
->ai_family
== AF_INET6
)
704 res
->got_ipv6
= true;
707 *pat
= ((*pat
)->next
);
711 no_inet6_data
= no_data
;
715 nss_gethostbyname3_r
*fct
= NULL
;
716 if (req
->ai_flags
& AI_CANONNAME
)
717 /* No need to use this function if we do not look for
718 the canonical name. The function does not exist in
719 all NSS modules and therefore the lookup would
721 fct
= __nss_lookup_function (nip
, "gethostbyname3_r");
723 /* We are cheating here. The gethostbyname2_r
724 function does not have the same interface as
725 gethostbyname3_r but the extra arguments the
726 latter takes are added at the end. So the
727 gethostbyname2_r code will just ignore them. */
728 fct
= __nss_lookup_function (nip
, "gethostbyname2_r");
732 if (req
->ai_family
== AF_INET6
733 || req
->ai_family
== AF_UNSPEC
)
735 if ((result
= gethosts (fct
, AF_INET6
, name
, req
, tmpbuf
,
736 res
, &status
, &no_data
)) != 0)
738 __resolv_context_put (res_ctx
);
741 no_inet6_data
= no_data
;
742 inet6_status
= status
;
744 if (req
->ai_family
== AF_INET
745 || req
->ai_family
== AF_UNSPEC
746 || (req
->ai_family
== AF_INET6
747 && (req
->ai_flags
& AI_V4MAPPED
)
748 /* Avoid generating the mapped addresses if we
749 know we are not going to need them. */
750 && ((req
->ai_flags
& AI_ALL
) || !res
->got_ipv6
)))
752 if ((result
= gethosts (fct
, AF_INET
, name
, req
, tmpbuf
,
753 res
, &status
, &no_data
)) != 0)
755 __resolv_context_put (res_ctx
);
759 if (req
->ai_family
== AF_INET
)
761 no_inet6_data
= no_data
;
762 inet6_status
= status
;
766 /* If we found one address for AF_INET or AF_INET6,
767 don't continue the search. */
768 if (inet6_status
== NSS_STATUS_SUCCESS
769 || status
== NSS_STATUS_SUCCESS
)
771 if ((req
->ai_flags
& AI_CANONNAME
) != 0
772 && res
->canon
== NULL
)
774 char *canonbuf
= getcanonname (nip
, res
->at
, name
);
775 if (canonbuf
== NULL
)
777 __resolv_context_put (res_ctx
);
778 result
= -EAI_MEMORY
;
781 res
->canon
= canonbuf
;
783 status
= NSS_STATUS_SUCCESS
;
787 /* We can have different states for AF_INET and
788 AF_INET6. Try to find a useful one for both. */
789 if (inet6_status
== NSS_STATUS_TRYAGAIN
)
790 status
= NSS_STATUS_TRYAGAIN
;
791 else if (status
== NSS_STATUS_UNAVAIL
792 && inet6_status
!= NSS_STATUS_UNAVAIL
)
793 status
= inet6_status
;
798 /* Could not locate any of the lookup functions.
799 The NSS lookup code does not consistently set
800 errno, so we need to supply our own error
801 code here. The root cause could either be a
802 resource allocation failure, or a missing
803 service function in the DSO (so it should not
804 be listed in /etc/nsswitch.conf). Assume the
805 former, and return EBUSY. */
806 status
= NSS_STATUS_UNAVAIL
;
807 __set_h_errno (NETDB_INTERNAL
);
812 if (nss_next_action (nip
, status
) == NSS_ACTION_RETURN
)
815 /* The hosts database does not support MERGE. */
816 if (nss_next_action (nip
, status
) == NSS_ACTION_MERGE
)
820 if (nip
->module
== NULL
)
824 __resolv_context_put (res_ctx
);
826 /* If we have a failure which sets errno, report it using
828 if ((status
== NSS_STATUS_TRYAGAIN
|| status
== NSS_STATUS_UNAVAIL
)
829 && h_errno
== NETDB_INTERNAL
)
831 result
= -EAI_SYSTEM
;
835 if (no_data
!= 0 && no_inet6_data
!= 0)
837 /* If both requests timed out report this. */
838 if (no_data
== EAI_AGAIN
&& no_inet6_data
== EAI_AGAIN
)
841 /* We made requests but they turned out no data. The name
843 result
= -EAI_NODATA
;
848 gaih_result_reset (res
);
852 /* Convert numeric addresses to binary into RES. On failure, RES->AT is set to
853 NULL and an error code is returned. If AI_NUMERIC_HOST is not requested and
854 the function cannot determine a result, RES->AT is set to NULL and 0
858 text_to_binary_address (const char *name
, const struct addrinfo
*req
,
859 struct gaih_result
*res
)
861 struct gaih_addrtuple
*at
= res
->at
;
866 memset (at
->addr
, 0, sizeof (at
->addr
));
867 if (__inet_aton_exact (name
, (struct in_addr
*) at
->addr
) != 0)
869 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET
)
870 at
->family
= AF_INET
;
871 else if (req
->ai_family
== AF_INET6
&& (req
->ai_flags
& AI_V4MAPPED
))
873 at
->addr
[3] = at
->addr
[0];
874 at
->addr
[2] = htonl (0xffff);
877 at
->family
= AF_INET6
;
881 result
= -EAI_ADDRFAMILY
;
885 if (req
->ai_flags
& AI_CANONNAME
)
887 char *canonbuf
= __strdup (name
);
888 if (canonbuf
== NULL
)
890 result
= -EAI_MEMORY
;
893 res
->canon
= canonbuf
;
898 char *scope_delim
= strchr (name
, SCOPE_DELIMITER
);
901 if (scope_delim
== NULL
)
902 e
= inet_pton (AF_INET6
, name
, at
->addr
);
904 e
= __inet_pton_length (AF_INET6
, name
, scope_delim
- name
, at
->addr
);
908 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET6
)
909 at
->family
= AF_INET6
;
910 else if (req
->ai_family
== AF_INET
911 && IN6_IS_ADDR_V4MAPPED (at
->addr
))
913 at
->addr
[0] = at
->addr
[3];
914 at
->family
= AF_INET
;
918 result
= -EAI_ADDRFAMILY
;
922 if (scope_delim
!= NULL
923 && __inet6_scopeid_pton ((struct in6_addr
*) at
->addr
,
924 scope_delim
+ 1, &at
->scopeid
) != 0)
926 result
= -EAI_NONAME
;
930 if (req
->ai_flags
& AI_CANONNAME
)
932 char *canonbuf
= __strdup (name
);
933 if (canonbuf
== NULL
)
935 result
= -EAI_MEMORY
;
938 res
->canon
= canonbuf
;
943 if ((req
->ai_flags
& AI_NUMERICHOST
))
944 result
= -EAI_NONAME
;
951 /* If possible, call the simple, old functions, which do not support IPv6 scope
952 ids, nor retrieving the canonical name. */
955 try_simple_gethostbyname (const char *name
, const struct addrinfo
*req
,
956 struct scratch_buffer
*tmpbuf
,
957 struct gaih_result
*res
)
961 if (req
->ai_family
!= AF_INET
|| (req
->ai_flags
& AI_CANONNAME
) != 0)
970 rc
= __gethostbyname2_r (name
, AF_INET
, &th
, tmpbuf
->data
,
971 tmpbuf
->length
, &h
, &h_errno
);
972 if (rc
!= ERANGE
|| h_errno
!= NETDB_INTERNAL
)
974 if (!scratch_buffer_grow (tmpbuf
))
982 /* We found data, convert it. RES->AT from the conversion will
983 either be an allocated block or NULL, both of which are safe to
985 if (!convert_hostent_to_gaih_addrtuple (req
, AF_INET
, h
, res
))
991 if (h_errno
== NO_DATA
)
997 if (h_errno
== NETDB_INTERNAL
)
999 if (h_errno
== TRY_AGAIN
)
1002 /* We made requests but they turned out no data.
1003 The name is known, though. */
1007 /* Add local address information into RES. RES->AT is assumed to have enough
1008 space for two tuples and is zeroed out. */
1011 get_local_addresses (const struct addrinfo
*req
, struct gaih_result
*res
)
1013 struct gaih_addrtuple
*atr
= res
->at
;
1014 if (req
->ai_family
== AF_UNSPEC
)
1015 res
->at
->next
= res
->at
+ 1;
1017 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET6
)
1019 res
->at
->family
= AF_INET6
;
1020 if ((req
->ai_flags
& AI_PASSIVE
) == 0)
1021 memcpy (res
->at
->addr
, &in6addr_loopback
, sizeof (struct in6_addr
));
1022 atr
= res
->at
->next
;
1025 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET
)
1027 atr
->family
= AF_INET
;
1028 if ((req
->ai_flags
& AI_PASSIVE
) == 0)
1029 atr
->addr
[0] = htonl (INADDR_LOOPBACK
);
1033 /* Generate results in PAI and its count in NADDRS. Return 0 on success or an
1034 error code on failure. */
1037 generate_addrinfo (const struct addrinfo
*req
, struct gaih_result
*res
,
1038 const struct gaih_servtuple
*st
, struct addrinfo
**pai
,
1039 unsigned int *naddrs
)
1044 /* Buffer is the size of an unformatted IPv6 address in printable format. */
1045 for (struct gaih_addrtuple
*at
= res
->at
; at
!= NULL
; at
= at
->next
)
1047 family
= at
->family
;
1048 if (family
== AF_INET6
)
1050 socklen
= sizeof (struct sockaddr_in6
);
1052 /* If we looked up IPv4 mapped address discard them here if
1053 the caller isn't interested in all address and we have
1054 found at least one IPv6 address. */
1056 && (req
->ai_flags
& (AI_V4MAPPED
|AI_ALL
)) == AI_V4MAPPED
1057 && IN6_IS_ADDR_V4MAPPED (at
->addr
))
1061 socklen
= sizeof (struct sockaddr_in
);
1063 for (int i
= 0; st
[i
].set
; i
++)
1065 struct addrinfo
*ai
;
1066 ai
= *pai
= malloc (sizeof (struct addrinfo
) + socklen
);
1070 ai
->ai_flags
= req
->ai_flags
;
1071 ai
->ai_family
= family
;
1072 ai
->ai_socktype
= st
[i
].socktype
;
1073 ai
->ai_protocol
= st
[i
].protocol
;
1074 ai
->ai_addrlen
= socklen
;
1075 ai
->ai_addr
= (void *) (ai
+ 1);
1077 /* We only add the canonical name once. */
1078 ai
->ai_canonname
= res
->canon
;
1082 ai
->ai_addr
->sa_len
= socklen
;
1083 #endif /* _HAVE_SA_LEN */
1084 ai
->ai_addr
->sa_family
= family
;
1086 /* In case of an allocation error the list must be NULL
1090 if (family
== AF_INET6
)
1092 struct sockaddr_in6
*sin6p
= (struct sockaddr_in6
*) ai
->ai_addr
;
1093 sin6p
->sin6_port
= st
[i
].port
;
1094 sin6p
->sin6_flowinfo
= 0;
1095 memcpy (&sin6p
->sin6_addr
, at
->addr
, sizeof (struct in6_addr
));
1096 sin6p
->sin6_scope_id
= at
->scopeid
;
1100 struct sockaddr_in
*sinp
= (struct sockaddr_in
*) ai
->ai_addr
;
1101 sinp
->sin_port
= st
[i
].port
;
1102 memcpy (&sinp
->sin_addr
, at
->addr
, sizeof (struct in_addr
));
1103 memset (sinp
->sin_zero
, '\0', sizeof (sinp
->sin_zero
));
1106 pai
= &(ai
->ai_next
);
1115 gaih_inet (const char *name
, const struct gaih_service
*service
,
1116 const struct addrinfo
*req
, struct addrinfo
**pai
,
1117 unsigned int *naddrs
, struct scratch_buffer
*tmpbuf
)
1119 struct gaih_servtuple st
[sizeof (gaih_inet_typeproto
)
1120 / sizeof (struct gaih_typeproto
)] = {0};
1122 const char *orig_name
= name
;
1125 if ((rc
= get_servtuples (service
, req
, st
, tmpbuf
)) != 0)
1128 bool malloc_name
= false;
1129 struct gaih_addrtuple
*addrmem
= NULL
;
1132 struct gaih_result res
= {0};
1133 struct gaih_addrtuple local_at
[2] = {0};
1137 if (__glibc_unlikely (name
== NULL
))
1139 get_local_addresses (req
, &res
);
1143 if (req
->ai_flags
& AI_IDN
)
1146 result
= __idna_to_dns_encoding (name
, &out
);
1153 if ((result
= text_to_binary_address (name
, req
, &res
)) != 0)
1154 goto free_and_return
;
1155 else if (res
.at
!= NULL
)
1158 if ((result
= try_simple_gethostbyname (name
, req
, tmpbuf
, &res
)) != 0)
1159 goto free_and_return
;
1160 else if (res
.at
!= NULL
)
1164 if ((result
= get_nscd_addresses (name
, req
, &res
)) != 0)
1165 goto free_and_return
;
1166 else if (res
.at
!= NULL
)
1170 if ((result
= get_nss_addresses (name
, req
, tmpbuf
, &res
)) != 0)
1171 goto free_and_return
;
1172 else if (res
.at
!= NULL
)
1175 /* None of the lookups worked, so name not found. */
1176 result
= -EAI_NONAME
;
1177 goto free_and_return
;
1180 /* Set up the canonical name if we need it. */
1181 if ((result
= process_canonname (req
, orig_name
, &res
)) != 0)
1182 goto free_and_return
;
1184 result
= generate_addrinfo (req
, &res
, st
, pai
, naddrs
);
1188 free ((char *) name
);
1200 struct addrinfo
*dest_addr
;
1201 /* Using sockaddr_storage is for now overkill. We only support IPv4
1202 and IPv6 so far. If this changes at some point we can adjust the
1204 struct sockaddr_in6 source_addr
;
1205 uint8_t source_addr_len
;
1206 bool got_source_addr
;
1207 uint8_t source_addr_flags
;
1213 struct sort_result_combo
1215 struct sort_result
*results
;
1220 #if __BYTE_ORDER == __BIG_ENDIAN
1221 # define htonl_c(n) n
1223 # define htonl_c(n) __bswap_constant_32 (n)
1226 static const struct scopeentry
1235 } default_scopes
[] =
1237 /* Link-local addresses: scope 2. */
1238 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1239 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1240 /* Default: scope 14. */
1241 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1244 /* The label table. */
1245 static const struct scopeentry
*scopes
;
1249 get_scope (const struct sockaddr_in6
*in6
)
1252 if (in6
->sin6_family
== PF_INET6
)
1254 if (! IN6_IS_ADDR_MULTICAST (&in6
->sin6_addr
))
1256 if (IN6_IS_ADDR_LINKLOCAL (&in6
->sin6_addr
)
1257 /* RFC 4291 2.5.3 says that the loopback address is to be
1258 treated like a link-local address. */
1259 || IN6_IS_ADDR_LOOPBACK (&in6
->sin6_addr
))
1261 else if (IN6_IS_ADDR_SITELOCAL (&in6
->sin6_addr
))
1264 /* XXX Is this the correct default behavior? */
1268 scope
= in6
->sin6_addr
.s6_addr
[1] & 0xf;
1270 else if (in6
->sin6_family
== PF_INET
)
1272 const struct sockaddr_in
*in
= (const struct sockaddr_in
*) in6
;
1277 if ((in
->sin_addr
.s_addr
& scopes
[cnt
].netmask
)
1278 == scopes
[cnt
].addr32
)
1279 return scopes
[cnt
].scope
;
1286 /* XXX What is a good default? */
1295 struct in6_addr prefix
;
1301 /* The label table. */
1302 static const struct prefixentry
*labels
;
1304 /* Default labels. */
1305 static const struct prefixentry default_labels
[] =
1307 /* See RFC 3484 for the details. */
1309 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1313 = { .__u6_addr8
= { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1317 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1321 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1322 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1324 /* The next two entries differ from RFC 3484. We need to treat
1325 IPv6 site-local addresses special because they are never NATed,
1326 unlike site-locale IPv4 addresses. If this would not happen, on
1327 machines which have only IPv4 and IPv6 site-local addresses, the
1328 sorting would prefer the IPv6 site-local addresses, causing
1329 unnecessary delays when trying to connect to a global IPv6 address
1330 through a site-local IPv6 address. */
1332 = { .__u6_addr8
= { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1336 = { .__u6_addr8
= { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1339 /* Additional rule for Teredo tunnels. */
1341 = { .__u6_addr8
= { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1345 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1351 /* The precedence table. */
1352 static const struct prefixentry
*precedence
;
1354 /* The default precedences. */
1355 static const struct prefixentry default_precedence
[] =
1357 /* See RFC 3484 for the details. */
1359 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1363 = { .__u6_addr8
= { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1367 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1371 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1372 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1375 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1382 match_prefix (const struct sockaddr_in6
*in6
,
1383 const struct prefixentry
*list
, int default_val
)
1386 struct sockaddr_in6 in6_mem
;
1388 if (in6
->sin6_family
== PF_INET
)
1390 const struct sockaddr_in
*in
= (const struct sockaddr_in
*) in6
;
1392 /* Construct a V4-to-6 mapped address. */
1393 in6_mem
.sin6_family
= PF_INET6
;
1394 in6_mem
.sin6_port
= in
->sin_port
;
1395 in6_mem
.sin6_flowinfo
= 0;
1396 memset (&in6_mem
.sin6_addr
, '\0', sizeof (in6_mem
.sin6_addr
));
1397 in6_mem
.sin6_addr
.s6_addr16
[5] = 0xffff;
1398 in6_mem
.sin6_addr
.s6_addr32
[3] = in
->sin_addr
.s_addr
;
1399 in6_mem
.sin6_scope_id
= 0;
1403 else if (in6
->sin6_family
!= PF_INET6
)
1406 for (idx
= 0; ; ++idx
)
1408 unsigned int bits
= list
[idx
].bits
;
1409 const uint8_t *mask
= list
[idx
].prefix
.s6_addr
;
1410 const uint8_t *val
= in6
->sin6_addr
.s6_addr
;
1424 if ((*mask
& (0xff00 >> bits
)) == (*val
& (0xff00 >> bits
)))
1430 return list
[idx
].val
;
1435 get_label (const struct sockaddr_in6
*in6
)
1437 /* XXX What is a good default value? */
1438 return match_prefix (in6
, labels
, INT_MAX
);
1443 get_precedence (const struct sockaddr_in6
*in6
)
1445 /* XXX What is a good default value? */
1446 return match_prefix (in6
, precedence
, 0);
1450 /* Find last bit set in a word. */
1456 for (n
= 0, mask
= 1 << 31; n
< 32; mask
>>= 1, ++n
)
1457 if ((a
& mask
) != 0)
1464 rfc3484_sort (const void *p1
, const void *p2
, void *arg
)
1466 const size_t idx1
= *(const size_t *) p1
;
1467 const size_t idx2
= *(const size_t *) p2
;
1468 struct sort_result_combo
*src
= (struct sort_result_combo
*) arg
;
1469 struct sort_result
*a1
= &src
->results
[idx1
];
1470 struct sort_result
*a2
= &src
->results
[idx2
];
1472 /* Rule 1: Avoid unusable destinations.
1473 We have the got_source_addr flag set if the destination is reachable. */
1474 if (a1
->got_source_addr
&& ! a2
->got_source_addr
)
1476 if (! a1
->got_source_addr
&& a2
->got_source_addr
)
1480 /* Rule 2: Prefer matching scope. Only interesting if both
1481 destination addresses are IPv6. */
1483 = get_scope ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1486 = get_scope ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1488 if (a1
->got_source_addr
)
1490 int a1_src_scope
= get_scope (&a1
->source_addr
);
1491 int a2_src_scope
= get_scope (&a2
->source_addr
);
1493 if (a1_dst_scope
== a1_src_scope
&& a2_dst_scope
!= a2_src_scope
)
1495 if (a1_dst_scope
!= a1_src_scope
&& a2_dst_scope
== a2_src_scope
)
1500 /* Rule 3: Avoid deprecated addresses. */
1501 if (a1
->got_source_addr
)
1503 if (!(a1
->source_addr_flags
& in6ai_deprecated
)
1504 && (a2
->source_addr_flags
& in6ai_deprecated
))
1506 if ((a1
->source_addr_flags
& in6ai_deprecated
)
1507 && !(a2
->source_addr_flags
& in6ai_deprecated
))
1511 /* Rule 4: Prefer home addresses. */
1512 if (a1
->got_source_addr
)
1514 if (!(a1
->source_addr_flags
& in6ai_homeaddress
)
1515 && (a2
->source_addr_flags
& in6ai_homeaddress
))
1517 if ((a1
->source_addr_flags
& in6ai_homeaddress
)
1518 && !(a2
->source_addr_flags
& in6ai_homeaddress
))
1522 /* Rule 5: Prefer matching label. */
1523 if (a1
->got_source_addr
)
1526 = get_label ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1527 int a1_src_label
= get_label (&a1
->source_addr
);
1530 = get_label ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1531 int a2_src_label
= get_label (&a2
->source_addr
);
1533 if (a1_dst_label
== a1_src_label
&& a2_dst_label
!= a2_src_label
)
1535 if (a1_dst_label
!= a1_src_label
&& a2_dst_label
== a2_src_label
)
1540 /* Rule 6: Prefer higher precedence. */
1542 = get_precedence ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1544 = get_precedence ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1546 if (a1_prec
> a2_prec
)
1548 if (a1_prec
< a2_prec
)
1552 /* Rule 7: Prefer native transport. */
1553 if (a1
->got_source_addr
)
1555 /* The same interface index means the same interface which means
1556 there is no difference in transport. This should catch many
1558 if (a1
->index
!= a2
->index
)
1560 int a1_native
= a1
->native
;
1561 int a2_native
= a2
->native
;
1563 if (a1_native
== -1 || a2_native
== -1)
1566 if (a1_native
== -1)
1568 /* If we do not have the information use 'native' as
1571 a1_index
= a1
->index
;
1574 a1_index
= 0xffffffffu
;
1577 if (a2_native
== -1)
1579 /* If we do not have the information use 'native' as
1582 a2_index
= a2
->index
;
1585 a2_index
= 0xffffffffu
;
1587 __check_native (a1_index
, &a1_native
, a2_index
, &a2_native
);
1589 /* Fill in the results in all the records. */
1590 for (int i
= 0; i
< src
->nresults
; ++i
)
1591 if (a1_index
!= -1 && src
->results
[i
].index
== a1_index
)
1593 assert (src
->results
[i
].native
== -1
1594 || src
->results
[i
].native
== a1_native
);
1595 src
->results
[i
].native
= a1_native
;
1597 else if (a2_index
!= -1 && src
->results
[i
].index
== a2_index
)
1599 assert (src
->results
[i
].native
== -1
1600 || src
->results
[i
].native
== a2_native
);
1601 src
->results
[i
].native
= a2_native
;
1605 if (a1_native
&& !a2_native
)
1607 if (!a1_native
&& a2_native
)
1613 /* Rule 8: Prefer smaller scope. */
1614 if (a1_dst_scope
< a2_dst_scope
)
1616 if (a1_dst_scope
> a2_dst_scope
)
1620 /* Rule 9: Use longest matching prefix. */
1621 if (a1
->got_source_addr
1622 && a1
->dest_addr
->ai_family
== a2
->dest_addr
->ai_family
)
1627 if (a1
->dest_addr
->ai_family
== PF_INET
)
1629 assert (a1
->source_addr
.sin6_family
== PF_INET
);
1630 assert (a2
->source_addr
.sin6_family
== PF_INET
);
1632 /* Outside of subnets, as defined by the network masks,
1633 common address prefixes for IPv4 addresses make no sense.
1634 So, define a non-zero value only if source and
1635 destination address are on the same subnet. */
1636 struct sockaddr_in
*in1_dst
1637 = (struct sockaddr_in
*) a1
->dest_addr
->ai_addr
;
1638 in_addr_t in1_dst_addr
= ntohl (in1_dst
->sin_addr
.s_addr
);
1639 struct sockaddr_in
*in1_src
1640 = (struct sockaddr_in
*) &a1
->source_addr
;
1641 in_addr_t in1_src_addr
= ntohl (in1_src
->sin_addr
.s_addr
);
1642 in_addr_t netmask1
= 0xffffffffu
<< (32 - a1
->prefixlen
);
1644 if ((in1_src_addr
& netmask1
) == (in1_dst_addr
& netmask1
))
1645 bit1
= fls (in1_dst_addr
^ in1_src_addr
);
1647 struct sockaddr_in
*in2_dst
1648 = (struct sockaddr_in
*) a2
->dest_addr
->ai_addr
;
1649 in_addr_t in2_dst_addr
= ntohl (in2_dst
->sin_addr
.s_addr
);
1650 struct sockaddr_in
*in2_src
1651 = (struct sockaddr_in
*) &a2
->source_addr
;
1652 in_addr_t in2_src_addr
= ntohl (in2_src
->sin_addr
.s_addr
);
1653 in_addr_t netmask2
= 0xffffffffu
<< (32 - a2
->prefixlen
);
1655 if ((in2_src_addr
& netmask2
) == (in2_dst_addr
& netmask2
))
1656 bit2
= fls (in2_dst_addr
^ in2_src_addr
);
1658 else if (a1
->dest_addr
->ai_family
== PF_INET6
)
1660 assert (a1
->source_addr
.sin6_family
== PF_INET6
);
1661 assert (a2
->source_addr
.sin6_family
== PF_INET6
);
1663 struct sockaddr_in6
*in1_dst
;
1664 struct sockaddr_in6
*in1_src
;
1665 struct sockaddr_in6
*in2_dst
;
1666 struct sockaddr_in6
*in2_src
;
1668 in1_dst
= (struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
;
1669 in1_src
= (struct sockaddr_in6
*) &a1
->source_addr
;
1670 in2_dst
= (struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
;
1671 in2_src
= (struct sockaddr_in6
*) &a2
->source_addr
;
1674 for (i
= 0; i
< 4; ++i
)
1675 if (in1_dst
->sin6_addr
.s6_addr32
[i
]
1676 != in1_src
->sin6_addr
.s6_addr32
[i
]
1677 || (in2_dst
->sin6_addr
.s6_addr32
[i
]
1678 != in2_src
->sin6_addr
.s6_addr32
[i
]))
1683 bit1
= fls (ntohl (in1_dst
->sin6_addr
.s6_addr32
[i
]
1684 ^ in1_src
->sin6_addr
.s6_addr32
[i
]));
1685 bit2
= fls (ntohl (in2_dst
->sin6_addr
.s6_addr32
[i
]
1686 ^ in2_src
->sin6_addr
.s6_addr32
[i
]));
1697 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1698 compare with the value indicating the order in which the entries
1699 have been received from the services. NB: no two entries can have
1700 the same order so the test will never return zero. */
1701 return idx1
< idx2
? -1 : 1;
1706 in6aicmp (const void *p1
, const void *p2
)
1708 struct in6addrinfo
*a1
= (struct in6addrinfo
*) p1
;
1709 struct in6addrinfo
*a2
= (struct in6addrinfo
*) p2
;
1711 return memcmp (a1
->addr
, a2
->addr
, sizeof (a1
->addr
));
1715 /* Name of the config file for RFC 3484 sorting (for now). */
1716 #define GAICONF_FNAME "/etc/gai.conf"
1719 /* Non-zero if we are supposed to reload the config file automatically
1720 whenever it changed. */
1721 static int gaiconf_reload_flag
;
1723 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1724 static int gaiconf_reload_flag_ever_set
;
1726 /* Last modification time. */
1727 #ifdef _STATBUF_ST_NSEC
1729 static struct __timespec64 gaiconf_mtime
;
1732 save_gaiconf_mtime (const struct __stat64_t64
*st
)
1734 gaiconf_mtime
= (struct __timespec64
) { st
->st_mtim
.tv_sec
,
1735 st
->st_mtim
.tv_nsec
};
1739 check_gaiconf_mtime (const struct __stat64_t64
*st
)
1741 return (st
->st_mtim
.tv_sec
== gaiconf_mtime
.tv_sec
1742 && st
->st_mtim
.tv_nsec
== gaiconf_mtime
.tv_nsec
);
1747 static time_t gaiconf_mtime
;
1750 save_gaiconf_mtime (const struct __stat64_t64
*st
)
1752 gaiconf_mtime
= st
->st_mtime
;
1756 check_gaiconf_mtime (const struct __stat64_t64
*st
)
1758 return st
->st_mtime
== gaiconf_mtime
;
1764 libc_freeres_fn(fini
)
1766 if (labels
!= default_labels
)
1768 const struct prefixentry
*old
= labels
;
1769 labels
= default_labels
;
1770 free ((void *) old
);
1773 if (precedence
!= default_precedence
)
1775 const struct prefixentry
*old
= precedence
;
1776 precedence
= default_precedence
;
1777 free ((void *) old
);
1780 if (scopes
!= default_scopes
)
1782 const struct scopeentry
*old
= scopes
;
1783 scopes
= default_scopes
;
1784 free ((void *) old
);
1791 struct prefixentry entry
;
1792 struct prefixlist
*next
;
1798 struct scopeentry entry
;
1799 struct scopelist
*next
;
1804 free_prefixlist (struct prefixlist
*list
)
1806 while (list
!= NULL
)
1808 struct prefixlist
*oldp
= list
;
1816 free_scopelist (struct scopelist
*list
)
1818 while (list
!= NULL
)
1820 struct scopelist
*oldp
= list
;
1828 prefixcmp (const void *p1
, const void *p2
)
1830 const struct prefixentry
*e1
= (const struct prefixentry
*) p1
;
1831 const struct prefixentry
*e2
= (const struct prefixentry
*) p2
;
1833 if (e1
->bits
< e2
->bits
)
1835 if (e1
->bits
== e2
->bits
)
1842 scopecmp (const void *p1
, const void *p2
)
1844 const struct scopeentry
*e1
= (const struct scopeentry
*) p1
;
1845 const struct scopeentry
*e2
= (const struct scopeentry
*) p2
;
1847 if (e1
->netmask
> e2
->netmask
)
1849 if (e1
->netmask
== e2
->netmask
)
1855 add_prefixlist (struct prefixlist
**listp
, size_t *lenp
, bool *nullbitsp
,
1856 char *val1
, char *val2
, char **pos
)
1858 struct in6_addr prefix
;
1859 unsigned long int bits
;
1860 unsigned long int val
;
1865 char *cp
= strchr (val1
, '/');
1869 if (inet_pton (AF_INET6
, val1
, &prefix
)
1871 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
1875 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
1880 struct prefixlist
*newp
= malloc (sizeof (*newp
));
1884 memcpy (&newp
->entry
.prefix
, &prefix
, sizeof (prefix
));
1885 newp
->entry
.bits
= bits
;
1886 newp
->entry
.val
= val
;
1887 newp
->next
= *listp
;
1890 *nullbitsp
|= bits
== 0;
1896 add_scopelist (struct scopelist
**listp
, size_t *lenp
, bool *nullbitsp
,
1897 const struct in6_addr
*prefixp
, unsigned long int bits
,
1898 unsigned long int val
)
1900 struct scopelist
*newp
= malloc (sizeof (*newp
));
1904 newp
->entry
.netmask
= htonl (bits
!= 96 ? (0xffffffff << (128 - bits
)) : 0);
1905 newp
->entry
.addr32
= (prefixp
->s6_addr32
[3] & newp
->entry
.netmask
);
1906 newp
->entry
.scope
= val
;
1907 newp
->next
= *listp
;
1910 *nullbitsp
|= bits
== 96;
1918 struct prefixlist
*labellist
= NULL
;
1919 size_t nlabellist
= 0;
1920 bool labellist_nullbits
= false;
1921 struct prefixlist
*precedencelist
= NULL
;
1922 size_t nprecedencelist
= 0;
1923 bool precedencelist_nullbits
= false;
1924 struct scopelist
*scopelist
= NULL
;
1925 size_t nscopelist
= 0;
1926 bool scopelist_nullbits
= false;
1928 FILE *fp
= fopen (GAICONF_FNAME
, "rce");
1932 struct __stat64_t64 st
;
1933 if (__fstat64_time64 (fileno (fp
), &st
) != 0)
1942 __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
1944 while (!feof_unlocked (fp
))
1946 ssize_t n
= __getline (&line
, &linelen
, fp
);
1950 /* Handle comments. No escaping possible so this is easy. */
1951 char *cp
= strchr (line
, '#');
1956 while (isspace (*cp
))
1960 while (*cp
!= '\0' && !isspace (*cp
))
1962 size_t cmdlen
= cp
- cmd
;
1966 while (isspace (*cp
))
1970 while (*cp
!= '\0' && !isspace (*cp
))
1972 size_t val1len
= cp
- cmd
;
1974 /* We always need at least two values. */
1980 while (isspace (*cp
))
1984 while (*cp
!= '\0' && !isspace (*cp
))
1987 /* Ignore the rest of the line. */
1993 if (strcmp (cmd
, "label") == 0)
1995 if (!add_prefixlist (&labellist
, &nlabellist
,
1996 &labellist_nullbits
, val1
, val2
, &cp
))
2006 if (strcmp (cmd
, "reload") == 0)
2008 gaiconf_reload_flag
= strcmp (val1
, "yes") == 0;
2009 if (gaiconf_reload_flag
)
2010 gaiconf_reload_flag_ever_set
= 1;
2015 if (strcmp (cmd
, "scopev4") == 0)
2017 struct in6_addr prefix
;
2018 unsigned long int bits
;
2019 unsigned long int val
;
2024 cp
= strchr (val1
, '/');
2027 if (inet_pton (AF_INET6
, val1
, &prefix
))
2030 if (IN6_IS_ADDR_V4MAPPED (&prefix
)
2032 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
2037 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
2042 if (!add_scopelist (&scopelist
, &nscopelist
,
2043 &scopelist_nullbits
, &prefix
,
2052 else if (inet_pton (AF_INET
, val1
, &prefix
.s6_addr32
[3])
2054 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
2058 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
2063 if (!add_scopelist (&scopelist
, &nscopelist
,
2064 &scopelist_nullbits
, &prefix
,
2076 if (strcmp (cmd
, "precedence") == 0)
2078 if (!add_prefixlist (&precedencelist
, &nprecedencelist
,
2079 &precedencelist_nullbits
, val1
, val2
,
2095 /* Create the array for the labels. */
2096 struct prefixentry
*new_labels
;
2099 if (!labellist_nullbits
)
2101 new_labels
= malloc (nlabellist
* sizeof (*new_labels
));
2102 if (new_labels
== NULL
)
2106 if (!labellist_nullbits
)
2109 memset (&new_labels
[i
].prefix
, '\0', sizeof (struct in6_addr
));
2110 new_labels
[i
].bits
= 0;
2111 new_labels
[i
].val
= 1;
2114 struct prefixlist
*l
= labellist
;
2117 new_labels
[i
] = l
->entry
;
2120 free_prefixlist (labellist
);
2123 /* Sort the entries so that the most specific ones are at
2125 qsort (new_labels
, nlabellist
, sizeof (*new_labels
), prefixcmp
);
2128 new_labels
= (struct prefixentry
*) default_labels
;
2130 struct prefixentry
*new_precedence
;
2131 if (nprecedencelist
> 0)
2133 if (!precedencelist_nullbits
)
2135 new_precedence
= malloc (nprecedencelist
* sizeof (*new_precedence
));
2136 if (new_precedence
== NULL
)
2138 if (new_labels
!= default_labels
)
2143 int i
= nprecedencelist
;
2144 if (!precedencelist_nullbits
)
2147 memset (&new_precedence
[i
].prefix
, '\0',
2148 sizeof (struct in6_addr
));
2149 new_precedence
[i
].bits
= 0;
2150 new_precedence
[i
].val
= 40;
2153 struct prefixlist
*l
= precedencelist
;
2156 new_precedence
[i
] = l
->entry
;
2159 free_prefixlist (precedencelist
);
2160 precedencelist
= NULL
;
2162 /* Sort the entries so that the most specific ones are at
2164 qsort (new_precedence
, nprecedencelist
, sizeof (*new_precedence
),
2168 new_precedence
= (struct prefixentry
*) default_precedence
;
2170 struct scopeentry
*new_scopes
;
2173 if (!scopelist_nullbits
)
2175 new_scopes
= malloc (nscopelist
* sizeof (*new_scopes
));
2176 if (new_scopes
== NULL
)
2178 if (new_labels
!= default_labels
)
2180 if (new_precedence
!= default_precedence
)
2181 free (new_precedence
);
2186 if (!scopelist_nullbits
)
2189 new_scopes
[i
].addr32
= 0;
2190 new_scopes
[i
].netmask
= 0;
2191 new_scopes
[i
].scope
= 14;
2194 struct scopelist
*l
= scopelist
;
2197 new_scopes
[i
] = l
->entry
;
2200 free_scopelist (scopelist
);
2202 /* Sort the entries so that the most specific ones are at
2204 qsort (new_scopes
, nscopelist
, sizeof (*new_scopes
),
2208 new_scopes
= (struct scopeentry
*) default_scopes
;
2210 /* Now we are ready to replace the values. */
2211 const struct prefixentry
*old
= labels
;
2212 labels
= new_labels
;
2213 if (old
!= default_labels
)
2214 free ((void *) old
);
2217 precedence
= new_precedence
;
2218 if (old
!= default_precedence
)
2219 free ((void *) old
);
2221 const struct scopeentry
*oldscope
= scopes
;
2222 scopes
= new_scopes
;
2223 if (oldscope
!= default_scopes
)
2224 free ((void *) oldscope
);
2226 save_gaiconf_mtime (&st
);
2230 free_prefixlist (labellist
);
2231 free_prefixlist (precedencelist
);
2232 free_scopelist (scopelist
);
2234 /* If we previously read the file but it is gone now, free the old data and
2235 use the builtin one. Leave the reload flag alone. */
2241 gaiconf_reload (void)
2243 struct __stat64_t64 st
;
2244 if (__stat64_time64 (GAICONF_FNAME
, &st
) != 0
2245 || !check_gaiconf_mtime (&st
))
2250 try_connect (int *fdp
, int *afp
, struct sockaddr_in6
*source_addrp
,
2251 const struct sockaddr
*addr
, socklen_t addrlen
, int family
)
2255 socklen_t sl
= sizeof (*source_addrp
);
2259 if (fd
!= -1 && __connect (fd
, addr
, addrlen
) == 0
2260 && __getsockname (fd
, (struct sockaddr
*) source_addrp
, &sl
) == 0)
2263 if (errno
== EAFNOSUPPORT
&& af
== AF_INET6
&& family
== AF_INET
)
2265 /* This could mean IPv6 sockets are IPv6-only. */
2267 __close_nocancel_nostatus (fd
);
2268 *afp
= af
= AF_INET
;
2269 *fdp
= fd
= __socket (AF_INET
, SOCK_DGRAM
| SOCK_CLOEXEC
,
2277 __builtin_unreachable ();
2281 getaddrinfo (const char *name
, const char *service
,
2282 const struct addrinfo
*hints
, struct addrinfo
**pai
)
2284 int i
= 0, last_i
= 0;
2286 struct addrinfo
*p
= NULL
;
2287 struct gaih_service gaih_service
, *pservice
;
2288 struct addrinfo local_hints
;
2290 if (name
!= NULL
&& name
[0] == '*' && name
[1] == 0)
2293 if (service
!= NULL
&& service
[0] == '*' && service
[1] == 0)
2296 if (name
== NULL
&& service
== NULL
)
2300 hints
= &default_hints
;
2303 & ~(AI_PASSIVE
|AI_CANONNAME
|AI_NUMERICHOST
|AI_ADDRCONFIG
|AI_V4MAPPED
2304 |AI_IDN
|AI_CANONIDN
|DEPRECATED_AI_IDN
2305 |AI_NUMERICSERV
|AI_ALL
))
2306 return EAI_BADFLAGS
;
2308 if ((hints
->ai_flags
& AI_CANONNAME
) && name
== NULL
)
2309 return EAI_BADFLAGS
;
2311 if (hints
->ai_family
!= AF_UNSPEC
&& hints
->ai_family
!= AF_INET
2312 && hints
->ai_family
!= AF_INET6
)
2315 struct in6addrinfo
*in6ai
= NULL
;
2316 size_t in6ailen
= 0;
2317 bool seen_ipv4
= false;
2318 bool seen_ipv6
= false;
2319 bool check_pf_called
= false;
2321 if (hints
->ai_flags
& AI_ADDRCONFIG
)
2323 /* We might need information about what interfaces are available.
2324 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2325 cannot cache the results since new interfaces could be added at
2327 __check_pf (&seen_ipv4
, &seen_ipv6
, &in6ai
, &in6ailen
);
2328 check_pf_called
= true;
2330 /* Now make a decision on what we return, if anything. */
2331 if (hints
->ai_family
== PF_UNSPEC
&& (seen_ipv4
|| seen_ipv6
))
2333 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2334 narrow down the search. */
2335 if (seen_ipv4
!= seen_ipv6
)
2337 local_hints
= *hints
;
2338 local_hints
.ai_family
= seen_ipv4
? PF_INET
: PF_INET6
;
2339 hints
= &local_hints
;
2342 else if ((hints
->ai_family
== PF_INET
&& ! seen_ipv4
)
2343 || (hints
->ai_family
== PF_INET6
&& ! seen_ipv6
))
2345 /* We cannot possibly return a valid answer. */
2346 __free_in6ai (in6ai
);
2351 if (service
&& service
[0])
2354 gaih_service
.name
= service
;
2355 gaih_service
.num
= strtoul (gaih_service
.name
, &c
, 10);
2358 if (hints
->ai_flags
& AI_NUMERICSERV
)
2360 __free_in6ai (in6ai
);
2364 gaih_service
.num
= -1;
2367 pservice
= &gaih_service
;
2372 struct addrinfo
**end
= &p
;
2373 unsigned int naddrs
= 0;
2374 struct scratch_buffer tmpbuf
;
2376 scratch_buffer_init (&tmpbuf
);
2377 last_i
= gaih_inet (name
, pservice
, hints
, end
, &naddrs
, &tmpbuf
);
2378 scratch_buffer_free (&tmpbuf
);
2383 __free_in6ai (in6ai
);
2390 end
= &((*end
)->ai_next
);
2396 /* Read the config file. */
2397 __libc_once_define (static, once
);
2398 __typeof (once
) old_once
= once
;
2399 __libc_once (once
, gaiconf_init
);
2400 /* Sort results according to RFC 3484. */
2401 struct sort_result
*results
;
2404 struct addrinfo
*last
= NULL
;
2405 char *canonname
= NULL
;
2406 bool malloc_results
;
2407 size_t alloc_size
= nresults
* (sizeof (*results
) + sizeof (size_t));
2410 = !__libc_use_alloca (alloc_size
);
2413 results
= malloc (alloc_size
);
2414 if (results
== NULL
)
2416 __free_in6ai (in6ai
);
2421 results
= alloca (alloc_size
);
2422 order
= (size_t *) (results
+ nresults
);
2424 /* Now we definitely need the interface information. */
2425 if (! check_pf_called
)
2426 __check_pf (&seen_ipv4
, &seen_ipv6
, &in6ai
, &in6ailen
);
2428 /* If we have information about deprecated and temporary addresses
2429 sort the array now. */
2431 qsort (in6ai
, in6ailen
, sizeof (*in6ai
), in6aicmp
);
2436 for (i
= 0, q
= p
; q
!= NULL
; ++i
, last
= q
, q
= q
->ai_next
)
2438 results
[i
].dest_addr
= q
;
2439 results
[i
].native
= -1;
2442 /* If we just looked up the address for a different
2443 protocol, reuse the result. */
2444 if (last
!= NULL
&& last
->ai_addrlen
== q
->ai_addrlen
2445 && memcmp (last
->ai_addr
, q
->ai_addr
, q
->ai_addrlen
) == 0)
2447 memcpy (&results
[i
].source_addr
, &results
[i
- 1].source_addr
,
2448 results
[i
- 1].source_addr_len
);
2449 results
[i
].source_addr_len
= results
[i
- 1].source_addr_len
;
2450 results
[i
].got_source_addr
= results
[i
- 1].got_source_addr
;
2451 results
[i
].source_addr_flags
= results
[i
- 1].source_addr_flags
;
2452 results
[i
].prefixlen
= results
[i
- 1].prefixlen
;
2453 results
[i
].index
= results
[i
- 1].index
;
2457 results
[i
].got_source_addr
= false;
2458 results
[i
].source_addr_flags
= 0;
2459 results
[i
].prefixlen
= 0;
2460 results
[i
].index
= 0xffffffffu
;
2462 /* We overwrite the type with SOCK_DGRAM since we do not
2463 want connect() to connect to the other side. If we
2464 cannot determine the source address remember this
2466 if (fd
== -1 || (af
== AF_INET
&& q
->ai_family
== AF_INET6
))
2469 __close_nocancel_nostatus (fd
);
2471 fd
= __socket (af
, SOCK_DGRAM
| SOCK_CLOEXEC
, IPPROTO_IP
);
2475 /* Reset the connection. */
2476 struct sockaddr sa
= { .sa_family
= AF_UNSPEC
};
2477 __connect (fd
, &sa
, sizeof (sa
));
2480 if (try_connect (&fd
, &af
, &results
[i
].source_addr
, q
->ai_addr
,
2481 q
->ai_addrlen
, q
->ai_family
))
2483 results
[i
].source_addr_len
= sizeof (results
[i
].source_addr
);
2484 results
[i
].got_source_addr
= true;
2488 /* See whether the source address is on the list of
2489 deprecated or temporary addresses. */
2490 struct in6addrinfo tmp
;
2492 if (q
->ai_family
== AF_INET
&& af
== AF_INET
)
2494 struct sockaddr_in
*sinp
2495 = (struct sockaddr_in
*) &results
[i
].source_addr
;
2498 tmp
.addr
[2] = htonl (0xffff);
2499 /* Special case for lo interface, the source address
2500 being possibly different than the interface
2502 if ((ntohl(sinp
->sin_addr
.s_addr
) & 0xff000000)
2504 tmp
.addr
[3] = htonl(0x7f000001);
2506 tmp
.addr
[3] = sinp
->sin_addr
.s_addr
;
2510 struct sockaddr_in6
*sin6p
2511 = (struct sockaddr_in6
*) &results
[i
].source_addr
;
2512 memcpy (tmp
.addr
, &sin6p
->sin6_addr
, IN6ADDRSZ
);
2515 struct in6addrinfo
*found
2516 = bsearch (&tmp
, in6ai
, in6ailen
, sizeof (*in6ai
),
2520 results
[i
].source_addr_flags
= found
->flags
;
2521 results
[i
].prefixlen
= found
->prefixlen
;
2522 results
[i
].index
= found
->index
;
2526 if (q
->ai_family
== AF_INET
&& af
== AF_INET6
)
2528 /* We have to convert the address. The socket is
2529 IPv6 and the request is for IPv4. */
2530 struct sockaddr_in6
*sin6
2531 = (struct sockaddr_in6
*) &results
[i
].source_addr
;
2532 struct sockaddr_in
*sin
2533 = (struct sockaddr_in
*) &results
[i
].source_addr
;
2534 assert (IN6_IS_ADDR_V4MAPPED (sin6
->sin6_addr
.s6_addr32
));
2535 sin
->sin_family
= AF_INET
;
2536 /* We do not have to initialize sin_port since this
2537 fields has the same position and size in the IPv6
2539 assert (offsetof (struct sockaddr_in
, sin_port
)
2540 == offsetof (struct sockaddr_in6
, sin6_port
));
2541 assert (sizeof (sin
->sin_port
)
2542 == sizeof (sin6
->sin6_port
));
2543 memcpy (&sin
->sin_addr
,
2544 &sin6
->sin6_addr
.s6_addr32
[3], INADDRSZ
);
2545 results
[i
].source_addr_len
= sizeof (struct sockaddr_in
);
2549 /* Just make sure that if we have to process the same
2550 address again we do not copy any memory. */
2551 results
[i
].source_addr_len
= 0;
2554 /* Remember the canonical name. */
2555 if (q
->ai_canonname
!= NULL
)
2557 assert (canonname
== NULL
);
2558 canonname
= q
->ai_canonname
;
2559 q
->ai_canonname
= NULL
;
2564 __close_nocancel_nostatus (fd
);
2566 /* We got all the source addresses we can get, now sort using
2568 struct sort_result_combo src
2569 = { .results
= results
, .nresults
= nresults
};
2570 if (__glibc_unlikely (gaiconf_reload_flag_ever_set
))
2572 __libc_lock_define_initialized (static, lock
);
2574 __libc_lock_lock (lock
);
2575 if (__libc_once_get (old_once
) && gaiconf_reload_flag
)
2577 __qsort_r (order
, nresults
, sizeof (order
[0]), rfc3484_sort
, &src
);
2578 __libc_lock_unlock (lock
);
2581 __qsort_r (order
, nresults
, sizeof (order
[0]), rfc3484_sort
, &src
);
2583 /* Queue the results up as they come out of sorting. */
2584 q
= p
= results
[order
[0]].dest_addr
;
2585 for (i
= 1; i
< nresults
; ++i
)
2586 q
= q
->ai_next
= results
[order
[i
]].dest_addr
;
2589 /* Fill in the canonical name into the new first entry. */
2590 p
->ai_canonname
= canonname
;
2596 __free_in6ai (in6ai
);
2604 return last_i
? -last_i
: EAI_NONAME
;
2606 libc_hidden_def (getaddrinfo
)
2608 nss_interface_function (getaddrinfo
)
2611 freeaddrinfo (struct addrinfo
*ai
)
2619 free (p
->ai_canonname
);
2623 libc_hidden_def (freeaddrinfo
)