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>
64 #include <resolv/res_use_inet6.h>
67 #include <stdio_ext.h>
71 #include <arpa/inet.h>
73 #include <netinet/in.h>
74 #include <sys/socket.h>
76 #include <sys/types.h>
78 #include <sys/utsname.h>
81 #include <libc-lock.h>
82 #include <not-cancel.h>
83 #include <nscd/nscd-client.h>
84 #include <nscd/nscd_proto.h>
85 #include <scratch_buffer.h>
86 #include <inet/net-internal.h>
88 /* Former AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES
89 flags, now ignored. */
90 #define DEPRECATED_AI_IDN 0x300
93 # define feof_unlocked(fp) __feof_unlocked (fp)
102 struct gaih_servtuple
104 struct gaih_servtuple
*next
;
110 static const struct gaih_servtuple nullserv
;
113 struct gaih_typeproto
122 /* Values for `protoflag'. */
123 #define GAI_PROTO_NOSERVICE 1
124 #define GAI_PROTO_PROTOANY 2
126 static const struct gaih_typeproto gaih_inet_typeproto
[] =
128 { 0, 0, 0, false, "" },
129 { SOCK_STREAM
, IPPROTO_TCP
, 0, true, "tcp" },
130 { SOCK_DGRAM
, IPPROTO_UDP
, 0, true, "udp" },
131 #if defined SOCK_DCCP && defined IPPROTO_DCCP
132 { SOCK_DCCP
, IPPROTO_DCCP
, 0, false, "dccp" },
134 #ifdef IPPROTO_UDPLITE
135 { SOCK_DGRAM
, IPPROTO_UDPLITE
, 0, false, "udplite" },
138 { SOCK_STREAM
, IPPROTO_SCTP
, 0, false, "sctp" },
139 { SOCK_SEQPACKET
, IPPROTO_SCTP
, 0, false, "sctp" },
141 { SOCK_RAW
, 0, GAI_PROTO_PROTOANY
|GAI_PROTO_NOSERVICE
, true, "raw" },
142 { 0, 0, 0, false, "" }
145 static const struct addrinfo default_hints
=
147 .ai_flags
= AI_DEFAULT
,
148 .ai_family
= PF_UNSPEC
,
153 .ai_canonname
= NULL
,
159 gaih_inet_serv (const char *servicename
, const struct gaih_typeproto
*tp
,
160 const struct addrinfo
*req
, struct gaih_servtuple
*st
,
161 struct scratch_buffer
*tmpbuf
)
169 r
= __getservbyname_r (servicename
, tp
->name
, &ts
,
170 tmpbuf
->data
, tmpbuf
->length
, &s
);
171 if (r
!= 0 || s
== NULL
)
175 if (!scratch_buffer_grow (tmpbuf
))
185 st
->socktype
= tp
->socktype
;
186 st
->protocol
= ((tp
->protoflag
& GAI_PROTO_PROTOANY
)
187 ? req
->ai_protocol
: tp
->protocol
);
188 st
->port
= s
->s_port
;
193 /* Convert struct hostent to a list of struct gaih_addrtuple objects.
194 h_name is not copied, and the struct hostent object must not be
195 deallocated prematurely. *RESULT must be NULL or a pointer to a
196 linked-list. The new addresses are appended at the end. */
198 convert_hostent_to_gaih_addrtuple (const struct addrinfo
*req
,
201 struct gaih_addrtuple
**result
)
204 result
= &(*result
)->next
;
206 /* Count the number of addresses in h->h_addr_list. */
208 for (char **p
= h
->h_addr_list
; *p
!= NULL
; ++p
)
211 /* Report no data if no addresses are available, or if the incoming
212 address size is larger than what we can store. */
213 if (count
== 0 || h
->h_length
> sizeof (((struct gaih_addrtuple
) {}).addr
))
216 struct gaih_addrtuple
*array
= calloc (count
, sizeof (*array
));
220 for (size_t i
= 0; i
< count
; ++i
)
222 if (family
== AF_INET
&& req
->ai_family
== AF_INET6
)
224 /* Perform address mapping. */
225 array
[i
].family
= AF_INET6
;
226 memcpy(array
[i
].addr
+ 3, h
->h_addr_list
[i
], sizeof (uint32_t));
227 array
[i
].addr
[2] = htonl (0xffff);
231 array
[i
].family
= family
;
232 memcpy (array
[i
].addr
, h
->h_addr_list
[i
], h
->h_length
);
234 array
[i
].next
= array
+ i
+ 1;
236 array
[0].name
= h
->h_name
;
237 array
[count
- 1].next
= NULL
;
243 #define gethosts(_family, _type) \
246 char *localcanon = NULL; \
250 status = DL_CALL_FCT (fct, (name, _family, &th, \
251 tmpbuf->data, tmpbuf->length, \
252 &errno, &h_errno, NULL, &localcanon)); \
253 if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL \
254 || errno != ERANGE) \
256 if (!scratch_buffer_grow (tmpbuf)) \
258 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
259 __resolv_context_put (res_ctx); \
260 result = -EAI_MEMORY; \
261 goto free_and_return; \
264 if (status == NSS_STATUS_NOTFOUND \
265 || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) \
267 if (h_errno == NETDB_INTERNAL) \
269 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
270 __resolv_context_put (res_ctx); \
271 result = -EAI_SYSTEM; \
272 goto free_and_return; \
274 if (h_errno == TRY_AGAIN) \
275 no_data = EAI_AGAIN; \
277 no_data = h_errno == NO_DATA; \
279 else if (status == NSS_STATUS_SUCCESS) \
281 if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem)) \
283 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
284 __resolv_context_put (res_ctx); \
285 result = -EAI_SYSTEM; \
286 goto free_and_return; \
290 if (localcanon != NULL && canon == NULL) \
292 canonbuf = __strdup (localcanon); \
293 if (canonbuf == NULL) \
295 result = -EAI_SYSTEM; \
296 goto free_and_return; \
300 if (_family == AF_INET6 && *pat != NULL) \
306 typedef enum nss_status (*nss_gethostbyname4_r
)
307 (const char *name
, struct gaih_addrtuple
**pat
,
308 char *buffer
, size_t buflen
, int *errnop
,
309 int *h_errnop
, int32_t *ttlp
);
310 typedef enum nss_status (*nss_gethostbyname3_r
)
311 (const char *name
, int af
, struct hostent
*host
,
312 char *buffer
, size_t buflen
, int *errnop
,
313 int *h_errnop
, int32_t *ttlp
, char **canonp
);
314 typedef enum nss_status (*nss_getcanonname_r
)
315 (const char *name
, char *buffer
, size_t buflen
, char **result
,
316 int *errnop
, int *h_errnop
);
318 /* This function is called if a canonical name is requested, but if
319 the service function did not provide it. It tries to obtain the
320 name using getcanonname_r from the same service NIP. If the name
321 cannot be canonicalized, return a copy of NAME. Return NULL on
322 memory allocation failure. The returned string is allocated on the
323 heap; the caller has to free it. */
325 getcanonname (service_user
*nip
, struct gaih_addrtuple
*at
, const char *name
)
327 nss_getcanonname_r cfct
= __nss_lookup_function (nip
, "getcanonname_r");
328 char *s
= (char *) name
;
332 if (DL_CALL_FCT (cfct
, (at
->name
?: name
, buf
, sizeof (buf
),
333 &s
, &errno
, &h_errno
)) != NSS_STATUS_SUCCESS
)
334 /* If the canonical name cannot be determined, use the passed
338 return __strdup (name
);
342 gaih_inet (const char *name
, const struct gaih_service
*service
,
343 const struct addrinfo
*req
, struct addrinfo
**pai
,
344 unsigned int *naddrs
, struct scratch_buffer
*tmpbuf
)
346 const struct gaih_typeproto
*tp
= gaih_inet_typeproto
;
347 struct gaih_servtuple
*st
= (struct gaih_servtuple
*) &nullserv
;
348 struct gaih_addrtuple
*at
= NULL
;
349 bool got_ipv6
= false;
350 const char *canon
= NULL
;
351 const char *orig_name
= name
;
353 /* Reserve stack memory for the scratch buffer in the getaddrinfo
355 size_t alloca_used
= sizeof (struct scratch_buffer
);
357 if (req
->ai_protocol
|| req
->ai_socktype
)
362 && ((req
->ai_socktype
!= 0 && req
->ai_socktype
!= tp
->socktype
)
363 || (req
->ai_protocol
!= 0
364 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
365 && req
->ai_protocol
!= tp
->protocol
)))
370 if (req
->ai_socktype
)
371 return -EAI_SOCKTYPE
;
380 if ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0)
383 if (service
->num
< 0)
387 st
= (struct gaih_servtuple
*)
388 alloca_account (sizeof (struct gaih_servtuple
), alloca_used
);
390 int rc
= gaih_inet_serv (service
->name
, tp
, req
, st
, tmpbuf
);
391 if (__glibc_unlikely (rc
!= 0))
396 struct gaih_servtuple
**pst
= &st
;
397 for (tp
++; tp
->name
[0]; tp
++)
399 struct gaih_servtuple
*newp
;
401 if ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0)
404 if (req
->ai_socktype
!= 0
405 && req
->ai_socktype
!= tp
->socktype
)
407 if (req
->ai_protocol
!= 0
408 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
409 && req
->ai_protocol
!= tp
->protocol
)
412 newp
= (struct gaih_servtuple
*)
413 alloca_account (sizeof (struct gaih_servtuple
),
416 if (gaih_inet_serv (service
->name
,
417 tp
, req
, newp
, tmpbuf
) != 0)
423 if (st
== (struct gaih_servtuple
*) &nullserv
)
429 port
= htons (service
->num
);
437 if (req
->ai_socktype
|| req
->ai_protocol
)
439 st
= alloca_account (sizeof (struct gaih_servtuple
), alloca_used
);
441 st
->socktype
= tp
->socktype
;
442 st
->protocol
= ((tp
->protoflag
& GAI_PROTO_PROTOANY
)
443 ? req
->ai_protocol
: tp
->protocol
);
448 /* Neither socket type nor protocol is set. Return all socket types
450 struct gaih_servtuple
**lastp
= &st
;
451 for (++tp
; tp
->name
[0]; ++tp
)
454 struct gaih_servtuple
*newp
;
456 newp
= alloca_account (sizeof (struct gaih_servtuple
),
459 newp
->socktype
= tp
->socktype
;
460 newp
->protocol
= tp
->protocol
;
469 bool malloc_name
= false;
470 struct gaih_addrtuple
*addrmem
= NULL
;
471 char *canonbuf
= NULL
;
476 at
= alloca_account (sizeof (struct gaih_addrtuple
), alloca_used
);
477 at
->family
= AF_UNSPEC
;
481 if (req
->ai_flags
& AI_IDN
)
484 result
= __idna_to_dns_encoding (name
, &out
);
491 if (__inet_aton_exact (name
, (struct in_addr
*) at
->addr
) != 0)
493 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET
)
494 at
->family
= AF_INET
;
495 else if (req
->ai_family
== AF_INET6
&& (req
->ai_flags
& AI_V4MAPPED
))
497 at
->addr
[3] = at
->addr
[0];
498 at
->addr
[2] = htonl (0xffff);
501 at
->family
= AF_INET6
;
505 result
= -EAI_ADDRFAMILY
;
506 goto free_and_return
;
509 if (req
->ai_flags
& AI_CANONNAME
)
512 else if (at
->family
== AF_UNSPEC
)
514 char *scope_delim
= strchr (name
, SCOPE_DELIMITER
);
516 if (scope_delim
== NULL
)
517 e
= inet_pton (AF_INET6
, name
, at
->addr
);
519 e
= __inet_pton_length (AF_INET6
, name
, scope_delim
- name
,
523 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET6
)
524 at
->family
= AF_INET6
;
525 else if (req
->ai_family
== AF_INET
526 && IN6_IS_ADDR_V4MAPPED (at
->addr
))
528 at
->addr
[0] = at
->addr
[3];
529 at
->family
= AF_INET
;
533 result
= -EAI_ADDRFAMILY
;
534 goto free_and_return
;
537 if (scope_delim
!= NULL
538 && __inet6_scopeid_pton ((struct in6_addr
*) at
->addr
,
542 result
= -EAI_NONAME
;
543 goto free_and_return
;
546 if (req
->ai_flags
& AI_CANONNAME
)
551 if (at
->family
== AF_UNSPEC
&& (req
->ai_flags
& AI_NUMERICHOST
) == 0)
553 struct gaih_addrtuple
**pat
= &at
;
555 int no_inet6_data
= 0;
557 enum nss_status inet6_status
= NSS_STATUS_UNAVAIL
;
558 enum nss_status status
= NSS_STATUS_UNAVAIL
;
560 struct resolv_context
*res_ctx
= NULL
;
561 bool res_enable_inet6
= false;
563 /* If we do not have to look for IPv6 addresses or the canonical
564 name, use the simple, old functions, which do not support
565 IPv6 scope ids, nor retrieving the canonical name. */
566 if (req
->ai_family
== AF_INET
567 && (req
->ai_flags
& AI_CANONNAME
) == 0)
575 rc
= __gethostbyname2_r (name
, AF_INET
, &th
,
576 tmpbuf
->data
, tmpbuf
->length
,
578 if (rc
!= ERANGE
|| h_errno
!= NETDB_INTERNAL
)
580 if (!scratch_buffer_grow (tmpbuf
))
582 result
= -EAI_MEMORY
;
583 goto free_and_return
;
591 /* We found data, convert it. */
592 if (!convert_hostent_to_gaih_addrtuple
593 (req
, AF_INET
, h
, &addrmem
))
595 result
= -EAI_MEMORY
;
596 goto free_and_return
;
602 if (h_errno
== NO_DATA
)
603 result
= -EAI_NODATA
;
605 result
= -EAI_NONAME
;
606 goto free_and_return
;
611 if (h_errno
== NETDB_INTERNAL
)
612 result
= -EAI_SYSTEM
;
613 else if (h_errno
== TRY_AGAIN
)
616 /* We made requests but they turned out no data.
617 The name is known, though. */
618 result
= -EAI_NODATA
;
620 goto free_and_return
;
627 if (__nss_not_use_nscd_hosts
> 0
628 && ++__nss_not_use_nscd_hosts
> NSS_NSCD_RETRY
)
629 __nss_not_use_nscd_hosts
= 0;
631 if (!__nss_not_use_nscd_hosts
632 && !__nss_database_custom
[NSS_DBSIDX_hosts
])
634 /* Try to use nscd. */
635 struct nscd_ai_result
*air
= NULL
;
636 int err
= __nscd_getai (name
, &air
, &h_errno
);
639 /* Transform into gaih_addrtuple list. */
640 bool added_canon
= (req
->ai_flags
& AI_CANONNAME
) == 0;
641 char *addrs
= air
->addrs
;
643 addrmem
= calloc (air
->naddrs
, sizeof (*addrmem
));
646 result
= -EAI_MEMORY
;
647 goto free_and_return
;
650 struct gaih_addrtuple
*addrfree
= addrmem
;
651 for (int i
= 0; i
< air
->naddrs
; ++i
)
653 socklen_t size
= (air
->family
[i
] == AF_INET
654 ? INADDRSZ
: IN6ADDRSZ
);
656 if (!((air
->family
[i
] == AF_INET
657 && req
->ai_family
== AF_INET6
658 && (req
->ai_flags
& AI_V4MAPPED
) != 0)
659 || req
->ai_family
== AF_UNSPEC
660 || air
->family
[i
] == req
->ai_family
))
662 /* Skip over non-matching result. */
672 uint32_t *pataddr
= (*pat
)->addr
;
674 if (added_canon
|| air
->canon
== NULL
)
676 else if (canonbuf
== NULL
)
678 canonbuf
= __strdup (air
->canon
);
679 if (canonbuf
== NULL
)
681 result
= -EAI_MEMORY
;
682 goto free_and_return
;
684 canon
= (*pat
)->name
= canonbuf
;
687 if (air
->family
[i
] == AF_INET
688 && req
->ai_family
== AF_INET6
689 && (req
->ai_flags
& AI_V4MAPPED
))
691 (*pat
)->family
= AF_INET6
;
692 pataddr
[3] = *(uint32_t *) addrs
;
693 pataddr
[2] = htonl (0xffff);
696 pat
= &((*pat
)->next
);
699 else if (req
->ai_family
== AF_UNSPEC
700 || air
->family
[i
] == req
->ai_family
)
702 (*pat
)->family
= air
->family
[i
];
703 memcpy (pataddr
, addrs
, size
);
704 pat
= &((*pat
)->next
);
706 if (air
->family
[i
] == AF_INET6
)
714 if (at
->family
== AF_UNSPEC
)
716 result
= -EAI_NONAME
;
717 goto free_and_return
;
723 /* The database contains a negative entry. */
724 goto free_and_return
;
725 else if (__nss_not_use_nscd_hosts
== 0)
727 if (h_errno
== NETDB_INTERNAL
&& errno
== ENOMEM
)
728 result
= -EAI_MEMORY
;
729 else if (h_errno
== TRY_AGAIN
)
732 result
= -EAI_SYSTEM
;
734 goto free_and_return
;
739 if (__nss_hosts_database
== NULL
)
740 no_more
= __nss_database_lookup ("hosts", NULL
,
741 "dns [!UNAVAIL=return] files",
742 &__nss_hosts_database
);
745 nip
= __nss_hosts_database
;
747 /* If we are looking for both IPv4 and IPv6 address we don't
748 want the lookup functions to automatically promote IPv4
749 addresses to IPv6 addresses, so we use the no_inet6
751 res_ctx
= __resolv_context_get ();
752 res_enable_inet6
= __resolv_context_disable_inet6 (res_ctx
);
759 nss_gethostbyname4_r fct4
= NULL
;
761 /* gethostbyname4_r sends out parallel A and AAAA queries and
762 is thus only suitable for PF_UNSPEC. */
763 if (req
->ai_family
== PF_UNSPEC
)
764 fct4
= __nss_lookup_function (nip
, "gethostbyname4_r");
770 status
= DL_CALL_FCT (fct4
, (name
, pat
,
771 tmpbuf
->data
, tmpbuf
->length
,
774 if (status
== NSS_STATUS_SUCCESS
)
776 if (status
!= NSS_STATUS_TRYAGAIN
777 || errno
!= ERANGE
|| h_errno
!= NETDB_INTERNAL
)
779 if (h_errno
== TRY_AGAIN
)
782 no_data
= h_errno
== NO_DATA
;
786 if (!scratch_buffer_grow (tmpbuf
))
788 __resolv_context_enable_inet6
789 (res_ctx
, res_enable_inet6
);
790 __resolv_context_put (res_ctx
);
791 result
= -EAI_MEMORY
;
792 goto free_and_return
;
796 if (status
== NSS_STATUS_SUCCESS
)
801 if ((req
->ai_flags
& AI_CANONNAME
) != 0 && canon
== NULL
)
802 canon
= (*pat
)->name
;
806 if ((*pat
)->family
== AF_INET
807 && req
->ai_family
== AF_INET6
808 && (req
->ai_flags
& AI_V4MAPPED
) != 0)
810 uint32_t *pataddr
= (*pat
)->addr
;
811 (*pat
)->family
= AF_INET6
;
812 pataddr
[3] = pataddr
[0];
813 pataddr
[2] = htonl (0xffff);
816 pat
= &((*pat
)->next
);
819 else if (req
->ai_family
== AF_UNSPEC
820 || (*pat
)->family
== req
->ai_family
)
822 pat
= &((*pat
)->next
);
825 if (req
->ai_family
== AF_INET6
)
829 *pat
= ((*pat
)->next
);
833 no_inet6_data
= no_data
;
837 nss_gethostbyname3_r fct
= NULL
;
838 if (req
->ai_flags
& AI_CANONNAME
)
839 /* No need to use this function if we do not look for
840 the canonical name. The function does not exist in
841 all NSS modules and therefore the lookup would
843 fct
= __nss_lookup_function (nip
, "gethostbyname3_r");
845 /* We are cheating here. The gethostbyname2_r
846 function does not have the same interface as
847 gethostbyname3_r but the extra arguments the
848 latter takes are added at the end. So the
849 gethostbyname2_r code will just ignore them. */
850 fct
= __nss_lookup_function (nip
, "gethostbyname2_r");
854 if (req
->ai_family
== AF_INET6
855 || req
->ai_family
== AF_UNSPEC
)
857 gethosts (AF_INET6
, struct in6_addr
);
858 no_inet6_data
= no_data
;
859 inet6_status
= status
;
861 if (req
->ai_family
== AF_INET
862 || req
->ai_family
== AF_UNSPEC
863 || (req
->ai_family
== AF_INET6
864 && (req
->ai_flags
& AI_V4MAPPED
)
865 /* Avoid generating the mapped addresses if we
866 know we are not going to need them. */
867 && ((req
->ai_flags
& AI_ALL
) || !got_ipv6
)))
869 gethosts (AF_INET
, struct in_addr
);
871 if (req
->ai_family
== AF_INET
)
873 no_inet6_data
= no_data
;
874 inet6_status
= status
;
878 /* If we found one address for AF_INET or AF_INET6,
879 don't continue the search. */
880 if (inet6_status
== NSS_STATUS_SUCCESS
881 || status
== NSS_STATUS_SUCCESS
)
883 if ((req
->ai_flags
& AI_CANONNAME
) != 0
886 canonbuf
= getcanonname (nip
, at
, name
);
887 if (canonbuf
== NULL
)
889 __resolv_context_enable_inet6
890 (res_ctx
, res_enable_inet6
);
891 __resolv_context_put (res_ctx
);
892 result
= -EAI_MEMORY
;
893 goto free_and_return
;
897 status
= NSS_STATUS_SUCCESS
;
901 /* We can have different states for AF_INET and
902 AF_INET6. Try to find a useful one for both. */
903 if (inet6_status
== NSS_STATUS_TRYAGAIN
)
904 status
= NSS_STATUS_TRYAGAIN
;
905 else if (status
== NSS_STATUS_UNAVAIL
906 && inet6_status
!= NSS_STATUS_UNAVAIL
)
907 status
= inet6_status
;
912 /* Could not locate any of the lookup functions.
913 The NSS lookup code does not consistently set
914 errno, so we need to supply our own error
915 code here. The root cause could either be a
916 resource allocation failure, or a missing
917 service function in the DSO (so it should not
918 be listed in /etc/nsswitch.conf). Assume the
919 former, and return EBUSY. */
920 status
= NSS_STATUS_UNAVAIL
;
921 __set_h_errno (NETDB_INTERNAL
);
926 if (nss_next_action (nip
, status
) == NSS_ACTION_RETURN
)
929 if (nip
->next
== NULL
)
935 __resolv_context_enable_inet6 (res_ctx
, res_enable_inet6
);
936 __resolv_context_put (res_ctx
);
938 /* If we have a failure which sets errno, report it using
940 if ((status
== NSS_STATUS_TRYAGAIN
|| status
== NSS_STATUS_UNAVAIL
)
941 && h_errno
== NETDB_INTERNAL
)
943 result
= -EAI_SYSTEM
;
944 goto free_and_return
;
947 if (no_data
!= 0 && no_inet6_data
!= 0)
949 /* If both requests timed out report this. */
950 if (no_data
== EAI_AGAIN
&& no_inet6_data
== EAI_AGAIN
)
953 /* We made requests but they turned out no data. The name
955 result
= -EAI_NODATA
;
957 goto free_and_return
;
962 if (at
->family
== AF_UNSPEC
)
964 result
= -EAI_NONAME
;
965 goto free_and_return
;
970 struct gaih_addrtuple
*atr
;
971 atr
= at
= alloca_account (sizeof (struct gaih_addrtuple
), alloca_used
);
972 memset (at
, '\0', sizeof (struct gaih_addrtuple
));
974 if (req
->ai_family
== AF_UNSPEC
)
976 at
->next
= __alloca (sizeof (struct gaih_addrtuple
));
977 memset (at
->next
, '\0', sizeof (struct gaih_addrtuple
));
980 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET6
)
982 at
->family
= AF_INET6
;
983 if ((req
->ai_flags
& AI_PASSIVE
) == 0)
984 memcpy (at
->addr
, &in6addr_loopback
, sizeof (struct in6_addr
));
988 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET
)
990 atr
->family
= AF_INET
;
991 if ((req
->ai_flags
& AI_PASSIVE
) == 0)
992 atr
->addr
[0] = htonl (INADDR_LOOPBACK
);
997 struct gaih_servtuple
*st2
;
998 struct gaih_addrtuple
*at2
= at
;
1003 buffer is the size of an unformatted IPv6 address in printable format.
1007 /* Only the first entry gets the canonical name. */
1008 if (at2
== at
&& (req
->ai_flags
& AI_CANONNAME
) != 0)
1011 /* If the canonical name cannot be determined, use
1012 the passed in string. */
1015 bool do_idn
= req
->ai_flags
& AI_CANONIDN
;
1019 int rc
= __idna_from_dns_encoding (canon
, &out
);
1022 else if (rc
== EAI_IDN_ENCODE
)
1023 /* Use the punycode name as a fallback. */
1028 goto free_and_return
;
1033 if (canonbuf
!= NULL
)
1034 /* We already allocated the string using malloc, but
1035 the buffer is now owned by canon. */
1039 canon
= __strdup (canon
);
1042 result
= -EAI_MEMORY
;
1043 goto free_and_return
;
1049 family
= at2
->family
;
1050 if (family
== AF_INET6
)
1052 socklen
= sizeof (struct sockaddr_in6
);
1054 /* If we looked up IPv4 mapped address discard them here if
1055 the caller isn't interested in all address and we have
1056 found at least one IPv6 address. */
1058 && (req
->ai_flags
& (AI_V4MAPPED
|AI_ALL
)) == AI_V4MAPPED
1059 && IN6_IS_ADDR_V4MAPPED (at2
->addr
))
1063 socklen
= sizeof (struct sockaddr_in
);
1065 for (st2
= st
; st2
!= NULL
; st2
= st2
->next
)
1067 struct addrinfo
*ai
;
1068 ai
= *pai
= malloc (sizeof (struct addrinfo
) + socklen
);
1071 free ((char *) canon
);
1072 result
= -EAI_MEMORY
;
1073 goto free_and_return
;
1076 ai
->ai_flags
= req
->ai_flags
;
1077 ai
->ai_family
= family
;
1078 ai
->ai_socktype
= st2
->socktype
;
1079 ai
->ai_protocol
= st2
->protocol
;
1080 ai
->ai_addrlen
= socklen
;
1081 ai
->ai_addr
= (void *) (ai
+ 1);
1083 /* We only add the canonical name once. */
1084 ai
->ai_canonname
= (char *) canon
;
1088 ai
->ai_addr
->sa_len
= socklen
;
1089 #endif /* _HAVE_SA_LEN */
1090 ai
->ai_addr
->sa_family
= family
;
1092 /* In case of an allocation error the list must be NULL
1096 if (family
== AF_INET6
)
1098 struct sockaddr_in6
*sin6p
=
1099 (struct sockaddr_in6
*) ai
->ai_addr
;
1101 sin6p
->sin6_port
= st2
->port
;
1102 sin6p
->sin6_flowinfo
= 0;
1103 memcpy (&sin6p
->sin6_addr
,
1104 at2
->addr
, sizeof (struct in6_addr
));
1105 sin6p
->sin6_scope_id
= at2
->scopeid
;
1109 struct sockaddr_in
*sinp
=
1110 (struct sockaddr_in
*) ai
->ai_addr
;
1111 sinp
->sin_port
= st2
->port
;
1112 memcpy (&sinp
->sin_addr
,
1113 at2
->addr
, sizeof (struct in_addr
));
1114 memset (sinp
->sin_zero
, '\0', sizeof (sinp
->sin_zero
));
1117 pai
= &(ai
->ai_next
);
1129 free ((char *) name
);
1139 struct addrinfo
*dest_addr
;
1140 /* Using sockaddr_storage is for now overkill. We only support IPv4
1141 and IPv6 so far. If this changes at some point we can adjust the
1143 struct sockaddr_in6 source_addr
;
1144 uint8_t source_addr_len
;
1145 bool got_source_addr
;
1146 uint8_t source_addr_flags
;
1152 struct sort_result_combo
1154 struct sort_result
*results
;
1159 #if __BYTE_ORDER == __BIG_ENDIAN
1160 # define htonl_c(n) n
1162 # define htonl_c(n) __bswap_constant_32 (n)
1165 static const struct scopeentry
1174 } default_scopes
[] =
1176 /* Link-local addresses: scope 2. */
1177 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1178 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1179 /* Default: scope 14. */
1180 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1183 /* The label table. */
1184 static const struct scopeentry
*scopes
;
1188 get_scope (const struct sockaddr_in6
*in6
)
1191 if (in6
->sin6_family
== PF_INET6
)
1193 if (! IN6_IS_ADDR_MULTICAST (&in6
->sin6_addr
))
1195 if (IN6_IS_ADDR_LINKLOCAL (&in6
->sin6_addr
)
1196 /* RFC 4291 2.5.3 says that the loopback address is to be
1197 treated like a link-local address. */
1198 || IN6_IS_ADDR_LOOPBACK (&in6
->sin6_addr
))
1200 else if (IN6_IS_ADDR_SITELOCAL (&in6
->sin6_addr
))
1203 /* XXX Is this the correct default behavior? */
1207 scope
= in6
->sin6_addr
.s6_addr
[1] & 0xf;
1209 else if (in6
->sin6_family
== PF_INET
)
1211 const struct sockaddr_in
*in
= (const struct sockaddr_in
*) in6
;
1216 if ((in
->sin_addr
.s_addr
& scopes
[cnt
].netmask
)
1217 == scopes
[cnt
].addr32
)
1218 return scopes
[cnt
].scope
;
1225 /* XXX What is a good default? */
1234 struct in6_addr prefix
;
1240 /* The label table. */
1241 static const struct prefixentry
*labels
;
1243 /* Default labels. */
1244 static const struct prefixentry default_labels
[] =
1246 /* See RFC 3484 for the details. */
1248 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1252 = { .__u6_addr8
= { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1256 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1260 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1261 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1263 /* The next two entries differ from RFC 3484. We need to treat
1264 IPv6 site-local addresses special because they are never NATed,
1265 unlike site-locale IPv4 addresses. If this would not happen, on
1266 machines which have only IPv4 and IPv6 site-local addresses, the
1267 sorting would prefer the IPv6 site-local addresses, causing
1268 unnecessary delays when trying to connect to a global IPv6 address
1269 through a site-local IPv6 address. */
1271 = { .__u6_addr8
= { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1275 = { .__u6_addr8
= { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1278 /* Additional rule for Teredo tunnels. */
1280 = { .__u6_addr8
= { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1281 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1284 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1285 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1290 /* The precedence table. */
1291 static const struct prefixentry
*precedence
;
1293 /* The default precedences. */
1294 static const struct prefixentry default_precedence
[] =
1296 /* See RFC 3484 for the details. */
1298 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1302 = { .__u6_addr8
= { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1306 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1310 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1311 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1314 = { .__u6_addr8
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1321 match_prefix (const struct sockaddr_in6
*in6
,
1322 const struct prefixentry
*list
, int default_val
)
1325 struct sockaddr_in6 in6_mem
;
1327 if (in6
->sin6_family
== PF_INET
)
1329 const struct sockaddr_in
*in
= (const struct sockaddr_in
*) in6
;
1331 /* Construct a V4-to-6 mapped address. */
1332 in6_mem
.sin6_family
= PF_INET6
;
1333 in6_mem
.sin6_port
= in
->sin_port
;
1334 in6_mem
.sin6_flowinfo
= 0;
1335 memset (&in6_mem
.sin6_addr
, '\0', sizeof (in6_mem
.sin6_addr
));
1336 in6_mem
.sin6_addr
.s6_addr16
[5] = 0xffff;
1337 in6_mem
.sin6_addr
.s6_addr32
[3] = in
->sin_addr
.s_addr
;
1338 in6_mem
.sin6_scope_id
= 0;
1342 else if (in6
->sin6_family
!= PF_INET6
)
1345 for (idx
= 0; ; ++idx
)
1347 unsigned int bits
= list
[idx
].bits
;
1348 const uint8_t *mask
= list
[idx
].prefix
.s6_addr
;
1349 const uint8_t *val
= in6
->sin6_addr
.s6_addr
;
1363 if ((*mask
& (0xff00 >> bits
)) == (*val
& (0xff00 >> bits
)))
1369 return list
[idx
].val
;
1374 get_label (const struct sockaddr_in6
*in6
)
1376 /* XXX What is a good default value? */
1377 return match_prefix (in6
, labels
, INT_MAX
);
1382 get_precedence (const struct sockaddr_in6
*in6
)
1384 /* XXX What is a good default value? */
1385 return match_prefix (in6
, precedence
, 0);
1389 /* Find last bit set in a word. */
1395 for (n
= 0, mask
= 1 << 31; n
< 32; mask
>>= 1, ++n
)
1396 if ((a
& mask
) != 0)
1403 rfc3484_sort (const void *p1
, const void *p2
, void *arg
)
1405 const size_t idx1
= *(const size_t *) p1
;
1406 const size_t idx2
= *(const size_t *) p2
;
1407 struct sort_result_combo
*src
= (struct sort_result_combo
*) arg
;
1408 struct sort_result
*a1
= &src
->results
[idx1
];
1409 struct sort_result
*a2
= &src
->results
[idx2
];
1411 /* Rule 1: Avoid unusable destinations.
1412 We have the got_source_addr flag set if the destination is reachable. */
1413 if (a1
->got_source_addr
&& ! a2
->got_source_addr
)
1415 if (! a1
->got_source_addr
&& a2
->got_source_addr
)
1419 /* Rule 2: Prefer matching scope. Only interesting if both
1420 destination addresses are IPv6. */
1422 = get_scope ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1425 = get_scope ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1427 if (a1
->got_source_addr
)
1429 int a1_src_scope
= get_scope (&a1
->source_addr
);
1430 int a2_src_scope
= get_scope (&a2
->source_addr
);
1432 if (a1_dst_scope
== a1_src_scope
&& a2_dst_scope
!= a2_src_scope
)
1434 if (a1_dst_scope
!= a1_src_scope
&& a2_dst_scope
== a2_src_scope
)
1439 /* Rule 3: Avoid deprecated addresses. */
1440 if (a1
->got_source_addr
)
1442 if (!(a1
->source_addr_flags
& in6ai_deprecated
)
1443 && (a2
->source_addr_flags
& in6ai_deprecated
))
1445 if ((a1
->source_addr_flags
& in6ai_deprecated
)
1446 && !(a2
->source_addr_flags
& in6ai_deprecated
))
1450 /* Rule 4: Prefer home addresses. */
1451 if (a1
->got_source_addr
)
1453 if (!(a1
->source_addr_flags
& in6ai_homeaddress
)
1454 && (a2
->source_addr_flags
& in6ai_homeaddress
))
1456 if ((a1
->source_addr_flags
& in6ai_homeaddress
)
1457 && !(a2
->source_addr_flags
& in6ai_homeaddress
))
1461 /* Rule 5: Prefer matching label. */
1462 if (a1
->got_source_addr
)
1465 = get_label ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1466 int a1_src_label
= get_label (&a1
->source_addr
);
1469 = get_label ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1470 int a2_src_label
= get_label (&a2
->source_addr
);
1472 if (a1_dst_label
== a1_src_label
&& a2_dst_label
!= a2_src_label
)
1474 if (a1_dst_label
!= a1_src_label
&& a2_dst_label
== a2_src_label
)
1479 /* Rule 6: Prefer higher precedence. */
1481 = get_precedence ((struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
);
1483 = get_precedence ((struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
);
1485 if (a1_prec
> a2_prec
)
1487 if (a1_prec
< a2_prec
)
1491 /* Rule 7: Prefer native transport. */
1492 if (a1
->got_source_addr
)
1494 /* The same interface index means the same interface which means
1495 there is no difference in transport. This should catch many
1497 if (a1
->index
!= a2
->index
)
1499 int a1_native
= a1
->native
;
1500 int a2_native
= a2
->native
;
1502 if (a1_native
== -1 || a2_native
== -1)
1505 if (a1_native
== -1)
1507 /* If we do not have the information use 'native' as
1510 a1_index
= a1
->index
;
1513 a1_index
= 0xffffffffu
;
1516 if (a2_native
== -1)
1518 /* If we do not have the information use 'native' as
1521 a2_index
= a2
->index
;
1524 a2_index
= 0xffffffffu
;
1526 __check_native (a1_index
, &a1_native
, a2_index
, &a2_native
);
1528 /* Fill in the results in all the records. */
1529 for (int i
= 0; i
< src
->nresults
; ++i
)
1530 if (a1_index
!= -1 && src
->results
[i
].index
== a1_index
)
1532 assert (src
->results
[i
].native
== -1
1533 || src
->results
[i
].native
== a1_native
);
1534 src
->results
[i
].native
= a1_native
;
1536 else if (a2_index
!= -1 && src
->results
[i
].index
== a2_index
)
1538 assert (src
->results
[i
].native
== -1
1539 || src
->results
[i
].native
== a2_native
);
1540 src
->results
[i
].native
= a2_native
;
1544 if (a1_native
&& !a2_native
)
1546 if (!a1_native
&& a2_native
)
1552 /* Rule 8: Prefer smaller scope. */
1553 if (a1_dst_scope
< a2_dst_scope
)
1555 if (a1_dst_scope
> a2_dst_scope
)
1559 /* Rule 9: Use longest matching prefix. */
1560 if (a1
->got_source_addr
1561 && a1
->dest_addr
->ai_family
== a2
->dest_addr
->ai_family
)
1566 if (a1
->dest_addr
->ai_family
== PF_INET
)
1568 assert (a1
->source_addr
.sin6_family
== PF_INET
);
1569 assert (a2
->source_addr
.sin6_family
== PF_INET
);
1571 /* Outside of subnets, as defined by the network masks,
1572 common address prefixes for IPv4 addresses make no sense.
1573 So, define a non-zero value only if source and
1574 destination address are on the same subnet. */
1575 struct sockaddr_in
*in1_dst
1576 = (struct sockaddr_in
*) a1
->dest_addr
->ai_addr
;
1577 in_addr_t in1_dst_addr
= ntohl (in1_dst
->sin_addr
.s_addr
);
1578 struct sockaddr_in
*in1_src
1579 = (struct sockaddr_in
*) &a1
->source_addr
;
1580 in_addr_t in1_src_addr
= ntohl (in1_src
->sin_addr
.s_addr
);
1581 in_addr_t netmask1
= 0xffffffffu
<< (32 - a1
->prefixlen
);
1583 if ((in1_src_addr
& netmask1
) == (in1_dst_addr
& netmask1
))
1584 bit1
= fls (in1_dst_addr
^ in1_src_addr
);
1586 struct sockaddr_in
*in2_dst
1587 = (struct sockaddr_in
*) a2
->dest_addr
->ai_addr
;
1588 in_addr_t in2_dst_addr
= ntohl (in2_dst
->sin_addr
.s_addr
);
1589 struct sockaddr_in
*in2_src
1590 = (struct sockaddr_in
*) &a2
->source_addr
;
1591 in_addr_t in2_src_addr
= ntohl (in2_src
->sin_addr
.s_addr
);
1592 in_addr_t netmask2
= 0xffffffffu
<< (32 - a2
->prefixlen
);
1594 if ((in2_src_addr
& netmask2
) == (in2_dst_addr
& netmask2
))
1595 bit2
= fls (in2_dst_addr
^ in2_src_addr
);
1597 else if (a1
->dest_addr
->ai_family
== PF_INET6
)
1599 assert (a1
->source_addr
.sin6_family
== PF_INET6
);
1600 assert (a2
->source_addr
.sin6_family
== PF_INET6
);
1602 struct sockaddr_in6
*in1_dst
;
1603 struct sockaddr_in6
*in1_src
;
1604 struct sockaddr_in6
*in2_dst
;
1605 struct sockaddr_in6
*in2_src
;
1607 in1_dst
= (struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
;
1608 in1_src
= (struct sockaddr_in6
*) &a1
->source_addr
;
1609 in2_dst
= (struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
;
1610 in2_src
= (struct sockaddr_in6
*) &a2
->source_addr
;
1613 for (i
= 0; i
< 4; ++i
)
1614 if (in1_dst
->sin6_addr
.s6_addr32
[i
]
1615 != in1_src
->sin6_addr
.s6_addr32
[i
]
1616 || (in2_dst
->sin6_addr
.s6_addr32
[i
]
1617 != in2_src
->sin6_addr
.s6_addr32
[i
]))
1622 bit1
= fls (ntohl (in1_dst
->sin6_addr
.s6_addr32
[i
]
1623 ^ in1_src
->sin6_addr
.s6_addr32
[i
]));
1624 bit2
= fls (ntohl (in2_dst
->sin6_addr
.s6_addr32
[i
]
1625 ^ in2_src
->sin6_addr
.s6_addr32
[i
]));
1636 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1637 compare with the value indicating the order in which the entries
1638 have been received from the services. NB: no two entries can have
1639 the same order so the test will never return zero. */
1640 return idx1
< idx2
? -1 : 1;
1645 in6aicmp (const void *p1
, const void *p2
)
1647 struct in6addrinfo
*a1
= (struct in6addrinfo
*) p1
;
1648 struct in6addrinfo
*a2
= (struct in6addrinfo
*) p2
;
1650 return memcmp (a1
->addr
, a2
->addr
, sizeof (a1
->addr
));
1654 /* Name of the config file for RFC 3484 sorting (for now). */
1655 #define GAICONF_FNAME "/etc/gai.conf"
1658 /* Non-zero if we are supposed to reload the config file automatically
1659 whenever it changed. */
1660 static int gaiconf_reload_flag
;
1662 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1663 static int gaiconf_reload_flag_ever_set
;
1665 /* Last modification time. */
1666 #ifdef _STATBUF_ST_NSEC
1668 static struct timespec gaiconf_mtime
;
1671 save_gaiconf_mtime (const struct stat64
*st
)
1673 gaiconf_mtime
= st
->st_mtim
;
1677 check_gaiconf_mtime (const struct stat64
*st
)
1679 return (st
->st_mtim
.tv_sec
== gaiconf_mtime
.tv_sec
1680 && st
->st_mtim
.tv_nsec
== gaiconf_mtime
.tv_nsec
);
1685 static time_t gaiconf_mtime
;
1688 save_gaiconf_mtime (const struct stat64
*st
)
1690 gaiconf_mtime
= st
->st_mtime
;
1694 check_gaiconf_mtime (const struct stat64
*st
)
1696 return st
->st_mtime
== gaiconf_mtime
;
1702 libc_freeres_fn(fini
)
1704 if (labels
!= default_labels
)
1706 const struct prefixentry
*old
= labels
;
1707 labels
= default_labels
;
1708 free ((void *) old
);
1711 if (precedence
!= default_precedence
)
1713 const struct prefixentry
*old
= precedence
;
1714 precedence
= default_precedence
;
1715 free ((void *) old
);
1718 if (scopes
!= default_scopes
)
1720 const struct scopeentry
*old
= scopes
;
1721 scopes
= default_scopes
;
1722 free ((void *) old
);
1729 struct prefixentry entry
;
1730 struct prefixlist
*next
;
1736 struct scopeentry entry
;
1737 struct scopelist
*next
;
1742 free_prefixlist (struct prefixlist
*list
)
1744 while (list
!= NULL
)
1746 struct prefixlist
*oldp
= list
;
1754 free_scopelist (struct scopelist
*list
)
1756 while (list
!= NULL
)
1758 struct scopelist
*oldp
= list
;
1766 prefixcmp (const void *p1
, const void *p2
)
1768 const struct prefixentry
*e1
= (const struct prefixentry
*) p1
;
1769 const struct prefixentry
*e2
= (const struct prefixentry
*) p2
;
1771 if (e1
->bits
< e2
->bits
)
1773 if (e1
->bits
== e2
->bits
)
1780 scopecmp (const void *p1
, const void *p2
)
1782 const struct scopeentry
*e1
= (const struct scopeentry
*) p1
;
1783 const struct scopeentry
*e2
= (const struct scopeentry
*) p2
;
1785 if (e1
->netmask
> e2
->netmask
)
1787 if (e1
->netmask
== e2
->netmask
)
1796 struct prefixlist
*labellist
= NULL
;
1797 size_t nlabellist
= 0;
1798 bool labellist_nullbits
= false;
1799 struct prefixlist
*precedencelist
= NULL
;
1800 size_t nprecedencelist
= 0;
1801 bool precedencelist_nullbits
= false;
1802 struct scopelist
*scopelist
= NULL
;
1803 size_t nscopelist
= 0;
1804 bool scopelist_nullbits
= false;
1806 FILE *fp
= fopen (GAICONF_FNAME
, "rce");
1810 if (__fxstat64 (_STAT_VER
, fileno (fp
), &st
) != 0)
1819 __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
1821 while (!feof_unlocked (fp
))
1823 ssize_t n
= __getline (&line
, &linelen
, fp
);
1827 /* Handle comments. No escaping possible so this is easy. */
1828 char *cp
= strchr (line
, '#');
1833 while (isspace (*cp
))
1837 while (*cp
!= '\0' && !isspace (*cp
))
1839 size_t cmdlen
= cp
- cmd
;
1843 while (isspace (*cp
))
1847 while (*cp
!= '\0' && !isspace (*cp
))
1849 size_t val1len
= cp
- cmd
;
1851 /* We always need at least two values. */
1857 while (isspace (*cp
))
1861 while (*cp
!= '\0' && !isspace (*cp
))
1864 /* Ignore the rest of the line. */
1867 struct prefixlist
**listp
;
1873 if (strcmp (cmd
, "label") == 0)
1875 struct in6_addr prefix
;
1876 unsigned long int bits
;
1877 unsigned long int val
;
1882 nullbitsp
= &labellist_nullbits
;
1887 cp
= strchr (val1
, '/');
1890 if (inet_pton (AF_INET6
, val1
, &prefix
)
1892 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
1896 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
1901 struct prefixlist
*newp
= malloc (sizeof (*newp
));
1909 memcpy (&newp
->entry
.prefix
, &prefix
, sizeof (prefix
));
1910 newp
->entry
.bits
= bits
;
1911 newp
->entry
.val
= val
;
1912 newp
->next
= *listp
;
1915 *nullbitsp
|= bits
== 0;
1921 if (strcmp (cmd
, "reload") == 0)
1923 gaiconf_reload_flag
= strcmp (val1
, "yes") == 0;
1924 if (gaiconf_reload_flag
)
1925 gaiconf_reload_flag_ever_set
= 1;
1930 if (strcmp (cmd
, "scopev4") == 0)
1932 struct in6_addr prefix
;
1933 unsigned long int bits
;
1934 unsigned long int val
;
1939 cp
= strchr (val1
, '/');
1942 if (inet_pton (AF_INET6
, val1
, &prefix
))
1945 if (IN6_IS_ADDR_V4MAPPED (&prefix
)
1947 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
1952 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
1957 struct scopelist
*newp
;
1959 newp
= malloc (sizeof (*newp
));
1967 newp
->entry
.netmask
= htonl (bits
!= 96
1971 newp
->entry
.addr32
= (prefix
.s6_addr32
[3]
1972 & newp
->entry
.netmask
);
1973 newp
->entry
.scope
= val
;
1974 newp
->next
= scopelist
;
1977 scopelist_nullbits
|= bits
== 96;
1980 else if (inet_pton (AF_INET
, val1
, &prefix
.s6_addr32
[3])
1982 || (bits
= strtoul (cp
, &endp
, 10)) != ULONG_MAX
1986 && ((val
= strtoul (val2
, &endp
, 10)) != ULONG_MAX
1998 if (strcmp (cmd
, "precedence") == 0)
2000 listp
= &precedencelist
;
2001 lenp
= &nprecedencelist
;
2002 nullbitsp
= &precedencelist_nullbits
;
2013 /* Create the array for the labels. */
2014 struct prefixentry
*new_labels
;
2017 if (!labellist_nullbits
)
2019 new_labels
= malloc (nlabellist
* sizeof (*new_labels
));
2020 if (new_labels
== NULL
)
2024 if (!labellist_nullbits
)
2027 memset (&new_labels
[i
].prefix
, '\0', sizeof (struct in6_addr
));
2028 new_labels
[i
].bits
= 0;
2029 new_labels
[i
].val
= 1;
2032 struct prefixlist
*l
= labellist
;
2035 new_labels
[i
] = l
->entry
;
2038 free_prefixlist (labellist
);
2040 /* Sort the entries so that the most specific ones are at
2042 qsort (new_labels
, nlabellist
, sizeof (*new_labels
), prefixcmp
);
2045 new_labels
= (struct prefixentry
*) default_labels
;
2047 struct prefixentry
*new_precedence
;
2048 if (nprecedencelist
> 0)
2050 if (!precedencelist_nullbits
)
2052 new_precedence
= malloc (nprecedencelist
* sizeof (*new_precedence
));
2053 if (new_precedence
== NULL
)
2055 if (new_labels
!= default_labels
)
2060 int i
= nprecedencelist
;
2061 if (!precedencelist_nullbits
)
2064 memset (&new_precedence
[i
].prefix
, '\0',
2065 sizeof (struct in6_addr
));
2066 new_precedence
[i
].bits
= 0;
2067 new_precedence
[i
].val
= 40;
2070 struct prefixlist
*l
= precedencelist
;
2073 new_precedence
[i
] = l
->entry
;
2076 free_prefixlist (precedencelist
);
2078 /* Sort the entries so that the most specific ones are at
2080 qsort (new_precedence
, nprecedencelist
, sizeof (*new_precedence
),
2084 new_precedence
= (struct prefixentry
*) default_precedence
;
2086 struct scopeentry
*new_scopes
;
2089 if (!scopelist_nullbits
)
2091 new_scopes
= malloc (nscopelist
* sizeof (*new_scopes
));
2092 if (new_scopes
== NULL
)
2094 if (new_labels
!= default_labels
)
2096 if (new_precedence
!= default_precedence
)
2097 free (new_precedence
);
2102 if (!scopelist_nullbits
)
2105 new_scopes
[i
].addr32
= 0;
2106 new_scopes
[i
].netmask
= 0;
2107 new_scopes
[i
].scope
= 14;
2110 struct scopelist
*l
= scopelist
;
2113 new_scopes
[i
] = l
->entry
;
2116 free_scopelist (scopelist
);
2118 /* Sort the entries so that the most specific ones are at
2120 qsort (new_scopes
, nscopelist
, sizeof (*new_scopes
),
2124 new_scopes
= (struct scopeentry
*) default_scopes
;
2126 /* Now we are ready to replace the values. */
2127 const struct prefixentry
*old
= labels
;
2128 labels
= new_labels
;
2129 if (old
!= default_labels
)
2130 free ((void *) old
);
2133 precedence
= new_precedence
;
2134 if (old
!= default_precedence
)
2135 free ((void *) old
);
2137 const struct scopeentry
*oldscope
= scopes
;
2138 scopes
= new_scopes
;
2139 if (oldscope
!= default_scopes
)
2140 free ((void *) oldscope
);
2142 save_gaiconf_mtime (&st
);
2147 free_prefixlist (labellist
);
2148 free_prefixlist (precedencelist
);
2149 free_scopelist (scopelist
);
2151 /* If we previously read the file but it is gone now, free the
2152 old data and use the builtin one. Leave the reload flag
2160 gaiconf_reload (void)
2163 if (__xstat64 (_STAT_VER
, GAICONF_FNAME
, &st
) != 0
2164 || !check_gaiconf_mtime (&st
))
2170 getaddrinfo (const char *name
, const char *service
,
2171 const struct addrinfo
*hints
, struct addrinfo
**pai
)
2173 int i
= 0, last_i
= 0;
2175 struct addrinfo
*p
= NULL
;
2176 struct gaih_service gaih_service
, *pservice
;
2177 struct addrinfo local_hints
;
2179 if (name
!= NULL
&& name
[0] == '*' && name
[1] == 0)
2182 if (service
!= NULL
&& service
[0] == '*' && service
[1] == 0)
2185 if (name
== NULL
&& service
== NULL
)
2189 hints
= &default_hints
;
2192 & ~(AI_PASSIVE
|AI_CANONNAME
|AI_NUMERICHOST
|AI_ADDRCONFIG
|AI_V4MAPPED
2193 |AI_IDN
|AI_CANONIDN
|DEPRECATED_AI_IDN
2194 |AI_NUMERICSERV
|AI_ALL
))
2195 return EAI_BADFLAGS
;
2197 if ((hints
->ai_flags
& AI_CANONNAME
) && name
== NULL
)
2198 return EAI_BADFLAGS
;
2200 struct in6addrinfo
*in6ai
= NULL
;
2201 size_t in6ailen
= 0;
2202 bool seen_ipv4
= false;
2203 bool seen_ipv6
= false;
2204 bool check_pf_called
= false;
2206 if (hints
->ai_flags
& AI_ADDRCONFIG
)
2208 /* We might need information about what interfaces are available.
2209 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2210 cannot cache the results since new interfaces could be added at
2212 __check_pf (&seen_ipv4
, &seen_ipv6
, &in6ai
, &in6ailen
);
2213 check_pf_called
= true;
2215 /* Now make a decision on what we return, if anything. */
2216 if (hints
->ai_family
== PF_UNSPEC
&& (seen_ipv4
|| seen_ipv6
))
2218 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2219 narrow down the search. */
2220 if ((! seen_ipv4
|| ! seen_ipv6
) && (seen_ipv4
|| seen_ipv6
))
2222 local_hints
= *hints
;
2223 local_hints
.ai_family
= seen_ipv4
? PF_INET
: PF_INET6
;
2224 hints
= &local_hints
;
2227 else if ((hints
->ai_family
== PF_INET
&& ! seen_ipv4
)
2228 || (hints
->ai_family
== PF_INET6
&& ! seen_ipv6
))
2230 /* We cannot possibly return a valid answer. */
2231 __free_in6ai (in6ai
);
2236 if (service
&& service
[0])
2239 gaih_service
.name
= service
;
2240 gaih_service
.num
= strtoul (gaih_service
.name
, &c
, 10);
2243 if (hints
->ai_flags
& AI_NUMERICSERV
)
2245 __free_in6ai (in6ai
);
2249 gaih_service
.num
= -1;
2252 pservice
= &gaih_service
;
2257 struct addrinfo
**end
= &p
;
2259 unsigned int naddrs
= 0;
2260 if (hints
->ai_family
== AF_UNSPEC
|| hints
->ai_family
== AF_INET
2261 || hints
->ai_family
== AF_INET6
)
2263 struct scratch_buffer tmpbuf
;
2264 scratch_buffer_init (&tmpbuf
);
2265 last_i
= gaih_inet (name
, pservice
, hints
, end
, &naddrs
, &tmpbuf
);
2266 scratch_buffer_free (&tmpbuf
);
2271 __free_in6ai (in6ai
);
2277 end
= &((*end
)->ai_next
);
2283 __free_in6ai (in6ai
);
2289 /* Read the config file. */
2290 __libc_once_define (static, once
);
2291 __typeof (once
) old_once
= once
;
2292 __libc_once (once
, gaiconf_init
);
2293 /* Sort results according to RFC 3484. */
2294 struct sort_result
*results
;
2297 struct addrinfo
*last
= NULL
;
2298 char *canonname
= NULL
;
2299 bool malloc_results
;
2300 size_t alloc_size
= nresults
* (sizeof (*results
) + sizeof (size_t));
2303 = !__libc_use_alloca (alloc_size
);
2306 results
= malloc (alloc_size
);
2307 if (results
== NULL
)
2309 __free_in6ai (in6ai
);
2314 results
= alloca (alloc_size
);
2315 order
= (size_t *) (results
+ nresults
);
2317 /* Now we definitely need the interface information. */
2318 if (! check_pf_called
)
2319 __check_pf (&seen_ipv4
, &seen_ipv6
, &in6ai
, &in6ailen
);
2321 /* If we have information about deprecated and temporary addresses
2322 sort the array now. */
2324 qsort (in6ai
, in6ailen
, sizeof (*in6ai
), in6aicmp
);
2329 for (i
= 0, q
= p
; q
!= NULL
; ++i
, last
= q
, q
= q
->ai_next
)
2331 results
[i
].dest_addr
= q
;
2332 results
[i
].native
= -1;
2335 /* If we just looked up the address for a different
2336 protocol, reuse the result. */
2337 if (last
!= NULL
&& last
->ai_addrlen
== q
->ai_addrlen
2338 && memcmp (last
->ai_addr
, q
->ai_addr
, q
->ai_addrlen
) == 0)
2340 memcpy (&results
[i
].source_addr
, &results
[i
- 1].source_addr
,
2341 results
[i
- 1].source_addr_len
);
2342 results
[i
].source_addr_len
= results
[i
- 1].source_addr_len
;
2343 results
[i
].got_source_addr
= results
[i
- 1].got_source_addr
;
2344 results
[i
].source_addr_flags
= results
[i
- 1].source_addr_flags
;
2345 results
[i
].prefixlen
= results
[i
- 1].prefixlen
;
2346 results
[i
].index
= results
[i
- 1].index
;
2350 results
[i
].got_source_addr
= false;
2351 results
[i
].source_addr_flags
= 0;
2352 results
[i
].prefixlen
= 0;
2353 results
[i
].index
= 0xffffffffu
;
2355 /* We overwrite the type with SOCK_DGRAM since we do not
2356 want connect() to connect to the other side. If we
2357 cannot determine the source address remember this
2359 if (fd
== -1 || (af
== AF_INET
&& q
->ai_family
== AF_INET6
))
2363 __close_nocancel_nostatus (fd
);
2365 fd
= __socket (af
, SOCK_DGRAM
| SOCK_CLOEXEC
, IPPROTO_IP
);
2369 /* Reset the connection. */
2370 struct sockaddr sa
= { .sa_family
= AF_UNSPEC
};
2371 __connect (fd
, &sa
, sizeof (sa
));
2374 socklen_t sl
= sizeof (results
[i
].source_addr
);
2376 && __connect (fd
, q
->ai_addr
, q
->ai_addrlen
) == 0
2377 && __getsockname (fd
,
2378 (struct sockaddr
*) &results
[i
].source_addr
,
2381 results
[i
].source_addr_len
= sl
;
2382 results
[i
].got_source_addr
= true;
2386 /* See whether the source address is on the list of
2387 deprecated or temporary addresses. */
2388 struct in6addrinfo tmp
;
2390 if (q
->ai_family
== AF_INET
&& af
== AF_INET
)
2392 struct sockaddr_in
*sinp
2393 = (struct sockaddr_in
*) &results
[i
].source_addr
;
2396 tmp
.addr
[2] = htonl (0xffff);
2397 /* Special case for lo interface, the source address
2398 being possibly different than the interface
2400 if ((ntohl(sinp
->sin_addr
.s_addr
) & 0xff000000)
2402 tmp
.addr
[3] = htonl(0x7f000001);
2404 tmp
.addr
[3] = sinp
->sin_addr
.s_addr
;
2408 struct sockaddr_in6
*sin6p
2409 = (struct sockaddr_in6
*) &results
[i
].source_addr
;
2410 memcpy (tmp
.addr
, &sin6p
->sin6_addr
, IN6ADDRSZ
);
2413 struct in6addrinfo
*found
2414 = bsearch (&tmp
, in6ai
, in6ailen
, sizeof (*in6ai
),
2418 results
[i
].source_addr_flags
= found
->flags
;
2419 results
[i
].prefixlen
= found
->prefixlen
;
2420 results
[i
].index
= found
->index
;
2424 if (q
->ai_family
== AF_INET
&& af
== AF_INET6
)
2426 /* We have to convert the address. The socket is
2427 IPv6 and the request is for IPv4. */
2428 struct sockaddr_in6
*sin6
2429 = (struct sockaddr_in6
*) &results
[i
].source_addr
;
2430 struct sockaddr_in
*sin
2431 = (struct sockaddr_in
*) &results
[i
].source_addr
;
2432 assert (IN6_IS_ADDR_V4MAPPED (sin6
->sin6_addr
.s6_addr32
));
2433 sin
->sin_family
= AF_INET
;
2434 /* We do not have to initialize sin_port since this
2435 fields has the same position and size in the IPv6
2437 assert (offsetof (struct sockaddr_in
, sin_port
)
2438 == offsetof (struct sockaddr_in6
, sin6_port
));
2439 assert (sizeof (sin
->sin_port
)
2440 == sizeof (sin6
->sin6_port
));
2441 memcpy (&sin
->sin_addr
,
2442 &sin6
->sin6_addr
.s6_addr32
[3], INADDRSZ
);
2443 results
[i
].source_addr_len
= sizeof (struct sockaddr_in
);
2446 else if (errno
== EAFNOSUPPORT
&& af
== AF_INET6
2447 && q
->ai_family
== AF_INET
)
2448 /* This could mean IPv6 sockets are IPv6-only. */
2451 /* Just make sure that if we have to process the same
2452 address again we do not copy any memory. */
2453 results
[i
].source_addr_len
= 0;
2456 /* Remember the canonical name. */
2457 if (q
->ai_canonname
!= NULL
)
2459 assert (canonname
== NULL
);
2460 canonname
= q
->ai_canonname
;
2461 q
->ai_canonname
= NULL
;
2466 __close_nocancel_nostatus (fd
);
2468 /* We got all the source addresses we can get, now sort using
2470 struct sort_result_combo src
2471 = { .results
= results
, .nresults
= nresults
};
2472 if (__glibc_unlikely (gaiconf_reload_flag_ever_set
))
2474 __libc_lock_define_initialized (static, lock
);
2476 __libc_lock_lock (lock
);
2477 if (__libc_once_get (old_once
) && gaiconf_reload_flag
)
2479 __qsort_r (order
, nresults
, sizeof (order
[0]), rfc3484_sort
, &src
);
2480 __libc_lock_unlock (lock
);
2483 __qsort_r (order
, nresults
, sizeof (order
[0]), rfc3484_sort
, &src
);
2485 /* Queue the results up as they come out of sorting. */
2486 q
= p
= results
[order
[0]].dest_addr
;
2487 for (i
= 1; i
< nresults
; ++i
)
2488 q
= q
->ai_next
= results
[order
[i
]].dest_addr
;
2491 /* Fill in the canonical name into the new first entry. */
2492 p
->ai_canonname
= canonname
;
2498 __free_in6ai (in6ai
);
2506 return last_i
? -last_i
: EAI_NONAME
;
2508 libc_hidden_def (getaddrinfo
)
2510 nss_interface_function (getaddrinfo
)
2513 freeaddrinfo (struct addrinfo
*ai
)
2521 free (p
->ai_canonname
);
2525 libc_hidden_def (freeaddrinfo
)