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