1 /*
2 * Original file name getaddrinfo.c
3 * Lifted from the 'Android Bionic' project with the BSD license.
4 */
5
6 /*
7 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
8 * Copyright (C) 2018 The Android Open Source Project
9 * Copyright (C) 2019 by Andrew Selivanov
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the project nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37 #include "ares_setup.h"
38
39 #ifdef HAVE_NETINET_IN_H
40 # include <netinet/in.h>
41 #endif
42 #ifdef HAVE_NETDB_H
43 # include <netdb.h>
44 #endif
45 #ifdef HAVE_STRINGS_H
46 # include <strings.h>
47 #endif
48
49 #include <assert.h>
50 #include <limits.h>
51
52 #include "ares.h"
53 #include "ares_private.h"
54
55 struct addrinfo_sort_elem
56 {
57 struct ares_addrinfo_node *ai;
58 int has_src_addr;
59 ares_sockaddr src_addr;
60 int original_order;
61 };
62
63 #define ARES_IPV6_ADDR_MC_SCOPE(a) ((a)->s6_addr[1] & 0x0f)
64
65 #define ARES_IPV6_ADDR_SCOPE_NODELOCAL 0x01
66 #define ARES_IPV6_ADDR_SCOPE_INTFACELOCAL 0x01
67 #define ARES_IPV6_ADDR_SCOPE_LINKLOCAL 0x02
68 #define ARES_IPV6_ADDR_SCOPE_SITELOCAL 0x05
69 #define ARES_IPV6_ADDR_SCOPE_ORGLOCAL 0x08
70 #define ARES_IPV6_ADDR_SCOPE_GLOBAL 0x0e
71
72 #define ARES_IN_LOOPBACK(a) ((((long int)(a)) & 0xff000000) == 0x7f000000)
73
74 /* RFC 4193. */
75 #define ARES_IN6_IS_ADDR_ULA(a) (((a)->s6_addr[0] & 0xfe) == 0xfc)
76
77 /* These macros are modelled after the ones in <netinet/in6.h>. */
78 /* RFC 4380, section 2.6 */
79 #define ARES_IN6_IS_ADDR_TEREDO(a) \
80 ((*(const unsigned int *)(const void *)(&(a)->s6_addr[0]) == ntohl(0x20010000)))
81 /* RFC 3056, section 2. */
82 #define ARES_IN6_IS_ADDR_6TO4(a) \
83 (((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02))
84 /* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */
85 #define ARES_IN6_IS_ADDR_6BONE(a) \
86 (((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe))
87
88
get_scope(const struct sockaddr * addr)89 static int get_scope(const struct sockaddr *addr)
90 {
91 if (addr->sa_family == AF_INET6)
92 {
93 const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr);
94 if (IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr))
95 {
96 return ARES_IPV6_ADDR_MC_SCOPE(&addr6->sin6_addr);
97 }
98 else if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr) ||
99 IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr))
100 {
101 /*
102 * RFC 4291 section 2.5.3 says loopback is to be treated as having
103 * link-local scope.
104 */
105 return ARES_IPV6_ADDR_SCOPE_LINKLOCAL;
106 }
107 else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr))
108 {
109 return ARES_IPV6_ADDR_SCOPE_SITELOCAL;
110 }
111 else
112 {
113 return ARES_IPV6_ADDR_SCOPE_GLOBAL;
114 }
115 }
116 else if (addr->sa_family == AF_INET)
117 {
118 const struct sockaddr_in *addr4 = CARES_INADDR_CAST(const struct sockaddr_in *, addr);
119 unsigned long int na = ntohl(addr4->sin_addr.s_addr);
120 if (ARES_IN_LOOPBACK(na) || /* 127.0.0.0/8 */
121 (na & 0xffff0000) == 0xa9fe0000) /* 169.254.0.0/16 */
122 {
123 return ARES_IPV6_ADDR_SCOPE_LINKLOCAL;
124 }
125 else
126 {
127 /*
128 * RFC 6724 section 3.2. Other IPv4 addresses, including private
129 * addresses and shared addresses (100.64.0.0/10), are assigned global
130 * scope.
131 */
132 return ARES_IPV6_ADDR_SCOPE_GLOBAL;
133 }
134 }
135 else
136 {
137 /*
138 * This should never happen.
139 * Return a scope with low priority as a last resort.
140 */
141 return ARES_IPV6_ADDR_SCOPE_NODELOCAL;
142 }
143 }
144
get_label(const struct sockaddr * addr)145 static int get_label(const struct sockaddr *addr)
146 {
147 if (addr->sa_family == AF_INET)
148 {
149 return 4;
150 }
151 else if (addr->sa_family == AF_INET6)
152 {
153 const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr);
154 if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr))
155 {
156 return 0;
157 }
158 else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr))
159 {
160 return 4;
161 }
162 else if (ARES_IN6_IS_ADDR_6TO4(&addr6->sin6_addr))
163 {
164 return 2;
165 }
166 else if (ARES_IN6_IS_ADDR_TEREDO(&addr6->sin6_addr))
167 {
168 return 5;
169 }
170 else if (ARES_IN6_IS_ADDR_ULA(&addr6->sin6_addr))
171 {
172 return 13;
173 }
174 else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr))
175 {
176 return 3;
177 }
178 else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr))
179 {
180 return 11;
181 }
182 else if (ARES_IN6_IS_ADDR_6BONE(&addr6->sin6_addr))
183 {
184 return 12;
185 }
186 else
187 {
188 /* All other IPv6 addresses, including global unicast addresses. */
189 return 1;
190 }
191 }
192 else
193 {
194 /*
195 * This should never happen.
196 * Return a semi-random label as a last resort.
197 */
198 return 1;
199 }
200 }
201
202 /*
203 * Get the precedence for a given IPv4/IPv6 address.
204 * RFC 6724, section 2.1.
205 */
get_precedence(const struct sockaddr * addr)206 static int get_precedence(const struct sockaddr *addr)
207 {
208 if (addr->sa_family == AF_INET)
209 {
210 return 35;
211 }
212 else if (addr->sa_family == AF_INET6)
213 {
214 const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr);
215 if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr))
216 {
217 return 50;
218 }
219 else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr))
220 {
221 return 35;
222 }
223 else if (ARES_IN6_IS_ADDR_6TO4(&addr6->sin6_addr))
224 {
225 return 30;
226 }
227 else if (ARES_IN6_IS_ADDR_TEREDO(&addr6->sin6_addr))
228 {
229 return 5;
230 }
231 else if (ARES_IN6_IS_ADDR_ULA(&addr6->sin6_addr))
232 {
233 return 3;
234 }
235 else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) ||
236 IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) ||
237 ARES_IN6_IS_ADDR_6BONE(&addr6->sin6_addr))
238 {
239 return 1;
240 }
241 else
242 {
243 /* All other IPv6 addresses, including global unicast addresses. */
244 return 40;
245 }
246 }
247 else
248 {
249 return 1;
250 }
251 }
252
253 /*
254 * Find number of matching initial bits between the two addresses a1 and a2.
255 */
common_prefix_len(const struct in6_addr * a1,const struct in6_addr * a2)256 static int common_prefix_len(const struct in6_addr *a1,
257 const struct in6_addr *a2)
258 {
259 const char *p1 = (const char *)a1;
260 const char *p2 = (const char *)a2;
261 unsigned i;
262 for (i = 0; i < sizeof(*a1); ++i)
263 {
264 int x, j;
265 if (p1[i] == p2[i])
266 {
267 continue;
268 }
269 x = p1[i] ^ p2[i];
270 for (j = 0; j < CHAR_BIT; ++j)
271 {
272 if (x & (1 << (CHAR_BIT - 1)))
273 {
274 return i * CHAR_BIT + j;
275 }
276 x <<= 1;
277 }
278 }
279 return sizeof(*a1) * CHAR_BIT;
280 }
281
282 /*
283 * Compare two source/destination address pairs.
284 * RFC 6724, section 6.
285 */
rfc6724_compare(const void * ptr1,const void * ptr2)286 static int rfc6724_compare(const void *ptr1, const void *ptr2)
287 {
288 const struct addrinfo_sort_elem *a1 = (const struct addrinfo_sort_elem *)ptr1;
289 const struct addrinfo_sort_elem *a2 = (const struct addrinfo_sort_elem *)ptr2;
290 int scope_src1, scope_dst1, scope_match1;
291 int scope_src2, scope_dst2, scope_match2;
292 int label_src1, label_dst1, label_match1;
293 int label_src2, label_dst2, label_match2;
294 int precedence1, precedence2;
295 int prefixlen1, prefixlen2;
296
297 /* Rule 1: Avoid unusable destinations. */
298 if (a1->has_src_addr != a2->has_src_addr)
299 {
300 return a2->has_src_addr - a1->has_src_addr;
301 }
302
303 /* Rule 2: Prefer matching scope. */
304 scope_src1 = ARES_IPV6_ADDR_SCOPE_NODELOCAL;
305 if (a1->has_src_addr)
306 scope_src1 = get_scope(&a1->src_addr.sa);
307 scope_dst1 = get_scope(a1->ai->ai_addr);
308 scope_match1 = (scope_src1 == scope_dst1);
309
310 scope_src2 = ARES_IPV6_ADDR_SCOPE_NODELOCAL;
311 if (a2->has_src_addr)
312 scope_src2 = get_scope(&a2->src_addr.sa);
313 scope_dst2 = get_scope(a2->ai->ai_addr);
314 scope_match2 = (scope_src2 == scope_dst2);
315
316 if (scope_match1 != scope_match2)
317 {
318 return scope_match2 - scope_match1;
319 }
320
321 /* Rule 3: Avoid deprecated addresses. */
322
323 /* Rule 4: Prefer home addresses. */
324
325 /* Rule 5: Prefer matching label. */
326 label_src1 = 1;
327 if (a1->has_src_addr)
328 label_src1 = get_label(&a1->src_addr.sa);
329 label_dst1 = get_label(a1->ai->ai_addr);
330 label_match1 = (label_src1 == label_dst1);
331
332 label_src2 = 1;
333 if (a2->has_src_addr)
334 label_src2 = get_label(&a2->src_addr.sa);
335 label_dst2 = get_label(a2->ai->ai_addr);
336 label_match2 = (label_src2 == label_dst2);
337
338 if (label_match1 != label_match2)
339 {
340 return label_match2 - label_match1;
341 }
342
343 /* Rule 6: Prefer higher precedence. */
344 precedence1 = get_precedence(a1->ai->ai_addr);
345 precedence2 = get_precedence(a2->ai->ai_addr);
346 if (precedence1 != precedence2)
347 {
348 return precedence2 - precedence1;
349 }
350
351 /* Rule 7: Prefer native transport. */
352
353 /* Rule 8: Prefer smaller scope. */
354 if (scope_dst1 != scope_dst2)
355 {
356 return scope_dst1 - scope_dst2;
357 }
358
359 /* Rule 9: Use longest matching prefix. */
360 if (a1->has_src_addr && a1->ai->ai_addr->sa_family == AF_INET6 &&
361 a2->has_src_addr && a2->ai->ai_addr->sa_family == AF_INET6)
362 {
363 const struct sockaddr_in6 *a1_src = &a1->src_addr.sa6;
364 const struct sockaddr_in6 *a1_dst =
365 CARES_INADDR_CAST(const struct sockaddr_in6 *, a1->ai->ai_addr);
366 const struct sockaddr_in6 *a2_src = &a2->src_addr.sa6;
367 const struct sockaddr_in6 *a2_dst =
368 CARES_INADDR_CAST(const struct sockaddr_in6 *, a2->ai->ai_addr);
369 prefixlen1 = common_prefix_len(&a1_src->sin6_addr, &a1_dst->sin6_addr);
370 prefixlen2 = common_prefix_len(&a2_src->sin6_addr, &a2_dst->sin6_addr);
371 if (prefixlen1 != prefixlen2)
372 {
373 return prefixlen2 - prefixlen1;
374 }
375 }
376
377 /*
378 * Rule 10: Leave the order unchanged.
379 * We need this since qsort() is not necessarily stable.
380 */
381 return a1->original_order - a2->original_order;
382 }
383
384 /*
385 * Find the source address that will be used if trying to connect to the given
386 * address.
387 *
388 * Returns 1 if a source address was found, 0 if the address is unreachable,
389 * and -1 if a fatal error occurred. If 0 or 1, the contents of src_addr are
390 * undefined.
391 */
find_src_addr(ares_channel channel,const struct sockaddr * addr,struct sockaddr * src_addr)392 static int find_src_addr(ares_channel channel,
393 const struct sockaddr *addr,
394 struct sockaddr *src_addr)
395 {
396 ares_socket_t sock;
397 int ret;
398 ares_socklen_t len;
399
400 switch (addr->sa_family)
401 {
402 case AF_INET:
403 len = sizeof(struct sockaddr_in);
404 break;
405 case AF_INET6:
406 len = sizeof(struct sockaddr_in6);
407 break;
408 default:
409 /* No known usable source address for non-INET families. */
410 return 0;
411 }
412
413 sock = ares__open_socket(channel, addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
414 if (sock == ARES_SOCKET_BAD)
415 {
416 if (errno == EAFNOSUPPORT)
417 {
418 return 0;
419 }
420 else
421 {
422 return -1;
423 }
424 }
425
426 do
427 {
428 ret = ares__connect_socket(channel, sock, addr, len);
429 }
430 while (ret == -1 && errno == EINTR);
431
432 if (ret == -1)
433 {
434 ares__close_socket(channel, sock);
435 return 0;
436 }
437
438 if (getsockname(sock, src_addr, &len) != 0)
439 {
440 ares__close_socket(channel, sock);
441 return -1;
442 }
443 ares__close_socket(channel, sock);
444 return 1;
445 }
446
447 /*
448 * Sort the linked list starting at sentinel->ai_next in RFC6724 order.
449 * Will leave the list unchanged if an error occurs.
450 */
ares__sortaddrinfo(ares_channel channel,struct ares_addrinfo_node * list_sentinel)451 int ares__sortaddrinfo(ares_channel channel, struct ares_addrinfo_node *list_sentinel)
452 {
453 struct ares_addrinfo_node *cur;
454 int nelem = 0, i;
455 int has_src_addr;
456 struct addrinfo_sort_elem *elems;
457
458 cur = list_sentinel->ai_next;
459 while (cur)
460 {
461 ++nelem;
462 cur = cur->ai_next;
463 }
464
465 if (!nelem)
466 return ARES_ENODATA;
467
468 elems = (struct addrinfo_sort_elem *)ares_malloc(
469 nelem * sizeof(struct addrinfo_sort_elem));
470 if (!elems)
471 {
472 return ARES_ENOMEM;
473 }
474
475 /*
476 * Convert the linked list to an array that also contains the candidate
477 * source address for each destination address.
478 */
479 for (i = 0, cur = list_sentinel->ai_next; i < nelem; ++i, cur = cur->ai_next)
480 {
481 assert(cur != NULL);
482 elems[i].ai = cur;
483 elems[i].original_order = i;
484 has_src_addr = find_src_addr(channel, cur->ai_addr, &elems[i].src_addr.sa);
485 if (has_src_addr == -1)
486 {
487 ares_free(elems);
488 return ARES_ENOTFOUND;
489 }
490 elems[i].has_src_addr = has_src_addr;
491 }
492
493 /* Sort the addresses, and rearrange the linked list so it matches the sorted
494 * order. */
495 qsort((void *)elems, nelem, sizeof(struct addrinfo_sort_elem),
496 rfc6724_compare);
497
498 list_sentinel->ai_next = elems[0].ai;
499 for (i = 0; i < nelem - 1; ++i)
500 {
501 elems[i].ai->ai_next = elems[i + 1].ai;
502 }
503 elems[nelem - 1].ai->ai_next = NULL;
504
505 ares_free(elems);
506 return ARES_SUCCESS;
507 }
508