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