mips: FIx clone3 implementation (BZ 31325)
[glibc.git] / nss / getaddrinfo.c
blob3ccd3905fa0f07c58fe78ba559c9eb89294c0f8f
1 /* Host and service name lookups using Name Service Switch modules.
2 Copyright (C) 1996-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 /* The Inner Net License, Version 2.00
21 The author(s) grant permission for redistribution and use in source and
22 binary forms, with or without modification, of the software and documentation
23 provided that the following conditions are met:
25 0. If you receive a version of the software that is specifically labelled
26 as not being for redistribution (check the version message and/or README),
27 you are not permitted to redistribute that version of the software in any
28 way or form.
29 1. All terms of the all other applicable copyrights and licenses must be
30 followed.
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. */
56 #include <assert.h>
57 #include <ctype.h>
58 #include <errno.h>
59 #include <ifaddrs.h>
60 #include <netdb.h>
61 #include <nss.h>
62 #include <resolv/resolv-internal.h>
63 #include <resolv/resolv_context.h>
64 #include <stdbool.h>
65 #include <stdio.h>
66 #include <stdio_ext.h>
67 #include <stdlib.h>
68 #include <string.h>
69 #include <stdint.h>
70 #include <arpa/inet.h>
71 #include <net/if.h>
72 #include <netinet/in.h>
73 #include <sys/socket.h>
74 #include <sys/stat.h>
75 #include <sys/types.h>
76 #include <sys/un.h>
77 #include <sys/utsname.h>
78 #include <unistd.h>
79 #include <nsswitch.h>
80 #include <libc-lock.h>
81 #include <not-cancel.h>
82 #include <nscd/nscd-client.h>
83 #include <nscd/nscd_proto.h>
84 #include <scratch_buffer.h>
85 #include <inet/net-internal.h>
87 /* Former AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES
88 flags, now ignored. */
89 #define DEPRECATED_AI_IDN 0x300
91 #if IS_IN (libc)
92 # define feof_unlocked(fp) __feof_unlocked (fp)
93 #endif
95 struct gaih_service
97 const char *name;
98 int num;
101 struct gaih_servtuple
103 int socktype;
104 int protocol;
105 int port;
106 bool set;
110 struct gaih_typeproto
112 int socktype;
113 int protocol;
114 uint8_t protoflag;
115 bool defaultflag;
116 char name[8];
119 struct gaih_result
121 struct gaih_addrtuple *at;
122 char *canon;
123 char *h_name;
124 bool free_at;
125 bool got_ipv6;
128 /* Values for `protoflag'. */
129 #define GAI_PROTO_NOSERVICE 1
130 #define GAI_PROTO_PROTOANY 2
132 static const struct gaih_typeproto gaih_inet_typeproto[] =
134 { 0, 0, 0, false, "" },
135 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
136 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
137 #if defined SOCK_DCCP && defined IPPROTO_DCCP
138 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
139 #endif
140 #ifdef IPPROTO_UDPLITE
141 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
142 #endif
143 #ifdef IPPROTO_SCTP
144 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
145 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
146 #endif
147 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
148 { 0, 0, 0, false, "" }
151 static const struct addrinfo default_hints =
153 .ai_flags = AI_DEFAULT,
154 .ai_family = PF_UNSPEC,
155 .ai_socktype = 0,
156 .ai_protocol = 0,
157 .ai_addrlen = 0,
158 .ai_addr = NULL,
159 .ai_canonname = NULL,
160 .ai_next = NULL
163 static void
164 gaih_result_reset (struct gaih_result *res)
166 if (res->free_at)
167 free (res->at);
168 free (res->canon);
169 free (res->h_name);
170 memset (res, 0, sizeof (*res));
173 static int
174 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
175 const struct addrinfo *req, struct gaih_servtuple *st,
176 struct scratch_buffer *tmpbuf)
178 struct servent *s;
179 struct servent ts;
180 int r;
184 r = __getservbyname_r (servicename, tp->name, &ts,
185 tmpbuf->data, tmpbuf->length, &s);
186 if (r != 0 || s == NULL)
188 if (r == ERANGE)
190 if (!scratch_buffer_grow (tmpbuf))
191 return -EAI_MEMORY;
193 else
194 return -EAI_SERVICE;
197 while (r);
199 st->socktype = tp->socktype;
200 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
201 ? req->ai_protocol : tp->protocol);
202 st->port = s->s_port;
203 st->set = true;
205 return 0;
208 /* Convert struct hostent to a list of struct gaih_addrtuple objects. The new
209 addresses are appended to the tuple array in RES. */
210 static bool
211 convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family,
212 struct hostent *h, struct gaih_result *res)
214 /* Count the number of addresses in h->h_addr_list. */
215 size_t count = 0;
216 for (char **p = h->h_addr_list; *p != NULL; ++p)
217 ++count;
219 /* Report no data if no addresses are available, or if the incoming
220 address size is larger than what we can store. */
221 if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
222 return true;
224 struct gaih_addrtuple *array = res->at;
225 size_t old = 0;
227 while (array != NULL)
229 old++;
230 array = array->next;
233 array = realloc (res->at, (old + count) * sizeof (*array));
235 if (array == NULL)
236 return false;
238 res->got_ipv6 = family == AF_INET6;
239 res->at = array;
240 res->free_at = true;
242 /* Duplicate h_name because it may get reclaimed when the underlying storage
243 is freed. */
244 if (res->h_name == NULL)
246 res->h_name = __strdup (h->h_name);
247 if (res->h_name == NULL)
248 return false;
251 /* Update the next pointers on reallocation. */
252 for (size_t i = 0; i < old; i++)
253 array[i].next = array + i + 1;
255 array += old;
257 memset (array, 0, count * sizeof (*array));
259 for (size_t i = 0; i < count; ++i)
261 if (family == AF_INET && req->ai_family == AF_INET6)
263 /* Perform address mapping. */
264 array[i].family = AF_INET6;
265 memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
266 array[i].addr[2] = htonl (0xffff);
268 else
270 array[i].family = family;
271 memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
273 array[i].next = array + i + 1;
275 array[count - 1].next = NULL;
277 return true;
280 static int
281 gethosts (nss_gethostbyname3_r fct, int family, const char *name,
282 const struct addrinfo *req, struct scratch_buffer *tmpbuf,
283 struct gaih_result *res, enum nss_status *statusp, int *no_datap)
285 struct hostent th;
286 char *localcanon = NULL;
287 enum nss_status status;
289 *no_datap = 0;
290 while (1)
292 *statusp = status = DL_CALL_FCT (fct, (name, family, &th,
293 tmpbuf->data, tmpbuf->length,
294 &errno, &h_errno, NULL,
295 &localcanon));
296 if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL
297 || errno != ERANGE)
298 break;
299 if (!scratch_buffer_grow (tmpbuf))
300 return -EAI_MEMORY;
302 if (status == NSS_STATUS_NOTFOUND
303 || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
305 if (h_errno == NETDB_INTERNAL)
306 return -EAI_SYSTEM;
307 if (h_errno == TRY_AGAIN)
308 *no_datap = EAI_AGAIN;
309 else
310 *no_datap = h_errno == NO_DATA;
312 else if (status == NSS_STATUS_SUCCESS)
314 if (!convert_hostent_to_gaih_addrtuple (req, family, &th, res))
315 return -EAI_MEMORY;
317 if (localcanon != NULL && res->canon == NULL)
319 char *canonbuf = __strdup (localcanon);
320 if (canonbuf == NULL)
321 return -EAI_MEMORY;
322 res->canon = canonbuf;
326 return 0;
329 /* This function is called if a canonical name is requested, but if
330 the service function did not provide it. It tries to obtain the
331 name using getcanonname_r from the same service NIP. If the name
332 cannot be canonicalized, return a copy of NAME. Return NULL on
333 memory allocation failure. The returned string is allocated on the
334 heap; the caller has to free it. */
335 static char *
336 getcanonname (nss_action_list nip, const char *hname, const char *name)
338 nss_getcanonname_r *cfct = __nss_lookup_function (nip, "getcanonname_r");
339 char *s = (char *) name;
340 if (cfct != NULL)
342 char buf[256];
343 if (DL_CALL_FCT (cfct, (hname ?: name, buf, sizeof (buf), &s, &errno,
344 &h_errno)) != NSS_STATUS_SUCCESS)
345 /* If the canonical name cannot be determined, use the passed
346 string. */
347 s = (char *) name;
349 return __strdup (s);
352 /* Process looked up canonical name and if necessary, decode to IDNA. Result
353 is a new string written to CANONP and the earlier string is freed. */
355 static int
356 process_canonname (const struct addrinfo *req, const char *orig_name,
357 struct gaih_result *res)
359 char *canon = res->canon;
361 if ((req->ai_flags & AI_CANONNAME) != 0)
363 bool do_idn = req->ai_flags & AI_CANONIDN;
364 if (do_idn)
366 char *out;
367 int rc = __idna_from_dns_encoding (canon ?: orig_name, &out);
368 if (rc == 0)
370 free (canon);
371 canon = out;
373 else if (rc == EAI_IDN_ENCODE)
374 /* Use the punycode name as a fallback. */
375 do_idn = false;
376 else
377 return -rc;
379 if (!do_idn && canon == NULL && (canon = __strdup (orig_name)) == NULL)
380 return -EAI_MEMORY;
383 res->canon = canon;
384 return 0;
387 static int
388 get_servtuples (const struct gaih_service *service, const struct addrinfo *req,
389 struct gaih_servtuple *st, struct scratch_buffer *tmpbuf)
391 int i;
392 const struct gaih_typeproto *tp = gaih_inet_typeproto;
394 if (req->ai_protocol || req->ai_socktype)
396 ++tp;
398 while (tp->name[0]
399 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
400 || (req->ai_protocol != 0
401 && !(tp->protoflag & GAI_PROTO_PROTOANY)
402 && req->ai_protocol != tp->protocol)))
403 ++tp;
405 if (! tp->name[0])
407 if (req->ai_socktype)
408 return -EAI_SOCKTYPE;
409 else
410 return -EAI_SERVICE;
414 if (service != NULL && (tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
415 return -EAI_SERVICE;
417 if (service == NULL || service->num >= 0)
419 int port = service != NULL ? htons (service->num) : 0;
421 if (req->ai_socktype || req->ai_protocol)
423 st[0].socktype = tp->socktype;
424 st[0].protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
425 ? req->ai_protocol : tp->protocol);
426 st[0].port = port;
427 st[0].set = true;
429 return 0;
432 /* Neither socket type nor protocol is set. Return all socket types
433 we know about. */
434 for (i = 0, ++tp; tp->name[0]; ++tp)
435 if (tp->defaultflag)
437 st[i].socktype = tp->socktype;
438 st[i].protocol = tp->protocol;
439 st[i].port = port;
440 st[i++].set = true;
443 return 0;
446 if (tp->name[0])
447 return gaih_inet_serv (service->name, tp, req, st, tmpbuf);
449 for (i = 0, tp++; tp->name[0]; tp++)
451 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
452 continue;
454 if (req->ai_socktype != 0
455 && req->ai_socktype != tp->socktype)
456 continue;
457 if (req->ai_protocol != 0
458 && !(tp->protoflag & GAI_PROTO_PROTOANY)
459 && req->ai_protocol != tp->protocol)
460 continue;
462 if (gaih_inet_serv (service->name,
463 tp, req, &st[i], tmpbuf) != 0)
464 continue;
466 i++;
469 if (!st[0].set)
470 return -EAI_SERVICE;
472 return 0;
475 #ifdef USE_NSCD
476 /* Query addresses from nscd cache, returning a non-zero value on error.
477 RES members have the lookup result; RES->AT is NULL if there were no errors
478 but also no results. */
480 static int
481 get_nscd_addresses (const char *name, const struct addrinfo *req,
482 struct gaih_result *res)
484 if (__nss_not_use_nscd_hosts > 0
485 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
486 __nss_not_use_nscd_hosts = 0;
488 res->at = NULL;
490 if (__nss_not_use_nscd_hosts || __nss_database_custom[NSS_DBSIDX_hosts])
491 return 0;
493 /* Try to use nscd. */
494 struct nscd_ai_result *air = NULL;
495 int err = __nscd_getai (name, &air, &h_errno);
497 if (__glibc_unlikely (air == NULL))
499 /* The database contains a negative entry. */
500 if (err == 0)
501 return -EAI_NONAME;
502 if (__nss_not_use_nscd_hosts == 0)
504 if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
505 return -EAI_MEMORY;
506 if (h_errno == TRY_AGAIN)
507 return -EAI_AGAIN;
508 return -EAI_SYSTEM;
510 return 0;
513 /* Transform into gaih_addrtuple list. */
514 int result = 0;
515 char *addrs = air->addrs;
517 struct gaih_addrtuple *at = calloc (air->naddrs, sizeof (*at));
518 if (at == NULL)
520 result = -EAI_MEMORY;
521 goto out;
524 res->free_at = true;
526 int count = 0;
527 for (int i = 0; i < air->naddrs; ++i)
529 socklen_t size = (air->family[i] == AF_INET
530 ? INADDRSZ : IN6ADDRSZ);
532 if (!((air->family[i] == AF_INET
533 && req->ai_family == AF_INET6
534 && (req->ai_flags & AI_V4MAPPED) != 0)
535 || req->ai_family == AF_UNSPEC
536 || air->family[i] == req->ai_family))
538 /* Skip over non-matching result. */
539 addrs += size;
540 continue;
543 if (air->family[i] == AF_INET && req->ai_family == AF_INET6
544 && (req->ai_flags & AI_V4MAPPED))
546 at[count].family = AF_INET6;
547 at[count].addr[3] = *(uint32_t *) addrs;
548 at[count].addr[2] = htonl (0xffff);
550 else if (req->ai_family == AF_UNSPEC
551 || air->family[i] == req->ai_family)
553 at[count].family = air->family[i];
554 memcpy (at[count].addr, addrs, size);
555 if (air->family[i] == AF_INET6)
556 res->got_ipv6 = true;
558 at[count].next = at + count + 1;
559 count++;
560 addrs += size;
563 if ((req->ai_flags & AI_CANONNAME) && air->canon != NULL)
565 char *canonbuf = __strdup (air->canon);
566 if (canonbuf == NULL)
568 result = -EAI_MEMORY;
569 goto out;
571 res->canon = canonbuf;
574 if (count == 0)
576 result = -EAI_NONAME;
577 goto out;
580 at[count - 1].next = NULL;
582 res->at = at;
584 out:
585 free (air);
586 if (result != 0)
588 free (at);
589 res->free_at = false;
592 return result;
594 #endif
596 static int
597 get_nss_addresses (const char *name, const struct addrinfo *req,
598 struct scratch_buffer *tmpbuf, struct gaih_result *res)
600 int no_data = 0;
601 int no_inet6_data = 0;
602 nss_action_list nip;
603 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
604 enum nss_status status = NSS_STATUS_UNAVAIL;
605 int no_more;
606 struct resolv_context *res_ctx = NULL;
607 bool do_merge = false;
608 int result = 0;
610 no_more = !__nss_database_get (nss_database_hosts, &nip);
612 /* If we are looking for both IPv4 and IPv6 address we don't
613 want the lookup functions to automatically promote IPv4
614 addresses to IPv6 addresses, so we use the no_inet6
615 function variant. */
616 res_ctx = __resolv_context_get ();
617 if (res_ctx == NULL)
619 if (errno == ENOMEM)
621 result = -EAI_MEMORY;
622 goto out;
624 no_more = 1;
627 while (!no_more)
629 /* Always start afresh; continue should discard previous results
630 and the hosts database does not support merge. */
631 gaih_result_reset (res);
633 if (do_merge)
635 __set_h_errno (NETDB_INTERNAL);
636 __set_errno (EBUSY);
637 break;
640 no_data = 0;
641 nss_gethostbyname4_r *fct4 = NULL;
643 /* gethostbyname4_r sends out parallel A and AAAA queries and
644 is thus only suitable for PF_UNSPEC. */
645 if (req->ai_family == PF_UNSPEC)
646 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
648 if (fct4 != NULL)
650 while (1)
652 status = DL_CALL_FCT (fct4, (name, &res->at,
653 tmpbuf->data, tmpbuf->length,
654 &errno, &h_errno,
655 NULL));
656 if (status == NSS_STATUS_SUCCESS)
657 break;
658 /* gethostbyname4_r may write into AT, so reset it. */
659 res->at = NULL;
660 if (status != NSS_STATUS_TRYAGAIN
661 || errno != ERANGE || h_errno != NETDB_INTERNAL)
663 if (h_errno == TRY_AGAIN)
664 no_data = EAI_AGAIN;
665 else
666 no_data = h_errno == NO_DATA;
667 break;
670 if (!scratch_buffer_grow (tmpbuf))
672 __resolv_context_put (res_ctx);
673 result = -EAI_MEMORY;
674 goto out;
678 if (status == NSS_STATUS_SUCCESS)
680 assert (!no_data);
681 no_data = 1;
683 if ((req->ai_flags & AI_CANONNAME) != 0 && res->canon == NULL)
685 char *canonbuf = __strdup (res->at->name);
686 if (canonbuf == NULL)
688 __resolv_context_put (res_ctx);
689 result = -EAI_MEMORY;
690 goto out;
692 res->canon = canonbuf;
695 struct gaih_addrtuple **pat = &res->at;
697 while (*pat != NULL)
699 if ((*pat)->family == AF_INET
700 && req->ai_family == AF_INET6
701 && (req->ai_flags & AI_V4MAPPED) != 0)
703 uint32_t *pataddr = (*pat)->addr;
704 (*pat)->family = AF_INET6;
705 pataddr[3] = pataddr[0];
706 pataddr[2] = htonl (0xffff);
707 pataddr[1] = 0;
708 pataddr[0] = 0;
709 pat = &((*pat)->next);
710 no_data = 0;
712 else if (req->ai_family == AF_UNSPEC
713 || (*pat)->family == req->ai_family)
715 pat = &((*pat)->next);
717 no_data = 0;
718 if (req->ai_family == AF_INET6)
719 res->got_ipv6 = true;
721 else
722 *pat = ((*pat)->next);
726 no_inet6_data = no_data;
728 else
730 nss_gethostbyname3_r *fct = NULL;
731 if (req->ai_flags & AI_CANONNAME)
732 /* No need to use this function if we do not look for
733 the canonical name. The function does not exist in
734 all NSS modules and therefore the lookup would
735 often fail. */
736 fct = __nss_lookup_function (nip, "gethostbyname3_r");
737 if (fct == NULL)
738 /* We are cheating here. The gethostbyname2_r
739 function does not have the same interface as
740 gethostbyname3_r but the extra arguments the
741 latter takes are added at the end. So the
742 gethostbyname2_r code will just ignore them. */
743 fct = __nss_lookup_function (nip, "gethostbyname2_r");
745 if (fct != NULL)
747 if (req->ai_family == AF_INET6
748 || req->ai_family == AF_UNSPEC)
750 if ((result = gethosts (fct, AF_INET6, name, req, tmpbuf,
751 res, &status, &no_data)) != 0)
753 __resolv_context_put (res_ctx);
754 goto out;
756 no_inet6_data = no_data;
757 inet6_status = status;
759 if (req->ai_family == AF_INET
760 || req->ai_family == AF_UNSPEC
761 || (req->ai_family == AF_INET6
762 && (req->ai_flags & AI_V4MAPPED)
763 /* Avoid generating the mapped addresses if we
764 know we are not going to need them. */
765 && ((req->ai_flags & AI_ALL) || !res->got_ipv6)))
767 if ((result = gethosts (fct, AF_INET, name, req, tmpbuf,
768 res, &status, &no_data)) != 0)
770 __resolv_context_put (res_ctx);
771 goto out;
774 if (req->ai_family == AF_INET)
776 no_inet6_data = no_data;
777 inet6_status = status;
781 /* If we found one address for AF_INET or AF_INET6,
782 don't continue the search. */
783 if (inet6_status == NSS_STATUS_SUCCESS
784 || status == NSS_STATUS_SUCCESS)
786 if ((req->ai_flags & AI_CANONNAME) != 0
787 && res->canon == NULL)
789 char *canonbuf = getcanonname (nip, res->h_name, name);
790 if (canonbuf == NULL)
792 __resolv_context_put (res_ctx);
793 result = -EAI_MEMORY;
794 goto out;
796 res->canon = canonbuf;
798 status = NSS_STATUS_SUCCESS;
800 else
802 /* We can have different states for AF_INET and
803 AF_INET6. Try to find a useful one for both. */
804 if (inet6_status == NSS_STATUS_TRYAGAIN)
805 status = NSS_STATUS_TRYAGAIN;
806 else if (status == NSS_STATUS_UNAVAIL
807 && inet6_status != NSS_STATUS_UNAVAIL)
808 status = inet6_status;
811 else
813 /* Could not locate any of the lookup functions.
814 The NSS lookup code does not consistently set
815 errno, so we need to supply our own error
816 code here. The root cause could either be a
817 resource allocation failure, or a missing
818 service function in the DSO (so it should not
819 be listed in /etc/nsswitch.conf). Assume the
820 former, and return EBUSY. */
821 status = NSS_STATUS_UNAVAIL;
822 __set_h_errno (NETDB_INTERNAL);
823 __set_errno (EBUSY);
827 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
828 break;
830 /* The hosts database does not support MERGE. */
831 if (nss_next_action (nip, status) == NSS_ACTION_MERGE)
832 do_merge = true;
834 nip++;
835 if (nip->module == NULL)
836 no_more = -1;
839 __resolv_context_put (res_ctx);
841 /* If we have a failure which sets errno, report it using
842 EAI_SYSTEM. */
843 if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
844 && h_errno == NETDB_INTERNAL)
846 result = -EAI_SYSTEM;
847 goto out;
850 if (no_data != 0 && no_inet6_data != 0)
852 /* If both requests timed out report this. */
853 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
854 result = -EAI_AGAIN;
855 else
856 /* We made requests but they turned out no data. The name
857 is known, though. */
858 result = -EAI_NODATA;
861 out:
862 if (result != 0)
863 gaih_result_reset (res);
864 return result;
867 /* Convert numeric addresses to binary into RES. On failure, RES->AT is set to
868 NULL and an error code is returned. If AI_NUMERIC_HOST is not requested and
869 the function cannot determine a result, RES->AT is set to NULL and 0
870 returned. */
872 static int
873 text_to_binary_address (const char *name, const struct addrinfo *req,
874 struct gaih_result *res)
876 struct gaih_addrtuple *at = res->at;
877 int result = 0;
879 assert (at != NULL);
881 memset (at->addr, 0, sizeof (at->addr));
882 if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
884 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
885 at->family = AF_INET;
886 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
888 at->addr[3] = at->addr[0];
889 at->addr[2] = htonl (0xffff);
890 at->addr[1] = 0;
891 at->addr[0] = 0;
892 at->family = AF_INET6;
894 else
896 result = -EAI_ADDRFAMILY;
897 goto out;
900 if (req->ai_flags & AI_CANONNAME)
902 char *canonbuf = __strdup (name);
903 if (canonbuf == NULL)
905 result = -EAI_MEMORY;
906 goto out;
908 res->canon = canonbuf;
910 return 0;
913 char *scope_delim = strchr (name, SCOPE_DELIMITER);
914 int e;
916 if (scope_delim == NULL)
917 e = inet_pton (AF_INET6, name, at->addr);
918 else
919 e = __inet_pton_length (AF_INET6, name, scope_delim - name, at->addr);
921 if (e > 0)
923 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
924 at->family = AF_INET6;
925 else if (req->ai_family == AF_INET
926 && IN6_IS_ADDR_V4MAPPED (at->addr))
928 at->addr[0] = at->addr[3];
929 at->family = AF_INET;
931 else
933 result = -EAI_ADDRFAMILY;
934 goto out;
937 if (scope_delim != NULL
938 && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
939 scope_delim + 1, &at->scopeid) != 0)
941 result = -EAI_NONAME;
942 goto out;
945 if (req->ai_flags & AI_CANONNAME)
947 char *canonbuf = __strdup (name);
948 if (canonbuf == NULL)
950 result = -EAI_MEMORY;
951 goto out;
953 res->canon = canonbuf;
955 return 0;
958 if ((req->ai_flags & AI_NUMERICHOST))
959 result = -EAI_NONAME;
961 out:
962 res->at = NULL;
963 return result;
966 /* If possible, call the simple, old functions, which do not support IPv6 scope
967 ids, nor retrieving the canonical name. */
969 static int
970 try_simple_gethostbyname (const char *name, const struct addrinfo *req,
971 struct scratch_buffer *tmpbuf,
972 struct gaih_result *res)
974 res->at = NULL;
976 if (req->ai_family != AF_INET || (req->ai_flags & AI_CANONNAME) != 0)
977 return 0;
979 int rc;
980 struct hostent th;
981 struct hostent *h;
983 while (1)
985 rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf->data,
986 tmpbuf->length, &h, &h_errno);
987 if (rc != ERANGE || h_errno != NETDB_INTERNAL)
988 break;
989 if (!scratch_buffer_grow (tmpbuf))
990 return -EAI_MEMORY;
993 if (rc == 0)
995 if (h != NULL)
997 /* We found data, convert it. RES->AT from the conversion will
998 either be an allocated block or NULL, both of which are safe to
999 pass to free (). */
1000 if (!convert_hostent_to_gaih_addrtuple (req, AF_INET, h, res))
1001 return -EAI_MEMORY;
1003 res->free_at = true;
1004 return 0;
1006 if (h_errno == NO_DATA)
1007 return -EAI_NODATA;
1009 return -EAI_NONAME;
1012 if (h_errno == NETDB_INTERNAL)
1013 return -EAI_SYSTEM;
1014 if (h_errno == TRY_AGAIN)
1015 return -EAI_AGAIN;
1017 /* We made requests but they turned out no data.
1018 The name is known, though. */
1019 return -EAI_NODATA;
1022 /* Add local address information into RES. RES->AT is assumed to have enough
1023 space for two tuples and is zeroed out. */
1025 static void
1026 get_local_addresses (const struct addrinfo *req, struct gaih_result *res)
1028 struct gaih_addrtuple *atr = res->at;
1029 if (req->ai_family == AF_UNSPEC)
1030 res->at->next = res->at + 1;
1032 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
1034 res->at->family = AF_INET6;
1035 if ((req->ai_flags & AI_PASSIVE) == 0)
1036 memcpy (res->at->addr, &in6addr_loopback, sizeof (struct in6_addr));
1037 atr = res->at->next;
1040 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
1042 atr->family = AF_INET;
1043 if ((req->ai_flags & AI_PASSIVE) == 0)
1044 atr->addr[0] = htonl (INADDR_LOOPBACK);
1048 /* Generate results in PAI and its count in NADDRS. Return 0 on success or an
1049 error code on failure. */
1051 static int
1052 generate_addrinfo (const struct addrinfo *req, struct gaih_result *res,
1053 const struct gaih_servtuple *st, struct addrinfo **pai,
1054 unsigned int *naddrs)
1056 size_t socklen;
1057 sa_family_t family;
1059 /* Buffer is the size of an unformatted IPv6 address in printable format. */
1060 for (struct gaih_addrtuple *at = res->at; at != NULL; at = at->next)
1062 family = at->family;
1063 if (family == AF_INET6)
1065 socklen = sizeof (struct sockaddr_in6);
1067 /* If we looked up IPv4 mapped address discard them here if
1068 the caller isn't interested in all address and we have
1069 found at least one IPv6 address. */
1070 if (res->got_ipv6
1071 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1072 && IN6_IS_ADDR_V4MAPPED (at->addr))
1073 continue;
1075 else
1076 socklen = sizeof (struct sockaddr_in);
1078 for (int i = 0; st[i].set; i++)
1080 struct addrinfo *ai;
1081 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1082 if (ai == NULL)
1083 return -EAI_MEMORY;
1085 ai->ai_flags = req->ai_flags;
1086 ai->ai_family = family;
1087 ai->ai_socktype = st[i].socktype;
1088 ai->ai_protocol = st[i].protocol;
1089 ai->ai_addrlen = socklen;
1090 ai->ai_addr = (void *) (ai + 1);
1092 /* We only add the canonical name once. */
1093 ai->ai_canonname = res->canon;
1094 res->canon = NULL;
1096 #ifdef _HAVE_SA_LEN
1097 ai->ai_addr->sa_len = socklen;
1098 #endif /* _HAVE_SA_LEN */
1099 ai->ai_addr->sa_family = family;
1101 /* In case of an allocation error the list must be NULL
1102 terminated. */
1103 ai->ai_next = NULL;
1105 if (family == AF_INET6)
1107 struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *) ai->ai_addr;
1108 sin6p->sin6_port = st[i].port;
1109 sin6p->sin6_flowinfo = 0;
1110 memcpy (&sin6p->sin6_addr, at->addr, sizeof (struct in6_addr));
1111 sin6p->sin6_scope_id = at->scopeid;
1113 else
1115 struct sockaddr_in *sinp = (struct sockaddr_in *) ai->ai_addr;
1116 sinp->sin_port = st[i].port;
1117 memcpy (&sinp->sin_addr, at->addr, sizeof (struct in_addr));
1118 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1121 pai = &(ai->ai_next);
1124 ++*naddrs;
1126 return 0;
1129 static int
1130 gaih_inet (const char *name, const struct gaih_service *service,
1131 const struct addrinfo *req, struct addrinfo **pai,
1132 unsigned int *naddrs, struct scratch_buffer *tmpbuf)
1134 struct gaih_servtuple st[sizeof (gaih_inet_typeproto)
1135 / sizeof (struct gaih_typeproto)] = {0};
1137 const char *orig_name = name;
1139 int rc;
1140 if ((rc = get_servtuples (service, req, st, tmpbuf)) != 0)
1141 return rc;
1143 bool malloc_name = false;
1144 struct gaih_addrtuple *addrmem = NULL;
1145 int result = 0;
1147 struct gaih_result res = {0};
1148 struct gaih_addrtuple local_at[2] = {0};
1150 res.at = local_at;
1152 if (__glibc_unlikely (name == NULL))
1154 get_local_addresses (req, &res);
1155 goto process_list;
1158 if (req->ai_flags & AI_IDN)
1160 char *out;
1161 result = __idna_to_dns_encoding (name, &out);
1162 if (result != 0)
1163 return -result;
1164 name = out;
1165 malloc_name = true;
1168 if ((result = text_to_binary_address (name, req, &res)) != 0)
1169 goto free_and_return;
1170 else if (res.at != NULL)
1171 goto process_list;
1173 if ((result = try_simple_gethostbyname (name, req, tmpbuf, &res)) != 0)
1174 goto free_and_return;
1175 else if (res.at != NULL)
1176 goto process_list;
1178 #ifdef USE_NSCD
1179 if ((result = get_nscd_addresses (name, req, &res)) != 0)
1180 goto free_and_return;
1181 else if (res.at != NULL)
1182 goto process_list;
1183 #endif
1185 if ((result = get_nss_addresses (name, req, tmpbuf, &res)) != 0)
1186 goto free_and_return;
1187 else if (res.at != NULL)
1188 goto process_list;
1190 /* None of the lookups worked, so name not found. */
1191 result = -EAI_NONAME;
1192 goto free_and_return;
1194 process_list:
1195 /* Set up the canonical name if we need it. */
1196 if ((result = process_canonname (req, orig_name, &res)) != 0)
1197 goto free_and_return;
1199 result = generate_addrinfo (req, &res, st, pai, naddrs);
1201 free_and_return:
1202 if (malloc_name)
1203 free ((char *) name);
1204 free (addrmem);
1205 gaih_result_reset (&res);
1207 return result;
1211 struct sort_result
1213 struct addrinfo *dest_addr;
1214 /* Using sockaddr_storage is for now overkill. We only support IPv4
1215 and IPv6 so far. If this changes at some point we can adjust the
1216 type here. */
1217 struct sockaddr_in6 source_addr;
1218 uint8_t source_addr_len;
1219 bool got_source_addr;
1220 uint8_t source_addr_flags;
1221 uint8_t prefixlen;
1222 uint32_t index;
1223 int32_t native;
1226 struct sort_result_combo
1228 struct sort_result *results;
1229 int nresults;
1233 #if __BYTE_ORDER == __BIG_ENDIAN
1234 # define htonl_c(n) n
1235 #else
1236 # define htonl_c(n) __bswap_constant_32 (n)
1237 #endif
1239 static const struct scopeentry
1241 union
1243 char addr[4];
1244 uint32_t addr32;
1246 uint32_t netmask;
1247 int32_t scope;
1248 } default_scopes[] =
1250 /* Link-local addresses: scope 2. */
1251 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1252 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1253 /* Default: scope 14. */
1254 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1257 /* The label table. */
1258 static const struct scopeentry *scopes;
1261 static int
1262 get_scope (const struct sockaddr_in6 *in6)
1264 int scope;
1265 if (in6->sin6_family == PF_INET6)
1267 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1269 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1270 /* RFC 4291 2.5.3 says that the loopback address is to be
1271 treated like a link-local address. */
1272 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1273 scope = 2;
1274 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1275 scope = 5;
1276 else
1277 /* XXX Is this the correct default behavior? */
1278 scope = 14;
1280 else
1281 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1283 else if (in6->sin6_family == PF_INET)
1285 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1287 size_t cnt = 0;
1288 while (1)
1290 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1291 == scopes[cnt].addr32)
1292 return scopes[cnt].scope;
1294 ++cnt;
1296 /* NOTREACHED */
1298 else
1299 /* XXX What is a good default? */
1300 scope = 15;
1302 return scope;
1306 struct prefixentry
1308 struct in6_addr prefix;
1309 unsigned int bits;
1310 int val;
1314 /* The label table. */
1315 static const struct prefixentry *labels;
1317 /* Default labels. */
1318 static const struct prefixentry default_labels[] =
1320 /* See RFC 3484 for the details. */
1321 { { .__in6_u
1322 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1324 }, 128, 0 },
1325 { { .__in6_u
1326 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1328 }, 16, 2 },
1329 { { .__in6_u
1330 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1332 }, 96, 3 },
1333 { { .__in6_u
1334 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1335 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1336 }, 96, 4 },
1337 /* The next two entries differ from RFC 3484. We need to treat
1338 IPv6 site-local addresses special because they are never NATed,
1339 unlike site-locale IPv4 addresses. If this would not happen, on
1340 machines which have only IPv4 and IPv6 site-local addresses, the
1341 sorting would prefer the IPv6 site-local addresses, causing
1342 unnecessary delays when trying to connect to a global IPv6 address
1343 through a site-local IPv6 address. */
1344 { { .__in6_u
1345 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1347 }, 10, 5 },
1348 { { .__in6_u
1349 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1351 }, 7, 6 },
1352 /* Additional rule for Teredo tunnels. */
1353 { { .__in6_u
1354 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1356 }, 32, 7 },
1357 { { .__in6_u
1358 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1360 }, 0, 1 }
1364 /* The precedence table. */
1365 static const struct prefixentry *precedence;
1367 /* The default precedences. */
1368 static const struct prefixentry default_precedence[] =
1370 /* See RFC 3484 for the details. */
1371 { { .__in6_u
1372 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1374 }, 128, 50 },
1375 { { .__in6_u
1376 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1378 }, 16, 30 },
1379 { { .__in6_u
1380 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1382 }, 96, 20 },
1383 { { .__in6_u
1384 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1385 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1386 }, 96, 10 },
1387 { { .__in6_u
1388 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1390 }, 0, 40 }
1394 static int
1395 match_prefix (const struct sockaddr_in6 *in6,
1396 const struct prefixentry *list, int default_val)
1398 int idx;
1399 struct sockaddr_in6 in6_mem;
1401 if (in6->sin6_family == PF_INET)
1403 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1405 /* Construct a V4-to-6 mapped address. */
1406 in6_mem.sin6_family = PF_INET6;
1407 in6_mem.sin6_port = in->sin_port;
1408 in6_mem.sin6_flowinfo = 0;
1409 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1410 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1411 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1412 in6_mem.sin6_scope_id = 0;
1414 in6 = &in6_mem;
1416 else if (in6->sin6_family != PF_INET6)
1417 return default_val;
1419 for (idx = 0; ; ++idx)
1421 unsigned int bits = list[idx].bits;
1422 const uint8_t *mask = list[idx].prefix.s6_addr;
1423 const uint8_t *val = in6->sin6_addr.s6_addr;
1425 while (bits >= 8)
1427 if (*mask != *val)
1428 break;
1430 ++mask;
1431 ++val;
1432 bits -= 8;
1435 if (bits < 8)
1437 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1438 /* Match! */
1439 break;
1443 return list[idx].val;
1447 static int
1448 get_label (const struct sockaddr_in6 *in6)
1450 /* XXX What is a good default value? */
1451 return match_prefix (in6, labels, INT_MAX);
1455 static int
1456 get_precedence (const struct sockaddr_in6 *in6)
1458 /* XXX What is a good default value? */
1459 return match_prefix (in6, precedence, 0);
1463 /* Find last bit set in a word. */
1464 static int
1465 fls (uint32_t a)
1467 uint32_t mask;
1468 int n;
1469 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1470 if ((a & mask) != 0)
1471 break;
1472 return n;
1476 static int
1477 rfc3484_sort (const void *p1, const void *p2, void *arg)
1479 const size_t idx1 = *(const size_t *) p1;
1480 const size_t idx2 = *(const size_t *) p2;
1481 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1482 struct sort_result *a1 = &src->results[idx1];
1483 struct sort_result *a2 = &src->results[idx2];
1485 /* Rule 1: Avoid unusable destinations.
1486 We have the got_source_addr flag set if the destination is reachable. */
1487 if (a1->got_source_addr && ! a2->got_source_addr)
1488 return -1;
1489 if (! a1->got_source_addr && a2->got_source_addr)
1490 return 1;
1493 /* Rule 2: Prefer matching scope. Only interesting if both
1494 destination addresses are IPv6. */
1495 int a1_dst_scope
1496 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1498 int a2_dst_scope
1499 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1501 if (a1->got_source_addr)
1503 int a1_src_scope = get_scope (&a1->source_addr);
1504 int a2_src_scope = get_scope (&a2->source_addr);
1506 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1507 return -1;
1508 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1509 return 1;
1513 /* Rule 3: Avoid deprecated addresses. */
1514 if (a1->got_source_addr)
1516 if (!(a1->source_addr_flags & in6ai_deprecated)
1517 && (a2->source_addr_flags & in6ai_deprecated))
1518 return -1;
1519 if ((a1->source_addr_flags & in6ai_deprecated)
1520 && !(a2->source_addr_flags & in6ai_deprecated))
1521 return 1;
1524 /* Rule 4: Prefer home addresses. */
1525 if (a1->got_source_addr)
1527 if (!(a1->source_addr_flags & in6ai_homeaddress)
1528 && (a2->source_addr_flags & in6ai_homeaddress))
1529 return 1;
1530 if ((a1->source_addr_flags & in6ai_homeaddress)
1531 && !(a2->source_addr_flags & in6ai_homeaddress))
1532 return -1;
1535 /* Rule 5: Prefer matching label. */
1536 if (a1->got_source_addr)
1538 int a1_dst_label
1539 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1540 int a1_src_label = get_label (&a1->source_addr);
1542 int a2_dst_label
1543 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1544 int a2_src_label = get_label (&a2->source_addr);
1546 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1547 return -1;
1548 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1549 return 1;
1553 /* Rule 6: Prefer higher precedence. */
1554 int a1_prec
1555 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1556 int a2_prec
1557 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1559 if (a1_prec > a2_prec)
1560 return -1;
1561 if (a1_prec < a2_prec)
1562 return 1;
1565 /* Rule 7: Prefer native transport. */
1566 if (a1->got_source_addr)
1568 /* The same interface index means the same interface which means
1569 there is no difference in transport. This should catch many
1570 (most?) cases. */
1571 if (a1->index != a2->index)
1573 int a1_native = a1->native;
1574 int a2_native = a2->native;
1576 if (a1_native == -1 || a2_native == -1)
1578 uint32_t a1_index;
1579 if (a1_native == -1)
1581 /* If we do not have the information use 'native' as
1582 the default. */
1583 a1_native = 0;
1584 a1_index = a1->index;
1586 else
1587 a1_index = 0xffffffffu;
1589 uint32_t a2_index;
1590 if (a2_native == -1)
1592 /* If we do not have the information use 'native' as
1593 the default. */
1594 a2_native = 0;
1595 a2_index = a2->index;
1597 else
1598 a2_index = 0xffffffffu;
1600 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1602 /* Fill in the results in all the records. */
1603 for (int i = 0; i < src->nresults; ++i)
1604 if (a1_index != -1 && src->results[i].index == a1_index)
1606 assert (src->results[i].native == -1
1607 || src->results[i].native == a1_native);
1608 src->results[i].native = a1_native;
1610 else if (a2_index != -1 && src->results[i].index == a2_index)
1612 assert (src->results[i].native == -1
1613 || src->results[i].native == a2_native);
1614 src->results[i].native = a2_native;
1618 if (a1_native && !a2_native)
1619 return -1;
1620 if (!a1_native && a2_native)
1621 return 1;
1626 /* Rule 8: Prefer smaller scope. */
1627 if (a1_dst_scope < a2_dst_scope)
1628 return -1;
1629 if (a1_dst_scope > a2_dst_scope)
1630 return 1;
1633 /* Rule 9: Use longest matching prefix. */
1634 if (a1->got_source_addr
1635 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1637 int bit1 = 0;
1638 int bit2 = 0;
1640 if (a1->dest_addr->ai_family == PF_INET)
1642 assert (a1->source_addr.sin6_family == PF_INET);
1643 assert (a2->source_addr.sin6_family == PF_INET);
1645 /* Outside of subnets, as defined by the network masks,
1646 common address prefixes for IPv4 addresses make no sense.
1647 So, define a non-zero value only if source and
1648 destination address are on the same subnet. */
1649 struct sockaddr_in *in1_dst
1650 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1651 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1652 struct sockaddr_in *in1_src
1653 = (struct sockaddr_in *) &a1->source_addr;
1654 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1655 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1657 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1658 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1660 struct sockaddr_in *in2_dst
1661 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1662 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1663 struct sockaddr_in *in2_src
1664 = (struct sockaddr_in *) &a2->source_addr;
1665 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1666 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1668 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1669 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1671 else if (a1->dest_addr->ai_family == PF_INET6)
1673 assert (a1->source_addr.sin6_family == PF_INET6);
1674 assert (a2->source_addr.sin6_family == PF_INET6);
1676 struct sockaddr_in6 *in1_dst;
1677 struct sockaddr_in6 *in1_src;
1678 struct sockaddr_in6 *in2_dst;
1679 struct sockaddr_in6 *in2_src;
1681 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1682 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1683 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1684 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1686 int i;
1687 for (i = 0; i < 4; ++i)
1688 if (in1_dst->sin6_addr.s6_addr32[i]
1689 != in1_src->sin6_addr.s6_addr32[i]
1690 || (in2_dst->sin6_addr.s6_addr32[i]
1691 != in2_src->sin6_addr.s6_addr32[i]))
1692 break;
1694 if (i < 4)
1696 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1697 ^ in1_src->sin6_addr.s6_addr32[i]));
1698 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1699 ^ in2_src->sin6_addr.s6_addr32[i]));
1703 if (bit1 > bit2)
1704 return -1;
1705 if (bit1 < bit2)
1706 return 1;
1710 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1711 compare with the value indicating the order in which the entries
1712 have been received from the services. NB: no two entries can have
1713 the same order so the test will never return zero. */
1714 return idx1 < idx2 ? -1 : 1;
1718 static int
1719 in6aicmp (const void *p1, const void *p2)
1721 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1722 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1724 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1728 /* Name of the config file for RFC 3484 sorting (for now). */
1729 #define GAICONF_FNAME "/etc/gai.conf"
1732 /* Non-zero if we are supposed to reload the config file automatically
1733 whenever it changed. */
1734 static int gaiconf_reload_flag;
1736 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1737 static int gaiconf_reload_flag_ever_set;
1739 /* Last modification time. */
1740 #ifdef _STATBUF_ST_NSEC
1742 static struct __timespec64 gaiconf_mtime;
1744 static inline void
1745 save_gaiconf_mtime (const struct __stat64_t64 *st)
1747 gaiconf_mtime = (struct __timespec64) { st->st_mtim.tv_sec,
1748 st->st_mtim.tv_nsec };
1751 static inline bool
1752 check_gaiconf_mtime (const struct __stat64_t64 *st)
1754 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1755 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1758 #else
1760 static time_t gaiconf_mtime;
1762 static inline void
1763 save_gaiconf_mtime (const struct __stat64_t64 *st)
1765 gaiconf_mtime = st->st_mtime;
1768 static inline bool
1769 check_gaiconf_mtime (const struct __stat64_t64 *st)
1771 return st->st_mtime == gaiconf_mtime;
1774 #endif
1777 void
1778 __libc_getaddrinfo_freemem (void)
1780 if (labels != default_labels)
1782 const struct prefixentry *old = labels;
1783 labels = default_labels;
1784 free ((void *) old);
1787 if (precedence != default_precedence)
1789 const struct prefixentry *old = precedence;
1790 precedence = default_precedence;
1791 free ((void *) old);
1794 if (scopes != default_scopes)
1796 const struct scopeentry *old = scopes;
1797 scopes = default_scopes;
1798 free ((void *) old);
1803 struct prefixlist
1805 struct prefixentry entry;
1806 struct prefixlist *next;
1810 struct scopelist
1812 struct scopeentry entry;
1813 struct scopelist *next;
1817 static void
1818 free_prefixlist (struct prefixlist *list)
1820 while (list != NULL)
1822 struct prefixlist *oldp = list;
1823 list = list->next;
1824 free (oldp);
1829 static void
1830 free_scopelist (struct scopelist *list)
1832 while (list != NULL)
1834 struct scopelist *oldp = list;
1835 list = list->next;
1836 free (oldp);
1841 static int
1842 prefixcmp (const void *p1, const void *p2)
1844 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1845 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1847 if (e1->bits < e2->bits)
1848 return 1;
1849 if (e1->bits == e2->bits)
1850 return 0;
1851 return -1;
1855 static int
1856 scopecmp (const void *p1, const void *p2)
1858 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1859 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1861 if (e1->netmask > e2->netmask)
1862 return -1;
1863 if (e1->netmask == e2->netmask)
1864 return 0;
1865 return 1;
1868 static bool
1869 add_prefixlist (struct prefixlist **listp, size_t *lenp, bool *nullbitsp,
1870 char *val1, char *val2, char **pos)
1872 struct in6_addr prefix;
1873 unsigned long int bits;
1874 unsigned long int val;
1875 char *endp;
1877 bits = 128;
1878 __set_errno (0);
1879 char *cp = strchr (val1, '/');
1880 if (cp != NULL)
1881 *cp++ = '\0';
1882 *pos = cp;
1883 if (inet_pton (AF_INET6, val1, &prefix)
1884 && (cp == NULL
1885 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1886 || errno != ERANGE)
1887 && *endp == '\0'
1888 && bits <= 128
1889 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1890 || errno != ERANGE)
1891 && *endp == '\0'
1892 && val <= INT_MAX)
1894 struct prefixlist *newp = malloc (sizeof (*newp));
1895 if (newp == NULL)
1896 return false;
1898 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1899 newp->entry.bits = bits;
1900 newp->entry.val = val;
1901 newp->next = *listp;
1902 *listp = newp;
1903 ++*lenp;
1904 *nullbitsp |= bits == 0;
1906 return true;
1909 static bool
1910 add_scopelist (struct scopelist **listp, size_t *lenp, bool *nullbitsp,
1911 const struct in6_addr *prefixp, unsigned long int bits,
1912 unsigned long int val)
1914 struct scopelist *newp = malloc (sizeof (*newp));
1915 if (newp == NULL)
1916 return false;
1918 newp->entry.netmask = htonl (bits != 96 ? (0xffffffff << (128 - bits)) : 0);
1919 newp->entry.addr32 = (prefixp->s6_addr32[3] & newp->entry.netmask);
1920 newp->entry.scope = val;
1921 newp->next = *listp;
1922 *listp = newp;
1923 ++*lenp;
1924 *nullbitsp |= bits == 96;
1926 return true;
1929 static void
1930 gaiconf_init (void)
1932 struct prefixlist *labellist = NULL;
1933 size_t nlabellist = 0;
1934 bool labellist_nullbits = false;
1935 struct prefixlist *precedencelist = NULL;
1936 size_t nprecedencelist = 0;
1937 bool precedencelist_nullbits = false;
1938 struct scopelist *scopelist = NULL;
1939 size_t nscopelist = 0;
1940 bool scopelist_nullbits = false;
1942 FILE *fp = fopen (GAICONF_FNAME, "rce");
1943 if (fp == NULL)
1944 goto no_file;
1946 struct __stat64_t64 st;
1947 if (__fstat64_time64 (fileno (fp), &st) != 0)
1949 fclose (fp);
1950 goto no_file;
1953 char *line = NULL;
1954 size_t linelen = 0;
1956 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1958 while (!feof_unlocked (fp))
1960 ssize_t n = __getline (&line, &linelen, fp);
1961 if (n <= 0)
1962 break;
1964 /* Handle comments. No escaping possible so this is easy. */
1965 char *cp = strchr (line, '#');
1966 if (cp != NULL)
1967 *cp = '\0';
1969 cp = line;
1970 while (isspace (*cp))
1971 ++cp;
1973 char *cmd = cp;
1974 while (*cp != '\0' && !isspace (*cp))
1975 ++cp;
1976 size_t cmdlen = cp - cmd;
1978 if (*cp != '\0')
1979 *cp++ = '\0';
1980 while (isspace (*cp))
1981 ++cp;
1983 char *val1 = cp;
1984 while (*cp != '\0' && !isspace (*cp))
1985 ++cp;
1986 size_t val1len = cp - cmd;
1988 /* We always need at least two values. */
1989 if (val1len == 0)
1990 continue;
1992 if (*cp != '\0')
1993 *cp++ = '\0';
1994 while (isspace (*cp))
1995 ++cp;
1997 char *val2 = cp;
1998 while (*cp != '\0' && !isspace (*cp))
1999 ++cp;
2001 /* Ignore the rest of the line. */
2002 *cp = '\0';
2004 switch (cmdlen)
2006 case 5:
2007 if (strcmp (cmd, "label") == 0)
2009 if (!add_prefixlist (&labellist, &nlabellist,
2010 &labellist_nullbits, val1, val2, &cp))
2012 free (line);
2013 fclose (fp);
2014 goto no_file;
2017 break;
2019 case 6:
2020 if (strcmp (cmd, "reload") == 0)
2022 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
2023 if (gaiconf_reload_flag)
2024 gaiconf_reload_flag_ever_set = 1;
2026 break;
2028 case 7:
2029 if (strcmp (cmd, "scopev4") == 0)
2031 struct in6_addr prefix;
2032 unsigned long int bits;
2033 unsigned long int val;
2034 char *endp;
2036 bits = 32;
2037 __set_errno (0);
2038 cp = strchr (val1, '/');
2039 if (cp != NULL)
2040 *cp++ = '\0';
2041 if (inet_pton (AF_INET6, val1, &prefix))
2043 bits = 128;
2044 if (IN6_IS_ADDR_V4MAPPED (&prefix)
2045 && (cp == NULL
2046 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2047 || errno != ERANGE)
2048 && *endp == '\0'
2049 && bits >= 96
2050 && bits <= 128
2051 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2052 || errno != ERANGE)
2053 && *endp == '\0'
2054 && val <= INT_MAX)
2056 if (!add_scopelist (&scopelist, &nscopelist,
2057 &scopelist_nullbits, &prefix,
2058 bits, val))
2060 free (line);
2061 fclose (fp);
2062 goto no_file;
2066 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
2067 && (cp == NULL
2068 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2069 || errno != ERANGE)
2070 && *endp == '\0'
2071 && bits <= 32
2072 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2073 || errno != ERANGE)
2074 && *endp == '\0'
2075 && val <= INT_MAX)
2077 if (!add_scopelist (&scopelist, &nscopelist,
2078 &scopelist_nullbits, &prefix,
2079 bits + 96, val))
2081 free (line);
2082 fclose (fp);
2083 goto no_file;
2087 break;
2089 case 10:
2090 if (strcmp (cmd, "precedence") == 0)
2092 if (!add_prefixlist (&precedencelist, &nprecedencelist,
2093 &precedencelist_nullbits, val1, val2,
2094 &cp))
2096 free (line);
2097 fclose (fp);
2098 goto no_file;
2101 break;
2105 free (line);
2107 fclose (fp);
2109 /* Create the array for the labels. */
2110 struct prefixentry *new_labels;
2111 if (nlabellist > 0)
2113 if (!labellist_nullbits)
2114 ++nlabellist;
2115 new_labels = malloc (nlabellist * sizeof (*new_labels));
2116 if (new_labels == NULL)
2117 goto no_file;
2119 int i = nlabellist;
2120 if (!labellist_nullbits)
2122 --i;
2123 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2124 new_labels[i].bits = 0;
2125 new_labels[i].val = 1;
2128 struct prefixlist *l = labellist;
2129 while (i-- > 0)
2131 new_labels[i] = l->entry;
2132 l = l->next;
2134 free_prefixlist (labellist);
2135 labellist = NULL;
2137 /* Sort the entries so that the most specific ones are at
2138 the beginning. */
2139 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2141 else
2142 new_labels = (struct prefixentry *) default_labels;
2144 struct prefixentry *new_precedence;
2145 if (nprecedencelist > 0)
2147 if (!precedencelist_nullbits)
2148 ++nprecedencelist;
2149 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2150 if (new_precedence == NULL)
2152 if (new_labels != default_labels)
2153 free (new_labels);
2154 goto no_file;
2157 int i = nprecedencelist;
2158 if (!precedencelist_nullbits)
2160 --i;
2161 memset (&new_precedence[i].prefix, '\0',
2162 sizeof (struct in6_addr));
2163 new_precedence[i].bits = 0;
2164 new_precedence[i].val = 40;
2167 struct prefixlist *l = precedencelist;
2168 while (i-- > 0)
2170 new_precedence[i] = l->entry;
2171 l = l->next;
2173 free_prefixlist (precedencelist);
2174 precedencelist = NULL;
2176 /* Sort the entries so that the most specific ones are at
2177 the beginning. */
2178 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2179 prefixcmp);
2181 else
2182 new_precedence = (struct prefixentry *) default_precedence;
2184 struct scopeentry *new_scopes;
2185 if (nscopelist > 0)
2187 if (!scopelist_nullbits)
2188 ++nscopelist;
2189 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2190 if (new_scopes == NULL)
2192 if (new_labels != default_labels)
2193 free (new_labels);
2194 if (new_precedence != default_precedence)
2195 free (new_precedence);
2196 goto no_file;
2199 int i = nscopelist;
2200 if (!scopelist_nullbits)
2202 --i;
2203 new_scopes[i].addr32 = 0;
2204 new_scopes[i].netmask = 0;
2205 new_scopes[i].scope = 14;
2208 struct scopelist *l = scopelist;
2209 while (i-- > 0)
2211 new_scopes[i] = l->entry;
2212 l = l->next;
2214 free_scopelist (scopelist);
2216 /* Sort the entries so that the most specific ones are at
2217 the beginning. */
2218 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2219 scopecmp);
2221 else
2222 new_scopes = (struct scopeentry *) default_scopes;
2224 /* Now we are ready to replace the values. */
2225 const struct prefixentry *old = labels;
2226 labels = new_labels;
2227 if (old != default_labels)
2228 free ((void *) old);
2230 old = precedence;
2231 precedence = new_precedence;
2232 if (old != default_precedence)
2233 free ((void *) old);
2235 const struct scopeentry *oldscope = scopes;
2236 scopes = new_scopes;
2237 if (oldscope != default_scopes)
2238 free ((void *) oldscope);
2240 save_gaiconf_mtime (&st);
2241 return;
2243 no_file:
2244 free_prefixlist (labellist);
2245 free_prefixlist (precedencelist);
2246 free_scopelist (scopelist);
2248 /* If we previously read the file but it is gone now, free the old data and
2249 use the builtin one. Leave the reload flag alone. */
2250 __libc_getaddrinfo_freemem ();
2254 static void
2255 gaiconf_reload (void)
2257 struct __stat64_t64 st;
2258 if (__stat64_time64 (GAICONF_FNAME, &st) != 0
2259 || !check_gaiconf_mtime (&st))
2260 gaiconf_init ();
2263 static bool
2264 try_connect (int *fdp, int *afp, struct sockaddr_in6 *source_addrp,
2265 const struct sockaddr *addr, socklen_t addrlen, int family)
2267 int fd = *fdp;
2268 int af = *afp;
2269 socklen_t sl = sizeof (*source_addrp);
2271 while (true)
2273 if (fd != -1 && __connect (fd, addr, addrlen) == 0
2274 && __getsockname (fd, (struct sockaddr *) source_addrp, &sl) == 0)
2275 return true;
2277 if (errno == EAFNOSUPPORT && af == AF_INET6 && family == AF_INET)
2279 /* This could mean IPv6 sockets are IPv6-only. */
2280 if (fd != -1)
2281 __close_nocancel_nostatus (fd);
2282 *afp = af = AF_INET;
2283 *fdp = fd = __socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC,
2284 IPPROTO_IP);
2285 continue;
2288 return false;
2291 __builtin_unreachable ();
2295 getaddrinfo (const char *name, const char *service,
2296 const struct addrinfo *hints, struct addrinfo **pai)
2298 int i = 0, last_i = 0;
2299 int nresults = 0;
2300 struct addrinfo *p = NULL;
2301 struct gaih_service gaih_service, *pservice;
2302 struct addrinfo local_hints;
2304 if (name != NULL && name[0] == '*' && name[1] == 0)
2305 name = NULL;
2307 if (service != NULL && service[0] == '*' && service[1] == 0)
2308 service = NULL;
2310 if (name == NULL && service == NULL)
2311 return EAI_NONAME;
2313 if (hints == NULL)
2314 hints = &default_hints;
2316 if (hints->ai_flags
2317 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2318 |AI_IDN|AI_CANONIDN|DEPRECATED_AI_IDN
2319 |AI_NUMERICSERV|AI_ALL))
2320 return EAI_BADFLAGS;
2322 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2323 return EAI_BADFLAGS;
2325 if (hints->ai_family != AF_UNSPEC && hints->ai_family != AF_INET
2326 && hints->ai_family != AF_INET6)
2327 return EAI_FAMILY;
2329 struct in6addrinfo *in6ai = NULL;
2330 size_t in6ailen = 0;
2331 bool seen_ipv4 = false;
2332 bool seen_ipv6 = false;
2333 bool check_pf_called = false;
2335 if (hints->ai_flags & AI_ADDRCONFIG)
2337 /* We might need information about what interfaces are available.
2338 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2339 cannot cache the results since new interfaces could be added at
2340 any time. */
2341 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2342 check_pf_called = true;
2344 /* Now make a decision on what we return, if anything. */
2345 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2347 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2348 narrow down the search. */
2349 if (seen_ipv4 != seen_ipv6)
2351 local_hints = *hints;
2352 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2353 hints = &local_hints;
2356 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2357 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2359 /* We cannot possibly return a valid answer. */
2360 __free_in6ai (in6ai);
2361 return EAI_NONAME;
2365 if (service && service[0])
2367 char *c;
2368 gaih_service.name = service;
2369 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2370 if (*c != '\0')
2372 if (hints->ai_flags & AI_NUMERICSERV)
2374 __free_in6ai (in6ai);
2375 return EAI_NONAME;
2378 gaih_service.num = -1;
2381 pservice = &gaih_service;
2383 else
2384 pservice = NULL;
2386 struct addrinfo **end = &p;
2387 unsigned int naddrs = 0;
2388 struct scratch_buffer tmpbuf;
2390 scratch_buffer_init (&tmpbuf);
2391 last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf);
2392 scratch_buffer_free (&tmpbuf);
2394 if (last_i != 0)
2396 freeaddrinfo (p);
2397 __free_in6ai (in6ai);
2399 return -last_i;
2402 while (*end)
2404 end = &((*end)->ai_next);
2405 ++nresults;
2408 if (naddrs > 1)
2410 /* Read the config file. */
2411 __libc_once_define (static, once);
2412 __typeof (once) old_once = once;
2413 __libc_once (once, gaiconf_init);
2414 /* Sort results according to RFC 3484. */
2415 struct sort_result *results;
2416 size_t *order;
2417 struct addrinfo *q;
2418 struct addrinfo *last = NULL;
2419 char *canonname = NULL;
2420 struct scratch_buffer buf;
2421 scratch_buffer_init (&buf);
2423 if (!scratch_buffer_set_array_size (&buf, nresults,
2424 sizeof (*results) + sizeof (size_t)))
2426 __free_in6ai (in6ai);
2427 return EAI_MEMORY;
2429 results = buf.data;
2431 order = (size_t *) (results + nresults);
2433 /* Now we definitely need the interface information. */
2434 if (! check_pf_called)
2435 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2437 /* If we have information about deprecated and temporary addresses
2438 sort the array now. */
2439 if (in6ai != NULL)
2440 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2442 int fd = -1;
2443 int af = AF_UNSPEC;
2445 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2447 results[i].dest_addr = q;
2448 results[i].native = -1;
2449 order[i] = i;
2451 /* If we just looked up the address for a different
2452 protocol, reuse the result. */
2453 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2454 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2456 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2457 results[i - 1].source_addr_len);
2458 results[i].source_addr_len = results[i - 1].source_addr_len;
2459 results[i].got_source_addr = results[i - 1].got_source_addr;
2460 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2461 results[i].prefixlen = results[i - 1].prefixlen;
2462 results[i].index = results[i - 1].index;
2464 else
2466 results[i].got_source_addr = false;
2467 results[i].source_addr_flags = 0;
2468 results[i].prefixlen = 0;
2469 results[i].index = 0xffffffffu;
2471 /* We overwrite the type with SOCK_DGRAM since we do not
2472 want connect() to connect to the other side. If we
2473 cannot determine the source address remember this
2474 fact. */
2475 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2477 if (fd != -1)
2478 __close_nocancel_nostatus (fd);
2479 af = q->ai_family;
2480 fd = __socket (af, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP);
2482 else
2484 /* Reset the connection. */
2485 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2486 __connect (fd, &sa, sizeof (sa));
2489 if (try_connect (&fd, &af, &results[i].source_addr, q->ai_addr,
2490 q->ai_addrlen, q->ai_family))
2492 results[i].source_addr_len = sizeof (results[i].source_addr);
2493 results[i].got_source_addr = true;
2495 if (in6ai != NULL)
2497 /* See whether the source address is on the list of
2498 deprecated or temporary addresses. */
2499 struct in6addrinfo tmp;
2501 if (q->ai_family == AF_INET && af == AF_INET)
2503 struct sockaddr_in *sinp
2504 = (struct sockaddr_in *) &results[i].source_addr;
2505 tmp.addr[0] = 0;
2506 tmp.addr[1] = 0;
2507 tmp.addr[2] = htonl (0xffff);
2508 /* Special case for lo interface, the source address
2509 being possibly different than the interface
2510 address. */
2511 if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2512 == 0x7f000000)
2513 tmp.addr[3] = htonl(0x7f000001);
2514 else
2515 tmp.addr[3] = sinp->sin_addr.s_addr;
2517 else
2519 struct sockaddr_in6 *sin6p
2520 = (struct sockaddr_in6 *) &results[i].source_addr;
2521 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2524 struct in6addrinfo *found
2525 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2526 in6aicmp);
2527 if (found != NULL)
2529 results[i].source_addr_flags = found->flags;
2530 results[i].prefixlen = found->prefixlen;
2531 results[i].index = found->index;
2535 if (q->ai_family == AF_INET && af == AF_INET6)
2537 /* We have to convert the address. The socket is
2538 IPv6 and the request is for IPv4. */
2539 struct sockaddr_in6 *sin6
2540 = (struct sockaddr_in6 *) &results[i].source_addr;
2541 struct sockaddr_in *sin
2542 = (struct sockaddr_in *) &results[i].source_addr;
2543 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2544 sin->sin_family = AF_INET;
2545 /* We do not have to initialize sin_port since this
2546 fields has the same position and size in the IPv6
2547 structure. */
2548 assert (offsetof (struct sockaddr_in, sin_port)
2549 == offsetof (struct sockaddr_in6, sin6_port));
2550 assert (sizeof (sin->sin_port)
2551 == sizeof (sin6->sin6_port));
2552 memcpy (&sin->sin_addr,
2553 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2554 results[i].source_addr_len = sizeof (struct sockaddr_in);
2557 else
2558 /* Just make sure that if we have to process the same
2559 address again we do not copy any memory. */
2560 results[i].source_addr_len = 0;
2563 /* Remember the canonical name. */
2564 if (q->ai_canonname != NULL)
2566 assert (canonname == NULL);
2567 canonname = q->ai_canonname;
2568 q->ai_canonname = NULL;
2572 if (fd != -1)
2573 __close_nocancel_nostatus (fd);
2575 /* We got all the source addresses we can get, now sort using
2576 the information. */
2577 struct sort_result_combo src
2578 = { .results = results, .nresults = nresults };
2579 if (__glibc_unlikely (gaiconf_reload_flag_ever_set))
2581 __libc_lock_define_initialized (static, lock);
2583 __libc_lock_lock (lock);
2584 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2585 gaiconf_reload ();
2586 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2587 __libc_lock_unlock (lock);
2589 else
2590 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2592 /* Queue the results up as they come out of sorting. */
2593 q = p = results[order[0]].dest_addr;
2594 for (i = 1; i < nresults; ++i)
2595 q = q->ai_next = results[order[i]].dest_addr;
2596 q->ai_next = NULL;
2598 /* Fill in the canonical name into the new first entry. */
2599 p->ai_canonname = canonname;
2601 scratch_buffer_free (&buf);
2604 __free_in6ai (in6ai);
2606 if (p)
2608 *pai = p;
2609 return 0;
2612 return last_i ? -last_i : EAI_NONAME;
2614 libc_hidden_def (getaddrinfo)
2616 nss_interface_function (getaddrinfo)
2618 void
2619 freeaddrinfo (struct addrinfo *ai)
2621 struct addrinfo *p;
2623 while (ai != NULL)
2625 p = ai;
2626 ai = ai->ai_next;
2627 free (p->ai_canonname);
2628 free (p);
2631 libc_hidden_def (freeaddrinfo)