libio: Remove unused pragma weak on vtable
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob0356b622be6dda5e6ac9bf70c9813cc1351a0b81
1 /* Host and service name lookups using Name Service Switch modules.
2 Copyright (C) 1996-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 /* The Inner Net License, Version 2.00
21 The author(s) grant permission for redistribution and use in source and
22 binary forms, with or without modification, of the software and documentation
23 provided that the following conditions are met:
25 0. If you receive a version of the software that is specifically labelled
26 as not being for redistribution (check the version message and/or README),
27 you are not permitted to redistribute that version of the software in any
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 bool free_at;
124 bool got_ipv6;
127 /* Values for `protoflag'. */
128 #define GAI_PROTO_NOSERVICE 1
129 #define GAI_PROTO_PROTOANY 2
131 static const struct gaih_typeproto gaih_inet_typeproto[] =
133 { 0, 0, 0, false, "" },
134 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
135 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
136 #if defined SOCK_DCCP && defined IPPROTO_DCCP
137 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
138 #endif
139 #ifdef IPPROTO_UDPLITE
140 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
141 #endif
142 #ifdef IPPROTO_SCTP
143 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
144 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
145 #endif
146 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
147 { 0, 0, 0, false, "" }
150 static const struct addrinfo default_hints =
152 .ai_flags = AI_DEFAULT,
153 .ai_family = PF_UNSPEC,
154 .ai_socktype = 0,
155 .ai_protocol = 0,
156 .ai_addrlen = 0,
157 .ai_addr = NULL,
158 .ai_canonname = NULL,
159 .ai_next = NULL
162 static void
163 gaih_result_reset (struct gaih_result *res)
165 if (res->free_at)
166 free (res->at);
167 free (res->canon);
168 memset (res, 0, sizeof (*res));
171 static int
172 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
173 const struct addrinfo *req, struct gaih_servtuple *st,
174 struct scratch_buffer *tmpbuf)
176 struct servent *s;
177 struct servent ts;
178 int r;
182 r = __getservbyname_r (servicename, tp->name, &ts,
183 tmpbuf->data, tmpbuf->length, &s);
184 if (r != 0 || s == NULL)
186 if (r == ERANGE)
188 if (!scratch_buffer_grow (tmpbuf))
189 return -EAI_MEMORY;
191 else
192 return -EAI_SERVICE;
195 while (r);
197 st->socktype = tp->socktype;
198 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
199 ? req->ai_protocol : tp->protocol);
200 st->port = s->s_port;
201 st->set = true;
203 return 0;
206 /* Convert struct hostent to a list of struct gaih_addrtuple objects. h_name
207 is not copied, and the struct hostent object must not be deallocated
208 prematurely. The new addresses are appended to the tuple array in RES. */
209 static bool
210 convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family,
211 struct hostent *h, struct gaih_result *res)
213 /* Count the number of addresses in h->h_addr_list. */
214 size_t count = 0;
215 for (char **p = h->h_addr_list; *p != NULL; ++p)
216 ++count;
218 /* Report no data if no addresses are available, or if the incoming
219 address size is larger than what we can store. */
220 if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
221 return true;
223 struct gaih_addrtuple *array = res->at;
224 size_t old = 0;
226 while (array != NULL)
228 old++;
229 array = array->next;
232 array = realloc (res->at, (old + count) * sizeof (*array));
234 if (array == NULL)
235 return false;
237 res->got_ipv6 = family == AF_INET6;
238 res->at = array;
239 res->free_at = true;
241 /* Update the next pointers on reallocation. */
242 for (size_t i = 0; i < old; i++)
243 array[i].next = array + i + 1;
245 array += old;
247 memset (array, 0, count * sizeof (*array));
249 for (size_t i = 0; i < count; ++i)
251 if (family == AF_INET && req->ai_family == AF_INET6)
253 /* Perform address mapping. */
254 array[i].family = AF_INET6;
255 memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
256 array[i].addr[2] = htonl (0xffff);
258 else
260 array[i].family = family;
261 memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
263 array[i].next = array + i + 1;
265 array[0].name = h->h_name;
266 array[count - 1].next = NULL;
268 return true;
271 static int
272 gethosts (nss_gethostbyname3_r fct, int family, const char *name,
273 const struct addrinfo *req, struct scratch_buffer *tmpbuf,
274 struct gaih_result *res, enum nss_status *statusp, int *no_datap)
276 struct hostent th;
277 char *localcanon = NULL;
278 enum nss_status status;
280 *no_datap = 0;
281 while (1)
283 *statusp = status = DL_CALL_FCT (fct, (name, family, &th,
284 tmpbuf->data, tmpbuf->length,
285 &errno, &h_errno, NULL,
286 &localcanon));
287 if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL
288 || errno != ERANGE)
289 break;
290 if (!scratch_buffer_grow (tmpbuf))
291 return -EAI_MEMORY;
293 if (status == NSS_STATUS_NOTFOUND
294 || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
296 if (h_errno == NETDB_INTERNAL)
297 return -EAI_SYSTEM;
298 if (h_errno == TRY_AGAIN)
299 *no_datap = EAI_AGAIN;
300 else
301 *no_datap = h_errno == NO_DATA;
303 else if (status == NSS_STATUS_SUCCESS)
305 if (!convert_hostent_to_gaih_addrtuple (req, family, &th, res))
306 return -EAI_MEMORY;
308 if (localcanon != NULL && res->canon == NULL)
310 char *canonbuf = __strdup (localcanon);
311 if (canonbuf == NULL)
312 return -EAI_MEMORY;
313 res->canon = canonbuf;
317 return 0;
320 /* This function is called if a canonical name is requested, but if
321 the service function did not provide it. It tries to obtain the
322 name using getcanonname_r from the same service NIP. If the name
323 cannot be canonicalized, return a copy of NAME. Return NULL on
324 memory allocation failure. The returned string is allocated on the
325 heap; the caller has to free it. */
326 static char *
327 getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name)
329 nss_getcanonname_r *cfct = __nss_lookup_function (nip, "getcanonname_r");
330 char *s = (char *) name;
331 if (cfct != NULL)
333 char buf[256];
334 if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf),
335 &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS)
336 /* If the canonical name cannot be determined, use the passed
337 string. */
338 s = (char *) name;
340 return __strdup (name);
343 /* Process looked up canonical name and if necessary, decode to IDNA. Result
344 is a new string written to CANONP and the earlier string is freed. */
346 static int
347 process_canonname (const struct addrinfo *req, const char *orig_name,
348 struct gaih_result *res)
350 char *canon = res->canon;
352 if ((req->ai_flags & AI_CANONNAME) != 0)
354 bool do_idn = req->ai_flags & AI_CANONIDN;
355 if (do_idn)
357 char *out;
358 int rc = __idna_from_dns_encoding (canon ?: orig_name, &out);
359 if (rc == 0)
361 free (canon);
362 canon = out;
364 else if (rc == EAI_IDN_ENCODE)
365 /* Use the punycode name as a fallback. */
366 do_idn = false;
367 else
368 return -rc;
370 if (!do_idn && canon == NULL && (canon = __strdup (orig_name)) == NULL)
371 return -EAI_MEMORY;
374 res->canon = canon;
375 return 0;
378 static int
379 get_servtuples (const struct gaih_service *service, const struct addrinfo *req,
380 struct gaih_servtuple *st, struct scratch_buffer *tmpbuf)
382 int i;
383 const struct gaih_typeproto *tp = gaih_inet_typeproto;
385 if (req->ai_protocol || req->ai_socktype)
387 ++tp;
389 while (tp->name[0]
390 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
391 || (req->ai_protocol != 0
392 && !(tp->protoflag & GAI_PROTO_PROTOANY)
393 && req->ai_protocol != tp->protocol)))
394 ++tp;
396 if (! tp->name[0])
398 if (req->ai_socktype)
399 return -EAI_SOCKTYPE;
400 else
401 return -EAI_SERVICE;
405 if (service != NULL && (tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
406 return -EAI_SERVICE;
408 if (service == NULL || service->num >= 0)
410 int port = service != NULL ? htons (service->num) : 0;
412 if (req->ai_socktype || req->ai_protocol)
414 st[0].socktype = tp->socktype;
415 st[0].protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
416 ? req->ai_protocol : tp->protocol);
417 st[0].port = port;
418 st[0].set = true;
420 return 0;
423 /* Neither socket type nor protocol is set. Return all socket types
424 we know about. */
425 for (i = 0, ++tp; tp->name[0]; ++tp)
426 if (tp->defaultflag)
428 st[i].socktype = tp->socktype;
429 st[i].protocol = tp->protocol;
430 st[i].port = port;
431 st[i++].set = true;
434 return 0;
437 if (tp->name[0])
438 return gaih_inet_serv (service->name, tp, req, st, tmpbuf);
440 for (i = 0, tp++; tp->name[0]; tp++)
442 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
443 continue;
445 if (req->ai_socktype != 0
446 && req->ai_socktype != tp->socktype)
447 continue;
448 if (req->ai_protocol != 0
449 && !(tp->protoflag & GAI_PROTO_PROTOANY)
450 && req->ai_protocol != tp->protocol)
451 continue;
453 if (gaih_inet_serv (service->name,
454 tp, req, &st[i], tmpbuf) != 0)
455 continue;
457 i++;
460 if (!st[0].set)
461 return -EAI_SERVICE;
463 return 0;
466 #ifdef USE_NSCD
467 /* Query addresses from nscd cache, returning a non-zero value on error.
468 RES members have the lookup result; RES->AT is NULL if there were no errors
469 but also no results. */
471 static int
472 get_nscd_addresses (const char *name, const struct addrinfo *req,
473 struct gaih_result *res)
475 if (__nss_not_use_nscd_hosts > 0
476 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
477 __nss_not_use_nscd_hosts = 0;
479 res->at = NULL;
481 if (__nss_not_use_nscd_hosts || __nss_database_custom[NSS_DBSIDX_hosts])
482 return 0;
484 /* Try to use nscd. */
485 struct nscd_ai_result *air = NULL;
486 int err = __nscd_getai (name, &air, &h_errno);
488 if (__glibc_unlikely (air == NULL))
490 /* The database contains a negative entry. */
491 if (err == 0)
492 return -EAI_NONAME;
493 if (__nss_not_use_nscd_hosts == 0)
495 if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
496 return -EAI_MEMORY;
497 if (h_errno == TRY_AGAIN)
498 return -EAI_AGAIN;
499 return -EAI_SYSTEM;
501 return 0;
504 /* Transform into gaih_addrtuple list. */
505 int result = 0;
506 char *addrs = air->addrs;
508 struct gaih_addrtuple *addrfree = calloc (air->naddrs, sizeof (*addrfree));
509 struct gaih_addrtuple *at = calloc (air->naddrs, sizeof (*at));
510 if (at == NULL)
512 result = -EAI_MEMORY;
513 goto out;
516 res->free_at = true;
518 int count = 0;
519 for (int i = 0; i < air->naddrs; ++i)
521 socklen_t size = (air->family[i] == AF_INET
522 ? INADDRSZ : IN6ADDRSZ);
524 if (!((air->family[i] == AF_INET
525 && req->ai_family == AF_INET6
526 && (req->ai_flags & AI_V4MAPPED) != 0)
527 || req->ai_family == AF_UNSPEC
528 || air->family[i] == req->ai_family))
530 /* Skip over non-matching result. */
531 addrs += size;
532 continue;
535 if (air->family[i] == AF_INET && req->ai_family == AF_INET6
536 && (req->ai_flags & AI_V4MAPPED))
538 at[count].family = AF_INET6;
539 at[count].addr[3] = *(uint32_t *) addrs;
540 at[count].addr[2] = htonl (0xffff);
542 else if (req->ai_family == AF_UNSPEC
543 || air->family[i] == req->ai_family)
545 at[count].family = air->family[i];
546 memcpy (at[count].addr, addrs, size);
547 if (air->family[i] == AF_INET6)
548 res->got_ipv6 = true;
550 at[count].next = at + count + 1;
551 count++;
552 addrs += size;
555 if ((req->ai_flags & AI_CANONNAME) && air->canon != NULL)
557 char *canonbuf = __strdup (air->canon);
558 if (canonbuf == NULL)
560 result = -EAI_MEMORY;
561 goto out;
563 res->canon = canonbuf;
566 if (count == 0)
568 result = -EAI_NONAME;
569 goto out;
572 at[count - 1].next = NULL;
574 res->at = at;
576 out:
577 free (air);
578 if (result != 0)
580 free (at);
581 res->free_at = false;
584 return result;
586 #endif
588 static int
589 get_nss_addresses (const char *name, const struct addrinfo *req,
590 struct scratch_buffer *tmpbuf, struct gaih_result *res)
592 int no_data = 0;
593 int no_inet6_data = 0;
594 nss_action_list nip;
595 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
596 enum nss_status status = NSS_STATUS_UNAVAIL;
597 int no_more;
598 struct resolv_context *res_ctx = NULL;
599 bool do_merge = false;
600 int result = 0;
602 no_more = !__nss_database_get (nss_database_hosts, &nip);
604 /* If we are looking for both IPv4 and IPv6 address we don't
605 want the lookup functions to automatically promote IPv4
606 addresses to IPv6 addresses, so we use the no_inet6
607 function variant. */
608 res_ctx = __resolv_context_get ();
609 if (res_ctx == NULL)
610 no_more = 1;
612 while (!no_more)
614 /* Always start afresh; continue should discard previous results
615 and the hosts database does not support merge. */
616 gaih_result_reset (res);
618 if (do_merge)
620 __set_h_errno (NETDB_INTERNAL);
621 __set_errno (EBUSY);
622 break;
625 no_data = 0;
626 nss_gethostbyname4_r *fct4 = NULL;
628 /* gethostbyname4_r sends out parallel A and AAAA queries and
629 is thus only suitable for PF_UNSPEC. */
630 if (req->ai_family == PF_UNSPEC)
631 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
633 if (fct4 != NULL)
635 while (1)
637 status = DL_CALL_FCT (fct4, (name, &res->at,
638 tmpbuf->data, tmpbuf->length,
639 &errno, &h_errno,
640 NULL));
641 if (status == NSS_STATUS_SUCCESS)
642 break;
643 /* gethostbyname4_r may write into AT, so reset it. */
644 res->at = NULL;
645 if (status != NSS_STATUS_TRYAGAIN
646 || errno != ERANGE || h_errno != NETDB_INTERNAL)
648 if (h_errno == TRY_AGAIN)
649 no_data = EAI_AGAIN;
650 else
651 no_data = h_errno == NO_DATA;
652 break;
655 if (!scratch_buffer_grow (tmpbuf))
657 __resolv_context_put (res_ctx);
658 result = -EAI_MEMORY;
659 goto out;
663 if (status == NSS_STATUS_SUCCESS)
665 assert (!no_data);
666 no_data = 1;
668 if ((req->ai_flags & AI_CANONNAME) != 0 && res->canon == NULL)
670 char *canonbuf = __strdup (res->at->name);
671 if (canonbuf == NULL)
673 __resolv_context_put (res_ctx);
674 result = -EAI_MEMORY;
675 goto out;
677 res->canon = canonbuf;
680 struct gaih_addrtuple **pat = &res->at;
682 while (*pat != NULL)
684 if ((*pat)->family == AF_INET
685 && req->ai_family == AF_INET6
686 && (req->ai_flags & AI_V4MAPPED) != 0)
688 uint32_t *pataddr = (*pat)->addr;
689 (*pat)->family = AF_INET6;
690 pataddr[3] = pataddr[0];
691 pataddr[2] = htonl (0xffff);
692 pataddr[1] = 0;
693 pataddr[0] = 0;
694 pat = &((*pat)->next);
695 no_data = 0;
697 else if (req->ai_family == AF_UNSPEC
698 || (*pat)->family == req->ai_family)
700 pat = &((*pat)->next);
702 no_data = 0;
703 if (req->ai_family == AF_INET6)
704 res->got_ipv6 = true;
706 else
707 *pat = ((*pat)->next);
711 no_inet6_data = no_data;
713 else
715 nss_gethostbyname3_r *fct = NULL;
716 if (req->ai_flags & AI_CANONNAME)
717 /* No need to use this function if we do not look for
718 the canonical name. The function does not exist in
719 all NSS modules and therefore the lookup would
720 often fail. */
721 fct = __nss_lookup_function (nip, "gethostbyname3_r");
722 if (fct == NULL)
723 /* We are cheating here. The gethostbyname2_r
724 function does not have the same interface as
725 gethostbyname3_r but the extra arguments the
726 latter takes are added at the end. So the
727 gethostbyname2_r code will just ignore them. */
728 fct = __nss_lookup_function (nip, "gethostbyname2_r");
730 if (fct != NULL)
732 if (req->ai_family == AF_INET6
733 || req->ai_family == AF_UNSPEC)
735 if ((result = gethosts (fct, AF_INET6, name, req, tmpbuf,
736 res, &status, &no_data)) != 0)
738 __resolv_context_put (res_ctx);
739 goto out;
741 no_inet6_data = no_data;
742 inet6_status = status;
744 if (req->ai_family == AF_INET
745 || req->ai_family == AF_UNSPEC
746 || (req->ai_family == AF_INET6
747 && (req->ai_flags & AI_V4MAPPED)
748 /* Avoid generating the mapped addresses if we
749 know we are not going to need them. */
750 && ((req->ai_flags & AI_ALL) || !res->got_ipv6)))
752 if ((result = gethosts (fct, AF_INET, name, req, tmpbuf,
753 res, &status, &no_data)) != 0)
755 __resolv_context_put (res_ctx);
756 goto out;
759 if (req->ai_family == AF_INET)
761 no_inet6_data = no_data;
762 inet6_status = status;
766 /* If we found one address for AF_INET or AF_INET6,
767 don't continue the search. */
768 if (inet6_status == NSS_STATUS_SUCCESS
769 || status == NSS_STATUS_SUCCESS)
771 if ((req->ai_flags & AI_CANONNAME) != 0
772 && res->canon == NULL)
774 char *canonbuf = getcanonname (nip, res->at, name);
775 if (canonbuf == NULL)
777 __resolv_context_put (res_ctx);
778 result = -EAI_MEMORY;
779 goto out;
781 res->canon = canonbuf;
783 status = NSS_STATUS_SUCCESS;
785 else
787 /* We can have different states for AF_INET and
788 AF_INET6. Try to find a useful one for both. */
789 if (inet6_status == NSS_STATUS_TRYAGAIN)
790 status = NSS_STATUS_TRYAGAIN;
791 else if (status == NSS_STATUS_UNAVAIL
792 && inet6_status != NSS_STATUS_UNAVAIL)
793 status = inet6_status;
796 else
798 /* Could not locate any of the lookup functions.
799 The NSS lookup code does not consistently set
800 errno, so we need to supply our own error
801 code here. The root cause could either be a
802 resource allocation failure, or a missing
803 service function in the DSO (so it should not
804 be listed in /etc/nsswitch.conf). Assume the
805 former, and return EBUSY. */
806 status = NSS_STATUS_UNAVAIL;
807 __set_h_errno (NETDB_INTERNAL);
808 __set_errno (EBUSY);
812 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
813 break;
815 /* The hosts database does not support MERGE. */
816 if (nss_next_action (nip, status) == NSS_ACTION_MERGE)
817 do_merge = true;
819 nip++;
820 if (nip->module == NULL)
821 no_more = -1;
824 __resolv_context_put (res_ctx);
826 /* If we have a failure which sets errno, report it using
827 EAI_SYSTEM. */
828 if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
829 && h_errno == NETDB_INTERNAL)
831 result = -EAI_SYSTEM;
832 goto out;
835 if (no_data != 0 && no_inet6_data != 0)
837 /* If both requests timed out report this. */
838 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
839 result = -EAI_AGAIN;
840 else
841 /* We made requests but they turned out no data. The name
842 is known, though. */
843 result = -EAI_NODATA;
846 out:
847 if (result != 0)
848 gaih_result_reset (res);
849 return result;
852 /* Convert numeric addresses to binary into RES. On failure, RES->AT is set to
853 NULL and an error code is returned. If AI_NUMERIC_HOST is not requested and
854 the function cannot determine a result, RES->AT is set to NULL and 0
855 returned. */
857 static int
858 text_to_binary_address (const char *name, const struct addrinfo *req,
859 struct gaih_result *res)
861 struct gaih_addrtuple *at = res->at;
862 int result = 0;
864 assert (at != NULL);
866 memset (at->addr, 0, sizeof (at->addr));
867 if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
869 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
870 at->family = AF_INET;
871 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
873 at->addr[3] = at->addr[0];
874 at->addr[2] = htonl (0xffff);
875 at->addr[1] = 0;
876 at->addr[0] = 0;
877 at->family = AF_INET6;
879 else
881 result = -EAI_ADDRFAMILY;
882 goto out;
885 if (req->ai_flags & AI_CANONNAME)
887 char *canonbuf = __strdup (name);
888 if (canonbuf == NULL)
890 result = -EAI_MEMORY;
891 goto out;
893 res->canon = canonbuf;
895 return 0;
898 char *scope_delim = strchr (name, SCOPE_DELIMITER);
899 int e;
901 if (scope_delim == NULL)
902 e = inet_pton (AF_INET6, name, at->addr);
903 else
904 e = __inet_pton_length (AF_INET6, name, scope_delim - name, at->addr);
906 if (e > 0)
908 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
909 at->family = AF_INET6;
910 else if (req->ai_family == AF_INET
911 && IN6_IS_ADDR_V4MAPPED (at->addr))
913 at->addr[0] = at->addr[3];
914 at->family = AF_INET;
916 else
918 result = -EAI_ADDRFAMILY;
919 goto out;
922 if (scope_delim != NULL
923 && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
924 scope_delim + 1, &at->scopeid) != 0)
926 result = -EAI_NONAME;
927 goto out;
930 if (req->ai_flags & AI_CANONNAME)
932 char *canonbuf = __strdup (name);
933 if (canonbuf == NULL)
935 result = -EAI_MEMORY;
936 goto out;
938 res->canon = canonbuf;
940 return 0;
943 if ((req->ai_flags & AI_NUMERICHOST))
944 result = -EAI_NONAME;
946 out:
947 res->at = NULL;
948 return result;
951 /* If possible, call the simple, old functions, which do not support IPv6 scope
952 ids, nor retrieving the canonical name. */
954 static int
955 try_simple_gethostbyname (const char *name, const struct addrinfo *req,
956 struct scratch_buffer *tmpbuf,
957 struct gaih_result *res)
959 res->at = NULL;
961 if (req->ai_family != AF_INET || (req->ai_flags & AI_CANONNAME) != 0)
962 return 0;
964 int rc;
965 struct hostent th;
966 struct hostent *h;
968 while (1)
970 rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf->data,
971 tmpbuf->length, &h, &h_errno);
972 if (rc != ERANGE || h_errno != NETDB_INTERNAL)
973 break;
974 if (!scratch_buffer_grow (tmpbuf))
975 return -EAI_MEMORY;
978 if (rc == 0)
980 if (h != NULL)
982 /* We found data, convert it. RES->AT from the conversion will
983 either be an allocated block or NULL, both of which are safe to
984 pass to free (). */
985 if (!convert_hostent_to_gaih_addrtuple (req, AF_INET, h, res))
986 return -EAI_MEMORY;
988 res->free_at = true;
989 return 0;
991 if (h_errno == NO_DATA)
992 return -EAI_NODATA;
994 return -EAI_NONAME;
997 if (h_errno == NETDB_INTERNAL)
998 return -EAI_SYSTEM;
999 if (h_errno == TRY_AGAIN)
1000 return -EAI_AGAIN;
1002 /* We made requests but they turned out no data.
1003 The name is known, though. */
1004 return -EAI_NODATA;
1007 /* Add local address information into RES. RES->AT is assumed to have enough
1008 space for two tuples and is zeroed out. */
1010 static void
1011 get_local_addresses (const struct addrinfo *req, struct gaih_result *res)
1013 struct gaih_addrtuple *atr = res->at;
1014 if (req->ai_family == AF_UNSPEC)
1015 res->at->next = res->at + 1;
1017 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
1019 res->at->family = AF_INET6;
1020 if ((req->ai_flags & AI_PASSIVE) == 0)
1021 memcpy (res->at->addr, &in6addr_loopback, sizeof (struct in6_addr));
1022 atr = res->at->next;
1025 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
1027 atr->family = AF_INET;
1028 if ((req->ai_flags & AI_PASSIVE) == 0)
1029 atr->addr[0] = htonl (INADDR_LOOPBACK);
1033 /* Generate results in PAI and its count in NADDRS. Return 0 on success or an
1034 error code on failure. */
1036 static int
1037 generate_addrinfo (const struct addrinfo *req, struct gaih_result *res,
1038 const struct gaih_servtuple *st, struct addrinfo **pai,
1039 unsigned int *naddrs)
1041 size_t socklen;
1042 sa_family_t family;
1044 /* Buffer is the size of an unformatted IPv6 address in printable format. */
1045 for (struct gaih_addrtuple *at = res->at; at != NULL; at = at->next)
1047 family = at->family;
1048 if (family == AF_INET6)
1050 socklen = sizeof (struct sockaddr_in6);
1052 /* If we looked up IPv4 mapped address discard them here if
1053 the caller isn't interested in all address and we have
1054 found at least one IPv6 address. */
1055 if (res->got_ipv6
1056 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1057 && IN6_IS_ADDR_V4MAPPED (at->addr))
1058 continue;
1060 else
1061 socklen = sizeof (struct sockaddr_in);
1063 for (int i = 0; st[i].set; i++)
1065 struct addrinfo *ai;
1066 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1067 if (ai == NULL)
1068 return -EAI_MEMORY;
1070 ai->ai_flags = req->ai_flags;
1071 ai->ai_family = family;
1072 ai->ai_socktype = st[i].socktype;
1073 ai->ai_protocol = st[i].protocol;
1074 ai->ai_addrlen = socklen;
1075 ai->ai_addr = (void *) (ai + 1);
1077 /* We only add the canonical name once. */
1078 ai->ai_canonname = res->canon;
1079 res->canon = NULL;
1081 #ifdef _HAVE_SA_LEN
1082 ai->ai_addr->sa_len = socklen;
1083 #endif /* _HAVE_SA_LEN */
1084 ai->ai_addr->sa_family = family;
1086 /* In case of an allocation error the list must be NULL
1087 terminated. */
1088 ai->ai_next = NULL;
1090 if (family == AF_INET6)
1092 struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *) ai->ai_addr;
1093 sin6p->sin6_port = st[i].port;
1094 sin6p->sin6_flowinfo = 0;
1095 memcpy (&sin6p->sin6_addr, at->addr, sizeof (struct in6_addr));
1096 sin6p->sin6_scope_id = at->scopeid;
1098 else
1100 struct sockaddr_in *sinp = (struct sockaddr_in *) ai->ai_addr;
1101 sinp->sin_port = st[i].port;
1102 memcpy (&sinp->sin_addr, at->addr, sizeof (struct in_addr));
1103 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1106 pai = &(ai->ai_next);
1109 ++*naddrs;
1111 return 0;
1114 static int
1115 gaih_inet (const char *name, const struct gaih_service *service,
1116 const struct addrinfo *req, struct addrinfo **pai,
1117 unsigned int *naddrs, struct scratch_buffer *tmpbuf)
1119 struct gaih_servtuple st[sizeof (gaih_inet_typeproto)
1120 / sizeof (struct gaih_typeproto)] = {0};
1122 const char *orig_name = name;
1124 int rc;
1125 if ((rc = get_servtuples (service, req, st, tmpbuf)) != 0)
1126 return rc;
1128 bool malloc_name = false;
1129 struct gaih_addrtuple *addrmem = NULL;
1130 int result = 0;
1132 struct gaih_result res = {0};
1133 struct gaih_addrtuple local_at[2] = {0};
1135 res.at = local_at;
1137 if (__glibc_unlikely (name == NULL))
1139 get_local_addresses (req, &res);
1140 goto process_list;
1143 if (req->ai_flags & AI_IDN)
1145 char *out;
1146 result = __idna_to_dns_encoding (name, &out);
1147 if (result != 0)
1148 return -result;
1149 name = out;
1150 malloc_name = true;
1153 if ((result = text_to_binary_address (name, req, &res)) != 0)
1154 goto free_and_return;
1155 else if (res.at != NULL)
1156 goto process_list;
1158 if ((result = try_simple_gethostbyname (name, req, tmpbuf, &res)) != 0)
1159 goto free_and_return;
1160 else if (res.at != NULL)
1161 goto process_list;
1163 #ifdef USE_NSCD
1164 if ((result = get_nscd_addresses (name, req, &res)) != 0)
1165 goto free_and_return;
1166 else if (res.at != NULL)
1167 goto process_list;
1168 #endif
1170 if ((result = get_nss_addresses (name, req, tmpbuf, &res)) != 0)
1171 goto free_and_return;
1172 else if (res.at != NULL)
1173 goto process_list;
1175 /* None of the lookups worked, so name not found. */
1176 result = -EAI_NONAME;
1177 goto free_and_return;
1179 process_list:
1180 /* Set up the canonical name if we need it. */
1181 if ((result = process_canonname (req, orig_name, &res)) != 0)
1182 goto free_and_return;
1184 result = generate_addrinfo (req, &res, st, pai, naddrs);
1186 free_and_return:
1187 if (malloc_name)
1188 free ((char *) name);
1189 free (addrmem);
1190 if (res.free_at)
1191 free (res.at);
1192 free (res.canon);
1194 return result;
1198 struct sort_result
1200 struct addrinfo *dest_addr;
1201 /* Using sockaddr_storage is for now overkill. We only support IPv4
1202 and IPv6 so far. If this changes at some point we can adjust the
1203 type here. */
1204 struct sockaddr_in6 source_addr;
1205 uint8_t source_addr_len;
1206 bool got_source_addr;
1207 uint8_t source_addr_flags;
1208 uint8_t prefixlen;
1209 uint32_t index;
1210 int32_t native;
1213 struct sort_result_combo
1215 struct sort_result *results;
1216 int nresults;
1220 #if __BYTE_ORDER == __BIG_ENDIAN
1221 # define htonl_c(n) n
1222 #else
1223 # define htonl_c(n) __bswap_constant_32 (n)
1224 #endif
1226 static const struct scopeentry
1228 union
1230 char addr[4];
1231 uint32_t addr32;
1233 uint32_t netmask;
1234 int32_t scope;
1235 } default_scopes[] =
1237 /* Link-local addresses: scope 2. */
1238 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1239 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1240 /* Default: scope 14. */
1241 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1244 /* The label table. */
1245 static const struct scopeentry *scopes;
1248 static int
1249 get_scope (const struct sockaddr_in6 *in6)
1251 int scope;
1252 if (in6->sin6_family == PF_INET6)
1254 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1256 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1257 /* RFC 4291 2.5.3 says that the loopback address is to be
1258 treated like a link-local address. */
1259 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1260 scope = 2;
1261 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1262 scope = 5;
1263 else
1264 /* XXX Is this the correct default behavior? */
1265 scope = 14;
1267 else
1268 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1270 else if (in6->sin6_family == PF_INET)
1272 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1274 size_t cnt = 0;
1275 while (1)
1277 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1278 == scopes[cnt].addr32)
1279 return scopes[cnt].scope;
1281 ++cnt;
1283 /* NOTREACHED */
1285 else
1286 /* XXX What is a good default? */
1287 scope = 15;
1289 return scope;
1293 struct prefixentry
1295 struct in6_addr prefix;
1296 unsigned int bits;
1297 int val;
1301 /* The label table. */
1302 static const struct prefixentry *labels;
1304 /* Default labels. */
1305 static const struct prefixentry default_labels[] =
1307 /* See RFC 3484 for the details. */
1308 { { .__in6_u
1309 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1311 }, 128, 0 },
1312 { { .__in6_u
1313 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1315 }, 16, 2 },
1316 { { .__in6_u
1317 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1319 }, 96, 3 },
1320 { { .__in6_u
1321 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1322 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1323 }, 96, 4 },
1324 /* The next two entries differ from RFC 3484. We need to treat
1325 IPv6 site-local addresses special because they are never NATed,
1326 unlike site-locale IPv4 addresses. If this would not happen, on
1327 machines which have only IPv4 and IPv6 site-local addresses, the
1328 sorting would prefer the IPv6 site-local addresses, causing
1329 unnecessary delays when trying to connect to a global IPv6 address
1330 through a site-local IPv6 address. */
1331 { { .__in6_u
1332 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1334 }, 10, 5 },
1335 { { .__in6_u
1336 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1338 }, 7, 6 },
1339 /* Additional rule for Teredo tunnels. */
1340 { { .__in6_u
1341 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1343 }, 32, 7 },
1344 { { .__in6_u
1345 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1347 }, 0, 1 }
1351 /* The precedence table. */
1352 static const struct prefixentry *precedence;
1354 /* The default precedences. */
1355 static const struct prefixentry default_precedence[] =
1357 /* See RFC 3484 for the details. */
1358 { { .__in6_u
1359 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1361 }, 128, 50 },
1362 { { .__in6_u
1363 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1365 }, 16, 30 },
1366 { { .__in6_u
1367 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1369 }, 96, 20 },
1370 { { .__in6_u
1371 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1372 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1373 }, 96, 10 },
1374 { { .__in6_u
1375 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1377 }, 0, 40 }
1381 static int
1382 match_prefix (const struct sockaddr_in6 *in6,
1383 const struct prefixentry *list, int default_val)
1385 int idx;
1386 struct sockaddr_in6 in6_mem;
1388 if (in6->sin6_family == PF_INET)
1390 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1392 /* Construct a V4-to-6 mapped address. */
1393 in6_mem.sin6_family = PF_INET6;
1394 in6_mem.sin6_port = in->sin_port;
1395 in6_mem.sin6_flowinfo = 0;
1396 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1397 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1398 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1399 in6_mem.sin6_scope_id = 0;
1401 in6 = &in6_mem;
1403 else if (in6->sin6_family != PF_INET6)
1404 return default_val;
1406 for (idx = 0; ; ++idx)
1408 unsigned int bits = list[idx].bits;
1409 const uint8_t *mask = list[idx].prefix.s6_addr;
1410 const uint8_t *val = in6->sin6_addr.s6_addr;
1412 while (bits >= 8)
1414 if (*mask != *val)
1415 break;
1417 ++mask;
1418 ++val;
1419 bits -= 8;
1422 if (bits < 8)
1424 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1425 /* Match! */
1426 break;
1430 return list[idx].val;
1434 static int
1435 get_label (const struct sockaddr_in6 *in6)
1437 /* XXX What is a good default value? */
1438 return match_prefix (in6, labels, INT_MAX);
1442 static int
1443 get_precedence (const struct sockaddr_in6 *in6)
1445 /* XXX What is a good default value? */
1446 return match_prefix (in6, precedence, 0);
1450 /* Find last bit set in a word. */
1451 static int
1452 fls (uint32_t a)
1454 uint32_t mask;
1455 int n;
1456 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1457 if ((a & mask) != 0)
1458 break;
1459 return n;
1463 static int
1464 rfc3484_sort (const void *p1, const void *p2, void *arg)
1466 const size_t idx1 = *(const size_t *) p1;
1467 const size_t idx2 = *(const size_t *) p2;
1468 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1469 struct sort_result *a1 = &src->results[idx1];
1470 struct sort_result *a2 = &src->results[idx2];
1472 /* Rule 1: Avoid unusable destinations.
1473 We have the got_source_addr flag set if the destination is reachable. */
1474 if (a1->got_source_addr && ! a2->got_source_addr)
1475 return -1;
1476 if (! a1->got_source_addr && a2->got_source_addr)
1477 return 1;
1480 /* Rule 2: Prefer matching scope. Only interesting if both
1481 destination addresses are IPv6. */
1482 int a1_dst_scope
1483 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1485 int a2_dst_scope
1486 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1488 if (a1->got_source_addr)
1490 int a1_src_scope = get_scope (&a1->source_addr);
1491 int a2_src_scope = get_scope (&a2->source_addr);
1493 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1494 return -1;
1495 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1496 return 1;
1500 /* Rule 3: Avoid deprecated addresses. */
1501 if (a1->got_source_addr)
1503 if (!(a1->source_addr_flags & in6ai_deprecated)
1504 && (a2->source_addr_flags & in6ai_deprecated))
1505 return -1;
1506 if ((a1->source_addr_flags & in6ai_deprecated)
1507 && !(a2->source_addr_flags & in6ai_deprecated))
1508 return 1;
1511 /* Rule 4: Prefer home addresses. */
1512 if (a1->got_source_addr)
1514 if (!(a1->source_addr_flags & in6ai_homeaddress)
1515 && (a2->source_addr_flags & in6ai_homeaddress))
1516 return 1;
1517 if ((a1->source_addr_flags & in6ai_homeaddress)
1518 && !(a2->source_addr_flags & in6ai_homeaddress))
1519 return -1;
1522 /* Rule 5: Prefer matching label. */
1523 if (a1->got_source_addr)
1525 int a1_dst_label
1526 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1527 int a1_src_label = get_label (&a1->source_addr);
1529 int a2_dst_label
1530 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1531 int a2_src_label = get_label (&a2->source_addr);
1533 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1534 return -1;
1535 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1536 return 1;
1540 /* Rule 6: Prefer higher precedence. */
1541 int a1_prec
1542 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1543 int a2_prec
1544 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1546 if (a1_prec > a2_prec)
1547 return -1;
1548 if (a1_prec < a2_prec)
1549 return 1;
1552 /* Rule 7: Prefer native transport. */
1553 if (a1->got_source_addr)
1555 /* The same interface index means the same interface which means
1556 there is no difference in transport. This should catch many
1557 (most?) cases. */
1558 if (a1->index != a2->index)
1560 int a1_native = a1->native;
1561 int a2_native = a2->native;
1563 if (a1_native == -1 || a2_native == -1)
1565 uint32_t a1_index;
1566 if (a1_native == -1)
1568 /* If we do not have the information use 'native' as
1569 the default. */
1570 a1_native = 0;
1571 a1_index = a1->index;
1573 else
1574 a1_index = 0xffffffffu;
1576 uint32_t a2_index;
1577 if (a2_native == -1)
1579 /* If we do not have the information use 'native' as
1580 the default. */
1581 a2_native = 0;
1582 a2_index = a2->index;
1584 else
1585 a2_index = 0xffffffffu;
1587 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1589 /* Fill in the results in all the records. */
1590 for (int i = 0; i < src->nresults; ++i)
1591 if (a1_index != -1 && src->results[i].index == a1_index)
1593 assert (src->results[i].native == -1
1594 || src->results[i].native == a1_native);
1595 src->results[i].native = a1_native;
1597 else if (a2_index != -1 && src->results[i].index == a2_index)
1599 assert (src->results[i].native == -1
1600 || src->results[i].native == a2_native);
1601 src->results[i].native = a2_native;
1605 if (a1_native && !a2_native)
1606 return -1;
1607 if (!a1_native && a2_native)
1608 return 1;
1613 /* Rule 8: Prefer smaller scope. */
1614 if (a1_dst_scope < a2_dst_scope)
1615 return -1;
1616 if (a1_dst_scope > a2_dst_scope)
1617 return 1;
1620 /* Rule 9: Use longest matching prefix. */
1621 if (a1->got_source_addr
1622 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1624 int bit1 = 0;
1625 int bit2 = 0;
1627 if (a1->dest_addr->ai_family == PF_INET)
1629 assert (a1->source_addr.sin6_family == PF_INET);
1630 assert (a2->source_addr.sin6_family == PF_INET);
1632 /* Outside of subnets, as defined by the network masks,
1633 common address prefixes for IPv4 addresses make no sense.
1634 So, define a non-zero value only if source and
1635 destination address are on the same subnet. */
1636 struct sockaddr_in *in1_dst
1637 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1638 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1639 struct sockaddr_in *in1_src
1640 = (struct sockaddr_in *) &a1->source_addr;
1641 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1642 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1644 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1645 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1647 struct sockaddr_in *in2_dst
1648 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1649 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1650 struct sockaddr_in *in2_src
1651 = (struct sockaddr_in *) &a2->source_addr;
1652 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1653 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1655 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1656 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1658 else if (a1->dest_addr->ai_family == PF_INET6)
1660 assert (a1->source_addr.sin6_family == PF_INET6);
1661 assert (a2->source_addr.sin6_family == PF_INET6);
1663 struct sockaddr_in6 *in1_dst;
1664 struct sockaddr_in6 *in1_src;
1665 struct sockaddr_in6 *in2_dst;
1666 struct sockaddr_in6 *in2_src;
1668 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1669 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1670 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1671 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1673 int i;
1674 for (i = 0; i < 4; ++i)
1675 if (in1_dst->sin6_addr.s6_addr32[i]
1676 != in1_src->sin6_addr.s6_addr32[i]
1677 || (in2_dst->sin6_addr.s6_addr32[i]
1678 != in2_src->sin6_addr.s6_addr32[i]))
1679 break;
1681 if (i < 4)
1683 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1684 ^ in1_src->sin6_addr.s6_addr32[i]));
1685 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1686 ^ in2_src->sin6_addr.s6_addr32[i]));
1690 if (bit1 > bit2)
1691 return -1;
1692 if (bit1 < bit2)
1693 return 1;
1697 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1698 compare with the value indicating the order in which the entries
1699 have been received from the services. NB: no two entries can have
1700 the same order so the test will never return zero. */
1701 return idx1 < idx2 ? -1 : 1;
1705 static int
1706 in6aicmp (const void *p1, const void *p2)
1708 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1709 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1711 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1715 /* Name of the config file for RFC 3484 sorting (for now). */
1716 #define GAICONF_FNAME "/etc/gai.conf"
1719 /* Non-zero if we are supposed to reload the config file automatically
1720 whenever it changed. */
1721 static int gaiconf_reload_flag;
1723 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1724 static int gaiconf_reload_flag_ever_set;
1726 /* Last modification time. */
1727 #ifdef _STATBUF_ST_NSEC
1729 static struct __timespec64 gaiconf_mtime;
1731 static inline void
1732 save_gaiconf_mtime (const struct __stat64_t64 *st)
1734 gaiconf_mtime = (struct __timespec64) { st->st_mtim.tv_sec,
1735 st->st_mtim.tv_nsec };
1738 static inline bool
1739 check_gaiconf_mtime (const struct __stat64_t64 *st)
1741 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1742 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1745 #else
1747 static time_t gaiconf_mtime;
1749 static inline void
1750 save_gaiconf_mtime (const struct __stat64_t64 *st)
1752 gaiconf_mtime = st->st_mtime;
1755 static inline bool
1756 check_gaiconf_mtime (const struct __stat64_t64 *st)
1758 return st->st_mtime == gaiconf_mtime;
1761 #endif
1764 void
1765 __libc_getaddrinfo_freemem (void)
1767 if (labels != default_labels)
1769 const struct prefixentry *old = labels;
1770 labels = default_labels;
1771 free ((void *) old);
1774 if (precedence != default_precedence)
1776 const struct prefixentry *old = precedence;
1777 precedence = default_precedence;
1778 free ((void *) old);
1781 if (scopes != default_scopes)
1783 const struct scopeentry *old = scopes;
1784 scopes = default_scopes;
1785 free ((void *) old);
1790 struct prefixlist
1792 struct prefixentry entry;
1793 struct prefixlist *next;
1797 struct scopelist
1799 struct scopeentry entry;
1800 struct scopelist *next;
1804 static void
1805 free_prefixlist (struct prefixlist *list)
1807 while (list != NULL)
1809 struct prefixlist *oldp = list;
1810 list = list->next;
1811 free (oldp);
1816 static void
1817 free_scopelist (struct scopelist *list)
1819 while (list != NULL)
1821 struct scopelist *oldp = list;
1822 list = list->next;
1823 free (oldp);
1828 static int
1829 prefixcmp (const void *p1, const void *p2)
1831 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1832 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1834 if (e1->bits < e2->bits)
1835 return 1;
1836 if (e1->bits == e2->bits)
1837 return 0;
1838 return -1;
1842 static int
1843 scopecmp (const void *p1, const void *p2)
1845 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1846 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1848 if (e1->netmask > e2->netmask)
1849 return -1;
1850 if (e1->netmask == e2->netmask)
1851 return 0;
1852 return 1;
1855 static bool
1856 add_prefixlist (struct prefixlist **listp, size_t *lenp, bool *nullbitsp,
1857 char *val1, char *val2, char **pos)
1859 struct in6_addr prefix;
1860 unsigned long int bits;
1861 unsigned long int val;
1862 char *endp;
1864 bits = 128;
1865 __set_errno (0);
1866 char *cp = strchr (val1, '/');
1867 if (cp != NULL)
1868 *cp++ = '\0';
1869 *pos = cp;
1870 if (inet_pton (AF_INET6, val1, &prefix)
1871 && (cp == NULL
1872 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1873 || errno != ERANGE)
1874 && *endp == '\0'
1875 && bits <= 128
1876 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1877 || errno != ERANGE)
1878 && *endp == '\0'
1879 && val <= INT_MAX)
1881 struct prefixlist *newp = malloc (sizeof (*newp));
1882 if (newp == NULL)
1883 return false;
1885 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1886 newp->entry.bits = bits;
1887 newp->entry.val = val;
1888 newp->next = *listp;
1889 *listp = newp;
1890 ++*lenp;
1891 *nullbitsp |= bits == 0;
1893 return true;
1896 static bool
1897 add_scopelist (struct scopelist **listp, size_t *lenp, bool *nullbitsp,
1898 const struct in6_addr *prefixp, unsigned long int bits,
1899 unsigned long int val)
1901 struct scopelist *newp = malloc (sizeof (*newp));
1902 if (newp == NULL)
1903 return false;
1905 newp->entry.netmask = htonl (bits != 96 ? (0xffffffff << (128 - bits)) : 0);
1906 newp->entry.addr32 = (prefixp->s6_addr32[3] & newp->entry.netmask);
1907 newp->entry.scope = val;
1908 newp->next = *listp;
1909 *listp = newp;
1910 ++*lenp;
1911 *nullbitsp |= bits == 96;
1913 return true;
1916 static void
1917 gaiconf_init (void)
1919 struct prefixlist *labellist = NULL;
1920 size_t nlabellist = 0;
1921 bool labellist_nullbits = false;
1922 struct prefixlist *precedencelist = NULL;
1923 size_t nprecedencelist = 0;
1924 bool precedencelist_nullbits = false;
1925 struct scopelist *scopelist = NULL;
1926 size_t nscopelist = 0;
1927 bool scopelist_nullbits = false;
1929 FILE *fp = fopen (GAICONF_FNAME, "rce");
1930 if (fp == NULL)
1931 goto no_file;
1933 struct __stat64_t64 st;
1934 if (__fstat64_time64 (fileno (fp), &st) != 0)
1936 fclose (fp);
1937 goto no_file;
1940 char *line = NULL;
1941 size_t linelen = 0;
1943 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1945 while (!feof_unlocked (fp))
1947 ssize_t n = __getline (&line, &linelen, fp);
1948 if (n <= 0)
1949 break;
1951 /* Handle comments. No escaping possible so this is easy. */
1952 char *cp = strchr (line, '#');
1953 if (cp != NULL)
1954 *cp = '\0';
1956 cp = line;
1957 while (isspace (*cp))
1958 ++cp;
1960 char *cmd = cp;
1961 while (*cp != '\0' && !isspace (*cp))
1962 ++cp;
1963 size_t cmdlen = cp - cmd;
1965 if (*cp != '\0')
1966 *cp++ = '\0';
1967 while (isspace (*cp))
1968 ++cp;
1970 char *val1 = cp;
1971 while (*cp != '\0' && !isspace (*cp))
1972 ++cp;
1973 size_t val1len = cp - cmd;
1975 /* We always need at least two values. */
1976 if (val1len == 0)
1977 continue;
1979 if (*cp != '\0')
1980 *cp++ = '\0';
1981 while (isspace (*cp))
1982 ++cp;
1984 char *val2 = cp;
1985 while (*cp != '\0' && !isspace (*cp))
1986 ++cp;
1988 /* Ignore the rest of the line. */
1989 *cp = '\0';
1991 switch (cmdlen)
1993 case 5:
1994 if (strcmp (cmd, "label") == 0)
1996 if (!add_prefixlist (&labellist, &nlabellist,
1997 &labellist_nullbits, val1, val2, &cp))
1999 free (line);
2000 fclose (fp);
2001 goto no_file;
2004 break;
2006 case 6:
2007 if (strcmp (cmd, "reload") == 0)
2009 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
2010 if (gaiconf_reload_flag)
2011 gaiconf_reload_flag_ever_set = 1;
2013 break;
2015 case 7:
2016 if (strcmp (cmd, "scopev4") == 0)
2018 struct in6_addr prefix;
2019 unsigned long int bits;
2020 unsigned long int val;
2021 char *endp;
2023 bits = 32;
2024 __set_errno (0);
2025 cp = strchr (val1, '/');
2026 if (cp != NULL)
2027 *cp++ = '\0';
2028 if (inet_pton (AF_INET6, val1, &prefix))
2030 bits = 128;
2031 if (IN6_IS_ADDR_V4MAPPED (&prefix)
2032 && (cp == NULL
2033 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2034 || errno != ERANGE)
2035 && *endp == '\0'
2036 && bits >= 96
2037 && bits <= 128
2038 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2039 || errno != ERANGE)
2040 && *endp == '\0'
2041 && val <= INT_MAX)
2043 if (!add_scopelist (&scopelist, &nscopelist,
2044 &scopelist_nullbits, &prefix,
2045 bits, val))
2047 free (line);
2048 fclose (fp);
2049 goto no_file;
2053 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
2054 && (cp == NULL
2055 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2056 || errno != ERANGE)
2057 && *endp == '\0'
2058 && bits <= 32
2059 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2060 || errno != ERANGE)
2061 && *endp == '\0'
2062 && val <= INT_MAX)
2064 if (!add_scopelist (&scopelist, &nscopelist,
2065 &scopelist_nullbits, &prefix,
2066 bits + 96, val))
2068 free (line);
2069 fclose (fp);
2070 goto no_file;
2074 break;
2076 case 10:
2077 if (strcmp (cmd, "precedence") == 0)
2079 if (!add_prefixlist (&precedencelist, &nprecedencelist,
2080 &precedencelist_nullbits, val1, val2,
2081 &cp))
2083 free (line);
2084 fclose (fp);
2085 goto no_file;
2088 break;
2092 free (line);
2094 fclose (fp);
2096 /* Create the array for the labels. */
2097 struct prefixentry *new_labels;
2098 if (nlabellist > 0)
2100 if (!labellist_nullbits)
2101 ++nlabellist;
2102 new_labels = malloc (nlabellist * sizeof (*new_labels));
2103 if (new_labels == NULL)
2104 goto no_file;
2106 int i = nlabellist;
2107 if (!labellist_nullbits)
2109 --i;
2110 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2111 new_labels[i].bits = 0;
2112 new_labels[i].val = 1;
2115 struct prefixlist *l = labellist;
2116 while (i-- > 0)
2118 new_labels[i] = l->entry;
2119 l = l->next;
2121 free_prefixlist (labellist);
2122 labellist = NULL;
2124 /* Sort the entries so that the most specific ones are at
2125 the beginning. */
2126 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2128 else
2129 new_labels = (struct prefixentry *) default_labels;
2131 struct prefixentry *new_precedence;
2132 if (nprecedencelist > 0)
2134 if (!precedencelist_nullbits)
2135 ++nprecedencelist;
2136 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2137 if (new_precedence == NULL)
2139 if (new_labels != default_labels)
2140 free (new_labels);
2141 goto no_file;
2144 int i = nprecedencelist;
2145 if (!precedencelist_nullbits)
2147 --i;
2148 memset (&new_precedence[i].prefix, '\0',
2149 sizeof (struct in6_addr));
2150 new_precedence[i].bits = 0;
2151 new_precedence[i].val = 40;
2154 struct prefixlist *l = precedencelist;
2155 while (i-- > 0)
2157 new_precedence[i] = l->entry;
2158 l = l->next;
2160 free_prefixlist (precedencelist);
2161 precedencelist = NULL;
2163 /* Sort the entries so that the most specific ones are at
2164 the beginning. */
2165 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2166 prefixcmp);
2168 else
2169 new_precedence = (struct prefixentry *) default_precedence;
2171 struct scopeentry *new_scopes;
2172 if (nscopelist > 0)
2174 if (!scopelist_nullbits)
2175 ++nscopelist;
2176 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2177 if (new_scopes == NULL)
2179 if (new_labels != default_labels)
2180 free (new_labels);
2181 if (new_precedence != default_precedence)
2182 free (new_precedence);
2183 goto no_file;
2186 int i = nscopelist;
2187 if (!scopelist_nullbits)
2189 --i;
2190 new_scopes[i].addr32 = 0;
2191 new_scopes[i].netmask = 0;
2192 new_scopes[i].scope = 14;
2195 struct scopelist *l = scopelist;
2196 while (i-- > 0)
2198 new_scopes[i] = l->entry;
2199 l = l->next;
2201 free_scopelist (scopelist);
2203 /* Sort the entries so that the most specific ones are at
2204 the beginning. */
2205 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2206 scopecmp);
2208 else
2209 new_scopes = (struct scopeentry *) default_scopes;
2211 /* Now we are ready to replace the values. */
2212 const struct prefixentry *old = labels;
2213 labels = new_labels;
2214 if (old != default_labels)
2215 free ((void *) old);
2217 old = precedence;
2218 precedence = new_precedence;
2219 if (old != default_precedence)
2220 free ((void *) old);
2222 const struct scopeentry *oldscope = scopes;
2223 scopes = new_scopes;
2224 if (oldscope != default_scopes)
2225 free ((void *) oldscope);
2227 save_gaiconf_mtime (&st);
2228 return;
2230 no_file:
2231 free_prefixlist (labellist);
2232 free_prefixlist (precedencelist);
2233 free_scopelist (scopelist);
2235 /* If we previously read the file but it is gone now, free the old data and
2236 use the builtin one. Leave the reload flag alone. */
2237 __libc_getaddrinfo_freemem ();
2241 static void
2242 gaiconf_reload (void)
2244 struct __stat64_t64 st;
2245 if (__stat64_time64 (GAICONF_FNAME, &st) != 0
2246 || !check_gaiconf_mtime (&st))
2247 gaiconf_init ();
2250 static bool
2251 try_connect (int *fdp, int *afp, struct sockaddr_in6 *source_addrp,
2252 const struct sockaddr *addr, socklen_t addrlen, int family)
2254 int fd = *fdp;
2255 int af = *afp;
2256 socklen_t sl = sizeof (*source_addrp);
2258 while (true)
2260 if (fd != -1 && __connect (fd, addr, addrlen) == 0
2261 && __getsockname (fd, (struct sockaddr *) source_addrp, &sl) == 0)
2262 return true;
2264 if (errno == EAFNOSUPPORT && af == AF_INET6 && family == AF_INET)
2266 /* This could mean IPv6 sockets are IPv6-only. */
2267 if (fd != -1)
2268 __close_nocancel_nostatus (fd);
2269 *afp = af = AF_INET;
2270 *fdp = fd = __socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC,
2271 IPPROTO_IP);
2272 continue;
2275 return false;
2278 __builtin_unreachable ();
2282 getaddrinfo (const char *name, const char *service,
2283 const struct addrinfo *hints, struct addrinfo **pai)
2285 int i = 0, last_i = 0;
2286 int nresults = 0;
2287 struct addrinfo *p = NULL;
2288 struct gaih_service gaih_service, *pservice;
2289 struct addrinfo local_hints;
2291 if (name != NULL && name[0] == '*' && name[1] == 0)
2292 name = NULL;
2294 if (service != NULL && service[0] == '*' && service[1] == 0)
2295 service = NULL;
2297 if (name == NULL && service == NULL)
2298 return EAI_NONAME;
2300 if (hints == NULL)
2301 hints = &default_hints;
2303 if (hints->ai_flags
2304 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2305 |AI_IDN|AI_CANONIDN|DEPRECATED_AI_IDN
2306 |AI_NUMERICSERV|AI_ALL))
2307 return EAI_BADFLAGS;
2309 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2310 return EAI_BADFLAGS;
2312 if (hints->ai_family != AF_UNSPEC && hints->ai_family != AF_INET
2313 && hints->ai_family != AF_INET6)
2314 return EAI_FAMILY;
2316 struct in6addrinfo *in6ai = NULL;
2317 size_t in6ailen = 0;
2318 bool seen_ipv4 = false;
2319 bool seen_ipv6 = false;
2320 bool check_pf_called = false;
2322 if (hints->ai_flags & AI_ADDRCONFIG)
2324 /* We might need information about what interfaces are available.
2325 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2326 cannot cache the results since new interfaces could be added at
2327 any time. */
2328 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2329 check_pf_called = true;
2331 /* Now make a decision on what we return, if anything. */
2332 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2334 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2335 narrow down the search. */
2336 if (seen_ipv4 != seen_ipv6)
2338 local_hints = *hints;
2339 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2340 hints = &local_hints;
2343 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2344 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2346 /* We cannot possibly return a valid answer. */
2347 __free_in6ai (in6ai);
2348 return EAI_NONAME;
2352 if (service && service[0])
2354 char *c;
2355 gaih_service.name = service;
2356 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2357 if (*c != '\0')
2359 if (hints->ai_flags & AI_NUMERICSERV)
2361 __free_in6ai (in6ai);
2362 return EAI_NONAME;
2365 gaih_service.num = -1;
2368 pservice = &gaih_service;
2370 else
2371 pservice = NULL;
2373 struct addrinfo **end = &p;
2374 unsigned int naddrs = 0;
2375 struct scratch_buffer tmpbuf;
2377 scratch_buffer_init (&tmpbuf);
2378 last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf);
2379 scratch_buffer_free (&tmpbuf);
2381 if (last_i != 0)
2383 freeaddrinfo (p);
2384 __free_in6ai (in6ai);
2386 return -last_i;
2389 while (*end)
2391 end = &((*end)->ai_next);
2392 ++nresults;
2395 if (naddrs > 1)
2397 /* Read the config file. */
2398 __libc_once_define (static, once);
2399 __typeof (once) old_once = once;
2400 __libc_once (once, gaiconf_init);
2401 /* Sort results according to RFC 3484. */
2402 struct sort_result *results;
2403 size_t *order;
2404 struct addrinfo *q;
2405 struct addrinfo *last = NULL;
2406 char *canonname = NULL;
2407 bool malloc_results;
2408 size_t alloc_size = nresults * (sizeof (*results) + sizeof (size_t));
2410 malloc_results
2411 = !__libc_use_alloca (alloc_size);
2412 if (malloc_results)
2414 results = malloc (alloc_size);
2415 if (results == NULL)
2417 __free_in6ai (in6ai);
2418 return EAI_MEMORY;
2421 else
2422 results = alloca (alloc_size);
2423 order = (size_t *) (results + nresults);
2425 /* Now we definitely need the interface information. */
2426 if (! check_pf_called)
2427 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2429 /* If we have information about deprecated and temporary addresses
2430 sort the array now. */
2431 if (in6ai != NULL)
2432 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2434 int fd = -1;
2435 int af = AF_UNSPEC;
2437 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2439 results[i].dest_addr = q;
2440 results[i].native = -1;
2441 order[i] = i;
2443 /* If we just looked up the address for a different
2444 protocol, reuse the result. */
2445 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2446 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2448 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2449 results[i - 1].source_addr_len);
2450 results[i].source_addr_len = results[i - 1].source_addr_len;
2451 results[i].got_source_addr = results[i - 1].got_source_addr;
2452 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2453 results[i].prefixlen = results[i - 1].prefixlen;
2454 results[i].index = results[i - 1].index;
2456 else
2458 results[i].got_source_addr = false;
2459 results[i].source_addr_flags = 0;
2460 results[i].prefixlen = 0;
2461 results[i].index = 0xffffffffu;
2463 /* We overwrite the type with SOCK_DGRAM since we do not
2464 want connect() to connect to the other side. If we
2465 cannot determine the source address remember this
2466 fact. */
2467 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2469 if (fd != -1)
2470 __close_nocancel_nostatus (fd);
2471 af = q->ai_family;
2472 fd = __socket (af, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP);
2474 else
2476 /* Reset the connection. */
2477 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2478 __connect (fd, &sa, sizeof (sa));
2481 if (try_connect (&fd, &af, &results[i].source_addr, q->ai_addr,
2482 q->ai_addrlen, q->ai_family))
2484 results[i].source_addr_len = sizeof (results[i].source_addr);
2485 results[i].got_source_addr = true;
2487 if (in6ai != NULL)
2489 /* See whether the source address is on the list of
2490 deprecated or temporary addresses. */
2491 struct in6addrinfo tmp;
2493 if (q->ai_family == AF_INET && af == AF_INET)
2495 struct sockaddr_in *sinp
2496 = (struct sockaddr_in *) &results[i].source_addr;
2497 tmp.addr[0] = 0;
2498 tmp.addr[1] = 0;
2499 tmp.addr[2] = htonl (0xffff);
2500 /* Special case for lo interface, the source address
2501 being possibly different than the interface
2502 address. */
2503 if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2504 == 0x7f000000)
2505 tmp.addr[3] = htonl(0x7f000001);
2506 else
2507 tmp.addr[3] = sinp->sin_addr.s_addr;
2509 else
2511 struct sockaddr_in6 *sin6p
2512 = (struct sockaddr_in6 *) &results[i].source_addr;
2513 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2516 struct in6addrinfo *found
2517 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2518 in6aicmp);
2519 if (found != NULL)
2521 results[i].source_addr_flags = found->flags;
2522 results[i].prefixlen = found->prefixlen;
2523 results[i].index = found->index;
2527 if (q->ai_family == AF_INET && af == AF_INET6)
2529 /* We have to convert the address. The socket is
2530 IPv6 and the request is for IPv4. */
2531 struct sockaddr_in6 *sin6
2532 = (struct sockaddr_in6 *) &results[i].source_addr;
2533 struct sockaddr_in *sin
2534 = (struct sockaddr_in *) &results[i].source_addr;
2535 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2536 sin->sin_family = AF_INET;
2537 /* We do not have to initialize sin_port since this
2538 fields has the same position and size in the IPv6
2539 structure. */
2540 assert (offsetof (struct sockaddr_in, sin_port)
2541 == offsetof (struct sockaddr_in6, sin6_port));
2542 assert (sizeof (sin->sin_port)
2543 == sizeof (sin6->sin6_port));
2544 memcpy (&sin->sin_addr,
2545 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2546 results[i].source_addr_len = sizeof (struct sockaddr_in);
2549 else
2550 /* Just make sure that if we have to process the same
2551 address again we do not copy any memory. */
2552 results[i].source_addr_len = 0;
2555 /* Remember the canonical name. */
2556 if (q->ai_canonname != NULL)
2558 assert (canonname == NULL);
2559 canonname = q->ai_canonname;
2560 q->ai_canonname = NULL;
2564 if (fd != -1)
2565 __close_nocancel_nostatus (fd);
2567 /* We got all the source addresses we can get, now sort using
2568 the information. */
2569 struct sort_result_combo src
2570 = { .results = results, .nresults = nresults };
2571 if (__glibc_unlikely (gaiconf_reload_flag_ever_set))
2573 __libc_lock_define_initialized (static, lock);
2575 __libc_lock_lock (lock);
2576 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2577 gaiconf_reload ();
2578 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2579 __libc_lock_unlock (lock);
2581 else
2582 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2584 /* Queue the results up as they come out of sorting. */
2585 q = p = results[order[0]].dest_addr;
2586 for (i = 1; i < nresults; ++i)
2587 q = q->ai_next = results[order[i]].dest_addr;
2588 q->ai_next = NULL;
2590 /* Fill in the canonical name into the new first entry. */
2591 p->ai_canonname = canonname;
2593 if (malloc_results)
2594 free (results);
2597 __free_in6ai (in6ai);
2599 if (p)
2601 *pai = p;
2602 return 0;
2605 return last_i ? -last_i : EAI_NONAME;
2607 libc_hidden_def (getaddrinfo)
2609 nss_interface_function (getaddrinfo)
2611 void
2612 freeaddrinfo (struct addrinfo *ai)
2614 struct addrinfo *p;
2616 while (ai != NULL)
2618 p = ai;
2619 ai = ai->ai_next;
2620 free (p->ai_canonname);
2621 free (p);
2624 libc_hidden_def (freeaddrinfo)