1 /* The Inner Net License, Version 2.00
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:
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
11 1. All terms of the all other applicable copyrights and licenses must be
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.
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.
34 If these license terms cause you a real problem, contact the author. */
36 /* This software is Copyright 1996 by Craig Metz, All Rights Reserved. */
48 #include <arpa/inet.h>
49 #include <sys/socket.h>
50 #include <netinet/in.h>
51 #include <sys/types.h>
53 #include <sys/utsname.h>
56 #include <not-cancel.h>
57 #include <nscd/nscd-client.h>
58 #include <nscd/nscd_proto.h>
61 extern int __idna_to_ascii_lz (const char *input
, char **output
, int flags
);
62 extern int __idna_to_unicode_lzlz (const char *input
, char **output
,
64 # include <libidn/idna.h>
67 #define GAIH_OKIFUNSPEC 0x0100
68 #define GAIH_EAI ~(GAIH_OKIFUNSPEC)
71 #define UNIX_PATH_MAX 108
82 struct gaih_servtuple
*next
;
88 static const struct gaih_servtuple nullserv
;
92 struct gaih_addrtuple
*next
;
107 /* Values for `protoflag'. */
108 #define GAI_PROTO_NOSERVICE 1
109 #define GAI_PROTO_PROTOANY 2
111 static const struct gaih_typeproto gaih_inet_typeproto
[] =
114 { SOCK_STREAM
, IPPROTO_TCP
, "tcp", 0 },
115 { SOCK_DGRAM
, IPPROTO_UDP
, "udp", 0 },
116 { SOCK_RAW
, 0, "raw", GAI_PROTO_PROTOANY
|GAI_PROTO_NOSERVICE
},
123 int (*gaih
)(const char *name
, const struct gaih_service
*service
,
124 const struct addrinfo
*req
, struct addrinfo
**pai
);
127 static const struct addrinfo default_hints
=
129 .ai_flags
= AI_DEFAULT
,
130 .ai_family
= PF_UNSPEC
,
135 .ai_canonname
= NULL
,
141 /* Using Unix sockets this way is a security risk. */
143 gaih_local (const char *name
, const struct gaih_service
*service
,
144 const struct addrinfo
*req
, struct addrinfo
**pai
)
146 struct utsname utsname
;
148 if ((name
!= NULL
) && (req
->ai_flags
& AI_NUMERICHOST
))
149 return GAIH_OKIFUNSPEC
| -EAI_NONAME
;
151 if ((name
!= NULL
) || (req
->ai_flags
& AI_CANONNAME
))
152 if (uname (&utsname
) < 0)
157 if (strcmp(name
, "localhost") &&
158 strcmp(name
, "local") &&
159 strcmp(name
, "unix") &&
160 strcmp(name
, utsname
.nodename
))
161 return GAIH_OKIFUNSPEC
| -EAI_NONAME
;
164 if (req
->ai_protocol
|| req
->ai_socktype
)
166 const struct gaih_typeproto
*tp
= gaih_inet_typeproto
+ 1;
169 && ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0
170 || (req
->ai_socktype
!= 0 && req
->ai_socktype
!= tp
->socktype
)
171 || (req
->ai_protocol
!= 0
172 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
173 && req
->ai_protocol
!= tp
->protocol
)))
178 if (req
->ai_socktype
)
179 return (GAIH_OKIFUNSPEC
| -EAI_SOCKTYPE
);
181 return (GAIH_OKIFUNSPEC
| -EAI_SERVICE
);
185 *pai
= malloc (sizeof (struct addrinfo
) + sizeof (struct sockaddr_un
)
186 + ((req
->ai_flags
& AI_CANONNAME
)
187 ? (strlen(utsname
.nodename
) + 1): 0));
191 (*pai
)->ai_next
= NULL
;
192 (*pai
)->ai_flags
= req
->ai_flags
;
193 (*pai
)->ai_family
= AF_LOCAL
;
194 (*pai
)->ai_socktype
= req
->ai_socktype
? req
->ai_socktype
: SOCK_STREAM
;
195 (*pai
)->ai_protocol
= req
->ai_protocol
;
196 (*pai
)->ai_addrlen
= sizeof (struct sockaddr_un
);
197 (*pai
)->ai_addr
= (void *) (*pai
) + sizeof (struct addrinfo
);
200 ((struct sockaddr_un
*) (*pai
)->ai_addr
)->sun_len
=
201 sizeof (struct sockaddr_un
);
204 ((struct sockaddr_un
*)(*pai
)->ai_addr
)->sun_family
= AF_LOCAL
;
205 memset(((struct sockaddr_un
*)(*pai
)->ai_addr
)->sun_path
, 0, UNIX_PATH_MAX
);
209 struct sockaddr_un
*sunp
= (struct sockaddr_un
*) (*pai
)->ai_addr
;
211 if (strchr (service
->name
, '/') != NULL
)
213 if (strlen (service
->name
) >= sizeof (sunp
->sun_path
))
214 return GAIH_OKIFUNSPEC
| -EAI_SERVICE
;
216 strcpy (sunp
->sun_path
, service
->name
);
220 if (strlen (P_tmpdir
"/") + 1 + strlen (service
->name
) >=
221 sizeof (sunp
->sun_path
))
222 return GAIH_OKIFUNSPEC
| -EAI_SERVICE
;
224 __stpcpy (__stpcpy (sunp
->sun_path
, P_tmpdir
"/"), service
->name
);
229 /* This is a dangerous use of the interface since there is a time
230 window between the test for the file and the actual creation
231 (done by the caller) in which a file with the same name could
233 char *buf
= ((struct sockaddr_un
*) (*pai
)->ai_addr
)->sun_path
;
235 if (__builtin_expect (__path_search (buf
, L_tmpnam
, NULL
, NULL
, 0),
237 || __builtin_expect (__gen_tempname (buf
, __GT_NOCREATE
), 0) != 0)
241 if (req
->ai_flags
& AI_CANONNAME
)
242 (*pai
)->ai_canonname
= strcpy ((char *) *pai
+ sizeof (struct addrinfo
)
243 + sizeof (struct sockaddr_un
),
246 (*pai
)->ai_canonname
= NULL
;
252 gaih_inet_serv (const char *servicename
, const struct gaih_typeproto
*tp
,
253 const struct addrinfo
*req
, struct gaih_servtuple
*st
)
256 size_t tmpbuflen
= 1024;
263 tmpbuf
= __alloca (tmpbuflen
);
265 r
= __getservbyname_r (servicename
, tp
->name
, &ts
, tmpbuf
, tmpbuflen
,
267 if (r
!= 0 || s
== NULL
)
272 return GAIH_OKIFUNSPEC
| -EAI_SERVICE
;
278 st
->socktype
= tp
->socktype
;
279 st
->protocol
= ((tp
->protoflag
& GAI_PROTO_PROTOANY
)
280 ? req
->ai_protocol
: tp
->protocol
);
281 st
->port
= s
->s_port
;
286 #define gethosts(_family, _type) \
292 char *localcanon = NULL; \
296 status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, tmpbuflen, \
297 &rc, &herrno, NULL, &localcanon)); \
298 if (rc != ERANGE || herrno != NETDB_INTERNAL) \
300 tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
302 if (status == NSS_STATUS_SUCCESS && rc == 0) \
308 if (herrno == NETDB_INTERNAL) \
310 __set_h_errno (herrno); \
311 return -EAI_SYSTEM; \
313 if (herrno == TRY_AGAIN) \
314 no_data = EAI_AGAIN; \
316 no_data = herrno == NO_DATA; \
318 else if (h != NULL) \
320 for (i = 0; h->h_addr_list[i]; i++) \
324 *pat = __alloca (sizeof (struct gaih_addrtuple)); \
325 (*pat)->scopeid = 0; \
327 uint32_t *addr = (*pat)->addr; \
328 (*pat)->next = NULL; \
329 (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \
330 if (_family == AF_INET && req->ai_family == AF_INET6) \
332 (*pat)->family = AF_INET6; \
333 addr[3] = *(uint32_t *) h->h_addr_list[i]; \
334 addr[2] = htonl (0xffff); \
340 (*pat)->family = _family; \
341 memcpy (addr, h->h_addr_list[i], sizeof(_type)); \
343 pat = &((*pat)->next); \
346 if (localcanon != NULL && canon == NULL) \
347 canon = strdupa (localcanon); \
349 if (_family == AF_INET6 && i > 0) \
355 typedef enum nss_status (*nss_gethostbyname3_r
)
356 (const char *name
, int af
, struct hostent
*host
,
357 char *buffer
, size_t buflen
, int *errnop
,
358 int *h_errnop
, int32_t *ttlp
, char **canonp
);
359 typedef enum nss_status (*nss_getcanonname_r
)
360 (const char *name
, char *buffer
, size_t buflen
, char **result
,
361 int *errnop
, int *h_errnop
);
362 extern service_user
*__nss_hosts_database attribute_hidden
;
365 gaih_inet (const char *name
, const struct gaih_service
*service
,
366 const struct addrinfo
*req
, struct addrinfo
**pai
)
368 const struct gaih_typeproto
*tp
= gaih_inet_typeproto
;
369 struct gaih_servtuple
*st
= (struct gaih_servtuple
*) &nullserv
;
370 struct gaih_addrtuple
*at
= NULL
;
372 bool got_ipv6
= false;
373 const char *canon
= NULL
;
374 const char *orig_name
= name
;
376 if (req
->ai_protocol
|| req
->ai_socktype
)
381 && ((req
->ai_socktype
!= 0 && req
->ai_socktype
!= tp
->socktype
)
382 || (req
->ai_protocol
!= 0
383 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
384 && req
->ai_protocol
!= tp
->protocol
)))
389 if (req
->ai_socktype
)
390 return (GAIH_OKIFUNSPEC
| -EAI_SOCKTYPE
);
392 return (GAIH_OKIFUNSPEC
| -EAI_SERVICE
);
398 if ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0)
399 return (GAIH_OKIFUNSPEC
| -EAI_SERVICE
);
401 if (service
->num
< 0)
405 st
= (struct gaih_servtuple
*)
406 __alloca (sizeof (struct gaih_servtuple
));
408 if ((rc
= gaih_inet_serv (service
->name
, tp
, req
, st
)))
413 struct gaih_servtuple
**pst
= &st
;
414 for (tp
++; tp
->name
[0]; tp
++)
416 struct gaih_servtuple
*newp
;
418 if ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) != 0)
421 if (req
->ai_socktype
!= 0
422 && req
->ai_socktype
!= tp
->socktype
)
424 if (req
->ai_protocol
!= 0
425 && !(tp
->protoflag
& GAI_PROTO_PROTOANY
)
426 && req
->ai_protocol
!= tp
->protocol
)
429 newp
= (struct gaih_servtuple
*)
430 __alloca (sizeof (struct gaih_servtuple
));
432 if ((rc
= gaih_inet_serv (service
->name
, tp
, req
, newp
)))
434 if (rc
& GAIH_OKIFUNSPEC
)
442 if (st
== (struct gaih_servtuple
*) &nullserv
)
443 return (GAIH_OKIFUNSPEC
| -EAI_SERVICE
);
448 if (req
->ai_socktype
|| req
->ai_protocol
)
450 st
= __alloca (sizeof (struct gaih_servtuple
));
452 st
->socktype
= tp
->socktype
;
453 st
->protocol
= ((tp
->protoflag
& GAI_PROTO_PROTOANY
)
454 ? req
->ai_protocol
: tp
->protocol
);
455 st
->port
= htons (service
->num
);
459 /* Neither socket type nor protocol is set. Return all
460 socket types we know about. */
461 struct gaih_servtuple
**lastp
= &st
;
462 for (tp
= gaih_inet_typeproto
+ 1; tp
->name
[0]; ++tp
)
463 if ((tp
->protoflag
& GAI_PROTO_NOSERVICE
) == 0)
465 struct gaih_servtuple
*newp
;
467 newp
= __alloca (sizeof (struct gaih_servtuple
));
469 newp
->socktype
= tp
->socktype
;
470 newp
->protocol
= tp
->protocol
;
471 newp
->port
= htons (service
->num
);
479 else if (req
->ai_socktype
|| req
->ai_protocol
)
481 st
= __alloca (sizeof (struct gaih_servtuple
));
483 st
->socktype
= tp
->socktype
;
484 st
->protocol
= ((tp
->protoflag
& GAI_PROTO_PROTOANY
)
485 ? req
->ai_protocol
: tp
->protocol
);
490 /* Neither socket type nor protocol is set. Return all socket types
492 struct gaih_servtuple
**lastp
= &st
;
493 for (++tp
; tp
->name
[0]; ++tp
)
495 struct gaih_servtuple
*newp
;
497 newp
= __alloca (sizeof (struct gaih_servtuple
));
499 newp
->socktype
= tp
->socktype
;
500 newp
->protocol
= tp
->protocol
;
510 at
= __alloca (sizeof (struct gaih_addrtuple
));
512 at
->family
= AF_UNSPEC
;
517 if (req
->ai_flags
& AI_IDN
)
520 if (req
->ai_flags
& AI_IDN_ALLOW_UNASSIGNED
)
521 idn_flags
|= IDNA_ALLOW_UNASSIGNED
;
522 if (req
->ai_flags
& AI_IDN_USE_STD3_ASCII_RULES
)
523 idn_flags
|= IDNA_USE_STD3_ASCII_RULES
;
526 rc
= __idna_to_ascii_lz (name
, &p
, idn_flags
);
527 if (rc
!= IDNA_SUCCESS
)
529 if (rc
== IDNA_MALLOC_ERROR
)
531 if (rc
== IDNA_DLOPEN_ERROR
)
533 return -EAI_IDN_ENCODE
;
535 /* In case the output string is the same as the input string
536 no new string has been allocated. */
545 if (__inet_aton (name
, (struct in_addr
*) at
->addr
) != 0)
547 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET
)
548 at
->family
= AF_INET
;
549 else if (req
->ai_family
== AF_INET6
&& req
->ai_flags
& AI_V4MAPPED
)
551 at
->addr
[3] = at
->addr
[0];
552 at
->addr
[2] = htonl (0xffff);
555 at
->family
= AF_INET6
;
558 return -EAI_ADDRFAMILY
;
561 if (req
->ai_flags
& AI_CANONNAME
)
563 canon
= strdup (name
);
569 if (at
->family
== AF_UNSPEC
)
571 char *namebuf
= strdupa (name
);
574 scope_delim
= strchr (namebuf
, SCOPE_DELIMITER
);
575 if (scope_delim
!= NULL
)
578 if (inet_pton (AF_INET6
, namebuf
, at
->addr
) > 0)
580 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET6
)
581 at
->family
= AF_INET6
;
582 else if (req
->ai_family
== AF_INET
583 && IN6_IS_ADDR_V4MAPPED (at
->addr
))
585 at
->addr
[0] = at
->addr
[3];
586 at
->family
= AF_INET
;
589 return -EAI_ADDRFAMILY
;
591 if (scope_delim
!= NULL
)
593 int try_numericscope
= 0;
594 if (IN6_IS_ADDR_LINKLOCAL (at
->addr
)
595 || IN6_IS_ADDR_MC_LINKLOCAL (at
->addr
))
597 at
->scopeid
= if_nametoindex (scope_delim
+ 1);
598 if (at
->scopeid
== 0)
599 try_numericscope
= 1;
602 try_numericscope
= 1;
604 if (try_numericscope
!= 0)
607 assert (sizeof (uint32_t) <= sizeof (unsigned long));
608 at
->scopeid
= (uint32_t) strtoul (scope_delim
+ 1, &end
,
611 return GAIH_OKIFUNSPEC
| -EAI_NONAME
;
619 if (at
->family
== AF_UNSPEC
&& (req
->ai_flags
& AI_NUMERICHOST
) == 0)
621 struct gaih_addrtuple
**pat
= &at
;
623 int no_inet6_data
= 0;
624 service_user
*nip
= NULL
;
625 enum nss_status inet6_status
= NSS_STATUS_UNAVAIL
;
626 enum nss_status status
= NSS_STATUS_UNAVAIL
;
630 /* If we do not have to look for IPv4 and IPv6 together, use
631 the simple, old functions. */
632 if (req
->ai_family
== AF_INET
|| req
->ai_family
== AF_INET6
)
634 int family
= req
->ai_family
;
635 size_t tmpbuflen
= 512;
636 char *tmpbuf
= alloca (tmpbuflen
);
645 rc
= __gethostbyname2_r (name
, family
, &th
, tmpbuf
,
646 tmpbuflen
, &h
, &herrno
);
647 if (rc
!= ERANGE
|| herrno
!= NETDB_INTERNAL
)
649 tmpbuf
= extend_alloca (tmpbuf
, tmpbuflen
, 2 * tmpbuflen
);
656 if (req
->ai_family
== AF_INET6
657 && (req
->ai_flags
& AI_V4MAPPED
)
658 && family
== AF_INET6
)
660 /* Try again, this time looking for IPv4
668 /* We found data, now convert it into the list. */
669 for (int i
= 0; h
->h_addr_list
[i
]; ++i
)
673 *pat
= __alloca (sizeof (struct gaih_addrtuple
));
677 (*pat
)->family
= req
->ai_family
;
678 if (family
== req
->ai_family
)
679 memcpy ((*pat
)->addr
, h
->h_addr_list
[i
],
683 int32_t *addr
= (uint32_t *) (*pat
)->addr
;
684 addr
[3] = *(uint32_t *) h
->h_addr_list
[i
];
685 addr
[2] = htonl (0xffff);
689 pat
= &((*pat
)->next
);
695 if (herrno
== NETDB_INTERNAL
)
697 __set_h_errno (herrno
);
700 if (herrno
== TRY_AGAIN
)
704 /* We made requests but they turned out no data.
705 The name is known, though. */
706 return (GAIH_OKIFUNSPEC
| -EAI_NODATA
);
713 if (__nss_not_use_nscd_hosts
> 0
714 && ++__nss_not_use_nscd_hosts
> NSS_NSCD_RETRY
)
715 __nss_not_use_nscd_hosts
= 0;
717 if (!__nss_not_use_nscd_hosts
)
719 /* Try to use nscd. */
720 struct nscd_ai_result
*air
= NULL
;
722 int err
= __nscd_getai (name
, &air
, &herrno
);
725 /* Transform into gaih_addrtuple list. */
726 bool added_canon
= (req
->ai_flags
& AI_CANONNAME
) == 0;
727 char *addrs
= air
->addrs
;
729 for (int i
= 0; i
< air
->naddrs
; ++i
)
731 socklen_t size
= (air
->family
[i
] == AF_INET
732 ? INADDRSZ
: IN6ADDRSZ
);
735 *pat
= __alloca (sizeof (struct gaih_addrtuple
));
738 uint32_t *pataddr
= (*pat
)->addr
;
740 if (added_canon
|| air
->canon
== NULL
)
743 canon
= (*pat
)->name
= strdupa (air
->canon
);
745 if (air
->family
[i
] == AF_INET
746 && req
->ai_family
== AF_INET6
747 && (req
->ai_flags
& AI_V4MAPPED
))
749 (*pat
)->family
= AF_INET6
;
750 pataddr
[3] = *(uint32_t *) addrs
;
751 pataddr
[2] = htonl (0xffff);
754 pat
= &((*pat
)->next
);
757 else if (req
->ai_family
== AF_UNSPEC
758 || air
->family
[i
] == req
->ai_family
)
760 (*pat
)->family
= air
->family
[i
];
761 memcpy (pataddr
, addrs
, size
);
762 pat
= &((*pat
)->next
);
764 if (air
->family
[i
] == AF_INET6
)
770 if (at
->family
== AF_UNSPEC
)
771 return (GAIH_OKIFUNSPEC
| -EAI_NONAME
);
775 else if (err
!= 0 && __nss_not_use_nscd_hosts
== 0)
777 if (herrno
== NETDB_INTERNAL
&& errno
== ENOMEM
)
779 if (herrno
== TRY_AGAIN
)
786 if (__nss_hosts_database
!= NULL
)
789 nip
= __nss_hosts_database
;
792 no_more
= __nss_database_lookup ("hosts", NULL
,
793 "dns [!UNAVAIL=return] files",
796 if (__res_maybe_init (&_res
, 0) == -1)
799 /* If we are looking for both IPv4 and IPv6 address we don't
800 want the lookup functions to automatically promote IPv4
801 addresses to IPv6 addresses. Currently this is decided
802 by setting the RES_USE_INET6 bit in _res.options. */
803 old_res_options
= _res
.options
;
804 _res
.options
&= ~RES_USE_INET6
;
806 size_t tmpbuflen
= 512;
807 char *tmpbuf
= alloca (tmpbuflen
);
811 nss_gethostbyname3_r fct
= NULL
;
812 if (req
->ai_flags
& AI_CANONNAME
)
813 /* No need to use this function if we do not look for
814 the canonical name. The function does not exist in
815 all NSS modules and therefore the lookup would
817 fct
= __nss_lookup_function (nip
, "gethostbyname3_r");
819 /* We are cheating here. The gethostbyname2_r function does
820 not have the same interface as gethostbyname3_r but the
821 extra arguments the latter takes are added at the end.
822 So the gethostbyname2_r code will just ignore them. */
823 fct
= __nss_lookup_function (nip
, "gethostbyname2_r");
827 if (req
->ai_family
== AF_INET6
828 || req
->ai_family
== AF_UNSPEC
)
830 gethosts (AF_INET6
, struct in6_addr
);
831 no_inet6_data
= no_data
;
832 inet6_status
= status
;
834 if (req
->ai_family
== AF_INET
835 || req
->ai_family
== AF_UNSPEC
836 || (req
->ai_family
== AF_INET6
837 && (req
->ai_flags
& AI_V4MAPPED
)
838 /* Avoid generating the mapped addresses if we
839 know we are not going to need them. */
840 && ((req
->ai_flags
& AI_ALL
) || !got_ipv6
)))
842 gethosts (AF_INET
, struct in_addr
);
844 if (req
->ai_family
== AF_INET
)
846 no_inet6_data
= no_data
;
847 inet6_status
= status
;
851 /* If we found one address for AF_INET or AF_INET6,
852 don't continue the search. */
853 if (inet6_status
== NSS_STATUS_SUCCESS
854 || status
== NSS_STATUS_SUCCESS
)
856 if ((req
->ai_flags
& AI_CANONNAME
) != 0 && canon
== NULL
)
858 /* If we need the canonical name, get it
859 from the same service as the result. */
860 nss_getcanonname_r cfct
;
863 cfct
= __nss_lookup_function (nip
, "getcanonname_r");
866 const size_t max_fqdn_len
= 256;
867 char *buf
= alloca (max_fqdn_len
);
870 if (DL_CALL_FCT (cfct
, (at
->name
?: name
, buf
,
871 max_fqdn_len
, &s
, &rc
,
873 == NSS_STATUS_SUCCESS
)
876 /* Set to name now to avoid using
885 /* We can have different states for AF_INET and
886 AF_INET6. Try to find a useful one for both. */
887 if (inet6_status
== NSS_STATUS_TRYAGAIN
)
888 status
= NSS_STATUS_TRYAGAIN
;
889 else if (status
== NSS_STATUS_UNAVAIL
&&
890 inet6_status
!= NSS_STATUS_UNAVAIL
)
891 status
= inet6_status
;
894 if (nss_next_action (nip
, status
) == NSS_ACTION_RETURN
)
897 if (nip
->next
== NULL
)
903 _res
.options
= old_res_options
;
905 if (no_data
!= 0 && no_inet6_data
!= 0)
907 /* If both requests timed out report this. */
908 if (no_data
== EAI_AGAIN
&& no_inet6_data
== EAI_AGAIN
)
911 /* We made requests but they turned out no data. The name
913 return (GAIH_OKIFUNSPEC
| -EAI_NODATA
);
918 if (at
->family
== AF_UNSPEC
)
919 return (GAIH_OKIFUNSPEC
| -EAI_NONAME
);
923 struct gaih_addrtuple
*atr
;
924 atr
= at
= __alloca (sizeof (struct gaih_addrtuple
));
925 memset (at
, '\0', sizeof (struct gaih_addrtuple
));
927 if (req
->ai_family
== AF_UNSPEC
)
929 at
->next
= __alloca (sizeof (struct gaih_addrtuple
));
930 memset (at
->next
, '\0', sizeof (struct gaih_addrtuple
));
933 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET6
)
935 at
->family
= AF_INET6
;
936 if ((req
->ai_flags
& AI_PASSIVE
) == 0)
937 memcpy (at
->addr
, &in6addr_loopback
, sizeof (struct in6_addr
));
941 if (req
->ai_family
== AF_UNSPEC
|| req
->ai_family
== AF_INET
)
943 atr
->family
= AF_INET
;
944 if ((req
->ai_flags
& AI_PASSIVE
) == 0)
945 atr
->addr
[0] = htonl (INADDR_LOOPBACK
);
953 struct gaih_servtuple
*st2
;
954 struct gaih_addrtuple
*at2
= at
;
959 buffer is the size of an unformatted IPv6 address in printable format.
963 /* Only the first entry gets the canonical name. */
964 if (at2
== at
&& (req
->ai_flags
& AI_CANONNAME
) != 0)
968 struct hostent
*h
= NULL
;
971 size_t tmpbuflen
= 512;
976 tmpbuf
= extend_alloca (tmpbuf
, tmpbuflen
, tmpbuflen
* 2);
977 rc
= __gethostbyaddr_r (at2
->addr
,
978 ((at2
->family
== AF_INET6
)
979 ? sizeof (struct in6_addr
)
980 : sizeof (struct in_addr
)),
981 at2
->family
, &th
, tmpbuf
,
982 tmpbuflen
, &h
, &herrno
);
984 while (rc
== ERANGE
&& herrno
== NETDB_INTERNAL
);
986 if (rc
!= 0 && herrno
== NETDB_INTERNAL
)
988 __set_h_errno (herrno
);
996 assert (orig_name
!= NULL
);
997 /* If the canonical name cannot be determined, use
998 the passed in string. */
1004 if (req
->ai_flags
& AI_CANONIDN
)
1007 if (req
->ai_flags
& AI_IDN_ALLOW_UNASSIGNED
)
1008 idn_flags
|= IDNA_ALLOW_UNASSIGNED
;
1009 if (req
->ai_flags
& AI_IDN_USE_STD3_ASCII_RULES
)
1010 idn_flags
|= IDNA_USE_STD3_ASCII_RULES
;
1013 int rc
= __idna_to_unicode_lzlz (canon
, &out
, idn_flags
);
1014 if (rc
!= IDNA_SUCCESS
)
1016 if (rc
== IDNA_MALLOC_ERROR
)
1018 if (rc
== IDNA_DLOPEN_ERROR
)
1020 return -EAI_IDN_ENCODE
;
1022 /* In case the output string is the same as the input
1023 string no new string has been allocated. Otherwise
1034 canon
= strdup (canon
);
1040 if (at2
->family
== AF_INET6
)
1043 socklen
= sizeof (struct sockaddr_in6
);
1045 /* If we looked up IPv4 mapped address discard them here if
1046 the caller isn't interested in all address and we have
1047 found at least one IPv6 address. */
1049 && (req
->ai_flags
& (AI_V4MAPPED
|AI_ALL
)) == AI_V4MAPPED
1050 && IN6_IS_ADDR_V4MAPPED (at2
->addr
))
1056 socklen
= sizeof (struct sockaddr_in
);
1059 for (st2
= st
; st2
!= NULL
; st2
= st2
->next
)
1061 struct addrinfo
*ai
;
1062 ai
= *pai
= malloc (sizeof (struct addrinfo
) + socklen
);
1066 ai
->ai_flags
= req
->ai_flags
;
1067 ai
->ai_family
= family
;
1068 ai
->ai_socktype
= st2
->socktype
;
1069 ai
->ai_protocol
= st2
->protocol
;
1070 ai
->ai_addrlen
= socklen
;
1071 ai
->ai_addr
= (void *) (ai
+ 1);
1073 /* We only add the canonical name once. */
1074 ai
->ai_canonname
= (char *) canon
;
1078 ai
->ai_addr
->sa_len
= socklen
;
1080 ai
->ai_addr
->sa_family
= family
;
1082 if (family
== AF_INET6
)
1084 struct sockaddr_in6
*sin6p
=
1085 (struct sockaddr_in6
*) ai
->ai_addr
;
1087 sin6p
->sin6_port
= st2
->port
;
1088 sin6p
->sin6_flowinfo
= 0;
1089 memcpy (&sin6p
->sin6_addr
,
1090 at2
->addr
, sizeof (struct in6_addr
));
1091 sin6p
->sin6_scope_id
= at2
->scopeid
;
1095 struct sockaddr_in
*sinp
=
1096 (struct sockaddr_in
*) ai
->ai_addr
;
1097 sinp
->sin_port
= st2
->port
;
1098 memcpy (&sinp
->sin_addr
,
1099 at2
->addr
, sizeof (struct in_addr
));
1100 memset (sinp
->sin_zero
, '\0', sizeof (sinp
->sin_zero
));
1103 pai
= &(ai
->ai_next
);
1114 static struct gaih gaih
[] =
1116 { PF_INET6
, gaih_inet
},
1117 { PF_INET
, gaih_inet
},
1119 { PF_LOCAL
, gaih_local
},
1126 struct addrinfo
*dest_addr
;
1127 struct sockaddr_storage source_addr
;
1128 uint8_t source_addr_len
;
1129 bool got_source_addr
;
1134 get_scope (const struct sockaddr_storage
*ss
)
1137 if (ss
->ss_family
== PF_INET6
)
1139 const struct sockaddr_in6
*in6
= (const struct sockaddr_in6
*) ss
;
1141 if (! IN6_IS_ADDR_MULTICAST (&in6
->sin6_addr
))
1143 if (IN6_IS_ADDR_LINKLOCAL (&in6
->sin6_addr
))
1145 else if (IN6_IS_ADDR_SITELOCAL (&in6
->sin6_addr
))
1148 /* XXX Is this the correct default behavior? */
1152 scope
= in6
->sin6_addr
.s6_addr
[1] & 0xf;
1154 else if (ss
->ss_family
== PF_INET
)
1156 const struct sockaddr_in
*in
= (const struct sockaddr_in
*) ss
;
1157 const uint8_t *addr
= (const uint8_t *) &in
->sin_addr
;
1159 /* RFC 3484 specifies how to map IPv6 addresses to scopes.
1160 169.254/16 and 127/8 are link-local. */
1161 if ((addr
[0] == 169 && addr
[1] == 254) || addr
[0] == 127)
1163 else if (addr
[0] == 10 || (addr
[0] == 172 && addr
[1] == 16)
1164 || (addr
[0] == 192 && addr
[1] == 168))
1170 /* XXX What is a good default? */
1177 /* XXX The system administrator should be able to install other
1178 tables. We need to make this configurable. The problem is that
1179 the kernel is also involved since it needs the same table. */
1180 static const struct prefixlist
1182 struct in6_addr prefix
;
1185 } default_labels
[] =
1187 /* See RFC 3484 for the details. */
1188 { { .in6_u
= { .u6_addr16
= { 0x0000, 0x0000, 0x0000, 0x0000,
1189 0x0000, 0x0000, 0x0000, 0x0001 } } },
1191 { { .in6_u
= { .u6_addr16
= { 0x2002, 0x0000, 0x0000, 0x0000,
1192 0x0000, 0x0000, 0x0000, 0x0000 } } },
1194 { { .in6_u
= { .u6_addr16
= { 0x0000, 0x0000, 0x0000, 0x0000,
1195 0x0000, 0x0000, 0x0000, 0x0000 } } },
1197 { { .in6_u
= { .u6_addr16
= { 0x0000, 0x0000, 0x0000, 0x0000,
1198 0x0000, 0xffff, 0x0000, 0x0000 } } },
1200 { { .in6_u
= { .u6_addr16
= { 0x0000, 0x0000, 0x0000, 0x0000,
1201 0x0000, 0x0000, 0x0000, 0x0000 } } },
1206 static const struct prefixlist default_precedence
[] =
1208 /* See RFC 3484 for the details. */
1209 { { .in6_u
= { .u6_addr16
= { 0x0000, 0x0000, 0x0000, 0x0000,
1210 0x0000, 0x0000, 0x0000, 0x0001 } } },
1212 { { .in6_u
= { .u6_addr16
= { 0x2002, 0x0000, 0x0000, 0x0000,
1213 0x0000, 0x0000, 0x0000, 0x0000 } } },
1215 { { .in6_u
= { .u6_addr16
= { 0x0000, 0x0000, 0x0000, 0x0000,
1216 0x0000, 0x0000, 0x0000, 0x0000 } } },
1218 { { .in6_u
= { .u6_addr16
= { 0x0000, 0x0000, 0x0000, 0x0000,
1219 0x0000, 0xffff, 0x0000, 0x0000 } } },
1221 { { .in6_u
= { .u6_addr16
= { 0x0000, 0x0000, 0x0000, 0x0000,
1222 0x0000, 0x0000, 0x0000, 0x0000 } } },
1228 match_prefix (const struct sockaddr_storage
*ss
, const struct prefixlist
*list
,
1232 struct sockaddr_in6 in6_mem
;
1233 const struct sockaddr_in6
*in6
;
1235 if (ss
->ss_family
== PF_INET6
)
1236 in6
= (const struct sockaddr_in6
*) ss
;
1237 else if (ss
->ss_family
== PF_INET
)
1239 const struct sockaddr_in
*in
= (const struct sockaddr_in
*) ss
;
1241 /* Convert to IPv6 address. */
1242 in6_mem
.sin6_family
= PF_INET6
;
1243 in6_mem
.sin6_port
= in
->sin_port
;
1244 in6_mem
.sin6_flowinfo
= 0;
1245 if (in
->sin_addr
.s_addr
== htonl (0x7f000001))
1246 in6_mem
.sin6_addr
= (struct in6_addr
) IN6ADDR_LOOPBACK_INIT
;
1249 /* Construct a V4-to-6 mapped address. */
1250 memset (&in6_mem
.sin6_addr
, '\0', sizeof (in6_mem
.sin6_addr
));
1251 in6_mem
.sin6_addr
.s6_addr16
[5] = 0xffff;
1252 in6_mem
.sin6_addr
.s6_addr32
[3] = in
->sin_addr
.s_addr
;
1253 in6_mem
.sin6_scope_id
= 0;
1261 for (idx
= 0; ; ++idx
)
1263 unsigned int bits
= list
[idx
].bits
;
1264 uint8_t *mask
= list
[idx
].prefix
.s6_addr
;
1265 uint8_t *val
= in6
->sin6_addr
.s6_addr
;
1279 if ((*mask
& (0xff00 >> bits
)) == (*val
& (0xff00 >> bits
)))
1285 return list
[idx
].val
;
1290 get_label (const struct sockaddr_storage
*ss
)
1292 /* XXX What is a good default value? */
1293 return match_prefix (ss
, default_labels
, INT_MAX
);
1298 get_precedence (const struct sockaddr_storage
*ss
)
1300 /* XXX What is a good default value? */
1301 return match_prefix (ss
, default_precedence
, 0);
1306 rfc3484_sort (const void *p1
, const void *p2
)
1308 const struct sort_result
*a1
= (const struct sort_result
*) p1
;
1309 const struct sort_result
*a2
= (const struct sort_result
*) p2
;
1311 /* Rule 1: Avoid unusable destinations.
1312 We have the got_source_addr flag set if the destination is reachable. */
1313 if (a1
->got_source_addr
&& ! a2
->got_source_addr
)
1315 if (! a1
->got_source_addr
&& a2
->got_source_addr
)
1319 /* Rule 2: Prefer matching scope. Only interesting if both
1320 destination addresses are IPv6. */
1322 = get_scope ((struct sockaddr_storage
*) a1
->dest_addr
->ai_addr
);
1325 = get_scope ((struct sockaddr_storage
*) a2
->dest_addr
->ai_addr
);
1327 if (a1
->got_source_addr
)
1329 int a1_src_scope
= get_scope (&a1
->source_addr
);
1330 int a2_src_scope
= get_scope (&a2
->source_addr
);
1332 if (a1_dst_scope
== a1_src_scope
&& a2_dst_scope
!= a2_src_scope
)
1334 if (a1_dst_scope
!= a1_src_scope
&& a2_dst_scope
== a2_src_scope
)
1339 /* Rule 3: Avoid deprecated addresses.
1340 That's something only the kernel could decide. */
1342 /* Rule 4: Prefer home addresses.
1343 Another thing only the kernel can decide. */
1345 /* Rule 5: Prefer matching label. */
1346 if (a1
->got_source_addr
)
1349 = get_label ((struct sockaddr_storage
*) a1
->dest_addr
->ai_addr
);
1350 int a1_src_label
= get_label (&a1
->source_addr
);
1353 = get_label ((struct sockaddr_storage
*) a2
->dest_addr
->ai_addr
);
1354 int a2_src_label
= get_label (&a2
->source_addr
);
1356 if (a1_dst_label
== a1_src_label
&& a2_dst_label
!= a2_src_label
)
1358 if (a1_dst_label
!= a1_src_label
&& a2_dst_label
== a2_src_label
)
1363 /* Rule 6: Prefer higher precedence. */
1365 = get_precedence ((struct sockaddr_storage
*) a1
->dest_addr
->ai_addr
);
1367 = get_precedence ((struct sockaddr_storage
*) a2
->dest_addr
->ai_addr
);
1369 if (a1_prec
> a2_prec
)
1371 if (a1_prec
< a2_prec
)
1375 /* Rule 7: Prefer native transport.
1376 XXX How to recognize tunnels? */
1379 /* Rule 8: Prefer smaller scope. */
1380 if (a1_dst_scope
< a2_dst_scope
)
1382 if (a1_dst_scope
> a2_dst_scope
)
1386 /* Rule 9: Use longest matching prefix. */
1387 if (a1
->got_source_addr
1388 && a1
->dest_addr
->ai_family
== a2
->dest_addr
->ai_family
)
1393 if (a1
->dest_addr
->ai_family
== PF_INET
)
1395 assert (a1
->source_addr
.ss_family
== PF_INET
);
1396 assert (a2
->source_addr
.ss_family
== PF_INET
);
1398 struct sockaddr_in
*in1_dst
;
1399 struct sockaddr_in
*in1_src
;
1400 struct sockaddr_in
*in2_dst
;
1401 struct sockaddr_in
*in2_src
;
1403 in1_dst
= (struct sockaddr_in
*) a1
->dest_addr
->ai_addr
;
1404 in1_src
= (struct sockaddr_in
*) &a1
->source_addr
;
1405 in2_dst
= (struct sockaddr_in
*) a2
->dest_addr
->ai_addr
;
1406 in2_src
= (struct sockaddr_in
*) &a2
->source_addr
;
1408 bit1
= ffs (in1_dst
->sin_addr
.s_addr
^ in1_src
->sin_addr
.s_addr
);
1409 bit2
= ffs (in2_dst
->sin_addr
.s_addr
^ in2_src
->sin_addr
.s_addr
);
1411 else if (a1
->dest_addr
->ai_family
== PF_INET6
)
1413 assert (a1
->source_addr
.ss_family
== PF_INET6
);
1414 assert (a2
->source_addr
.ss_family
== PF_INET6
);
1416 struct sockaddr_in6
*in1_dst
;
1417 struct sockaddr_in6
*in1_src
;
1418 struct sockaddr_in6
*in2_dst
;
1419 struct sockaddr_in6
*in2_src
;
1421 in1_dst
= (struct sockaddr_in6
*) a1
->dest_addr
->ai_addr
;
1422 in1_src
= (struct sockaddr_in6
*) &a1
->source_addr
;
1423 in2_dst
= (struct sockaddr_in6
*) a2
->dest_addr
->ai_addr
;
1424 in2_src
= (struct sockaddr_in6
*) &a2
->source_addr
;
1427 for (i
= 0; i
< 4; ++i
)
1428 if (in1_dst
->sin6_addr
.s6_addr32
[i
]
1429 != in1_src
->sin6_addr
.s6_addr32
[i
]
1430 || (in2_dst
->sin6_addr
.s6_addr32
[i
]
1431 != in2_src
->sin6_addr
.s6_addr32
[i
]))
1436 bit1
= ffs (in1_dst
->sin6_addr
.s6_addr32
[i
]
1437 ^ in1_src
->sin6_addr
.s6_addr32
[i
]);
1438 bit2
= ffs (in2_dst
->sin6_addr
.s6_addr32
[i
]
1439 ^ in2_src
->sin6_addr
.s6_addr32
[i
]);
1450 /* Rule 10: Otherwise, leave the order unchanged. */
1456 getaddrinfo (const char *name
, const char *service
,
1457 const struct addrinfo
*hints
, struct addrinfo
**pai
)
1459 int i
= 0, j
= 0, last_i
= 0;
1461 struct addrinfo
*p
= NULL
, **end
;
1462 struct gaih
*g
= gaih
, *pg
= NULL
;
1463 struct gaih_service gaih_service
, *pservice
;
1464 struct addrinfo local_hints
;
1466 if (name
!= NULL
&& name
[0] == '*' && name
[1] == 0)
1469 if (service
!= NULL
&& service
[0] == '*' && service
[1] == 0)
1472 if (name
== NULL
&& service
== NULL
)
1476 hints
= &default_hints
;
1479 & ~(AI_PASSIVE
|AI_CANONNAME
|AI_NUMERICHOST
|AI_ADDRCONFIG
|AI_V4MAPPED
1481 |AI_IDN
|AI_CANONIDN
|AI_IDN_ALLOW_UNASSIGNED
1482 |AI_IDN_USE_STD3_ASCII_RULES
1484 |AI_NUMERICSERV
|AI_ALL
))
1485 return EAI_BADFLAGS
;
1487 if ((hints
->ai_flags
& AI_CANONNAME
) && name
== NULL
)
1488 return EAI_BADFLAGS
;
1490 if (hints
->ai_flags
& AI_ADDRCONFIG
)
1492 /* Determine whether we have IPv4 or IPv6 interfaces or both.
1493 We cannot cache the results since new interfaces could be
1494 added at any time. */
1497 __check_pf (&seen_ipv4
, &seen_ipv6
);
1499 /* Now make a decision on what we return, if anything. */
1500 if (hints
->ai_family
== PF_UNSPEC
&& (seen_ipv4
|| seen_ipv6
))
1502 /* If we haven't seen both IPv4 and IPv6 interfaces we can
1503 narrow down the search. */
1504 if (! seen_ipv4
|| ! seen_ipv6
)
1506 local_hints
= *hints
;
1507 local_hints
.ai_family
= seen_ipv4
? PF_INET
: PF_INET6
;
1508 hints
= &local_hints
;
1511 else if ((hints
->ai_family
== PF_INET
&& ! seen_ipv4
)
1512 || (hints
->ai_family
== PF_INET6
&& ! seen_ipv6
))
1513 /* We cannot possibly return a valid answer. */
1517 if (service
&& service
[0])
1520 gaih_service
.name
= service
;
1521 gaih_service
.num
= strtoul (gaih_service
.name
, &c
, 10);
1524 if (hints
->ai_flags
& AI_NUMERICSERV
)
1527 gaih_service
.num
= -1;
1530 pservice
= &gaih_service
;
1542 if (hints
->ai_family
== g
->family
|| hints
->ai_family
== AF_UNSPEC
)
1545 if (pg
== NULL
|| pg
->gaih
!= g
->gaih
)
1548 i
= g
->gaih (name
, pservice
, hints
, end
);
1551 /* EAI_NODATA is a more specific result as it says that
1552 we found a result but it is not usable. */
1553 if (last_i
!= (GAIH_OKIFUNSPEC
| -EAI_NODATA
))
1556 if (hints
->ai_family
== AF_UNSPEC
&& (i
& GAIH_OKIFUNSPEC
))
1564 return -(i
& GAIH_EAI
);
1569 end
= &((*end
)->ai_next
);
1582 /* Sort results according to RFC 3484. */
1583 struct sort_result results
[nresults
];
1585 struct addrinfo
*last
= NULL
;
1586 char *canonname
= NULL
;
1588 for (i
= 0, q
= p
; q
!= NULL
; ++i
, last
= q
, q
= q
->ai_next
)
1590 results
[i
].dest_addr
= q
;
1591 results
[i
].got_source_addr
= false;
1593 /* If we just looked up the address for a different
1594 protocol, reuse the result. */
1595 if (last
!= NULL
&& last
->ai_addrlen
== q
->ai_addrlen
1596 && memcmp (last
->ai_addr
, q
->ai_addr
, q
->ai_addrlen
) == 0)
1598 memcpy (&results
[i
].source_addr
, &results
[i
- 1].source_addr
,
1599 results
[i
- 1].source_addr_len
);
1600 results
[i
].source_addr_len
= results
[i
- 1].source_addr_len
;
1601 results
[i
].got_source_addr
= results
[i
- 1].got_source_addr
;
1605 /* We overwrite the type with SOCK_DGRAM since we do not
1606 want connect() to connect to the other side. If we
1607 cannot determine the source address remember this
1609 int fd
= __socket (q
->ai_family
, SOCK_DGRAM
, IPPROTO_IP
);
1610 socklen_t sl
= sizeof (results
[i
].source_addr
);
1612 && __connect (fd
, q
->ai_addr
, q
->ai_addrlen
) == 0
1613 && __getsockname (fd
,
1614 (struct sockaddr
*) &results
[i
].source_addr
,
1617 results
[i
].source_addr_len
= sl
;
1618 results
[i
].got_source_addr
= true;
1621 /* Just make sure that if we have to process the same
1622 address again we do not copy any memory. */
1623 results
[i
].source_addr_len
= 0;
1626 close_not_cancel_no_status (fd
);
1629 /* Remember the canonical name. */
1630 if (q
->ai_canonname
!= NULL
)
1632 assert (canonname
== NULL
);
1633 canonname
= q
->ai_canonname
;
1634 q
->ai_canonname
= NULL
;
1638 /* We got all the source addresses we can get, now sort using
1640 qsort (results
, nresults
, sizeof (results
[0]), rfc3484_sort
);
1642 /* Queue the results up as they come out of sorting. */
1643 q
= p
= results
[0].dest_addr
;
1644 for (i
= 1; i
< nresults
; ++i
)
1645 q
= q
->ai_next
= results
[i
].dest_addr
;
1648 /* Fill in the canonical name into the new first entry. */
1649 p
->ai_canonname
= canonname
;
1658 if (pai
== NULL
&& last_i
== 0)
1661 return last_i
? -(last_i
& GAIH_EAI
) : EAI_NONAME
;
1663 libc_hidden_def (getaddrinfo
)
1665 static_link_warning (getaddrinfo
)
1668 freeaddrinfo (struct addrinfo
*ai
)
1676 free (p
->ai_canonname
);
1680 libc_hidden_def (freeaddrinfo
)