1 /* Host and service name lookups using Name Service Switch modules.
2 Copyright (C) 1996-2019 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>
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
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) \
245 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 (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL \
253 || errno != ERANGE) \
255 if (!scratch_buffer_grow (tmpbuf)) \
257 __resolv_context_put (res_ctx); \
258 result = -EAI_MEMORY; \
259 goto free_and_return; \
262 if (status == NSS_STATUS_NOTFOUND \
263 || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) \
265 if (h_errno == NETDB_INTERNAL) \
267 __resolv_context_put (res_ctx); \
268 result = -EAI_SYSTEM; \
269 goto free_and_return; \
271 if (h_errno == TRY_AGAIN) \
272 no_data = EAI_AGAIN; \
274 no_data = h_errno == NO_DATA; \
276 else if (status == NSS_STATUS_SUCCESS) \
278 if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem)) \
280 __resolv_context_put (res_ctx); \
281 result = -EAI_SYSTEM; \
282 goto free_and_return; \
286 if (localcanon != NULL && canon == NULL) \
288 canonbuf = __strdup (localcanon); \
289 if (canonbuf == NULL) \
291 result = -EAI_SYSTEM; \
292 goto free_and_return; \
296 if (_family == AF_INET6 && *pat != NULL) \
302 typedef enum nss_status (*nss_gethostbyname4_r
)
303 (const char *name
, struct gaih_addrtuple
**pat
,
304 char *buffer
, size_t buflen
, int *errnop
,
305 int *h_errnop
, int32_t *ttlp
);
306 typedef enum nss_status (*nss_gethostbyname3_r
)
307 (const char *name
, int af
, struct hostent
*host
,
308 char *buffer
, size_t buflen
, int *errnop
,
309 int *h_errnop
, int32_t *ttlp
, char **canonp
);
310 typedef enum nss_status (*nss_getcanonname_r
)
311 (const char *name
, char *buffer
, size_t buflen
, char **result
,
312 int *errnop
, int *h_errnop
);
314 /* This function is called if a canonical name is requested, but if
315 the service function did not provide it. It tries to obtain the
316 name using getcanonname_r from the same service NIP. If the name
317 cannot be canonicalized, return a copy of NAME. Return NULL on
318 memory allocation failure. The returned string is allocated on the
319 heap; the caller has to free it. */
321 getcanonname (service_user
*nip
, struct gaih_addrtuple
*at
, const char *name
)
323 nss_getcanonname_r cfct
= __nss_lookup_function (nip
, "getcanonname_r");
324 char *s
= (char *) name
;
328 if (DL_CALL_FCT (cfct
, (at
->name
?: name
, buf
, sizeof (buf
),
329 &s
, &errno
, &h_errno
)) != NSS_STATUS_SUCCESS
)
330 /* If the canonical name cannot be determined, use the passed
334 return __strdup (name
);
338 gaih_inet (const char *name
, const struct gaih_service
*service
,
339 const struct addrinfo
*req
, struct addrinfo
**pai
,
340 unsigned int *naddrs
, struct scratch_buffer
*tmpbuf
)
342 const struct gaih_typeproto
*tp
= gaih_inet_typeproto
;
343 struct gaih_servtuple
*st
= (struct gaih_servtuple
*) &nullserv
;
344 struct gaih_addrtuple
*at
= NULL
;
345 bool got_ipv6
= false;
346 const char *canon
= NULL
;
347 const char *orig_name
= name
;
349 /* Reserve stack memory for the scratch buffer in the getaddrinfo
351 size_t alloca_used
= sizeof (struct scratch_buffer
);
353 if (req
->ai_protocol
|| req
->ai_socktype
)
358 && ((req
->ai_socktype
!= 0 && req
->ai_socktype
!= tp
->socktype
)
359 || (req
->ai_protocol
!= 0
360 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
361 && req
->ai_protocol
!= tp
->protocol
)))
366 if (req
->ai_socktype
)
367 return -EAI_SOCKTYPE
;
376 if ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0)
379 if (service
->num
< 0)
383 st
= (struct gaih_servtuple
*)
384 alloca_account (sizeof (struct gaih_servtuple
), alloca_used
);
386 int rc
= gaih_inet_serv (service
->name
, tp
, req
, st
, tmpbuf
);
387 if (__glibc_unlikely (rc
!= 0))
392 struct gaih_servtuple
**pst
= &st
;
393 for (tp
++; tp
->name
[0]; tp
++)
395 struct gaih_servtuple
*newp
;
397 if ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0)
400 if (req
->ai_socktype
!= 0
401 && req
->ai_socktype
!= tp
->socktype
)
403 if (req
->ai_protocol
!= 0
404 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
405 && req
->ai_protocol
!= tp
->protocol
)
408 newp
= (struct gaih_servtuple
*)
409 alloca_account (sizeof (struct gaih_servtuple
),
412 if (gaih_inet_serv (service
->name
,
413 tp
, req
, newp
, tmpbuf
) != 0)
419 if (st
== (struct gaih_servtuple
*) &nullserv
)
425 port
= htons (service
->num
);
433 if (req
->ai_socktype
|| req
->ai_protocol
)
435 st
= alloca_account (sizeof (struct gaih_servtuple
), alloca_used
);
437 st
->socktype
= tp
->socktype
;
438 st
->protocol
= ((tp
->protoflag
& GAI_PROTO_PROTOANY
)
439 ? req
->ai_protocol
: tp
->protocol
);
444 /* Neither socket type nor protocol is set. Return all socket types
446 struct gaih_servtuple
**lastp
= &st
;
447 for (++tp
; tp
->name
[0]; ++tp
)
450 struct gaih_servtuple
*newp
;
452 newp
= alloca_account (sizeof (struct gaih_servtuple
),
455 newp
->socktype
= tp
->socktype
;
456 newp
->protocol
= tp
->protocol
;
465 bool malloc_name
= false;
466 struct gaih_addrtuple
*addrmem
= NULL
;
467 char *canonbuf
= NULL
;
472 at
= alloca_account (sizeof (struct gaih_addrtuple
), alloca_used
);
473 at
->family
= AF_UNSPEC
;
477 if (req
->ai_flags
& AI_IDN
)
480 result
= __idna_to_dns_encoding (name
, &out
);
487 if (__inet_aton_exact (name
, (struct in_addr
*) at
->addr
) != 0)
489 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET
)
490 at
->family
= AF_INET
;
491 else if (req
->ai_family
== AF_INET6
&& (req
->ai_flags
& AI_V4MAPPED
))
493 at
->addr
[3] = at
->addr
[0];
494 at
->addr
[2] = htonl (0xffff);
497 at
->family
= AF_INET6
;
501 result
= -EAI_ADDRFAMILY
;
502 goto free_and_return
;
505 if (req
->ai_flags
& AI_CANONNAME
)
508 else if (at
->family
== AF_UNSPEC
)
510 char *scope_delim
= strchr (name
, SCOPE_DELIMITER
);
512 if (scope_delim
== NULL
)
513 e
= inet_pton (AF_INET6
, name
, at
->addr
);
515 e
= __inet_pton_length (AF_INET6
, name
, scope_delim
- name
,
519 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET6
)
520 at
->family
= AF_INET6
;
521 else if (req
->ai_family
== AF_INET
522 && IN6_IS_ADDR_V4MAPPED (at
->addr
))
524 at
->addr
[0] = at
->addr
[3];
525 at
->family
= AF_INET
;
529 result
= -EAI_ADDRFAMILY
;
530 goto free_and_return
;
533 if (scope_delim
!= NULL
534 && __inet6_scopeid_pton ((struct in6_addr
*) at
->addr
,
538 result
= -EAI_NONAME
;
539 goto free_and_return
;
542 if (req
->ai_flags
& AI_CANONNAME
)
547 if (at
->family
== AF_UNSPEC
&& (req
->ai_flags
& AI_NUMERICHOST
) == 0)
549 struct gaih_addrtuple
**pat
= &at
;
551 int no_inet6_data
= 0;
553 enum nss_status inet6_status
= NSS_STATUS_UNAVAIL
;
554 enum nss_status status
= NSS_STATUS_UNAVAIL
;
556 struct resolv_context
*res_ctx
= NULL
;
558 /* If we do not have to look for IPv6 addresses or the canonical
559 name, use the simple, old functions, which do not support
560 IPv6 scope ids, nor retrieving the canonical name. */
561 if (req
->ai_family
== AF_INET
562 && (req
->ai_flags
& AI_CANONNAME
) == 0)
570 rc
= __gethostbyname2_r (name
, AF_INET
, &th
,
571 tmpbuf
->data
, tmpbuf
->length
,
573 if (rc
!= ERANGE
|| h_errno
!= NETDB_INTERNAL
)
575 if (!scratch_buffer_grow (tmpbuf
))
577 result
= -EAI_MEMORY
;
578 goto free_and_return
;
586 /* We found data, convert it. */
587 if (!convert_hostent_to_gaih_addrtuple
588 (req
, AF_INET
, h
, &addrmem
))
590 result
= -EAI_MEMORY
;
591 goto free_and_return
;
597 if (h_errno
== NO_DATA
)
598 result
= -EAI_NODATA
;
600 result
= -EAI_NONAME
;
601 goto free_and_return
;
606 if (h_errno
== NETDB_INTERNAL
)
607 result
= -EAI_SYSTEM
;
608 else if (h_errno
== TRY_AGAIN
)
611 /* We made requests but they turned out no data.
612 The name is known, though. */
613 result
= -EAI_NODATA
;
615 goto free_and_return
;
622 if (__nss_not_use_nscd_hosts
> 0
623 && ++__nss_not_use_nscd_hosts
> NSS_NSCD_RETRY
)
624 __nss_not_use_nscd_hosts
= 0;
626 if (!__nss_not_use_nscd_hosts
627 && !__nss_database_custom
[NSS_DBSIDX_hosts
])
629 /* Try to use nscd. */
630 struct nscd_ai_result
*air
= NULL
;
631 int err
= __nscd_getai (name
, &air
, &h_errno
);
634 /* Transform into gaih_addrtuple list. */
635 bool added_canon
= (req
->ai_flags
& AI_CANONNAME
) == 0;
636 char *addrs
= air
->addrs
;
638 addrmem
= calloc (air
->naddrs
, sizeof (*addrmem
));
641 result
= -EAI_MEMORY
;
642 goto free_and_return
;
645 struct gaih_addrtuple
*addrfree
= addrmem
;
646 for (int i
= 0; i
< air
->naddrs
; ++i
)
648 socklen_t size
= (air
->family
[i
] == AF_INET
649 ? INADDRSZ
: IN6ADDRSZ
);
651 if (!((air
->family
[i
] == AF_INET
652 && req
->ai_family
== AF_INET6
653 && (req
->ai_flags
& AI_V4MAPPED
) != 0)
654 || req
->ai_family
== AF_UNSPEC
655 || air
->family
[i
] == req
->ai_family
))
657 /* Skip over non-matching result. */
667 uint32_t *pataddr
= (*pat
)->addr
;
669 if (added_canon
|| air
->canon
== NULL
)
671 else if (canonbuf
== NULL
)
673 canonbuf
= __strdup (air
->canon
);
674 if (canonbuf
== NULL
)
676 result
= -EAI_MEMORY
;
677 goto free_and_return
;
679 canon
= (*pat
)->name
= canonbuf
;
682 if (air
->family
[i
] == AF_INET
683 && req
->ai_family
== AF_INET6
684 && (req
->ai_flags
& AI_V4MAPPED
))
686 (*pat
)->family
= AF_INET6
;
687 pataddr
[3] = *(uint32_t *) addrs
;
688 pataddr
[2] = htonl (0xffff);
691 pat
= &((*pat
)->next
);
694 else if (req
->ai_family
== AF_UNSPEC
695 || air
->family
[i
] == req
->ai_family
)
697 (*pat
)->family
= air
->family
[i
];
698 memcpy (pataddr
, addrs
, size
);
699 pat
= &((*pat
)->next
);
701 if (air
->family
[i
] == AF_INET6
)
709 if (at
->family
== AF_UNSPEC
)
711 result
= -EAI_NONAME
;
712 goto free_and_return
;
718 /* The database contains a negative entry. */
719 goto free_and_return
;
720 else if (__nss_not_use_nscd_hosts
== 0)
722 if (h_errno
== NETDB_INTERNAL
&& errno
== ENOMEM
)
723 result
= -EAI_MEMORY
;
724 else if (h_errno
== TRY_AGAIN
)
727 result
= -EAI_SYSTEM
;
729 goto free_and_return
;
734 if (__nss_hosts_database
== NULL
)
735 no_more
= __nss_database_lookup ("hosts", NULL
,
736 "dns [!UNAVAIL=return] files",
737 &__nss_hosts_database
);
740 nip
= __nss_hosts_database
;
742 /* If we are looking for both IPv4 and IPv6 address we don't
743 want the lookup functions to automatically promote IPv4
744 addresses to IPv6 addresses, so we use the no_inet6
746 res_ctx
= __resolv_context_get ();
753 nss_gethostbyname4_r fct4
= NULL
;
755 /* gethostbyname4_r sends out parallel A and AAAA queries and
756 is thus only suitable for PF_UNSPEC. */
757 if (req
->ai_family
== PF_UNSPEC
)
758 fct4
= __nss_lookup_function (nip
, "gethostbyname4_r");
764 status
= DL_CALL_FCT (fct4
, (name
, pat
,
765 tmpbuf
->data
, tmpbuf
->length
,
768 if (status
== NSS_STATUS_SUCCESS
)
770 if (status
!= NSS_STATUS_TRYAGAIN
771 || errno
!= ERANGE
|| h_errno
!= NETDB_INTERNAL
)
773 if (h_errno
== TRY_AGAIN
)
776 no_data
= h_errno
== NO_DATA
;
780 if (!scratch_buffer_grow (tmpbuf
))
782 __resolv_context_put (res_ctx
);
783 result
= -EAI_MEMORY
;
784 goto free_and_return
;
788 if (status
== NSS_STATUS_SUCCESS
)
793 if ((req
->ai_flags
& AI_CANONNAME
) != 0 && canon
== NULL
)
794 canon
= (*pat
)->name
;
798 if ((*pat
)->family
== AF_INET
799 && req
->ai_family
== AF_INET6
800 && (req
->ai_flags
& AI_V4MAPPED
) != 0)
802 uint32_t *pataddr
= (*pat
)->addr
;
803 (*pat
)->family
= AF_INET6
;
804 pataddr
[3] = pataddr
[0];
805 pataddr
[2] = htonl (0xffff);
808 pat
= &((*pat
)->next
);
811 else if (req
->ai_family
== AF_UNSPEC
812 || (*pat
)->family
== req
->ai_family
)
814 pat
= &((*pat
)->next
);
817 if (req
->ai_family
== AF_INET6
)
821 *pat
= ((*pat
)->next
);
825 no_inet6_data
= no_data
;
829 nss_gethostbyname3_r fct
= NULL
;
830 if (req
->ai_flags
& AI_CANONNAME
)
831 /* No need to use this function if we do not look for
832 the canonical name. The function does not exist in
833 all NSS modules and therefore the lookup would
835 fct
= __nss_lookup_function (nip
, "gethostbyname3_r");
837 /* We are cheating here. The gethostbyname2_r
838 function does not have the same interface as
839 gethostbyname3_r but the extra arguments the
840 latter takes are added at the end. So the
841 gethostbyname2_r code will just ignore them. */
842 fct
= __nss_lookup_function (nip
, "gethostbyname2_r");
846 if (req
->ai_family
== AF_INET6
847 || req
->ai_family
== AF_UNSPEC
)
849 gethosts (AF_INET6
, struct in6_addr
);
850 no_inet6_data
= no_data
;
851 inet6_status
= status
;
853 if (req
->ai_family
== AF_INET
854 || req
->ai_family
== AF_UNSPEC
855 || (req
->ai_family
== AF_INET6
856 && (req
->ai_flags
& AI_V4MAPPED
)
857 /* Avoid generating the mapped addresses if we
858 know we are not going to need them. */
859 && ((req
->ai_flags
& AI_ALL
) || !got_ipv6
)))
861 gethosts (AF_INET
, struct in_addr
);
863 if (req
->ai_family
== AF_INET
)
865 no_inet6_data
= no_data
;
866 inet6_status
= status
;
870 /* If we found one address for AF_INET or AF_INET6,
871 don't continue the search. */
872 if (inet6_status
== NSS_STATUS_SUCCESS
873 || status
== NSS_STATUS_SUCCESS
)
875 if ((req
->ai_flags
& AI_CANONNAME
) != 0
878 canonbuf
= getcanonname (nip
, at
, name
);
879 if (canonbuf
== NULL
)
881 __resolv_context_put (res_ctx
);
882 result
= -EAI_MEMORY
;
883 goto free_and_return
;
887 status
= NSS_STATUS_SUCCESS
;
891 /* We can have different states for AF_INET and
892 AF_INET6. Try to find a useful one for both. */
893 if (inet6_status
== NSS_STATUS_TRYAGAIN
)
894 status
= NSS_STATUS_TRYAGAIN
;
895 else if (status
== NSS_STATUS_UNAVAIL
896 && inet6_status
!= NSS_STATUS_UNAVAIL
)
897 status
= inet6_status
;
902 /* Could not locate any of the lookup functions.
903 The NSS lookup code does not consistently set
904 errno, so we need to supply our own error
905 code here. The root cause could either be a
906 resource allocation failure, or a missing
907 service function in the DSO (so it should not
908 be listed in /etc/nsswitch.conf). Assume the
909 former, and return EBUSY. */
910 status
= NSS_STATUS_UNAVAIL
;
911 __set_h_errno (NETDB_INTERNAL
);
916 if (nss_next_action (nip
, status
) == NSS_ACTION_RETURN
)
919 if (nip
->next
== NULL
)
925 __resolv_context_put (res_ctx
);
927 /* If we have a failure which sets errno, report it using
929 if ((status
== NSS_STATUS_TRYAGAIN
|| status
== NSS_STATUS_UNAVAIL
)
930 && h_errno
== NETDB_INTERNAL
)
932 result
= -EAI_SYSTEM
;
933 goto free_and_return
;
936 if (no_data
!= 0 && no_inet6_data
!= 0)
938 /* If both requests timed out report this. */
939 if (no_data
== EAI_AGAIN
&& no_inet6_data
== EAI_AGAIN
)
942 /* We made requests but they turned out no data. The name
944 result
= -EAI_NODATA
;
946 goto free_and_return
;
951 if (at
->family
== AF_UNSPEC
)
953 result
= -EAI_NONAME
;
954 goto free_and_return
;
959 struct gaih_addrtuple
*atr
;
960 atr
= at
= alloca_account (sizeof (struct gaih_addrtuple
), alloca_used
);
961 memset (at
, '\0', sizeof (struct gaih_addrtuple
));
963 if (req
->ai_family
== AF_UNSPEC
)
965 at
->next
= __alloca (sizeof (struct gaih_addrtuple
));
966 memset (at
->next
, '\0', sizeof (struct gaih_addrtuple
));
969 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET6
)
971 at
->family
= AF_INET6
;
972 if ((req
->ai_flags
& AI_PASSIVE
) == 0)
973 memcpy (at
->addr
, &in6addr_loopback
, sizeof (struct in6_addr
));
977 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET
)
979 atr
->family
= AF_INET
;
980 if ((req
->ai_flags
& AI_PASSIVE
) == 0)
981 atr
->addr
[0] = htonl (INADDR_LOOPBACK
);
986 struct gaih_servtuple
*st2
;
987 struct gaih_addrtuple
*at2
= at
;
992 buffer is the size of an unformatted IPv6 address in printable format.
996 /* Only the first entry gets the canonical name. */
997 if (at2
== at
&& (req
->ai_flags
& AI_CANONNAME
) != 0)
1000 /* If the canonical name cannot be determined, use
1001 the passed in string. */
1004 bool do_idn
= req
->ai_flags
& AI_CANONIDN
;
1008 int rc
= __idna_from_dns_encoding (canon
, &out
);
1011 else if (rc
== EAI_IDN_ENCODE
)
1012 /* Use the punycode name as a fallback. */
1017 goto free_and_return
;
1022 if (canonbuf
!= NULL
)
1023 /* We already allocated the string using malloc, but
1024 the buffer is now owned by canon. */
1028 canon
= __strdup (canon
);
1031 result
= -EAI_MEMORY
;
1032 goto free_and_return
;
1038 family
= at2
->family
;
1039 if (family
== AF_INET6
)
1041 socklen
= sizeof (struct sockaddr_in6
);
1043 /* If we looked up IPv4 mapped address discard them here if
1044 the caller isn't interested in all address and we have
1045 found at least one IPv6 address. */
1047 && (req
->ai_flags
& (AI_V4MAPPED
|AI_ALL
)) == AI_V4MAPPED
1048 && IN6_IS_ADDR_V4MAPPED (at2
->addr
))
1052 socklen
= sizeof (struct sockaddr_in
);
1054 for (st2
= st
; st2
!= NULL
; st2
= st2
->next
)
1056 struct addrinfo
*ai
;
1057 ai
= *pai
= malloc (sizeof (struct addrinfo
) + socklen
);
1060 free ((char *) canon
);
1061 result
= -EAI_MEMORY
;
1062 goto free_and_return
;
1065 ai
->ai_flags
= req
->ai_flags
;
1066 ai
->ai_family
= family
;
1067 ai
->ai_socktype
= st2
->socktype
;
1068 ai
->ai_protocol
= st2
->protocol
;
1069 ai
->ai_addrlen
= socklen
;
1070 ai
->ai_addr
= (void *) (ai
+ 1);
1072 /* We only add the canonical name once. */
1073 ai
->ai_canonname
= (char *) canon
;
1077 ai
->ai_addr
->sa_len
= socklen
;
1078 #endif /* _HAVE_SA_LEN */
1079 ai
->ai_addr
->sa_family
= family
;
1081 /* In case of an allocation error the list must be NULL
1085 if (family
== AF_INET6
)
1087 struct sockaddr_in6
*sin6p
=
1088 (struct sockaddr_in6
*) ai
->ai_addr
;
1090 sin6p
->sin6_port
= st2
->port
;
1091 sin6p
->sin6_flowinfo
= 0;
1092 memcpy (&sin6p
->sin6_addr
,
1093 at2
->addr
, sizeof (struct in6_addr
));
1094 sin6p
->sin6_scope_id
= at2
->scopeid
;
1098 struct sockaddr_in
*sinp
=
1099 (struct sockaddr_in
*) ai
->ai_addr
;
1100 sinp
->sin_port
= st2
->port
;
1101 memcpy (&sinp
->sin_addr
,
1102 at2
->addr
, sizeof (struct in_addr
));
1103 memset (sinp
->sin_zero
, '\0', sizeof (sinp
->sin_zero
));
1106 pai
= &(ai
->ai_next
);
1118 free ((char *) name
);
1128 struct addrinfo
*dest_addr
;
1129 /* Using sockaddr_storage is for now overkill. We only support IPv4
1130 and IPv6 so far. If this changes at some point we can adjust the
1132 struct sockaddr_in6 source_addr
;
1133 uint8_t source_addr_len
;
1134 bool got_source_addr
;
1135 uint8_t source_addr_flags
;
1141 struct sort_result_combo
1143 struct sort_result
*results
;
1148 #if __BYTE_ORDER == __BIG_ENDIAN
1149 # define htonl_c(n) n
1151 # define htonl_c(n) __bswap_constant_32 (n)
1154 static const struct scopeentry
1163 } default_scopes
[] =
1165 /* Link-local addresses: scope 2. */
1166 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1167 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1168 /* Default: scope 14. */
1169 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1172 /* The label table. */
1173 static const struct scopeentry
*scopes
;
1177 get_scope (const struct sockaddr_in6
*in6
)
1180 if (in6
->sin6_family
== PF_INET6
)
1182 if (! IN6_IS_ADDR_MULTICAST (&in6
->sin6_addr
))
1184 if (IN6_IS_ADDR_LINKLOCAL (&in6
->sin6_addr
)
1185 /* RFC 4291 2.5.3 says that the loopback address is to be
1186 treated like a link-local address. */
1187 || IN6_IS_ADDR_LOOPBACK (&in6
->sin6_addr
))
1189 else if (IN6_IS_ADDR_SITELOCAL (&in6
->sin6_addr
))
1192 /* XXX Is this the correct default behavior? */
1196 scope
= in6
->sin6_addr
.s6_addr
[1] & 0xf;
1198 else if (in6
->sin6_family
== PF_INET
)
1200 const struct sockaddr_in
*in
= (const struct sockaddr_in
*) in6
;
1205 if ((in
->sin_addr
.s_addr
& scopes
[cnt
].netmask
)
1206 == scopes
[cnt
].addr32
)
1207 return scopes
[cnt
].scope
;
1214 /* XXX What is a good default? */
1223 struct in6_addr prefix
;
1229 /* The label table. */
1230 static const struct prefixentry
*labels
;
1232 /* Default labels. */
1233 static const struct prefixentry default_labels
[] =
1235 /* See RFC 3484 for the details. */
1237 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1241 = { .__u6_addr8
= { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1245 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1246 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1249 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1250 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1252 /* The next two entries differ from RFC 3484. We need to treat
1253 IPv6 site-local addresses special because they are never NATed,
1254 unlike site-locale IPv4 addresses. If this would not happen, on
1255 machines which have only IPv4 and IPv6 site-local addresses, the
1256 sorting would prefer the IPv6 site-local addresses, causing
1257 unnecessary delays when trying to connect to a global IPv6 address
1258 through a site-local IPv6 address. */
1260 = { .__u6_addr8
= { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1264 = { .__u6_addr8
= { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1265 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1267 /* Additional rule for Teredo tunnels. */
1269 = { .__u6_addr8
= { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1273 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1279 /* The precedence table. */
1280 static const struct prefixentry
*precedence
;
1282 /* The default precedences. */
1283 static const struct prefixentry default_precedence
[] =
1285 /* See RFC 3484 for the details. */
1287 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1288 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1291 = { .__u6_addr8
= { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1295 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1299 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1300 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1303 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1310 match_prefix (const struct sockaddr_in6
*in6
,
1311 const struct prefixentry
*list
, int default_val
)
1314 struct sockaddr_in6 in6_mem
;
1316 if (in6
->sin6_family
== PF_INET
)
1318 const struct sockaddr_in
*in
= (const struct sockaddr_in
*) in6
;
1320 /* Construct a V4-to-6 mapped address. */
1321 in6_mem
.sin6_family
= PF_INET6
;
1322 in6_mem
.sin6_port
= in
->sin_port
;
1323 in6_mem
.sin6_flowinfo
= 0;
1324 memset (&in6_mem
.sin6_addr
, '\0', sizeof (in6_mem
.sin6_addr
));
1325 in6_mem
.sin6_addr
.s6_addr16
[5] = 0xffff;
1326 in6_mem
.sin6_addr
.s6_addr32
[3] = in
->sin_addr
.s_addr
;
1327 in6_mem
.sin6_scope_id
= 0;
1331 else if (in6
->sin6_family
!= PF_INET6
)
1334 for (idx
= 0; ; ++idx
)
1336 unsigned int bits
= list
[idx
].bits
;
1337 const uint8_t *mask
= list
[idx
].prefix
.s6_addr
;
1338 const uint8_t *val
= in6
->sin6_addr
.s6_addr
;
1352 if ((*mask
& (0xff00 >> bits
)) == (*val
& (0xff00 >> bits
)))
1358 return list
[idx
].val
;
1363 get_label (const struct sockaddr_in6
*in6
)
1365 /* XXX What is a good default value? */
1366 return match_prefix (in6
, labels
, INT_MAX
);
1371 get_precedence (const struct sockaddr_in6
*in6
)
1373 /* XXX What is a good default value? */
1374 return match_prefix (in6
, precedence
, 0);
1378 /* Find last bit set in a word. */
1384 for (n
= 0, mask
= 1 << 31; n
< 32; mask
>>= 1, ++n
)
1385 if ((a
& mask
) != 0)
1392 rfc3484_sort (const void *p1
, const void *p2
, void *arg
)
1394 const size_t idx1
= *(const size_t *) p1
;
1395 const size_t idx2
= *(const size_t *) p2
;
1396 struct sort_result_combo
*src
= (struct sort_result_combo
*) arg
;
1397 struct sort_result
*a1
= &src
->results
[idx1
];
1398 struct sort_result
*a2
= &src
->results
[idx2
];
1400 /* Rule 1: Avoid unusable destinations.
1401 We have the got_source_addr flag set if the destination is reachable. */
1402 if (a1
->got_source_addr
&& ! a2
->got_source_addr
)
1404 if (! a1
->got_source_addr
&& a2
->got_source_addr
)
1408 /* Rule 2: Prefer matching scope. Only interesting if both
1409 destination addresses are IPv6. */
1411 = get_scope ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1414 = get_scope ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1416 if (a1
->got_source_addr
)
1418 int a1_src_scope
= get_scope (&a1
->source_addr
);
1419 int a2_src_scope
= get_scope (&a2
->source_addr
);
1421 if (a1_dst_scope
== a1_src_scope
&& a2_dst_scope
!= a2_src_scope
)
1423 if (a1_dst_scope
!= a1_src_scope
&& a2_dst_scope
== a2_src_scope
)
1428 /* Rule 3: Avoid deprecated addresses. */
1429 if (a1
->got_source_addr
)
1431 if (!(a1
->source_addr_flags
& in6ai_deprecated
)
1432 && (a2
->source_addr_flags
& in6ai_deprecated
))
1434 if ((a1
->source_addr_flags
& in6ai_deprecated
)
1435 && !(a2
->source_addr_flags
& in6ai_deprecated
))
1439 /* Rule 4: Prefer home addresses. */
1440 if (a1
->got_source_addr
)
1442 if (!(a1
->source_addr_flags
& in6ai_homeaddress
)
1443 && (a2
->source_addr_flags
& in6ai_homeaddress
))
1445 if ((a1
->source_addr_flags
& in6ai_homeaddress
)
1446 && !(a2
->source_addr_flags
& in6ai_homeaddress
))
1450 /* Rule 5: Prefer matching label. */
1451 if (a1
->got_source_addr
)
1454 = get_label ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1455 int a1_src_label
= get_label (&a1
->source_addr
);
1458 = get_label ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1459 int a2_src_label
= get_label (&a2
->source_addr
);
1461 if (a1_dst_label
== a1_src_label
&& a2_dst_label
!= a2_src_label
)
1463 if (a1_dst_label
!= a1_src_label
&& a2_dst_label
== a2_src_label
)
1468 /* Rule 6: Prefer higher precedence. */
1470 = get_precedence ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1472 = get_precedence ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1474 if (a1_prec
> a2_prec
)
1476 if (a1_prec
< a2_prec
)
1480 /* Rule 7: Prefer native transport. */
1481 if (a1
->got_source_addr
)
1483 /* The same interface index means the same interface which means
1484 there is no difference in transport. This should catch many
1486 if (a1
->index
!= a2
->index
)
1488 int a1_native
= a1
->native
;
1489 int a2_native
= a2
->native
;
1491 if (a1_native
== -1 || a2_native
== -1)
1494 if (a1_native
== -1)
1496 /* If we do not have the information use 'native' as
1499 a1_index
= a1
->index
;
1502 a1_index
= 0xffffffffu
;
1505 if (a2_native
== -1)
1507 /* If we do not have the information use 'native' as
1510 a2_index
= a2
->index
;
1513 a2_index
= 0xffffffffu
;
1515 __check_native (a1_index
, &a1_native
, a2_index
, &a2_native
);
1517 /* Fill in the results in all the records. */
1518 for (int i
= 0; i
< src
->nresults
; ++i
)
1519 if (a1_index
!= -1 && src
->results
[i
].index
== a1_index
)
1521 assert (src
->results
[i
].native
== -1
1522 || src
->results
[i
].native
== a1_native
);
1523 src
->results
[i
].native
= a1_native
;
1525 else if (a2_index
!= -1 && src
->results
[i
].index
== a2_index
)
1527 assert (src
->results
[i
].native
== -1
1528 || src
->results
[i
].native
== a2_native
);
1529 src
->results
[i
].native
= a2_native
;
1533 if (a1_native
&& !a2_native
)
1535 if (!a1_native
&& a2_native
)
1541 /* Rule 8: Prefer smaller scope. */
1542 if (a1_dst_scope
< a2_dst_scope
)
1544 if (a1_dst_scope
> a2_dst_scope
)
1548 /* Rule 9: Use longest matching prefix. */
1549 if (a1
->got_source_addr
1550 && a1
->dest_addr
->ai_family
== a2
->dest_addr
->ai_family
)
1555 if (a1
->dest_addr
->ai_family
== PF_INET
)
1557 assert (a1
->source_addr
.sin6_family
== PF_INET
);
1558 assert (a2
->source_addr
.sin6_family
== PF_INET
);
1560 /* Outside of subnets, as defined by the network masks,
1561 common address prefixes for IPv4 addresses make no sense.
1562 So, define a non-zero value only if source and
1563 destination address are on the same subnet. */
1564 struct sockaddr_in
*in1_dst
1565 = (struct sockaddr_in
*) a1
->dest_addr
->ai_addr
;
1566 in_addr_t in1_dst_addr
= ntohl (in1_dst
->sin_addr
.s_addr
);
1567 struct sockaddr_in
*in1_src
1568 = (struct sockaddr_in
*) &a1
->source_addr
;
1569 in_addr_t in1_src_addr
= ntohl (in1_src
->sin_addr
.s_addr
);
1570 in_addr_t netmask1
= 0xffffffffu
<< (32 - a1
->prefixlen
);
1572 if ((in1_src_addr
& netmask1
) == (in1_dst_addr
& netmask1
))
1573 bit1
= fls (in1_dst_addr
^ in1_src_addr
);
1575 struct sockaddr_in
*in2_dst
1576 = (struct sockaddr_in
*) a2
->dest_addr
->ai_addr
;
1577 in_addr_t in2_dst_addr
= ntohl (in2_dst
->sin_addr
.s_addr
);
1578 struct sockaddr_in
*in2_src
1579 = (struct sockaddr_in
*) &a2
->source_addr
;
1580 in_addr_t in2_src_addr
= ntohl (in2_src
->sin_addr
.s_addr
);
1581 in_addr_t netmask2
= 0xffffffffu
<< (32 - a2
->prefixlen
);
1583 if ((in2_src_addr
& netmask2
) == (in2_dst_addr
& netmask2
))
1584 bit2
= fls (in2_dst_addr
^ in2_src_addr
);
1586 else if (a1
->dest_addr
->ai_family
== PF_INET6
)
1588 assert (a1
->source_addr
.sin6_family
== PF_INET6
);
1589 assert (a2
->source_addr
.sin6_family
== PF_INET6
);
1591 struct sockaddr_in6
*in1_dst
;
1592 struct sockaddr_in6
*in1_src
;
1593 struct sockaddr_in6
*in2_dst
;
1594 struct sockaddr_in6
*in2_src
;
1596 in1_dst
= (struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
;
1597 in1_src
= (struct sockaddr_in6
*) &a1
->source_addr
;
1598 in2_dst
= (struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
;
1599 in2_src
= (struct sockaddr_in6
*) &a2
->source_addr
;
1602 for (i
= 0; i
< 4; ++i
)
1603 if (in1_dst
->sin6_addr
.s6_addr32
[i
]
1604 != in1_src
->sin6_addr
.s6_addr32
[i
]
1605 || (in2_dst
->sin6_addr
.s6_addr32
[i
]
1606 != in2_src
->sin6_addr
.s6_addr32
[i
]))
1611 bit1
= fls (ntohl (in1_dst
->sin6_addr
.s6_addr32
[i
]
1612 ^ in1_src
->sin6_addr
.s6_addr32
[i
]));
1613 bit2
= fls (ntohl (in2_dst
->sin6_addr
.s6_addr32
[i
]
1614 ^ in2_src
->sin6_addr
.s6_addr32
[i
]));
1625 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1626 compare with the value indicating the order in which the entries
1627 have been received from the services. NB: no two entries can have
1628 the same order so the test will never return zero. */
1629 return idx1
< idx2
? -1 : 1;
1634 in6aicmp (const void *p1
, const void *p2
)
1636 struct in6addrinfo
*a1
= (struct in6addrinfo
*) p1
;
1637 struct in6addrinfo
*a2
= (struct in6addrinfo
*) p2
;
1639 return memcmp (a1
->addr
, a2
->addr
, sizeof (a1
->addr
));
1643 /* Name of the config file for RFC 3484 sorting (for now). */
1644 #define GAICONF_FNAME "/etc/gai.conf"
1647 /* Non-zero if we are supposed to reload the config file automatically
1648 whenever it changed. */
1649 static int gaiconf_reload_flag
;
1651 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1652 static int gaiconf_reload_flag_ever_set
;
1654 /* Last modification time. */
1655 #ifdef _STATBUF_ST_NSEC
1657 static struct timespec gaiconf_mtime
;
1660 save_gaiconf_mtime (const struct stat64
*st
)
1662 gaiconf_mtime
= st
->st_mtim
;
1666 check_gaiconf_mtime (const struct stat64
*st
)
1668 return (st
->st_mtim
.tv_sec
== gaiconf_mtime
.tv_sec
1669 && st
->st_mtim
.tv_nsec
== gaiconf_mtime
.tv_nsec
);
1674 static time_t gaiconf_mtime
;
1677 save_gaiconf_mtime (const struct stat64
*st
)
1679 gaiconf_mtime
= st
->st_mtime
;
1683 check_gaiconf_mtime (const struct stat64
*st
)
1685 return st
->st_mtime
== gaiconf_mtime
;
1691 libc_freeres_fn(fini
)
1693 if (labels
!= default_labels
)
1695 const struct prefixentry
*old
= labels
;
1696 labels
= default_labels
;
1697 free ((void *) old
);
1700 if (precedence
!= default_precedence
)
1702 const struct prefixentry
*old
= precedence
;
1703 precedence
= default_precedence
;
1704 free ((void *) old
);
1707 if (scopes
!= default_scopes
)
1709 const struct scopeentry
*old
= scopes
;
1710 scopes
= default_scopes
;
1711 free ((void *) old
);
1718 struct prefixentry entry
;
1719 struct prefixlist
*next
;
1725 struct scopeentry entry
;
1726 struct scopelist
*next
;
1731 free_prefixlist (struct prefixlist
*list
)
1733 while (list
!= NULL
)
1735 struct prefixlist
*oldp
= list
;
1743 free_scopelist (struct scopelist
*list
)
1745 while (list
!= NULL
)
1747 struct scopelist
*oldp
= list
;
1755 prefixcmp (const void *p1
, const void *p2
)
1757 const struct prefixentry
*e1
= (const struct prefixentry
*) p1
;
1758 const struct prefixentry
*e2
= (const struct prefixentry
*) p2
;
1760 if (e1
->bits
< e2
->bits
)
1762 if (e1
->bits
== e2
->bits
)
1769 scopecmp (const void *p1
, const void *p2
)
1771 const struct scopeentry
*e1
= (const struct scopeentry
*) p1
;
1772 const struct scopeentry
*e2
= (const struct scopeentry
*) p2
;
1774 if (e1
->netmask
> e2
->netmask
)
1776 if (e1
->netmask
== e2
->netmask
)
1785 struct prefixlist
*labellist
= NULL
;
1786 size_t nlabellist
= 0;
1787 bool labellist_nullbits
= false;
1788 struct prefixlist
*precedencelist
= NULL
;
1789 size_t nprecedencelist
= 0;
1790 bool precedencelist_nullbits
= false;
1791 struct scopelist
*scopelist
= NULL
;
1792 size_t nscopelist
= 0;
1793 bool scopelist_nullbits
= false;
1795 FILE *fp
= fopen (GAICONF_FNAME
, "rce");
1799 if (__fxstat64 (_STAT_VER
, fileno (fp
), &st
) != 0)
1808 __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
1810 while (!feof_unlocked (fp
))
1812 ssize_t n
= __getline (&line
, &linelen
, fp
);
1816 /* Handle comments. No escaping possible so this is easy. */
1817 char *cp
= strchr (line
, '#');
1822 while (isspace (*cp
))
1826 while (*cp
!= '\0' && !isspace (*cp
))
1828 size_t cmdlen
= cp
- cmd
;
1832 while (isspace (*cp
))
1836 while (*cp
!= '\0' && !isspace (*cp
))
1838 size_t val1len
= cp
- cmd
;
1840 /* We always need at least two values. */
1846 while (isspace (*cp
))
1850 while (*cp
!= '\0' && !isspace (*cp
))
1853 /* Ignore the rest of the line. */
1856 struct prefixlist
**listp
;
1862 if (strcmp (cmd
, "label") == 0)
1864 struct in6_addr prefix
;
1865 unsigned long int bits
;
1866 unsigned long int val
;
1871 nullbitsp
= &labellist_nullbits
;
1876 cp
= strchr (val1
, '/');
1879 if (inet_pton (AF_INET6
, val1
, &prefix
)
1881 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
1885 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
1890 struct prefixlist
*newp
= malloc (sizeof (*newp
));
1898 memcpy (&newp
->entry
.prefix
, &prefix
, sizeof (prefix
));
1899 newp
->entry
.bits
= bits
;
1900 newp
->entry
.val
= val
;
1901 newp
->next
= *listp
;
1904 *nullbitsp
|= bits
== 0;
1910 if (strcmp (cmd
, "reload") == 0)
1912 gaiconf_reload_flag
= strcmp (val1
, "yes") == 0;
1913 if (gaiconf_reload_flag
)
1914 gaiconf_reload_flag_ever_set
= 1;
1919 if (strcmp (cmd
, "scopev4") == 0)
1921 struct in6_addr prefix
;
1922 unsigned long int bits
;
1923 unsigned long int val
;
1928 cp
= strchr (val1
, '/');
1931 if (inet_pton (AF_INET6
, val1
, &prefix
))
1934 if (IN6_IS_ADDR_V4MAPPED (&prefix
)
1936 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
1941 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
1946 struct scopelist
*newp
;
1948 newp
= malloc (sizeof (*newp
));
1956 newp
->entry
.netmask
= htonl (bits
!= 96
1960 newp
->entry
.addr32
= (prefix
.s6_addr32
[3]
1961 & newp
->entry
.netmask
);
1962 newp
->entry
.scope
= val
;
1963 newp
->next
= scopelist
;
1966 scopelist_nullbits
|= bits
== 96;
1969 else if (inet_pton (AF_INET
, val1
, &prefix
.s6_addr32
[3])
1971 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
1975 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
1987 if (strcmp (cmd
, "precedence") == 0)
1989 listp
= &precedencelist
;
1990 lenp
= &nprecedencelist
;
1991 nullbitsp
= &precedencelist_nullbits
;
2002 /* Create the array for the labels. */
2003 struct prefixentry
*new_labels
;
2006 if (!labellist_nullbits
)
2008 new_labels
= malloc (nlabellist
* sizeof (*new_labels
));
2009 if (new_labels
== NULL
)
2013 if (!labellist_nullbits
)
2016 memset (&new_labels
[i
].prefix
, '\0', sizeof (struct in6_addr
));
2017 new_labels
[i
].bits
= 0;
2018 new_labels
[i
].val
= 1;
2021 struct prefixlist
*l
= labellist
;
2024 new_labels
[i
] = l
->entry
;
2027 free_prefixlist (labellist
);
2029 /* Sort the entries so that the most specific ones are at
2031 qsort (new_labels
, nlabellist
, sizeof (*new_labels
), prefixcmp
);
2034 new_labels
= (struct prefixentry
*) default_labels
;
2036 struct prefixentry
*new_precedence
;
2037 if (nprecedencelist
> 0)
2039 if (!precedencelist_nullbits
)
2041 new_precedence
= malloc (nprecedencelist
* sizeof (*new_precedence
));
2042 if (new_precedence
== NULL
)
2044 if (new_labels
!= default_labels
)
2049 int i
= nprecedencelist
;
2050 if (!precedencelist_nullbits
)
2053 memset (&new_precedence
[i
].prefix
, '\0',
2054 sizeof (struct in6_addr
));
2055 new_precedence
[i
].bits
= 0;
2056 new_precedence
[i
].val
= 40;
2059 struct prefixlist
*l
= precedencelist
;
2062 new_precedence
[i
] = l
->entry
;
2065 free_prefixlist (precedencelist
);
2067 /* Sort the entries so that the most specific ones are at
2069 qsort (new_precedence
, nprecedencelist
, sizeof (*new_precedence
),
2073 new_precedence
= (struct prefixentry
*) default_precedence
;
2075 struct scopeentry
*new_scopes
;
2078 if (!scopelist_nullbits
)
2080 new_scopes
= malloc (nscopelist
* sizeof (*new_scopes
));
2081 if (new_scopes
== NULL
)
2083 if (new_labels
!= default_labels
)
2085 if (new_precedence
!= default_precedence
)
2086 free (new_precedence
);
2091 if (!scopelist_nullbits
)
2094 new_scopes
[i
].addr32
= 0;
2095 new_scopes
[i
].netmask
= 0;
2096 new_scopes
[i
].scope
= 14;
2099 struct scopelist
*l
= scopelist
;
2102 new_scopes
[i
] = l
->entry
;
2105 free_scopelist (scopelist
);
2107 /* Sort the entries so that the most specific ones are at
2109 qsort (new_scopes
, nscopelist
, sizeof (*new_scopes
),
2113 new_scopes
= (struct scopeentry
*) default_scopes
;
2115 /* Now we are ready to replace the values. */
2116 const struct prefixentry
*old
= labels
;
2117 labels
= new_labels
;
2118 if (old
!= default_labels
)
2119 free ((void *) old
);
2122 precedence
= new_precedence
;
2123 if (old
!= default_precedence
)
2124 free ((void *) old
);
2126 const struct scopeentry
*oldscope
= scopes
;
2127 scopes
= new_scopes
;
2128 if (oldscope
!= default_scopes
)
2129 free ((void *) oldscope
);
2131 save_gaiconf_mtime (&st
);
2136 free_prefixlist (labellist
);
2137 free_prefixlist (precedencelist
);
2138 free_scopelist (scopelist
);
2140 /* If we previously read the file but it is gone now, free the
2141 old data and use the builtin one. Leave the reload flag
2149 gaiconf_reload (void)
2152 if (__xstat64 (_STAT_VER
, GAICONF_FNAME
, &st
) != 0
2153 || !check_gaiconf_mtime (&st
))
2159 getaddrinfo (const char *name
, const char *service
,
2160 const struct addrinfo
*hints
, struct addrinfo
**pai
)
2162 int i
= 0, last_i
= 0;
2164 struct addrinfo
*p
= NULL
;
2165 struct gaih_service gaih_service
, *pservice
;
2166 struct addrinfo local_hints
;
2168 if (name
!= NULL
&& name
[0] == '*' && name
[1] == 0)
2171 if (service
!= NULL
&& service
[0] == '*' && service
[1] == 0)
2174 if (name
== NULL
&& service
== NULL
)
2178 hints
= &default_hints
;
2181 & ~(AI_PASSIVE
|AI_CANONNAME
|AI_NUMERICHOST
|AI_ADDRCONFIG
|AI_V4MAPPED
2182 |AI_IDN
|AI_CANONIDN
|DEPRECATED_AI_IDN
2183 |AI_NUMERICSERV
|AI_ALL
))
2184 return EAI_BADFLAGS
;
2186 if ((hints
->ai_flags
& AI_CANONNAME
) && name
== NULL
)
2187 return EAI_BADFLAGS
;
2189 struct in6addrinfo
*in6ai
= NULL
;
2190 size_t in6ailen
= 0;
2191 bool seen_ipv4
= false;
2192 bool seen_ipv6
= false;
2193 bool check_pf_called
= false;
2195 if (hints
->ai_flags
& AI_ADDRCONFIG
)
2197 /* We might need information about what interfaces are available.
2198 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2199 cannot cache the results since new interfaces could be added at
2201 __check_pf (&seen_ipv4
, &seen_ipv6
, &in6ai
, &in6ailen
);
2202 check_pf_called
= true;
2204 /* Now make a decision on what we return, if anything. */
2205 if (hints
->ai_family
== PF_UNSPEC
&& (seen_ipv4
|| seen_ipv6
))
2207 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2208 narrow down the search. */
2209 if ((! seen_ipv4
|| ! seen_ipv6
) && (seen_ipv4
|| seen_ipv6
))
2211 local_hints
= *hints
;
2212 local_hints
.ai_family
= seen_ipv4
? PF_INET
: PF_INET6
;
2213 hints
= &local_hints
;
2216 else if ((hints
->ai_family
== PF_INET
&& ! seen_ipv4
)
2217 || (hints
->ai_family
== PF_INET6
&& ! seen_ipv6
))
2219 /* We cannot possibly return a valid answer. */
2220 __free_in6ai (in6ai
);
2225 if (service
&& service
[0])
2228 gaih_service
.name
= service
;
2229 gaih_service
.num
= strtoul (gaih_service
.name
, &c
, 10);
2232 if (hints
->ai_flags
& AI_NUMERICSERV
)
2234 __free_in6ai (in6ai
);
2238 gaih_service
.num
= -1;
2241 pservice
= &gaih_service
;
2246 struct addrinfo
**end
= &p
;
2248 unsigned int naddrs
= 0;
2249 if (hints
->ai_family
== AF_UNSPEC
|| hints
->ai_family
== AF_INET
2250 || hints
->ai_family
== AF_INET6
)
2252 struct scratch_buffer tmpbuf
;
2253 scratch_buffer_init (&tmpbuf
);
2254 last_i
= gaih_inet (name
, pservice
, hints
, end
, &naddrs
, &tmpbuf
);
2255 scratch_buffer_free (&tmpbuf
);
2260 __free_in6ai (in6ai
);
2266 end
= &((*end
)->ai_next
);
2272 __free_in6ai (in6ai
);
2278 /* Read the config file. */
2279 __libc_once_define (static, once
);
2280 __typeof (once
) old_once
= once
;
2281 __libc_once (once
, gaiconf_init
);
2282 /* Sort results according to RFC 3484. */
2283 struct sort_result
*results
;
2286 struct addrinfo
*last
= NULL
;
2287 char *canonname
= NULL
;
2288 bool malloc_results
;
2289 size_t alloc_size
= nresults
* (sizeof (*results
) + sizeof (size_t));
2292 = !__libc_use_alloca (alloc_size
);
2295 results
= malloc (alloc_size
);
2296 if (results
== NULL
)
2298 __free_in6ai (in6ai
);
2303 results
= alloca (alloc_size
);
2304 order
= (size_t *) (results
+ nresults
);
2306 /* Now we definitely need the interface information. */
2307 if (! check_pf_called
)
2308 __check_pf (&seen_ipv4
, &seen_ipv6
, &in6ai
, &in6ailen
);
2310 /* If we have information about deprecated and temporary addresses
2311 sort the array now. */
2313 qsort (in6ai
, in6ailen
, sizeof (*in6ai
), in6aicmp
);
2318 for (i
= 0, q
= p
; q
!= NULL
; ++i
, last
= q
, q
= q
->ai_next
)
2320 results
[i
].dest_addr
= q
;
2321 results
[i
].native
= -1;
2324 /* If we just looked up the address for a different
2325 protocol, reuse the result. */
2326 if (last
!= NULL
&& last
->ai_addrlen
== q
->ai_addrlen
2327 && memcmp (last
->ai_addr
, q
->ai_addr
, q
->ai_addrlen
) == 0)
2329 memcpy (&results
[i
].source_addr
, &results
[i
- 1].source_addr
,
2330 results
[i
- 1].source_addr_len
);
2331 results
[i
].source_addr_len
= results
[i
- 1].source_addr_len
;
2332 results
[i
].got_source_addr
= results
[i
- 1].got_source_addr
;
2333 results
[i
].source_addr_flags
= results
[i
- 1].source_addr_flags
;
2334 results
[i
].prefixlen
= results
[i
- 1].prefixlen
;
2335 results
[i
].index
= results
[i
- 1].index
;
2339 results
[i
].got_source_addr
= false;
2340 results
[i
].source_addr_flags
= 0;
2341 results
[i
].prefixlen
= 0;
2342 results
[i
].index
= 0xffffffffu
;
2344 /* We overwrite the type with SOCK_DGRAM since we do not
2345 want connect() to connect to the other side. If we
2346 cannot determine the source address remember this
2348 if (fd
== -1 || (af
== AF_INET
&& q
->ai_family
== AF_INET6
))
2352 __close_nocancel_nostatus (fd
);
2354 fd
= __socket (af
, SOCK_DGRAM
| SOCK_CLOEXEC
, IPPROTO_IP
);
2358 /* Reset the connection. */
2359 struct sockaddr sa
= { .sa_family
= AF_UNSPEC
};
2360 __connect (fd
, &sa
, sizeof (sa
));
2363 socklen_t sl
= sizeof (results
[i
].source_addr
);
2365 && __connect (fd
, q
->ai_addr
, q
->ai_addrlen
) == 0
2366 && __getsockname (fd
,
2367 (struct sockaddr
*) &results
[i
].source_addr
,
2370 results
[i
].source_addr_len
= sl
;
2371 results
[i
].got_source_addr
= true;
2375 /* See whether the source address is on the list of
2376 deprecated or temporary addresses. */
2377 struct in6addrinfo tmp
;
2379 if (q
->ai_family
== AF_INET
&& af
== AF_INET
)
2381 struct sockaddr_in
*sinp
2382 = (struct sockaddr_in
*) &results
[i
].source_addr
;
2385 tmp
.addr
[2] = htonl (0xffff);
2386 /* Special case for lo interface, the source address
2387 being possibly different than the interface
2389 if ((ntohl(sinp
->sin_addr
.s_addr
) & 0xff000000)
2391 tmp
.addr
[3] = htonl(0x7f000001);
2393 tmp
.addr
[3] = sinp
->sin_addr
.s_addr
;
2397 struct sockaddr_in6
*sin6p
2398 = (struct sockaddr_in6
*) &results
[i
].source_addr
;
2399 memcpy (tmp
.addr
, &sin6p
->sin6_addr
, IN6ADDRSZ
);
2402 struct in6addrinfo
*found
2403 = bsearch (&tmp
, in6ai
, in6ailen
, sizeof (*in6ai
),
2407 results
[i
].source_addr_flags
= found
->flags
;
2408 results
[i
].prefixlen
= found
->prefixlen
;
2409 results
[i
].index
= found
->index
;
2413 if (q
->ai_family
== AF_INET
&& af
== AF_INET6
)
2415 /* We have to convert the address. The socket is
2416 IPv6 and the request is for IPv4. */
2417 struct sockaddr_in6
*sin6
2418 = (struct sockaddr_in6
*) &results
[i
].source_addr
;
2419 struct sockaddr_in
*sin
2420 = (struct sockaddr_in
*) &results
[i
].source_addr
;
2421 assert (IN6_IS_ADDR_V4MAPPED (sin6
->sin6_addr
.s6_addr32
));
2422 sin
->sin_family
= AF_INET
;
2423 /* We do not have to initialize sin_port since this
2424 fields has the same position and size in the IPv6
2426 assert (offsetof (struct sockaddr_in
, sin_port
)
2427 == offsetof (struct sockaddr_in6
, sin6_port
));
2428 assert (sizeof (sin
->sin_port
)
2429 == sizeof (sin6
->sin6_port
));
2430 memcpy (&sin
->sin_addr
,
2431 &sin6
->sin6_addr
.s6_addr32
[3], INADDRSZ
);
2432 results
[i
].source_addr_len
= sizeof (struct sockaddr_in
);
2435 else if (errno
== EAFNOSUPPORT
&& af
== AF_INET6
2436 && q
->ai_family
== AF_INET
)
2437 /* This could mean IPv6 sockets are IPv6-only. */
2440 /* Just make sure that if we have to process the same
2441 address again we do not copy any memory. */
2442 results
[i
].source_addr_len
= 0;
2445 /* Remember the canonical name. */
2446 if (q
->ai_canonname
!= NULL
)
2448 assert (canonname
== NULL
);
2449 canonname
= q
->ai_canonname
;
2450 q
->ai_canonname
= NULL
;
2455 __close_nocancel_nostatus (fd
);
2457 /* We got all the source addresses we can get, now sort using
2459 struct sort_result_combo src
2460 = { .results
= results
, .nresults
= nresults
};
2461 if (__glibc_unlikely (gaiconf_reload_flag_ever_set
))
2463 __libc_lock_define_initialized (static, lock
);
2465 __libc_lock_lock (lock
);
2466 if (__libc_once_get (old_once
) && gaiconf_reload_flag
)
2468 __qsort_r (order
, nresults
, sizeof (order
[0]), rfc3484_sort
, &src
);
2469 __libc_lock_unlock (lock
);
2472 __qsort_r (order
, nresults
, sizeof (order
[0]), rfc3484_sort
, &src
);
2474 /* Queue the results up as they come out of sorting. */
2475 q
= p
= results
[order
[0]].dest_addr
;
2476 for (i
= 1; i
< nresults
; ++i
)
2477 q
= q
->ai_next
= results
[order
[i
]].dest_addr
;
2480 /* Fill in the canonical name into the new first entry. */
2481 p
->ai_canonname
= canonname
;
2487 __free_in6ai (in6ai
);
2495 return last_i
? -last_i
: EAI_NONAME
;
2497 libc_hidden_def (getaddrinfo
)
2499 nss_interface_function (getaddrinfo
)
2502 freeaddrinfo (struct addrinfo
*ai
)
2510 free (p
->ai_canonname
);
2514 libc_hidden_def (freeaddrinfo
)