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