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