More NEWS entries / fixes for float_t / double_t changes.
[glibc.git] / sysdeps / posix / getaddrinfo.c
blob740e9555d5c836c02a329b39540fb367ee8f8a4e
1 /* Host and service name lookups using Name Service Switch modules.
2 Copyright (C) 1996-2016 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 /* The Inner Net License, Version 2.00
21 The author(s) grant permission for redistribution and use in source and
22 binary forms, with or without modification, of the software and documentation
23 provided that the following conditions are met:
25 0. If you receive a version of the software that is specifically labelled
26 as not being for redistribution (check the version message and/or README),
27 you are not permitted to redistribute that version of the software in any
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.h>
63 #include <stdbool.h>
64 #include <stdio.h>
65 #include <stdio_ext.h>
66 #include <stdlib.h>
67 #include <string.h>
68 #include <stdint.h>
69 #include <arpa/inet.h>
70 #include <net/if.h>
71 #include <netinet/in.h>
72 #include <sys/socket.h>
73 #include <sys/stat.h>
74 #include <sys/types.h>
75 #include <sys/un.h>
76 #include <sys/utsname.h>
77 #include <unistd.h>
78 #include <nsswitch.h>
79 #include <libc-lock.h>
80 #include <not-cancel.h>
81 #include <nscd/nscd-client.h>
82 #include <nscd/nscd_proto.h>
83 #include <resolv/res_hconf.h>
84 #include <scratch_buffer.h>
85 #include <inet/net-internal.h>
87 #ifdef HAVE_LIBIDN
88 extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
89 extern int __idna_to_unicode_lzlz (const char *input, char **output,
90 int flags);
91 # include <libidn/idna.h>
92 #endif
94 struct gaih_service
96 const char *name;
97 int num;
100 struct gaih_servtuple
102 struct gaih_servtuple *next;
103 int socktype;
104 int protocol;
105 int port;
108 static const struct gaih_servtuple nullserv;
111 struct gaih_typeproto
113 int socktype;
114 int protocol;
115 uint8_t protoflag;
116 bool defaultflag;
117 char name[8];
120 /* Values for `protoflag'. */
121 #define GAI_PROTO_NOSERVICE 1
122 #define GAI_PROTO_PROTOANY 2
124 static const struct gaih_typeproto gaih_inet_typeproto[] =
126 { 0, 0, 0, false, "" },
127 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
128 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
129 #if defined SOCK_DCCP && defined IPPROTO_DCCP
130 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
131 #endif
132 #ifdef IPPROTO_UDPLITE
133 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
134 #endif
135 #ifdef IPPROTO_SCTP
136 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
137 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
138 #endif
139 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
140 { 0, 0, 0, false, "" }
143 static const struct addrinfo default_hints =
145 .ai_flags = AI_DEFAULT,
146 .ai_family = PF_UNSPEC,
147 .ai_socktype = 0,
148 .ai_protocol = 0,
149 .ai_addrlen = 0,
150 .ai_addr = NULL,
151 .ai_canonname = NULL,
152 .ai_next = NULL
156 static int
157 gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
158 const struct addrinfo *req, struct gaih_servtuple *st,
159 struct scratch_buffer *tmpbuf)
161 struct servent *s;
162 struct servent ts;
163 int r;
167 r = __getservbyname_r (servicename, tp->name, &ts,
168 tmpbuf->data, tmpbuf->length, &s);
169 if (r != 0 || s == NULL)
171 if (r == ERANGE)
173 if (!scratch_buffer_grow (tmpbuf))
174 return -EAI_MEMORY;
176 else
177 return -EAI_SERVICE;
180 while (r);
182 st->next = NULL;
183 st->socktype = tp->socktype;
184 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
185 ? req->ai_protocol : tp->protocol);
186 st->port = s->s_port;
188 return 0;
191 /* Convert struct hostent to a list of struct gaih_addrtuple objects.
192 h_name is not copied, and the struct hostent object must not be
193 deallocated prematurely. *RESULT must be NULL or a pointer to an
194 object allocated using malloc, which is freed. */
195 static bool
196 convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
197 int family,
198 struct hostent *h,
199 struct gaih_addrtuple **result)
201 free (*result);
202 *result = NULL;
204 /* Count the number of addresses in h->h_addr_list. */
205 size_t count = 0;
206 for (char **p = h->h_addr_list; *p != NULL; ++p)
207 ++count;
209 /* Report no data if no addresses are available, or if the incoming
210 address size is larger than what we can store. */
211 if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
212 return true;
214 struct gaih_addrtuple *array = calloc (count, sizeof (*array));
215 if (array == NULL)
216 return false;
218 for (size_t i = 0; i < count; ++i)
220 if (family == AF_INET && req->ai_family == AF_INET6)
222 /* Perform address mapping. */
223 array[i].family = AF_INET6;
224 memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
225 array[i].addr[2] = htonl (0xffff);
227 else
229 array[i].family = family;
230 memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
232 array[i].next = array + i + 1;
234 array[0].name = h->h_name;
235 array[count - 1].next = NULL;
237 *result = array;
238 return true;
241 #define gethosts(_family, _type) \
243 int herrno; \
244 struct hostent th; \
245 struct hostent *h; \
246 char *localcanon = NULL; \
247 no_data = 0; \
248 while (1) { \
249 rc = 0; \
250 status = DL_CALL_FCT (fct, (name, _family, &th, \
251 tmpbuf->data, tmpbuf->length, \
252 &rc, &herrno, NULL, &localcanon)); \
253 if (rc != ERANGE || herrno != NETDB_INTERNAL) \
254 break; \
255 if (!scratch_buffer_grow (tmpbuf)) \
257 result = -EAI_MEMORY; \
258 goto free_and_return; \
261 if (status == NSS_STATUS_SUCCESS && rc == 0) \
262 h = &th; \
263 else \
264 h = NULL; \
265 if (rc != 0) \
267 if (herrno == NETDB_INTERNAL) \
269 __set_h_errno (herrno); \
270 _res.options |= old_res_options & RES_USE_INET6; \
271 result = -EAI_SYSTEM; \
272 goto free_and_return; \
274 if (herrno == TRY_AGAIN) \
275 no_data = EAI_AGAIN; \
276 else \
277 no_data = herrno == NO_DATA; \
279 else if (h != NULL) \
281 /* Make sure that addrmem can be freed. */ \
282 if (!malloc_addrmem) \
283 addrmem = NULL; \
284 if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \
286 _res.options |= old_res_options & RES_USE_INET6; \
287 result = -EAI_SYSTEM; \
288 goto free_and_return; \
290 *pat = addrmem; \
291 /* The conversion uses malloc unconditionally. */ \
292 malloc_addrmem = true; \
294 if (localcanon != NULL && canon == NULL) \
295 canon = strdupa (localcanon); \
297 if (_family == AF_INET6 && *pat != NULL) \
298 got_ipv6 = true; \
303 typedef enum nss_status (*nss_gethostbyname4_r)
304 (const char *name, struct gaih_addrtuple **pat,
305 char *buffer, size_t buflen, int *errnop,
306 int *h_errnop, int32_t *ttlp);
307 typedef enum nss_status (*nss_gethostbyname3_r)
308 (const char *name, int af, struct hostent *host,
309 char *buffer, size_t buflen, int *errnop,
310 int *h_errnop, int32_t *ttlp, char **canonp);
311 typedef enum nss_status (*nss_getcanonname_r)
312 (const char *name, char *buffer, size_t buflen, char **result,
313 int *errnop, int *h_errnop);
314 extern service_user *__nss_hosts_database attribute_hidden;
317 static int
318 gaih_inet (const char *name, const struct gaih_service *service,
319 const struct addrinfo *req, struct addrinfo **pai,
320 unsigned int *naddrs, struct scratch_buffer *tmpbuf)
322 const struct gaih_typeproto *tp = gaih_inet_typeproto;
323 struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
324 struct gaih_addrtuple *at = NULL;
325 int rc;
326 bool got_ipv6 = false;
327 const char *canon = NULL;
328 const char *orig_name = name;
330 /* Reserve stack memory for the scratch buffer in the getaddrinfo
331 function. */
332 size_t alloca_used = sizeof (struct scratch_buffer);
334 if (req->ai_protocol || req->ai_socktype)
336 ++tp;
338 while (tp->name[0]
339 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
340 || (req->ai_protocol != 0
341 && !(tp->protoflag & GAI_PROTO_PROTOANY)
342 && req->ai_protocol != tp->protocol)))
343 ++tp;
345 if (! tp->name[0])
347 if (req->ai_socktype)
348 return -EAI_SOCKTYPE;
349 else
350 return -EAI_SERVICE;
354 int port = 0;
355 if (service != NULL)
357 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
358 return -EAI_SERVICE;
360 if (service->num < 0)
362 if (tp->name[0])
364 st = (struct gaih_servtuple *)
365 alloca_account (sizeof (struct gaih_servtuple), alloca_used);
367 if ((rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf)))
368 return rc;
370 else
372 struct gaih_servtuple **pst = &st;
373 for (tp++; tp->name[0]; tp++)
375 struct gaih_servtuple *newp;
377 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
378 continue;
380 if (req->ai_socktype != 0
381 && req->ai_socktype != tp->socktype)
382 continue;
383 if (req->ai_protocol != 0
384 && !(tp->protoflag & GAI_PROTO_PROTOANY)
385 && req->ai_protocol != tp->protocol)
386 continue;
388 newp = (struct gaih_servtuple *)
389 alloca_account (sizeof (struct gaih_servtuple),
390 alloca_used);
392 if ((rc = gaih_inet_serv (service->name,
393 tp, req, newp, tmpbuf)))
395 if (rc)
396 continue;
397 return rc;
400 *pst = newp;
401 pst = &(newp->next);
403 if (st == (struct gaih_servtuple *) &nullserv)
404 return -EAI_SERVICE;
407 else
409 port = htons (service->num);
410 goto got_port;
413 else
415 got_port:
417 if (req->ai_socktype || req->ai_protocol)
419 st = alloca_account (sizeof (struct gaih_servtuple), alloca_used);
420 st->next = NULL;
421 st->socktype = tp->socktype;
422 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
423 ? req->ai_protocol : tp->protocol);
424 st->port = port;
426 else
428 /* Neither socket type nor protocol is set. Return all socket types
429 we know about. */
430 struct gaih_servtuple **lastp = &st;
431 for (++tp; tp->name[0]; ++tp)
432 if (tp->defaultflag)
434 struct gaih_servtuple *newp;
436 newp = alloca_account (sizeof (struct gaih_servtuple),
437 alloca_used);
438 newp->next = NULL;
439 newp->socktype = tp->socktype;
440 newp->protocol = tp->protocol;
441 newp->port = port;
443 *lastp = newp;
444 lastp = &newp->next;
449 bool malloc_name = false;
450 bool malloc_addrmem = false;
451 struct gaih_addrtuple *addrmem = NULL;
452 bool malloc_canonbuf = false;
453 char *canonbuf = NULL;
454 int result = 0;
456 if (name != NULL)
458 at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
459 at->family = AF_UNSPEC;
460 at->scopeid = 0;
461 at->next = NULL;
463 #ifdef HAVE_LIBIDN
464 if (req->ai_flags & AI_IDN)
466 int idn_flags = 0;
467 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
468 idn_flags |= IDNA_ALLOW_UNASSIGNED;
469 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
470 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
472 char *p = NULL;
473 rc = __idna_to_ascii_lz (name, &p, idn_flags);
474 if (rc != IDNA_SUCCESS)
476 /* No need to jump to free_and_return here. */
477 if (rc == IDNA_MALLOC_ERROR)
478 return -EAI_MEMORY;
479 if (rc == IDNA_DLOPEN_ERROR)
480 return -EAI_SYSTEM;
481 return -EAI_IDN_ENCODE;
483 /* In case the output string is the same as the input string
484 no new string has been allocated. */
485 if (p != name)
487 name = p;
488 malloc_name = true;
491 #endif
493 if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
495 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
496 at->family = AF_INET;
497 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
499 at->addr[3] = at->addr[0];
500 at->addr[2] = htonl (0xffff);
501 at->addr[1] = 0;
502 at->addr[0] = 0;
503 at->family = AF_INET6;
505 else
507 result = -EAI_ADDRFAMILY;
508 goto free_and_return;
511 if (req->ai_flags & AI_CANONNAME)
512 canon = name;
514 else if (at->family == AF_UNSPEC)
516 char *scope_delim = strchr (name, SCOPE_DELIMITER);
517 int e;
520 bool malloc_namebuf = false;
521 char *namebuf = (char *) name;
523 if (__glibc_unlikely (scope_delim != NULL))
525 if (malloc_name)
526 *scope_delim = '\0';
527 else
529 if (__libc_use_alloca (alloca_used
530 + scope_delim - name + 1))
532 namebuf = alloca_account (scope_delim - name + 1,
533 alloca_used);
534 *((char *) __mempcpy (namebuf, name,
535 scope_delim - name)) = '\0';
537 else
539 namebuf = strndup (name, scope_delim - name);
540 if (namebuf == NULL)
542 assert (!malloc_name);
543 return -EAI_MEMORY;
545 malloc_namebuf = true;
550 e = inet_pton (AF_INET6, namebuf, at->addr);
552 if (malloc_namebuf)
553 free (namebuf);
554 else if (scope_delim != NULL && malloc_name)
555 /* Undo what we did above. */
556 *scope_delim = SCOPE_DELIMITER;
558 if (e > 0)
560 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
561 at->family = AF_INET6;
562 else if (req->ai_family == AF_INET
563 && IN6_IS_ADDR_V4MAPPED (at->addr))
565 at->addr[0] = at->addr[3];
566 at->family = AF_INET;
568 else
570 result = -EAI_ADDRFAMILY;
571 goto free_and_return;
574 if (scope_delim != NULL
575 && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
576 scope_delim + 1,
577 &at->scopeid) != 0)
579 result = -EAI_NONAME;
580 goto free_and_return;
583 if (req->ai_flags & AI_CANONNAME)
584 canon = name;
588 if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
590 struct gaih_addrtuple **pat = &at;
591 int no_data = 0;
592 int no_inet6_data = 0;
593 service_user *nip;
594 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
595 enum nss_status status = NSS_STATUS_UNAVAIL;
596 int no_more;
597 int old_res_options;
599 /* If we do not have to look for IPv6 addresses or the canonical
600 name, use the simple, old functions, which do not support
601 IPv6 scope ids, nor retrieving the canonical name. */
602 if (req->ai_family == AF_INET
603 && (req->ai_flags & AI_CANONNAME) == 0)
605 int rc;
606 struct hostent th;
607 struct hostent *h;
608 int herrno;
610 while (1)
612 rc = __gethostbyname2_r (name, AF_INET, &th,
613 tmpbuf->data, tmpbuf->length,
614 &h, &herrno);
615 if (rc != ERANGE || herrno != NETDB_INTERNAL)
616 break;
617 if (!scratch_buffer_grow (tmpbuf))
619 result = -EAI_MEMORY;
620 goto free_and_return;
624 if (rc == 0)
626 if (h != NULL)
628 /* We found data, convert it. */
629 if (!convert_hostent_to_gaih_addrtuple
630 (req, AF_INET, h, &addrmem))
632 result = -EAI_MEMORY;
633 goto free_and_return;
635 *pat = addrmem;
636 /* The conversion uses malloc unconditionally. */
637 malloc_addrmem = true;
640 else
642 if (herrno == NETDB_INTERNAL)
644 __set_h_errno (herrno);
645 result = -EAI_SYSTEM;
647 else if (herrno == TRY_AGAIN)
648 result = -EAI_AGAIN;
649 else
650 /* We made requests but they turned out no data.
651 The name is known, though. */
652 result = -EAI_NODATA;
654 goto free_and_return;
657 goto process_list;
660 #ifdef USE_NSCD
661 if (__nss_not_use_nscd_hosts > 0
662 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
663 __nss_not_use_nscd_hosts = 0;
665 if (!__nss_not_use_nscd_hosts
666 && !__nss_database_custom[NSS_DBSIDX_hosts])
668 /* Try to use nscd. */
669 struct nscd_ai_result *air = NULL;
670 int herrno;
671 int err = __nscd_getai (name, &air, &herrno);
672 if (air != NULL)
674 /* Transform into gaih_addrtuple list. */
675 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
676 char *addrs = air->addrs;
678 if (__libc_use_alloca (alloca_used
679 + air->naddrs * sizeof (struct gaih_addrtuple)))
680 addrmem = alloca_account (air->naddrs
681 * sizeof (struct gaih_addrtuple),
682 alloca_used);
683 else
685 addrmem = malloc (air->naddrs
686 * sizeof (struct gaih_addrtuple));
687 if (addrmem == NULL)
689 result = -EAI_MEMORY;
690 goto free_and_return;
692 malloc_addrmem = true;
695 struct gaih_addrtuple *addrfree = addrmem;
696 for (int i = 0; i < air->naddrs; ++i)
698 socklen_t size = (air->family[i] == AF_INET
699 ? INADDRSZ : IN6ADDRSZ);
701 if (!((air->family[i] == AF_INET
702 && req->ai_family == AF_INET6
703 && (req->ai_flags & AI_V4MAPPED) != 0)
704 || req->ai_family == AF_UNSPEC
705 || air->family[i] == req->ai_family))
707 /* Skip over non-matching result. */
708 addrs += size;
709 continue;
712 if (*pat == NULL)
714 *pat = addrfree++;
715 (*pat)->scopeid = 0;
717 uint32_t *pataddr = (*pat)->addr;
718 (*pat)->next = NULL;
719 if (added_canon || air->canon == NULL)
720 (*pat)->name = NULL;
721 else if (canonbuf == NULL)
723 size_t canonlen = strlen (air->canon) + 1;
724 if ((req->ai_flags & AI_CANONIDN) != 0
725 && __libc_use_alloca (alloca_used + canonlen))
726 canonbuf = alloca_account (canonlen, alloca_used);
727 else
729 canonbuf = malloc (canonlen);
730 if (canonbuf == NULL)
732 result = -EAI_MEMORY;
733 goto free_and_return;
735 malloc_canonbuf = true;
737 canon = (*pat)->name = memcpy (canonbuf, air->canon,
738 canonlen);
741 if (air->family[i] == AF_INET
742 && req->ai_family == AF_INET6
743 && (req->ai_flags & AI_V4MAPPED))
745 (*pat)->family = AF_INET6;
746 pataddr[3] = *(uint32_t *) addrs;
747 pataddr[2] = htonl (0xffff);
748 pataddr[1] = 0;
749 pataddr[0] = 0;
750 pat = &((*pat)->next);
751 added_canon = true;
753 else if (req->ai_family == AF_UNSPEC
754 || air->family[i] == req->ai_family)
756 (*pat)->family = air->family[i];
757 memcpy (pataddr, addrs, size);
758 pat = &((*pat)->next);
759 added_canon = true;
760 if (air->family[i] == AF_INET6)
761 got_ipv6 = true;
763 addrs += size;
766 free (air);
768 if (at->family == AF_UNSPEC)
770 result = -EAI_NONAME;
771 goto free_and_return;
774 goto process_list;
776 else if (err == 0)
777 /* The database contains a negative entry. */
778 goto free_and_return;
779 else if (__nss_not_use_nscd_hosts == 0)
781 if (herrno == NETDB_INTERNAL && errno == ENOMEM)
782 result = -EAI_MEMORY;
783 else if (herrno == TRY_AGAIN)
784 result = -EAI_AGAIN;
785 else
786 result = -EAI_SYSTEM;
788 goto free_and_return;
791 #endif
793 if (__nss_hosts_database == NULL)
794 no_more = __nss_database_lookup ("hosts", NULL,
795 "dns [!UNAVAIL=return] files",
796 &__nss_hosts_database);
797 else
798 no_more = 0;
799 nip = __nss_hosts_database;
801 /* Initialize configurations. */
802 _res_hconf_init ();
803 if (__res_maybe_init (&_res, 0) == -1)
804 no_more = 1;
806 /* If we are looking for both IPv4 and IPv6 address we don't
807 want the lookup functions to automatically promote IPv4
808 addresses to IPv6 addresses. Currently this is decided
809 by setting the RES_USE_INET6 bit in _res.options. */
810 old_res_options = _res.options;
811 _res.options &= ~RES_USE_INET6;
813 while (!no_more)
815 no_data = 0;
816 nss_gethostbyname4_r fct4 = NULL;
818 /* gethostbyname4_r sends out parallel A and AAAA queries and
819 is thus only suitable for PF_UNSPEC. */
820 if (req->ai_family == PF_UNSPEC)
821 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
823 if (fct4 != NULL)
825 int herrno;
827 while (1)
829 rc = 0;
830 status = DL_CALL_FCT (fct4, (name, pat,
831 tmpbuf->data, tmpbuf->length,
832 &rc, &herrno,
833 NULL));
834 if (status == NSS_STATUS_SUCCESS)
835 break;
836 if (status != NSS_STATUS_TRYAGAIN
837 || rc != ERANGE || herrno != NETDB_INTERNAL)
839 if (herrno == TRY_AGAIN)
840 no_data = EAI_AGAIN;
841 else
842 no_data = herrno == NO_DATA;
843 break;
846 if (!scratch_buffer_grow (tmpbuf))
848 _res.options |= old_res_options & RES_USE_INET6;
849 result = -EAI_MEMORY;
850 goto free_and_return;
854 if (status == NSS_STATUS_SUCCESS)
856 assert (!no_data);
857 no_data = 1;
859 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
860 canon = (*pat)->name;
862 while (*pat != NULL)
864 if ((*pat)->family == AF_INET
865 && req->ai_family == AF_INET6
866 && (req->ai_flags & AI_V4MAPPED) != 0)
868 uint32_t *pataddr = (*pat)->addr;
869 (*pat)->family = AF_INET6;
870 pataddr[3] = pataddr[0];
871 pataddr[2] = htonl (0xffff);
872 pataddr[1] = 0;
873 pataddr[0] = 0;
874 pat = &((*pat)->next);
875 no_data = 0;
877 else if (req->ai_family == AF_UNSPEC
878 || (*pat)->family == req->ai_family)
880 pat = &((*pat)->next);
882 no_data = 0;
883 if (req->ai_family == AF_INET6)
884 got_ipv6 = true;
886 else
887 *pat = ((*pat)->next);
891 no_inet6_data = no_data;
893 else
895 nss_gethostbyname3_r fct = NULL;
896 if (req->ai_flags & AI_CANONNAME)
897 /* No need to use this function if we do not look for
898 the canonical name. The function does not exist in
899 all NSS modules and therefore the lookup would
900 often fail. */
901 fct = __nss_lookup_function (nip, "gethostbyname3_r");
902 if (fct == NULL)
903 /* We are cheating here. The gethostbyname2_r
904 function does not have the same interface as
905 gethostbyname3_r but the extra arguments the
906 latter takes are added at the end. So the
907 gethostbyname2_r code will just ignore them. */
908 fct = __nss_lookup_function (nip, "gethostbyname2_r");
910 if (fct != NULL)
912 if (req->ai_family == AF_INET6
913 || req->ai_family == AF_UNSPEC)
915 gethosts (AF_INET6, struct in6_addr);
916 no_inet6_data = no_data;
917 inet6_status = status;
919 if (req->ai_family == AF_INET
920 || req->ai_family == AF_UNSPEC
921 || (req->ai_family == AF_INET6
922 && (req->ai_flags & AI_V4MAPPED)
923 /* Avoid generating the mapped addresses if we
924 know we are not going to need them. */
925 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
927 gethosts (AF_INET, struct in_addr);
929 if (req->ai_family == AF_INET)
931 no_inet6_data = no_data;
932 inet6_status = status;
936 /* If we found one address for AF_INET or AF_INET6,
937 don't continue the search. */
938 if (inet6_status == NSS_STATUS_SUCCESS
939 || status == NSS_STATUS_SUCCESS)
941 if ((req->ai_flags & AI_CANONNAME) != 0
942 && canon == NULL)
944 /* If we need the canonical name, get it
945 from the same service as the result. */
946 nss_getcanonname_r cfct;
947 int herrno;
949 cfct = __nss_lookup_function (nip,
950 "getcanonname_r");
951 if (cfct != NULL)
953 const size_t max_fqdn_len = 256;
954 if ((req->ai_flags & AI_CANONIDN) != 0
955 && __libc_use_alloca (alloca_used
956 + max_fqdn_len))
957 canonbuf = alloca_account (max_fqdn_len,
958 alloca_used);
959 else
961 canonbuf = malloc (max_fqdn_len);
962 if (canonbuf == NULL)
964 _res.options
965 |= old_res_options & RES_USE_INET6;
966 result = -EAI_MEMORY;
967 goto free_and_return;
969 malloc_canonbuf = true;
971 char *s;
973 if (DL_CALL_FCT (cfct, (at->name ?: name,
974 canonbuf,
975 max_fqdn_len,
976 &s, &rc, &herrno))
977 == NSS_STATUS_SUCCESS)
978 canon = s;
979 else
981 /* If the canonical name cannot be
982 determined, use the passed in
983 string. */
984 if (malloc_canonbuf)
986 free (canonbuf);
987 malloc_canonbuf = false;
989 canon = name;
993 status = NSS_STATUS_SUCCESS;
995 else
997 /* We can have different states for AF_INET and
998 AF_INET6. Try to find a useful one for both. */
999 if (inet6_status == NSS_STATUS_TRYAGAIN)
1000 status = NSS_STATUS_TRYAGAIN;
1001 else if (status == NSS_STATUS_UNAVAIL
1002 && inet6_status != NSS_STATUS_UNAVAIL)
1003 status = inet6_status;
1006 else
1008 status = NSS_STATUS_UNAVAIL;
1009 /* Could not load any of the lookup functions. Indicate
1010 an internal error if the failure was due to a system
1011 error other than the file not being found. We use the
1012 errno from the last failed callback. */
1013 if (errno != 0 && errno != ENOENT)
1014 __set_h_errno (NETDB_INTERNAL);
1018 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
1019 break;
1021 if (nip->next == NULL)
1022 no_more = -1;
1023 else
1024 nip = nip->next;
1027 _res.options |= old_res_options & RES_USE_INET6;
1029 if (h_errno == NETDB_INTERNAL)
1031 result = -EAI_SYSTEM;
1032 goto free_and_return;
1035 if (no_data != 0 && no_inet6_data != 0)
1037 /* If both requests timed out report this. */
1038 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
1039 result = -EAI_AGAIN;
1040 else
1041 /* We made requests but they turned out no data. The name
1042 is known, though. */
1043 result = -EAI_NODATA;
1045 goto free_and_return;
1049 process_list:
1050 if (at->family == AF_UNSPEC)
1052 result = -EAI_NONAME;
1053 goto free_and_return;
1056 else
1058 struct gaih_addrtuple *atr;
1059 atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
1060 memset (at, '\0', sizeof (struct gaih_addrtuple));
1062 if (req->ai_family == AF_UNSPEC)
1064 at->next = __alloca (sizeof (struct gaih_addrtuple));
1065 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
1068 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
1070 at->family = AF_INET6;
1071 if ((req->ai_flags & AI_PASSIVE) == 0)
1072 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
1073 atr = at->next;
1076 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
1078 atr->family = AF_INET;
1079 if ((req->ai_flags & AI_PASSIVE) == 0)
1080 atr->addr[0] = htonl (INADDR_LOOPBACK);
1085 struct gaih_servtuple *st2;
1086 struct gaih_addrtuple *at2 = at;
1087 size_t socklen;
1088 sa_family_t family;
1091 buffer is the size of an unformatted IPv6 address in printable format.
1093 while (at2 != NULL)
1095 /* Only the first entry gets the canonical name. */
1096 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
1098 if (canon == NULL)
1099 /* If the canonical name cannot be determined, use
1100 the passed in string. */
1101 canon = orig_name;
1103 #ifdef HAVE_LIBIDN
1104 if (req->ai_flags & AI_CANONIDN)
1106 int idn_flags = 0;
1107 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
1108 idn_flags |= IDNA_ALLOW_UNASSIGNED;
1109 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
1110 idn_flags |= IDNA_USE_STD3_ASCII_RULES;
1112 char *out;
1113 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
1114 if (rc != IDNA_SUCCESS)
1116 if (rc == IDNA_MALLOC_ERROR)
1117 result = -EAI_MEMORY;
1118 else if (rc == IDNA_DLOPEN_ERROR)
1119 result = -EAI_SYSTEM;
1120 else
1121 result = -EAI_IDN_ENCODE;
1122 goto free_and_return;
1124 /* In case the output string is the same as the input
1125 string no new string has been allocated and we
1126 make a copy. */
1127 if (out == canon)
1128 goto make_copy;
1129 canon = out;
1131 else
1132 #endif
1134 #ifdef HAVE_LIBIDN
1135 make_copy:
1136 #endif
1137 if (malloc_canonbuf)
1138 /* We already allocated the string using malloc. */
1139 malloc_canonbuf = false;
1140 else
1142 canon = strdup (canon);
1143 if (canon == NULL)
1145 result = -EAI_MEMORY;
1146 goto free_and_return;
1152 family = at2->family;
1153 if (family == AF_INET6)
1155 socklen = sizeof (struct sockaddr_in6);
1157 /* If we looked up IPv4 mapped address discard them here if
1158 the caller isn't interested in all address and we have
1159 found at least one IPv6 address. */
1160 if (got_ipv6
1161 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1162 && IN6_IS_ADDR_V4MAPPED (at2->addr))
1163 goto ignore;
1165 else
1166 socklen = sizeof (struct sockaddr_in);
1168 for (st2 = st; st2 != NULL; st2 = st2->next)
1170 struct addrinfo *ai;
1171 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1172 if (ai == NULL)
1174 free ((char *) canon);
1175 result = -EAI_MEMORY;
1176 goto free_and_return;
1179 ai->ai_flags = req->ai_flags;
1180 ai->ai_family = family;
1181 ai->ai_socktype = st2->socktype;
1182 ai->ai_protocol = st2->protocol;
1183 ai->ai_addrlen = socklen;
1184 ai->ai_addr = (void *) (ai + 1);
1186 /* We only add the canonical name once. */
1187 ai->ai_canonname = (char *) canon;
1188 canon = NULL;
1190 #ifdef _HAVE_SA_LEN
1191 ai->ai_addr->sa_len = socklen;
1192 #endif /* _HAVE_SA_LEN */
1193 ai->ai_addr->sa_family = family;
1195 /* In case of an allocation error the list must be NULL
1196 terminated. */
1197 ai->ai_next = NULL;
1199 if (family == AF_INET6)
1201 struct sockaddr_in6 *sin6p =
1202 (struct sockaddr_in6 *) ai->ai_addr;
1204 sin6p->sin6_port = st2->port;
1205 sin6p->sin6_flowinfo = 0;
1206 memcpy (&sin6p->sin6_addr,
1207 at2->addr, sizeof (struct in6_addr));
1208 sin6p->sin6_scope_id = at2->scopeid;
1210 else
1212 struct sockaddr_in *sinp =
1213 (struct sockaddr_in *) ai->ai_addr;
1214 sinp->sin_port = st2->port;
1215 memcpy (&sinp->sin_addr,
1216 at2->addr, sizeof (struct in_addr));
1217 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1220 pai = &(ai->ai_next);
1223 ++*naddrs;
1225 ignore:
1226 at2 = at2->next;
1230 free_and_return:
1231 if (malloc_name)
1232 free ((char *) name);
1233 if (malloc_addrmem)
1234 free (addrmem);
1235 if (malloc_canonbuf)
1236 free (canonbuf);
1238 return result;
1242 struct sort_result
1244 struct addrinfo *dest_addr;
1245 /* Using sockaddr_storage is for now overkill. We only support IPv4
1246 and IPv6 so far. If this changes at some point we can adjust the
1247 type here. */
1248 struct sockaddr_in6 source_addr;
1249 uint8_t source_addr_len;
1250 bool got_source_addr;
1251 uint8_t source_addr_flags;
1252 uint8_t prefixlen;
1253 uint32_t index;
1254 int32_t native;
1257 struct sort_result_combo
1259 struct sort_result *results;
1260 int nresults;
1264 #if __BYTE_ORDER == __BIG_ENDIAN
1265 # define htonl_c(n) n
1266 #else
1267 # define htonl_c(n) __bswap_constant_32 (n)
1268 #endif
1270 static const struct scopeentry
1272 union
1274 char addr[4];
1275 uint32_t addr32;
1277 uint32_t netmask;
1278 int32_t scope;
1279 } default_scopes[] =
1281 /* Link-local addresses: scope 2. */
1282 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1283 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1284 /* Default: scope 14. */
1285 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1288 /* The label table. */
1289 static const struct scopeentry *scopes;
1292 static int
1293 get_scope (const struct sockaddr_in6 *in6)
1295 int scope;
1296 if (in6->sin6_family == PF_INET6)
1298 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1300 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1301 /* RFC 4291 2.5.3 says that the loopback address is to be
1302 treated like a link-local address. */
1303 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1304 scope = 2;
1305 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1306 scope = 5;
1307 else
1308 /* XXX Is this the correct default behavior? */
1309 scope = 14;
1311 else
1312 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1314 else if (in6->sin6_family == PF_INET)
1316 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1318 size_t cnt = 0;
1319 while (1)
1321 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1322 == scopes[cnt].addr32)
1323 return scopes[cnt].scope;
1325 ++cnt;
1327 /* NOTREACHED */
1329 else
1330 /* XXX What is a good default? */
1331 scope = 15;
1333 return scope;
1337 struct prefixentry
1339 struct in6_addr prefix;
1340 unsigned int bits;
1341 int val;
1345 /* The label table. */
1346 static const struct prefixentry *labels;
1348 /* Default labels. */
1349 static const struct prefixentry default_labels[] =
1351 /* See RFC 3484 for the details. */
1352 { { .__in6_u
1353 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1355 }, 128, 0 },
1356 { { .__in6_u
1357 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1359 }, 16, 2 },
1360 { { .__in6_u
1361 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1363 }, 96, 3 },
1364 { { .__in6_u
1365 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1366 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1367 }, 96, 4 },
1368 /* The next two entries differ from RFC 3484. We need to treat
1369 IPv6 site-local addresses special because they are never NATed,
1370 unlike site-locale IPv4 addresses. If this would not happen, on
1371 machines which have only IPv4 and IPv6 site-local addresses, the
1372 sorting would prefer the IPv6 site-local addresses, causing
1373 unnecessary delays when trying to connect to a global IPv6 address
1374 through a site-local IPv6 address. */
1375 { { .__in6_u
1376 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1378 }, 10, 5 },
1379 { { .__in6_u
1380 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1382 }, 7, 6 },
1383 /* Additional rule for Teredo tunnels. */
1384 { { .__in6_u
1385 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1387 }, 32, 7 },
1388 { { .__in6_u
1389 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1391 }, 0, 1 }
1395 /* The precedence table. */
1396 static const struct prefixentry *precedence;
1398 /* The default precedences. */
1399 static const struct prefixentry default_precedence[] =
1401 /* See RFC 3484 for the details. */
1402 { { .__in6_u
1403 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1405 }, 128, 50 },
1406 { { .__in6_u
1407 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1409 }, 16, 30 },
1410 { { .__in6_u
1411 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1412 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1413 }, 96, 20 },
1414 { { .__in6_u
1415 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1416 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1417 }, 96, 10 },
1418 { { .__in6_u
1419 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1421 }, 0, 40 }
1425 static int
1426 match_prefix (const struct sockaddr_in6 *in6,
1427 const struct prefixentry *list, int default_val)
1429 int idx;
1430 struct sockaddr_in6 in6_mem;
1432 if (in6->sin6_family == PF_INET)
1434 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1436 /* Construct a V4-to-6 mapped address. */
1437 in6_mem.sin6_family = PF_INET6;
1438 in6_mem.sin6_port = in->sin_port;
1439 in6_mem.sin6_flowinfo = 0;
1440 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1441 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1442 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1443 in6_mem.sin6_scope_id = 0;
1445 in6 = &in6_mem;
1447 else if (in6->sin6_family != PF_INET6)
1448 return default_val;
1450 for (idx = 0; ; ++idx)
1452 unsigned int bits = list[idx].bits;
1453 const uint8_t *mask = list[idx].prefix.s6_addr;
1454 const uint8_t *val = in6->sin6_addr.s6_addr;
1456 while (bits >= 8)
1458 if (*mask != *val)
1459 break;
1461 ++mask;
1462 ++val;
1463 bits -= 8;
1466 if (bits < 8)
1468 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1469 /* Match! */
1470 break;
1474 return list[idx].val;
1478 static int
1479 get_label (const struct sockaddr_in6 *in6)
1481 /* XXX What is a good default value? */
1482 return match_prefix (in6, labels, INT_MAX);
1486 static int
1487 get_precedence (const struct sockaddr_in6 *in6)
1489 /* XXX What is a good default value? */
1490 return match_prefix (in6, precedence, 0);
1494 /* Find last bit set in a word. */
1495 static int
1496 fls (uint32_t a)
1498 uint32_t mask;
1499 int n;
1500 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1501 if ((a & mask) != 0)
1502 break;
1503 return n;
1507 static int
1508 rfc3484_sort (const void *p1, const void *p2, void *arg)
1510 const size_t idx1 = *(const size_t *) p1;
1511 const size_t idx2 = *(const size_t *) p2;
1512 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1513 struct sort_result *a1 = &src->results[idx1];
1514 struct sort_result *a2 = &src->results[idx2];
1516 /* Rule 1: Avoid unusable destinations.
1517 We have the got_source_addr flag set if the destination is reachable. */
1518 if (a1->got_source_addr && ! a2->got_source_addr)
1519 return -1;
1520 if (! a1->got_source_addr && a2->got_source_addr)
1521 return 1;
1524 /* Rule 2: Prefer matching scope. Only interesting if both
1525 destination addresses are IPv6. */
1526 int a1_dst_scope
1527 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1529 int a2_dst_scope
1530 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1532 if (a1->got_source_addr)
1534 int a1_src_scope = get_scope (&a1->source_addr);
1535 int a2_src_scope = get_scope (&a2->source_addr);
1537 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1538 return -1;
1539 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1540 return 1;
1544 /* Rule 3: Avoid deprecated addresses. */
1545 if (a1->got_source_addr)
1547 if (!(a1->source_addr_flags & in6ai_deprecated)
1548 && (a2->source_addr_flags & in6ai_deprecated))
1549 return -1;
1550 if ((a1->source_addr_flags & in6ai_deprecated)
1551 && !(a2->source_addr_flags & in6ai_deprecated))
1552 return 1;
1555 /* Rule 4: Prefer home addresses. */
1556 if (a1->got_source_addr)
1558 if (!(a1->source_addr_flags & in6ai_homeaddress)
1559 && (a2->source_addr_flags & in6ai_homeaddress))
1560 return 1;
1561 if ((a1->source_addr_flags & in6ai_homeaddress)
1562 && !(a2->source_addr_flags & in6ai_homeaddress))
1563 return -1;
1566 /* Rule 5: Prefer matching label. */
1567 if (a1->got_source_addr)
1569 int a1_dst_label
1570 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1571 int a1_src_label = get_label (&a1->source_addr);
1573 int a2_dst_label
1574 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1575 int a2_src_label = get_label (&a2->source_addr);
1577 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1578 return -1;
1579 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1580 return 1;
1584 /* Rule 6: Prefer higher precedence. */
1585 int a1_prec
1586 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1587 int a2_prec
1588 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1590 if (a1_prec > a2_prec)
1591 return -1;
1592 if (a1_prec < a2_prec)
1593 return 1;
1596 /* Rule 7: Prefer native transport. */
1597 if (a1->got_source_addr)
1599 /* The same interface index means the same interface which means
1600 there is no difference in transport. This should catch many
1601 (most?) cases. */
1602 if (a1->index != a2->index)
1604 int a1_native = a1->native;
1605 int a2_native = a2->native;
1607 if (a1_native == -1 || a2_native == -1)
1609 uint32_t a1_index;
1610 if (a1_native == -1)
1612 /* If we do not have the information use 'native' as
1613 the default. */
1614 a1_native = 0;
1615 a1_index = a1->index;
1617 else
1618 a1_index = 0xffffffffu;
1620 uint32_t a2_index;
1621 if (a2_native == -1)
1623 /* If we do not have the information use 'native' as
1624 the default. */
1625 a2_native = 0;
1626 a2_index = a2->index;
1628 else
1629 a2_index = 0xffffffffu;
1631 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1633 /* Fill in the results in all the records. */
1634 for (int i = 0; i < src->nresults; ++i)
1635 if (a1_index != -1 && src->results[i].index == a1_index)
1637 assert (src->results[i].native == -1
1638 || src->results[i].native == a1_native);
1639 src->results[i].native = a1_native;
1641 else if (a2_index != -1 && src->results[i].index == a2_index)
1643 assert (src->results[i].native == -1
1644 || src->results[i].native == a2_native);
1645 src->results[i].native = a2_native;
1649 if (a1_native && !a2_native)
1650 return -1;
1651 if (!a1_native && a2_native)
1652 return 1;
1657 /* Rule 8: Prefer smaller scope. */
1658 if (a1_dst_scope < a2_dst_scope)
1659 return -1;
1660 if (a1_dst_scope > a2_dst_scope)
1661 return 1;
1664 /* Rule 9: Use longest matching prefix. */
1665 if (a1->got_source_addr
1666 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1668 int bit1 = 0;
1669 int bit2 = 0;
1671 if (a1->dest_addr->ai_family == PF_INET)
1673 assert (a1->source_addr.sin6_family == PF_INET);
1674 assert (a2->source_addr.sin6_family == PF_INET);
1676 /* Outside of subnets, as defined by the network masks,
1677 common address prefixes for IPv4 addresses make no sense.
1678 So, define a non-zero value only if source and
1679 destination address are on the same subnet. */
1680 struct sockaddr_in *in1_dst
1681 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1682 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1683 struct sockaddr_in *in1_src
1684 = (struct sockaddr_in *) &a1->source_addr;
1685 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1686 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1688 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1689 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1691 struct sockaddr_in *in2_dst
1692 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1693 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1694 struct sockaddr_in *in2_src
1695 = (struct sockaddr_in *) &a2->source_addr;
1696 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1697 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1699 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1700 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1702 else if (a1->dest_addr->ai_family == PF_INET6)
1704 assert (a1->source_addr.sin6_family == PF_INET6);
1705 assert (a2->source_addr.sin6_family == PF_INET6);
1707 struct sockaddr_in6 *in1_dst;
1708 struct sockaddr_in6 *in1_src;
1709 struct sockaddr_in6 *in2_dst;
1710 struct sockaddr_in6 *in2_src;
1712 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1713 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1714 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1715 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1717 int i;
1718 for (i = 0; i < 4; ++i)
1719 if (in1_dst->sin6_addr.s6_addr32[i]
1720 != in1_src->sin6_addr.s6_addr32[i]
1721 || (in2_dst->sin6_addr.s6_addr32[i]
1722 != in2_src->sin6_addr.s6_addr32[i]))
1723 break;
1725 if (i < 4)
1727 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1728 ^ in1_src->sin6_addr.s6_addr32[i]));
1729 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1730 ^ in2_src->sin6_addr.s6_addr32[i]));
1734 if (bit1 > bit2)
1735 return -1;
1736 if (bit1 < bit2)
1737 return 1;
1741 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1742 compare with the value indicating the order in which the entries
1743 have been received from the services. NB: no two entries can have
1744 the same order so the test will never return zero. */
1745 return idx1 < idx2 ? -1 : 1;
1749 static int
1750 in6aicmp (const void *p1, const void *p2)
1752 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1753 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1755 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1759 /* Name of the config file for RFC 3484 sorting (for now). */
1760 #define GAICONF_FNAME "/etc/gai.conf"
1763 /* Non-zero if we are supposed to reload the config file automatically
1764 whenever it changed. */
1765 static int gaiconf_reload_flag;
1767 /* Non-zero if gaiconf_reload_flag was ever set to true. */
1768 static int gaiconf_reload_flag_ever_set;
1770 /* Last modification time. */
1771 #ifdef _STATBUF_ST_NSEC
1773 static struct timespec gaiconf_mtime;
1775 static inline void
1776 save_gaiconf_mtime (const struct stat64 *st)
1778 gaiconf_mtime = st->st_mtim;
1781 static inline bool
1782 check_gaiconf_mtime (const struct stat64 *st)
1784 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1785 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1788 #else
1790 static time_t gaiconf_mtime;
1792 static inline void
1793 save_gaiconf_mtime (const struct stat64 *st)
1795 gaiconf_mtime = st->st_mtime;
1798 static inline bool
1799 check_gaiconf_mtime (const struct stat64 *st)
1801 return st->st_mtime == gaiconf_mtime;
1804 #endif
1807 libc_freeres_fn(fini)
1809 if (labels != default_labels)
1811 const struct prefixentry *old = labels;
1812 labels = default_labels;
1813 free ((void *) old);
1816 if (precedence != default_precedence)
1818 const struct prefixentry *old = precedence;
1819 precedence = default_precedence;
1820 free ((void *) old);
1823 if (scopes != default_scopes)
1825 const struct scopeentry *old = scopes;
1826 scopes = default_scopes;
1827 free ((void *) old);
1832 struct prefixlist
1834 struct prefixentry entry;
1835 struct prefixlist *next;
1839 struct scopelist
1841 struct scopeentry entry;
1842 struct scopelist *next;
1846 static void
1847 free_prefixlist (struct prefixlist *list)
1849 while (list != NULL)
1851 struct prefixlist *oldp = list;
1852 list = list->next;
1853 free (oldp);
1858 static void
1859 free_scopelist (struct scopelist *list)
1861 while (list != NULL)
1863 struct scopelist *oldp = list;
1864 list = list->next;
1865 free (oldp);
1870 static int
1871 prefixcmp (const void *p1, const void *p2)
1873 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1874 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1876 if (e1->bits < e2->bits)
1877 return 1;
1878 if (e1->bits == e2->bits)
1879 return 0;
1880 return -1;
1884 static int
1885 scopecmp (const void *p1, const void *p2)
1887 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1888 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1890 if (e1->netmask > e2->netmask)
1891 return -1;
1892 if (e1->netmask == e2->netmask)
1893 return 0;
1894 return 1;
1898 static void
1899 gaiconf_init (void)
1901 struct prefixlist *labellist = NULL;
1902 size_t nlabellist = 0;
1903 bool labellist_nullbits = false;
1904 struct prefixlist *precedencelist = NULL;
1905 size_t nprecedencelist = 0;
1906 bool precedencelist_nullbits = false;
1907 struct scopelist *scopelist = NULL;
1908 size_t nscopelist = 0;
1909 bool scopelist_nullbits = false;
1911 FILE *fp = fopen (GAICONF_FNAME, "rce");
1912 if (fp != NULL)
1914 struct stat64 st;
1915 if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1917 fclose (fp);
1918 goto no_file;
1921 char *line = NULL;
1922 size_t linelen = 0;
1924 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1926 while (!feof_unlocked (fp))
1928 ssize_t n = __getline (&line, &linelen, fp);
1929 if (n <= 0)
1930 break;
1932 /* Handle comments. No escaping possible so this is easy. */
1933 char *cp = strchr (line, '#');
1934 if (cp != NULL)
1935 *cp = '\0';
1937 cp = line;
1938 while (isspace (*cp))
1939 ++cp;
1941 char *cmd = cp;
1942 while (*cp != '\0' && !isspace (*cp))
1943 ++cp;
1944 size_t cmdlen = cp - cmd;
1946 if (*cp != '\0')
1947 *cp++ = '\0';
1948 while (isspace (*cp))
1949 ++cp;
1951 char *val1 = cp;
1952 while (*cp != '\0' && !isspace (*cp))
1953 ++cp;
1954 size_t val1len = cp - cmd;
1956 /* We always need at least two values. */
1957 if (val1len == 0)
1958 continue;
1960 if (*cp != '\0')
1961 *cp++ = '\0';
1962 while (isspace (*cp))
1963 ++cp;
1965 char *val2 = cp;
1966 while (*cp != '\0' && !isspace (*cp))
1967 ++cp;
1969 /* Ignore the rest of the line. */
1970 *cp = '\0';
1972 struct prefixlist **listp;
1973 size_t *lenp;
1974 bool *nullbitsp;
1975 switch (cmdlen)
1977 case 5:
1978 if (strcmp (cmd, "label") == 0)
1980 struct in6_addr prefix;
1981 unsigned long int bits;
1982 unsigned long int val;
1983 char *endp;
1985 listp = &labellist;
1986 lenp = &nlabellist;
1987 nullbitsp = &labellist_nullbits;
1989 new_elem:
1990 bits = 128;
1991 __set_errno (0);
1992 cp = strchr (val1, '/');
1993 if (cp != NULL)
1994 *cp++ = '\0';
1995 if (inet_pton (AF_INET6, val1, &prefix)
1996 && (cp == NULL
1997 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1998 || errno != ERANGE)
1999 && *endp == '\0'
2000 && bits <= 128
2001 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2002 || errno != ERANGE)
2003 && *endp == '\0'
2004 && val <= INT_MAX)
2006 struct prefixlist *newp = malloc (sizeof (*newp));
2007 if (newp == NULL)
2009 free (line);
2010 fclose (fp);
2011 goto no_file;
2014 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
2015 newp->entry.bits = bits;
2016 newp->entry.val = val;
2017 newp->next = *listp;
2018 *listp = newp;
2019 ++*lenp;
2020 *nullbitsp |= bits == 0;
2023 break;
2025 case 6:
2026 if (strcmp (cmd, "reload") == 0)
2028 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
2029 if (gaiconf_reload_flag)
2030 gaiconf_reload_flag_ever_set = 1;
2032 break;
2034 case 7:
2035 if (strcmp (cmd, "scopev4") == 0)
2037 struct in6_addr prefix;
2038 unsigned long int bits;
2039 unsigned long int val;
2040 char *endp;
2042 bits = 32;
2043 __set_errno (0);
2044 cp = strchr (val1, '/');
2045 if (cp != NULL)
2046 *cp++ = '\0';
2047 if (inet_pton (AF_INET6, val1, &prefix))
2049 bits = 128;
2050 if (IN6_IS_ADDR_V4MAPPED (&prefix)
2051 && (cp == NULL
2052 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2053 || errno != ERANGE)
2054 && *endp == '\0'
2055 && bits >= 96
2056 && bits <= 128
2057 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2058 || errno != ERANGE)
2059 && *endp == '\0'
2060 && val <= INT_MAX)
2062 struct scopelist *newp;
2063 new_scope:
2064 newp = malloc (sizeof (*newp));
2065 if (newp == NULL)
2067 free (line);
2068 fclose (fp);
2069 goto no_file;
2072 newp->entry.netmask = htonl (bits != 96
2073 ? (0xffffffff
2074 << (128 - bits))
2075 : 0);
2076 newp->entry.addr32 = (prefix.s6_addr32[3]
2077 & newp->entry.netmask);
2078 newp->entry.scope = val;
2079 newp->next = scopelist;
2080 scopelist = newp;
2081 ++nscopelist;
2082 scopelist_nullbits |= bits == 96;
2085 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
2086 && (cp == NULL
2087 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2088 || errno != ERANGE)
2089 && *endp == '\0'
2090 && bits <= 32
2091 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2092 || errno != ERANGE)
2093 && *endp == '\0'
2094 && val <= INT_MAX)
2096 bits += 96;
2097 goto new_scope;
2100 break;
2102 case 10:
2103 if (strcmp (cmd, "precedence") == 0)
2105 listp = &precedencelist;
2106 lenp = &nprecedencelist;
2107 nullbitsp = &precedencelist_nullbits;
2108 goto new_elem;
2110 break;
2114 free (line);
2116 fclose (fp);
2118 /* Create the array for the labels. */
2119 struct prefixentry *new_labels;
2120 if (nlabellist > 0)
2122 if (!labellist_nullbits)
2123 ++nlabellist;
2124 new_labels = malloc (nlabellist * sizeof (*new_labels));
2125 if (new_labels == NULL)
2126 goto no_file;
2128 int i = nlabellist;
2129 if (!labellist_nullbits)
2131 --i;
2132 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2133 new_labels[i].bits = 0;
2134 new_labels[i].val = 1;
2137 struct prefixlist *l = labellist;
2138 while (i-- > 0)
2140 new_labels[i] = l->entry;
2141 l = l->next;
2143 free_prefixlist (labellist);
2145 /* Sort the entries so that the most specific ones are at
2146 the beginning. */
2147 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2149 else
2150 new_labels = (struct prefixentry *) default_labels;
2152 struct prefixentry *new_precedence;
2153 if (nprecedencelist > 0)
2155 if (!precedencelist_nullbits)
2156 ++nprecedencelist;
2157 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2158 if (new_precedence == NULL)
2160 if (new_labels != default_labels)
2161 free (new_labels);
2162 goto no_file;
2165 int i = nprecedencelist;
2166 if (!precedencelist_nullbits)
2168 --i;
2169 memset (&new_precedence[i].prefix, '\0',
2170 sizeof (struct in6_addr));
2171 new_precedence[i].bits = 0;
2172 new_precedence[i].val = 40;
2175 struct prefixlist *l = precedencelist;
2176 while (i-- > 0)
2178 new_precedence[i] = l->entry;
2179 l = l->next;
2181 free_prefixlist (precedencelist);
2183 /* Sort the entries so that the most specific ones are at
2184 the beginning. */
2185 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2186 prefixcmp);
2188 else
2189 new_precedence = (struct prefixentry *) default_precedence;
2191 struct scopeentry *new_scopes;
2192 if (nscopelist > 0)
2194 if (!scopelist_nullbits)
2195 ++nscopelist;
2196 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2197 if (new_scopes == NULL)
2199 if (new_labels != default_labels)
2200 free (new_labels);
2201 if (new_precedence != default_precedence)
2202 free (new_precedence);
2203 goto no_file;
2206 int i = nscopelist;
2207 if (!scopelist_nullbits)
2209 --i;
2210 new_scopes[i].addr32 = 0;
2211 new_scopes[i].netmask = 0;
2212 new_scopes[i].scope = 14;
2215 struct scopelist *l = scopelist;
2216 while (i-- > 0)
2218 new_scopes[i] = l->entry;
2219 l = l->next;
2221 free_scopelist (scopelist);
2223 /* Sort the entries so that the most specific ones are at
2224 the beginning. */
2225 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2226 scopecmp);
2228 else
2229 new_scopes = (struct scopeentry *) default_scopes;
2231 /* Now we are ready to replace the values. */
2232 const struct prefixentry *old = labels;
2233 labels = new_labels;
2234 if (old != default_labels)
2235 free ((void *) old);
2237 old = precedence;
2238 precedence = new_precedence;
2239 if (old != default_precedence)
2240 free ((void *) old);
2242 const struct scopeentry *oldscope = scopes;
2243 scopes = new_scopes;
2244 if (oldscope != default_scopes)
2245 free ((void *) oldscope);
2247 save_gaiconf_mtime (&st);
2249 else
2251 no_file:
2252 free_prefixlist (labellist);
2253 free_prefixlist (precedencelist);
2254 free_scopelist (scopelist);
2256 /* If we previously read the file but it is gone now, free the
2257 old data and use the builtin one. Leave the reload flag
2258 alone. */
2259 fini ();
2264 static void
2265 gaiconf_reload (void)
2267 struct stat64 st;
2268 if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2269 || !check_gaiconf_mtime (&st))
2270 gaiconf_init ();
2275 getaddrinfo (const char *name, const char *service,
2276 const struct addrinfo *hints, struct addrinfo **pai)
2278 int i = 0, last_i = 0;
2279 int nresults = 0;
2280 struct addrinfo *p = NULL;
2281 struct gaih_service gaih_service, *pservice;
2282 struct addrinfo local_hints;
2284 if (name != NULL && name[0] == '*' && name[1] == 0)
2285 name = NULL;
2287 if (service != NULL && service[0] == '*' && service[1] == 0)
2288 service = NULL;
2290 if (name == NULL && service == NULL)
2291 return EAI_NONAME;
2293 if (hints == NULL)
2294 hints = &default_hints;
2296 if (hints->ai_flags
2297 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2298 #ifdef HAVE_LIBIDN
2299 |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2300 |AI_IDN_USE_STD3_ASCII_RULES
2301 #endif
2302 |AI_NUMERICSERV|AI_ALL))
2303 return EAI_BADFLAGS;
2305 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2306 return EAI_BADFLAGS;
2308 struct in6addrinfo *in6ai = NULL;
2309 size_t in6ailen = 0;
2310 bool seen_ipv4 = false;
2311 bool seen_ipv6 = false;
2312 bool check_pf_called = false;
2314 if (hints->ai_flags & AI_ADDRCONFIG)
2316 /* We might need information about what interfaces are available.
2317 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2318 cannot cache the results since new interfaces could be added at
2319 any time. */
2320 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2321 check_pf_called = true;
2323 /* Now make a decision on what we return, if anything. */
2324 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2326 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2327 narrow down the search. */
2328 if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2330 local_hints = *hints;
2331 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2332 hints = &local_hints;
2335 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2336 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2338 /* We cannot possibly return a valid answer. */
2339 __free_in6ai (in6ai);
2340 return EAI_NONAME;
2344 if (service && service[0])
2346 char *c;
2347 gaih_service.name = service;
2348 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2349 if (*c != '\0')
2351 if (hints->ai_flags & AI_NUMERICSERV)
2353 __free_in6ai (in6ai);
2354 return EAI_NONAME;
2357 gaih_service.num = -1;
2360 pservice = &gaih_service;
2362 else
2363 pservice = NULL;
2365 struct addrinfo **end = &p;
2367 unsigned int naddrs = 0;
2368 if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2369 || hints->ai_family == AF_INET6)
2371 struct scratch_buffer tmpbuf;
2372 scratch_buffer_init (&tmpbuf);
2373 last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf);
2374 scratch_buffer_free (&tmpbuf);
2376 if (last_i != 0)
2378 freeaddrinfo (p);
2379 __free_in6ai (in6ai);
2381 return -last_i;
2383 while (*end)
2385 end = &((*end)->ai_next);
2386 ++nresults;
2389 else
2391 __free_in6ai (in6ai);
2392 return EAI_FAMILY;
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_retry:
2471 close_not_cancel_no_status (fd);
2472 af = q->ai_family;
2473 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2475 else
2477 /* Reset the connection. */
2478 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2479 __connect (fd, &sa, sizeof (sa));
2482 socklen_t sl = sizeof (results[i].source_addr);
2483 if (fd != -1
2484 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2485 && __getsockname (fd,
2486 (struct sockaddr *) &results[i].source_addr,
2487 &sl) == 0)
2489 results[i].source_addr_len = sl;
2490 results[i].got_source_addr = true;
2492 if (in6ai != NULL)
2494 /* See whether the source address is on the list of
2495 deprecated or temporary addresses. */
2496 struct in6addrinfo tmp;
2498 if (q->ai_family == AF_INET && af == AF_INET)
2500 struct sockaddr_in *sinp
2501 = (struct sockaddr_in *) &results[i].source_addr;
2502 tmp.addr[0] = 0;
2503 tmp.addr[1] = 0;
2504 tmp.addr[2] = htonl (0xffff);
2505 /* Special case for lo interface, the source address
2506 being possibly different than the interface
2507 address. */
2508 if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2509 == 0x7f000000)
2510 tmp.addr[3] = htonl(0x7f000001);
2511 else
2512 tmp.addr[3] = sinp->sin_addr.s_addr;
2514 else
2516 struct sockaddr_in6 *sin6p
2517 = (struct sockaddr_in6 *) &results[i].source_addr;
2518 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2521 struct in6addrinfo *found
2522 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2523 in6aicmp);
2524 if (found != NULL)
2526 results[i].source_addr_flags = found->flags;
2527 results[i].prefixlen = found->prefixlen;
2528 results[i].index = found->index;
2532 if (q->ai_family == AF_INET && af == AF_INET6)
2534 /* We have to convert the address. The socket is
2535 IPv6 and the request is for IPv4. */
2536 struct sockaddr_in6 *sin6
2537 = (struct sockaddr_in6 *) &results[i].source_addr;
2538 struct sockaddr_in *sin
2539 = (struct sockaddr_in *) &results[i].source_addr;
2540 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2541 sin->sin_family = AF_INET;
2542 /* We do not have to initialize sin_port since this
2543 fields has the same position and size in the IPv6
2544 structure. */
2545 assert (offsetof (struct sockaddr_in, sin_port)
2546 == offsetof (struct sockaddr_in6, sin6_port));
2547 assert (sizeof (sin->sin_port)
2548 == sizeof (sin6->sin6_port));
2549 memcpy (&sin->sin_addr,
2550 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2551 results[i].source_addr_len = sizeof (struct sockaddr_in);
2554 else if (errno == EAFNOSUPPORT && af == AF_INET6
2555 && q->ai_family == AF_INET)
2556 /* This could mean IPv6 sockets are IPv6-only. */
2557 goto close_retry;
2558 else
2559 /* Just make sure that if we have to process the same
2560 address again we do not copy any memory. */
2561 results[i].source_addr_len = 0;
2564 /* Remember the canonical name. */
2565 if (q->ai_canonname != NULL)
2567 assert (canonname == NULL);
2568 canonname = q->ai_canonname;
2569 q->ai_canonname = NULL;
2573 if (fd != -1)
2574 close_not_cancel_no_status (fd);
2576 /* We got all the source addresses we can get, now sort using
2577 the information. */
2578 struct sort_result_combo src
2579 = { .results = results, .nresults = nresults };
2580 if (__glibc_unlikely (gaiconf_reload_flag_ever_set))
2582 __libc_lock_define_initialized (static, lock);
2584 __libc_lock_lock (lock);
2585 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2586 gaiconf_reload ();
2587 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2588 __libc_lock_unlock (lock);
2590 else
2591 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2593 /* Queue the results up as they come out of sorting. */
2594 q = p = results[order[0]].dest_addr;
2595 for (i = 1; i < nresults; ++i)
2596 q = q->ai_next = results[order[i]].dest_addr;
2597 q->ai_next = NULL;
2599 /* Fill in the canonical name into the new first entry. */
2600 p->ai_canonname = canonname;
2602 if (malloc_results)
2603 free (results);
2606 __free_in6ai (in6ai);
2608 if (p)
2610 *pai = p;
2611 return 0;
2614 return last_i ? -last_i : EAI_NONAME;
2616 libc_hidden_def (getaddrinfo)
2618 nss_interface_function (getaddrinfo)
2620 void
2621 freeaddrinfo (struct addrinfo *ai)
2623 struct addrinfo *p;
2625 while (ai != NULL)
2627 p = ai;
2628 ai = ai->ai_next;
2629 free (p->ai_canonname);
2630 free (p);
2633 libc_hidden_def (freeaddrinfo)