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