address_sorting.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /* $NetBSD: getaddrinfo.c,v 1.82 2006/03/25 12:09:40 rpaulo Exp $ */
  2. /* $KAME: getaddrinfo.c,v 1.29 2000/08/31 17:26:57 itojun Exp $ */
  3. /*
  4. * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the project nor the names of its contributors
  16. * may be used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  23. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. *
  31. */
  32. /*
  33. * This is an adaptation of Android's implementation of RFC 6724
  34. * (in Android's getaddrinfo.c). It has some cosmetic differences
  35. * from Android's getaddrinfo.c, but Android's getaddrinfo.c was
  36. * used as a guide or example of a way to implement the RFC 6724 spec when
  37. * this was written.
  38. */
  39. #include "address_sorting_internal.h"
  40. #include <errno.h>
  41. #include <inttypes.h>
  42. #include <limits.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include <sys/types.h>
  46. // Scope values increase with increase in scope.
  47. static const int kIPv6AddrScopeLinkLocal = 1;
  48. static const int kIPv6AddrScopeSiteLocal = 2;
  49. static const int kIPv6AddrScopeGlobal = 3;
  50. static address_sorting_source_addr_factory* g_current_source_addr_factory =
  51. NULL;
  52. static bool address_sorting_get_source_addr(const address_sorting_address* dest,
  53. address_sorting_address* source) {
  54. return g_current_source_addr_factory->vtable->get_source_addr(
  55. g_current_source_addr_factory, dest, source);
  56. }
  57. bool address_sorting_get_source_addr_for_testing(
  58. const address_sorting_address* dest, address_sorting_address* source) {
  59. return address_sorting_get_source_addr(dest, source);
  60. }
  61. static int ipv6_prefix_match_length(const struct sockaddr_in6* sa,
  62. const struct sockaddr_in6* sb) {
  63. unsigned char* a = (unsigned char*)&sa->sin6_addr;
  64. unsigned char* b = (unsigned char*)&sb->sin6_addr;
  65. int cur_bit = 0;
  66. while (cur_bit < 128) {
  67. int high_bit = 1 << (CHAR_BIT - 1);
  68. int a_val = a[cur_bit / CHAR_BIT] & (high_bit >> (cur_bit % CHAR_BIT));
  69. int b_val = b[cur_bit / CHAR_BIT] & (high_bit >> (cur_bit % CHAR_BIT));
  70. if (a_val == b_val) {
  71. cur_bit++;
  72. } else {
  73. break;
  74. }
  75. }
  76. return cur_bit;
  77. }
  78. static int in6_is_addr_loopback(const struct in6_addr* ipv6_address) {
  79. uint32_t* bits32 = (uint32_t*)ipv6_address;
  80. return bits32[0] == 0 && bits32[1] == 0 && bits32[2] == 0 &&
  81. bits32[3] == htonl(1);
  82. }
  83. static int in6_is_addr_v4mapped(const struct in6_addr* ipv6_address) {
  84. uint32_t* bits32 = (uint32_t*)ipv6_address;
  85. return bits32[0] == 0 && bits32[1] == 0 && bits32[2] == htonl(0x0000ffff);
  86. }
  87. static int in6_is_addr_v4compat(const struct in6_addr* ipv6_address) {
  88. uint32_t* bits32 = (uint32_t*)ipv6_address;
  89. return bits32[0] == 0 && bits32[1] == 0 && bits32[2] == 0 && bits32[3] != 0 &&
  90. bits32[3] != htonl(1);
  91. }
  92. static int in6_is_addr_sitelocal(const struct in6_addr* ipv6_address) {
  93. uint8_t* bytes = (uint8_t*)ipv6_address;
  94. return bytes[0] == 0xfe && (bytes[1] & 0xc0) == 0xc0;
  95. }
  96. static int in6_is_addr_linklocal(const struct in6_addr* ipv6_address) {
  97. uint8_t* bytes = (uint8_t*)ipv6_address;
  98. return bytes[0] == 0xfe && (bytes[1] & 0xc0) == 0x80;
  99. }
  100. static int in6_is_addr_6to4(const struct in6_addr* ipv6_address) {
  101. uint8_t* bytes = (uint8_t*)ipv6_address;
  102. return bytes[0] == 0x20 && bytes[1] == 0x02;
  103. }
  104. static int in6_is_addr_ula(const struct in6_addr* ipv6_address) {
  105. uint8_t* bytes = (uint8_t*)ipv6_address;
  106. return (bytes[0] & 0xfe) == 0xfc;
  107. }
  108. static int in6_is_addr_teredo(const struct in6_addr* ipv6_address) {
  109. uint8_t* bytes = (uint8_t*)ipv6_address;
  110. return bytes[0] == 0x20 && bytes[1] == 0x01 && bytes[2] == 0x00 &&
  111. bytes[3] == 0x00;
  112. }
  113. static int in6_is_addr_6bone(const struct in6_addr* ipv6_address) {
  114. uint8_t* bytes = (uint8_t*)ipv6_address;
  115. return bytes[0] == 0x3f && bytes[1] == 0xfe;
  116. }
  117. address_sorting_family address_sorting_abstract_get_family(
  118. const address_sorting_address* address) {
  119. switch (((struct sockaddr*)address)->sa_family) {
  120. case AF_INET:
  121. return ADDRESS_SORTING_AF_INET;
  122. case AF_INET6:
  123. return ADDRESS_SORTING_AF_INET6;
  124. default:
  125. return ADDRESS_SORTING_UNKNOWN_FAMILY;
  126. }
  127. }
  128. static int get_label_value(const address_sorting_address* resolved_addr) {
  129. if (address_sorting_abstract_get_family(resolved_addr) ==
  130. ADDRESS_SORTING_AF_INET) {
  131. return 4;
  132. } else if (address_sorting_abstract_get_family(resolved_addr) !=
  133. ADDRESS_SORTING_AF_INET6) {
  134. return 1;
  135. }
  136. struct sockaddr_in6* ipv6_addr = (struct sockaddr_in6*)&resolved_addr->addr;
  137. if (in6_is_addr_loopback(&ipv6_addr->sin6_addr)) {
  138. return 0;
  139. } else if (in6_is_addr_v4mapped(&ipv6_addr->sin6_addr)) {
  140. return 4;
  141. } else if (in6_is_addr_6to4(&ipv6_addr->sin6_addr)) {
  142. return 2;
  143. } else if (in6_is_addr_teredo(&ipv6_addr->sin6_addr)) {
  144. return 5;
  145. } else if (in6_is_addr_ula(&ipv6_addr->sin6_addr)) {
  146. return 13;
  147. } else if (in6_is_addr_v4compat(&ipv6_addr->sin6_addr)) {
  148. return 3;
  149. } else if (in6_is_addr_sitelocal(&ipv6_addr->sin6_addr)) {
  150. return 11;
  151. } else if (in6_is_addr_6bone(&ipv6_addr->sin6_addr)) {
  152. return 12;
  153. }
  154. return 1;
  155. }
  156. static int get_precedence_value(const address_sorting_address* resolved_addr) {
  157. if (address_sorting_abstract_get_family(resolved_addr) ==
  158. ADDRESS_SORTING_AF_INET) {
  159. return 35;
  160. } else if (address_sorting_abstract_get_family(resolved_addr) !=
  161. ADDRESS_SORTING_AF_INET6) {
  162. return 1;
  163. }
  164. struct sockaddr_in6* ipv6_addr = (struct sockaddr_in6*)&resolved_addr->addr;
  165. if (in6_is_addr_loopback(&ipv6_addr->sin6_addr)) {
  166. return 50;
  167. } else if (in6_is_addr_v4mapped(&ipv6_addr->sin6_addr)) {
  168. return 35;
  169. } else if (in6_is_addr_6to4(&ipv6_addr->sin6_addr)) {
  170. return 30;
  171. } else if (in6_is_addr_teredo(&ipv6_addr->sin6_addr)) {
  172. return 5;
  173. } else if (in6_is_addr_ula(&ipv6_addr->sin6_addr)) {
  174. return 3;
  175. } else if (in6_is_addr_v4compat(&ipv6_addr->sin6_addr) ||
  176. in6_is_addr_sitelocal(&ipv6_addr->sin6_addr) ||
  177. in6_is_addr_6bone(&ipv6_addr->sin6_addr)) {
  178. return 1;
  179. }
  180. return 40;
  181. }
  182. static int sockaddr_get_scope(const address_sorting_address* resolved_addr) {
  183. if (address_sorting_abstract_get_family(resolved_addr) ==
  184. ADDRESS_SORTING_AF_INET) {
  185. return kIPv6AddrScopeGlobal;
  186. } else if (address_sorting_abstract_get_family(resolved_addr) ==
  187. ADDRESS_SORTING_AF_INET6) {
  188. struct sockaddr_in6* ipv6_addr = (struct sockaddr_in6*)&resolved_addr->addr;
  189. if (in6_is_addr_loopback(&ipv6_addr->sin6_addr) ||
  190. in6_is_addr_linklocal(&ipv6_addr->sin6_addr)) {
  191. return kIPv6AddrScopeLinkLocal;
  192. }
  193. if (in6_is_addr_sitelocal(&ipv6_addr->sin6_addr)) {
  194. return kIPv6AddrScopeSiteLocal;
  195. }
  196. return kIPv6AddrScopeGlobal;
  197. }
  198. return 0;
  199. }
  200. static int compare_source_addr_exists(const address_sorting_sortable* first,
  201. const address_sorting_sortable* second) {
  202. if (first->source_addr_exists != second->source_addr_exists) {
  203. return first->source_addr_exists ? -1 : 1;
  204. }
  205. return 0;
  206. }
  207. static int compare_source_dest_scope_matches(
  208. const address_sorting_sortable* first,
  209. const address_sorting_sortable* second) {
  210. bool first_src_dst_scope_matches = false;
  211. if (sockaddr_get_scope(&first->dest_addr) ==
  212. sockaddr_get_scope(&first->source_addr)) {
  213. first_src_dst_scope_matches = true;
  214. }
  215. bool second_src_dst_scope_matches = false;
  216. if (sockaddr_get_scope(&second->dest_addr) ==
  217. sockaddr_get_scope(&second->source_addr)) {
  218. second_src_dst_scope_matches = true;
  219. }
  220. if (first_src_dst_scope_matches != second_src_dst_scope_matches) {
  221. return first_src_dst_scope_matches ? -1 : 1;
  222. }
  223. return 0;
  224. }
  225. static int compare_source_dest_labels_match(
  226. const address_sorting_sortable* first,
  227. const address_sorting_sortable* second) {
  228. bool first_label_matches = false;
  229. if (get_label_value(&first->dest_addr) ==
  230. get_label_value(&first->source_addr)) {
  231. first_label_matches = true;
  232. }
  233. bool second_label_matches = false;
  234. if (get_label_value(&second->dest_addr) ==
  235. get_label_value(&second->source_addr)) {
  236. second_label_matches = true;
  237. }
  238. if (first_label_matches != second_label_matches) {
  239. return first_label_matches ? -1 : 1;
  240. }
  241. return 0;
  242. }
  243. static int compare_dest_precedence(const address_sorting_sortable* first,
  244. const address_sorting_sortable* second) {
  245. return get_precedence_value(&second->dest_addr) -
  246. get_precedence_value(&first->dest_addr);
  247. }
  248. static int compare_dest_scope(const address_sorting_sortable* first,
  249. const address_sorting_sortable* second) {
  250. return sockaddr_get_scope(&first->dest_addr) -
  251. sockaddr_get_scope(&second->dest_addr);
  252. }
  253. static int compare_source_dest_prefix_match_lengths(
  254. const address_sorting_sortable* first,
  255. const address_sorting_sortable* second) {
  256. if (first->source_addr_exists &&
  257. address_sorting_abstract_get_family(&first->source_addr) ==
  258. ADDRESS_SORTING_AF_INET6 &&
  259. second->source_addr_exists &&
  260. address_sorting_abstract_get_family(&second->source_addr) ==
  261. ADDRESS_SORTING_AF_INET6) {
  262. int first_match_length =
  263. ipv6_prefix_match_length((struct sockaddr_in6*)&first->source_addr.addr,
  264. (struct sockaddr_in6*)&first->dest_addr.addr);
  265. int second_match_length = ipv6_prefix_match_length(
  266. (struct sockaddr_in6*)&second->source_addr.addr,
  267. (struct sockaddr_in6*)&second->dest_addr.addr);
  268. return second_match_length - first_match_length;
  269. }
  270. return 0;
  271. }
  272. static int rfc_6724_compare(const void* a, const void* b) {
  273. const address_sorting_sortable* first = (address_sorting_sortable*)a;
  274. const address_sorting_sortable* second = (address_sorting_sortable*)b;
  275. int out = 0;
  276. if ((out = compare_source_addr_exists(first, second))) {
  277. return out;
  278. }
  279. if ((out = compare_source_dest_scope_matches(first, second))) {
  280. return out;
  281. }
  282. if ((out = compare_source_dest_labels_match(first, second))) {
  283. return out;
  284. }
  285. // TODO: Implement rule 3; avoid deprecated addresses.
  286. // TODO: Implement rule 4; avoid temporary addresses.
  287. if ((out = compare_dest_precedence(first, second))) {
  288. return out;
  289. }
  290. // TODO: Implement rule 7; prefer native transports.
  291. if ((out = compare_dest_scope(first, second))) {
  292. return out;
  293. }
  294. if ((out = compare_source_dest_prefix_match_lengths(first, second))) {
  295. return out;
  296. }
  297. // Prefer that the sort be stable otherwise
  298. return (int)(first->original_index - second->original_index);
  299. }
  300. void address_sorting_override_source_addr_factory_for_testing(
  301. address_sorting_source_addr_factory* factory) {
  302. if (g_current_source_addr_factory == NULL) {
  303. abort();
  304. }
  305. g_current_source_addr_factory->vtable->destroy(g_current_source_addr_factory);
  306. g_current_source_addr_factory = factory;
  307. }
  308. static void sanity_check_private_fields_are_unused(
  309. const address_sorting_sortable* sortable) {
  310. address_sorting_address expected_source_addr;
  311. memset(&expected_source_addr, 0, sizeof(expected_source_addr));
  312. if (memcmp(&expected_source_addr, &sortable->source_addr,
  313. sizeof(address_sorting_address)) ||
  314. sortable->original_index || sortable->source_addr_exists) {
  315. abort();
  316. }
  317. }
  318. void address_sorting_rfc_6724_sort(address_sorting_sortable* sortables,
  319. size_t sortables_len) {
  320. for (size_t i = 0; i < sortables_len; i++) {
  321. sanity_check_private_fields_are_unused(&sortables[i]);
  322. sortables[i].original_index = i;
  323. sortables[i].source_addr_exists = address_sorting_get_source_addr(
  324. &sortables[i].dest_addr, &sortables[i].source_addr);
  325. }
  326. qsort(sortables, sortables_len, sizeof(address_sorting_sortable),
  327. rfc_6724_compare);
  328. }
  329. void address_sorting_init() {
  330. if (g_current_source_addr_factory != NULL) {
  331. abort();
  332. }
  333. g_current_source_addr_factory =
  334. address_sorting_create_source_addr_factory_for_current_platform();
  335. }
  336. void address_sorting_shutdown() {
  337. if (g_current_source_addr_factory == NULL) {
  338. abort();
  339. }
  340. g_current_source_addr_factory->vtable->destroy(g_current_source_addr_factory);
  341. g_current_source_addr_factory = NULL;
  342. }