1 /* The Inner Net License, Version 2.00
3 The author(s) grant permission for redistribution and use in source and
4 binary forms, with or without modification, of the software and documentation
5 provided that the following conditions are met:
7 0. If you receive a version of the software that is specifically labelled
8 as not being for redistribution (check the version message and/or README),
9 you are not permitted to redistribute that version of the software in any
11 1. All terms of the all other applicable copyrights and licenses must be
13 2. Redistributions of source code must retain the authors' copyright
14 notice(s), this list of conditions, and the following disclaimer.
15 3. Redistributions in binary form must reproduce the authors' copyright
16 notice(s), this list of conditions, and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18 4. [The copyright holder has authorized the removal of this clause.]
19 5. Neither the name(s) of the author(s) nor the names of its contributors
20 may be used to endorse or promote products derived from this software
21 without specific prior written permission.
23 THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS ``AS IS'' AND ANY
24 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
27 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 If these license terms cause you a real problem, contact the author. */
36 /* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */
47 #include <stdio_ext.h>
50 #include <arpa/inet.h>
52 #include <netinet/in.h>
53 #include <sys/socket.h>
55 #include <sys/types.h>
57 #include <sys/utsname.h>
60 #include <bits/libc-lock.h>
61 #include <not-cancel.h>
62 #include <nscd/nscd-client.h>
63 #include <nscd/nscd_proto.h>
64 #include <resolv/res_hconf.h>
67 extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
68 extern int __idna_to_unicode_lzlz (const char *input, char **output,
70 # include <libidn/idna.h>
73 #define GAIH_OKIFUNSPEC 0x0100
74 #define GAIH_EAI ~(GAIH_OKIFUNSPEC)
77 # define UNIX_PATH_MAX 108
88 struct gaih_servtuple *next;
94 static const struct gaih_servtuple nullserv;
106 /* Values for `protoflag'. */
107 #define GAI_PROTO_NOSERVICE 1
108 #define GAI_PROTO_PROTOANY 2
110 static const struct gaih_typeproto gaih_inet_typeproto[] =
112 { 0, 0, 0, false, "" },
113 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
114 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
115 #if defined SOCK_DCCP && defined IPPROTO_DCCP
116 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
118 #ifdef IPPROTO_UDPLITE
119 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
122 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
123 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
125 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
126 { 0, 0, 0, false, "" }
132 int (*gaih)(const char *name, const struct gaih_service *service,
133 const struct addrinfo *req, struct addrinfo **pai,
134 unsigned int *naddrs);
137 static const struct addrinfo default_hints =
139 .ai_flags = AI_DEFAULT,
140 .ai_family = PF_UNSPEC,
145 .ai_canonname = NULL,
151 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
152 const struct addrinfo *req, struct gaih_servtuple *st)
155 size_t tmpbuflen = 1024;
162 tmpbuf = __alloca (tmpbuflen);
164 r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen,
166 if (r != 0 || s == NULL)
171 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
177 st->socktype = tp->socktype;
178 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
179 ? req->ai_protocol : tp->protocol);
180 st->port = s->s_port;
185 #define gethosts(_family, _type) \
191 char *localcanon = NULL; \
195 status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, tmpbuflen, \
196 &rc, &herrno, NULL, &localcanon)); \
197 if (rc != ERANGE || herrno != NETDB_INTERNAL) \
199 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
201 if (status == NSS_STATUS_SUCCESS && rc == 0) \
207 if (herrno == NETDB_INTERNAL) \
209 __set_h_errno (herrno); \
210 _res.options = old_res_options; \
211 return -EAI_SYSTEM; \
213 if (herrno == TRY_AGAIN) \
214 no_data = EAI_AGAIN; \
216 no_data = herrno == NO_DATA; \
218 else if (h != NULL) \
220 for (i = 0; h->h_addr_list[i]; i++) \
224 *pat = __alloca (sizeof (struct gaih_addrtuple)); \
225 (*pat)->scopeid = 0; \
227 uint32_t *addr = (*pat)->addr; \
228 (*pat)->next = NULL; \
229 (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \
230 if (_family == AF_INET && req->ai_family == AF_INET6) \
232 (*pat)->family = AF_INET6; \
233 addr[3] = *(uint32_t *) h->h_addr_list[i]; \
234 addr[2] = htonl (0xffff); \
240 (*pat)->family = _family; \
241 memcpy (addr, h->h_addr_list[i], sizeof(_type)); \
243 pat = &((*pat)->next); \
246 if (localcanon != NULL && canon == NULL) \
247 canon = strdupa (localcanon); \
249 if (_family == AF_INET6 && i > 0) \
255 typedef enum nss_status (*nss_gethostbyname4_r)
256 (const char *name, struct gaih_addrtuple **pat,
257 char *buffer, size_t buflen, int *errnop,
258 int *h_errnop, int32_t *ttlp);
259 typedef enum nss_status (*nss_gethostbyname3_r)
260 (const char *name, int af, struct hostent *host,
261 char *buffer, size_t buflen, int *errnop,
262 int *h_errnop, int32_t *ttlp, char **canonp);
263 typedef enum nss_status (*nss_getcanonname_r)
264 (const char *name, char *buffer, size_t buflen, char **result,
265 int *errnop, int *h_errnop);
266 extern service_user *__nss_hosts_database attribute_hidden;
270 gaih_inet (const char *name, const struct gaih_service *service,
271 const struct addrinfo *req, struct addrinfo **pai,
272 unsigned int *naddrs)
274 const struct gaih_typeproto *tp = gaih_inet_typeproto;
275 struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
276 struct gaih_addrtuple *at = NULL;
278 bool got_ipv6 = false;
279 const char *canon = NULL;
280 const char *orig_name = name;
282 if (req->ai_protocol || req->ai_socktype)
287 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
288 || (req->ai_protocol != 0
289 && !(tp->protoflag & GAI_PROTO_PROTOANY)
290 && req->ai_protocol != tp->protocol)))
295 if (req->ai_socktype)
296 return GAIH_OKIFUNSPEC | -EAI_SOCKTYPE;
298 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
305 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
306 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
308 if (service->num < 0)
312 st = (struct gaih_servtuple *)
313 __alloca (sizeof (struct gaih_servtuple));
315 if ((rc = gaih_inet_serv (service->name, tp, req, st)))
320 struct gaih_servtuple **pst = &st;
321 for (tp++; tp->name[0]; tp++)
323 struct gaih_servtuple *newp;
325 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
328 if (req->ai_socktype != 0
329 && req->ai_socktype != tp->socktype)
331 if (req->ai_protocol != 0
332 && !(tp->protoflag & GAI_PROTO_PROTOANY)
333 && req->ai_protocol != tp->protocol)
336 newp = (struct gaih_servtuple *)
337 __alloca (sizeof (struct gaih_servtuple));
339 if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
341 if (rc & GAIH_OKIFUNSPEC)
349 if (st == (struct gaih_servtuple *) &nullserv)
350 return GAIH_OKIFUNSPEC | -EAI_SERVICE;
355 port = htons (service->num);
363 if (req->ai_socktype || req->ai_protocol)
365 st = __alloca (sizeof (struct gaih_servtuple));
367 st->socktype = tp->socktype;
368 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
369 ? req->ai_protocol : tp->protocol);
374 /* Neither socket type nor protocol is set. Return all socket types
376 struct gaih_servtuple **lastp = &st;
377 for (++tp; tp->name[0]; ++tp)
380 struct gaih_servtuple *newp;
382 newp = __alloca (sizeof (struct gaih_servtuple));
384 newp->socktype = tp->socktype;
385 newp->protocol = tp->protocol;
396 at = __alloca (sizeof (struct gaih_addrtuple));
398 at->family = AF_UNSPEC;
403 if (req->ai_flags & AI_IDN)
406 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
407 idn_flags |= IDNA_ALLOW_UNASSIGNED;
408 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
409 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
412 rc = __idna_to_ascii_lz (name, &p, idn_flags);
413 if (rc != IDNA_SUCCESS)
415 if (rc == IDNA_MALLOC_ERROR)
417 if (rc == IDNA_DLOPEN_ERROR)
419 return -EAI_IDN_ENCODE;
421 /* In case the output string is the same as the input string
422 no new string has been allocated. */
431 if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
433 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
434 at->family = AF_INET;
435 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
437 at->addr[3] = at->addr[0];
438 at->addr[2] = htonl (0xffff);
441 at->family = AF_INET6;
444 return -EAI_ADDRFAMILY;
446 if (req->ai_flags & AI_CANONNAME)
449 else if (at->family == AF_UNSPEC)
451 char *namebuf = (char *) name;
452 char *scope_delim = strchr (name, SCOPE_DELIMITER);
454 if (__builtin_expect (scope_delim != NULL, 0))
456 namebuf = alloca (scope_delim - name + 1);
457 *((char *) __mempcpy (namebuf, name, scope_delim - name)) = '\0';
460 if (inet_pton (AF_INET6, namebuf, at->addr) > 0)
462 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
463 at->family = AF_INET6;
464 else if (req->ai_family == AF_INET
465 && IN6_IS_ADDR_V4MAPPED (at->addr))
467 at->addr[0] = at->addr[3];
468 at->family = AF_INET;
471 return -EAI_ADDRFAMILY;
473 if (scope_delim != NULL)
475 int try_numericscope = 0;
476 if (IN6_IS_ADDR_LINKLOCAL (at->addr)
477 || IN6_IS_ADDR_MC_LINKLOCAL (at->addr))
479 at->scopeid = if_nametoindex (scope_delim + 1);
480 if (at->scopeid == 0)
481 try_numericscope = 1;
484 try_numericscope = 1;
486 if (try_numericscope != 0)
489 assert (sizeof (uint32_t) <= sizeof (unsigned long));
490 at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end,
493 return GAIH_OKIFUNSPEC | -EAI_NONAME;
497 if (req->ai_flags & AI_CANONNAME)
502 if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
504 struct gaih_addrtuple **pat = &at;
506 int no_inet6_data = 0;
507 service_user *nip = NULL;
508 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
509 enum nss_status status = NSS_STATUS_UNAVAIL;
513 /* If we do not have to look for IPv4 and IPv6 together, use
514 the simple, old functions. */
515 if (req->ai_family == AF_INET
516 || (req->ai_family == AF_INET6
517 && ((req->ai_flags & AI_V4MAPPED) == 0
518 || (req->ai_flags & AI_ALL) == 0)))
520 int family = req->ai_family;
521 size_t tmpbuflen = 512;
522 char *tmpbuf = alloca (tmpbuflen);
531 rc = __gethostbyname2_r (name, family, &th, tmpbuf,
532 tmpbuflen, &h, &herrno);
533 if (rc != ERANGE || herrno != NETDB_INTERNAL)
535 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
542 if (req->ai_family == AF_INET6
543 && (req->ai_flags & AI_V4MAPPED)
544 && family == AF_INET6)
546 /* Try again, this time looking for IPv4
554 /* We found data, now convert it into the list. */
555 for (int i = 0; h->h_addr_list[i]; ++i)
559 *pat = __alloca (sizeof (struct gaih_addrtuple));
563 (*pat)->family = req->ai_family;
564 if (family == req->ai_family)
565 memcpy ((*pat)->addr, h->h_addr_list[i],
569 uint32_t *addr = (uint32_t *) (*pat)->addr;
570 addr[3] = *(uint32_t *) h->h_addr_list[i];
571 addr[2] = htonl (0xffff);
575 pat = &((*pat)->next);
581 if (herrno == NETDB_INTERNAL)
583 __set_h_errno (herrno);
586 if (herrno == TRY_AGAIN)
590 /* We made requests but they turned out no data.
591 The name is known, though. */
592 return GAIH_OKIFUNSPEC | -EAI_NODATA;
599 if (__nss_not_use_nscd_hosts > 0
600 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
601 __nss_not_use_nscd_hosts = 0;
603 if (!__nss_not_use_nscd_hosts
604 && !__nss_database_custom[NSS_DBSIDX_hosts])
606 /* Try to use nscd. */
607 struct nscd_ai_result *air = NULL;
609 int err = __nscd_getai (name, &air, &herrno);
612 /* Transform into gaih_addrtuple list. */
613 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
614 char *addrs = air->addrs;
616 for (int i = 0; i < air->naddrs; ++i)
618 socklen_t size = (air->family[i] == AF_INET
619 ? INADDRSZ : IN6ADDRSZ);
622 *pat = __alloca (sizeof (struct gaih_addrtuple));
625 uint32_t *pataddr = (*pat)->addr;
627 if (added_canon || air->canon == NULL)
630 canon = (*pat)->name = strdupa (air->canon);
632 if (air->family[i] == AF_INET
633 && req->ai_family == AF_INET6
634 && (req->ai_flags & AI_V4MAPPED))
636 (*pat)->family = AF_INET6;
637 pataddr[3] = *(uint32_t *) addrs;
638 pataddr[2] = htonl (0xffff);
641 pat = &((*pat)->next);
644 else if (req->ai_family == AF_UNSPEC
645 || air->family[i] == req->ai_family)
647 (*pat)->family = air->family[i];
648 memcpy (pataddr, addrs, size);
649 pat = &((*pat)->next);
651 if (air->family[i] == AF_INET6)
659 if (at->family == AF_UNSPEC)
660 return GAIH_OKIFUNSPEC | -EAI_NONAME;
665 /* The database contains a negative entry. */
667 else if (__nss_not_use_nscd_hosts == 0)
669 if (herrno == NETDB_INTERNAL && errno == ENOMEM)
671 if (herrno == TRY_AGAIN)
678 if (__nss_hosts_database != NULL)
681 nip = __nss_hosts_database;
684 no_more = __nss_database_lookup ("hosts", NULL,
685 "dns [!UNAVAIL=return] files",
688 /* Initialize configurations. */
689 if (__builtin_expect (!_res_hconf.initialized, 0))
691 if (__res_maybe_init (&_res, 0) == -1)
694 /* If we are looking for both IPv4 and IPv6 address we don't
695 want the lookup functions to automatically promote IPv4
696 addresses to IPv6 addresses. Currently this is decided
697 by setting the RES_USE_INET6 bit in _res.options. */
698 old_res_options = _res.options;
699 _res.options &= ~RES_USE_INET6;
701 size_t tmpbuflen = 1024;
702 char *tmpbuf = alloca (tmpbuflen);
707 nss_gethostbyname4_r fct4
708 = __nss_lookup_function (nip, "gethostbyname4_r");
716 status = DL_CALL_FCT (fct4, (name, pat, tmpbuf,
717 tmpbuflen, &rc, &herrno,
719 if (status == NSS_STATUS_SUCCESS)
721 if (status != NSS_STATUS_TRYAGAIN
722 || rc != ERANGE || herrno != NETDB_INTERNAL)
724 if (status == NSS_STATUS_TRYAGAIN
725 && herrno == TRY_AGAIN)
728 no_data = herrno == NO_DATA;
731 tmpbuf = extend_alloca (tmpbuf,
732 tmpbuflen, 2 * tmpbuflen);
735 no_inet6_data = no_data;
737 if (status == NSS_STATUS_SUCCESS)
739 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
740 canon = (*pat)->name;
743 pat = &((*pat)->next);
748 nss_gethostbyname3_r fct = NULL;
749 if (req->ai_flags & AI_CANONNAME)
750 /* No need to use this function if we do not look for
751 the canonical name. The function does not exist in
752 all NSS modules and therefore the lookup would
754 fct = __nss_lookup_function (nip, "gethostbyname3_r");
756 /* We are cheating here. The gethostbyname2_r
757 function does not have the same interface as
758 gethostbyname3_r but the extra arguments the
759 latter takes are added at the end. So the
760 gethostbyname2_r code will just ignore them. */
761 fct = __nss_lookup_function (nip, "gethostbyname2_r");
765 if (req->ai_family == AF_INET6
766 || req->ai_family == AF_UNSPEC)
768 gethosts (AF_INET6, struct in6_addr);
769 no_inet6_data = no_data;
770 inet6_status = status;
772 if (req->ai_family == AF_INET
773 || req->ai_family == AF_UNSPEC
774 || (req->ai_family == AF_INET6
775 && (req->ai_flags & AI_V4MAPPED)
776 /* Avoid generating the mapped addresses if we
777 know we are not going to need them. */
778 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
780 gethosts (AF_INET, struct in_addr);
782 if (req->ai_family == AF_INET)
784 no_inet6_data = no_data;
785 inet6_status = status;
789 /* If we found one address for AF_INET or AF_INET6,
790 don't continue the search. */
791 if (inet6_status == NSS_STATUS_SUCCESS
792 || status == NSS_STATUS_SUCCESS)
794 if ((req->ai_flags & AI_CANONNAME) != 0
797 /* If we need the canonical name, get it
798 from the same service as the result. */
799 nss_getcanonname_r cfct;
802 cfct = __nss_lookup_function (nip,
806 const size_t max_fqdn_len = 256;
807 char *buf = alloca (max_fqdn_len);
810 if (DL_CALL_FCT (cfct, (at->name ?: name,
813 == NSS_STATUS_SUCCESS)
816 /* Set to name now to avoid using
821 status = NSS_STATUS_SUCCESS;
825 /* We can have different states for AF_INET and
826 AF_INET6. Try to find a useful one for both. */
827 if (inet6_status == NSS_STATUS_TRYAGAIN)
828 status = NSS_STATUS_TRYAGAIN;
829 else if (status == NSS_STATUS_UNAVAIL
830 && inet6_status != NSS_STATUS_UNAVAIL)
831 status = inet6_status;
835 status = NSS_STATUS_UNAVAIL;
838 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
841 if (nip->next == NULL)
847 _res.options = old_res_options;
849 if (no_data != 0 && no_inet6_data != 0)
851 /* If both requests timed out report this. */
852 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
855 /* We made requests but they turned out no data. The name
857 return GAIH_OKIFUNSPEC | -EAI_NODATA;
862 if (at->family == AF_UNSPEC)
863 return GAIH_OKIFUNSPEC | -EAI_NONAME;
867 struct gaih_addrtuple *atr;
868 atr = at = __alloca (sizeof (struct gaih_addrtuple));
869 memset (at, '\0', sizeof (struct gaih_addrtuple));
871 if (req->ai_family == AF_UNSPEC)
873 at->next = __alloca (sizeof (struct gaih_addrtuple));
874 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
877 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
879 at->family = AF_INET6;
880 if ((req->ai_flags & AI_PASSIVE) == 0)
881 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
885 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
887 atr->family = AF_INET;
888 if ((req->ai_flags & AI_PASSIVE) == 0)
889 atr->addr[0] = htonl (INADDR_LOOPBACK);
894 struct gaih_servtuple *st2;
895 struct gaih_addrtuple *at2 = at;
900 buffer is the size of an unformatted IPv6 address in printable format.
904 /* Only the first entry gets the canonical name. */
905 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
909 struct hostent *h = NULL;
912 size_t tmpbuflen = 512;
917 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, tmpbuflen * 2);
918 rc = __gethostbyaddr_r (at2->addr,
919 ((at2->family == AF_INET6)
920 ? sizeof (struct in6_addr)
921 : sizeof (struct in_addr)),
922 at2->family, &th, tmpbuf,
923 tmpbuflen, &h, &herrno);
925 while (rc == ERANGE && herrno == NETDB_INTERNAL);
927 if (rc != 0 && herrno == NETDB_INTERNAL)
929 __set_h_errno (herrno);
937 assert (orig_name != NULL);
938 /* If the canonical name cannot be determined, use
939 the passed in string. */
945 if (req->ai_flags & AI_CANONIDN)
948 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
949 idn_flags |= IDNA_ALLOW_UNASSIGNED;
950 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
951 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
954 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
955 if (rc != IDNA_SUCCESS)
957 if (rc == IDNA_MALLOC_ERROR)
959 if (rc == IDNA_DLOPEN_ERROR)
961 return -EAI_IDN_ENCODE;
963 /* In case the output string is the same as the input
964 string no new string has been allocated and we
976 canon = strdup (canon);
982 family = at2->family;
983 if (family == AF_INET6)
985 socklen = sizeof (struct sockaddr_in6);
987 /* If we looked up IPv4 mapped address discard them here if
988 the caller isn't interested in all address and we have
989 found at least one IPv6 address. */
991 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
992 && IN6_IS_ADDR_V4MAPPED (at2->addr))
996 socklen = sizeof (struct sockaddr_in);
998 for (st2 = st; st2 != NULL; st2 = st2->next)
1000 struct addrinfo *ai;
1001 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1004 free ((char *) canon);
1008 ai->ai_flags = req->ai_flags;
1009 ai->ai_family = family;
1010 ai->ai_socktype = st2->socktype;
1011 ai->ai_protocol = st2->protocol;
1012 ai->ai_addrlen = socklen;
1013 ai->ai_addr = (void *) (ai + 1);
1015 /* We only add the canonical name once. */
1016 ai->ai_canonname = (char *) canon;
1020 ai->ai_addr->sa_len = socklen;
1021 #endif /* _HAVE_SA_LEN */
1022 ai->ai_addr->sa_family = family;
1024 /* In case of an allocation error the list must be NULL
1028 if (family == AF_INET6)
1030 struct sockaddr_in6 *sin6p =
1031 (struct sockaddr_in6 *) ai->ai_addr;
1033 sin6p->sin6_port = st2->port;
1034 sin6p->sin6_flowinfo = 0;
1035 memcpy (&sin6p->sin6_addr,
1036 at2->addr, sizeof (struct in6_addr));
1037 sin6p->sin6_scope_id = at2->scopeid;
1041 struct sockaddr_in *sinp =
1042 (struct sockaddr_in *) ai->ai_addr;
1043 sinp->sin_port = st2->port;
1044 memcpy (&sinp->sin_addr,
1045 at2->addr, sizeof (struct in_addr));
1046 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1049 pai = &(ai->ai_next);
1064 struct addrinfo *dest_addr;
1065 /* Using sockaddr_storage is for now overkill. We only support IPv4
1066 and IPv6 so far. If this changes at some point we can adjust the
1068 struct sockaddr_in6 source_addr;
1069 uint8_t source_addr_len;
1070 bool got_source_addr;
1071 uint8_t source_addr_flags;
1077 struct sort_result_combo
1079 struct sort_result *results;
1084 #if __BYTE_ORDER == __BIG_ENDIAN
1085 # define htonl_c(n) n
1087 # define htonl_c(n) __bswap_constant_32 (n)
1090 static const struct scopeentry
1099 } default_scopes[] =
1101 /* Link-local addresses: scope 2. */
1102 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1103 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1104 /* Site-local addresses: scope 5. */
1105 { { { 10, 0, 0, 0 } }, htonl_c (0xff000000), 5 },
1106 { { { 172, 16, 0, 0 } }, htonl_c (0xfff00000), 5 },
1107 { { { 192, 168, 0, 0 } }, htonl_c (0xffff0000), 5 },
1108 /* Default: scope 14. */
1109 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1112 /* The label table. */
1113 static const struct scopeentry *scopes;
1117 get_scope (const struct sockaddr_in6 *in6)
1120 if (in6->sin6_family == PF_INET6)
1122 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1124 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1125 /* RFC 4291 2.5.3 says that the loopback address is to be
1126 treated like a link-local address. */
1127 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1129 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1132 /* XXX Is this the correct default behavior? */
1136 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1138 else if (in6->sin6_family == PF_INET)
1140 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1145 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1146 == scopes[cnt].addr32)
1147 return scopes[cnt].scope;
1154 /* XXX What is a good default? */
1163 struct in6_addr prefix;
1169 /* The label table. */
1170 static const struct prefixentry *labels;
1172 /* Default labels. */
1173 static const struct prefixentry default_labels[] =
1175 /* See RFC 3484 for the details. */
1177 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1181 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1185 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1189 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1190 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1192 /* The next two entries differ from RFC 3484. We need to treat
1193 IPv6 site-local addresses special because they are never NATed,
1194 unlike site-locale IPv4 addresses. If this would not happen, on
1195 machines which have only IPv4 and IPv6 site-local addresses, the
1196 sorting would prefer the IPv6 site-local addresses, causing
1197 unnecessary delays when trying to connect to a global IPv6 address
1198 through a site-local IPv6 address. */
1200 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1204 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1207 /* Additional rule for Teredo tunnels. */
1209 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1213 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1219 /* The precedence table. */
1220 static const struct prefixentry *precedence;
1222 /* The default precedences. */
1223 static const struct prefixentry default_precedence[] =
1225 /* See RFC 3484 for the details. */
1227 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1228 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1231 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1235 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1239 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1240 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1243 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1250 match_prefix (const struct sockaddr_in6 *in6,
1251 const struct prefixentry *list, int default_val)
1254 struct sockaddr_in6 in6_mem;
1256 if (in6->sin6_family == PF_INET)
1258 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1260 /* Construct a V4-to-6 mapped address. */
1261 in6_mem.sin6_family = PF_INET6;
1262 in6_mem.sin6_port = in->sin_port;
1263 in6_mem.sin6_flowinfo = 0;
1264 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1265 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1266 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1267 in6_mem.sin6_scope_id = 0;
1271 else if (in6->sin6_family != PF_INET6)
1274 for (idx = 0; ; ++idx)
1276 unsigned int bits = list[idx].bits;
1277 const uint8_t *mask = list[idx].prefix.s6_addr;
1278 const uint8_t *val = in6->sin6_addr.s6_addr;
1292 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1298 return list[idx].val;
1303 get_label (const struct sockaddr_in6 *in6)
1305 /* XXX What is a good default value? */
1306 return match_prefix (in6, labels, INT_MAX);
1311 get_precedence (const struct sockaddr_in6 *in6)
1313 /* XXX What is a good default value? */
1314 return match_prefix (in6, precedence, 0);
1318 /* Find last bit set in a word. */
1324 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1325 if ((a & mask) != 0)
1332 rfc3484_sort (const void *p1, const void *p2, void *arg)
1334 const size_t idx1 = *(const size_t *) p1;
1335 const size_t idx2 = *(const size_t *) p2;
1336 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1337 struct sort_result *a1 = &src->results[idx1];
1338 struct sort_result *a2 = &src->results[idx2];
1340 /* Rule 1: Avoid unusable destinations.
1341 We have the got_source_addr flag set if the destination is reachable. */
1342 if (a1->got_source_addr && ! a2->got_source_addr)
1344 if (! a1->got_source_addr && a2->got_source_addr)
1348 /* Rule 2: Prefer matching scope. Only interesting if both
1349 destination addresses are IPv6. */
1351 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1354 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1356 if (a1->got_source_addr)
1358 int a1_src_scope = get_scope (&a1->source_addr);
1359 int a2_src_scope = get_scope (&a2->source_addr);
1361 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1363 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1368 /* Rule 3: Avoid deprecated addresses. */
1369 if (a1->got_source_addr)
1371 if (!(a1->source_addr_flags & in6ai_deprecated)
1372 && (a2->source_addr_flags & in6ai_deprecated))
1374 if ((a1->source_addr_flags & in6ai_deprecated)
1375 && !(a2->source_addr_flags & in6ai_deprecated))
1379 /* Rule 4: Prefer home addresses. */
1380 if (a1->got_source_addr)
1382 if (!(a1->source_addr_flags & in6ai_homeaddress)
1383 && (a2->source_addr_flags & in6ai_homeaddress))
1385 if ((a1->source_addr_flags & in6ai_homeaddress)
1386 && !(a2->source_addr_flags & in6ai_homeaddress))
1390 /* Rule 5: Prefer matching label. */
1391 if (a1->got_source_addr)
1394 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1395 int a1_src_label = get_label (&a1->source_addr);
1398 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1399 int a2_src_label = get_label (&a2->source_addr);
1401 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1403 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1408 /* Rule 6: Prefer higher precedence. */
1410 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1412 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1414 if (a1_prec > a2_prec)
1416 if (a1_prec < a2_prec)
1420 /* Rule 7: Prefer native transport. */
1421 if (a1->got_source_addr)
1423 /* The same interface index means the same interface which means
1424 there is no difference in transport. This should catch many
1426 if (a1->index != a2->index)
1428 int a1_native = a1->native;
1429 int a2_native = a2->native;
1431 if (a1_native == -1 || a2_native == -1)
1434 if (a1_native == -1)
1436 /* If we do not have the information use 'native' as
1439 a1_index = a1->index;
1442 a1_index = 0xffffffffu;
1445 if (a2_native == -1)
1447 /* If we do not have the information use 'native' as
1450 a2_index = a2->index;
1453 a2_index = 0xffffffffu;
1455 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1457 /* Fill in the results in all the records. */
1458 for (int i = 0; i < src->nresults; ++i)
1459 if (src->results[i].index == a1_index)
1461 assert (src->results[i].native == -1
1462 || src->results[i].native == a1_native);
1463 src->results[i].native = a1_native;
1465 else if (src->results[i].index == a2_index)
1467 assert (src->results[i].native == -1
1468 || src->results[i].native == a2_native);
1469 src->results[i].native = a2_native;
1473 if (a1_native && !a2_native)
1475 if (!a1_native && a2_native)
1481 /* Rule 8: Prefer smaller scope. */
1482 if (a1_dst_scope < a2_dst_scope)
1484 if (a1_dst_scope > a2_dst_scope)
1488 /* Rule 9: Use longest matching prefix. */
1489 if (a1->got_source_addr
1490 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1495 if (a1->dest_addr->ai_family == PF_INET)
1497 assert (a1->source_addr.sin6_family == PF_INET);
1498 assert (a2->source_addr.sin6_family == PF_INET);
1500 /* Outside of subnets, as defined by the network masks,
1501 common address prefixes for IPv4 addresses make no sense.
1502 So, define a non-zero value only if source and
1503 destination address are on the same subnet. */
1504 struct sockaddr_in *in1_dst
1505 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1506 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1507 struct sockaddr_in *in1_src
1508 = (struct sockaddr_in *) &a1->source_addr;
1509 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1510 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1512 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1513 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1515 struct sockaddr_in *in2_dst
1516 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1517 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1518 struct sockaddr_in *in2_src
1519 = (struct sockaddr_in *) &a2->source_addr;
1520 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1521 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1523 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1524 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1526 else if (a1->dest_addr->ai_family == PF_INET6)
1528 assert (a1->source_addr.sin6_family == PF_INET6);
1529 assert (a2->source_addr.sin6_family == PF_INET6);
1531 struct sockaddr_in6 *in1_dst;
1532 struct sockaddr_in6 *in1_src;
1533 struct sockaddr_in6 *in2_dst;
1534 struct sockaddr_in6 *in2_src;
1536 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1537 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1538 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1539 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1542 for (i = 0; i < 4; ++i)
1543 if (in1_dst->sin6_addr.s6_addr32[i]
1544 != in1_src->sin6_addr.s6_addr32[i]
1545 || (in2_dst->sin6_addr.s6_addr32[i]
1546 != in2_src->sin6_addr.s6_addr32[i]))
1551 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1552 ^ in1_src->sin6_addr.s6_addr32[i]));
1553 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1554 ^ in2_src->sin6_addr.s6_addr32[i]));
1565 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1566 compare with the value indicating the order in which the entries
1567 have been received from the services. NB: no two entries can have
1568 the same order so the test will never return zero. */
1569 return idx1 < idx2 ? -1 : 1;
1574 in6aicmp (const void *p1, const void *p2)
1576 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1577 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1579 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1583 /* Name of the config file for RFC 3484 sorting (for now). */
1584 #define GAICONF_FNAME "/etc/gai.conf"
1587 /* Non-zero if we are supposed to reload the config file automatically
1588 whenever it changed. */
1589 static int gaiconf_reload_flag;
1591 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1592 static int gaiconf_reload_flag_ever_set;
1594 /* Last modification time. */
1595 static struct timespec gaiconf_mtime;
1598 libc_freeres_fn(fini)
1600 if (labels != default_labels)
1602 const struct prefixentry *old = labels;
1603 labels = default_labels;
1604 free ((void *) old);
1607 if (precedence != default_precedence)
1609 const struct prefixentry *old = precedence;
1610 precedence = default_precedence;
1611 free ((void *) old);
1614 if (scopes != default_scopes)
1616 const struct scopeentry *old = scopes;
1617 scopes = default_scopes;
1618 free ((void *) old);
1625 struct prefixentry entry;
1626 struct prefixlist *next;
1632 struct scopeentry entry;
1633 struct scopelist *next;
1638 free_prefixlist (struct prefixlist *list)
1640 while (list != NULL)
1642 struct prefixlist *oldp = list;
1650 free_scopelist (struct scopelist *list)
1652 while (list != NULL)
1654 struct scopelist *oldp = list;
1662 prefixcmp (const void *p1, const void *p2)
1664 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1665 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1667 if (e1->bits < e2->bits)
1669 if (e1->bits == e2->bits)
1676 scopecmp (const void *p1, const void *p2)
1678 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1679 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1681 if (e1->netmask > e2->netmask)
1683 if (e1->netmask == e2->netmask)
1692 struct prefixlist *labellist = NULL;
1693 size_t nlabellist = 0;
1694 bool labellist_nullbits = false;
1695 struct prefixlist *precedencelist = NULL;
1696 size_t nprecedencelist = 0;
1697 bool precedencelist_nullbits = false;
1698 struct scopelist *scopelist = NULL;
1699 size_t nscopelist = 0;
1700 bool scopelist_nullbits = false;
1702 FILE *fp = fopen (GAICONF_FNAME, "rc");
1706 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1715 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1717 while (!feof_unlocked (fp))
1719 ssize_t n = __getline (&line, &linelen, fp);
1723 /* Handle comments. No escaping possible so this is easy. */
1724 char *cp = strchr (line, '#');
1729 while (isspace (*cp))
1733 while (*cp != '\0' && !isspace (*cp))
1735 size_t cmdlen = cp - cmd;
1739 while (isspace (*cp))
1743 while (*cp != '\0' && !isspace (*cp))
1745 size_t val1len = cp - cmd;
1747 /* We always need at least two values. */
1753 while (isspace (*cp))
1757 while (*cp != '\0' && !isspace (*cp))
1760 /* Ignore the rest of the line. */
1763 struct prefixlist **listp;
1769 if (strcmp (cmd, "label") == 0)
1771 struct in6_addr prefix;
1772 unsigned long int bits;
1773 unsigned long int val;
1778 nullbitsp = &labellist_nullbits;
1783 cp = strchr (val1, '/');
1786 if (inet_pton (AF_INET6, val1, &prefix)
1788 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1792 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1797 struct prefixlist *newp = malloc (sizeof (*newp));
1805 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1806 newp->entry.bits = bits;
1807 newp->entry.val = val;
1808 newp->next = *listp;
1811 *nullbitsp |= bits == 0;
1817 if (strcmp (cmd, "reload") == 0)
1819 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
1820 if (gaiconf_reload_flag)
1821 gaiconf_reload_flag_ever_set = 1;
1826 if (strcmp (cmd, "scopev4") == 0)
1828 struct in6_addr prefix;
1829 unsigned long int bits;
1830 unsigned long int val;
1835 cp = strchr (val1, '/');
1838 if (inet_pton (AF_INET6, val1, &prefix))
1841 if (IN6_IS_ADDR_V4MAPPED (&prefix)
1843 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1848 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1853 struct scopelist *newp;
1855 newp = malloc (sizeof (*newp));
1863 newp->entry.netmask = htonl (bits != 96
1867 newp->entry.addr32 = (prefix.s6_addr32[3]
1868 & newp->entry.netmask);
1869 newp->entry.scope = val;
1870 newp->next = scopelist;
1873 scopelist_nullbits |= bits == 96;
1876 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
1878 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1882 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1894 if (strcmp (cmd, "precedence") == 0)
1896 listp = &precedencelist;
1897 lenp = &nprecedencelist;
1898 nullbitsp = &precedencelist_nullbits;
1909 /* Create the array for the labels. */
1910 struct prefixentry *new_labels;
1913 if (!labellist_nullbits)
1915 new_labels = malloc (nlabellist * sizeof (*new_labels));
1916 if (new_labels == NULL)
1920 if (!labellist_nullbits)
1923 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
1924 new_labels[i].bits = 0;
1925 new_labels[i].val = 1;
1928 struct prefixlist *l = labellist;
1931 new_labels[i] = l->entry;
1934 free_prefixlist (labellist);
1936 /* Sort the entries so that the most specific ones are at
1938 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
1941 new_labels = (struct prefixentry *) default_labels;
1943 struct prefixentry *new_precedence;
1944 if (nprecedencelist > 0)
1946 if (!precedencelist_nullbits)
1948 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
1949 if (new_precedence == NULL)
1951 if (new_labels != default_labels)
1956 int i = nprecedencelist;
1957 if (!precedencelist_nullbits)
1960 memset (&new_precedence[i].prefix, '\0',
1961 sizeof (struct in6_addr));
1962 new_precedence[i].bits = 0;
1963 new_precedence[i].val = 40;
1966 struct prefixlist *l = precedencelist;
1969 new_precedence[i] = l->entry;
1972 free_prefixlist (precedencelist);
1974 /* Sort the entries so that the most specific ones are at
1976 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
1980 new_precedence = (struct prefixentry *) default_precedence;
1982 struct scopeentry *new_scopes;
1985 if (!scopelist_nullbits)
1987 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
1988 if (new_scopes == NULL)
1990 if (new_labels != default_labels)
1992 if (new_precedence != default_precedence)
1993 free (new_precedence);
1998 if (!scopelist_nullbits)
2001 new_scopes[i].addr32 = 0;
2002 new_scopes[i].netmask = 0;
2003 new_scopes[i].scope = 14;
2006 struct scopelist *l = scopelist;
2009 new_scopes[i] = l->entry;
2012 free_scopelist (scopelist);
2014 /* Sort the entries so that the most specific ones are at
2016 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2020 new_scopes = (struct scopeentry *) default_scopes;
2022 /* Now we are ready to replace the values. */
2023 const struct prefixentry *old = labels;
2024 labels = new_labels;
2025 if (old != default_labels)
2026 free ((void *) old);
2029 precedence = new_precedence;
2030 if (old != default_precedence)
2031 free ((void *) old);
2033 const struct scopeentry *oldscope = scopes;
2034 scopes = new_scopes;
2035 if (oldscope != default_scopes)
2036 free ((void *) oldscope);
2038 gaiconf_mtime = st.st_mtim;
2043 free_prefixlist (labellist);
2044 free_prefixlist (precedencelist);
2045 free_scopelist (scopelist);
2047 /* If we previously read the file but it is gone now, free the
2048 old data and use the builtin one. Leave the reload flag
2056 gaiconf_reload (void)
2059 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2060 || memcmp (&st.st_mtim, &gaiconf_mtime, sizeof (gaiconf_mtime)) != 0)
2066 getaddrinfo (const char *name, const char *service,
2067 const struct addrinfo *hints, struct addrinfo **pai)
2069 int i = 0, last_i = 0;
2071 struct addrinfo *p = NULL;
2072 struct gaih_service gaih_service, *pservice;
2073 struct addrinfo local_hints;
2075 if (name != NULL && name[0] == '*' && name[1] == 0)
2078 if (service != NULL && service[0] == '*' && service[1] == 0)
2081 if (name == NULL && service == NULL)
2085 hints = &default_hints;
2088 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2090 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2091 |AI_IDN_USE_STD3_ASCII_RULES
2093 |AI_NUMERICSERV|AI_ALL))
2094 return EAI_BADFLAGS;
2096 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2097 return EAI_BADFLAGS;
2099 struct in6addrinfo *in6ai = NULL;
2100 size_t in6ailen = 0;
2101 bool seen_ipv4 = false;
2102 bool seen_ipv6 = false;
2103 /* We might need information about what interfaces are available.
2104 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2105 cannot cache the results since new interfaces could be added at
2107 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2109 if (hints->ai_flags & AI_ADDRCONFIG)
2111 /* Now make a decision on what we return, if anything. */
2112 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2114 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2115 narrow down the search. */
2116 if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2118 local_hints = *hints;
2119 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2120 hints = &local_hints;
2123 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2124 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2126 /* We cannot possibly return a valid answer. */
2132 if (service && service[0])
2135 gaih_service.name = service;
2136 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2139 if (hints->ai_flags & AI_NUMERICSERV)
2145 gaih_service.num = -1;
2148 pservice = &gaih_service;
2153 struct addrinfo **end = &p;
2155 unsigned int naddrs = 0;
2156 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2157 || hints->ai_family == AF_INET6)
2159 last_i = gaih_inet (name, pservice, hints, end, &naddrs);
2165 return -(last_i & GAIH_EAI);
2169 end = &((*end)->ai_next);
2181 /* Read the config file. */
2182 __libc_once_define (static, once);
2183 __typeof (once) old_once = once;
2184 __libc_once (once, gaiconf_init);
2185 /* Sort results according to RFC 3484. */
2186 struct sort_result results[nresults];
2187 size_t order[nresults];
2189 struct addrinfo *last = NULL;
2190 char *canonname = NULL;
2192 /* If we have information about deprecated and temporary addresses
2193 sort the array now. */
2195 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2200 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2202 results[i].dest_addr = q;
2203 results[i].native = -1;
2206 /* If we just looked up the address for a different
2207 protocol, reuse the result. */
2208 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2209 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2211 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2212 results[i - 1].source_addr_len);
2213 results[i].source_addr_len = results[i - 1].source_addr_len;
2214 results[i].got_source_addr = results[i - 1].got_source_addr;
2215 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2216 results[i].prefixlen = results[i - 1].prefixlen;
2217 results[i].index = results[i - 1].index;
2221 results[i].got_source_addr = false;
2222 results[i].source_addr_flags = 0;
2223 results[i].prefixlen = 0;
2224 results[i].index = 0xffffffffu;
2226 /* We overwrite the type with SOCK_DGRAM since we do not
2227 want connect() to connect to the other side. If we
2228 cannot determine the source address remember this
2230 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2234 close_not_cancel_no_status (fd);
2236 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2240 /* Reset the connection. */
2241 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2242 __connect (fd, &sa, sizeof (sa));
2245 socklen_t sl = sizeof (results[i].source_addr);
2247 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2248 && __getsockname (fd,
2249 (struct sockaddr *) &results[i].source_addr,
2252 results[i].source_addr_len = sl;
2253 results[i].got_source_addr = true;
2257 /* See whether the source address is on the list of
2258 deprecated or temporary addresses. */
2259 struct in6addrinfo tmp;
2261 if (q->ai_family == AF_INET && af == AF_INET)
2263 struct sockaddr_in *sinp
2264 = (struct sockaddr_in *) &results[i].source_addr;
2267 tmp.addr[2] = htonl (0xffff);
2268 tmp.addr[3] = sinp->sin_addr.s_addr;
2272 struct sockaddr_in6 *sin6p
2273 = (struct sockaddr_in6 *) &results[i].source_addr;
2274 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2277 struct in6addrinfo *found
2278 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2282 results[i].source_addr_flags = found->flags;
2283 results[i].prefixlen = found->prefixlen;
2284 results[i].index = found->index;
2288 if (q->ai_family == AF_INET && af == AF_INET6)
2290 /* We have to convert the address. The socket is
2291 IPv6 and the request is for IPv4. */
2292 struct sockaddr_in6 *sin6
2293 = (struct sockaddr_in6 *) &results[i].source_addr;
2294 struct sockaddr_in *sin
2295 = (struct sockaddr_in *) &results[i].source_addr;
2296 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2297 sin->sin_family = AF_INET;
2298 /* We do not have to initialize sin_port since this
2299 fields has the same position and size in the IPv6
2301 assert (offsetof (struct sockaddr_in, sin_port)
2302 == offsetof (struct sockaddr_in6, sin6_port));
2303 assert (sizeof (sin->sin_port)
2304 == sizeof (sin6->sin6_port));
2305 memcpy (&sin->sin_addr,
2306 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2307 results[i].source_addr_len = sizeof (struct sockaddr_in);
2310 else if (errno == EAFNOSUPPORT && af == AF_INET6
2311 && q->ai_family == AF_INET)
2312 /* This could mean IPv6 sockets are IPv6-only. */
2315 /* Just make sure that if we have to process the same
2316 address again we do not copy any memory. */
2317 results[i].source_addr_len = 0;
2320 /* Remember the canonical name. */
2321 if (q->ai_canonname != NULL)
2323 assert (canonname == NULL);
2324 canonname = q->ai_canonname;
2325 q->ai_canonname = NULL;
2330 close_not_cancel_no_status (fd);
2332 /* We got all the source addresses we can get, now sort using
2334 struct sort_result_combo src
2335 = { .results = results, .nresults = nresults };
2336 if (__builtin_expect (gaiconf_reload_flag_ever_set, 0))
2338 __libc_lock_define_initialized (static, lock);
2340 __libc_lock_lock (lock);
2341 if (old_once && gaiconf_reload_flag)
2343 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2344 __libc_lock_unlock (lock);
2347 qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2349 /* Queue the results up as they come out of sorting. */
2350 q = p = results[order[0]].dest_addr;
2351 for (i = 1; i < nresults; ++i)
2352 q = q->ai_next = results[order[i]].dest_addr;
2355 /* Fill in the canonical name into the new first entry. */
2356 p->ai_canonname = canonname;
2367 return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
2369 libc_hidden_def (getaddrinfo)
2371 static_link_warning (getaddrinfo)
2374 freeaddrinfo (struct addrinfo *ai)
2382 free (p->ai_canonname);
2386 libc_hidden_def (freeaddrinfo)