1/* Host and service name lookups using Name Service Switch modules.
2 Copyright (C) 1996-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
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.
9
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.
14
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/>. */
18
19/* The Inner Net License, Version 2.00
20
21 The author(s) grant permission for redistribution and use in source and
22binary forms, with or without modification, of the software and documentation
23provided that the following conditions are met:
24
250. 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.
291. All terms of the all other applicable copyrights and licenses must be
30 followed.
312. Redistributions of source code must retain the authors' copyright
32 notice(s), this list of conditions, and the following disclaimer.
333. 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.
364. [The copyright holder has authorized the removal of this clause.]
375. 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.
40
41THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS ``AS IS'' AND ANY
42EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
45DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
48ANY 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
50SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51
52 If these license terms cause you a real problem, contact the author. */
53
54/* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */
55
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>
86
87/* Former AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES
88 flags, now ignored. */
89#define DEPRECATED_AI_IDN 0x300
90
91#if IS_IN (libc)
92# define feof_unlocked(fp) __feof_unlocked (fp)
93#endif
94
95struct gaih_service
96 {
97 const char *name;
98 int num;
99 };
100
101struct gaih_servtuple
102 {
103 struct gaih_servtuple *next;
104 int socktype;
105 int protocol;
106 int port;
107 };
108
109static const struct gaih_servtuple nullserv;
110
111
112struct gaih_typeproto
113 {
114 int socktype;
115 int protocol;
116 uint8_t protoflag;
117 bool defaultflag;
118 char name[8];
119 };
120
121/* Values for `protoflag'. */
122#define GAI_PROTO_NOSERVICE 1
123#define GAI_PROTO_PROTOANY 2
124
125static const struct gaih_typeproto gaih_inet_typeproto[] =
126{
127 { 0, 0, 0, false, "" },
128 { SOCK_STREAM, IPPROTO_TCP, 0, true, "tcp" },
129 { SOCK_DGRAM, IPPROTO_UDP, 0, true, "udp" },
130#if defined SOCK_DCCP && defined IPPROTO_DCCP
131 { SOCK_DCCP, IPPROTO_DCCP, 0, false, "dccp" },
132#endif
133#ifdef IPPROTO_UDPLITE
134 { SOCK_DGRAM, IPPROTO_UDPLITE, 0, false, "udplite" },
135#endif
136#ifdef IPPROTO_SCTP
137 { SOCK_STREAM, IPPROTO_SCTP, 0, false, "sctp" },
138 { SOCK_SEQPACKET, IPPROTO_SCTP, 0, false, "sctp" },
139#endif
140 { SOCK_RAW, 0, GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, true, "raw" },
141 { 0, 0, 0, false, "" }
142};
143
144static const struct addrinfo default_hints =
145 {
146 .ai_flags = AI_DEFAULT,
147 .ai_family = PF_UNSPEC,
148 .ai_socktype = 0,
149 .ai_protocol = 0,
150 .ai_addrlen = 0,
151 .ai_addr = NULL,
152 .ai_canonname = NULL,
153 .ai_next = NULL
154 };
155
156
157static int
158gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
159 const struct addrinfo *req, struct gaih_servtuple *st,
160 struct scratch_buffer *tmpbuf)
161{
162 struct servent *s;
163 struct servent ts;
164 int r;
165
166 do
167 {
168 r = __getservbyname_r (servicename, tp->name, &ts,
169 tmpbuf->data, tmpbuf->length, &s);
170 if (r != 0 || s == NULL)
171 {
172 if (r == ERANGE)
173 {
174 if (!scratch_buffer_grow (tmpbuf))
175 return -EAI_MEMORY;
176 }
177 else
178 return -EAI_SERVICE;
179 }
180 }
181 while (r);
182
183 st->next = NULL;
184 st->socktype = tp->socktype;
185 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
186 ? req->ai_protocol : tp->protocol);
187 st->port = s->s_port;
188
189 return 0;
190}
191
192/* Convert struct hostent to a list of struct gaih_addrtuple objects.
193 h_name is not copied, and the struct hostent object must not be
194 deallocated prematurely. *RESULT must be NULL or a pointer to a
195 linked-list. The new addresses are appended at the end. */
196static bool
197convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
198 int family,
199 struct hostent *h,
200 struct gaih_addrtuple **result)
201{
202 while (*result)
203 result = &(*result)->next;
204
205 /* Count the number of addresses in h->h_addr_list. */
206 size_t count = 0;
207 for (char **p = h->h_addr_list; *p != NULL; ++p)
208 ++count;
209
210 /* Report no data if no addresses are available, or if the incoming
211 address size is larger than what we can store. */
212 if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
213 return true;
214
215 struct gaih_addrtuple *array = calloc (count, sizeof (*array));
216 if (array == NULL)
217 return false;
218
219 for (size_t i = 0; i < count; ++i)
220 {
221 if (family == AF_INET && req->ai_family == AF_INET6)
222 {
223 /* Perform address mapping. */
224 array[i].family = AF_INET6;
225 memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
226 array[i].addr[2] = htonl (0xffff);
227 }
228 else
229 {
230 array[i].family = family;
231 memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
232 }
233 array[i].next = array + i + 1;
234 }
235 array[0].name = h->h_name;
236 array[count - 1].next = NULL;
237
238 *result = array;
239 return true;
240}
241
242#define gethosts(_family, _type) \
243 { \
244 struct hostent th; \
245 char *localcanon = NULL; \
246 no_data = 0; \
247 while (1) \
248 { \
249 status = DL_CALL_FCT (fct, (name, _family, &th, \
250 tmpbuf->data, tmpbuf->length, \
251 &errno, &h_errno, NULL, &localcanon)); \
252 if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL \
253 || errno != ERANGE) \
254 break; \
255 if (!scratch_buffer_grow (tmpbuf)) \
256 { \
257 __resolv_context_put (res_ctx); \
258 result = -EAI_MEMORY; \
259 goto free_and_return; \
260 } \
261 } \
262 if (status == NSS_STATUS_NOTFOUND \
263 || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) \
264 { \
265 if (h_errno == NETDB_INTERNAL) \
266 { \
267 __resolv_context_put (res_ctx); \
268 result = -EAI_SYSTEM; \
269 goto free_and_return; \
270 } \
271 if (h_errno == TRY_AGAIN) \
272 no_data = EAI_AGAIN; \
273 else \
274 no_data = h_errno == NO_DATA; \
275 } \
276 else if (status == NSS_STATUS_SUCCESS) \
277 { \
278 if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem)) \
279 { \
280 __resolv_context_put (res_ctx); \
281 result = -EAI_SYSTEM; \
282 goto free_and_return; \
283 } \
284 *pat = addrmem; \
285 \
286 if (localcanon != NULL && canon == NULL) \
287 { \
288 canonbuf = __strdup (localcanon); \
289 if (canonbuf == NULL) \
290 { \
291 __resolv_context_put (res_ctx); \
292 result = -EAI_SYSTEM; \
293 goto free_and_return; \
294 } \
295 canon = canonbuf; \
296 } \
297 if (_family == AF_INET6 && *pat != NULL) \
298 got_ipv6 = true; \
299 } \
300 }
301
302
303/* This function is called if a canonical name is requested, but if
304 the service function did not provide it. It tries to obtain the
305 name using getcanonname_r from the same service NIP. If the name
306 cannot be canonicalized, return a copy of NAME. Return NULL on
307 memory allocation failure. The returned string is allocated on the
308 heap; the caller has to free it. */
309static char *
310getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name)
311{
312 nss_getcanonname_r *cfct = __nss_lookup_function (nip, "getcanonname_r");
313 char *s = (char *) name;
314 if (cfct != NULL)
315 {
316 char buf[256];
317 if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf),
318 &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS)
319 /* If the canonical name cannot be determined, use the passed
320 string. */
321 s = (char *) name;
322 }
323 return __strdup (name);
324}
325
326static int
327gaih_inet (const char *name, const struct gaih_service *service,
328 const struct addrinfo *req, struct addrinfo **pai,
329 unsigned int *naddrs, struct scratch_buffer *tmpbuf)
330{
331 const struct gaih_typeproto *tp = gaih_inet_typeproto;
332 struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
333 struct gaih_addrtuple *at = NULL;
334 bool got_ipv6 = false;
335 const char *canon = NULL;
336 const char *orig_name = name;
337
338 /* Reserve stack memory for the scratch buffer in the getaddrinfo
339 function. */
340 size_t alloca_used = sizeof (struct scratch_buffer);
341
342 if (req->ai_protocol || req->ai_socktype)
343 {
344 ++tp;
345
346 while (tp->name[0]
347 && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
348 || (req->ai_protocol != 0
349 && !(tp->protoflag & GAI_PROTO_PROTOANY)
350 && req->ai_protocol != tp->protocol)))
351 ++tp;
352
353 if (! tp->name[0])
354 {
355 if (req->ai_socktype)
356 return -EAI_SOCKTYPE;
357 else
358 return -EAI_SERVICE;
359 }
360 }
361
362 int port = 0;
363 if (service != NULL)
364 {
365 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
366 return -EAI_SERVICE;
367
368 if (service->num < 0)
369 {
370 if (tp->name[0])
371 {
372 st = (struct gaih_servtuple *)
373 alloca_account (sizeof (struct gaih_servtuple), alloca_used);
374
375 int rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf);
376 if (__glibc_unlikely (rc != 0))
377 return rc;
378 }
379 else
380 {
381 struct gaih_servtuple **pst = &st;
382 for (tp++; tp->name[0]; tp++)
383 {
384 struct gaih_servtuple *newp;
385
386 if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
387 continue;
388
389 if (req->ai_socktype != 0
390 && req->ai_socktype != tp->socktype)
391 continue;
392 if (req->ai_protocol != 0
393 && !(tp->protoflag & GAI_PROTO_PROTOANY)
394 && req->ai_protocol != tp->protocol)
395 continue;
396
397 newp = (struct gaih_servtuple *)
398 alloca_account (sizeof (struct gaih_servtuple),
399 alloca_used);
400
401 if (gaih_inet_serv (service->name,
402 tp, req, newp, tmpbuf) != 0)
403 continue;
404
405 *pst = newp;
406 pst = &(newp->next);
407 }
408 if (st == (struct gaih_servtuple *) &nullserv)
409 return -EAI_SERVICE;
410 }
411 }
412 else
413 {
414 port = htons (service->num);
415 goto got_port;
416 }
417 }
418 else
419 {
420 got_port:
421
422 if (req->ai_socktype || req->ai_protocol)
423 {
424 st = alloca_account (sizeof (struct gaih_servtuple), alloca_used);
425 st->next = NULL;
426 st->socktype = tp->socktype;
427 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
428 ? req->ai_protocol : tp->protocol);
429 st->port = port;
430 }
431 else
432 {
433 /* Neither socket type nor protocol is set. Return all socket types
434 we know about. */
435 struct gaih_servtuple **lastp = &st;
436 for (++tp; tp->name[0]; ++tp)
437 if (tp->defaultflag)
438 {
439 struct gaih_servtuple *newp;
440
441 newp = alloca_account (sizeof (struct gaih_servtuple),
442 alloca_used);
443 newp->next = NULL;
444 newp->socktype = tp->socktype;
445 newp->protocol = tp->protocol;
446 newp->port = port;
447
448 *lastp = newp;
449 lastp = &newp->next;
450 }
451 }
452 }
453
454 bool malloc_name = false;
455 struct gaih_addrtuple *addrmem = NULL;
456 char *canonbuf = NULL;
457 int result = 0;
458
459 if (name != NULL)
460 {
461 at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
462 at->family = AF_UNSPEC;
463 at->scopeid = 0;
464 at->next = NULL;
465
466 if (req->ai_flags & AI_IDN)
467 {
468 char *out;
469 result = __idna_to_dns_encoding (name, &out);
470 if (result != 0)
471 return -result;
472 name = out;
473 malloc_name = true;
474 }
475
476 if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
477 {
478 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
479 at->family = AF_INET;
480 else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
481 {
482 at->addr[3] = at->addr[0];
483 at->addr[2] = htonl (0xffff);
484 at->addr[1] = 0;
485 at->addr[0] = 0;
486 at->family = AF_INET6;
487 }
488 else
489 {
490 result = -EAI_ADDRFAMILY;
491 goto free_and_return;
492 }
493
494 if (req->ai_flags & AI_CANONNAME)
495 canon = name;
496 }
497 else if (at->family == AF_UNSPEC)
498 {
499 char *scope_delim = strchr (name, SCOPE_DELIMITER);
500 int e;
501 if (scope_delim == NULL)
502 e = inet_pton (AF_INET6, name, at->addr);
503 else
504 e = __inet_pton_length (AF_INET6, name, scope_delim - name,
505 at->addr);
506 if (e > 0)
507 {
508 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
509 at->family = AF_INET6;
510 else if (req->ai_family == AF_INET
511 && IN6_IS_ADDR_V4MAPPED (at->addr))
512 {
513 at->addr[0] = at->addr[3];
514 at->family = AF_INET;
515 }
516 else
517 {
518 result = -EAI_ADDRFAMILY;
519 goto free_and_return;
520 }
521
522 if (scope_delim != NULL
523 && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
524 scope_delim + 1,
525 &at->scopeid) != 0)
526 {
527 result = -EAI_NONAME;
528 goto free_and_return;
529 }
530
531 if (req->ai_flags & AI_CANONNAME)
532 canon = name;
533 }
534 }
535
536 if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
537 {
538 struct gaih_addrtuple **pat = &at;
539 int no_data = 0;
540 int no_inet6_data = 0;
541 nss_action_list nip;
542 enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
543 enum nss_status status = NSS_STATUS_UNAVAIL;
544 int no_more;
545 struct resolv_context *res_ctx = NULL;
546
547 /* If we do not have to look for IPv6 addresses or the canonical
548 name, use the simple, old functions, which do not support
549 IPv6 scope ids, nor retrieving the canonical name. */
550 if (req->ai_family == AF_INET
551 && (req->ai_flags & AI_CANONNAME) == 0)
552 {
553 int rc;
554 struct hostent th;
555 struct hostent *h;
556
557 while (1)
558 {
559 rc = __gethostbyname2_r (name, AF_INET, &th,
560 tmpbuf->data, tmpbuf->length,
561 &h, &h_errno);
562 if (rc != ERANGE || h_errno != NETDB_INTERNAL)
563 break;
564 if (!scratch_buffer_grow (tmpbuf))
565 {
566 result = -EAI_MEMORY;
567 goto free_and_return;
568 }
569 }
570
571 if (rc == 0)
572 {
573 if (h != NULL)
574 {
575 /* We found data, convert it. */
576 if (!convert_hostent_to_gaih_addrtuple
577 (req, AF_INET, h, &addrmem))
578 {
579 result = -EAI_MEMORY;
580 goto free_and_return;
581 }
582 *pat = addrmem;
583 }
584 else
585 {
586 if (h_errno == NO_DATA)
587 result = -EAI_NODATA;
588 else
589 result = -EAI_NONAME;
590 goto free_and_return;
591 }
592 }
593 else
594 {
595 if (h_errno == NETDB_INTERNAL)
596 result = -EAI_SYSTEM;
597 else if (h_errno == TRY_AGAIN)
598 result = -EAI_AGAIN;
599 else
600 /* We made requests but they turned out no data.
601 The name is known, though. */
602 result = -EAI_NODATA;
603
604 goto free_and_return;
605 }
606
607 goto process_list;
608 }
609
610#ifdef USE_NSCD
611 if (__nss_not_use_nscd_hosts > 0
612 && ++__nss_not_use_nscd_hosts > NSS_NSCD_RETRY)
613 __nss_not_use_nscd_hosts = 0;
614
615 if (!__nss_not_use_nscd_hosts
616 && !__nss_database_custom[NSS_DBSIDX_hosts])
617 {
618 /* Try to use nscd. */
619 struct nscd_ai_result *air = NULL;
620 int err = __nscd_getai (name, &air, &h_errno);
621 if (air != NULL)
622 {
623 /* Transform into gaih_addrtuple list. */
624 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
625 char *addrs = air->addrs;
626
627 addrmem = calloc (air->naddrs, sizeof (*addrmem));
628 if (addrmem == NULL)
629 {
630 result = -EAI_MEMORY;
631 goto free_and_return;
632 }
633
634 struct gaih_addrtuple *addrfree = addrmem;
635 for (int i = 0; i < air->naddrs; ++i)
636 {
637 socklen_t size = (air->family[i] == AF_INET
638 ? INADDRSZ : IN6ADDRSZ);
639
640 if (!((air->family[i] == AF_INET
641 && req->ai_family == AF_INET6
642 && (req->ai_flags & AI_V4MAPPED) != 0)
643 || req->ai_family == AF_UNSPEC
644 || air->family[i] == req->ai_family))
645 {
646 /* Skip over non-matching result. */
647 addrs += size;
648 continue;
649 }
650
651 if (*pat == NULL)
652 {
653 *pat = addrfree++;
654 (*pat)->scopeid = 0;
655 }
656 uint32_t *pataddr = (*pat)->addr;
657 (*pat)->next = NULL;
658 if (added_canon || air->canon == NULL)
659 (*pat)->name = NULL;
660 else if (canonbuf == NULL)
661 {
662 canonbuf = __strdup (air->canon);
663 if (canonbuf == NULL)
664 {
665 result = -EAI_MEMORY;
666 goto free_and_return;
667 }
668 canon = (*pat)->name = canonbuf;
669 }
670
671 if (air->family[i] == AF_INET
672 && req->ai_family == AF_INET6
673 && (req->ai_flags & AI_V4MAPPED))
674 {
675 (*pat)->family = AF_INET6;
676 pataddr[3] = *(uint32_t *) addrs;
677 pataddr[2] = htonl (0xffff);
678 pataddr[1] = 0;
679 pataddr[0] = 0;
680 pat = &((*pat)->next);
681 added_canon = true;
682 }
683 else if (req->ai_family == AF_UNSPEC
684 || air->family[i] == req->ai_family)
685 {
686 (*pat)->family = air->family[i];
687 memcpy (pataddr, addrs, size);
688 pat = &((*pat)->next);
689 added_canon = true;
690 if (air->family[i] == AF_INET6)
691 got_ipv6 = true;
692 }
693 addrs += size;
694 }
695
696 free (air);
697
698 if (at->family == AF_UNSPEC)
699 {
700 result = -EAI_NONAME;
701 goto free_and_return;
702 }
703
704 goto process_list;
705 }
706 else if (err == 0)
707 /* The database contains a negative entry. */
708 goto free_and_return;
709 else if (__nss_not_use_nscd_hosts == 0)
710 {
711 if (h_errno == NETDB_INTERNAL && errno == ENOMEM)
712 result = -EAI_MEMORY;
713 else if (h_errno == TRY_AGAIN)
714 result = -EAI_AGAIN;
715 else
716 result = -EAI_SYSTEM;
717
718 goto free_and_return;
719 }
720 }
721#endif
722
723 no_more = __nss_database_lookup2 ("hosts", NULL,
724 "dns [!UNAVAIL=return] files",
725 &nip);
726
727 /* If we are looking for both IPv4 and IPv6 address we don't
728 want the lookup functions to automatically promote IPv4
729 addresses to IPv6 addresses, so we use the no_inet6
730 function variant. */
731 res_ctx = __resolv_context_get ();
732 if (res_ctx == NULL)
733 no_more = 1;
734
735 while (!no_more)
736 {
737 no_data = 0;
738 nss_gethostbyname4_r *fct4 = NULL;
739
740 /* gethostbyname4_r sends out parallel A and AAAA queries and
741 is thus only suitable for PF_UNSPEC. */
742 if (req->ai_family == PF_UNSPEC)
743 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
744
745 if (fct4 != NULL)
746 {
747 while (1)
748 {
749 status = DL_CALL_FCT (fct4, (name, pat,
750 tmpbuf->data, tmpbuf->length,
751 &errno, &h_errno,
752 NULL));
753 if (status == NSS_STATUS_SUCCESS)
754 break;
755 if (status != NSS_STATUS_TRYAGAIN
756 || errno != ERANGE || h_errno != NETDB_INTERNAL)
757 {
758 if (h_errno == TRY_AGAIN)
759 no_data = EAI_AGAIN;
760 else
761 no_data = h_errno == NO_DATA;
762 break;
763 }
764
765 if (!scratch_buffer_grow (tmpbuf))
766 {
767 __resolv_context_put (res_ctx);
768 result = -EAI_MEMORY;
769 goto free_and_return;
770 }
771 }
772
773 if (status == NSS_STATUS_SUCCESS)
774 {
775 assert (!no_data);
776 no_data = 1;
777
778 if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
779 canon = (*pat)->name;
780
781 while (*pat != NULL)
782 {
783 if ((*pat)->family == AF_INET
784 && req->ai_family == AF_INET6
785 && (req->ai_flags & AI_V4MAPPED) != 0)
786 {
787 uint32_t *pataddr = (*pat)->addr;
788 (*pat)->family = AF_INET6;
789 pataddr[3] = pataddr[0];
790 pataddr[2] = htonl (0xffff);
791 pataddr[1] = 0;
792 pataddr[0] = 0;
793 pat = &((*pat)->next);
794 no_data = 0;
795 }
796 else if (req->ai_family == AF_UNSPEC
797 || (*pat)->family == req->ai_family)
798 {
799 pat = &((*pat)->next);
800
801 no_data = 0;
802 if (req->ai_family == AF_INET6)
803 got_ipv6 = true;
804 }
805 else
806 *pat = ((*pat)->next);
807 }
808 }
809
810 no_inet6_data = no_data;
811 }
812 else
813 {
814 nss_gethostbyname3_r *fct = NULL;
815 if (req->ai_flags & AI_CANONNAME)
816 /* No need to use this function if we do not look for
817 the canonical name. The function does not exist in
818 all NSS modules and therefore the lookup would
819 often fail. */
820 fct = __nss_lookup_function (nip, "gethostbyname3_r");
821 if (fct == NULL)
822 /* We are cheating here. The gethostbyname2_r
823 function does not have the same interface as
824 gethostbyname3_r but the extra arguments the
825 latter takes are added at the end. So the
826 gethostbyname2_r code will just ignore them. */
827 fct = __nss_lookup_function (nip, "gethostbyname2_r");
828
829 if (fct != NULL)
830 {
831 if (req->ai_family == AF_INET6
832 || req->ai_family == AF_UNSPEC)
833 {
834 gethosts (AF_INET6, struct in6_addr);
835 no_inet6_data = no_data;
836 inet6_status = status;
837 }
838 if (req->ai_family == AF_INET
839 || req->ai_family == AF_UNSPEC
840 || (req->ai_family == AF_INET6
841 && (req->ai_flags & AI_V4MAPPED)
842 /* Avoid generating the mapped addresses if we
843 know we are not going to need them. */
844 && ((req->ai_flags & AI_ALL) || !got_ipv6)))
845 {
846 gethosts (AF_INET, struct in_addr);
847
848 if (req->ai_family == AF_INET)
849 {
850 no_inet6_data = no_data;
851 inet6_status = status;
852 }
853 }
854
855 /* If we found one address for AF_INET or AF_INET6,
856 don't continue the search. */
857 if (inet6_status == NSS_STATUS_SUCCESS
858 || status == NSS_STATUS_SUCCESS)
859 {
860 if ((req->ai_flags & AI_CANONNAME) != 0
861 && canon == NULL)
862 {
863 canonbuf = getcanonname (nip, at, name);
864 if (canonbuf == NULL)
865 {
866 __resolv_context_put (res_ctx);
867 result = -EAI_MEMORY;
868 goto free_and_return;
869 }
870 canon = canonbuf;
871 }
872 status = NSS_STATUS_SUCCESS;
873 }
874 else
875 {
876 /* We can have different states for AF_INET and
877 AF_INET6. Try to find a useful one for both. */
878 if (inet6_status == NSS_STATUS_TRYAGAIN)
879 status = NSS_STATUS_TRYAGAIN;
880 else if (status == NSS_STATUS_UNAVAIL
881 && inet6_status != NSS_STATUS_UNAVAIL)
882 status = inet6_status;
883 }
884 }
885 else
886 {
887 /* Could not locate any of the lookup functions.
888 The NSS lookup code does not consistently set
889 errno, so we need to supply our own error
890 code here. The root cause could either be a
891 resource allocation failure, or a missing
892 service function in the DSO (so it should not
893 be listed in /etc/nsswitch.conf). Assume the
894 former, and return EBUSY. */
895 status = NSS_STATUS_UNAVAIL;
896 __set_h_errno (NETDB_INTERNAL);
897 __set_errno (EBUSY);
898 }
899 }
900
901 if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
902 break;
903
904 nip++;
905 if (nip->module == NULL)
906 no_more = -1;
907 }
908
909 __resolv_context_put (res_ctx);
910
911 /* If we have a failure which sets errno, report it using
912 EAI_SYSTEM. */
913 if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL)
914 && h_errno == NETDB_INTERNAL)
915 {
916 result = -EAI_SYSTEM;
917 goto free_and_return;
918 }
919
920 if (no_data != 0 && no_inet6_data != 0)
921 {
922 /* If both requests timed out report this. */
923 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
924 result = -EAI_AGAIN;
925 else
926 /* We made requests but they turned out no data. The name
927 is known, though. */
928 result = -EAI_NODATA;
929
930 goto free_and_return;
931 }
932 }
933
934 process_list:
935 if (at->family == AF_UNSPEC)
936 {
937 result = -EAI_NONAME;
938 goto free_and_return;
939 }
940 }
941 else
942 {
943 struct gaih_addrtuple *atr;
944 atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
945 memset (at, '\0', sizeof (struct gaih_addrtuple));
946
947 if (req->ai_family == AF_UNSPEC)
948 {
949 at->next = __alloca (sizeof (struct gaih_addrtuple));
950 memset (at->next, '\0', sizeof (struct gaih_addrtuple));
951 }
952
953 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
954 {
955 at->family = AF_INET6;
956 if ((req->ai_flags & AI_PASSIVE) == 0)
957 memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
958 atr = at->next;
959 }
960
961 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
962 {
963 atr->family = AF_INET;
964 if ((req->ai_flags & AI_PASSIVE) == 0)
965 atr->addr[0] = htonl (INADDR_LOOPBACK);
966 }
967 }
968
969 {
970 struct gaih_servtuple *st2;
971 struct gaih_addrtuple *at2 = at;
972 size_t socklen;
973 sa_family_t family;
974
975 /*
976 buffer is the size of an unformatted IPv6 address in printable format.
977 */
978 while (at2 != NULL)
979 {
980 /* Only the first entry gets the canonical name. */
981 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
982 {
983 if (canon == NULL)
984 /* If the canonical name cannot be determined, use
985 the passed in string. */
986 canon = orig_name;
987
988 bool do_idn = req->ai_flags & AI_CANONIDN;
989 if (do_idn)
990 {
991 char *out;
992 int rc = __idna_from_dns_encoding (canon, &out);
993 if (rc == 0)
994 canon = out;
995 else if (rc == EAI_IDN_ENCODE)
996 /* Use the punycode name as a fallback. */
997 do_idn = false;
998 else
999 {
1000 result = -rc;
1001 goto free_and_return;
1002 }
1003 }
1004 if (!do_idn)
1005 {
1006 if (canonbuf != NULL)
1007 /* We already allocated the string using malloc, but
1008 the buffer is now owned by canon. */
1009 canonbuf = NULL;
1010 else
1011 {
1012 canon = __strdup (canon);
1013 if (canon == NULL)
1014 {
1015 result = -EAI_MEMORY;
1016 goto free_and_return;
1017 }
1018 }
1019 }
1020 }
1021
1022 family = at2->family;
1023 if (family == AF_INET6)
1024 {
1025 socklen = sizeof (struct sockaddr_in6);
1026
1027 /* If we looked up IPv4 mapped address discard them here if
1028 the caller isn't interested in all address and we have
1029 found at least one IPv6 address. */
1030 if (got_ipv6
1031 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1032 && IN6_IS_ADDR_V4MAPPED (at2->addr))
1033 goto ignore;
1034 }
1035 else
1036 socklen = sizeof (struct sockaddr_in);
1037
1038 for (st2 = st; st2 != NULL; st2 = st2->next)
1039 {
1040 struct addrinfo *ai;
1041 ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1042 if (ai == NULL)
1043 {
1044 free ((char *) canon);
1045 result = -EAI_MEMORY;
1046 goto free_and_return;
1047 }
1048
1049 ai->ai_flags = req->ai_flags;
1050 ai->ai_family = family;
1051 ai->ai_socktype = st2->socktype;
1052 ai->ai_protocol = st2->protocol;
1053 ai->ai_addrlen = socklen;
1054 ai->ai_addr = (void *) (ai + 1);
1055
1056 /* We only add the canonical name once. */
1057 ai->ai_canonname = (char *) canon;
1058 canon = NULL;
1059
1060#ifdef _HAVE_SA_LEN
1061 ai->ai_addr->sa_len = socklen;
1062#endif /* _HAVE_SA_LEN */
1063 ai->ai_addr->sa_family = family;
1064
1065 /* In case of an allocation error the list must be NULL
1066 terminated. */
1067 ai->ai_next = NULL;
1068
1069 if (family == AF_INET6)
1070 {
1071 struct sockaddr_in6 *sin6p =
1072 (struct sockaddr_in6 *) ai->ai_addr;
1073
1074 sin6p->sin6_port = st2->port;
1075 sin6p->sin6_flowinfo = 0;
1076 memcpy (&sin6p->sin6_addr,
1077 at2->addr, sizeof (struct in6_addr));
1078 sin6p->sin6_scope_id = at2->scopeid;
1079 }
1080 else
1081 {
1082 struct sockaddr_in *sinp =
1083 (struct sockaddr_in *) ai->ai_addr;
1084 sinp->sin_port = st2->port;
1085 memcpy (&sinp->sin_addr,
1086 at2->addr, sizeof (struct in_addr));
1087 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1088 }
1089
1090 pai = &(ai->ai_next);
1091 }
1092
1093 ++*naddrs;
1094
1095 ignore:
1096 at2 = at2->next;
1097 }
1098 }
1099
1100 free_and_return:
1101 if (malloc_name)
1102 free ((char *) name);
1103 free (addrmem);
1104 free (canonbuf);
1105
1106 return result;
1107}
1108
1109
1110struct sort_result
1111{
1112 struct addrinfo *dest_addr;
1113 /* Using sockaddr_storage is for now overkill. We only support IPv4
1114 and IPv6 so far. If this changes at some point we can adjust the
1115 type here. */
1116 struct sockaddr_in6 source_addr;
1117 uint8_t source_addr_len;
1118 bool got_source_addr;
1119 uint8_t source_addr_flags;
1120 uint8_t prefixlen;
1121 uint32_t index;
1122 int32_t native;
1123};
1124
1125struct sort_result_combo
1126{
1127 struct sort_result *results;
1128 int nresults;
1129};
1130
1131
1132#if __BYTE_ORDER == __BIG_ENDIAN
1133# define htonl_c(n) n
1134#else
1135# define htonl_c(n) __bswap_constant_32 (n)
1136#endif
1137
1138static const struct scopeentry
1139{
1140 union
1141 {
1142 char addr[4];
1143 uint32_t addr32;
1144 };
1145 uint32_t netmask;
1146 int32_t scope;
1147} default_scopes[] =
1148 {
1149 /* Link-local addresses: scope 2. */
1150 { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1151 { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1152 /* Default: scope 14. */
1153 { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1154 };
1155
1156/* The label table. */
1157static const struct scopeentry *scopes;
1158
1159
1160static int
1161get_scope (const struct sockaddr_in6 *in6)
1162{
1163 int scope;
1164 if (in6->sin6_family == PF_INET6)
1165 {
1166 if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1167 {
1168 if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1169 /* RFC 4291 2.5.3 says that the loopback address is to be
1170 treated like a link-local address. */
1171 || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1172 scope = 2;
1173 else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1174 scope = 5;
1175 else
1176 /* XXX Is this the correct default behavior? */
1177 scope = 14;
1178 }
1179 else
1180 scope = in6->sin6_addr.s6_addr[1] & 0xf;
1181 }
1182 else if (in6->sin6_family == PF_INET)
1183 {
1184 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1185
1186 size_t cnt = 0;
1187 while (1)
1188 {
1189 if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1190 == scopes[cnt].addr32)
1191 return scopes[cnt].scope;
1192
1193 ++cnt;
1194 }
1195 /* NOTREACHED */
1196 }
1197 else
1198 /* XXX What is a good default? */
1199 scope = 15;
1200
1201 return scope;
1202}
1203
1204
1205struct prefixentry
1206{
1207 struct in6_addr prefix;
1208 unsigned int bits;
1209 int val;
1210};
1211
1212
1213/* The label table. */
1214static const struct prefixentry *labels;
1215
1216/* Default labels. */
1217static const struct prefixentry default_labels[] =
1218 {
1219 /* See RFC 3484 for the details. */
1220 { { .__in6_u
1221 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1222 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1223 }, 128, 0 },
1224 { { .__in6_u
1225 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1227 }, 16, 2 },
1228 { { .__in6_u
1229 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1231 }, 96, 3 },
1232 { { .__in6_u
1233 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1234 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1235 }, 96, 4 },
1236 /* The next two entries differ from RFC 3484. We need to treat
1237 IPv6 site-local addresses special because they are never NATed,
1238 unlike site-locale IPv4 addresses. If this would not happen, on
1239 machines which have only IPv4 and IPv6 site-local addresses, the
1240 sorting would prefer the IPv6 site-local addresses, causing
1241 unnecessary delays when trying to connect to a global IPv6 address
1242 through a site-local IPv6 address. */
1243 { { .__in6_u
1244 = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1245 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1246 }, 10, 5 },
1247 { { .__in6_u
1248 = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1250 }, 7, 6 },
1251 /* Additional rule for Teredo tunnels. */
1252 { { .__in6_u
1253 = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1255 }, 32, 7 },
1256 { { .__in6_u
1257 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1259 }, 0, 1 }
1260 };
1261
1262
1263/* The precedence table. */
1264static const struct prefixentry *precedence;
1265
1266/* The default precedences. */
1267static const struct prefixentry default_precedence[] =
1268 {
1269 /* See RFC 3484 for the details. */
1270 { { .__in6_u
1271 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1273 }, 128, 50 },
1274 { { .__in6_u
1275 = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1277 }, 16, 30 },
1278 { { .__in6_u
1279 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1281 }, 96, 20 },
1282 { { .__in6_u
1283 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1284 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1285 }, 96, 10 },
1286 { { .__in6_u
1287 = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1288 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1289 }, 0, 40 }
1290 };
1291
1292
1293static int
1294match_prefix (const struct sockaddr_in6 *in6,
1295 const struct prefixentry *list, int default_val)
1296{
1297 int idx;
1298 struct sockaddr_in6 in6_mem;
1299
1300 if (in6->sin6_family == PF_INET)
1301 {
1302 const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1303
1304 /* Construct a V4-to-6 mapped address. */
1305 in6_mem.sin6_family = PF_INET6;
1306 in6_mem.sin6_port = in->sin_port;
1307 in6_mem.sin6_flowinfo = 0;
1308 memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1309 in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1310 in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1311 in6_mem.sin6_scope_id = 0;
1312
1313 in6 = &in6_mem;
1314 }
1315 else if (in6->sin6_family != PF_INET6)
1316 return default_val;
1317
1318 for (idx = 0; ; ++idx)
1319 {
1320 unsigned int bits = list[idx].bits;
1321 const uint8_t *mask = list[idx].prefix.s6_addr;
1322 const uint8_t *val = in6->sin6_addr.s6_addr;
1323
1324 while (bits >= 8)
1325 {
1326 if (*mask != *val)
1327 break;
1328
1329 ++mask;
1330 ++val;
1331 bits -= 8;
1332 }
1333
1334 if (bits < 8)
1335 {
1336 if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1337 /* Match! */
1338 break;
1339 }
1340 }
1341
1342 return list[idx].val;
1343}
1344
1345
1346static int
1347get_label (const struct sockaddr_in6 *in6)
1348{
1349 /* XXX What is a good default value? */
1350 return match_prefix (in6, labels, INT_MAX);
1351}
1352
1353
1354static int
1355get_precedence (const struct sockaddr_in6 *in6)
1356{
1357 /* XXX What is a good default value? */
1358 return match_prefix (in6, precedence, 0);
1359}
1360
1361
1362/* Find last bit set in a word. */
1363static int
1364fls (uint32_t a)
1365{
1366 uint32_t mask;
1367 int n;
1368 for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1369 if ((a & mask) != 0)
1370 break;
1371 return n;
1372}
1373
1374
1375static int
1376rfc3484_sort (const void *p1, const void *p2, void *arg)
1377{
1378 const size_t idx1 = *(const size_t *) p1;
1379 const size_t idx2 = *(const size_t *) p2;
1380 struct sort_result_combo *src = (struct sort_result_combo *) arg;
1381 struct sort_result *a1 = &src->results[idx1];
1382 struct sort_result *a2 = &src->results[idx2];
1383
1384 /* Rule 1: Avoid unusable destinations.
1385 We have the got_source_addr flag set if the destination is reachable. */
1386 if (a1->got_source_addr && ! a2->got_source_addr)
1387 return -1;
1388 if (! a1->got_source_addr && a2->got_source_addr)
1389 return 1;
1390
1391
1392 /* Rule 2: Prefer matching scope. Only interesting if both
1393 destination addresses are IPv6. */
1394 int a1_dst_scope
1395 = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1396
1397 int a2_dst_scope
1398 = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1399
1400 if (a1->got_source_addr)
1401 {
1402 int a1_src_scope = get_scope (&a1->source_addr);
1403 int a2_src_scope = get_scope (&a2->source_addr);
1404
1405 if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1406 return -1;
1407 if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1408 return 1;
1409 }
1410
1411
1412 /* Rule 3: Avoid deprecated addresses. */
1413 if (a1->got_source_addr)
1414 {
1415 if (!(a1->source_addr_flags & in6ai_deprecated)
1416 && (a2->source_addr_flags & in6ai_deprecated))
1417 return -1;
1418 if ((a1->source_addr_flags & in6ai_deprecated)
1419 && !(a2->source_addr_flags & in6ai_deprecated))
1420 return 1;
1421 }
1422
1423 /* Rule 4: Prefer home addresses. */
1424 if (a1->got_source_addr)
1425 {
1426 if (!(a1->source_addr_flags & in6ai_homeaddress)
1427 && (a2->source_addr_flags & in6ai_homeaddress))
1428 return 1;
1429 if ((a1->source_addr_flags & in6ai_homeaddress)
1430 && !(a2->source_addr_flags & in6ai_homeaddress))
1431 return -1;
1432 }
1433
1434 /* Rule 5: Prefer matching label. */
1435 if (a1->got_source_addr)
1436 {
1437 int a1_dst_label
1438 = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1439 int a1_src_label = get_label (&a1->source_addr);
1440
1441 int a2_dst_label
1442 = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1443 int a2_src_label = get_label (&a2->source_addr);
1444
1445 if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1446 return -1;
1447 if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1448 return 1;
1449 }
1450
1451
1452 /* Rule 6: Prefer higher precedence. */
1453 int a1_prec
1454 = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1455 int a2_prec
1456 = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1457
1458 if (a1_prec > a2_prec)
1459 return -1;
1460 if (a1_prec < a2_prec)
1461 return 1;
1462
1463
1464 /* Rule 7: Prefer native transport. */
1465 if (a1->got_source_addr)
1466 {
1467 /* The same interface index means the same interface which means
1468 there is no difference in transport. This should catch many
1469 (most?) cases. */
1470 if (a1->index != a2->index)
1471 {
1472 int a1_native = a1->native;
1473 int a2_native = a2->native;
1474
1475 if (a1_native == -1 || a2_native == -1)
1476 {
1477 uint32_t a1_index;
1478 if (a1_native == -1)
1479 {
1480 /* If we do not have the information use 'native' as
1481 the default. */
1482 a1_native = 0;
1483 a1_index = a1->index;
1484 }
1485 else
1486 a1_index = 0xffffffffu;
1487
1488 uint32_t a2_index;
1489 if (a2_native == -1)
1490 {
1491 /* If we do not have the information use 'native' as
1492 the default. */
1493 a2_native = 0;
1494 a2_index = a2->index;
1495 }
1496 else
1497 a2_index = 0xffffffffu;
1498
1499 __check_native (a1_index, &a1_native, a2_index, &a2_native);
1500
1501 /* Fill in the results in all the records. */
1502 for (int i = 0; i < src->nresults; ++i)
1503 if (a1_index != -1 && src->results[i].index == a1_index)
1504 {
1505 assert (src->results[i].native == -1
1506 || src->results[i].native == a1_native);
1507 src->results[i].native = a1_native;
1508 }
1509 else if (a2_index != -1 && src->results[i].index == a2_index)
1510 {
1511 assert (src->results[i].native == -1
1512 || src->results[i].native == a2_native);
1513 src->results[i].native = a2_native;
1514 }
1515 }
1516
1517 if (a1_native && !a2_native)
1518 return -1;
1519 if (!a1_native && a2_native)
1520 return 1;
1521 }
1522 }
1523
1524
1525 /* Rule 8: Prefer smaller scope. */
1526 if (a1_dst_scope < a2_dst_scope)
1527 return -1;
1528 if (a1_dst_scope > a2_dst_scope)
1529 return 1;
1530
1531
1532 /* Rule 9: Use longest matching prefix. */
1533 if (a1->got_source_addr
1534 && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1535 {
1536 int bit1 = 0;
1537 int bit2 = 0;
1538
1539 if (a1->dest_addr->ai_family == PF_INET)
1540 {
1541 assert (a1->source_addr.sin6_family == PF_INET);
1542 assert (a2->source_addr.sin6_family == PF_INET);
1543
1544 /* Outside of subnets, as defined by the network masks,
1545 common address prefixes for IPv4 addresses make no sense.
1546 So, define a non-zero value only if source and
1547 destination address are on the same subnet. */
1548 struct sockaddr_in *in1_dst
1549 = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1550 in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1551 struct sockaddr_in *in1_src
1552 = (struct sockaddr_in *) &a1->source_addr;
1553 in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1554 in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1555
1556 if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1557 bit1 = fls (in1_dst_addr ^ in1_src_addr);
1558
1559 struct sockaddr_in *in2_dst
1560 = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1561 in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1562 struct sockaddr_in *in2_src
1563 = (struct sockaddr_in *) &a2->source_addr;
1564 in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1565 in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1566
1567 if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1568 bit2 = fls (in2_dst_addr ^ in2_src_addr);
1569 }
1570 else if (a1->dest_addr->ai_family == PF_INET6)
1571 {
1572 assert (a1->source_addr.sin6_family == PF_INET6);
1573 assert (a2->source_addr.sin6_family == PF_INET6);
1574
1575 struct sockaddr_in6 *in1_dst;
1576 struct sockaddr_in6 *in1_src;
1577 struct sockaddr_in6 *in2_dst;
1578 struct sockaddr_in6 *in2_src;
1579
1580 in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1581 in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1582 in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1583 in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1584
1585 int i;
1586 for (i = 0; i < 4; ++i)
1587 if (in1_dst->sin6_addr.s6_addr32[i]
1588 != in1_src->sin6_addr.s6_addr32[i]
1589 || (in2_dst->sin6_addr.s6_addr32[i]
1590 != in2_src->sin6_addr.s6_addr32[i]))
1591 break;
1592
1593 if (i < 4)
1594 {
1595 bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1596 ^ in1_src->sin6_addr.s6_addr32[i]));
1597 bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1598 ^ in2_src->sin6_addr.s6_addr32[i]));
1599 }
1600 }
1601
1602 if (bit1 > bit2)
1603 return -1;
1604 if (bit1 < bit2)
1605 return 1;
1606 }
1607
1608
1609 /* Rule 10: Otherwise, leave the order unchanged. To ensure this
1610 compare with the value indicating the order in which the entries
1611 have been received from the services. NB: no two entries can have
1612 the same order so the test will never return zero. */
1613 return idx1 < idx2 ? -1 : 1;
1614}
1615
1616
1617static int
1618in6aicmp (const void *p1, const void *p2)
1619{
1620 struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1621 struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1622
1623 return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1624}
1625
1626
1627/* Name of the config file for RFC 3484 sorting (for now). */
1628#define GAICONF_FNAME "/etc/gai.conf"
1629
1630
1631/* Non-zero if we are supposed to reload the config file automatically
1632 whenever it changed. */
1633static int gaiconf_reload_flag;
1634
1635/* Non-zero if gaiconf_reload_flag was ever set to true. */
1636static int gaiconf_reload_flag_ever_set;
1637
1638/* Last modification time. */
1639#ifdef _STATBUF_ST_NSEC
1640
1641static struct timespec gaiconf_mtime;
1642
1643static inline void
1644save_gaiconf_mtime (const struct stat64 *st)
1645{
1646 gaiconf_mtime = st->st_mtim;
1647}
1648
1649static inline bool
1650check_gaiconf_mtime (const struct stat64 *st)
1651{
1652 return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1653 && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1654}
1655
1656#else
1657
1658static time_t gaiconf_mtime;
1659
1660static inline void
1661save_gaiconf_mtime (const struct stat64 *st)
1662{
1663 gaiconf_mtime = st->st_mtime;
1664}
1665
1666static inline bool
1667check_gaiconf_mtime (const struct stat64 *st)
1668{
1669 return st->st_mtime == gaiconf_mtime;
1670}
1671
1672#endif
1673
1674
1675libc_freeres_fn(fini)
1676{
1677 if (labels != default_labels)
1678 {
1679 const struct prefixentry *old = labels;
1680 labels = default_labels;
1681 free ((void *) old);
1682 }
1683
1684 if (precedence != default_precedence)
1685 {
1686 const struct prefixentry *old = precedence;
1687 precedence = default_precedence;
1688 free ((void *) old);
1689 }
1690
1691 if (scopes != default_scopes)
1692 {
1693 const struct scopeentry *old = scopes;
1694 scopes = default_scopes;
1695 free ((void *) old);
1696 }
1697}
1698
1699
1700struct prefixlist
1701{
1702 struct prefixentry entry;
1703 struct prefixlist *next;
1704};
1705
1706
1707struct scopelist
1708{
1709 struct scopeentry entry;
1710 struct scopelist *next;
1711};
1712
1713
1714static void
1715free_prefixlist (struct prefixlist *list)
1716{
1717 while (list != NULL)
1718 {
1719 struct prefixlist *oldp = list;
1720 list = list->next;
1721 free (oldp);
1722 }
1723}
1724
1725
1726static void
1727free_scopelist (struct scopelist *list)
1728{
1729 while (list != NULL)
1730 {
1731 struct scopelist *oldp = list;
1732 list = list->next;
1733 free (oldp);
1734 }
1735}
1736
1737
1738static int
1739prefixcmp (const void *p1, const void *p2)
1740{
1741 const struct prefixentry *e1 = (const struct prefixentry *) p1;
1742 const struct prefixentry *e2 = (const struct prefixentry *) p2;
1743
1744 if (e1->bits < e2->bits)
1745 return 1;
1746 if (e1->bits == e2->bits)
1747 return 0;
1748 return -1;
1749}
1750
1751
1752static int
1753scopecmp (const void *p1, const void *p2)
1754{
1755 const struct scopeentry *e1 = (const struct scopeentry *) p1;
1756 const struct scopeentry *e2 = (const struct scopeentry *) p2;
1757
1758 if (e1->netmask > e2->netmask)
1759 return -1;
1760 if (e1->netmask == e2->netmask)
1761 return 0;
1762 return 1;
1763}
1764
1765
1766static void
1767gaiconf_init (void)
1768{
1769 struct prefixlist *labellist = NULL;
1770 size_t nlabellist = 0;
1771 bool labellist_nullbits = false;
1772 struct prefixlist *precedencelist = NULL;
1773 size_t nprecedencelist = 0;
1774 bool precedencelist_nullbits = false;
1775 struct scopelist *scopelist = NULL;
1776 size_t nscopelist = 0;
1777 bool scopelist_nullbits = false;
1778
1779 FILE *fp = fopen (GAICONF_FNAME, "rce");
1780 if (fp != NULL)
1781 {
1782 struct stat64 st;
1783 if (__fstat64 (fileno (fp), &st) != 0)
1784 {
1785 fclose (fp);
1786 goto no_file;
1787 }
1788
1789 char *line = NULL;
1790 size_t linelen = 0;
1791
1792 __fsetlocking (fp, FSETLOCKING_BYCALLER);
1793
1794 while (!feof_unlocked (fp))
1795 {
1796 ssize_t n = __getline (&line, &linelen, fp);
1797 if (n <= 0)
1798 break;
1799
1800 /* Handle comments. No escaping possible so this is easy. */
1801 char *cp = strchr (line, '#');
1802 if (cp != NULL)
1803 *cp = '\0';
1804
1805 cp = line;
1806 while (isspace (*cp))
1807 ++cp;
1808
1809 char *cmd = cp;
1810 while (*cp != '\0' && !isspace (*cp))
1811 ++cp;
1812 size_t cmdlen = cp - cmd;
1813
1814 if (*cp != '\0')
1815 *cp++ = '\0';
1816 while (isspace (*cp))
1817 ++cp;
1818
1819 char *val1 = cp;
1820 while (*cp != '\0' && !isspace (*cp))
1821 ++cp;
1822 size_t val1len = cp - cmd;
1823
1824 /* We always need at least two values. */
1825 if (val1len == 0)
1826 continue;
1827
1828 if (*cp != '\0')
1829 *cp++ = '\0';
1830 while (isspace (*cp))
1831 ++cp;
1832
1833 char *val2 = cp;
1834 while (*cp != '\0' && !isspace (*cp))
1835 ++cp;
1836
1837 /* Ignore the rest of the line. */
1838 *cp = '\0';
1839
1840 struct prefixlist **listp;
1841 size_t *lenp;
1842 bool *nullbitsp;
1843 switch (cmdlen)
1844 {
1845 case 5:
1846 if (strcmp (cmd, "label") == 0)
1847 {
1848 struct in6_addr prefix;
1849 unsigned long int bits;
1850 unsigned long int val;
1851 char *endp;
1852
1853 listp = &labellist;
1854 lenp = &nlabellist;
1855 nullbitsp = &labellist_nullbits;
1856
1857 new_elem:
1858 bits = 128;
1859 __set_errno (0);
1860 cp = strchr (val1, '/');
1861 if (cp != NULL)
1862 *cp++ = '\0';
1863 if (inet_pton (AF_INET6, val1, &prefix)
1864 && (cp == NULL
1865 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1866 || errno != ERANGE)
1867 && *endp == '\0'
1868 && bits <= 128
1869 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1870 || errno != ERANGE)
1871 && *endp == '\0'
1872 && val <= INT_MAX)
1873 {
1874 struct prefixlist *newp = malloc (sizeof (*newp));
1875 if (newp == NULL)
1876 {
1877 free (line);
1878 fclose (fp);
1879 goto no_file;
1880 }
1881
1882 memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
1883 newp->entry.bits = bits;
1884 newp->entry.val = val;
1885 newp->next = *listp;
1886 *listp = newp;
1887 ++*lenp;
1888 *nullbitsp |= bits == 0;
1889 }
1890 }
1891 break;
1892
1893 case 6:
1894 if (strcmp (cmd, "reload") == 0)
1895 {
1896 gaiconf_reload_flag = strcmp (val1, "yes") == 0;
1897 if (gaiconf_reload_flag)
1898 gaiconf_reload_flag_ever_set = 1;
1899 }
1900 break;
1901
1902 case 7:
1903 if (strcmp (cmd, "scopev4") == 0)
1904 {
1905 struct in6_addr prefix;
1906 unsigned long int bits;
1907 unsigned long int val;
1908 char *endp;
1909
1910 bits = 32;
1911 __set_errno (0);
1912 cp = strchr (val1, '/');
1913 if (cp != NULL)
1914 *cp++ = '\0';
1915 if (inet_pton (AF_INET6, val1, &prefix))
1916 {
1917 bits = 128;
1918 if (IN6_IS_ADDR_V4MAPPED (&prefix)
1919 && (cp == NULL
1920 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1921 || errno != ERANGE)
1922 && *endp == '\0'
1923 && bits >= 96
1924 && bits <= 128
1925 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1926 || errno != ERANGE)
1927 && *endp == '\0'
1928 && val <= INT_MAX)
1929 {
1930 struct scopelist *newp;
1931 new_scope:
1932 newp = malloc (sizeof (*newp));
1933 if (newp == NULL)
1934 {
1935 free (line);
1936 fclose (fp);
1937 goto no_file;
1938 }
1939
1940 newp->entry.netmask = htonl (bits != 96
1941 ? (0xffffffff
1942 << (128 - bits))
1943 : 0);
1944 newp->entry.addr32 = (prefix.s6_addr32[3]
1945 & newp->entry.netmask);
1946 newp->entry.scope = val;
1947 newp->next = scopelist;
1948 scopelist = newp;
1949 ++nscopelist;
1950 scopelist_nullbits |= bits == 96;
1951 }
1952 }
1953 else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
1954 && (cp == NULL
1955 || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
1956 || errno != ERANGE)
1957 && *endp == '\0'
1958 && bits <= 32
1959 && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
1960 || errno != ERANGE)
1961 && *endp == '\0'
1962 && val <= INT_MAX)
1963 {
1964 bits += 96;
1965 goto new_scope;
1966 }
1967 }
1968 break;
1969
1970 case 10:
1971 if (strcmp (cmd, "precedence") == 0)
1972 {
1973 listp = &precedencelist;
1974 lenp = &nprecedencelist;
1975 nullbitsp = &precedencelist_nullbits;
1976 goto new_elem;
1977 }
1978 break;
1979 }
1980 }
1981
1982 free (line);
1983
1984 fclose (fp);
1985
1986 /* Create the array for the labels. */
1987 struct prefixentry *new_labels;
1988 if (nlabellist > 0)
1989 {
1990 if (!labellist_nullbits)
1991 ++nlabellist;
1992 new_labels = malloc (nlabellist * sizeof (*new_labels));
1993 if (new_labels == NULL)
1994 goto no_file;
1995
1996 int i = nlabellist;
1997 if (!labellist_nullbits)
1998 {
1999 --i;
2000 memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2001 new_labels[i].bits = 0;
2002 new_labels[i].val = 1;
2003 }
2004
2005 struct prefixlist *l = labellist;
2006 while (i-- > 0)
2007 {
2008 new_labels[i] = l->entry;
2009 l = l->next;
2010 }
2011 free_prefixlist (labellist);
2012
2013 /* Sort the entries so that the most specific ones are at
2014 the beginning. */
2015 qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2016 }
2017 else
2018 new_labels = (struct prefixentry *) default_labels;
2019
2020 struct prefixentry *new_precedence;
2021 if (nprecedencelist > 0)
2022 {
2023 if (!precedencelist_nullbits)
2024 ++nprecedencelist;
2025 new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2026 if (new_precedence == NULL)
2027 {
2028 if (new_labels != default_labels)
2029 free (new_labels);
2030 goto no_file;
2031 }
2032
2033 int i = nprecedencelist;
2034 if (!precedencelist_nullbits)
2035 {
2036 --i;
2037 memset (&new_precedence[i].prefix, '\0',
2038 sizeof (struct in6_addr));
2039 new_precedence[i].bits = 0;
2040 new_precedence[i].val = 40;
2041 }
2042
2043 struct prefixlist *l = precedencelist;
2044 while (i-- > 0)
2045 {
2046 new_precedence[i] = l->entry;
2047 l = l->next;
2048 }
2049 free_prefixlist (precedencelist);
2050
2051 /* Sort the entries so that the most specific ones are at
2052 the beginning. */
2053 qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2054 prefixcmp);
2055 }
2056 else
2057 new_precedence = (struct prefixentry *) default_precedence;
2058
2059 struct scopeentry *new_scopes;
2060 if (nscopelist > 0)
2061 {
2062 if (!scopelist_nullbits)
2063 ++nscopelist;
2064 new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2065 if (new_scopes == NULL)
2066 {
2067 if (new_labels != default_labels)
2068 free (new_labels);
2069 if (new_precedence != default_precedence)
2070 free (new_precedence);
2071 goto no_file;
2072 }
2073
2074 int i = nscopelist;
2075 if (!scopelist_nullbits)
2076 {
2077 --i;
2078 new_scopes[i].addr32 = 0;
2079 new_scopes[i].netmask = 0;
2080 new_scopes[i].scope = 14;
2081 }
2082
2083 struct scopelist *l = scopelist;
2084 while (i-- > 0)
2085 {
2086 new_scopes[i] = l->entry;
2087 l = l->next;
2088 }
2089 free_scopelist (scopelist);
2090
2091 /* Sort the entries so that the most specific ones are at
2092 the beginning. */
2093 qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2094 scopecmp);
2095 }
2096 else
2097 new_scopes = (struct scopeentry *) default_scopes;
2098
2099 /* Now we are ready to replace the values. */
2100 const struct prefixentry *old = labels;
2101 labels = new_labels;
2102 if (old != default_labels)
2103 free ((void *) old);
2104
2105 old = precedence;
2106 precedence = new_precedence;
2107 if (old != default_precedence)
2108 free ((void *) old);
2109
2110 const struct scopeentry *oldscope = scopes;
2111 scopes = new_scopes;
2112 if (oldscope != default_scopes)
2113 free ((void *) oldscope);
2114
2115 save_gaiconf_mtime (&st);
2116 }
2117 else
2118 {
2119 no_file:
2120 free_prefixlist (labellist);
2121 free_prefixlist (precedencelist);
2122 free_scopelist (scopelist);
2123
2124 /* If we previously read the file but it is gone now, free the
2125 old data and use the builtin one. Leave the reload flag
2126 alone. */
2127 fini ();
2128 }
2129}
2130
2131
2132static void
2133gaiconf_reload (void)
2134{
2135 struct stat64 st;
2136 if (__stat64 (GAICONF_FNAME, &st) != 0
2137 || !check_gaiconf_mtime (&st))
2138 gaiconf_init ();
2139}
2140
2141
2142int
2143getaddrinfo (const char *name, const char *service,
2144 const struct addrinfo *hints, struct addrinfo **pai)
2145{
2146 int i = 0, last_i = 0;
2147 int nresults = 0;
2148 struct addrinfo *p = NULL;
2149 struct gaih_service gaih_service, *pservice;
2150 struct addrinfo local_hints;
2151
2152 if (name != NULL && name[0] == '*' && name[1] == 0)
2153 name = NULL;
2154
2155 if (service != NULL && service[0] == '*' && service[1] == 0)
2156 service = NULL;
2157
2158 if (name == NULL && service == NULL)
2159 return EAI_NONAME;
2160
2161 if (hints == NULL)
2162 hints = &default_hints;
2163
2164 if (hints->ai_flags
2165 & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2166 |AI_IDN|AI_CANONIDN|DEPRECATED_AI_IDN
2167 |AI_NUMERICSERV|AI_ALL))
2168 return EAI_BADFLAGS;
2169
2170 if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2171 return EAI_BADFLAGS;
2172
2173 if (hints->ai_family != AF_UNSPEC && hints->ai_family != AF_INET
2174 && hints->ai_family != AF_INET6)
2175 return EAI_FAMILY;
2176
2177 struct in6addrinfo *in6ai = NULL;
2178 size_t in6ailen = 0;
2179 bool seen_ipv4 = false;
2180 bool seen_ipv6 = false;
2181 bool check_pf_called = false;
2182
2183 if (hints->ai_flags & AI_ADDRCONFIG)
2184 {
2185 /* We might need information about what interfaces are available.
2186 Also determine whether we have IPv4 or IPv6 interfaces or both. We
2187 cannot cache the results since new interfaces could be added at
2188 any time. */
2189 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2190 check_pf_called = true;
2191
2192 /* Now make a decision on what we return, if anything. */
2193 if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2194 {
2195 /* If we haven't seen both IPv4 and IPv6 interfaces we can
2196 narrow down the search. */
2197 if (seen_ipv4 != seen_ipv6)
2198 {
2199 local_hints = *hints;
2200 local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2201 hints = &local_hints;
2202 }
2203 }
2204 else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2205 || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2206 {
2207 /* We cannot possibly return a valid answer. */
2208 __free_in6ai (in6ai);
2209 return EAI_NONAME;
2210 }
2211 }
2212
2213 if (service && service[0])
2214 {
2215 char *c;
2216 gaih_service.name = service;
2217 gaih_service.num = strtoul (gaih_service.name, &c, 10);
2218 if (*c != '\0')
2219 {
2220 if (hints->ai_flags & AI_NUMERICSERV)
2221 {
2222 __free_in6ai (in6ai);
2223 return EAI_NONAME;
2224 }
2225
2226 gaih_service.num = -1;
2227 }
2228
2229 pservice = &gaih_service;
2230 }
2231 else
2232 pservice = NULL;
2233
2234 struct addrinfo **end = &p;
2235 unsigned int naddrs = 0;
2236 struct scratch_buffer tmpbuf;
2237
2238 scratch_buffer_init (&tmpbuf);
2239 last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf);
2240 scratch_buffer_free (&tmpbuf);
2241
2242 if (last_i != 0)
2243 {
2244 freeaddrinfo (p);
2245 __free_in6ai (in6ai);
2246
2247 return -last_i;
2248 }
2249
2250 while (*end)
2251 {
2252 end = &((*end)->ai_next);
2253 ++nresults;
2254 }
2255
2256 if (naddrs > 1)
2257 {
2258 /* Read the config file. */
2259 __libc_once_define (static, once);
2260 __typeof (once) old_once = once;
2261 __libc_once (once, gaiconf_init);
2262 /* Sort results according to RFC 3484. */
2263 struct sort_result *results;
2264 size_t *order;
2265 struct addrinfo *q;
2266 struct addrinfo *last = NULL;
2267 char *canonname = NULL;
2268 bool malloc_results;
2269 size_t alloc_size = nresults * (sizeof (*results) + sizeof (size_t));
2270
2271 malloc_results
2272 = !__libc_use_alloca (alloc_size);
2273 if (malloc_results)
2274 {
2275 results = malloc (alloc_size);
2276 if (results == NULL)
2277 {
2278 __free_in6ai (in6ai);
2279 return EAI_MEMORY;
2280 }
2281 }
2282 else
2283 results = alloca (alloc_size);
2284 order = (size_t *) (results + nresults);
2285
2286 /* Now we definitely need the interface information. */
2287 if (! check_pf_called)
2288 __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2289
2290 /* If we have information about deprecated and temporary addresses
2291 sort the array now. */
2292 if (in6ai != NULL)
2293 qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2294
2295 int fd = -1;
2296 int af = AF_UNSPEC;
2297
2298 for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2299 {
2300 results[i].dest_addr = q;
2301 results[i].native = -1;
2302 order[i] = i;
2303
2304 /* If we just looked up the address for a different
2305 protocol, reuse the result. */
2306 if (last != NULL && last->ai_addrlen == q->ai_addrlen
2307 && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2308 {
2309 memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2310 results[i - 1].source_addr_len);
2311 results[i].source_addr_len = results[i - 1].source_addr_len;
2312 results[i].got_source_addr = results[i - 1].got_source_addr;
2313 results[i].source_addr_flags = results[i - 1].source_addr_flags;
2314 results[i].prefixlen = results[i - 1].prefixlen;
2315 results[i].index = results[i - 1].index;
2316 }
2317 else
2318 {
2319 results[i].got_source_addr = false;
2320 results[i].source_addr_flags = 0;
2321 results[i].prefixlen = 0;
2322 results[i].index = 0xffffffffu;
2323
2324 /* We overwrite the type with SOCK_DGRAM since we do not
2325 want connect() to connect to the other side. If we
2326 cannot determine the source address remember this
2327 fact. */
2328 if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2329 {
2330 if (fd != -1)
2331 close_retry:
2332 __close_nocancel_nostatus (fd);
2333 af = q->ai_family;
2334 fd = __socket (af, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP);
2335 }
2336 else
2337 {
2338 /* Reset the connection. */
2339 struct sockaddr sa = { .sa_family = AF_UNSPEC };
2340 __connect (fd, &sa, sizeof (sa));
2341 }
2342
2343 socklen_t sl = sizeof (results[i].source_addr);
2344 if (fd != -1
2345 && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2346 && __getsockname (fd,
2347 (struct sockaddr *) &results[i].source_addr,
2348 &sl) == 0)
2349 {
2350 results[i].source_addr_len = sl;
2351 results[i].got_source_addr = true;
2352
2353 if (in6ai != NULL)
2354 {
2355 /* See whether the source address is on the list of
2356 deprecated or temporary addresses. */
2357 struct in6addrinfo tmp;
2358
2359 if (q->ai_family == AF_INET && af == AF_INET)
2360 {
2361 struct sockaddr_in *sinp
2362 = (struct sockaddr_in *) &results[i].source_addr;
2363 tmp.addr[0] = 0;
2364 tmp.addr[1] = 0;
2365 tmp.addr[2] = htonl (0xffff);
2366 /* Special case for lo interface, the source address
2367 being possibly different than the interface
2368 address. */
2369 if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2370 == 0x7f000000)
2371 tmp.addr[3] = htonl(0x7f000001);
2372 else
2373 tmp.addr[3] = sinp->sin_addr.s_addr;
2374 }
2375 else
2376 {
2377 struct sockaddr_in6 *sin6p
2378 = (struct sockaddr_in6 *) &results[i].source_addr;
2379 memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2380 }
2381
2382 struct in6addrinfo *found
2383 = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2384 in6aicmp);
2385 if (found != NULL)
2386 {
2387 results[i].source_addr_flags = found->flags;
2388 results[i].prefixlen = found->prefixlen;
2389 results[i].index = found->index;
2390 }
2391 }
2392
2393 if (q->ai_family == AF_INET && af == AF_INET6)
2394 {
2395 /* We have to convert the address. The socket is
2396 IPv6 and the request is for IPv4. */
2397 struct sockaddr_in6 *sin6
2398 = (struct sockaddr_in6 *) &results[i].source_addr;
2399 struct sockaddr_in *sin
2400 = (struct sockaddr_in *) &results[i].source_addr;
2401 assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2402 sin->sin_family = AF_INET;
2403 /* We do not have to initialize sin_port since this
2404 fields has the same position and size in the IPv6
2405 structure. */
2406 assert (offsetof (struct sockaddr_in, sin_port)
2407 == offsetof (struct sockaddr_in6, sin6_port));
2408 assert (sizeof (sin->sin_port)
2409 == sizeof (sin6->sin6_port));
2410 memcpy (&sin->sin_addr,
2411 &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2412 results[i].source_addr_len = sizeof (struct sockaddr_in);
2413 }
2414 }
2415 else if (errno == EAFNOSUPPORT && af == AF_INET6
2416 && q->ai_family == AF_INET)
2417 /* This could mean IPv6 sockets are IPv6-only. */
2418 goto close_retry;
2419 else
2420 /* Just make sure that if we have to process the same
2421 address again we do not copy any memory. */
2422 results[i].source_addr_len = 0;
2423 }
2424
2425 /* Remember the canonical name. */
2426 if (q->ai_canonname != NULL)
2427 {
2428 assert (canonname == NULL);
2429 canonname = q->ai_canonname;
2430 q->ai_canonname = NULL;
2431 }
2432 }
2433
2434 if (fd != -1)
2435 __close_nocancel_nostatus (fd);
2436
2437 /* We got all the source addresses we can get, now sort using
2438 the information. */
2439 struct sort_result_combo src
2440 = { .results = results, .nresults = nresults };
2441 if (__glibc_unlikely (gaiconf_reload_flag_ever_set))
2442 {
2443 __libc_lock_define_initialized (static, lock);
2444
2445 __libc_lock_lock (lock);
2446 if (__libc_once_get (old_once) && gaiconf_reload_flag)
2447 gaiconf_reload ();
2448 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2449 __libc_lock_unlock (lock);
2450 }
2451 else
2452 __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2453
2454 /* Queue the results up as they come out of sorting. */
2455 q = p = results[order[0]].dest_addr;
2456 for (i = 1; i < nresults; ++i)
2457 q = q->ai_next = results[order[i]].dest_addr;
2458 q->ai_next = NULL;
2459
2460 /* Fill in the canonical name into the new first entry. */
2461 p->ai_canonname = canonname;
2462
2463 if (malloc_results)
2464 free (results);
2465 }
2466
2467 __free_in6ai (in6ai);
2468
2469 if (p)
2470 {
2471 *pai = p;
2472 return 0;
2473 }
2474
2475 return last_i ? -last_i : EAI_NONAME;
2476}
2477libc_hidden_def (getaddrinfo)
2478
2479nss_interface_function (getaddrinfo)
2480
2481void
2482freeaddrinfo (struct addrinfo *ai)
2483{
2484 struct addrinfo *p;
2485
2486 while (ai != NULL)
2487 {
2488 p = ai;
2489 ai = ai->ai_next;
2490 free (p->ai_canonname);
2491 free (p);
2492 }
2493}
2494libc_hidden_def (freeaddrinfo)
2495