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