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