3385bed3332252046746fb5a84f3dce12e2bfaf4
[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                       if (!((air->family[i] == AF_INET
714                              && req->ai_family == AF_INET6
715                              && (req->ai_flags & AI_V4MAPPED) != 0)
716                             || req->ai_family == AF_UNSPEC
717                             || air->family[i] == req->ai_family))
718                         /* Skip over non-matching result.  */
719                         continue;
720
721                       socklen_t size = (air->family[i] == AF_INET
722                                         ? INADDRSZ : IN6ADDRSZ);
723                       if (*pat == NULL)
724                         {
725                           *pat = addrfree++;
726                           (*pat)->scopeid = 0;
727                         }
728                       uint32_t *pataddr = (*pat)->addr;
729                       (*pat)->next = NULL;
730                       if (added_canon || air->canon == NULL)
731                         (*pat)->name = NULL;
732                       else if (canonbuf == NULL)
733                         {
734                           size_t canonlen = strlen (air->canon) + 1;
735                           if ((req->ai_flags & AI_CANONIDN) != 0
736                               && __libc_use_alloca (alloca_used + canonlen))
737                             canonbuf = alloca_account (canonlen, alloca_used);
738                           else
739                             {
740                               canonbuf = malloc (canonlen);
741                               if (canonbuf == NULL)
742                                 {
743                                   result = -EAI_MEMORY;
744                                   goto free_and_return;
745                                 }
746                               malloc_canonbuf = true;
747                             }
748                           canon = (*pat)->name = memcpy (canonbuf, air->canon,
749                                                          canonlen);
750                         }
751
752                       if (air->family[i] == AF_INET
753                           && req->ai_family == AF_INET6
754                           && (req->ai_flags & AI_V4MAPPED))
755                         {
756                           (*pat)->family = AF_INET6;
757                           pataddr[3] = *(uint32_t *) addrs;
758                           pataddr[2] = htonl (0xffff);
759                           pataddr[1] = 0;
760                           pataddr[0] = 0;
761                           pat = &((*pat)->next);
762                           added_canon = true;
763                         }
764                       else if (req->ai_family == AF_UNSPEC
765                                || air->family[i] == req->ai_family)
766                         {
767                           (*pat)->family = air->family[i];
768                           memcpy (pataddr, addrs, size);
769                           pat = &((*pat)->next);
770                           added_canon = true;
771                           if (air->family[i] == AF_INET6)
772                             got_ipv6 = true;
773                         }
774                       addrs += size;
775                     }
776
777                   free (air);
778
779                   if (at->family == AF_UNSPEC)
780                     {
781                       result = -EAI_NONAME;
782                       goto free_and_return;
783                     }
784
785                   goto process_list;
786                 }
787               else if (err == 0)
788                 /* The database contains a negative entry.  */
789                 goto free_and_return;
790               else if (__nss_not_use_nscd_hosts == 0)
791                 {
792                   if (herrno == NETDB_INTERNAL && errno == ENOMEM)
793                     result = -EAI_MEMORY;
794                   else if (herrno == TRY_AGAIN)
795                     result = -EAI_AGAIN;
796                   else
797                     result = -EAI_SYSTEM;
798
799                   goto free_and_return;
800                 }
801             }
802 #endif
803
804           if (__nss_hosts_database == NULL)
805             no_more = __nss_database_lookup ("hosts", NULL,
806                                              "dns [!UNAVAIL=return] files",
807                                              &__nss_hosts_database);
808           else
809             no_more = 0;
810           nip = __nss_hosts_database;
811
812           /* Initialize configurations.  */
813           if (__glibc_unlikely (!_res_hconf.initialized))
814             _res_hconf_init ();
815           if (__res_maybe_init (&_res, 0) == -1)
816             no_more = 1;
817
818           /* If we are looking for both IPv4 and IPv6 address we don't
819              want the lookup functions to automatically promote IPv4
820              addresses to IPv6 addresses.  Currently this is decided
821              by setting the RES_USE_INET6 bit in _res.options.  */
822           old_res_options = _res.options;
823           _res.options &= ~RES_USE_INET6;
824
825           size_t tmpbuflen = 1024 + sizeof(struct gaih_addrtuple);
826           malloc_tmpbuf = !__libc_use_alloca (alloca_used + tmpbuflen);
827           assert (tmpbuf == NULL);
828           if (!malloc_tmpbuf)
829             tmpbuf = alloca_account (tmpbuflen, alloca_used);
830           else
831             {
832               tmpbuf = malloc (tmpbuflen);
833               if (tmpbuf == NULL)
834                 {
835                   _res.options |= old_res_options & RES_USE_INET6;
836                   result = -EAI_MEMORY;
837                   goto free_and_return;
838                 }
839             }
840
841           while (!no_more)
842             {
843               no_data = 0;
844               nss_gethostbyname4_r fct4 = NULL;
845
846               /* gethostbyname4_r sends out parallel A and AAAA queries and
847                  is thus only suitable for PF_UNSPEC.  */
848               if (req->ai_family == PF_UNSPEC)
849                 fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
850
851               if (fct4 != NULL)
852                 {
853                   int herrno;
854
855                   while (1)
856                     {
857                       rc = 0;
858                       status = DL_CALL_FCT (fct4, (name, pat, tmpbuf,
859                                                    tmpbuflen, &rc, &herrno,
860                                                    NULL));
861                       if (status == NSS_STATUS_SUCCESS)
862                         break;
863                       if (status != NSS_STATUS_TRYAGAIN
864                           || rc != ERANGE || herrno != NETDB_INTERNAL)
865                         {
866                           if (status == NSS_STATUS_TRYAGAIN
867                               && herrno == TRY_AGAIN)
868                             no_data = EAI_AGAIN;
869                           else
870                             no_data = herrno == NO_DATA;
871                           break;
872                         }
873
874                       if (!malloc_tmpbuf
875                           && __libc_use_alloca (alloca_used + 2 * tmpbuflen))
876                         tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
877                                                         2 * tmpbuflen,
878                                                         alloca_used);
879                       else
880                         {
881                           char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
882                                                 2 * tmpbuflen);
883                           if (newp == NULL)
884                             {
885                               _res.options |= old_res_options & RES_USE_INET6;
886                               result = -EAI_MEMORY;
887                               goto free_and_return;
888                             }
889                           tmpbuf = newp;
890                           malloc_tmpbuf = true;
891                           tmpbuflen = 2 * tmpbuflen;
892                         }
893                     }
894
895                   if (status == NSS_STATUS_SUCCESS)
896                     {
897                       assert (!no_data);
898                       no_data = 1;
899
900                       if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
901                         canon = (*pat)->name;
902
903                       while (*pat != NULL)
904                         {
905                           if ((*pat)->family == AF_INET
906                               && req->ai_family == AF_INET6
907                               && (req->ai_flags & AI_V4MAPPED) != 0)
908                             {
909                               uint32_t *pataddr = (*pat)->addr;
910                               (*pat)->family = AF_INET6;
911                               pataddr[3] = pataddr[0];
912                               pataddr[2] = htonl (0xffff);
913                               pataddr[1] = 0;
914                               pataddr[0] = 0;
915                               pat = &((*pat)->next);
916                               no_data = 0;
917                             }
918                           else if (req->ai_family == AF_UNSPEC
919                                    || (*pat)->family == req->ai_family)
920                             {
921                               pat = &((*pat)->next);
922
923                               no_data = 0;
924                               if (req->ai_family == AF_INET6)
925                                 got_ipv6 = true;
926                             }
927                           else
928                             *pat = ((*pat)->next);
929                         }
930                     }
931
932                   no_inet6_data = no_data;
933                 }
934               else
935                 {
936                   nss_gethostbyname3_r fct = NULL;
937                   if (req->ai_flags & AI_CANONNAME)
938                     /* No need to use this function if we do not look for
939                        the canonical name.  The function does not exist in
940                        all NSS modules and therefore the lookup would
941                        often fail.  */
942                     fct = __nss_lookup_function (nip, "gethostbyname3_r");
943                   if (fct == NULL)
944                     /* We are cheating here.  The gethostbyname2_r
945                        function does not have the same interface as
946                        gethostbyname3_r but the extra arguments the
947                        latter takes are added at the end.  So the
948                        gethostbyname2_r code will just ignore them.  */
949                     fct = __nss_lookup_function (nip, "gethostbyname2_r");
950
951                   if (fct != NULL)
952                     {
953                       if (req->ai_family == AF_INET6
954                           || req->ai_family == AF_UNSPEC)
955                         {
956                           gethosts (AF_INET6, struct in6_addr);
957                           no_inet6_data = no_data;
958                           inet6_status = status;
959                         }
960                       if (req->ai_family == AF_INET
961                           || req->ai_family == AF_UNSPEC
962                           || (req->ai_family == AF_INET6
963                               && (req->ai_flags & AI_V4MAPPED)
964                               /* Avoid generating the mapped addresses if we
965                                  know we are not going to need them.  */
966                               && ((req->ai_flags & AI_ALL) || !got_ipv6)))
967                         {
968                           gethosts (AF_INET, struct in_addr);
969
970                           if (req->ai_family == AF_INET)
971                             {
972                               no_inet6_data = no_data;
973                               inet6_status = status;
974                             }
975                         }
976
977                       /* If we found one address for AF_INET or AF_INET6,
978                          don't continue the search.  */
979                       if (inet6_status == NSS_STATUS_SUCCESS
980                           || status == NSS_STATUS_SUCCESS)
981                         {
982                           if ((req->ai_flags & AI_CANONNAME) != 0
983                               && canon == NULL)
984                             {
985                               /* If we need the canonical name, get it
986                                  from the same service as the result.  */
987                               nss_getcanonname_r cfct;
988                               int herrno;
989
990                               cfct = __nss_lookup_function (nip,
991                                                             "getcanonname_r");
992                               if (cfct != NULL)
993                                 {
994                                   const size_t max_fqdn_len = 256;
995                                   if ((req->ai_flags & AI_CANONIDN) != 0
996                                       && __libc_use_alloca (alloca_used
997                                                             + max_fqdn_len))
998                                     canonbuf = alloca_account (max_fqdn_len,
999                                                                alloca_used);
1000                                   else
1001                                     {
1002                                       canonbuf = malloc (max_fqdn_len);
1003                                       if (canonbuf == NULL)
1004                                         {
1005                                           _res.options
1006                                             |= old_res_options & RES_USE_INET6;
1007                                           result = -EAI_MEMORY;
1008                                           goto free_and_return;
1009                                         }
1010                                       malloc_canonbuf = true;
1011                                     }
1012                                   char *s;
1013
1014                                   if (DL_CALL_FCT (cfct, (at->name ?: name,
1015                                                           canonbuf,
1016                                                           max_fqdn_len,
1017                                                           &s, &rc, &herrno))
1018                                       == NSS_STATUS_SUCCESS)
1019                                     canon = s;
1020                                   else
1021                                     {
1022                                       /* If the canonical name cannot be
1023                                          determined, use the passed in
1024                                          string.  */
1025                                       if (malloc_canonbuf)
1026                                         {
1027                                           free (canonbuf);
1028                                           malloc_canonbuf = false;
1029                                         }
1030                                       canon = name;
1031                                     }
1032                                 }
1033                             }
1034                           status = NSS_STATUS_SUCCESS;
1035                         }
1036                       else
1037                         {
1038                           /* We can have different states for AF_INET and
1039                              AF_INET6.  Try to find a useful one for both.  */
1040                           if (inet6_status == NSS_STATUS_TRYAGAIN)
1041                             status = NSS_STATUS_TRYAGAIN;
1042                           else if (status == NSS_STATUS_UNAVAIL
1043                                    && inet6_status != NSS_STATUS_UNAVAIL)
1044                             status = inet6_status;
1045                         }
1046                     }
1047                   else
1048                     {
1049                       status = NSS_STATUS_UNAVAIL;
1050                       /* Could not load any of the lookup functions.  Indicate
1051                          an internal error if the failure was due to a system
1052                          error other than the file not being found.  We use the
1053                          errno from the last failed callback.  */
1054                       if (errno != 0 && errno != ENOENT)
1055                         __set_h_errno (NETDB_INTERNAL);
1056                     }
1057                 }
1058
1059               if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
1060                 break;
1061
1062               if (nip->next == NULL)
1063                 no_more = -1;
1064               else
1065                 nip = nip->next;
1066             }
1067
1068           _res.options |= old_res_options & RES_USE_INET6;
1069
1070           if (h_errno == NETDB_INTERNAL)
1071             {
1072               result = -EAI_SYSTEM;
1073               goto free_and_return;
1074             }
1075
1076           if (no_data != 0 && no_inet6_data != 0)
1077             {
1078               /* If both requests timed out report this.  */
1079               if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
1080                 result = -EAI_AGAIN;
1081               else
1082                 /* We made requests but they turned out no data.  The name
1083                    is known, though.  */
1084                 result = -EAI_NODATA;
1085
1086               goto free_and_return;
1087             }
1088         }
1089
1090     process_list:
1091       if (at->family == AF_UNSPEC)
1092         {
1093           result = -EAI_NONAME;
1094           goto free_and_return;
1095         }
1096     }
1097   else
1098     {
1099       struct gaih_addrtuple *atr;
1100       atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
1101       memset (at, '\0', sizeof (struct gaih_addrtuple));
1102
1103       if (req->ai_family == AF_UNSPEC)
1104         {
1105           at->next = __alloca (sizeof (struct gaih_addrtuple));
1106           memset (at->next, '\0', sizeof (struct gaih_addrtuple));
1107         }
1108
1109       if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
1110         {
1111           at->family = AF_INET6;
1112           if ((req->ai_flags & AI_PASSIVE) == 0)
1113             memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
1114           atr = at->next;
1115         }
1116
1117       if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
1118         {
1119           atr->family = AF_INET;
1120           if ((req->ai_flags & AI_PASSIVE) == 0)
1121             atr->addr[0] = htonl (INADDR_LOOPBACK);
1122         }
1123     }
1124
1125   {
1126     struct gaih_servtuple *st2;
1127     struct gaih_addrtuple *at2 = at;
1128     size_t socklen;
1129     sa_family_t family;
1130
1131     /*
1132       buffer is the size of an unformatted IPv6 address in printable format.
1133      */
1134     while (at2 != NULL)
1135       {
1136         /* Only the first entry gets the canonical name.  */
1137         if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
1138           {
1139             if (canon == NULL)
1140               /* If the canonical name cannot be determined, use
1141                  the passed in string.  */
1142               canon = orig_name;
1143
1144 #ifdef HAVE_LIBIDN
1145             if (req->ai_flags & AI_CANONIDN)
1146               {
1147                 int idn_flags = 0;
1148                 if (req->ai_flags & AI_IDN_ALLOW_UNASSIGNED)
1149                   idn_flags |= IDNA_ALLOW_UNASSIGNED;
1150                 if (req->ai_flags & AI_IDN_USE_STD3_ASCII_RULES)
1151                   idn_flags |= IDNA_USE_STD3_ASCII_RULES;
1152
1153                 char *out;
1154                 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
1155                 if (rc != IDNA_SUCCESS)
1156                   {
1157                     if (rc == IDNA_MALLOC_ERROR)
1158                       result = -EAI_MEMORY;
1159                     else if (rc == IDNA_DLOPEN_ERROR)
1160                       result = -EAI_SYSTEM;
1161                     else
1162                       result = -EAI_IDN_ENCODE;
1163                     goto free_and_return;
1164                   }
1165                 /* In case the output string is the same as the input
1166                    string no new string has been allocated and we
1167                    make a copy.  */
1168                 if (out == canon)
1169                   goto make_copy;
1170                 canon = out;
1171               }
1172             else
1173 #endif
1174               {
1175 #ifdef HAVE_LIBIDN
1176               make_copy:
1177 #endif
1178                 if (malloc_canonbuf)
1179                   /* We already allocated the string using malloc.  */
1180                   malloc_canonbuf = false;
1181                 else
1182                   {
1183                     canon = strdup (canon);
1184                     if (canon == NULL)
1185                       {
1186                         result = -EAI_MEMORY;
1187                         goto free_and_return;
1188                       }
1189                   }
1190               }
1191           }
1192
1193         family = at2->family;
1194         if (family == AF_INET6)
1195           {
1196             socklen = sizeof (struct sockaddr_in6);
1197
1198             /* If we looked up IPv4 mapped address discard them here if
1199                the caller isn't interested in all address and we have
1200                found at least one IPv6 address.  */
1201             if (got_ipv6
1202                 && (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
1203                 && IN6_IS_ADDR_V4MAPPED (at2->addr))
1204               goto ignore;
1205           }
1206         else
1207           socklen = sizeof (struct sockaddr_in);
1208
1209         for (st2 = st; st2 != NULL; st2 = st2->next)
1210           {
1211             struct addrinfo *ai;
1212             ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
1213             if (ai == NULL)
1214               {
1215                 free ((char *) canon);
1216                 result = -EAI_MEMORY;
1217                 goto free_and_return;
1218               }
1219
1220             ai->ai_flags = req->ai_flags;
1221             ai->ai_family = family;
1222             ai->ai_socktype = st2->socktype;
1223             ai->ai_protocol = st2->protocol;
1224             ai->ai_addrlen = socklen;
1225             ai->ai_addr = (void *) (ai + 1);
1226
1227             /* We only add the canonical name once.  */
1228             ai->ai_canonname = (char *) canon;
1229             canon = NULL;
1230
1231 #ifdef _HAVE_SA_LEN
1232             ai->ai_addr->sa_len = socklen;
1233 #endif /* _HAVE_SA_LEN */
1234             ai->ai_addr->sa_family = family;
1235
1236             /* In case of an allocation error the list must be NULL
1237                terminated.  */
1238             ai->ai_next = NULL;
1239
1240             if (family == AF_INET6)
1241               {
1242                 struct sockaddr_in6 *sin6p =
1243                   (struct sockaddr_in6 *) ai->ai_addr;
1244
1245                 sin6p->sin6_port = st2->port;
1246                 sin6p->sin6_flowinfo = 0;
1247                 memcpy (&sin6p->sin6_addr,
1248                         at2->addr, sizeof (struct in6_addr));
1249                 sin6p->sin6_scope_id = at2->scopeid;
1250               }
1251             else
1252               {
1253                 struct sockaddr_in *sinp =
1254                   (struct sockaddr_in *) ai->ai_addr;
1255                 sinp->sin_port = st2->port;
1256                 memcpy (&sinp->sin_addr,
1257                         at2->addr, sizeof (struct in_addr));
1258                 memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
1259               }
1260
1261             pai = &(ai->ai_next);
1262           }
1263
1264         ++*naddrs;
1265
1266       ignore:
1267         at2 = at2->next;
1268       }
1269   }
1270
1271  free_and_return:
1272   if (malloc_name)
1273     free ((char *) name);
1274   if (malloc_addrmem)
1275     free (addrmem);
1276   if (malloc_canonbuf)
1277     free (canonbuf);
1278   if (malloc_tmpbuf)
1279     free (tmpbuf);
1280
1281   return result;
1282 }
1283
1284
1285 struct sort_result
1286 {
1287   struct addrinfo *dest_addr;
1288   /* Using sockaddr_storage is for now overkill.  We only support IPv4
1289      and IPv6 so far.  If this changes at some point we can adjust the
1290      type here.  */
1291   struct sockaddr_in6 source_addr;
1292   uint8_t source_addr_len;
1293   bool got_source_addr;
1294   uint8_t source_addr_flags;
1295   uint8_t prefixlen;
1296   uint32_t index;
1297   int32_t native;
1298 };
1299
1300 struct sort_result_combo
1301 {
1302   struct sort_result *results;
1303   int nresults;
1304 };
1305
1306
1307 #if __BYTE_ORDER == __BIG_ENDIAN
1308 # define htonl_c(n) n
1309 #else
1310 # define htonl_c(n) __bswap_constant_32 (n)
1311 #endif
1312
1313 static const struct scopeentry
1314 {
1315   union
1316   {
1317     char addr[4];
1318     uint32_t addr32;
1319   };
1320   uint32_t netmask;
1321   int32_t scope;
1322 } default_scopes[] =
1323   {
1324     /* Link-local addresses: scope 2.  */
1325     { { { 169, 254, 0, 0 } }, htonl_c (0xffff0000), 2 },
1326     { { { 127, 0, 0, 0 } }, htonl_c (0xff000000), 2 },
1327     /* Default: scope 14.  */
1328     { { { 0, 0, 0, 0 } }, htonl_c (0x00000000), 14 }
1329   };
1330
1331 /* The label table.  */
1332 static const struct scopeentry *scopes;
1333
1334
1335 static int
1336 get_scope (const struct sockaddr_in6 *in6)
1337 {
1338   int scope;
1339   if (in6->sin6_family == PF_INET6)
1340     {
1341       if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
1342         {
1343           if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)
1344               /* RFC 4291 2.5.3 says that the loopback address is to be
1345                  treated like a link-local address.  */
1346               || IN6_IS_ADDR_LOOPBACK (&in6->sin6_addr))
1347             scope = 2;
1348           else if (IN6_IS_ADDR_SITELOCAL (&in6->sin6_addr))
1349             scope = 5;
1350           else
1351             /* XXX Is this the correct default behavior?  */
1352             scope = 14;
1353         }
1354       else
1355         scope = in6->sin6_addr.s6_addr[1] & 0xf;
1356     }
1357   else if (in6->sin6_family == PF_INET)
1358     {
1359       const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1360
1361       size_t cnt = 0;
1362       while (1)
1363         {
1364           if ((in->sin_addr.s_addr & scopes[cnt].netmask)
1365               == scopes[cnt].addr32)
1366             return scopes[cnt].scope;
1367
1368           ++cnt;
1369         }
1370       /* NOTREACHED */
1371     }
1372   else
1373     /* XXX What is a good default?  */
1374     scope = 15;
1375
1376   return scope;
1377 }
1378
1379
1380 struct prefixentry
1381 {
1382   struct in6_addr prefix;
1383   unsigned int bits;
1384   int val;
1385 };
1386
1387
1388 /* The label table.  */
1389 static const struct prefixentry *labels;
1390
1391 /* Default labels.  */
1392 static const struct prefixentry default_labels[] =
1393   {
1394     /* See RFC 3484 for the details.  */
1395     { { .__in6_u
1396         = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1397                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1398       }, 128, 0 },
1399     { { .__in6_u
1400         = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1401                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1402       }, 16, 2 },
1403     { { .__in6_u
1404         = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1405                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1406       }, 96, 3 },
1407     { { .__in6_u
1408         = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1409                             0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1410       }, 96, 4 },
1411     /* The next two entries differ from RFC 3484.  We need to treat
1412        IPv6 site-local addresses special because they are never NATed,
1413        unlike site-locale IPv4 addresses.  If this would not happen, on
1414        machines which have only IPv4 and IPv6 site-local addresses, the
1415        sorting would prefer the IPv6 site-local addresses, causing
1416        unnecessary delays when trying to connect to a global IPv6 address
1417        through a site-local IPv6 address.  */
1418     { { .__in6_u
1419         = { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1420                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1421       }, 10, 5 },
1422     { { .__in6_u
1423         = { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1424                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1425       }, 7, 6 },
1426     /* Additional rule for Teredo tunnels.  */
1427     { { .__in6_u
1428         = { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1429                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1430       }, 32, 7 },
1431     { { .__in6_u
1432         = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1433                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1434       }, 0, 1 }
1435   };
1436
1437
1438 /* The precedence table.  */
1439 static const struct prefixentry *precedence;
1440
1441 /* The default precedences.  */
1442 static const struct prefixentry default_precedence[] =
1443   {
1444     /* See RFC 3484 for the details.  */
1445     { { .__in6_u
1446         = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1447                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1448       }, 128, 50 },
1449     { { .__in6_u
1450         = { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1451                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1452       }, 16, 30 },
1453     { { .__in6_u
1454         = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1455                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1456       }, 96, 20 },
1457     { { .__in6_u
1458         = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1459                             0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
1460       }, 96, 10 },
1461     { { .__in6_u
1462         = { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1463                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
1464       }, 0, 40 }
1465   };
1466
1467
1468 static int
1469 match_prefix (const struct sockaddr_in6 *in6,
1470               const struct prefixentry *list, int default_val)
1471 {
1472   int idx;
1473   struct sockaddr_in6 in6_mem;
1474
1475   if (in6->sin6_family == PF_INET)
1476     {
1477       const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
1478
1479       /* Construct a V4-to-6 mapped address.  */
1480       in6_mem.sin6_family = PF_INET6;
1481       in6_mem.sin6_port = in->sin_port;
1482       in6_mem.sin6_flowinfo = 0;
1483       memset (&in6_mem.sin6_addr, '\0', sizeof (in6_mem.sin6_addr));
1484       in6_mem.sin6_addr.s6_addr16[5] = 0xffff;
1485       in6_mem.sin6_addr.s6_addr32[3] = in->sin_addr.s_addr;
1486       in6_mem.sin6_scope_id = 0;
1487
1488       in6 = &in6_mem;
1489     }
1490   else if (in6->sin6_family != PF_INET6)
1491     return default_val;
1492
1493   for (idx = 0; ; ++idx)
1494     {
1495       unsigned int bits = list[idx].bits;
1496       const uint8_t *mask = list[idx].prefix.s6_addr;
1497       const uint8_t *val = in6->sin6_addr.s6_addr;
1498
1499       while (bits >= 8)
1500         {
1501           if (*mask != *val)
1502             break;
1503
1504           ++mask;
1505           ++val;
1506           bits -= 8;
1507         }
1508
1509       if (bits < 8)
1510         {
1511           if ((*mask & (0xff00 >> bits)) == (*val & (0xff00 >> bits)))
1512             /* Match!  */
1513             break;
1514         }
1515     }
1516
1517   return list[idx].val;
1518 }
1519
1520
1521 static int
1522 get_label (const struct sockaddr_in6 *in6)
1523 {
1524   /* XXX What is a good default value?  */
1525   return match_prefix (in6, labels, INT_MAX);
1526 }
1527
1528
1529 static int
1530 get_precedence (const struct sockaddr_in6 *in6)
1531 {
1532   /* XXX What is a good default value?  */
1533   return match_prefix (in6, precedence, 0);
1534 }
1535
1536
1537 /* Find last bit set in a word.  */
1538 static int
1539 fls (uint32_t a)
1540 {
1541   uint32_t mask;
1542   int n;
1543   for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
1544     if ((a & mask) != 0)
1545       break;
1546   return n;
1547 }
1548
1549
1550 static int
1551 rfc3484_sort (const void *p1, const void *p2, void *arg)
1552 {
1553   const size_t idx1 = *(const size_t *) p1;
1554   const size_t idx2 = *(const size_t *) p2;
1555   struct sort_result_combo *src = (struct sort_result_combo *) arg;
1556   struct sort_result *a1 = &src->results[idx1];
1557   struct sort_result *a2 = &src->results[idx2];
1558
1559   /* Rule 1: Avoid unusable destinations.
1560      We have the got_source_addr flag set if the destination is reachable.  */
1561   if (a1->got_source_addr && ! a2->got_source_addr)
1562     return -1;
1563   if (! a1->got_source_addr && a2->got_source_addr)
1564     return 1;
1565
1566
1567   /* Rule 2: Prefer matching scope.  Only interesting if both
1568      destination addresses are IPv6.  */
1569   int a1_dst_scope
1570     = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1571
1572   int a2_dst_scope
1573     = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1574
1575   if (a1->got_source_addr)
1576     {
1577       int a1_src_scope = get_scope (&a1->source_addr);
1578       int a2_src_scope = get_scope (&a2->source_addr);
1579
1580       if (a1_dst_scope == a1_src_scope && a2_dst_scope != a2_src_scope)
1581         return -1;
1582       if (a1_dst_scope != a1_src_scope && a2_dst_scope == a2_src_scope)
1583         return 1;
1584     }
1585
1586
1587   /* Rule 3: Avoid deprecated addresses.  */
1588   if (a1->got_source_addr)
1589     {
1590       if (!(a1->source_addr_flags & in6ai_deprecated)
1591           && (a2->source_addr_flags & in6ai_deprecated))
1592         return -1;
1593       if ((a1->source_addr_flags & in6ai_deprecated)
1594           && !(a2->source_addr_flags & in6ai_deprecated))
1595         return 1;
1596     }
1597
1598   /* Rule 4: Prefer home addresses.  */
1599   if (a1->got_source_addr)
1600     {
1601       if (!(a1->source_addr_flags & in6ai_homeaddress)
1602           && (a2->source_addr_flags & in6ai_homeaddress))
1603         return 1;
1604       if ((a1->source_addr_flags & in6ai_homeaddress)
1605           && !(a2->source_addr_flags & in6ai_homeaddress))
1606         return -1;
1607     }
1608
1609   /* Rule 5: Prefer matching label.  */
1610   if (a1->got_source_addr)
1611     {
1612       int a1_dst_label
1613         = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1614       int a1_src_label = get_label (&a1->source_addr);
1615
1616       int a2_dst_label
1617         = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1618       int a2_src_label = get_label (&a2->source_addr);
1619
1620       if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
1621         return -1;
1622       if (a1_dst_label != a1_src_label && a2_dst_label == a2_src_label)
1623         return 1;
1624     }
1625
1626
1627   /* Rule 6: Prefer higher precedence.  */
1628   int a1_prec
1629     = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
1630   int a2_prec
1631     = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
1632
1633   if (a1_prec > a2_prec)
1634     return -1;
1635   if (a1_prec < a2_prec)
1636     return 1;
1637
1638
1639   /* Rule 7: Prefer native transport.  */
1640   if (a1->got_source_addr)
1641     {
1642       /* The same interface index means the same interface which means
1643          there is no difference in transport.  This should catch many
1644          (most?) cases.  */
1645       if (a1->index != a2->index)
1646         {
1647           int a1_native = a1->native;
1648           int a2_native = a2->native;
1649
1650           if (a1_native == -1 || a2_native == -1)
1651             {
1652               uint32_t a1_index;
1653               if (a1_native == -1)
1654                 {
1655                   /* If we do not have the information use 'native' as
1656                      the default.  */
1657                   a1_native = 0;
1658                   a1_index = a1->index;
1659                 }
1660               else
1661                 a1_index = 0xffffffffu;
1662
1663               uint32_t a2_index;
1664               if (a2_native == -1)
1665                 {
1666                   /* If we do not have the information use 'native' as
1667                      the default.  */
1668                   a2_native = 0;
1669                   a2_index = a2->index;
1670                 }
1671               else
1672                 a2_index = 0xffffffffu;
1673
1674               __check_native (a1_index, &a1_native, a2_index, &a2_native);
1675
1676               /* Fill in the results in all the records.  */
1677               for (int i = 0; i < src->nresults; ++i)
1678                 if (a1_index != -1 && src->results[i].index == a1_index)
1679                   {
1680                     assert (src->results[i].native == -1
1681                             || src->results[i].native == a1_native);
1682                     src->results[i].native = a1_native;
1683                   }
1684                 else if (a2_index != -1 && src->results[i].index == a2_index)
1685                   {
1686                     assert (src->results[i].native == -1
1687                             || src->results[i].native == a2_native);
1688                     src->results[i].native = a2_native;
1689                   }
1690             }
1691
1692           if (a1_native && !a2_native)
1693             return -1;
1694           if (!a1_native && a2_native)
1695             return 1;
1696         }
1697     }
1698
1699
1700   /* Rule 8: Prefer smaller scope.  */
1701   if (a1_dst_scope < a2_dst_scope)
1702     return -1;
1703   if (a1_dst_scope > a2_dst_scope)
1704     return 1;
1705
1706
1707   /* Rule 9: Use longest matching prefix.  */
1708   if (a1->got_source_addr
1709       && a1->dest_addr->ai_family == a2->dest_addr->ai_family)
1710     {
1711       int bit1 = 0;
1712       int bit2 = 0;
1713
1714       if (a1->dest_addr->ai_family == PF_INET)
1715         {
1716           assert (a1->source_addr.sin6_family == PF_INET);
1717           assert (a2->source_addr.sin6_family == PF_INET);
1718
1719           /* Outside of subnets, as defined by the network masks,
1720              common address prefixes for IPv4 addresses make no sense.
1721              So, define a non-zero value only if source and
1722              destination address are on the same subnet.  */
1723           struct sockaddr_in *in1_dst
1724             = (struct sockaddr_in *) a1->dest_addr->ai_addr;
1725           in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
1726           struct sockaddr_in *in1_src
1727             = (struct sockaddr_in *) &a1->source_addr;
1728           in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
1729           in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
1730
1731           if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
1732             bit1 = fls (in1_dst_addr ^ in1_src_addr);
1733
1734           struct sockaddr_in *in2_dst
1735             = (struct sockaddr_in *) a2->dest_addr->ai_addr;
1736           in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
1737           struct sockaddr_in *in2_src
1738             = (struct sockaddr_in *) &a2->source_addr;
1739           in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
1740           in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
1741
1742           if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
1743             bit2 = fls (in2_dst_addr ^ in2_src_addr);
1744         }
1745       else if (a1->dest_addr->ai_family == PF_INET6)
1746         {
1747           assert (a1->source_addr.sin6_family == PF_INET6);
1748           assert (a2->source_addr.sin6_family == PF_INET6);
1749
1750           struct sockaddr_in6 *in1_dst;
1751           struct sockaddr_in6 *in1_src;
1752           struct sockaddr_in6 *in2_dst;
1753           struct sockaddr_in6 *in2_src;
1754
1755           in1_dst = (struct sockaddr_in6 *) a1->dest_addr->ai_addr;
1756           in1_src = (struct sockaddr_in6 *) &a1->source_addr;
1757           in2_dst = (struct sockaddr_in6 *) a2->dest_addr->ai_addr;
1758           in2_src = (struct sockaddr_in6 *) &a2->source_addr;
1759
1760           int i;
1761           for (i = 0; i < 4; ++i)
1762             if (in1_dst->sin6_addr.s6_addr32[i]
1763                 != in1_src->sin6_addr.s6_addr32[i]
1764                 || (in2_dst->sin6_addr.s6_addr32[i]
1765                     != in2_src->sin6_addr.s6_addr32[i]))
1766               break;
1767
1768           if (i < 4)
1769             {
1770               bit1 = fls (ntohl (in1_dst->sin6_addr.s6_addr32[i]
1771                                  ^ in1_src->sin6_addr.s6_addr32[i]));
1772               bit2 = fls (ntohl (in2_dst->sin6_addr.s6_addr32[i]
1773                                  ^ in2_src->sin6_addr.s6_addr32[i]));
1774             }
1775         }
1776
1777       if (bit1 > bit2)
1778         return -1;
1779       if (bit1 < bit2)
1780         return 1;
1781     }
1782
1783
1784   /* Rule 10: Otherwise, leave the order unchanged.  To ensure this
1785      compare with the value indicating the order in which the entries
1786      have been received from the services.  NB: no two entries can have
1787      the same order so the test will never return zero.  */
1788   return idx1 < idx2 ? -1 : 1;
1789 }
1790
1791
1792 static int
1793 in6aicmp (const void *p1, const void *p2)
1794 {
1795   struct in6addrinfo *a1 = (struct in6addrinfo *) p1;
1796   struct in6addrinfo *a2 = (struct in6addrinfo *) p2;
1797
1798   return memcmp (a1->addr, a2->addr, sizeof (a1->addr));
1799 }
1800
1801
1802 /* Name of the config file for RFC 3484 sorting (for now).  */
1803 #define GAICONF_FNAME "/etc/gai.conf"
1804
1805
1806 /* Non-zero if we are supposed to reload the config file automatically
1807    whenever it changed.  */
1808 static int gaiconf_reload_flag;
1809
1810 /* Non-zero if gaiconf_reload_flag was ever set to true.  */
1811 static int gaiconf_reload_flag_ever_set;
1812
1813 /* Last modification time.  */
1814 #ifdef _STATBUF_ST_NSEC
1815
1816 static struct timespec gaiconf_mtime;
1817
1818 static inline void
1819 save_gaiconf_mtime (const struct stat64 *st)
1820 {
1821   gaiconf_mtime = st->st_mtim;
1822 }
1823
1824 static inline bool
1825 check_gaiconf_mtime (const struct stat64 *st)
1826 {
1827   return (st->st_mtim.tv_sec == gaiconf_mtime.tv_sec
1828           && st->st_mtim.tv_nsec == gaiconf_mtime.tv_nsec);
1829 }
1830
1831 #else
1832
1833 static time_t gaiconf_mtime;
1834
1835 static inline void
1836 save_gaiconf_mtime (const struct stat64 *st)
1837 {
1838   gaiconf_mtime = st->st_mtime;
1839 }
1840
1841 static inline bool
1842 check_gaiconf_mtime (const struct stat64 *st)
1843 {
1844   return st->st_mtime == gaiconf_mtime;
1845 }
1846
1847 #endif
1848
1849
1850 libc_freeres_fn(fini)
1851 {
1852   if (labels != default_labels)
1853     {
1854       const struct prefixentry *old = labels;
1855       labels = default_labels;
1856       free ((void *) old);
1857     }
1858
1859   if (precedence != default_precedence)
1860     {
1861       const struct prefixentry *old = precedence;
1862       precedence = default_precedence;
1863       free ((void *) old);
1864     }
1865
1866   if (scopes != default_scopes)
1867     {
1868       const struct scopeentry *old = scopes;
1869       scopes = default_scopes;
1870       free ((void *) old);
1871     }
1872 }
1873
1874
1875 struct prefixlist
1876 {
1877   struct prefixentry entry;
1878   struct prefixlist *next;
1879 };
1880
1881
1882 struct scopelist
1883 {
1884   struct scopeentry entry;
1885   struct scopelist *next;
1886 };
1887
1888
1889 static void
1890 free_prefixlist (struct prefixlist *list)
1891 {
1892   while (list != NULL)
1893     {
1894       struct prefixlist *oldp = list;
1895       list = list->next;
1896       free (oldp);
1897     }
1898 }
1899
1900
1901 static void
1902 free_scopelist (struct scopelist *list)
1903 {
1904   while (list != NULL)
1905     {
1906       struct scopelist *oldp = list;
1907       list = list->next;
1908       free (oldp);
1909     }
1910 }
1911
1912
1913 static int
1914 prefixcmp (const void *p1, const void *p2)
1915 {
1916   const struct prefixentry *e1 = (const struct prefixentry *) p1;
1917   const struct prefixentry *e2 = (const struct prefixentry *) p2;
1918
1919   if (e1->bits < e2->bits)
1920     return 1;
1921   if (e1->bits == e2->bits)
1922     return 0;
1923   return -1;
1924 }
1925
1926
1927 static int
1928 scopecmp (const void *p1, const void *p2)
1929 {
1930   const struct scopeentry *e1 = (const struct scopeentry *) p1;
1931   const struct scopeentry *e2 = (const struct scopeentry *) p2;
1932
1933   if (e1->netmask > e2->netmask)
1934     return -1;
1935   if (e1->netmask == e2->netmask)
1936     return 0;
1937   return 1;
1938 }
1939
1940
1941 static void
1942 gaiconf_init (void)
1943 {
1944   struct prefixlist *labellist = NULL;
1945   size_t nlabellist = 0;
1946   bool labellist_nullbits = false;
1947   struct prefixlist *precedencelist = NULL;
1948   size_t nprecedencelist = 0;
1949   bool precedencelist_nullbits = false;
1950   struct scopelist *scopelist =  NULL;
1951   size_t nscopelist = 0;
1952   bool scopelist_nullbits = false;
1953
1954   FILE *fp = fopen (GAICONF_FNAME, "rce");
1955   if (fp != NULL)
1956     {
1957       struct stat64 st;
1958       if (__fxstat64 (_STAT_VER, fileno (fp), &st) != 0)
1959         {
1960           fclose (fp);
1961           goto no_file;
1962         }
1963
1964       char *line = NULL;
1965       size_t linelen = 0;
1966
1967       __fsetlocking (fp, FSETLOCKING_BYCALLER);
1968
1969       while (!feof_unlocked (fp))
1970         {
1971           ssize_t n = __getline (&line, &linelen, fp);
1972           if (n <= 0)
1973             break;
1974
1975           /* Handle comments.  No escaping possible so this is easy.  */
1976           char *cp = strchr (line, '#');
1977           if (cp != NULL)
1978             *cp = '\0';
1979
1980           cp = line;
1981           while (isspace (*cp))
1982             ++cp;
1983
1984           char *cmd = cp;
1985           while (*cp != '\0' && !isspace (*cp))
1986             ++cp;
1987           size_t cmdlen = cp - cmd;
1988
1989           if (*cp != '\0')
1990             *cp++ = '\0';
1991           while (isspace (*cp))
1992             ++cp;
1993
1994           char *val1 = cp;
1995           while (*cp != '\0' && !isspace (*cp))
1996             ++cp;
1997           size_t val1len = cp - cmd;
1998
1999           /* We always need at least two values.  */
2000           if (val1len == 0)
2001             continue;
2002
2003           if (*cp != '\0')
2004             *cp++ = '\0';
2005           while (isspace (*cp))
2006             ++cp;
2007
2008           char *val2 = cp;
2009           while (*cp != '\0' && !isspace (*cp))
2010             ++cp;
2011
2012           /*  Ignore the rest of the line.  */
2013           *cp = '\0';
2014
2015           struct prefixlist **listp;
2016           size_t *lenp;
2017           bool *nullbitsp;
2018           switch (cmdlen)
2019             {
2020             case 5:
2021               if (strcmp (cmd, "label") == 0)
2022                 {
2023                   struct in6_addr prefix;
2024                   unsigned long int bits;
2025                   unsigned long int val;
2026                   char *endp;
2027
2028                   listp = &labellist;
2029                   lenp = &nlabellist;
2030                   nullbitsp = &labellist_nullbits;
2031
2032                 new_elem:
2033                   bits = 128;
2034                   __set_errno (0);
2035                   cp = strchr (val1, '/');
2036                   if (cp != NULL)
2037                     *cp++ = '\0';
2038                   if (inet_pton (AF_INET6, val1, &prefix)
2039                       && (cp == NULL
2040                           || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2041                           || errno != ERANGE)
2042                       && *endp == '\0'
2043                       && bits <= 128
2044                       && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2045                           || errno != ERANGE)
2046                       && *endp == '\0'
2047                       && val <= INT_MAX)
2048                     {
2049                       struct prefixlist *newp = malloc (sizeof (*newp));
2050                       if (newp == NULL)
2051                         {
2052                           free (line);
2053                           fclose (fp);
2054                           goto no_file;
2055                         }
2056
2057                       memcpy (&newp->entry.prefix, &prefix, sizeof (prefix));
2058                       newp->entry.bits = bits;
2059                       newp->entry.val = val;
2060                       newp->next = *listp;
2061                       *listp = newp;
2062                       ++*lenp;
2063                       *nullbitsp |= bits == 0;
2064                     }
2065                 }
2066               break;
2067
2068             case 6:
2069               if (strcmp (cmd, "reload") == 0)
2070                 {
2071                   gaiconf_reload_flag = strcmp (val1, "yes") == 0;
2072                   if (gaiconf_reload_flag)
2073                     gaiconf_reload_flag_ever_set = 1;
2074                 }
2075               break;
2076
2077             case 7:
2078               if (strcmp (cmd, "scopev4") == 0)
2079                 {
2080                   struct in6_addr prefix;
2081                   unsigned long int bits;
2082                   unsigned long int val;
2083                   char *endp;
2084
2085                   bits = 32;
2086                   __set_errno (0);
2087                   cp = strchr (val1, '/');
2088                   if (cp != NULL)
2089                     *cp++ = '\0';
2090                   if (inet_pton (AF_INET6, val1, &prefix))
2091                     {
2092                       bits = 128;
2093                       if (IN6_IS_ADDR_V4MAPPED (&prefix)
2094                           && (cp == NULL
2095                               || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2096                               || errno != ERANGE)
2097                           && *endp == '\0'
2098                           && bits >= 96
2099                           && bits <= 128
2100                           && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2101                               || errno != ERANGE)
2102                           && *endp == '\0'
2103                           && val <= INT_MAX)
2104                         {
2105                           struct scopelist *newp;
2106                         new_scope:
2107                           newp = malloc (sizeof (*newp));
2108                           if (newp == NULL)
2109                             {
2110                               free (line);
2111                               fclose (fp);
2112                               goto no_file;
2113                             }
2114
2115                           newp->entry.netmask = htonl (bits != 96
2116                                                        ? (0xffffffff
2117                                                           << (128 - bits))
2118                                                        : 0);
2119                           newp->entry.addr32 = (prefix.s6_addr32[3]
2120                                                 & newp->entry.netmask);
2121                           newp->entry.scope = val;
2122                           newp->next = scopelist;
2123                           scopelist = newp;
2124                           ++nscopelist;
2125                           scopelist_nullbits |= bits == 96;
2126                         }
2127                     }
2128                   else if (inet_pton (AF_INET, val1, &prefix.s6_addr32[3])
2129                            && (cp == NULL
2130                                || (bits = strtoul (cp, &endp, 10)) != ULONG_MAX
2131                                || errno != ERANGE)
2132                            && *endp == '\0'
2133                            && bits <= 32
2134                            && ((val = strtoul (val2, &endp, 10)) != ULONG_MAX
2135                                || errno != ERANGE)
2136                            && *endp == '\0'
2137                            && val <= INT_MAX)
2138                     {
2139                       bits += 96;
2140                       goto new_scope;
2141                     }
2142                 }
2143               break;
2144
2145             case 10:
2146               if (strcmp (cmd, "precedence") == 0)
2147                 {
2148                   listp = &precedencelist;
2149                   lenp = &nprecedencelist;
2150                   nullbitsp = &precedencelist_nullbits;
2151                   goto new_elem;
2152                 }
2153               break;
2154             }
2155         }
2156
2157       free (line);
2158
2159       fclose (fp);
2160
2161       /* Create the array for the labels.  */
2162       struct prefixentry *new_labels;
2163       if (nlabellist > 0)
2164         {
2165           if (!labellist_nullbits)
2166             ++nlabellist;
2167           new_labels = malloc (nlabellist * sizeof (*new_labels));
2168           if (new_labels == NULL)
2169             goto no_file;
2170
2171           int i = nlabellist;
2172           if (!labellist_nullbits)
2173             {
2174               --i;
2175               memset (&new_labels[i].prefix, '\0', sizeof (struct in6_addr));
2176               new_labels[i].bits = 0;
2177               new_labels[i].val = 1;
2178             }
2179
2180           struct prefixlist *l = labellist;
2181           while (i-- > 0)
2182             {
2183               new_labels[i] = l->entry;
2184               l = l->next;
2185             }
2186           free_prefixlist (labellist);
2187
2188           /* Sort the entries so that the most specific ones are at
2189              the beginning.  */
2190           qsort (new_labels, nlabellist, sizeof (*new_labels), prefixcmp);
2191         }
2192       else
2193         new_labels = (struct prefixentry *) default_labels;
2194
2195       struct prefixentry *new_precedence;
2196       if (nprecedencelist > 0)
2197         {
2198           if (!precedencelist_nullbits)
2199             ++nprecedencelist;
2200           new_precedence = malloc (nprecedencelist * sizeof (*new_precedence));
2201           if (new_precedence == NULL)
2202             {
2203               if (new_labels != default_labels)
2204                 free (new_labels);
2205               goto no_file;
2206             }
2207
2208           int i = nprecedencelist;
2209           if (!precedencelist_nullbits)
2210             {
2211               --i;
2212               memset (&new_precedence[i].prefix, '\0',
2213                       sizeof (struct in6_addr));
2214               new_precedence[i].bits = 0;
2215               new_precedence[i].val = 40;
2216             }
2217
2218           struct prefixlist *l = precedencelist;
2219           while (i-- > 0)
2220             {
2221               new_precedence[i] = l->entry;
2222               l = l->next;
2223             }
2224           free_prefixlist (precedencelist);
2225
2226           /* Sort the entries so that the most specific ones are at
2227              the beginning.  */
2228           qsort (new_precedence, nprecedencelist, sizeof (*new_precedence),
2229                  prefixcmp);
2230         }
2231       else
2232         new_precedence = (struct prefixentry *) default_precedence;
2233
2234       struct scopeentry *new_scopes;
2235       if (nscopelist > 0)
2236         {
2237           if (!scopelist_nullbits)
2238             ++nscopelist;
2239           new_scopes = malloc (nscopelist * sizeof (*new_scopes));
2240           if (new_scopes == NULL)
2241             {
2242               if (new_labels != default_labels)
2243                 free (new_labels);
2244               if (new_precedence != default_precedence)
2245                 free (new_precedence);
2246               goto no_file;
2247             }
2248
2249           int i = nscopelist;
2250           if (!scopelist_nullbits)
2251             {
2252               --i;
2253               new_scopes[i].addr32 = 0;
2254               new_scopes[i].netmask = 0;
2255               new_scopes[i].scope = 14;
2256             }
2257
2258           struct scopelist *l = scopelist;
2259           while (i-- > 0)
2260             {
2261               new_scopes[i] = l->entry;
2262               l = l->next;
2263             }
2264           free_scopelist (scopelist);
2265
2266           /* Sort the entries so that the most specific ones are at
2267              the beginning.  */
2268           qsort (new_scopes, nscopelist, sizeof (*new_scopes),
2269                  scopecmp);
2270         }
2271       else
2272         new_scopes = (struct scopeentry *) default_scopes;
2273
2274       /* Now we are ready to replace the values.  */
2275       const struct prefixentry *old = labels;
2276       labels = new_labels;
2277       if (old != default_labels)
2278         free ((void *) old);
2279
2280       old = precedence;
2281       precedence = new_precedence;
2282       if (old != default_precedence)
2283         free ((void *) old);
2284
2285       const struct scopeentry *oldscope = scopes;
2286       scopes = new_scopes;
2287       if (oldscope != default_scopes)
2288         free ((void *) oldscope);
2289
2290       save_gaiconf_mtime (&st);
2291     }
2292   else
2293     {
2294     no_file:
2295       free_prefixlist (labellist);
2296       free_prefixlist (precedencelist);
2297       free_scopelist (scopelist);
2298
2299       /* If we previously read the file but it is gone now, free the
2300          old data and use the builtin one.  Leave the reload flag
2301          alone.  */
2302       fini ();
2303     }
2304 }
2305
2306
2307 static void
2308 gaiconf_reload (void)
2309 {
2310   struct stat64 st;
2311   if (__xstat64 (_STAT_VER, GAICONF_FNAME, &st) != 0
2312       || !check_gaiconf_mtime (&st))
2313     gaiconf_init ();
2314 }
2315
2316
2317 int
2318 getaddrinfo (const char *name, const char *service,
2319              const struct addrinfo *hints, struct addrinfo **pai)
2320 {
2321   int i = 0, last_i = 0;
2322   int nresults = 0;
2323   struct addrinfo *p = NULL;
2324   struct gaih_service gaih_service, *pservice;
2325   struct addrinfo local_hints;
2326
2327   if (name != NULL && name[0] == '*' && name[1] == 0)
2328     name = NULL;
2329
2330   if (service != NULL && service[0] == '*' && service[1] == 0)
2331     service = NULL;
2332
2333   if (name == NULL && service == NULL)
2334     return EAI_NONAME;
2335
2336   if (hints == NULL)
2337     hints = &default_hints;
2338
2339   if (hints->ai_flags
2340       & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
2341 #ifdef HAVE_LIBIDN
2342           |AI_IDN|AI_CANONIDN|AI_IDN_ALLOW_UNASSIGNED
2343           |AI_IDN_USE_STD3_ASCII_RULES
2344 #endif
2345           |AI_NUMERICSERV|AI_ALL))
2346     return EAI_BADFLAGS;
2347
2348   if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2349     return EAI_BADFLAGS;
2350
2351   struct in6addrinfo *in6ai = NULL;
2352   size_t in6ailen = 0;
2353   bool seen_ipv4 = false;
2354   bool seen_ipv6 = false;
2355   bool check_pf_called = false;
2356
2357   if (hints->ai_flags & AI_ADDRCONFIG)
2358     {
2359       /* We might need information about what interfaces are available.
2360          Also determine whether we have IPv4 or IPv6 interfaces or both.  We
2361          cannot cache the results since new interfaces could be added at
2362          any time.  */
2363       __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2364       check_pf_called = true;
2365
2366       /* Now make a decision on what we return, if anything.  */
2367       if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2368         {
2369           /* If we haven't seen both IPv4 and IPv6 interfaces we can
2370              narrow down the search.  */
2371           if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2372             {
2373               local_hints = *hints;
2374               local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2375               hints = &local_hints;
2376             }
2377         }
2378       else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2379                || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2380         {
2381           /* We cannot possibly return a valid answer.  */
2382           __free_in6ai (in6ai);
2383           return EAI_NONAME;
2384         }
2385     }
2386
2387   if (service && service[0])
2388     {
2389       char *c;
2390       gaih_service.name = service;
2391       gaih_service.num = strtoul (gaih_service.name, &c, 10);
2392       if (*c != '\0')
2393         {
2394           if (hints->ai_flags & AI_NUMERICSERV)
2395             {
2396               __free_in6ai (in6ai);
2397               return EAI_NONAME;
2398             }
2399
2400           gaih_service.num = -1;
2401         }
2402
2403       pservice = &gaih_service;
2404     }
2405   else
2406     pservice = NULL;
2407
2408   struct addrinfo **end = &p;
2409
2410   unsigned int naddrs = 0;
2411   if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
2412       || hints->ai_family == AF_INET6)
2413     {
2414       last_i = gaih_inet (name, pservice, hints, end, &naddrs);
2415       if (last_i != 0)
2416         {
2417           freeaddrinfo (p);
2418           __free_in6ai (in6ai);
2419
2420           return -last_i;
2421         }
2422       while (*end)
2423         {
2424           end = &((*end)->ai_next);
2425           ++nresults;
2426         }
2427     }
2428   else
2429     {
2430       __free_in6ai (in6ai);
2431       return EAI_FAMILY;
2432     }
2433
2434   if (naddrs > 1)
2435     {
2436       /* Read the config file.  */
2437       __libc_once_define (static, once);
2438       __typeof (once) old_once = once;
2439       __libc_once (once, gaiconf_init);
2440       /* Sort results according to RFC 3484.  */
2441       struct sort_result *results;
2442       size_t *order;
2443       struct addrinfo *q;
2444       struct addrinfo *last = NULL;
2445       char *canonname = NULL;
2446       bool malloc_results;
2447       size_t alloc_size = nresults * (sizeof (*results) + sizeof (size_t));
2448
2449       malloc_results
2450         = !__libc_use_alloca (alloc_size);
2451       if (malloc_results)
2452         {
2453           results = malloc (alloc_size);
2454           if (results == NULL)
2455             {
2456               __free_in6ai (in6ai);
2457               return EAI_MEMORY;
2458             }
2459         }
2460       else
2461         results = alloca (alloc_size);
2462       order = (size_t *) (results + nresults);
2463
2464       /* Now we definitely need the interface information.  */
2465       if (! check_pf_called)
2466         __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2467
2468       /* If we have information about deprecated and temporary addresses
2469          sort the array now.  */
2470       if (in6ai != NULL)
2471         qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
2472
2473       int fd = -1;
2474       int af = AF_UNSPEC;
2475
2476       for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
2477         {
2478           results[i].dest_addr = q;
2479           results[i].native = -1;
2480           order[i] = i;
2481
2482           /* If we just looked up the address for a different
2483              protocol, reuse the result.  */
2484           if (last != NULL && last->ai_addrlen == q->ai_addrlen
2485               && memcmp (last->ai_addr, q->ai_addr, q->ai_addrlen) == 0)
2486             {
2487               memcpy (&results[i].source_addr, &results[i - 1].source_addr,
2488                       results[i - 1].source_addr_len);
2489               results[i].source_addr_len = results[i - 1].source_addr_len;
2490               results[i].got_source_addr = results[i - 1].got_source_addr;
2491               results[i].source_addr_flags = results[i - 1].source_addr_flags;
2492               results[i].prefixlen = results[i - 1].prefixlen;
2493               results[i].index = results[i - 1].index;
2494             }
2495           else
2496             {
2497               results[i].got_source_addr = false;
2498               results[i].source_addr_flags = 0;
2499               results[i].prefixlen = 0;
2500               results[i].index = 0xffffffffu;
2501
2502               /* We overwrite the type with SOCK_DGRAM since we do not
2503                  want connect() to connect to the other side.  If we
2504                  cannot determine the source address remember this
2505                  fact.  */
2506               if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
2507                 {
2508                   if (fd != -1)
2509                   close_retry:
2510                     close_not_cancel_no_status (fd);
2511                   af = q->ai_family;
2512                   fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
2513                 }
2514               else
2515                 {
2516                   /* Reset the connection.  */
2517                   struct sockaddr sa = { .sa_family = AF_UNSPEC };
2518                   __connect (fd, &sa, sizeof (sa));
2519                 }
2520
2521               socklen_t sl = sizeof (results[i].source_addr);
2522               if (fd != -1
2523                   && __connect (fd, q->ai_addr, q->ai_addrlen) == 0
2524                   && __getsockname (fd,
2525                                     (struct sockaddr *) &results[i].source_addr,
2526                                     &sl) == 0)
2527                 {
2528                   results[i].source_addr_len = sl;
2529                   results[i].got_source_addr = true;
2530
2531                   if (in6ai != NULL)
2532                     {
2533                       /* See whether the source address is on the list of
2534                          deprecated or temporary addresses.  */
2535                       struct in6addrinfo tmp;
2536
2537                       if (q->ai_family == AF_INET && af == AF_INET)
2538                         {
2539                           struct sockaddr_in *sinp
2540                             = (struct sockaddr_in *) &results[i].source_addr;
2541                           tmp.addr[0] = 0;
2542                           tmp.addr[1] = 0;
2543                           tmp.addr[2] = htonl (0xffff);
2544                           /* Special case for lo interface, the source address
2545                              being possibly different than the interface
2546                              address. */
2547                           if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000)
2548                               == 0x7f000000)
2549                             tmp.addr[3] = htonl(0x7f000001);
2550                           else
2551                             tmp.addr[3] = sinp->sin_addr.s_addr;
2552                         }
2553                       else
2554                         {
2555                           struct sockaddr_in6 *sin6p
2556                             = (struct sockaddr_in6 *) &results[i].source_addr;
2557                           memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
2558                         }
2559
2560                       struct in6addrinfo *found
2561                         = bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
2562                                    in6aicmp);
2563                       if (found != NULL)
2564                         {
2565                           results[i].source_addr_flags = found->flags;
2566                           results[i].prefixlen = found->prefixlen;
2567                           results[i].index = found->index;
2568                         }
2569                     }
2570
2571                   if (q->ai_family == AF_INET && af == AF_INET6)
2572                     {
2573                       /* We have to convert the address.  The socket is
2574                          IPv6 and the request is for IPv4.  */
2575                       struct sockaddr_in6 *sin6
2576                         = (struct sockaddr_in6 *) &results[i].source_addr;
2577                       struct sockaddr_in *sin
2578                         = (struct sockaddr_in *) &results[i].source_addr;
2579                       assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
2580                       sin->sin_family = AF_INET;
2581                       /* We do not have to initialize sin_port since this
2582                          fields has the same position and size in the IPv6
2583                          structure.  */
2584                       assert (offsetof (struct sockaddr_in, sin_port)
2585                               == offsetof (struct sockaddr_in6, sin6_port));
2586                       assert (sizeof (sin->sin_port)
2587                               == sizeof (sin6->sin6_port));
2588                       memcpy (&sin->sin_addr,
2589                               &sin6->sin6_addr.s6_addr32[3], INADDRSZ);
2590                       results[i].source_addr_len = sizeof (struct sockaddr_in);
2591                     }
2592                 }
2593               else if (errno == EAFNOSUPPORT && af == AF_INET6
2594                        && q->ai_family == AF_INET)
2595                 /* This could mean IPv6 sockets are IPv6-only.  */
2596                 goto close_retry;
2597               else
2598                 /* Just make sure that if we have to process the same
2599                    address again we do not copy any memory.  */
2600                 results[i].source_addr_len = 0;
2601             }
2602
2603           /* Remember the canonical name.  */
2604           if (q->ai_canonname != NULL)
2605             {
2606               assert (canonname == NULL);
2607               canonname = q->ai_canonname;
2608               q->ai_canonname = NULL;
2609             }
2610         }
2611
2612       if (fd != -1)
2613         close_not_cancel_no_status (fd);
2614
2615       /* We got all the source addresses we can get, now sort using
2616          the information.  */
2617       struct sort_result_combo src
2618         = { .results = results, .nresults = nresults };
2619       if (__glibc_unlikely (gaiconf_reload_flag_ever_set))
2620         {
2621           __libc_lock_define_initialized (static, lock);
2622
2623           __libc_lock_lock (lock);
2624           if (__libc_once_get (old_once) && gaiconf_reload_flag)
2625             gaiconf_reload ();
2626           qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2627           __libc_lock_unlock (lock);
2628         }
2629       else
2630         qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
2631
2632       /* Queue the results up as they come out of sorting.  */
2633       q = p = results[order[0]].dest_addr;
2634       for (i = 1; i < nresults; ++i)
2635         q = q->ai_next = results[order[i]].dest_addr;
2636       q->ai_next = NULL;
2637
2638       /* Fill in the canonical name into the new first entry.  */
2639       p->ai_canonname = canonname;
2640
2641       if (malloc_results)
2642         free (results);
2643     }
2644
2645   __free_in6ai (in6ai);
2646
2647   if (p)
2648     {
2649       *pai = p;
2650       return 0;
2651     }
2652
2653   return last_i ? -last_i : EAI_NONAME;
2654 }
2655 libc_hidden_def (getaddrinfo)
2656
2657 nss_interface_function (getaddrinfo)
2658
2659 void
2660 freeaddrinfo (struct addrinfo *ai)
2661 {
2662   struct addrinfo *p;
2663
2664   while (ai != NULL)
2665     {
2666       p = ai;
2667       ai = ai->ai_next;
2668       free (p->ai_canonname);
2669       free (p);
2670     }
2671 }
2672 libc_hidden_def (freeaddrinfo)