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 /* 34 * This is an adaptation of Android's implementation of RFC 6724 35 * (in Android's getaddrinfo.c). It has some cosmetic differences 36 * from Android's getaddrinfo.c, but Android's getaddrinfo.c was 37 * used as a guide or example of a way to implement the RFC 6724 spec when 38 * this was written. 39 */ 40 41 #include "address_sorting_internal.h" 42 43 #include <errno.h> 44 #include <inttypes.h> 45 #include <limits.h> 46 #include <stdlib.h> 47 #include <string.h> 48 #include <sys/types.h> 49 50 // Scope values increase with increase in scope. 51 static const int kIPv6AddrScopeLinkLocal = 1; 52 static const int kIPv6AddrScopeSiteLocal = 2; 53 static const int kIPv6AddrScopeGlobal = 3; 54 55 static address_sorting_source_addr_factory* g_current_source_addr_factory = 56 NULL; 57 58 static bool address_sorting_get_source_addr(const address_sorting_address* dest, 59 address_sorting_address* source) { 60 return g_current_source_addr_factory->vtable->get_source_addr( 61 g_current_source_addr_factory, dest, source); 62 } 63 64 bool address_sorting_get_source_addr_for_testing( 65 const address_sorting_address* dest, address_sorting_address* source) { 66 return address_sorting_get_source_addr(dest, source); 67 } 68 69 static int ipv6_prefix_match_length(const struct sockaddr_in6* sa, 70 const struct sockaddr_in6* sb) { 71 unsigned char* a = (unsigned char*)&sa->sin6_addr; 72 unsigned char* b = (unsigned char*)&sb->sin6_addr; 73 int cur_bit = 0; 74 while (cur_bit < 128) { 75 int high_bit = 1 << (CHAR_BIT - 1); 76 int a_val = a[cur_bit / CHAR_BIT] & (high_bit >> (cur_bit % CHAR_BIT)); 77 int b_val = b[cur_bit / CHAR_BIT] & (high_bit >> (cur_bit % CHAR_BIT)); 78 if (a_val == b_val) { 79 cur_bit++; 80 } else { 81 break; 82 } 83 } 84 return cur_bit; 85 } 86 87 static int in6_is_addr_loopback(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 && 90 bits32[3] == htonl(1); 91 } 92 93 static int in6_is_addr_v4mapped(const struct in6_addr* ipv6_address) { 94 uint32_t* bits32 = (uint32_t*)ipv6_address; 95 return bits32[0] == 0 && bits32[1] == 0 && bits32[2] == htonl(0x0000ffff); 96 } 97 98 static int in6_is_addr_v4compat(const struct in6_addr* ipv6_address) { 99 uint32_t* bits32 = (uint32_t*)ipv6_address; 100 return bits32[0] == 0 && bits32[1] == 0 && bits32[2] == 0 && bits32[3] != 0 && 101 bits32[3] != htonl(1); 102 } 103 104 static int in6_is_addr_sitelocal(const struct in6_addr* ipv6_address) { 105 uint8_t* bytes = (uint8_t*)ipv6_address; 106 return bytes[0] == 0xfe && (bytes[1] & 0xc0) == 0xc0; 107 } 108 109 static int in6_is_addr_linklocal(const struct in6_addr* ipv6_address) { 110 uint8_t* bytes = (uint8_t*)ipv6_address; 111 return bytes[0] == 0xfe && (bytes[1] & 0xc0) == 0x80; 112 } 113 114 static int in6_is_addr_6to4(const struct in6_addr* ipv6_address) { 115 uint8_t* bytes = (uint8_t*)ipv6_address; 116 return bytes[0] == 0x20 && bytes[1] == 0x02; 117 } 118 119 static int in6_is_addr_ula(const struct in6_addr* ipv6_address) { 120 uint8_t* bytes = (uint8_t*)ipv6_address; 121 return (bytes[0] & 0xfe) == 0xfc; 122 } 123 124 static int in6_is_addr_teredo(const struct in6_addr* ipv6_address) { 125 uint8_t* bytes = (uint8_t*)ipv6_address; 126 return bytes[0] == 0x20 && bytes[1] == 0x01 && bytes[2] == 0x00 && 127 bytes[3] == 0x00; 128 } 129 130 static int in6_is_addr_6bone(const struct in6_addr* ipv6_address) { 131 uint8_t* bytes = (uint8_t*)ipv6_address; 132 return bytes[0] == 0x3f && bytes[1] == 0xfe; 133 } 134 135 address_sorting_family address_sorting_abstract_get_family( 136 const address_sorting_address* address) { 137 switch (((struct sockaddr*)address)->sa_family) { 138 case AF_INET: 139 return ADDRESS_SORTING_AF_INET; 140 case AF_INET6: 141 return ADDRESS_SORTING_AF_INET6; 142 default: 143 return ADDRESS_SORTING_UNKNOWN_FAMILY; 144 } 145 } 146 147 static int get_label_value(const address_sorting_address* resolved_addr) { 148 if (address_sorting_abstract_get_family(resolved_addr) == 149 ADDRESS_SORTING_AF_INET) { 150 return 4; 151 } else if (address_sorting_abstract_get_family(resolved_addr) != 152 ADDRESS_SORTING_AF_INET6) { 153 return 1; 154 } 155 struct sockaddr_in6* ipv6_addr = (struct sockaddr_in6*)&resolved_addr->addr; 156 if (in6_is_addr_loopback(&ipv6_addr->sin6_addr)) { 157 return 0; 158 } else if (in6_is_addr_v4mapped(&ipv6_addr->sin6_addr)) { 159 return 4; 160 } else if (in6_is_addr_6to4(&ipv6_addr->sin6_addr)) { 161 return 2; 162 } else if (in6_is_addr_teredo(&ipv6_addr->sin6_addr)) { 163 return 5; 164 } else if (in6_is_addr_ula(&ipv6_addr->sin6_addr)) { 165 return 13; 166 } else if (in6_is_addr_v4compat(&ipv6_addr->sin6_addr)) { 167 return 3; 168 } else if (in6_is_addr_sitelocal(&ipv6_addr->sin6_addr)) { 169 return 11; 170 } else if (in6_is_addr_6bone(&ipv6_addr->sin6_addr)) { 171 return 12; 172 } 173 return 1; 174 } 175 176 static int get_precedence_value(const address_sorting_address* resolved_addr) { 177 if (address_sorting_abstract_get_family(resolved_addr) == 178 ADDRESS_SORTING_AF_INET) { 179 return 35; 180 } else if (address_sorting_abstract_get_family(resolved_addr) != 181 ADDRESS_SORTING_AF_INET6) { 182 return 1; 183 } 184 struct sockaddr_in6* ipv6_addr = (struct sockaddr_in6*)&resolved_addr->addr; 185 if (in6_is_addr_loopback(&ipv6_addr->sin6_addr)) { 186 return 50; 187 } else if (in6_is_addr_v4mapped(&ipv6_addr->sin6_addr)) { 188 return 35; 189 } else if (in6_is_addr_6to4(&ipv6_addr->sin6_addr)) { 190 return 30; 191 } else if (in6_is_addr_teredo(&ipv6_addr->sin6_addr)) { 192 return 5; 193 } else if (in6_is_addr_ula(&ipv6_addr->sin6_addr)) { 194 return 3; 195 } else if (in6_is_addr_v4compat(&ipv6_addr->sin6_addr) || 196 in6_is_addr_sitelocal(&ipv6_addr->sin6_addr) || 197 in6_is_addr_6bone(&ipv6_addr->sin6_addr)) { 198 return 1; 199 } 200 return 40; 201 } 202 203 static int sockaddr_get_scope(const address_sorting_address* resolved_addr) { 204 if (address_sorting_abstract_get_family(resolved_addr) == 205 ADDRESS_SORTING_AF_INET) { 206 return kIPv6AddrScopeGlobal; 207 } else if (address_sorting_abstract_get_family(resolved_addr) == 208 ADDRESS_SORTING_AF_INET6) { 209 struct sockaddr_in6* ipv6_addr = (struct sockaddr_in6*)&resolved_addr->addr; 210 if (in6_is_addr_loopback(&ipv6_addr->sin6_addr) || 211 in6_is_addr_linklocal(&ipv6_addr->sin6_addr)) { 212 return kIPv6AddrScopeLinkLocal; 213 } 214 if (in6_is_addr_sitelocal(&ipv6_addr->sin6_addr)) { 215 return kIPv6AddrScopeSiteLocal; 216 } 217 return kIPv6AddrScopeGlobal; 218 } 219 return 0; 220 } 221 222 static int compare_source_addr_exists(const address_sorting_sortable* first, 223 const address_sorting_sortable* second) { 224 if (first->source_addr_exists != second->source_addr_exists) { 225 return first->source_addr_exists ? -1 : 1; 226 } 227 return 0; 228 } 229 230 static int compare_source_dest_scope_matches( 231 const address_sorting_sortable* first, 232 const address_sorting_sortable* second) { 233 bool first_src_dst_scope_matches = false; 234 if (sockaddr_get_scope(&first->dest_addr) == 235 sockaddr_get_scope(&first->source_addr)) { 236 first_src_dst_scope_matches = true; 237 } 238 bool second_src_dst_scope_matches = false; 239 if (sockaddr_get_scope(&second->dest_addr) == 240 sockaddr_get_scope(&second->source_addr)) { 241 second_src_dst_scope_matches = true; 242 } 243 if (first_src_dst_scope_matches != second_src_dst_scope_matches) { 244 return first_src_dst_scope_matches ? -1 : 1; 245 } 246 return 0; 247 } 248 249 static int compare_source_dest_labels_match( 250 const address_sorting_sortable* first, 251 const address_sorting_sortable* second) { 252 bool first_label_matches = false; 253 if (get_label_value(&first->dest_addr) == 254 get_label_value(&first->source_addr)) { 255 first_label_matches = true; 256 } 257 bool second_label_matches = false; 258 if (get_label_value(&second->dest_addr) == 259 get_label_value(&second->source_addr)) { 260 second_label_matches = true; 261 } 262 if (first_label_matches != second_label_matches) { 263 return first_label_matches ? -1 : 1; 264 } 265 return 0; 266 } 267 268 static int compare_dest_precedence(const address_sorting_sortable* first, 269 const address_sorting_sortable* second) { 270 return get_precedence_value(&second->dest_addr) - 271 get_precedence_value(&first->dest_addr); 272 } 273 274 static int compare_dest_scope(const address_sorting_sortable* first, 275 const address_sorting_sortable* second) { 276 return sockaddr_get_scope(&first->dest_addr) - 277 sockaddr_get_scope(&second->dest_addr); 278 } 279 280 static int compare_source_dest_prefix_match_lengths( 281 const address_sorting_sortable* first, 282 const address_sorting_sortable* second) { 283 if (first->source_addr_exists && 284 address_sorting_abstract_get_family(&first->source_addr) == 285 ADDRESS_SORTING_AF_INET6 && 286 second->source_addr_exists && 287 address_sorting_abstract_get_family(&second->source_addr) == 288 ADDRESS_SORTING_AF_INET6) { 289 int first_match_length = 290 ipv6_prefix_match_length((struct sockaddr_in6*)&first->source_addr.addr, 291 (struct sockaddr_in6*)&first->dest_addr.addr); 292 int second_match_length = ipv6_prefix_match_length( 293 (struct sockaddr_in6*)&second->source_addr.addr, 294 (struct sockaddr_in6*)&second->dest_addr.addr); 295 return second_match_length - first_match_length; 296 } 297 return 0; 298 } 299 300 static int rfc_6724_compare(const void* a, const void* b) { 301 const address_sorting_sortable* first = (address_sorting_sortable*)a; 302 const address_sorting_sortable* second = (address_sorting_sortable*)b; 303 int out = 0; 304 if ((out = compare_source_addr_exists(first, second))) { 305 return out; 306 } 307 if ((out = compare_source_dest_scope_matches(first, second))) { 308 return out; 309 } 310 if ((out = compare_source_dest_labels_match(first, second))) { 311 return out; 312 } 313 // TODO: Implement rule 3; avoid deprecated addresses. 314 // TODO: Implement rule 4; avoid temporary addresses. 315 if ((out = compare_dest_precedence(first, second))) { 316 return out; 317 } 318 // TODO: Implement rule 7; prefer native transports. 319 if ((out = compare_dest_scope(first, second))) { 320 return out; 321 } 322 if ((out = compare_source_dest_prefix_match_lengths(first, second))) { 323 return out; 324 } 325 // Prefer that the sort be stable otherwise 326 return (int)(first->original_index - second->original_index); 327 } 328 329 void address_sorting_override_source_addr_factory_for_testing( 330 address_sorting_source_addr_factory* factory) { 331 if (g_current_source_addr_factory == NULL) { 332 abort(); 333 } 334 g_current_source_addr_factory->vtable->destroy(g_current_source_addr_factory); 335 g_current_source_addr_factory = factory; 336 } 337 338 static void sanity_check_private_fields_are_unused( 339 const address_sorting_sortable* sortable) { 340 address_sorting_address expected_source_addr; 341 memset(&expected_source_addr, 0, sizeof(expected_source_addr)); 342 if (memcmp(&expected_source_addr, &sortable->source_addr, 343 sizeof(address_sorting_address)) || 344 sortable->original_index || sortable->source_addr_exists) { 345 abort(); 346 } 347 } 348 349 void address_sorting_rfc_6724_sort(address_sorting_sortable* sortables, 350 size_t sortables_len) { 351 for (size_t i = 0; i < sortables_len; i++) { 352 sanity_check_private_fields_are_unused(&sortables[i]); 353 sortables[i].original_index = i; 354 sortables[i].source_addr_exists = address_sorting_get_source_addr( 355 &sortables[i].dest_addr, &sortables[i].source_addr); 356 } 357 qsort(sortables, sortables_len, sizeof(address_sorting_sortable), 358 rfc_6724_compare); 359 } 360 361 void address_sorting_init() { 362 if (g_current_source_addr_factory != NULL) { 363 abort(); 364 } 365 g_current_source_addr_factory = 366 address_sorting_create_source_addr_factory_for_current_platform(); 367 } 368 369 void address_sorting_shutdown() { 370 if (g_current_source_addr_factory == NULL) { 371 abort(); 372 } 373 g_current_source_addr_factory->vtable->destroy(g_current_source_addr_factory); 374 g_current_source_addr_factory = NULL; 375 } 376