1 /* route.c 2 * 3 * Copyright (c) 2019-2024 Apple Inc. All rights reserved. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * https://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 * This code adds border router support to 3rd party HomeKit Routers as part of Apples commitment to the CHIP project. 18 * 19 * This file contains an implementation of Thread Border Router routing. 20 * The state of the Thread network is tracked, the state of the infrastructure 21 * network is tracked, and policy decisions are made as to what to advertise 22 * on both networks. 23 */ 24 25 #ifndef LINUX 26 #include <netinet/in.h> 27 #include <net/if.h> 28 #include <netinet6/in6_var.h> 29 #include <netinet6/nd6.h> 30 #include <net/if_media.h> 31 #include <sys/stat.h> 32 #else 33 #define _GNU_SOURCE 34 #include <netinet/in.h> 35 #include <fcntl.h> 36 #include <bsd/stdlib.h> 37 #include <net/if.h> 38 #endif 39 #include <sys/socket.h> 40 #include <sys/ioctl.h> 41 #include <net/route.h> 42 #include <netinet/icmp6.h> 43 #include <stdio.h> 44 #include <unistd.h> 45 #include <errno.h> 46 #include <stdlib.h> 47 #include <string.h> 48 #include <ctype.h> 49 #include <arpa/inet.h> 50 #if !USE_SYSCTL_COMMAND_TO_ENABLE_FORWARDING 51 #ifndef LINUX 52 #include <sys/sysctl.h> 53 #endif // LINUX 54 #endif // !USE_SYSCTL_COMMAND_TO_ENABLE_FORWARDING 55 #include <stdlib.h> 56 #include <stddef.h> 57 #include <dns_sd.h> 58 #include <inttypes.h> 59 #include <signal.h> 60 61 #ifdef IOLOOP_MACOS 62 #include <xpc/xpc.h> 63 64 #include <TargetConditionals.h> 65 #include <SystemConfiguration/SystemConfiguration.h> 66 #include <SystemConfiguration/SCPrivate.h> 67 #include <SystemConfiguration/SCNetworkConfigurationPrivate.h> 68 #include <SystemConfiguration/SCNetworkSignature.h> 69 #include <network_information.h> 70 71 #include <CoreUtils/CoreUtils.h> 72 #endif // IOLOOP_MACOS 73 74 #include "srp.h" 75 #include "dns-msg.h" 76 #include "ioloop.h" 77 #include "srp-crypto.h" 78 #include "srp-gw.h" 79 #include "srp-mdns-proxy.h" 80 #include "adv-ctl-server.h" 81 #include "srp-replication.h" 82 83 84 # define THREAD_DATA_DIR "/var/lib/openthread" 85 # define THREAD_ULA_FILE THREAD_DATA_DIR "/thread-mesh-ula" 86 87 #if STUB_ROUTER // Stub Router is true if we're building a Thread Border router or an RA tester. 88 #ifdef THREAD_BORDER_ROUTER 89 #include "cti-services.h" 90 #endif 91 #include "srp-gw.h" 92 #include "srp-proxy.h" 93 #include "srp-mdns-proxy.h" 94 #include "dnssd-proxy.h" 95 #if SRP_FEATURE_NAT64 96 #include "nat64-macos.h" 97 #endif 98 #include "srp-proxy.h" 99 #include "route.h" 100 #include "nat64.h" 101 102 #include "state-machine.h" 103 #include "thread-service.h" 104 #include "service-tracker.h" 105 #include "omr-watcher.h" 106 #include "omr-publisher.h" 107 #include "route-tracker.h" 108 #include "icmp.h" 109 110 111 #ifdef LINUX 112 #define CONFIGURE_STATIC_INTERFACE_ADDRESSES_WITH_IFCONFIG 1 113 #endif 114 115 #ifdef LINUX 116 struct in6_addr in6addr_linklocal_allnodes = {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}; 118 struct in6_addr in6addr_linklocal_allrouters = {{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}; 120 #endif 121 122 route_state_t *route_states; 123 124 #define CONFIGURE_STATIC_INTERFACE_ADDRESSES 1 125 126 #define interface_create(route_state, name, iface) interface_create_(route_state, name, iface, __FILE__, __LINE__) 127 interface_t *NULLABLE interface_create_(route_state_t *NONNULL route_state, const char *NONNULL name, int ifindex, 128 const char *NONNULL file, int line); 129 130 static void interface_beacon_schedule(interface_t *NONNULL interface, unsigned when); 131 static void interface_prefix_configure(struct in6_addr prefix, interface_t *NONNULL interface); 132 static void interface_prefix_evaluate(interface_t *interface); 133 static void start_router_solicit(interface_t *interface); 134 #ifndef RA_TESTER 135 static void attempt_wpan_reconnect(void *context); 136 static void routing_policy_evaluate_all_interfaces(route_state_t *route_state, bool assume_changed); 137 #endif 138 static void routing_policy_evaluate(interface_t *interface, bool assume_changed); 139 static void post_solicit_policy_evaluate(void *context); 140 static void schedule_next_router_probe(interface_t *interface); 141 142 #ifndef RA_TESTER 143 static void thread_network_startup(route_state_t *route_state); 144 static void thread_network_shutdown(route_state_t *route_state); 145 static void thread_network_shutdown_start(route_state_t *route_state); 146 static void partition_state_reset(route_state_t *route_state); 147 static void partition_utun0_address_changed(route_state_t *route_state, const struct in6_addr *NONNULL addr, enum interface_address_change change); 148 static void partition_utun0_pick_listener_address(route_state_t *route_state); 149 static void partition_got_tunnel_name(route_state_t *route_state); 150 static void partition_remove_service_done(void *UNUSED NULLABLE context, cti_status_t status); 151 static void partition_stop_advertising_service(route_state_t *route_state); 152 static void partition_proxy_listener_ready(void *UNUSED NULLABLE context, uint16_t port); 153 static void partition_maybe_advertise_service(route_state_t *route_state); 154 static void partition_service_set_changed(void *context); 155 static void partition_maybe_enable_services(route_state_t *route_state); 156 static void partition_disable_service(route_state_t *route_state); 157 void partition_discontinue_srp_service(route_state_t *route_state); 158 static void partition_schedule_service_add_wakeup(route_state_t *route_state); 159 static void partition_schedule_anycast_service_add_wakeup(route_state_t *route_state); 160 #endif 161 162 route_state_t * 163 route_state_create(srp_server_t *server_state, const char *name) 164 { 165 route_state_t *new_route_state = calloc(1, sizeof(*new_route_state)); 166 if (new_route_state == NULL || (new_route_state->name = strdup(name)) == NULL) { 167 free(new_route_state); 168 ERROR("no memory for route state."); 169 return NULL; 170 } 171 #if !defined(RA_TESTER) 172 new_route_state->thread_network_running = false; 173 new_route_state->partition_may_offer_service = false; 174 new_route_state->partition_settle_satisfied = true; 175 new_route_state->current_thread_state = kCTI_NCPState_Uninitialized; 176 #endif 177 new_route_state->have_non_thread_interface = false; 178 new_route_state->ula_serial = 1; 179 new_route_state->have_xpanid_prefix = false; 180 new_route_state->have_thread_prefix = false; 181 new_route_state->config_enable_dhcpv6_prefixes = false; 182 new_route_state->srp_server = server_state; // temporarily communicate the server_state object to route.c with a static assignment. 183 new_route_state->next = route_states; 184 route_states = new_route_state; 185 return new_route_state; 186 } 187 188 static void 189 interface_finalize(void *context) 190 { 191 interface_t *interface = context; 192 if (interface->name != NULL) { 193 free(interface->name); 194 } 195 if (interface->beacon_wakeup != NULL) { 196 ioloop_wakeup_release(interface->beacon_wakeup); 197 } 198 if (interface->post_solicit_wakeup != NULL) { 199 ioloop_wakeup_release(interface->post_solicit_wakeup); 200 } 201 if (interface->stale_evaluation_wakeup != NULL) { 202 ioloop_wakeup_release(interface->stale_evaluation_wakeup); 203 } 204 if (interface->router_solicit_wakeup != NULL) { 205 ioloop_wakeup_release(interface->router_solicit_wakeup); 206 } 207 if (interface->deconfigure_wakeup != NULL) { 208 ioloop_wakeup_release(interface->deconfigure_wakeup); 209 } 210 if (interface->neighbor_solicit_wakeup != NULL) { 211 ioloop_wakeup_release(interface->neighbor_solicit_wakeup); 212 } 213 if (interface->router_probe_wakeup != NULL) { 214 ioloop_wakeup_release(interface->router_probe_wakeup); 215 } 216 free(interface); 217 } 218 219 interface_t * 220 interface_create_(route_state_t *route_state, const char *name, int ifindex, const char *file, int line) 221 { 222 interface_t *ret; 223 224 if (name == NULL) { 225 ERROR("interface_create: missing name"); 226 return NULL; 227 } 228 229 ret = calloc(1, sizeof(*ret)); 230 if (ret) { 231 RETAIN(ret, interface); 232 ret->name = strdup(name); 233 if (ret->name == NULL) { 234 ERROR("interface_create: no memory for name"); 235 RELEASE(ret, interface); 236 return NULL; 237 } 238 ret->deconfigure_wakeup = ioloop_wakeup_create(); 239 if (ret->deconfigure_wakeup == NULL) { 240 ERROR("No memory for interface deconfigure wakeup on " PUB_S_SRP ".", ret->name); 241 RELEASE(ret, interface); 242 return NULL; 243 } 244 245 ret->route_state = route_state; 246 ret->index = ifindex; 247 ret->previously_inactive = true; 248 ret->inactive = true; 249 ret->previously_ineligible = true; 250 if (!strcmp(name, "lo") || !strcmp(name, "wpan0")) { 251 ret->ineligible = true; 252 } else { 253 ret->ineligible = false; 254 } 255 } 256 return ret; 257 } 258 259 void interface_retain_(interface_t *NONNULL interface, const char *file, int line) 260 { 261 RETAIN(interface, interface); 262 } 263 264 void interface_release_(interface_t *NONNULL interface, const char *file, int line) 265 { 266 RELEASE(interface, interface); 267 } 268 269 #ifndef RA_TESTER 270 #endif // RA_TESTER 271 272 static void 273 interface_prefix_deconfigure(void *context) 274 { 275 interface_t *interface = context; 276 INFO("post solicit wakeup."); 277 278 if (interface->preferred_lifetime != 0) { 279 INFO("PUT PREFIX DECONFIGURE CODE HERE!!"); 280 interface->valid_lifetime = 0; 281 } 282 interface->deprecate_deadline = 0; 283 } 284 285 static bool 286 want_routing(route_state_t *route_state) 287 { 288 #ifdef RA_TESTER 289 (void)route_state; 290 return true; 291 #else 292 return (route_state->partition_can_provide_routing && 293 route_state->partition_has_xpanid); 294 #endif 295 } 296 297 static void 298 interface_beacon_send(interface_t *interface, const struct in6_addr *destination) 299 { 300 uint64_t now = ioloop_timenow(); 301 #ifndef RA_TESTER 302 route_state_t *route_state = interface->route_state; 303 #endif 304 305 INFO(PUB_S_SRP PUB_S_SRP PUB_S_SRP PUB_S_SRP PUB_S_SRP PUB_S_SRP, 306 interface->deprecate_deadline > now ? " ddl>now" : "", 307 #ifdef RA_TESTER 308 "", "", "", 309 #else 310 route_state->partition_can_provide_routing ? " canpr" : " !canpr", 311 route_state->partition_has_xpanid ? " havexp" : " !havexp", 312 interface->suppress_ipv6_prefix ? " suppress" : " !suppress", 313 #endif 314 interface->our_prefix_advertised ? " advert" : " !advert", 315 interface->sent_first_beacon ? "" : " first beacon"); 316 317 if (interface->deprecate_deadline > now) { 318 // The remaining valid and preferred lifetimes is the time left until the deadline. 319 interface->valid_lifetime = (uint32_t)((interface->deprecate_deadline - now) / 1000); 320 interface->preferred_lifetime = 0; 321 if (interface->valid_lifetime < icmp_listener.unsolicited_interval / 1000) { 322 SEGMENTED_IPv6_ADDR_GEN_SRP(interface->ipv6_prefix.s6_addr, __prefix_buf); 323 INFO("prefix valid life time is less than the unsolicited interval, stop advertising it " 324 "and prepare to deconfigure the prefix - ifname: " PUB_S_SRP "prefix: " PRI_SEGMENTED_IPv6_ADDR_SRP 325 ", preferred time: %" PRIu32 ", valid time: %" PRIu32 ", unsolicited interval: %" PRIu32, 326 interface->name, SEGMENTED_IPv6_ADDR_PARAM_SRP(interface->ipv6_prefix.s6_addr, __prefix_buf), 327 interface->preferred_lifetime, interface->valid_lifetime, icmp_listener.unsolicited_interval / 1000); 328 interface->our_prefix_advertised = false; 329 ioloop_add_wake_event(interface->deconfigure_wakeup, 330 interface, interface_prefix_deconfigure, 331 NULL, interface->valid_lifetime * 1000); 332 } 333 } 334 335 #ifndef RA_TESTER 336 // If we have been beaconing, and router mode has been disabled, and we don't have 337 // an on-link prefix to advertise, discontinue beaconing. 338 if (want_routing(route_state) || interface->our_prefix_advertised) { 339 #endif 340 341 // Send an RA. 342 router_advertisement_send(interface, destination); 343 if (destination == &in6addr_linklocal_allnodes) { 344 interface->sent_first_beacon = true; 345 interface->last_beacon = ioloop_timenow();; 346 } 347 #ifndef CONTINUE_ADVERTISING_DURING_DEPRECATION 348 // If we are deprecating, just send the initial deprecation to shorten the preferred lifetime, and then go silent. 349 if (interface->deprecate_deadline > now && !interface->suppress_ipv6_prefix) { 350 INFO("suppressing ipv6 prefix on " PUB_S_SRP, interface->name); 351 interface->suppress_ipv6_prefix = true; 352 } 353 #endif 354 355 #ifndef RA_TESTER 356 } else { 357 INFO("didn't send: " PUB_S_SRP PUB_S_SRP PUB_S_SRP, 358 route_state->partition_can_provide_routing ? "canpr" : "!canpr", 359 route_state->partition_has_xpanid ? " route_state->xpanid" : " !route_state->xpanid", 360 interface->our_prefix_advertised ? " advert" : " !advert"); 361 } 362 #endif 363 if (destination == &in6addr_linklocal_allnodes) { 364 if (interface->num_beacons_sent < MAX_RA_RETRANSMISSION - 1) { 365 // Schedule a beacon for between 8 and 16 seconds in the future (<MAX_INITIAL_RTR_ADVERT_INTERVAL) 366 interface_beacon_schedule(interface, 8000 + srp_random16() % 8000); 367 } else { 368 interface_beacon_schedule(interface, icmp_listener.unsolicited_interval); 369 } 370 interface->num_beacons_sent++; 371 } 372 } 373 374 static void 375 interface_beacon(void *context) 376 { 377 interface_t *interface = context; 378 interface_beacon_send(interface, &in6addr_linklocal_allnodes); 379 } 380 381 static void 382 interface_beacon_schedule(interface_t *interface, unsigned when) 383 { 384 uint64_t now = ioloop_timenow(); 385 unsigned interval; 386 387 388 // Make sure we haven't send an RA too recently. 389 if (when < MIN_DELAY_BETWEEN_RAS && now - interface->last_beacon < MIN_DELAY_BETWEEN_RAS) { 390 when = MIN_DELAY_BETWEEN_RAS; 391 } 392 // Add up to a second of jitter. 393 when += srp_random16() % 1024; 394 interface->next_beacon = now + when; 395 if (interface->beacon_wakeup == NULL) { 396 interface->beacon_wakeup = ioloop_wakeup_create(); 397 if (interface->beacon_wakeup == NULL) { 398 ERROR("Unable to allocate beacon wakeup for " PUB_S_SRP, interface->name); 399 return; 400 } 401 } else { 402 // We can reschedule a beacon for sooner if we get a router solicit; in this case, we 403 // need to cancel the existing beacon wakeup, and if there is none scheduled, this will 404 // be a no-op. 405 ioloop_cancel_wake_event(interface->beacon_wakeup); 406 } 407 if (interface->next_beacon - now > UINT_MAX) { 408 interval = UINT_MAX; 409 } else { 410 interval = (unsigned)(interface->next_beacon - now); 411 } 412 INFO("Scheduling " PUB_S_SRP "beacon on " PUB_S_SRP " for %u milliseconds in the future", 413 interface->sent_first_beacon ? "" : "first ", interface->name, interval); 414 ioloop_add_wake_event(interface->beacon_wakeup, interface, interface_beacon, NULL, interval); 415 } 416 417 static void 418 router_discovery_start(interface_t *interface) 419 { 420 INFO("Starting router discovery on " PUB_S_SRP, interface->name); 421 422 // Immediately when an interface shows up, start doing router solicits. 423 start_router_solicit(interface); 424 425 if (interface->post_solicit_wakeup == NULL) { 426 interface->post_solicit_wakeup = ioloop_wakeup_create(); 427 if (interface->post_solicit_wakeup == NULL) { 428 ERROR("No memory for post-solicit RA wakeup on " PUB_S_SRP ".", interface->name); 429 } 430 } else { 431 ioloop_cancel_wake_event(interface->post_solicit_wakeup); 432 } 433 434 // In 20 seconds, check the results of router discovery and update policy as needed. 435 if (interface->post_solicit_wakeup) { 436 ioloop_add_wake_event(interface->post_solicit_wakeup, interface, post_solicit_policy_evaluate, 437 NULL, 20 * 1000); 438 } 439 interface->router_discovery_in_progress = true; 440 interface->router_discovery_started = true; 441 } 442 443 static void 444 flush_routers(interface_t *interface, uint64_t now) 445 { 446 icmp_message_t *router, **p_router; 447 448 // Flush stale routers (or all routers). 449 for (p_router = &interface->routers; *p_router != NULL; ) { 450 router = *p_router; 451 if (now == 0 || now - router->received_time > MAX_ROUTER_RECEIVED_TIME_GAP_BEFORE_STALE) { 452 *p_router = router->next; 453 SEGMENTED_IPv6_ADDR_GEN_SRP(router->source.s6_addr, __router_src_addr_buf); 454 INFO("flushing stale router - ifname: " PUB_S_SRP 455 ", router src: " PRI_SEGMENTED_IPv6_ADDR_SRP, interface->name, 456 SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, __router_src_addr_buf)); 457 icmp_message_free(router); 458 } else { 459 p_router = &(*p_router)->next; 460 } 461 } 462 } 463 464 static void 465 router_discovery_cancel(interface_t *interface) 466 { 467 if (interface->router_solicit_wakeup != NULL) { 468 ioloop_cancel_wake_event(interface->router_solicit_wakeup); 469 } 470 if (interface->post_solicit_wakeup != NULL) { 471 ioloop_cancel_wake_event(interface->post_solicit_wakeup); 472 } 473 #if SRP_FEATURE_VICARIOUS_ROUTER_DISCOVERY 474 if (interface->vicarious_discovery_complete != NULL) { 475 ioloop_cancel_wake_event(interface->vicarious_discovery_complete); 476 INFO("stopping vicarious router discovery on " PUB_S_SRP, interface->name); 477 } 478 interface->vicarious_router_discovery_in_progress = false; 479 #endif // SRP_FEATURE_VICARIOUS_ROUTER_DISCOVERY 480 } 481 482 static void 483 router_discovery_stop(interface_t *interface, uint64_t now) 484 { 485 if (!interface->router_discovery_started) { 486 INFO("router discovery not yet started."); 487 return; 488 } 489 if (!interface->router_discovery_complete) { 490 INFO("stopping router discovery on " PUB_S_SRP, interface->name); 491 } 492 router_discovery_cancel(interface); 493 interface->router_discovery_complete = true; 494 interface->router_discovery_in_progress = false; 495 // clear out need_reconfigure_prefix when router_discovery_complete is set back to true. 496 interface->need_reconfigure_prefix = false; 497 #ifdef FLUSH_STALE_ROUTERS 498 flush_routers(interface, now); 499 #else 500 (void)now; 501 #endif // FLUSH_STALE_ROUTERS 502 503 // See if we need a new prefix on the interface. 504 interface_prefix_evaluate(interface); 505 } 506 507 #if SRP_FEATURE_VICARIOUS_ROUTER_DISCOVERY 508 static void 509 adjust_router_received_time(interface_t *const interface, const uint64_t now, const int64_t time_adjusted) 510 { 511 icmp_message_t *router; 512 513 if (interface->routers == NULL) { 514 if (interface->our_prefix_advertised) { 515 SEGMENTED_IPv6_ADDR_GEN_SRP(interface->ipv6_prefix.s6_addr, __ipv6_prefix); 516 INFO("No router information available for the interface - " 517 "ifname: " PUB_S_SRP ", prefix: " PRI_SEGMENTED_IPv6_ADDR_SRP, 518 interface->name, SEGMENTED_IPv6_ADDR_PARAM_SRP(interface->ipv6_prefix.s6_addr, __ipv6_prefix)); 519 } else { 520 INFO("No router information available for the interface - " 521 "ifname: " PUB_S_SRP, interface->name); 522 } 523 524 goto exit; 525 } 526 527 for (router = interface->routers; router != NULL; router = router->next) { 528 SEGMENTED_IPv6_ADDR_GEN_SRP(router->source.s6_addr, __router_src_addr_buf); 529 // Only adjust the received time once. 530 if (router->received_time_already_adjusted) { 531 INFO("received time already adjusted - remaining time: %llu, " 532 "router src: " PRI_SEGMENTED_IPv6_ADDR_SRP, (now - router->received_time) / MSEC_PER_SEC, 533 SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, __router_src_addr_buf)); 534 continue; 535 } 536 require_action_quiet( 537 (time_adjusted > 0 && (UINT64_MAX - now) > (uint64_t)time_adjusted) || 538 (time_adjusted < 0 && now > ((uint64_t)-time_adjusted)), exit, 539 ERROR("adjust_router_received_time: invalid adjusted values is causing overflow - " 540 "now: %" PRIu64 ", time_adjusted: %" PRId64, now, time_adjusted)); 541 router->received_time = now + time_adjusted; 542 router->received_time_already_adjusted = true; // Only adjust the icmp message received time once. 543 INFO("router received time is adjusted - router src: " PRI_SEGMENTED_IPv6_ADDR_SRP 544 ", adjusted value: %" PRId64, 545 SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, __router_src_addr_buf), time_adjusted); 546 } 547 548 exit: 549 return; 550 } 551 552 static void 553 make_all_routers_nearly_stale(interface_t *interface, uint64_t now) 554 { 555 // Make every router go stale in 19.999 seconds. This means that if we don't get a response 556 // to our solicit in 20 seconds, then when the timeout callback is called, there will be no 557 // routers on the interface that aren't stale, which will trigger router discovery. 558 adjust_router_received_time(interface, now, 19999 - 600 * MSEC_PER_SEC); 559 } 560 561 static void 562 vicarious_discovery_callback(void *context) 563 { 564 interface_t *interface = context; 565 INFO("Vicarious router discovery finished on " PUB_S_SRP ".", interface->name); 566 interface->vicarious_router_discovery_in_progress = false; 567 // At this point, policy evaluate will show all the routes that were present before vicarious 568 // discovery as stale, so policy_evaluate will start router discovery if we didn't get any 569 // RAs containing on-link prefixes. 570 routing_policy_evaluate(interface, false); 571 } 572 #endif // SRP_FEATURE_VICARIOUS_ROUTER_DISCOVERY 573 574 #ifndef RA_TESTER 575 static void 576 routing_policy_evaluate_all_interfaces(route_state_t *route_state, bool assume_changed) 577 { 578 interface_t *interface; 579 580 for (interface = route_state->interfaces; interface; interface = interface->next) { 581 routing_policy_evaluate(interface, assume_changed); 582 } 583 } 584 #endif 585 586 #ifdef FLUSH_STALE_ROUTERS 587 static void 588 stale_router_policy_evaluate(void *context) 589 { 590 interface_t *interface = context; 591 INFO("Evaluating stale routers on " PUB_S_SRP, interface->name); 592 593 flush_routers(interface, ioloop_timenow()); 594 595 // See if we need a new prefix on the interface. 596 interface_prefix_evaluate(interface); 597 598 routing_policy_evaluate(interface, true); 599 } 600 #endif // FLUSH_STALE_ROUTERS 601 602 static bool 603 prefix_usable(interface_t *interface, route_state_t *route_state, icmp_message_t *router, prefix_information_t *prefix) 604 { 605 SEGMENTED_IPv6_ADDR_GEN_SRP(router->source.s6_addr, router_src_addr_buf); 606 SEGMENTED_IPv6_ADDR_GEN_SRP(prefix->prefix.s6_addr, prefix_addr_buf); 607 // It needs to be on link, autoconfiguration enabled, or have the managed flag set and we are allowing DHCPv6-only 608 // prefixes (not by default). And the preferred lifetime needs to be >0 (maybe should be >= 1800?) 609 if (!((prefix->flags & ND_OPT_PI_FLAG_ONLINK) && 610 ((prefix->flags & ND_OPT_PI_FLAG_AUTO) || 611 (route_state->config_enable_dhcpv6_prefixes && (router->flags & ND_RA_FLAG_MANAGED))) && 612 prefix->preferred_lifetime > 300)) 613 { 614 INFO("Router " PRI_SEGMENTED_IPv6_ADDR_SRP 615 " is advertising prefix " PRI_SEGMENTED_IPv6_ADDR_SRP ": %sonlink, %sautoconf, %sdhcp, preferred = %d", 616 SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, router_src_addr_buf), 617 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix->prefix.s6_addr, prefix_addr_buf), 618 bool_str(prefix->flags & ND_OPT_PI_FLAG_ONLINK), 619 bool_str(prefix->flags & ND_OPT_PI_FLAG_AUTO), 620 bool_str(route_state->config_enable_dhcpv6_prefixes && (router->flags & ND_RA_FLAG_MANAGED)), 621 prefix->preferred_lifetime); 622 return false; 623 } 624 int cmp = in6prefix_compare(&prefix->prefix, &route_state->xpanid_prefix, 8); 625 if (!cmp) 626 { 627 INFO("Router " PRI_SEGMENTED_IPv6_ADDR_SRP 628 " is advertising xpanid prefix " PRI_SEGMENTED_IPv6_ADDR_SRP ": not considering it usable", 629 SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, router_src_addr_buf), 630 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix->prefix.s6_addr, prefix_addr_buf)); 631 // If it's the xpanid prefix, we will also advertise the xpanid prefix 632 return false; 633 } 634 635 // If this is a stub router, and we are advertising our own prefix, and the PIO it is advertising is greater than 636 // the one we are advertising, then we keep advertising ours. 637 if (interface->our_prefix_advertised && router->stub_router && cmp > 0) { 638 INFO("Router " PRI_SEGMENTED_IPv6_ADDR_SRP 639 " is a stub router advertising prefix " PRI_SEGMENTED_IPv6_ADDR_SRP ", which loses the election and is not usable", 640 SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, router_src_addr_buf), 641 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix->prefix.s6_addr, prefix_addr_buf)); 642 return false; 643 } 644 INFO("Router " PRI_SEGMENTED_IPv6_ADDR_SRP 645 " is " PUB_S_SRP "advertising prefix " PRI_SEGMENTED_IPv6_ADDR_SRP ", which is usable", 646 SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, router_src_addr_buf), 647 router->stub_router ? "a stub router " : "", 648 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix->prefix.s6_addr, prefix_addr_buf)); 649 return true; 650 } 651 652 static void 653 routing_policy_evaluate(interface_t *interface, bool assume_changed) 654 { 655 icmp_message_t *router; 656 bool new_prefix = false; // new prefix means that srp-mdns-proxy received a new prefix from the wire, which it 657 // did not know before. 658 bool on_link_prefix_present = false; 659 bool something_changed = assume_changed; 660 uint64_t now = ioloop_timenow(); 661 bool stale_routers_exist = false; 662 uint64_t stale_refresh_time = 0; 663 route_state_t *route_state = interface->route_state; 664 665 // No action on interfaces that aren't eligible for routing or that isn't currently active. 666 if (interface->ineligible || interface->inactive) { 667 INFO("not evaluating policy on " PUB_S_SRP " because it's " PUB_S_SRP, interface->name, 668 interface->ineligible ? "ineligible" : "inactive"); 669 return; 670 } 671 672 // We can't tell whether any particular prefix is usable until we've gotten the xpanid. 673 if (route_state->have_xpanid_prefix) { 674 // Look at all the router advertisements we've seen to see if any contain a usable prefix which is not the 675 // prefix we'd advertise. Routers advertising that prefix are all Thread BRs, and it's fine for more than 676 // one router to advertise a prefix, so we will also advertise it for redundancy. 677 for (router = interface->routers; router; router = router->next) { 678 icmp_option_t *option = router->options; 679 int i; 680 bool usable = false; 681 for (i = 0; i < router->num_options; i++, option++) { 682 if (option->type == icmp_option_prefix_information) { 683 prefix_information_t *prefix = &option->option.prefix_information; 684 #ifndef RA_TESTER 685 omr_publisher_check_prefix(route_state->omr_publisher, &prefix->prefix, prefix->length); 686 #endif 687 if (prefix_usable(interface, route_state, router, prefix)) { 688 // We don't consider the prefix we would advertise to be infrastructure-provided if we see it 689 // advertised by another router, because that router is also a Thread BR, and we don't want 690 // to get into dueling prefixes with it. 691 if (in6prefix_compare(&option->option.prefix_information.prefix, &route_state->xpanid_prefix, 8)) 692 { 693 uint32_t preferred_lifetime_offset = MAX_ROUTER_RECEIVED_TIME_GAP_BEFORE_STALE / MSEC_PER_SEC; 694 uint32_t preferred_lifetime = prefix->preferred_lifetime; 695 696 // Infinite preferred lifetime. Bogus. 697 if (preferred_lifetime == UINT32_MAX) { 698 preferred_lifetime = 60 * 60; // One hour 699 } 700 701 // If the remaining time on this prefix is less than the stale time gap, use an offset that's the 702 // valid lifetime minus sixty seconds so that we have time if the prefix expires. 703 if (preferred_lifetime < preferred_lifetime_offset + 60) { 704 // If the preferred lifetime is less than a minute, we're not going to count this as a valid 705 // on-link prefix. 706 if (preferred_lifetime < 60) { 707 SEGMENTED_IPv6_ADDR_GEN_SRP(router->source.s6_addr, router_src_addr_buf); 708 SEGMENTED_IPv6_ADDR_GEN_SRP(option->option.prefix_information.prefix.s6_addr, pref_buf); 709 INFO("router " PRI_SEGMENTED_IPv6_ADDR_SRP " advertising " PRI_SEGMENTED_IPv6_ADDR_SRP 710 " has a preferred lifetime of %d, which is not enough to count as usable.", 711 SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, router_src_addr_buf), 712 SEGMENTED_IPv6_ADDR_PARAM_SRP(option->option.prefix_information.prefix.s6_addr, pref_buf), 713 preferred_lifetime); 714 continue; 715 } 716 preferred_lifetime_offset = preferred_lifetime - 60; 717 } 718 719 // Lifetimes are in seconds, but henceforth we will compare with clock times, which are in ms. 720 preferred_lifetime_offset *= MSEC_PER_SEC; 721 722 // If the prefix' preferred lifetime plus the time received is in the past, the prefix doesn't 723 // count as an on-link prefix that's present. 724 if (router->received_time + preferred_lifetime_offset < now) { 725 SEGMENTED_IPv6_ADDR_GEN_SRP(router->source.s6_addr, router_src_addr_buf); 726 SEGMENTED_IPv6_ADDR_GEN_SRP(option->option.prefix_information.prefix.s6_addr, pref_buf); 727 INFO("router " PRI_SEGMENTED_IPv6_ADDR_SRP " advertising " PRI_SEGMENTED_IPv6_ADDR_SRP 728 " was received %d seconds ago with a preferred lifetime of %d.", 729 SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, router_src_addr_buf), 730 SEGMENTED_IPv6_ADDR_PARAM_SRP(option->option.prefix_information.prefix.s6_addr, pref_buf), 731 (int)((now - router->received_time) / 1000), preferred_lifetime); 732 733 continue; 734 } 735 736 // This prefix is in principle usable. It may not actually be usable if it is stale, but we mark it usable so it 737 // will continue to be probed. 738 usable = true; 739 740 // router->reachable will be true immediately after receiving a router advertisement until we do a 741 // probe and don't get a response. It will become true again if, during a later probe, we get a 742 // response. 743 if (!router->reachable) { 744 SEGMENTED_IPv6_ADDR_GEN_SRP(router->source.s6_addr, router_src_addr_buf); 745 SEGMENTED_IPv6_ADDR_GEN_SRP(option->option.prefix_information.prefix.s6_addr, pref_buf); 746 INFO("router %p " PRI_SEGMENTED_IPv6_ADDR_SRP " advertising %d %p " PRI_SEGMENTED_IPv6_ADDR_SRP 747 " was last known to be reachable %d seconds ago.", 748 router, 749 SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, router_src_addr_buf), 750 i, option, 751 SEGMENTED_IPv6_ADDR_PARAM_SRP(option->option.prefix_information.prefix.s6_addr, pref_buf), 752 (int)((now - router->latest_na) / 1000)); 753 continue; 754 } 755 756 // Otherwise, if this router's on-link prefix will expire later than any other we've seen 757 if (stale_refresh_time < router->received_time + preferred_lifetime_offset) { 758 stale_refresh_time = router->received_time + preferred_lifetime_offset; 759 } 760 761 // If this is a new icmp_message received now and contains PIO. 762 if (router->new_router) { 763 new_prefix = true; 764 router->new_router = false; // clear the bit since srp-mdns-proxy already processed it. 765 } 766 767 // This router has a usable prefix. 768 usable = true; 769 770 // Right now all we need is to see if there is an on-link prefix. 771 on_link_prefix_present = true; 772 SEGMENTED_IPv6_ADDR_GEN_SRP(router->source.s6_addr, __router_src_add_buf); 773 SEGMENTED_IPv6_ADDR_GEN_SRP(prefix->prefix.s6_addr, __pio_prefix_buf); 774 INFO("router has usable PIO - ifname: " PUB_S_SRP ", router src: " PRI_SEGMENTED_IPv6_ADDR_SRP 775 ", prefix: " PRI_SEGMENTED_IPv6_ADDR_SRP, 776 interface->name, 777 SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, __router_src_add_buf), 778 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix->prefix.s6_addr, __pio_prefix_buf)); 779 } else { 780 SEGMENTED_IPv6_ADDR_GEN_SRP(router->source.s6_addr, router_src_addr_buf); 781 INFO("Router " PRI_SEGMENTED_IPv6_ADDR_SRP 782 " is advertising the xpanid prefix: not counting as usable ", 783 SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, router_src_addr_buf)); 784 } 785 } else { 786 SEGMENTED_IPv6_ADDR_GEN_SRP(router->source.s6_addr, __router_src_add_buf); 787 SEGMENTED_IPv6_ADDR_GEN_SRP(prefix->prefix.s6_addr, __pio_prefix_buf); 788 INFO("router has unusable PIO - ifname: " PUB_S_SRP ", router src: " PRI_SEGMENTED_IPv6_ADDR_SRP 789 ", prefix: " PRI_SEGMENTED_IPv6_ADDR_SRP, 790 interface->name, 791 SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, __router_src_add_buf), 792 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix->prefix.s6_addr, __pio_prefix_buf)); 793 } 794 } 795 } 796 // Remember whether or not this router has a usable prefix. 797 router->usable = usable; 798 } 799 } 800 801 INFO("policy on " PUB_S_SRP ": " PUB_S_SRP "stale " /* stale_routers_exist ? */ 802 PUB_S_SRP "started " /* interface->router_discovery_started ? */ 803 PUB_S_SRP "disco " /* interface->router_discovery_complete ? */ 804 PUB_S_SRP "present " /* on_link_prefix_present ? */ 805 PUB_S_SRP "advert " /* interface->our_prefix_advertised ? */ 806 PUB_S_SRP "conf " /* interface->on_link_prefix_configured ? */ 807 PUB_S_SRP "new_prefix " /* new_prefix ? */ 808 "preferred = %" PRIu32 " valid = %" PRIu32 " deadline = %" PRIu64, 809 interface->name, stale_routers_exist ? "" : "!", interface->router_discovery_started ? "" : "!", 810 interface->router_discovery_complete ? "" : "!", 811 on_link_prefix_present ? "" : "!", interface->our_prefix_advertised ? "" : "!", 812 interface->on_link_prefix_configured ? "" : "!", new_prefix ? "" : "!", 813 interface->preferred_lifetime, interface->valid_lifetime, interface->deprecate_deadline); 814 815 // If there are stale routers, start doing router discovery again to see if we can get them to respond. 816 // Note that doing router discover just because we haven't seen an RA is actually not allowed in RFC 4861, 817 // so this shouldn't be enabled. 818 // Also, if we have not yet done router discovery, do it now. 819 if ((!interface->router_discovery_started || !interface->router_discovery_complete 820 #if SRP_FEATURE_STALE_ROUTER_DISCOVERY 821 || stale_routers_exist 822 #endif //SRP_FEATURE_STALE_ROUTER_DISCOVERY 823 ) && !on_link_prefix_present) { 824 if (!interface->router_discovery_in_progress) { 825 // Start router discovery. 826 INFO("starting router discovery"); 827 router_discovery_start(interface); 828 } else { 829 INFO("router discovery in progress"); 830 } 831 } 832 // If we are advertising a prefix and there's another on-link prefix, deprecate the one we are 833 // advertising. 834 else if (interface->our_prefix_advertised && on_link_prefix_present) { 835 // If we have been advertising a preferred prefix, deprecate it. 836 SEGMENTED_IPv6_ADDR_GEN_SRP(interface->ipv6_prefix.s6_addr, __prefix_buf); 837 if (interface->preferred_lifetime == BR_PREFIX_LIFETIME) { 838 INFO("routing_policy_evaluate: deprecating interface prefix in 30 minutes - prefix: " PRI_SEGMENTED_IPv6_ADDR_SRP, 839 SEGMENTED_IPv6_ADDR_PARAM_SRP(interface->ipv6_prefix.s6_addr, __prefix_buf)); 840 interface->deprecate_deadline = now + BR_PREFIX_LIFETIME * 1000; 841 something_changed = true; 842 interface->preferred_lifetime = 0; 843 } else { 844 INFO("prefix deprecating in progress - prefix: " PRI_SEGMENTED_IPv6_ADDR_SRP, 845 SEGMENTED_IPv6_ADDR_PARAM_SRP(interface->ipv6_prefix.s6_addr, __prefix_buf)); 846 } 847 } 848 // If there is no on-link prefix and we aren't advertising, or have deprecated, start advertising 849 // again (or for the first time). 850 else if (!on_link_prefix_present && interface->router_discovery_complete && route_state->have_xpanid_prefix && 851 (!interface->our_prefix_advertised || interface->deprecate_deadline != 0 || 852 interface->preferred_lifetime == 0)) { 853 854 SEGMENTED_IPv6_ADDR_GEN_SRP(interface->ipv6_prefix.s6_addr, __prefix_buf); 855 INFO("advertising prefix again - ifname: " PUB_S_SRP 856 ", prefix: " PRI_SEGMENTED_IPv6_ADDR_SRP, interface->name, 857 SEGMENTED_IPv6_ADDR_PARAM_SRP(interface->ipv6_prefix.s6_addr, __prefix_buf)); 858 859 // If we were deprecating, stop. 860 ioloop_cancel_wake_event(interface->deconfigure_wakeup); 861 interface->deprecate_deadline = 0; 862 863 // Start advertising immediately, 30 minutes. 864 interface->preferred_lifetime = interface->valid_lifetime = BR_PREFIX_LIFETIME; 865 866 // If the on-link prefix isn't configured on the interface, do that. 867 if (!interface->on_link_prefix_configured) { 868 #ifndef RA_TESTER 869 if (!interface->is_thread) { 870 #endif 871 interface_prefix_configure(interface->ipv6_prefix, interface); 872 #ifndef RA_TESTER 873 } else { 874 INFO("Not setting up " PUB_S_SRP " because it is the thread interface", interface->name); 875 } 876 #endif 877 } else { 878 // Configuring the on-link prefix takes a while, so we want to re-evaluate after it's finished. 879 interface->our_prefix_advertised = true; 880 something_changed = true; 881 } 882 } 883 // If there is no on-link prefix present, and srp-mdns-proxy itself is advertising the prefix, and it has configured 884 // an on-link prefix, and the interface is not thread interface, and it just got an interface address removal event, 885 // it is possible that the IPv6 routing has been flushed due to loss of address in configd, so here we explicitly 886 // reconfigure the IPv6 prefix and the routing. 887 else if (interface->need_reconfigure_prefix && !on_link_prefix_present && interface->our_prefix_advertised && 888 interface->on_link_prefix_configured && !interface->is_thread) { 889 SEGMENTED_IPv6_ADDR_GEN_SRP(interface->ipv6_prefix.s6_addr, __prefix_buf); 890 INFO("reconfigure ipv6 prefix due to possible network changes -" 891 " prefix: " PRI_SEGMENTED_IPv6_ADDR_SRP, 892 SEGMENTED_IPv6_ADDR_PARAM_SRP(interface->ipv6_prefix.s6_addr, __prefix_buf)); 893 interface_prefix_configure(interface->ipv6_prefix, interface); 894 interface->need_reconfigure_prefix = false; 895 } 896 897 // If the on-link prefix goes away, stop suppressing the one we've been advertising (if it's still valid). 898 if (!on_link_prefix_present && interface->suppress_ipv6_prefix) { 899 INFO("un-suppressing ipv6 prefix."); 900 interface->suppress_ipv6_prefix = false; 901 } 902 903 // If we've been looking to see if there's an on-link prefix, and we got one from the new router advertisement, 904 // stop looking for new one. 905 if (new_prefix) { 906 router_discovery_stop(interface, now); 907 } 908 909 // If anything changed, do an immediate beacon; otherwise wait until the next one. 910 // Also when something changed, set the number of transmissions back to zero so that 911 // we send a few initial beacons quickly for reliability. 912 if (something_changed) { 913 INFO("change on " PUB_S_SRP ": " PUB_S_SRP "started " PUB_S_SRP "disco " PUB_S_SRP "present " PUB_S_SRP "advert " PUB_S_SRP 914 "conf preferred = %" PRIu32 " valid = %" PRIu32 " deadline = %" PRIu64, 915 interface->name, interface->router_discovery_started ? "" : "!", 916 interface->router_discovery_complete ? "" : "!", on_link_prefix_present ? "" : "!", 917 interface->our_prefix_advertised ? "" : "!", interface->on_link_prefix_configured ? "" : "!", 918 interface->preferred_lifetime, 919 interface->valid_lifetime, interface->deprecate_deadline); 920 interface->num_beacons_sent = 0; 921 interface_beacon_schedule(interface, 0); 922 } 923 924 // It's possible for us to start configuring the interface because there's no on-link prefix, and then see 925 // an advertisement for an on-link prefix before interface configuration completes. When this happens, we 926 // need to delete the address we just configured, because we're not going to be advertising it. We always 927 // get a policy re-evaluation event when interface configuration completes, so this will happen immediately. 928 // At this point we have not yet sent a router advertisement with the prefix, so even though it has a preferred 929 // lifetime of about 1800 seconds here, we can safely set it to zero without leaving stale information 930 // in any host's routing table. 931 if (!interface->our_prefix_advertised && interface->on_link_prefix_configured) { 932 INFO("on-link prefix appeared during interface configuration. removing"); 933 interface->preferred_lifetime = 0; 934 interface_prefix_deconfigure(interface); 935 } 936 937 #ifdef FLUSH_STALE_ROUTERS 938 // If we have an on-link prefix, schedule a policy re-evaluation at the stale router interval. 939 if (on_link_prefix_present) { 940 if (stale_refresh_time < now) { 941 ERROR("Stale refresh time is in the past: %" PRIu64 "!", stale_refresh_time); 942 } else { 943 // The math used to compute refresh timeout guarantees that refresh_timeout will be <10 minutes. 944 int refresh_timeout = (int)(stale_refresh_time - now); 945 946 if (interface->stale_evaluation_wakeup == NULL) { 947 interface->stale_evaluation_wakeup = ioloop_wakeup_create(); 948 if (interface->stale_evaluation_wakeup == NULL) { 949 ERROR("No memory for stale router evaluation wakeup on " PUB_S_SRP ".", interface->name); 950 } 951 } else { 952 ioloop_cancel_wake_event(interface->stale_evaluation_wakeup); 953 } 954 ioloop_add_wake_event(interface->stale_evaluation_wakeup, 955 interface, stale_router_policy_evaluate, NULL, refresh_timeout); 956 } 957 } 958 #endif // FLUSH_STALE_ROUTERS 959 960 // Once router discovery is complete, start doing aliveness checks on whatever we discovered (if anything). 961 if (interface->last_router_probe == 0 && interface->router_discovery_started && interface->router_discovery_complete) { 962 schedule_next_router_probe(interface); 963 } 964 965 #ifndef RA_TESTER 966 if (route_state->route_tracker != NULL) { 967 route_tracker_route_state_changed(route_state->route_tracker, interface); 968 } 969 #endif 970 } 971 972 #if SRP_FEATURE_VICARIOUS_ROUTER_DISCOVERY 973 static void 974 start_vicarious_router_discovery_if_appropriate(interface_t *const interface) 975 { 976 if (!interface->our_prefix_advertised && 977 !interface->vicarious_router_discovery_in_progress && !interface->router_discovery_in_progress) 978 { 979 if (interface->vicarious_discovery_complete == NULL) { 980 interface->vicarious_discovery_complete = ioloop_wakeup_create(); 981 } else { 982 ioloop_cancel_wake_event(interface->vicarious_discovery_complete); 983 } 984 if (interface->vicarious_discovery_complete != NULL) { 985 ioloop_add_wake_event(interface->vicarious_discovery_complete, 986 interface, vicarious_discovery_callback, NULL, 20 * 1000); 987 interface->vicarious_router_discovery_in_progress = true; 988 } 989 // In order for vicarious router discovery to be useful, we need all of the routers 990 // that were present when the first solicit was received to be stale when we give up 991 // on vicarious discovery. If we got any router advertisements, these will not be 992 // stale, and that means vicarious discovery succeeded. 993 make_all_routers_nearly_stale(interface, ioloop_timenow()); 994 INFO("Starting vicarious router discovery on " PUB_S_SRP, 995 interface->name); 996 } 997 } 998 #endif // SRP_FEATURE_VICARIOUS_ROUTER_DISCOVERY 999 1000 static void 1001 retransmit_unicast_beacon(void *context) 1002 { 1003 icmp_message_t *message = context; 1004 1005 // Schedule retranmsission 1006 interface_beacon_send(message->interface, &message->source); 1007 ioloop_add_wake_event(message->wakeup, message, retransmit_unicast_beacon, NULL, 1008 MIN_DELAY_BETWEEN_RAS + srp_random16() % RA_FUZZ_TIME); 1009 1010 // Discontinue retransmission after the third we've sent. 1011 if (message->messages_sent++ > 2) { 1012 icmp_message_t **sp = &message->interface->solicits; 1013 while (*sp != NULL) { 1014 if (*sp == message) { 1015 *sp = message->next; 1016 icmp_message_free(message); 1017 break; 1018 } else { 1019 sp = &(*sp)->next; 1020 } 1021 } 1022 } 1023 } 1024 1025 // This gets called to check to see if any of the usable routers are still responding. It gets called whenever 1026 // we get a router solicit, to ensure that the solicit gets a quick response, and also gets called once every 1027 // minute so that we quickly notice when a router becomes unreachable. 1028 1029 static void 1030 send_router_probes(void *context) 1031 { 1032 interface_t *interface = context; 1033 1034 // After sending three probes, do a policy evaluation. 1035 if (interface->num_solicits_sent++ > MAX_NS_RETRANSMISSIONS - 1) { 1036 // Mark routers from which we received neighbor advertises during the probe as reachable. Routers 1037 // that did not respond are no longer reachable. 1038 for (icmp_message_t *router = interface->routers; router != NULL; router = router->next) { 1039 SEGMENTED_IPv6_ADDR_GEN_SRP(router->source.s6_addr, router_src_addr_buf); 1040 INFO("router (%p) " PRI_SEGMENTED_IPv6_ADDR_SRP " was " PUB_S_SRP "reached during probing.", router, 1041 SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, router_src_addr_buf), 1042 router->reached ? "" : "not "); 1043 router->reachable = router->reached; 1044 } 1045 routing_policy_evaluate(interface, false); 1046 schedule_next_router_probe(interface); 1047 return; 1048 } 1049 1050 // Send Neighbor Solicits to any usable routers that haven't responded yet and schedule the next call to 1051 // send_router_probes... 1052 for (icmp_message_t *router = interface->routers; router != NULL; router = router->next) { 1053 // Don't probe routers that aren't usable, and don't re-probe a router that's already responded in this probe cycle. 1054 if (!router->usable || router->reached) { 1055 continue; 1056 } 1057 neighbor_solicit_send(router->interface, &router->source); 1058 } 1059 ioloop_add_wake_event(interface->neighbor_solicit_wakeup, interface, send_router_probes, NULL, 1060 MIN_DELAY_BETWEEN_RAS + srp_random16() % RA_FUZZ_TIME); 1061 } 1062 1063 static void 1064 check_router_aliveness(void *context) 1065 { 1066 interface_t *interface = context; 1067 1068 if (!interface->probing) { 1069 interface->probing = true; 1070 if (interface->neighbor_solicit_wakeup == NULL) { 1071 interface->neighbor_solicit_wakeup = ioloop_wakeup_create(); 1072 } 1073 if (interface->neighbor_solicit_wakeup != NULL) { 1074 interface->num_solicits_sent = 0; 1075 // Clear the reached flag on all routers 1076 for (icmp_message_t *router = interface->routers; router != NULL; router = router->next) { 1077 router->reached = false; 1078 } 1079 send_router_probes(interface); 1080 } 1081 } 1082 } 1083 1084 static void 1085 schedule_next_router_probe(interface_t *interface) 1086 { 1087 if (interface->router_probe_wakeup == NULL) { 1088 interface->router_probe_wakeup = ioloop_wakeup_create(); 1089 } 1090 if (interface->router_probe_wakeup != NULL) { 1091 INFO("scheduling router probe in 60 seconds."); 1092 ioloop_add_wake_event(interface->router_probe_wakeup, interface, check_router_aliveness, NULL, 60 * 1000); 1093 interface->probing = false; 1094 interface->last_router_probe = ioloop_timenow(); 1095 } 1096 } 1097 1098 void 1099 router_solicit(icmp_message_t *message) 1100 { 1101 interface_t *iface, *interface; 1102 bool is_retransmission = false; 1103 1104 1105 // Further validate the message 1106 if (message->hop_limit != 255 || message->code != 0) { 1107 ERROR("Invalid router solicitation, hop limit = %d, code = %d", message->hop_limit, message->code); 1108 goto out; 1109 } 1110 if (IN6_IS_ADDR_UNSPECIFIED(&message->source)) { 1111 icmp_option_t *option = message->options; 1112 int i; 1113 for (i = 0; i < message->num_options; i++) { 1114 if (option->type == icmp_option_source_link_layer_address) { 1115 ERROR("source link layer address in router solicitation from unspecified IP address"); 1116 goto out; 1117 } 1118 option++; 1119 } 1120 } else { 1121 // Make sure it's not from this host 1122 for (iface = message->route_state->interfaces; iface; iface = iface->next) { 1123 if (iface->have_link_layer_address && !in6addr_compare(&message->source, &iface->link_local)) { 1124 INFO("dropping router solicitation sent from this host."); 1125 goto out; 1126 } 1127 } 1128 } 1129 interface = message->interface; 1130 1131 SEGMENTED_IPv6_ADDR_GEN_SRP(message->source.s6_addr, source_buf); 1132 INFO(PUB_S_SRP " solicit on " PUB_S_SRP ": source address is " PRI_SEGMENTED_IPv6_ADDR_SRP, 1133 is_retransmission ? "retransmitted" : "initial", 1134 message->interface->name, SEGMENTED_IPv6_ADDR_PARAM_SRP(message->source.s6_addr, source_buf)); 1135 1136 // See if this is a retransmission... 1137 icmp_message_t **sp; 1138 sp = &interface->solicits; 1139 while (*sp != NULL) { 1140 icmp_message_t *solicit = *sp; 1141 // Same source? Not already found? 1142 if (!is_retransmission && !in6addr_compare(&message->source, &solicit->source)) { 1143 uint64_t now = ioloop_timenow(); 1144 // RFC 4861 limits RS transmissions to 3, separated by four seconds. Allowing for a bit of slop, 1145 // if it was received in the past 15 seconds, this is a retransmission. 1146 if (now - solicit->received_time > 15 * 1000) { 1147 *sp = solicit->next; 1148 icmp_message_free(solicit); 1149 } else { 1150 solicit->retransmissions_received++; 1151 is_retransmission = true; 1152 1153 // Since this is a retransmission, that hints that there might not be any live routers 1154 // on this link, so check to see if the routers we are aware of are alive. 1155 check_router_aliveness(interface); 1156 1157 sp = &(*sp)->next; 1158 } 1159 } else { 1160 sp = &(*sp)->next; 1161 } 1162 } 1163 1164 // Schedule an immediate send. If this is a retransmission, just let our retransmission schedule 1165 // dictate when to send the next one. 1166 if (!is_retransmission && !interface->ineligible && !interface->inactive) { 1167 message->wakeup = ioloop_wakeup_create(); 1168 if (message->wakeup == NULL) { 1169 ERROR("no memory for solicit wakeup."); 1170 } else { 1171 // Save the message for later 1172 *sp = message; 1173 // Start the unicast RA transmission train for this RS. 1174 retransmit_unicast_beacon(message); 1175 message = NULL; 1176 } 1177 } else { 1178 INFO("not sending a router advertisement."); 1179 } 1180 1181 #if SRP_FEATURE_VICARIOUS_ROUTER_DISCOVERY 1182 // When we receive a router solicit, it means that a host is looking for a router. We should 1183 // expect to hear replies if they are multicast. If we hear no replies, it could mean there is 1184 // no on-link prefix. In this case, we restart our own router discovery process. There is no 1185 // need to do this if we are the one advertising a prefix. 1186 start_vicarious_router_discovery_if_appropriate(interface); 1187 #endif // SRP_FEATURE_VICARIOUS_ROUTER_DISCOVERY 1188 out: 1189 if (message != NULL) { 1190 icmp_message_free(message); 1191 } 1192 } 1193 1194 void 1195 router_advertisement(icmp_message_t *message) 1196 { 1197 interface_t *iface; 1198 icmp_message_t *router, **rp; 1199 if (message->hop_limit != 255 || message->code != 0 || !IN6_IS_ADDR_LINKLOCAL(&message->source)) { 1200 ERROR("Invalid router advertisement, hop limit = %d, code = %d", message->hop_limit, message->code); 1201 icmp_message_free(message); 1202 return; 1203 } 1204 for (iface = message->route_state->interfaces; iface != NULL; iface = iface->next) { 1205 if (iface->have_link_layer_address && !in6addr_compare(&message->source, &iface->link_local)) { 1206 INFO("dropping router advertisement sent from this host."); 1207 icmp_message_free(message); 1208 return; 1209 } 1210 } 1211 1212 // See if we've had a previous advertisement from this router. Note that routers can send more than one 1213 // RA to advertise more data than will fit in one RA, but in practice routers tend not to do this, and how 1214 // this is supposed to work is not clearly specified. From RFC4861: 1215 // 1216 // If including all options causes the size of an advertisement to 1217 // exceed the link MTU, multiple advertisements can be sent, each 1218 // containing a subset of the options. 1219 // 1220 // If this happens, we're going to wind up using the last RA in the sequence. Ideally we'd do some work to marshal 1221 // RA trains. This is too much work to do in a current milestone. The issue is tracked in rdar://105200987 1222 // (Restructure handling of incoming router advertisements so as to marshal the data in case we get more than one RA 1223 // from the same router with different data.) 1224 for (rp = &message->interface->routers; *rp != NULL; rp = &(*rp)->next) { 1225 router = *rp; 1226 // The new RA is from the same router as this previous RA. 1227 if (!in6addr_compare(&router->source, &message->source)) { 1228 message->next = router->next; 1229 *rp = message; 1230 icmp_message_free(router); 1231 break; 1232 } 1233 } 1234 // If we got rid of the old RA, *rp will be non-NULL. If we didn't find a match for the old RA, or if we 1235 // need to keep the old RA, then *rp will be NULL, meaning that we should keep the new RA. 1236 if (*rp == NULL) { 1237 *rp = message; 1238 } 1239 1240 // When we receive an RA, we can assume that the router is reachable, and skip immediately probing with a 1241 // neighbor solicit. 1242 message->latest_na = message->received_time; 1243 message->reachable = true; 1244 message->reached = true; 1245 1246 // Check for the stub router flag here so that we have it when scanning PIOs for usability. 1247 for (int i = 0; i < message->num_options; i++) { 1248 icmp_option_t *option = &message->options[i]; 1249 if (option->type == icmp_option_ra_flags_extension) { 1250 if (option->option.ra_flags_extension[0] & RA_FLAGS1_STUB_ROUTER) { 1251 message->stub_router = true; 1252 } 1253 } 1254 } 1255 // Something may have changed, so do a policy recalculation for this interface 1256 routing_policy_evaluate(message->interface, false); 1257 } 1258 1259 void 1260 neighbor_advertisement(icmp_message_t *message) 1261 { 1262 if (message->hop_limit != 255 || message->code != 0) { 1263 ERROR("Invalid neighbor advertisement, hop limit = %d, code = %d", message->hop_limit, message->code); 1264 return; 1265 } 1266 1267 // If this NA matches a router that has advertised a usable prefix, mark the router as alive by setting the 1268 // "latest_na" value to the current time. We don't care about NAs for routers that are not advertising a usable 1269 // prefix. 1270 for (icmp_message_t *router = message->interface->routers; router != NULL; router = router->next) { 1271 if (!in6addr_compare(&message->source, &router->source)) { 1272 // Only log for usable routers, to avoid a lot of extra noise. However, we don't actually probe routers that 1273 // aren't usable, so generally speaking this test will always be true. 1274 if (router->usable) { 1275 SEGMENTED_IPv6_ADDR_GEN_SRP(message->source.s6_addr, source_buf); 1276 INFO("usable neighbor advertisement recieved on " PUB_S_SRP " from " PRI_SEGMENTED_IPv6_ADDR_SRP, 1277 message->interface->name, SEGMENTED_IPv6_ADDR_PARAM_SRP(message->source.s6_addr, source_buf)); 1278 } 1279 router->latest_na = ioloop_timenow(); 1280 router->reached = true; 1281 router->reachable = true; 1282 } 1283 } 1284 return; 1285 } 1286 1287 #if defined(CONFIGURE_STATIC_INTERFACE_ADDRESSES_WITH_IPCONFIG) || \ 1288 defined(CONFIGURE_STATIC_INTERFACE_ADDRESSES_WITH_IFCONFIG) 1289 static void 1290 link_route_done(void *context, int status, const char *error) 1291 { 1292 interface_t *interface = context; 1293 1294 if (error != NULL) { 1295 ERROR("link_route_done on " PUB_S_SRP ": " PUB_S_SRP, interface->name, error); 1296 } else { 1297 INFO("link_route_done on " PUB_S_SRP ": %d.", interface->name, status); 1298 } 1299 ioloop_subproc_release(interface->link_route_adder_process); 1300 interface->link_route_adder_process = NULL; 1301 // Now that the on-link prefix is configured, time for a policy re-evaluation. 1302 interface->on_link_prefix_configured = true; 1303 routing_policy_evaluate(interface, true); 1304 } 1305 #endif 1306 1307 static void 1308 interface_prefix_configure(struct in6_addr prefix, interface_t *interface) 1309 { 1310 int sock; 1311 route_state_t *route_state = interface->route_state; 1312 1313 sock = socket(PF_INET6, SOCK_DGRAM, 0); 1314 if (sock < 0) { 1315 ERROR("interface_prefix_configure: socket(PF_INET6, SOCK_DGRAM, 0) failed " PUB_S_SRP ": " PUB_S_SRP, 1316 interface->name, strerror(errno)); 1317 return; 1318 } 1319 #ifdef CONFIGURE_STATIC_INTERFACE_ADDRESSES 1320 struct in6_addr interface_address = prefix; 1321 char addrbuf[INET6_ADDRSTRLEN + 4]; 1322 // Use our ULA prefix as the host identifier. 1323 memcpy(&interface_address.s6_addr[10], &route_state->srp_server->ula_prefix.s6_addr[0], 6); 1324 interface_address.s6_addr[8] = (interface->index >> 8) & 255; 1325 interface_address.s6_addr[9] = interface->index & 255; 1326 inet_ntop(AF_INET6, &interface_address, addrbuf, INET6_ADDRSTRLEN); 1327 #if defined(CONFIGURE_STATIC_INTERFACE_ADDRESSES_WITH_IPCONFIG) 1328 char *args[] = { "set", interface->name, "MANUAL-V6", addrbuf, "64" }; 1329 1330 if (interface->link_route_adder_process != NULL) { 1331 ERROR("interface_prefix_configure: " PUB_S_SRP " already configuring the route.", interface->name); 1332 return; 1333 } 1334 INFO("/sbin/ipconfig " PUB_S_SRP " " PUB_S_SRP " " PUB_S_SRP " " PUB_S_SRP " " 1335 PUB_S_SRP, args[0], args[1], args[2], args[3], args[4]); 1336 interface->link_route_adder_process = ioloop_subproc("/usr/sbin/ipconfig", args, 5, link_route_done, interface, NULL); 1337 if (interface->link_route_adder_process == NULL) { 1338 ERROR("interface_prefix_configure: unable to set interface address for %s to %s.", interface->name, addrbuf); 1339 } 1340 #elif defined(CONFIGURE_STATIC_INTERFACE_ADDRESSES_WITH_IFCONFIG) 1341 char *eos = addrbuf + strlen(addrbuf); 1342 if (sizeof(addrbuf) - (eos - addrbuf) < 4) { 1343 ERROR("interface_prefix_configure: this shouldn't happen: no space in addrbuf"); 1344 return; 1345 } 1346 strcpy(eos, "/64"); 1347 char *args[] = { interface->name, "add", addrbuf }; 1348 1349 if (interface->link_route_adder_process != NULL) { 1350 ERROR("interface_prefix_configure: " PUB_S_SRP " already configuring the route.", interface->name); 1351 return; 1352 } 1353 INFO("/sbin/ifconfig %s %s %s", args[0], args[1], args[2]); 1354 interface->link_route_adder_process = ioloop_subproc("/sbin/ifconfig", args, 3, link_route_done, NULL, interface); 1355 if (interface->link_route_adder_process == NULL) { 1356 SEGMENTED_IPv6_ADDR_GEN_SRP(interface_address.s6_addr, if_addr_buf); 1357 ERROR("interface_prefix_configure: unable to set interface address for " PUB_S_SRP " to " 1358 PRI_SEGMENTED_IPv6_ADDR_SRP ".", interface->name, 1359 SEGMENTED_IPv6_ADDR_PARAM_SRP(interface_address.s6_addr, if_addr_buf)); 1360 } 1361 #else 1362 struct in6_aliasreq alias_request; 1363 int ret; 1364 1365 memset(&alias_request, 0, sizeof(alias_request)); 1366 strlcpy(alias_request.ifra_name, interface->name, IFNAMSIZ); 1367 alias_request.ifra_addr.sin6_family = AF_INET6; 1368 alias_request.ifra_addr.sin6_len = sizeof(alias_request.ifra_addr); 1369 memcpy(&alias_request.ifra_addr.sin6_addr, &interface_address, sizeof(alias_request.ifra_addr.sin6_addr)); 1370 alias_request.ifra_prefixmask.sin6_len = sizeof(alias_request.ifra_addr); 1371 alias_request.ifra_prefixmask.sin6_family = AF_INET6; 1372 memset(&alias_request.ifra_prefixmask.sin6_addr, 0xff, 8); // /64. 1373 alias_request.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; // seconds, I hope? 1374 alias_request.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; // seconds, I hope? 1375 1376 ret = ioctl(sock, SIOCAIFADDR_IN6, &alias_request); 1377 if (ret < 0) { 1378 SEGMENTED_IPv6_ADDR_GEN_SRP(interface_address.s6_addr, if_addr_buf); 1379 ERROR("interface_prefix_configure: can't configure static address " PRI_SEGMENTED_IPv6_ADDR_SRP " on " PUB_S_SRP 1380 ": " PUB_S_SRP, SEGMENTED_IPv6_ADDR_PARAM_SRP(interface_address.s6_addr, if_addr_buf), interface->name, 1381 strerror(errno)); 1382 } else { 1383 SEGMENTED_IPv6_ADDR_GEN_SRP(interface_address.s6_addr, if_addr_buf); 1384 INFO("added address " PRI_SEGMENTED_IPv6_ADDR_SRP " to " PUB_S_SRP, 1385 SEGMENTED_IPv6_ADDR_PARAM_SRP(interface_address.s6_addr, if_addr_buf), interface->name); 1386 } 1387 #endif // CONFIGURE_STATIC_INTERFACE_ADDRESSES_WITH_IPCONFIG 1388 #else 1389 (void)prefix; 1390 #endif // CONFIGURE_STATIC_INTERFACE_ADDRESSES 1391 close(sock); 1392 } 1393 1394 #ifndef RA_TESTER 1395 static void 1396 set_thread_forwarding(void) 1397 { 1398 #ifdef LINUX 1399 const char *procfile = "/proc/sys/net/ipv6/conf/all/forwarding"; 1400 int fd = open(procfile, O_WRONLY); 1401 if (fd < 0) { 1402 ERROR("%s: %s", procfile, strerror(errno)); 1403 } else { 1404 ssize_t ret = write(fd, "1", 1); 1405 if (ret < 0) { 1406 ERROR("write: %s", strerror(errno)); 1407 } else if (ret != 1) { 1408 ERROR("invalid write: %zd", ret); 1409 } 1410 close(fd); 1411 } 1412 #else 1413 int wun = 1; 1414 int ret = sysctlbyname("net.inet6.ip6.forwarding", NULL, 0, &wun, sizeof(wun)); 1415 if (ret < 0) { 1416 ERROR(PUB_S_SRP, strerror(errno)); 1417 } else { 1418 INFO("Enabled IPv6 forwarding."); 1419 } 1420 #endif 1421 } 1422 #endif // RA_TESTER 1423 1424 #ifdef NEED_THREAD_RTI_SETTER 1425 static void 1426 thread_rti_done(void *UNUSED context, int status, const char *error) 1427 { 1428 route_state_t *route_state = context; 1429 1430 if (error != NULL) { 1431 ERROR("thread_rti_done: " PUB_S_SRP, error); 1432 } else { 1433 INFO("%d.", status); 1434 } 1435 ioloop_subproc_release(route_state->thread_rti_setter_process); 1436 route_state->thread_rti_setter_process = NULL; 1437 } 1438 1439 static void 1440 set_thread_rti(route_state_t *route_state) 1441 { 1442 char *args[] = { "-w", "net.inet6.icmp6.nd6_process_rti=1" }; 1443 route_state->thread_rti_setter_process = ioloop_subproc("/usr/sbin/sysctl", args, 2, thread_rti_done, 1444 NULL, route_state); 1445 if (route_state->thread_rti_setter_process == NULL) { 1446 ERROR("Unable to set thread rti enabled."); 1447 } 1448 } 1449 #endif 1450 1451 #if defined(THREAD_BORDER_ROUTER) && !defined(RA_TESTER) 1452 #ifdef ADD_PREFIX_WITH_WPANCTL 1453 static void 1454 thread_prefix_done(void *context, int status, const char *error) 1455 { 1456 route_state_t *route_state = context; 1457 1458 if (error != NULL) { 1459 ERROR("thread_prefix_done: " PUB_S_SRP, error); 1460 } else { 1461 interface_t *interface; 1462 1463 INFO("%d.", status); 1464 for (interface = route_state->interfaces; interface; interface = interface->next) { 1465 if (!interface->inactive) { 1466 interface_beacon_schedule(interface, 0); 1467 } 1468 } 1469 } 1470 ioloop_subproc_release(route_state->thread_prefix_adder_process); 1471 route_state->thread_prefix_adder_process = NULL; 1472 } 1473 #endif 1474 #endif // THREAD_BORDER_ROUTRER && !RA_TESTER 1475 1476 static void 1477 post_solicit_policy_evaluate(void *context) 1478 { 1479 interface_t *interface = context; 1480 INFO("Done waiting for router discovery to finish on " PUB_S_SRP, interface->name); 1481 interface->router_discovery_complete = true; 1482 interface->router_discovery_in_progress = false; 1483 #ifdef FLUSH_STALE_ROUTERS 1484 flush_routers(interface, ioloop_timenow()); 1485 #endif // FLUSH_STALE_ROUTERS 1486 1487 // See if we need a new prefix on the interface. 1488 interface_prefix_evaluate(interface); 1489 1490 routing_policy_evaluate(interface, true); 1491 // Always clear out need_reconfigure_prefix when router_discovery_complete is set to true. 1492 interface->need_reconfigure_prefix = false; 1493 } 1494 1495 static void 1496 ula_record(const char *ula_printable) 1497 { 1498 size_t len = strlen(ula_printable); 1499 if (access(THREAD_DATA_DIR, F_OK) < 0) { 1500 if (mkdir(THREAD_DATA_DIR, 0700) < 0) { 1501 ERROR("ula_record: " THREAD_DATA_DIR " not present and can't be created: %s", strerror(errno)); 1502 return; 1503 } 1504 } 1505 srp_store_file_data(NULL, THREAD_ULA_FILE, (uint8_t *)ula_printable, len); 1506 } 1507 1508 void 1509 route_ula_generate(route_state_t *route_state) 1510 { 1511 char ula_prefix_buffer[INET6_ADDRSTRLEN]; 1512 struct in6_addr ula_prefix, old_ula_prefix; 1513 bool prefix_changed; 1514 1515 // Already have a prefix? 1516 if (route_state->srp_server->ula_prefix.s6_addr[0] == 0xfd) { 1517 old_ula_prefix = route_state->srp_server->ula_prefix; 1518 prefix_changed = true; 1519 } else { 1520 prefix_changed = false; 1521 } 1522 1523 in6addr_zero(&ula_prefix); 1524 srp_randombytes(&ula_prefix.s6_addr[1], 5); 1525 ula_prefix.s6_addr[0] = 0xfd; 1526 1527 inet_ntop(AF_INET6, &ula_prefix, ula_prefix_buffer, sizeof ula_prefix_buffer); 1528 1529 ula_record(ula_prefix_buffer); 1530 if (prefix_changed) { 1531 SEGMENTED_IPv6_ADDR_GEN_SRP(old_ula_prefix.s6_addr, old_prefix_buf); 1532 SEGMENTED_IPv6_ADDR_GEN_SRP(ula_prefix.s6_addr, new_prefix_buf); 1533 INFO("ula-generate: prefix changed from " PRI_SEGMENTED_IPv6_ADDR_SRP " to " PRI_SEGMENTED_IPv6_ADDR_SRP, 1534 SEGMENTED_IPv6_ADDR_PARAM_SRP(old_ula_prefix.s6_addr, old_prefix_buf), 1535 SEGMENTED_IPv6_ADDR_PARAM_SRP(ula_prefix.s6_addr, new_prefix_buf)); 1536 } else { 1537 SEGMENTED_IPv6_ADDR_GEN_SRP(ula_prefix.s6_addr, new_prefix_buf); 1538 INFO("ula-generate: generated ULA prefix " PRI_SEGMENTED_IPv6_ADDR_SRP, 1539 SEGMENTED_IPv6_ADDR_PARAM_SRP(ula_prefix.s6_addr, new_prefix_buf)); 1540 } 1541 1542 // Set up the thread prefix. 1543 route_state->my_thread_ula_prefix = ula_prefix; 1544 route_state->srp_server->ula_prefix = ula_prefix; 1545 route_state->have_thread_prefix = true; 1546 #if SRP_FEATURE_NAT64 1547 if (route_state->srp_server->srp_nat64_enabled) { 1548 nat64_set_ula_prefix(&ula_prefix); 1549 } 1550 #endif 1551 } 1552 1553 void 1554 route_ula_setup(route_state_t *route_state) 1555 { 1556 bool have_stored_ula_prefix = false; 1557 1558 char ula_buf[INET6_ADDRSTRLEN]; 1559 uint16_t length; 1560 if (srp_load_file_data(NULL, THREAD_ULA_FILE, (uint8_t *)ula_buf, &length, sizeof(ula_buf) - 1)) { 1561 ula_buf[length] = 0; 1562 if (inet_pton(AF_INET6, ula_buf, &route_state->srp_server->ula_prefix)) { 1563 have_stored_ula_prefix = true; 1564 } else { 1565 INFO("ula prefix %.*s is not valid", length, ula_buf); 1566 } 1567 } else { 1568 INFO("Couldn't open ULA file " THREAD_ULA_FILE "."); 1569 } 1570 1571 // If we didn't already successfully fetch a stored prefix, try to store one. 1572 if (!have_stored_ula_prefix) { 1573 route_ula_generate(route_state); 1574 } else { 1575 // Set up the thread prefix. 1576 route_state->my_thread_ula_prefix = route_state->srp_server->ula_prefix; 1577 route_state->have_thread_prefix = true; 1578 #if SRP_FEATURE_NAT64 1579 if (route_state->srp_server->srp_nat64_enabled) { 1580 nat64_set_ula_prefix(&route_state->srp_server->ula_prefix); 1581 } 1582 #endif 1583 } 1584 } 1585 1586 static void 1587 router_solicit_callback(void *context) 1588 { 1589 interface_t *interface = context; 1590 if (interface->is_thread) { 1591 INFO("discontinuing router solicitations on thread interface " PUB_S_SRP, interface->name); 1592 return; 1593 } 1594 if (interface->num_solicits_sent >= 3) { 1595 INFO("Done sending router solicitations on " PUB_S_SRP ".", interface->name); 1596 return; 1597 } 1598 INFO("sending router solicitation on " PUB_S_SRP , interface->name); 1599 router_solicit_send(interface); 1600 1601 interface->num_solicits_sent++; 1602 ioloop_add_wake_event(interface->router_solicit_wakeup, 1603 interface, router_solicit_callback, NULL, 1604 RTR_SOLICITATION_INTERVAL * 1000 + srp_random16() % 1024); 1605 } 1606 1607 static void 1608 start_router_solicit(interface_t *interface) 1609 { 1610 if (interface->router_solicit_wakeup == NULL) { 1611 interface->router_solicit_wakeup = ioloop_wakeup_create(); 1612 if (interface->router_solicit_wakeup == 0) { 1613 ERROR("No memory for router solicit wakeup on " PUB_S_SRP ".", interface->name); 1614 return; 1615 } 1616 } else { 1617 ioloop_cancel_wake_event(interface->router_solicit_wakeup); 1618 } 1619 interface->num_solicits_sent = 0; 1620 ioloop_add_wake_event(interface->router_solicit_wakeup, interface, router_solicit_callback, 1621 NULL, 128 + srp_random16() % 896); 1622 } 1623 1624 static interface_t * 1625 find_interface(route_state_t *route_state, const char *name, int ifindex) 1626 { 1627 interface_t **p_interface, *interface = NULL; 1628 1629 for (p_interface = &route_state->interfaces; *p_interface; p_interface = &(*p_interface)->next) { 1630 interface = *p_interface; 1631 if (!strcmp(name, interface->name)) { 1632 if (ifindex != -1 && interface->index != ifindex) { 1633 INFO("interface name " PUB_S_SRP " index changed from %d to %d", name, interface->index, ifindex); 1634 interface->index = ifindex; 1635 } 1636 break; 1637 } 1638 } 1639 1640 // If it's a new interface, make a structure. 1641 // We could do a callback, but don't have a use case 1642 if (*p_interface == NULL) { 1643 interface = interface_create(route_state, name, ifindex); 1644 if (interface != NULL) { 1645 if (route_state->thread_interface_name != NULL && !strcmp(name, route_state->thread_interface_name)) { 1646 interface->is_thread = true; 1647 } 1648 *p_interface = interface; 1649 } 1650 } 1651 return interface; 1652 } 1653 1654 1655 static void 1656 interface_shutdown(interface_t *interface) 1657 { 1658 icmp_message_t *router, *next; 1659 INFO("Interface " PUB_S_SRP " went away.", interface->name); 1660 if (interface->beacon_wakeup != NULL) { 1661 ioloop_cancel_wake_event(interface->beacon_wakeup); 1662 } 1663 if (interface->post_solicit_wakeup != NULL) { 1664 ioloop_cancel_wake_event(interface->post_solicit_wakeup); 1665 } 1666 if (interface->stale_evaluation_wakeup != NULL) { 1667 ioloop_cancel_wake_event(interface->stale_evaluation_wakeup); 1668 } 1669 if (interface->router_solicit_wakeup != NULL) { 1670 ioloop_cancel_wake_event(interface->router_solicit_wakeup); 1671 } 1672 if (interface->deconfigure_wakeup != NULL) { 1673 ioloop_cancel_wake_event(interface->deconfigure_wakeup); 1674 } 1675 #if SRP_FEATURE_VICARIOUS_ROUTER_DISCOVERY 1676 if (interface->vicarious_discovery_complete != NULL) { 1677 ioloop_cancel_wake_event(interface->vicarious_discovery_complete); 1678 } 1679 interface->vicarious_router_discovery_in_progress = false; 1680 #endif // SRP_FEATURE_VICARIOUS_ROUTER_DISCOVERY 1681 for (router = interface->routers; router; router = next) { 1682 next = router->next; 1683 icmp_message_free(router); 1684 } 1685 interface->routers = NULL; 1686 interface->last_beacon = interface->next_beacon = 0; 1687 interface->deprecate_deadline = 0; 1688 interface->preferred_lifetime = interface->valid_lifetime = 0; 1689 interface->num_solicits_sent = 0; 1690 interface->inactive = true; 1691 interface->ineligible = true; 1692 interface->our_prefix_advertised = false; 1693 interface->suppress_ipv6_prefix = false; 1694 interface->have_link_layer_address = false; 1695 interface->on_link_prefix_configured = false; 1696 interface->sent_first_beacon = false; 1697 interface->num_beacons_sent = 0; 1698 interface->router_discovery_started = false; 1699 interface->router_discovery_complete = false; 1700 interface->router_discovery_in_progress = false; 1701 interface->need_reconfigure_prefix = false; 1702 } 1703 1704 static void 1705 interface_prefix_evaluate(interface_t *interface) 1706 { 1707 route_state_t *route_state = interface->route_state; 1708 // Set up the interface prefix using the prefix number for the link. 1709 interface->ipv6_prefix = route_state->xpanid_prefix; 1710 } 1711 1712 1713 #ifndef RA_TESTER 1714 static bool 1715 router_is_advertising(icmp_message_t *router, const struct in6_addr *prefix, int preflen) 1716 { 1717 for (int i = 0; i < router->num_options; i++) { 1718 icmp_option_t *option = &router->options[i]; 1719 if (option->type == icmp_option_prefix_information) { 1720 prefix_information_t *pio = &option->option.prefix_information; 1721 if (pio->length != 64) { 1722 SEGMENTED_IPv6_ADDR_GEN_SRP(&pio->prefix, prefix_buf); 1723 INFO("invalid IP address prefix length: " PRI_SEGMENTED_IPv6_ADDR_SRP "/%d", 1724 SEGMENTED_IPv6_ADDR_PARAM_SRP(&pio->prefix, prefix_buf), preflen); 1725 continue; 1726 } 1727 if (!in6prefix_compare(prefix, &pio->prefix, 8)) { 1728 SEGMENTED_IPv6_ADDR_GEN_SRP(&pio->prefix, prefix_buf); 1729 SEGMENTED_IPv6_ADDR_GEN_SRP(&router->source, router_buf); 1730 INFO("router at " PRI_SEGMENTED_IPv6_ADDR_SRP " advertised prefix " PRI_SEGMENTED_IPv6_ADDR_SRP "/%d", 1731 SEGMENTED_IPv6_ADDR_PARAM_SRP(&router->source, router_buf), 1732 SEGMENTED_IPv6_ADDR_PARAM_SRP(&pio->prefix, prefix_buf), preflen); 1733 return true; 1734 } 1735 } 1736 } 1737 return false; 1738 } 1739 1740 static void 1741 route_remove_routers_advertising_prefix(interface_t *interface, const struct in6_addr *prefix, int preflen) 1742 { 1743 if (preflen != 64) { 1744 SEGMENTED_IPv6_ADDR_GEN_SRP(prefix, prefix_buf); 1745 INFO("invalid IP address prefix length: " PRI_SEGMENTED_IPv6_ADDR_SRP "/%d", 1746 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix, prefix_buf), preflen); 1747 return; 1748 } 1749 for (icmp_message_t **rp = &interface->routers; *rp != NULL; ) { 1750 icmp_message_t *router = *rp; 1751 if (router_is_advertising(router, prefix, preflen)) { 1752 *rp = router->next; 1753 router->next = NULL; 1754 icmp_message_free(router); 1755 } else { 1756 rp = &router->next; 1757 } 1758 } 1759 } 1760 #endif // RA_TESTER 1761 1762 static void 1763 ifaddr_callback(srp_server_t *server_state, void *context, const char *name, const addr_t *address, 1764 const addr_t *mask, unsigned flags, enum interface_address_change change) 1765 { 1766 char addrbuf[INET6_ADDRSTRLEN]; 1767 const uint8_t *addrbytes, *maskbytes, *prefp; 1768 int preflen, i; 1769 interface_t *interface; 1770 route_state_t *route_state = context; 1771 1772 #ifndef POSIX_BUILD 1773 interface = find_interface(route_state, name, -1); 1774 #else 1775 interface = find_interface(route_state, name, if_nametoindex(name)); 1776 #endif 1777 if (interface == NULL) { 1778 ERROR("find_interface returned NULL for " PUB_S_SRP, name); 1779 return; 1780 } 1781 1782 const bool is_thread_interface = interface->is_thread; 1783 1784 if (address->sa.sa_family == AF_INET) { 1785 addrbytes = (uint8_t *)&address->sin.sin_addr; 1786 maskbytes = (uint8_t *)&mask->sin.sin_addr; 1787 prefp = maskbytes + 3; 1788 preflen = 32; 1789 if (change == interface_address_added) { 1790 // Just got an IPv4 address? 1791 if (!interface->num_ipv4_addresses) { 1792 if (!(flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) { 1793 interface_prefix_evaluate(interface); 1794 } 1795 } 1796 interface->num_ipv4_addresses++; 1797 } else if (change == interface_address_deleted) { 1798 interface->num_ipv4_addresses--; 1799 // Just lost our last IPv4 address? 1800 if (!(flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) { 1801 if (!interface->num_ipv4_addresses) { 1802 interface_prefix_evaluate(interface); 1803 } 1804 } 1805 } 1806 } else if (address->sa.sa_family == AF_INET6) { 1807 if (change == interface_address_added) { 1808 interface->num_ipv6_addresses++; 1809 } else if (change == interface_address_deleted) { 1810 interface->num_ipv6_addresses--; 1811 } 1812 addrbytes = (uint8_t *)&address->sin6.sin6_addr; 1813 maskbytes = (uint8_t *)&mask->sin6.sin6_addr; 1814 prefp = maskbytes + 15; 1815 preflen = 128; 1816 #ifndef LINUX 1817 } else if (address->sa.sa_family == AF_LINK) { 1818 snprintf(addrbuf, sizeof addrbuf, "%02x:%02x:%02x:%02x:%02x:%02x", 1819 address->ether_addr.addr[0], address->ether_addr.addr[1], 1820 address->ether_addr.addr[2], address->ether_addr.addr[3], 1821 address->ether_addr.addr[4], address->ether_addr.addr[5]); 1822 prefp = (uint8_t *)&addrbuf[0]; maskbytes = prefp + 1; // Skip prefix length calculation 1823 preflen = 0; 1824 addrbytes = NULL; 1825 #endif 1826 } else { 1827 INFO("Unknown address type %d", address->sa.sa_family); 1828 return; 1829 } 1830 1831 if (change != interface_address_unchanged) { 1832 #ifndef LINUX 1833 if (address->sa.sa_family == AF_LINK) { 1834 if (!interface->ineligible) { 1835 INFO("interface " PUB_S_SRP PUB_S_SRP " " PUB_S_SRP " " PRI_MAC_ADDR_SRP " flags %x", 1836 name, is_thread_interface ? " (thread)" : "", 1837 change == interface_address_added ? "added" : "removed", 1838 MAC_ADDR_PARAM_SRP(address->ether_addr.addr), flags); 1839 } 1840 } else { 1841 #endif 1842 for (; prefp >= maskbytes; prefp--) { 1843 if (*prefp) { 1844 break; 1845 } 1846 preflen -= 8; 1847 } 1848 for (i = 0; i < 8; i++) { 1849 if (*prefp & (1<<i)) { 1850 break; 1851 } 1852 --preflen; 1853 } 1854 inet_ntop(address->sa.sa_family, addrbytes, addrbuf, sizeof addrbuf); 1855 if (!interface->ineligible) { 1856 if (address->sa.sa_family == AF_INET) { 1857 IPv4_ADDR_GEN_SRP(addrbytes, addr_buf); 1858 INFO("interface " PUB_S_SRP PUB_S_SRP " " PUB_S_SRP " " PRI_IPv4_ADDR_SRP 1859 "/%d flags %x", name, is_thread_interface ? " (thread)" : "", 1860 change == interface_address_added ? "added" : "removed", 1861 IPv4_ADDR_PARAM_SRP(addrbytes, addr_buf), preflen, flags); 1862 } else if (address->sa.sa_family == AF_INET6) { 1863 SEGMENTED_IPv6_ADDR_GEN_SRP(addrbytes, addr_buf); 1864 INFO("interface " PUB_S_SRP PUB_S_SRP " " PUB_S_SRP " " PRI_SEGMENTED_IPv6_ADDR_SRP 1865 "/%d flags %x", name, is_thread_interface ? " (thread)" : "", 1866 change == interface_address_added ? "added" : "removed", 1867 SEGMENTED_IPv6_ADDR_PARAM_SRP(addrbytes, addr_buf), preflen, flags); 1868 #ifndef RA_TESTER 1869 if (change == interface_address_deleted) { 1870 route_remove_routers_advertising_prefix(interface, &address->sin6.sin6_addr, preflen); 1871 if (route_state->route_tracker != NULL) { 1872 route_tracker_route_state_changed(route_state->route_tracker, interface); 1873 } 1874 } 1875 #endif 1876 } else { 1877 INFO("invalid sa_family: %d", address->sa.sa_family); 1878 } 1879 1880 // Only notify dnssd-proxy when srp-mdns-proxy and dnssd-proxy is combined together. 1881 #if !defined(RA_TESTER) && (SRP_FEATURE_COMBINED_SRP_DNSSD_PROXY) 1882 // Notify dnssd-proxy that address is added or removed. 1883 if (!is_thread_interface) { 1884 if (change == interface_address_added) { 1885 if (!interface->inactive) { 1886 dnssd_proxy_ifaddr_callback(server_state, context, name, address, mask, flags, change); 1887 } 1888 } else { // change == interface_address_removed 1889 dnssd_proxy_ifaddr_callback(server_state, context, name, address, mask, flags, change); 1890 } 1891 } 1892 #endif // #if !defined(RA_TESTER) && (SRP_FEATURE_COMBINED_SRP_DNSSD_PROXY) 1893 1894 // When new IP address is removed, it is possible that the existing router information, such as 1895 // PIO and RIO is no longer valid since srp-mdns-proxy is losing its IP address. In order to let it to 1896 // flush the stale router information as soon as possible, we mark all the router as stale immediately, 1897 // by setting the router received time to a value which is 601s ago (router will be stale if the router 1898 // information is received for more than 600s). And then do router discovery for 20s, so we can ensure 1899 // that all the stale router information will be updated during the discovery, or flushed away. If all 1900 // routers are flushed, then srp-mdns-proxy will advertise its own prefix and configure the new IPv6 1901 // address. 1902 if (address->sa.sa_family == AF_INET6 && // An IPv6 address 1903 change == interface_address_deleted && // went away 1904 in6prefix_compare(&address->sin6.sin6_addr, &interface->ipv6_prefix, 8) && // not one of ours 1905 !is_thread_mesh_synthetic_or_link_local(&address->sin6.sin6_addr)) // not link-local 1906 { 1907 1908 INFO("clearing router discovery complete flag because address deleted."); 1909 #ifdef VICARIOUS_ROUTER_DISCOVERY 1910 INFO("making all routers stale and start router discovery due to removed address"); 1911 adjust_router_received_time(interface, ioloop_timenow(), 1912 -(MAX_ROUTER_RECEIVED_TIME_GAP_BEFORE_STALE + MSEC_PER_SEC)); 1913 #endif 1914 // Explicitly set router_discovery_complete to false so we can ensure that srp-mdns-proxy will start 1915 // the router discovery immediately. 1916 interface->router_discovery_complete = false; 1917 interface->router_discovery_started = false; 1918 // Set need_reconfigure_prefix to true to let routing_policy_evaluate know that the router discovery 1919 // is caused by interface removal event, so when the router discovery finished and nothing changes, 1920 // it can reconfigure the IPv6 routing in case configured does not handle it correctly. 1921 interface->need_reconfigure_prefix = true; 1922 routing_policy_evaluate(interface, false); 1923 } 1924 } 1925 #ifndef LINUX 1926 } 1927 #endif 1928 } 1929 1930 // Not a broadcast interface 1931 if (flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) { 1932 // Not the thread interface 1933 if (!is_thread_interface) { 1934 return; 1935 } 1936 } 1937 1938 // 169.254.* 1939 if (address->sa.sa_family == AF_INET && IN_LINKLOCAL(address->sin.sin_addr.s_addr)) { 1940 return; 1941 } 1942 1943 if (interface->index == -1) { 1944 interface->index = address->ether_addr.index; 1945 } 1946 1947 #if defined(THREAD_BORDER_ROUTER) && !defined(RA_TESTER) 1948 if (is_thread_interface && address->sa.sa_family == AF_INET6) { 1949 partition_utun0_address_changed(route_state, &address->sin6.sin6_addr, change); 1950 } 1951 #endif 1952 1953 if (address->sa.sa_family == AF_INET) { 1954 } else if (address->sa.sa_family == AF_INET6) { 1955 if (IN6_IS_ADDR_LINKLOCAL(&address->sin6.sin6_addr)) { 1956 interface->link_local = address->sin6.sin6_addr; 1957 } 1958 #ifndef LINUX 1959 } else if (address->sa.sa_family == AF_LINK) { 1960 if (address->ether_addr.len == 6) { 1961 if (change != interface_address_deleted) { 1962 memcpy(interface->link_layer, address->ether_addr.addr, 6); 1963 INFO("setting link layer address for " PUB_S_SRP " to " PRI_MAC_ADDR_SRP, interface->name, 1964 MAC_ADDR_PARAM_SRP(interface->link_layer)); 1965 interface->have_link_layer_address = true; 1966 } else { 1967 INFO("resetting link layer address for " PUB_S_SRP " (was " PRI_MAC_ADDR_SRP ")", interface->name, 1968 MAC_ADDR_PARAM_SRP(interface->link_layer)); 1969 memset(interface->link_layer, 0, 6); 1970 interface->have_link_layer_address = false; 1971 } 1972 } 1973 #endif 1974 } 1975 #if defined(POSIX_BUILD) 1976 interface_active_state_evaluate(interface, true, true); 1977 #endif 1978 } 1979 1980 #ifndef RA_TESTER 1981 static void 1982 route_get_mesh_local_prefix_callback(void *context, const char *prefix_string, cti_status_t status) 1983 { 1984 route_state_t *route_state = context; 1985 char prefix_buf[INET6_ADDRSTRLEN]; 1986 1987 if (status == kCTIStatus_Disconnected || status == kCTIStatus_DaemonNotRunning) { 1988 INFO("disconnected"); 1989 attempt_wpan_reconnect(route_state); 1990 goto fail; 1991 } 1992 1993 INFO(PRI_S_SRP " %d", prefix_string != NULL ? prefix_string : "<null>", status); 1994 if (status != kCTIStatus_NoError) { 1995 INFO("error %d", status); 1996 } 1997 if (prefix_string == NULL) { 1998 INFO("NULL prefix string"); 1999 goto fail; 2000 } 2001 2002 const char *prefix_addr_string; 2003 char *slash = strchr(prefix_string, '/'); 2004 if (slash != NULL) { 2005 size_t len = slash - prefix_string; 2006 if (len == 0) { 2007 ERROR("bogus prefix: " PRI_S_SRP, prefix_string); 2008 goto fail; 2009 } 2010 if (len - 1 > sizeof(prefix_buf)) { 2011 ERROR("prefix too long: " PRI_S_SRP, prefix_string); 2012 goto fail; 2013 } 2014 memcpy(prefix_buf, prefix_string, len); 2015 prefix_buf[len] = 0; 2016 prefix_addr_string = prefix_buf; 2017 } else { 2018 prefix_addr_string = prefix_string; 2019 } 2020 if (!inet_pton(AF_INET6, prefix_addr_string, &route_state->thread_mesh_local_prefix)) { 2021 ERROR("prefix syntax incorrect: " PRI_S_SRP, prefix_addr_string); 2022 goto fail; 2023 } 2024 SEGMENTED_IPv6_ADDR_GEN_SRP(route_state->thread_mesh_local_prefix.s6_addr, ml_prefix_buf); 2025 INFO(PRI_SEGMENTED_IPv6_ADDR_SRP PUB_S_SRP, 2026 SEGMENTED_IPv6_ADDR_PARAM_SRP(route_state->thread_mesh_local_prefix.s6_addr, ml_prefix_buf), 2027 slash ? slash : ""); 2028 route_state->have_mesh_local_prefix = true; 2029 return; 2030 fail: 2031 route_state->have_mesh_local_prefix = false; 2032 return; 2033 } 2034 #endif // RA_TESTER 2035 2036 void 2037 route_refresh_interface_list(route_state_t *route_state) 2038 { 2039 interface_t *interface; 2040 bool UNUSED have_active = false; 2041 // We sometimes do not get "interface down" notifications when moving from one WiFi SSID to the next. To detect that 2042 // this has happened, see if we go from nonzero IPv6 addresses to zero after scanning the interface addresses 2043 for (interface = route_state->interfaces; interface != NULL; interface = interface->next) { 2044 interface->old_num_ipv6_addresses = interface->num_ipv6_addresses; 2045 } 2046 ioloop_map_interface_addresses_here(route_state->srp_server, &route_state->interface_addresses, NULL, route_state, ifaddr_callback); 2047 2048 for (interface = route_state->interfaces; interface; interface = interface->next) { 2049 #if defined(THREAD_BORDER_ROUTER) && !defined(RA_TESTER) 2050 if (interface->is_thread) { 2051 partition_utun0_pick_listener_address(route_state); 2052 } 2053 #endif 2054 if (!interface->ineligible && !interface->inactive) { 2055 have_active = true; 2056 } 2057 2058 if (!interface->ineligible && !interface->inactive && 2059 interface->num_ipv6_addresses == 0 && interface->old_num_ipv6_addresses != 0) 2060 { 2061 flush_routers(interface, 0); 2062 } 2063 } 2064 2065 #ifndef RA_TESTER 2066 // Notice if we have lost or gained infrastructure. 2067 if (have_active && !route_state->have_non_thread_interface) { 2068 INFO("we have an active interface"); 2069 route_state->have_non_thread_interface = true; 2070 route_state->partition_can_advertise_service = true; 2071 partition_maybe_advertise_anycast_service(route_state); 2072 } else if (!have_active && route_state->have_non_thread_interface) { 2073 INFO("we no longer have an active interface"); 2074 route_state->have_non_thread_interface = false; 2075 route_state->partition_can_advertise_service = false; 2076 // Stop advertising the service, if we are doing so. 2077 partition_discontinue_all_srp_service(route_state); 2078 } 2079 #endif // RA_TESTER 2080 } 2081 2082 2083 #if defined(THREAD_BORDER_ROUTER) && !defined(RA_TESTER) 2084 #if defined(POSIX_BUILD) 2085 static void 2086 wpan_reconnect_wakeup_callback(void *context) 2087 { 2088 route_state_t *route_state = context; 2089 if (route_state->wpan_reconnect_wakeup != NULL) { 2090 ioloop_wakeup_release(route_state->wpan_reconnect_wakeup); 2091 route_state->wpan_reconnect_wakeup = NULL; 2092 } 2093 // Attempt to restart the thread network... 2094 infrastructure_network_startup(context); 2095 } 2096 #endif // POSIX_BUILD 2097 2098 static void 2099 attempt_wpan_reconnect(void *context) 2100 { 2101 route_state_t *route_state = context; 2102 #if defined(POSIX_BUILD) 2103 if (route_state->wpan_reconnect_wakeup == NULL) { 2104 route_state->wpan_reconnect_wakeup = ioloop_wakeup_create(); 2105 if (route_state->wpan_reconnect_wakeup == NULL) { 2106 ERROR("can't allocate wpan reconnect wait wakeup."); 2107 return; 2108 } 2109 INFO("delaying for ten seconds before attempt to reconnect to thread daemon."); 2110 ioloop_add_wake_event(route_state->wpan_reconnect_wakeup, NULL, 2111 wpan_reconnect_wakeup_callback, NULL, 10 * 1000); 2112 partition_state_reset(route_state); 2113 #endif 2114 } 2115 } 2116 2117 static void 2118 cti_get_tunnel_name_callback(void *context, const char *name, cti_status_t status) 2119 { 2120 route_state_t *route_state = context; 2121 if (status == kCTIStatus_Disconnected || status == kCTIStatus_DaemonNotRunning) { 2122 INFO("disconnected"); 2123 attempt_wpan_reconnect(route_state); 2124 return; 2125 } 2126 2127 INFO(PUB_S_SRP " %d", name != NULL ? name : "<null>", status); 2128 if (status != kCTIStatus_NoError) { 2129 return; 2130 } 2131 route_state->num_thread_interfaces = 1; 2132 if (route_state->thread_interface_name != NULL) { 2133 free(route_state->thread_interface_name); 2134 } 2135 route_state->thread_interface_name = strdup(name); 2136 if (route_state->thread_interface_name == NULL) { 2137 ERROR("No memory to save thread interface name " PUB_S_SRP, name); 2138 return; 2139 } 2140 INFO("Thread interface at " PUB_S_SRP, route_state->thread_interface_name); 2141 partition_got_tunnel_name(route_state); 2142 } 2143 2144 static void 2145 cti_get_role_callback(void *context, cti_network_node_type_t role, cti_status_t status) 2146 { 2147 route_state_t *route_state = context; 2148 bool am_thread_router = false; 2149 2150 if (status == kCTIStatus_Disconnected || status == kCTIStatus_DaemonNotRunning) { 2151 INFO("disconnected"); 2152 attempt_wpan_reconnect(route_state); 2153 return; 2154 } 2155 2156 if (status == kCTIStatus_NoError) { 2157 route_state->partition_last_role_change = ioloop_timenow(); 2158 2159 if (role == kCTI_NetworkNodeType_Router || role == kCTI_NetworkNodeType_Leader) { 2160 am_thread_router = true; 2161 } 2162 2163 INFO("role is: " PUB_S_SRP " (%d)\n ", am_thread_router ? "router" : "not router", role); 2164 } else { 2165 ERROR("cti_get_role_callback: nonzero status %d", status); 2166 } 2167 2168 // Our thread role doesn't actually matter, but it's useful to report it in the logs. 2169 } 2170 2171 static void 2172 cti_get_state_callback(void *context, cti_network_state_t state, cti_status_t status) 2173 { 2174 route_state_t *route_state = context; 2175 bool associated = false; 2176 2177 if (status == kCTIStatus_Disconnected || status == kCTIStatus_DaemonNotRunning) { 2178 INFO("disconnected"); 2179 attempt_wpan_reconnect(context); 2180 return; 2181 } 2182 2183 route_state->partition_last_state_change = ioloop_timenow(); 2184 2185 if (status == kCTIStatus_NoError) { 2186 if ((state == kCTI_NCPState_Associated) || (state == kCTI_NCPState_Isolated) || 2187 (state == kCTI_NCPState_NetWake_Asleep) || (state == kCTI_NCPState_NetWake_Waking)) 2188 { 2189 associated = true; 2190 } 2191 2192 INFO("state is: " PUB_S_SRP " (%d)\n ", associated ? "associated" : "not associated", state); 2193 } else { 2194 ERROR("cti_get_state_callback: nonzero status %d", status); 2195 } 2196 2197 if (route_state->current_thread_state != state) { 2198 if (associated) { 2199 route_state->current_thread_state = state; 2200 partition_maybe_enable_services(route_state); // but probably not 2201 } else { 2202 route_state->current_thread_state = state; 2203 partition_disable_service(route_state); 2204 } 2205 } 2206 } 2207 2208 static void 2209 re_evaluate_interfaces(route_state_t *route_state) 2210 { 2211 for (interface_t *interface = route_state->interfaces; interface != NULL; interface = interface->next) { 2212 interface_prefix_evaluate(interface); 2213 } 2214 2215 partition_maybe_enable_services(route_state); 2216 } 2217 2218 static void 2219 route_get_xpanid_callback(void *context, uint64_t new_xpanid, cti_status_t status) 2220 { 2221 route_state_t *route_state = context; 2222 if (status == kCTIStatus_Disconnected || status == kCTIStatus_DaemonNotRunning) { 2223 INFO("disconnected"); 2224 attempt_wpan_reconnect(route_state); 2225 return; 2226 } 2227 2228 if (status == kCTIStatus_NoError) { 2229 if (route_state->partition_has_xpanid) { 2230 ERROR("Unexpected change to XPANID from %" PRIu64 " to %" PRIu64, 2231 route_state->srp_server->xpanid, new_xpanid); 2232 } else { 2233 INFO("XPANID is now %" PRIu64, new_xpanid); 2234 } 2235 } else { 2236 ERROR("nonzero status %d", status); 2237 return; 2238 } 2239 2240 route_state->srp_server->xpanid = new_xpanid; 2241 route_state->partition_has_xpanid = true; 2242 in6addr_zero(&route_state->xpanid_prefix); 2243 route_state->xpanid_prefix.s6_addr[0] = 0xfd; 2244 for (int i = 1; i < 8; i++) { 2245 route_state->xpanid_prefix.s6_addr[i] = ((route_state->srp_server->xpanid >> ((8 - i) * 8)) & 0xFFU); 2246 } 2247 route_state->have_xpanid_prefix = true; 2248 2249 #if SRP_FEATURE_REPLICATION 2250 if (route_state->srp_server->srp_replication_enabled) { 2251 INFO("start srp replication."); 2252 srpl_startup(route_state->srp_server); 2253 } 2254 #endif // SRP_FEATURE_REPLICATION 2255 2256 re_evaluate_interfaces(route_state); 2257 } 2258 2259 void 2260 adv_ctl_add_prefix(route_state_t *route_state, const uint8_t *const data) 2261 { 2262 if (route_state->omr_watcher != NULL) { 2263 omr_prefix_t *thread_prefixes = omr_watcher_prefixes_get(route_state->omr_watcher); 2264 omr_prefix_t *prefix = NULL; 2265 2266 for (prefix = thread_prefixes; prefix != NULL; prefix = prefix->next) { 2267 if (!memcmp(&prefix->prefix, data, BR_PREFIX_SLASH_64_BYTES)) { 2268 SEGMENTED_IPv6_ADDR_GEN_SRP(prefix->prefix.s6_addr, prefix_buf); 2269 INFO("prefix " PRI_SEGMENTED_IPv6_ADDR_SRP " already there", 2270 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix->prefix.s6_addr, prefix_buf)); 2271 break; 2272 } 2273 } 2274 if (prefix == NULL) { 2275 SEGMENTED_IPv6_ADDR_GEN_SRP(prefix->prefix.s6_addr, prefix_buf); 2276 INFO("adding prefix " PRI_SEGMENTED_IPv6_ADDR_SRP, 2277 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix->prefix.s6_addr, prefix_buf)); 2278 if (!omr_watcher_prefix_add(route_state->omr_watcher, (struct in6_addr *)data, BR_PREFIX_SLASH_64_BYTES, omr_prefix_priority_low)) { 2279 INFO("failed"); 2280 } 2281 } 2282 } 2283 } 2284 2285 void 2286 adv_ctl_remove_prefix(route_state_t *route_state, const uint8_t *const data) 2287 { 2288 if (route_state->omr_watcher != NULL) { 2289 omr_prefix_t *thread_prefixes = omr_watcher_prefixes_get(route_state->omr_watcher); 2290 omr_prefix_t *prefix = NULL; 2291 2292 for (prefix = thread_prefixes; prefix != NULL; prefix = prefix->next) { 2293 if (!memcmp(&prefix->prefix, data, BR_PREFIX_SLASH_64_BYTES)) { 2294 break; 2295 } 2296 } 2297 if (prefix == NULL) { 2298 SEGMENTED_IPv6_ADDR_GEN_SRP(data, prefix_buf); 2299 INFO("prefix " PRI_SEGMENTED_IPv6_ADDR_SRP " not present", 2300 SEGMENTED_IPv6_ADDR_PARAM_SRP(data, prefix_buf)); 2301 } else { 2302 SEGMENTED_IPv6_ADDR_GEN_SRP(prefix->prefix.s6_addr, prefix_buf); 2303 INFO("removing prefix " PRI_SEGMENTED_IPv6_ADDR_SRP, 2304 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix->prefix.s6_addr, prefix_buf)); 2305 if (!omr_watcher_prefix_remove(route_state->omr_watcher, data, BR_PREFIX_SLASH_64_BYTES)) { 2306 INFO("no prefix removed."); 2307 } 2308 } 2309 } 2310 } 2311 2312 static void 2313 route_rloc16_callback(void *context, uint16_t rloc16, cti_status_t status) 2314 { 2315 route_state_t *route_state = context; 2316 2317 if (status != kCTIStatus_NoError) { 2318 ERROR("%d", status); 2319 } else { 2320 route_state->srp_server->rloc16 = rloc16; 2321 route_state->have_rloc16 = true; 2322 INFO("server_state->rloc16 updated to %d", route_state->srp_server->rloc16); 2323 // whenever the local rloc16 is updated, we should re-evaluate if anycast 2324 // service should be advertised. 2325 partition_maybe_advertise_anycast_service(route_state); 2326 } 2327 } 2328 #endif // THREAD_BORDER_ROUTER && !RA_TESTER 2329 2330 void 2331 infrastructure_network_startup(route_state_t *route_state) 2332 { 2333 INFO("Thread network started."); 2334 2335 // ioloop_network_watcher_start(network_watch_event); 2336 #ifndef RA_TESTER 2337 set_thread_forwarding(); 2338 #endif 2339 } 2340 2341 #if defined(THREAD_BORDER_ROUTER) && !defined(RA_TESTER) 2342 static void 2343 route_omr_watcher_event(route_state_t *route_state, void *UNUSED context, omr_watcher_event_type_t event_type, 2344 omr_prefix_t *UNUSED prefixes, omr_prefix_t *UNUSED prefix) 2345 { 2346 // Whenever we get an update to the prefix list, we should check our interface addresses. 2347 if (event_type == omr_watcher_event_prefix_update_finished) { 2348 route_refresh_interface_list(route_state); 2349 int num_prefixes = 0; 2350 for (omr_prefix_t *prf = prefixes; prf != NULL; prf = prf->next) { 2351 num_prefixes++; 2352 } 2353 if (num_prefixes != route_state->num_thread_prefixes) { 2354 int old_num_prefixes = route_state->num_thread_prefixes; 2355 INFO("%d prefixes instead of %d, evaluating policy", num_prefixes, route_state->num_thread_prefixes); 2356 routing_policy_evaluate_all_interfaces(route_state, true); 2357 route_state->num_thread_prefixes = num_prefixes; 2358 if (old_num_prefixes == 0 && num_prefixes > 0) { 2359 INFO("thread prefix available, may advertise anycast"); 2360 partition_maybe_advertise_anycast_service(route_state); 2361 } 2362 if (old_num_prefixes > 0 && num_prefixes == 0) { 2363 INFO("all thread prefixes are gone, stop advertising anycast service"); 2364 partition_stop_advertising_anycast_service(route_state, route_state->thread_sequence_number); 2365 } 2366 } 2367 } 2368 } 2369 2370 static void 2371 thread_network_startup(route_state_t *route_state) 2372 { 2373 if (route_state->thread_network_shutting_down) { 2374 INFO("thread network still shutting down--canceling"); 2375 ioloop_cancel_wake_event(route_state->thread_network_shutdown_wakeup); 2376 route_state->thread_network_shutting_down = false; 2377 return; 2378 } 2379 int status = cti_get_state(route_state->srp_server, &route_state->thread_state_context, route_state, 2380 cti_get_state_callback, NULL); 2381 if (status == kCTIStatus_NoError) { 2382 status = cti_get_network_node_type(route_state->srp_server, &route_state->thread_role_context, route_state, 2383 cti_get_role_callback, NULL); 2384 } 2385 srp_server_t *server_state = route_state->srp_server; 2386 server_state->service_tracker = service_tracker_create(server_state); 2387 if (server_state->service_tracker != NULL) { 2388 service_tracker_callback_add(server_state->service_tracker, 2389 partition_service_set_changed, NULL, route_state); 2390 service_tracker_start(server_state->service_tracker); 2391 } 2392 if (status == kCTIStatus_NoError) { 2393 status = cti_get_tunnel_name(route_state->srp_server, route_state, cti_get_tunnel_name_callback, NULL); 2394 } 2395 if (status == kCTIStatus_NoError) { 2396 status = cti_get_extended_pan_id(route_state->srp_server, &route_state->thread_xpanid_context, route_state, 2397 route_get_xpanid_callback, NULL); 2398 } 2399 if (status == kCTIStatus_NoError) { 2400 status = cti_get_rloc16(route_state->srp_server, &route_state->thread_rloc16_context, route_state, 2401 route_rloc16_callback, NULL); 2402 } 2403 if (status == kCTIStatus_NoError) { 2404 status = cti_get_mesh_local_prefix(route_state->srp_server, route_state, 2405 route_get_mesh_local_prefix_callback, NULL); 2406 } 2407 if (status != kCTIStatus_NoError) { 2408 if (status == kCTIStatus_DaemonNotRunning) { 2409 attempt_wpan_reconnect(route_state); 2410 } else { 2411 ERROR("initial network setup failed"); 2412 } 2413 } 2414 #if SRP_FEATURE_NAT64 2415 INFO("start nat64."); 2416 nat64_start(route_state); 2417 #endif 2418 route_state->omr_watcher = omr_watcher_create(route_state, attempt_wpan_reconnect); 2419 if (route_state->omr_watcher == NULL) { 2420 ERROR("omr_watcher create failed"); 2421 return; 2422 } 2423 route_state->omr_watcher_callback = omr_watcher_callback_add(route_state->omr_watcher, 2424 route_omr_watcher_event, NULL, route_state); 2425 if (route_state->omr_watcher_callback == NULL) { 2426 ERROR("omr_watcher_callback add failed"); 2427 return; 2428 } 2429 route_state->omr_publisher = omr_publisher_create(route_state, "main"); 2430 if (route_state->omr_publisher == NULL) { 2431 ERROR("omr_publisher create failed"); 2432 return; 2433 } 2434 omr_publisher_set_omr_watcher(route_state->omr_publisher, route_state->omr_watcher); 2435 omr_publisher_set_reconnect_callback(route_state->omr_publisher, attempt_wpan_reconnect); 2436 omr_publisher_start(route_state->omr_publisher); 2437 omr_watcher_start(route_state->omr_watcher); 2438 route_state->thread_network_running = true; 2439 } 2440 #endif // defined(THREAD_BORDER_ROUTER) && !defined(RA_TESTER) 2441 2442 #ifndef RA_TESTER 2443 static void 2444 thread_network_shutdown_wakeup_callback(void *context) 2445 { 2446 route_state_t *route_state = context; 2447 INFO("shutdown timer expired, shutting down."); 2448 thread_network_shutdown(route_state); 2449 } 2450 2451 static void 2452 thread_network_shutdown_start(route_state_t *route_state) 2453 { 2454 if (route_state->thread_network_shutdown_wakeup == NULL) { 2455 route_state->thread_network_shutdown_wakeup = ioloop_wakeup_create(); 2456 } 2457 if (route_state->thread_network_shutdown_wakeup == NULL) { 2458 INFO("no memory for wakeup object"); 2459 thread_network_shutdown(route_state); 2460 } else { 2461 INFO("scheduling shutdown in ten seconds"); 2462 route_state->thread_network_shutting_down = true; 2463 ioloop_add_wake_event(route_state->thread_network_shutdown_wakeup, 2464 route_state, thread_network_shutdown_wakeup_callback, NULL, 10 * 1000); 2465 } 2466 } 2467 2468 static void 2469 thread_network_shutdown(route_state_t *route_state) 2470 { 2471 // If we get an explicit shutdown after getting a "shut down if nothing improves", cancel the scheduled shutdown. 2472 // This code also runs when we're called from the shutdown wakeup callback and serves to cancel that state. 2473 if (route_state->thread_network_shutdown_wakeup != NULL) { 2474 ioloop_cancel_wake_event(route_state->thread_network_shutdown_wakeup); 2475 } 2476 route_state->thread_network_shutting_down = false; 2477 if (route_state->thread_state_context != NULL) { 2478 INFO("discontinuing state events"); 2479 cti_events_discontinue(route_state->thread_state_context); 2480 route_state->thread_state_context = NULL; 2481 } 2482 if (route_state->thread_role_context != NULL) { 2483 INFO("discontinuing role events"); 2484 cti_events_discontinue(route_state->thread_role_context); 2485 route_state->thread_role_context = NULL; 2486 } 2487 if (route_state->thread_route_context != NULL) { 2488 INFO("discontinuing route events"); 2489 cti_events_discontinue(route_state->thread_route_context); 2490 route_state->thread_route_context = NULL; 2491 } 2492 if (route_state->thread_xpanid_context != NULL) { 2493 INFO("discontinuing xpanid events"); 2494 cti_events_discontinue(route_state->thread_xpanid_context); 2495 route_state->thread_xpanid_context = NULL; 2496 } 2497 if (route_state->thread_rloc16_context != NULL) { 2498 INFO("discontinuing rloc16 events"); 2499 cti_events_discontinue(route_state->thread_rloc16_context); 2500 route_state->thread_rloc16_context = NULL; 2501 } 2502 if (route_state->thread_ml_prefix_connection != NULL) { 2503 INFO("discontinuing route events"); 2504 cti_events_discontinue(route_state->thread_ml_prefix_connection); 2505 route_state->thread_ml_prefix_connection = NULL; 2506 } 2507 srp_mdns_flush(route_state->srp_server); 2508 #if SRP_FEATURE_REPLICATION 2509 INFO("stop srp replication."); 2510 srpl_shutdown(route_state->srp_server); 2511 #endif 2512 #if SRP_FEATURE_NAT64 2513 INFO("stop nat64."); 2514 nat64_stop(route_state); 2515 #endif 2516 partition_state_reset(route_state); 2517 route_state->thread_network_running = false; 2518 } 2519 #endif // RA_TESTER 2520 2521 void 2522 infrastructure_network_shutdown(route_state_t *route_state) 2523 { 2524 interface_t *interface; 2525 2526 #ifndef RA_TESTER 2527 if (route_state->thread_network_running) { 2528 thread_network_shutdown(route_state); 2529 } 2530 #endif 2531 INFO("Infrastructure network shutdown."); 2532 // Stop all activity on interfaces. 2533 for (interface = route_state->interfaces; interface; interface = interface->next) { 2534 interface_shutdown(interface); 2535 } 2536 // Whatever non-thread interface we may have had we just shut down, so mark it down so that we can 2537 // start it up later. 2538 route_state->have_non_thread_interface = false; 2539 } 2540 2541 #ifndef RA_TESTER 2542 static void 2543 partition_state_reset(route_state_t *route_state) 2544 { 2545 if (route_state->omr_watcher) { 2546 if (route_state->omr_watcher_callback != NULL) { 2547 INFO("canceling omr watcher callback"); 2548 omr_watcher_callback_cancel(route_state->omr_watcher, route_state->omr_watcher_callback); 2549 route_state->omr_watcher_callback = NULL; 2550 } 2551 INFO("discontinuing omr watcher"); 2552 omr_watcher_cancel(route_state->omr_watcher); 2553 omr_watcher_release(route_state->omr_watcher); 2554 2555 route_state->omr_watcher = NULL; 2556 } 2557 if (route_state->omr_publisher) { 2558 INFO("discontinuing omr publisher"); 2559 omr_publisher_cancel(route_state->omr_publisher); 2560 omr_publisher_release(route_state->omr_publisher); 2561 route_state->omr_publisher = NULL; 2562 } 2563 if (route_state->route_tracker) { 2564 INFO("discontinuing route tracker"); 2565 route_tracker_cancel(route_state->route_tracker); 2566 route_tracker_release(route_state->route_tracker); 2567 route_state->route_tracker = NULL; 2568 } 2569 srp_server_t *server_state = route_state->srp_server; 2570 if (server_state->service_tracker != NULL) { 2571 service_tracker_cancel(server_state->service_tracker); 2572 service_tracker_release(server_state->service_tracker); 2573 server_state->service_tracker = NULL; 2574 } 2575 2576 route_state->current_thread_state = kCTI_NCPState_Uninitialized; 2577 route_state->partition_last_prefix_set_change = 0; 2578 route_state->partition_last_pref_id_set_change = 0; 2579 route_state->partition_last_role_change = 0; 2580 route_state->partition_last_state_change = 0; 2581 route_state->partition_settle_start = 0; 2582 route_state->partition_service_last_add_time = 0; 2583 route_state->partition_have_prefix_list = false; 2584 route_state->partition_have_pref_id_list = false; 2585 route_state->partition_tunnel_name_is_known = false; 2586 route_state->partition_can_advertise_service = false; 2587 route_state->partition_can_advertise_anycast_service = false; 2588 route_state->srp_server->srp_anycast_service_blocked = false; 2589 route_state->srp_server->srp_unicast_service_blocked = false; 2590 route_state->partition_can_provide_routing = false; 2591 route_state->partition_has_xpanid = false; 2592 route_state->partition_may_offer_service = false; 2593 route_state->partition_settle_satisfied = true; 2594 route_state->have_rloc16 = false; 2595 route_state->advertising_srp_anycast_service = false; 2596 2597 if (route_state->partition_settle_wakeup != NULL) { 2598 ioloop_cancel_wake_event(route_state->partition_settle_wakeup); 2599 } 2600 2601 if (route_state->partition_post_partition_wakeup != NULL) { 2602 ioloop_cancel_wake_event(route_state->partition_post_partition_wakeup); 2603 } 2604 2605 if (route_state->partition_pref_id_wait_wakeup != NULL) { 2606 ioloop_cancel_wake_event(route_state->partition_pref_id_wait_wakeup); 2607 } 2608 2609 if (route_state->partition_service_add_pending_wakeup != NULL) { 2610 ioloop_cancel_wake_event(route_state->partition_service_add_pending_wakeup); 2611 } 2612 2613 if (route_state->partition_anycast_service_add_pending_wakeup != NULL) { 2614 ioloop_cancel_wake_event(route_state->partition_service_add_pending_wakeup); 2615 } 2616 2617 if (route_state->service_set_changed_wakeup != NULL) { 2618 ioloop_cancel_wake_event(route_state->service_set_changed_wakeup); 2619 } 2620 } 2621 2622 static void 2623 partition_proxy_listener_ready(void *context, uint16_t port) 2624 { 2625 srp_server_t *server_state = context; 2626 route_state_t *route_state = server_state->route_state; 2627 2628 INFO("listening on port %d", port); 2629 route_state->srp_service_listen_port = port; 2630 if (route_state->have_non_thread_interface) { 2631 route_state->partition_can_advertise_service = true; 2632 partition_maybe_advertise_service(route_state); 2633 } else { 2634 partition_discontinue_srp_service(route_state); 2635 } 2636 } 2637 2638 static void 2639 partition_srp_listener_canceled(comm_t *listener, void *context) 2640 { 2641 srp_server_t *server_state = context; 2642 route_state_t *route_state = server_state->route_state; 2643 2644 INFO("listener is %p", listener); 2645 if (route_state->srp_listener == listener) { 2646 ioloop_comm_release(route_state->srp_listener); 2647 route_state->srp_listener = NULL; 2648 2649 if (!server_state->srp_unicast_service_blocked) { 2650 partition_discontinue_srp_service(route_state); 2651 } 2652 } 2653 } 2654 2655 static void 2656 partition_stop_srp_listener(route_state_t *route_state) 2657 { 2658 if (route_state->srp_listener != NULL) { 2659 INFO("discontinuing SRP service on port %d", route_state->srp_service_listen_port); 2660 ioloop_listener_cancel(route_state->srp_listener); 2661 ioloop_comm_release(route_state->srp_listener); 2662 route_state->srp_listener = NULL; 2663 } 2664 } 2665 2666 void 2667 partition_start_srp_listener(route_state_t *route_state) 2668 { 2669 #define max_avoid_ports 100 2670 uint16_t avoid_ports[max_avoid_ports]; 2671 int num_avoid_ports = 0; 2672 thread_service_t *service; 2673 2674 for (service = service_tracker_services_get(route_state->srp_server->service_tracker); 2675 service != NULL; service = service->next) 2676 { 2677 if (service->service_type == unicast_service) { 2678 // Track the port regardless. 2679 if (num_avoid_ports < max_avoid_ports) { 2680 avoid_ports[num_avoid_ports] = (service->u.unicast.port[0] << 8) | (service->u.unicast.port[1]); 2681 num_avoid_ports++; 2682 } 2683 } 2684 } 2685 2686 // Make sure we don't overwrite the listener without stopping it. 2687 partition_stop_srp_listener(route_state); 2688 2689 INFO("starting listener."); 2690 route_state->srp_listener = srp_proxy_listen(avoid_ports, num_avoid_ports, NULL, partition_proxy_listener_ready, 2691 partition_srp_listener_canceled, NULL, NULL, route_state->srp_server); 2692 if (route_state->srp_listener == NULL) { 2693 ERROR("Unable to start SRP listener, so can't advertise it"); 2694 return; 2695 } 2696 } 2697 2698 void 2699 partition_discontinue_srp_service(route_state_t *route_state) 2700 { 2701 partition_stop_srp_listener(route_state); 2702 2703 // Won't match 2704 in6addr_zero(&route_state->srp_listener_ip_address); 2705 route_state->srp_service_listen_port = 0; 2706 2707 // Stop advertising the service, if we are doing so. 2708 partition_stop_advertising_service(route_state); 2709 } 2710 2711 void 2712 partition_discontinue_all_srp_service(route_state_t *route_state) 2713 { 2714 partition_discontinue_srp_service(route_state); 2715 partition_stop_advertising_anycast_service(route_state, route_state->thread_sequence_number); 2716 } 2717 2718 // An address on utun0 has changed. Evaluate what to do with our listener service. 2719 // This gets called from ifaddr_callback(). If we don't yet have a thread service configured, 2720 // it should be called for unchanged addresses as well as changed. 2721 static void 2722 partition_utun0_address_changed(route_state_t *route_state, const struct in6_addr *addr, 2723 enum interface_address_change change) 2724 { 2725 SEGMENTED_IPv6_ADDR_GEN_SRP(addr, addr_buf); 2726 2727 // Is this the address we are currently using? 2728 if (!in6addr_compare(&route_state->srp_listener_ip_address, addr)) { 2729 route_state->seen_listener_address = true; 2730 2731 // Did it go away? If so, drop the listener. 2732 if (change == interface_address_deleted) { 2733 INFO(PRI_SEGMENTED_IPv6_ADDR_SRP ": listener address removed.", 2734 SEGMENTED_IPv6_ADDR_PARAM_SRP(addr, addr_buf)); 2735 if (route_state->srp_listener != NULL) { 2736 INFO(PRI_SEGMENTED_IPv6_ADDR_SRP ": canceling listener on removed address.", 2737 SEGMENTED_IPv6_ADDR_PARAM_SRP(addr, addr_buf)); 2738 partition_discontinue_srp_service(route_state); 2739 } 2740 } else { 2741 // This should never happen. 2742 if (change == interface_address_added) { 2743 ERROR(PRI_SEGMENTED_IPv6_ADDR_SRP ": address we're listening on was added.", 2744 SEGMENTED_IPv6_ADDR_PARAM_SRP(addr, addr_buf)); 2745 } else { 2746 INFO("still listening on " PRI_SEGMENTED_IPv6_ADDR_SRP, SEGMENTED_IPv6_ADDR_PARAM_SRP(addr, addr_buf)); 2747 } 2748 } 2749 2750 // Nothing more to do for this address. 2751 return; 2752 } 2753 2754 // No point in looking at addresses if we don't have prerequisites. 2755 if (!route_state->have_mesh_local_prefix || !route_state->have_non_thread_interface) { 2756 return; 2757 } 2758 2759 // Otherwise, we don't care about deleted addresses, but added and existing addresses matter. 2760 if (change != interface_address_deleted) { 2761 // If this address isn't an address we're already listening on, check if it's an anycast address; if so, 2762 // skip it as a candidate to listen on. 2763 if (is_thread_mesh_synthetic_address(addr)) { 2764 INFO(PRI_SEGMENTED_IPv6_ADDR_SRP ": thread anycast address.", 2765 SEGMENTED_IPv6_ADDR_PARAM_SRP(addr, addr_buf)); 2766 } 2767 2768 // If it's not an anycast address, do an election on it against the previously-seen addresses in this 2769 // iteration of ioloop_map_interface_addresses(). Numerically lowest address wins. Note that this means 2770 // that a link-local address will always lose, and if we have any anycast address we at least have a 2771 // mesh-local address, and that's fine to use if it happens to win. If we could figure out what our 2772 // mesh-local prefix was, we'd actually prefer this address since it never changes. 2773 else { 2774 // Don't use the mesh-local prefix 2775 if (!in6prefix_compare(addr, &route_state->thread_mesh_local_prefix, 8)) { 2776 INFO(PRI_SEGMENTED_IPv6_ADDR_SRP ": is our mesh-local address, skipping", 2777 SEGMENTED_IPv6_ADDR_PARAM_SRP(addr, addr_buf)); 2778 } 2779 // RFC4297: Link-Scoped Unicast address range FE80::/10 2780 else if (addr->s6_addr[0] == 0xfe && (addr->s6_addr[1] & 0xc0) == 0x80) { 2781 INFO(PRI_SEGMENTED_IPv6_ADDR_SRP ": is our link-local address, skipping", 2782 SEGMENTED_IPv6_ADDR_PARAM_SRP(addr, addr_buf)); 2783 } 2784 // If the address is not on the list of prefixes we know about, let's not use it. 2785 else if (route_state->omr_watcher == NULL || 2786 !omr_watcher_prefix_exists(route_state->omr_watcher, addr, 64)) 2787 { 2788 INFO(PRI_SEGMENTED_IPv6_ADDR_SRP ": is unknown, skipping", 2789 SEGMENTED_IPv6_ADDR_PARAM_SRP(addr, addr_buf)); 2790 } 2791 // Otherwise it's legit and we can use it 2792 else { 2793 if (!route_state->have_proposed_srp_listener_address || 2794 in6addr_compare(&route_state->proposed_srp_listener_address, addr) > 0) 2795 { 2796 if (route_state->have_proposed_srp_listener_address) { 2797 INFO(PRI_SEGMENTED_IPv6_ADDR_SRP ": wins over previous winner.", 2798 SEGMENTED_IPv6_ADDR_PARAM_SRP(addr, addr_buf)); 2799 } else { 2800 INFO(PRI_SEGMENTED_IPv6_ADDR_SRP ": wins by being first.", 2801 SEGMENTED_IPv6_ADDR_PARAM_SRP(addr, addr_buf)); 2802 } 2803 in6addr_copy(&route_state->proposed_srp_listener_address, addr); 2804 route_state->have_proposed_srp_listener_address = true; 2805 } 2806 } 2807 } 2808 } else { 2809 INFO(PRI_SEGMENTED_IPv6_ADDR_SRP ": removed.", SEGMENTED_IPv6_ADDR_PARAM_SRP(addr, addr_buf)); 2810 } 2811 } 2812 2813 static void 2814 partition_utun0_pick_listener_address(route_state_t *route_state) 2815 { 2816 if (route_state->have_mesh_local_prefix && route_state->advertising_srp_anycast_service && 2817 route_state->have_non_thread_interface && route_state->have_proposed_srp_listener_address) 2818 { 2819 if (route_state->srp_listener == NULL) { 2820 SEGMENTED_IPv6_ADDR_GEN_SRP(&route_state->proposed_srp_listener_address, addr_buf); 2821 INFO("starting listener on" PRI_SEGMENTED_IPv6_ADDR_SRP, 2822 SEGMENTED_IPv6_ADDR_PARAM_SRP(&route_state->proposed_srp_listener_address, addr_buf)); 2823 2824 // Copy the winning proposed listener IP address to the listener IP address 2825 in6addr_copy(&route_state->srp_listener_ip_address, &route_state->proposed_srp_listener_address); 2826 2827 // Set up a listener. 2828 route_state->srp_service_listen_port = 0; 2829 partition_start_srp_listener(route_state); 2830 } else { 2831 SEGMENTED_IPv6_ADDR_GEN_SRP(&route_state->srp_listener_ip_address, addr_buf); 2832 if (!route_state->seen_listener_address) { 2833 FAULT("didn't see listener address " PRI_SEGMENTED_IPv6_ADDR_SRP, 2834 SEGMENTED_IPv6_ADDR_PARAM_SRP(&route_state->srp_listener_ip_address, addr_buf)); 2835 } else { 2836 INFO("already listening on" PRI_SEGMENTED_IPv6_ADDR_SRP, 2837 SEGMENTED_IPv6_ADDR_PARAM_SRP(&route_state->srp_listener_ip_address, addr_buf)); 2838 } 2839 } 2840 } else { 2841 INFO(PUB_S_SRP "advertising anycast service; " PUB_S_SRP " proposed listener address; " 2842 PUB_S_SRP " non-thread interface; " PUB_S_SRP " mesh-local prefix; " PUB_S_SRP " listener", 2843 route_state->advertising_srp_anycast_service ? "" : "not ", 2844 route_state->have_proposed_srp_listener_address ? "have" : "no", 2845 route_state->have_non_thread_interface ? "have" : "no", 2846 route_state->have_mesh_local_prefix ? "have" : "no", 2847 route_state->srp_listener != NULL ? "have" : "no"); 2848 // In common cases, if we are not advertising anycast service due to replication failure, 2849 // we can not advertise unicast either. One exception is that we manually block the anycast 2850 // service for testing purpose. Unicast service should not be affected in this case. 2851 if (route_state->srp_listener != NULL && !route_state->advertising_srp_anycast_service && 2852 !route_state->srp_server->srp_anycast_service_blocked) { 2853 SEGMENTED_IPv6_ADDR_GEN_SRP(&route_state->srp_listener_ip_address, addr_buf); 2854 INFO(PRI_SEGMENTED_IPv6_ADDR_SRP ": canceling listener.", 2855 SEGMENTED_IPv6_ADDR_PARAM_SRP(&route_state->srp_listener_ip_address, addr_buf)); 2856 partition_discontinue_srp_service(route_state); 2857 } 2858 } 2859 2860 // Clear all of the election state. 2861 route_state->seen_listener_address = false; 2862 route_state->have_proposed_srp_listener_address = false; 2863 in6addr_zero(&route_state->proposed_srp_listener_address); 2864 } 2865 2866 static void 2867 partition_got_tunnel_name(route_state_t *route_state) 2868 { 2869 route_state->partition_tunnel_name_is_known = true; 2870 for (interface_t *interface = route_state->interfaces; interface; interface = interface->next) { 2871 if (!strcmp(interface->name, route_state->thread_interface_name)) { 2872 interface->is_thread = true; 2873 break; 2874 } 2875 } 2876 route_refresh_interface_list(route_state); 2877 } 2878 2879 static void 2880 partition_remove_service_done(void *context, cti_status_t status) 2881 { 2882 route_state_t *route_state = context; 2883 INFO("%d", status); 2884 2885 // Flush any advertisements we're currently doing, since the accessories that advertised them will 2886 // notice the service is gone and start advertising with a different service. 2887 #if defined(SRP_FEATURE_REPLICATION) 2888 if (!route_state->srp_server->srp_replication_enabled) { 2889 #endif 2890 srp_mdns_flush(route_state->srp_server); 2891 #if defined(SRP_FEATURE_REPLICATION) 2892 } 2893 #endif 2894 } 2895 2896 static bool 2897 route_maybe_restart_service_tracker(route_state_t *route_state, int *reset, int *increment) 2898 { 2899 *reset = 0; 2900 (*increment)++; 2901 if (*increment > 5) { 2902 if (route_state->srp_server->service_tracker != NULL) { 2903 service_tracker_start(route_state->srp_server->service_tracker); 2904 } else { 2905 FAULT("service tracker not present when restarting."); 2906 } 2907 *increment = 0; 2908 return true; 2909 } 2910 return false; 2911 } 2912 2913 static void 2914 partition_stop_advertising_service(route_state_t *route_state) 2915 { 2916 // This should remove any copy of the service that this BR is advertising. 2917 INFO("%" PRIu64 "/%x", THREAD_ENTERPRISE_NUMBER, THREAD_SRP_SERVER_OPTION); 2918 uint8_t service_info[] = { 0, 0, 0, 1 }; 2919 int status; 2920 2921 if (route_maybe_restart_service_tracker(route_state, &route_state->times_advertised_unicast, &route_state->times_unadvertised_unicast)) { 2922 INFO("restarted service tracker."); 2923 } 2924 service_info[0] = THREAD_SRP_SERVER_OPTION & 255; 2925 status = cti_remove_service(route_state->srp_server, route_state, partition_remove_service_done, NULL, 2926 THREAD_ENTERPRISE_NUMBER, service_info, 1); 2927 if (status != kCTIStatus_NoError) { 2928 INFO("status %d", status); 2929 } 2930 route_state->advertising_srp_unicast_service = false; 2931 } 2932 2933 void 2934 partition_stop_advertising_anycast_service(route_state_t *route_state, uint8_t sequence_number) 2935 { 2936 // This should remove any copy of the service that this BR is advertising. 2937 INFO("%" PRIu64 "/%x %x", THREAD_ENTERPRISE_NUMBER, THREAD_SRP_SERVER_ANYCAST_OPTION, sequence_number); 2938 uint8_t service_info[] = { 0, 0, 0, 1 }; 2939 int status; 2940 2941 if (route_maybe_restart_service_tracker(route_state, &route_state->times_advertised_anycast, &route_state->times_unadvertised_anycast)) { 2942 INFO("restarted service tracker."); 2943 } 2944 service_info[0] = THREAD_SRP_SERVER_ANYCAST_OPTION & 255; 2945 service_info[1] = sequence_number; 2946 status = cti_remove_service(route_state->srp_server, route_state, partition_remove_service_done, NULL, 2947 THREAD_ENTERPRISE_NUMBER, service_info, 2); 2948 if (status != kCTIStatus_NoError) { 2949 INFO("status %d", status); 2950 } 2951 route_state->advertising_srp_anycast_service = false; 2952 if (route_state->route_tracker != NULL) { 2953 INFO("discontinuing route tracker"); 2954 route_tracker_cancel(route_state->route_tracker); 2955 route_tracker_release(route_state->route_tracker); 2956 route_state->route_tracker = NULL; 2957 } 2958 route_refresh_interface_list(route_state); 2959 } 2960 2961 static void 2962 partition_add_service_callback(void *context, cti_status_t status) 2963 { 2964 route_state_t *UNUSED route_state = context; 2965 if (status != kCTIStatus_NoError) { 2966 INFO("status = %d", status); 2967 } else { 2968 INFO("status = %d", status); 2969 } 2970 } 2971 2972 static void 2973 partition_start_advertising_service(route_state_t *route_state) 2974 { 2975 uint8_t service_info[] = {0, 0, 0, 1}; 2976 uint8_t server_info[18]; 2977 int ret; 2978 2979 if (route_maybe_restart_service_tracker(route_state, &route_state->times_unadvertised_unicast, &route_state->times_advertised_unicast)) { 2980 INFO("restarted service tracker."); 2981 } 2982 memcpy(&server_info, &route_state->srp_listener_ip_address, 16); 2983 server_info[16] = (route_state->srp_service_listen_port >> 8) & 255; 2984 server_info[17] = route_state->srp_service_listen_port & 255; 2985 2986 SEGMENTED_IPv6_ADDR_GEN_SRP(route_state->srp_listener_ip_address.s6_addr, server_ip_buf); 2987 service_info[0] = THREAD_SRP_SERVER_OPTION & 255; 2988 INFO("%" PRIu64 "/%02x/" PRI_SEGMENTED_IPv6_ADDR_SRP ":%d" , 2989 THREAD_ENTERPRISE_NUMBER, service_info[0], 2990 SEGMENTED_IPv6_ADDR_PARAM_SRP(route_state->srp_listener_ip_address.s6_addr, server_ip_buf), 2991 route_state->srp_service_listen_port); 2992 2993 ret = cti_add_service(route_state->srp_server, route_state, partition_add_service_callback, NULL, 2994 THREAD_ENTERPRISE_NUMBER, service_info, 1, server_info, sizeof server_info); 2995 if (ret != kCTIStatus_NoError) { 2996 INFO("status %d", ret); 2997 } 2998 2999 // Wait a while for the service add to be reflected in an event. 3000 partition_schedule_service_add_wakeup(route_state); 3001 route_state->advertising_srp_unicast_service = true; 3002 } 3003 3004 static void 3005 partition_start_advertising_anycast_service(route_state_t *route_state) 3006 { 3007 uint8_t service_info[] = {0, 0, 0, 1}; 3008 int ret; 3009 3010 if (route_maybe_restart_service_tracker(route_state, &route_state->times_unadvertised_anycast, &route_state->times_advertised_anycast)) { 3011 INFO("restarted service tracker."); 3012 } 3013 service_info[0] = THREAD_SRP_SERVER_ANYCAST_OPTION & 255; 3014 service_info[1] = route_state->thread_sequence_number; 3015 INFO("%" PRIu64 "/%02x/ %x", THREAD_ENTERPRISE_NUMBER, service_info[0], route_state->thread_sequence_number); 3016 3017 ret = cti_add_service(route_state->srp_server, route_state, partition_add_service_callback, NULL, 3018 THREAD_ENTERPRISE_NUMBER, service_info, 2, NULL, 0); 3019 if (ret != kCTIStatus_NoError) { 3020 INFO("status %d", ret); 3021 } 3022 3023 // Wait a while for the service add to be reflected in an event. 3024 partition_schedule_anycast_service_add_wakeup(route_state); 3025 route_state->advertising_srp_anycast_service = true; 3026 route_refresh_interface_list(route_state); 3027 3028 if (route_state->route_tracker == NULL) { 3029 route_state->route_tracker = route_tracker_create(route_state, "main"); 3030 if (route_state->route_tracker == NULL) { 3031 ERROR("route_tracker create failed"); 3032 return; 3033 } 3034 route_tracker_set_reconnect_callback(route_state->route_tracker, attempt_wpan_reconnect); 3035 route_tracker_start(route_state->route_tracker); 3036 } else { 3037 INFO("route tracker already running."); 3038 } 3039 } 3040 3041 static void 3042 partition_service_add_wakeup(void *context) 3043 { 3044 route_state_t *route_state = context; 3045 route_state->partition_service_last_add_time = 0; 3046 partition_maybe_advertise_service(route_state); 3047 } 3048 3049 static void 3050 partition_anycast_service_add_wakeup(void *context) 3051 { 3052 route_state_t *route_state = context; 3053 route_state->partition_service_last_add_time = 0; 3054 partition_maybe_advertise_anycast_service(route_state); 3055 } 3056 3057 static void 3058 partition_schedule_service_add_wakeup(route_state_t *route_state) 3059 { 3060 if (route_state->partition_service_add_pending_wakeup == NULL) { 3061 route_state->partition_service_add_pending_wakeup = ioloop_wakeup_create(); 3062 if (route_state->partition_service_add_pending_wakeup == NULL) { 3063 ERROR("Can't schedule service add pending wakeup: no memory!"); 3064 return; 3065 } 3066 } else { 3067 ioloop_cancel_wake_event(route_state->partition_service_add_pending_wakeup); 3068 } 3069 // Wait thirty seconds. 3070 ioloop_add_wake_event(route_state->partition_service_add_pending_wakeup, route_state, 3071 partition_service_add_wakeup, NULL, 30 * 1000); 3072 } 3073 3074 static void 3075 partition_schedule_anycast_service_add_wakeup(route_state_t *route_state) 3076 { 3077 if (route_state->partition_anycast_service_add_pending_wakeup == NULL) { 3078 route_state->partition_anycast_service_add_pending_wakeup = ioloop_wakeup_create(); 3079 if (route_state->partition_anycast_service_add_pending_wakeup == NULL) { 3080 ERROR("Can't schedule anycast service add pending wakeup: no memory!"); 3081 return; 3082 } 3083 } else { 3084 ioloop_cancel_wake_event(route_state->partition_anycast_service_add_pending_wakeup); 3085 } 3086 // Wait thirty seconds. 3087 ioloop_add_wake_event(route_state->partition_anycast_service_add_pending_wakeup, route_state, 3088 partition_anycast_service_add_wakeup, NULL, 30 * 1000); 3089 } 3090 3091 static void 3092 partition_maybe_advertise_service(route_state_t *route_state) 3093 { 3094 thread_service_t *service; 3095 int num_lower_services = 0; 3096 int num_other_services = 0; 3097 int num_legacy_services = 0; 3098 int i; 3099 int64_t last_add_time; 3100 bool advertising_service = false; 3101 3102 // If we aren't ready to advertise a service, there's nothing to do. 3103 if (!route_state->partition_can_advertise_service) { 3104 INFO("no service to advertise yet."); 3105 return; 3106 } 3107 3108 if (route_state->srp_server->srp_unicast_service_blocked) { 3109 INFO("service advertising is disabled."); 3110 return; 3111 } 3112 3113 for (i = 0; i < 16; i++) { 3114 if (route_state->srp_listener_ip_address.s6_addr[i] != 0) { 3115 break; 3116 } 3117 } 3118 if (i == 16) { 3119 INFO("no listener."); 3120 return; 3121 } 3122 3123 // The add service function requires a remove prior to the add, so if we are doing an add, we need to wait 3124 // for things to stabilize before allowing the removal of a service to trigger a re-evaluation. 3125 // Therefore, if we've done an add in the past ten seconds, wait ten seconds before trying another add. 3126 last_add_time = ioloop_timenow() - route_state->partition_service_last_add_time; 3127 INFO("last_add_time = %" PRId64, last_add_time); 3128 if (last_add_time < 10 * 1000) { 3129 schedule_wakeup: 3130 partition_schedule_service_add_wakeup(route_state); 3131 return; 3132 } 3133 3134 // Count how many services are numerically lower than the listener address 3135 for (service = service_tracker_services_get(route_state->srp_server->service_tracker); 3136 service; service = service->next) 3137 { 3138 if (service->ignore || service->service_type != unicast_service) { 3139 continue; 3140 } 3141 3142 if ((service->user || (route_state->have_rloc16 && service->rloc16 == route_state->srp_server->rloc16)) && 3143 (in6addr_compare(&service->u.unicast.address, &route_state->srp_listener_ip_address) || 3144 ((service->u.unicast.port[0] << 8) | service->u.unicast.port[1]) != route_state->srp_service_listen_port)) 3145 { 3146 thread_service_note("Rtr0", service, "is ours, but stale"); 3147 partition_stop_advertising_service(route_state); 3148 goto schedule_wakeup; 3149 } 3150 3151 // See if host advertising this unicast service is also advertising an anycast service; if not, then this 3152 // unicast service doesn't count (much). 3153 bool anycast_present = false; 3154 for (thread_service_t *aservice = service_tracker_services_get(route_state->srp_server->service_tracker); 3155 aservice != NULL; aservice = aservice->next) 3156 { 3157 if (aservice->ignore || aservice->service_type != anycast_service) { 3158 continue; 3159 } 3160 if (service->rloc16 == aservice->rloc16) { 3161 anycast_present = true; 3162 break; 3163 } 3164 } 3165 if (!anycast_present) { 3166 num_legacy_services++; 3167 route_state->seen_legacy_service = true; 3168 continue; 3169 } 3170 3171 int cmp = in6addr_compare(&service->u.unicast.address, &route_state->srp_listener_ip_address); 3172 SEGMENTED_IPv6_ADDR_GEN_SRP(&service->u.unicast.address, addr_buf); 3173 INFO(PUB_S_SRP PRI_SEGMENTED_IPv6_ADDR_SRP ": is " PUB_S_SRP " listener address.", 3174 anycast_present ? "legacy service " : "service ", 3175 SEGMENTED_IPv6_ADDR_PARAM_SRP(&service->u.unicast.address, addr_buf), 3176 cmp < 0 ? "less than" : cmp > 0 ? "greater than" : "equal to"); 3177 if (cmp < 0) { 3178 num_lower_services++; 3179 } else if (cmp == 0) { 3180 advertising_service = true; 3181 } else { 3182 num_other_services++; 3183 } 3184 } 3185 3186 // We only want to advertise our service if there are no services being advertised on addresses that are lower than 3187 // ours. Also, if we notice that a service is being advertised by our rloc16 with a different IP address than the 3188 // listener address, it's a stale address, so remove it. If we have seen a legacy service, and there is only one 3189 // other non-legacy service, continue to advertise a second service, since cooperating services are preferable. 3190 if ((num_lower_services > 0 && !route_state->seen_legacy_service) || num_lower_services > 1) { 3191 if (advertising_service) { 3192 SEGMENTED_IPv6_ADDR_GEN_SRP(&route_state->srp_listener_ip_address, addr_buf); 3193 INFO(PRI_SEGMENTED_IPv6_ADDR_SRP ": stopping advertising unicast service.", 3194 SEGMENTED_IPv6_ADDR_PARAM_SRP(&route_state->srp_listener_ip_address, addr_buf)); 3195 partition_stop_advertising_service(route_state); 3196 route_state->partition_service_last_add_time = ioloop_timenow(); 3197 } else { 3198 INFO("not advertising unicast service."); 3199 } 3200 } 3201 // If there is not some other service published, and we are not publishing, publish. If there is a legacy (no 3202 // anycast) service published, publish a second service so as to encourage the legacy service to withdraw, because 3203 // cooperating services are preferable to competing services. 3204 else if (num_other_services < 1 || (num_other_services < 2 && route_state->seen_legacy_service)) { 3205 if (num_legacy_services > 1 && num_other_services > 1) { 3206 ERROR("%d legacy services present!", num_legacy_services); 3207 } else if (!advertising_service) { 3208 SEGMENTED_IPv6_ADDR_GEN_SRP(&route_state->srp_listener_ip_address, addr_buf); 3209 INFO(PRI_SEGMENTED_IPv6_ADDR_SRP ": starting advertising unicast service.", 3210 SEGMENTED_IPv6_ADDR_PARAM_SRP(&route_state->srp_listener_ip_address, addr_buf)); 3211 partition_start_advertising_service(route_state); 3212 route_state->partition_service_last_add_time = ioloop_timenow(); 3213 } else { 3214 INFO("already advertising unicast service."); 3215 } 3216 } 3217 // There is some other service published. 3218 else { 3219 INFO("another service is present, no need to advertise."); 3220 } 3221 } 3222 3223 void 3224 partition_maybe_advertise_anycast_service(route_state_t *route_state) 3225 { 3226 int64_t last_add_time; 3227 bool publish = false; 3228 3229 // If we aren't ready to advertise a service, there's nothing to do. 3230 if (!route_state->have_non_thread_interface) { 3231 INFO("no active interface."); 3232 return; 3233 } 3234 3235 if (!route_state->partition_can_advertise_service) { 3236 INFO("service advertisements are blocked."); 3237 return; 3238 } 3239 3240 if (!route_state->partition_can_advertise_anycast_service) { 3241 INFO("no service to advertise yet."); 3242 return; 3243 } 3244 3245 if (route_state->srp_server->srp_anycast_service_blocked) { 3246 INFO("service advertising is disabled."); 3247 return; 3248 } 3249 3250 if (route_state->num_thread_prefixes == 0) { 3251 INFO("OMR prefix is not yet advertised."); 3252 return; 3253 } 3254 3255 // The add service function requires a remove prior to the add, so if we are doing an add, we need to wait 3256 // for things to stabilize before allowing the removal of a service to trigger a re-evaluation. 3257 // Therefore, if we've done an add in the past ten seconds, wait ten seconds before trying another add. 3258 last_add_time = ioloop_timenow() - route_state->partition_service_last_add_time; 3259 INFO("last_add_time = %" PRId64, last_add_time); 3260 if (last_add_time < 10 * 1000) { 3261 schedule_wakeup: 3262 partition_schedule_anycast_service_add_wakeup(route_state); 3263 return; 3264 } 3265 3266 // Find the highest (two's complement math) sequence number 3267 uint8_t winning_seq = route_state->thread_sequence_number; 3268 for (thread_service_t *service = service_tracker_services_get(route_state->srp_server->service_tracker); service; 3269 service = service->next) 3270 { 3271 if (service->service_type != anycast_service) { 3272 continue; 3273 } 3274 struct thread_anycast_service *aservice = &service->u.anycast; 3275 // Eliminate stale services before doing anything else. 3276 if ((service->user || (route_state->have_rloc16 && service->rloc16 == route_state->srp_server->rloc16)) && 3277 (aservice->sequence_number != route_state->thread_sequence_number || 3278 !route_state->advertising_srp_anycast_service)) 3279 { 3280 thread_service_note("Rtr0", service, "is ours, but stale"); 3281 partition_stop_advertising_anycast_service(route_state, aservice->sequence_number); 3282 goto schedule_wakeup; 3283 } 3284 #ifdef PING_ANYCAST_SERVICE 3285 if (service->ignore) { 3286 continue; 3287 } 3288 route_ping_aservice(route_state, service); 3289 #endif 3290 uint8_t service_seq = aservice->sequence_number; 3291 int8_t distance = service_seq - winning_seq; 3292 if (distance > 0) { 3293 winning_seq = service_seq; 3294 } 3295 if (distance == -128) { 3296 if ((int8_t)service_seq > (int8_t)winning_seq) { 3297 winning_seq = service_seq; 3298 } 3299 } 3300 } 3301 3302 if (winning_seq != route_state->thread_sequence_number) { 3303 INFO("our sequence number (0x%02x) loses the election to 0x%02x", route_state->thread_sequence_number, winning_seq); 3304 goto publication; 3305 } 3306 3307 // Count how many services on our anycast sequence number have lower RLOCs 3308 int num_less = 0; 3309 for (thread_service_t *service = service_tracker_services_get(route_state->srp_server->service_tracker); service; 3310 service = service->next) 3311 { 3312 struct thread_anycast_service *aservice = &service->u.anycast; 3313 if (aservice->sequence_number == winning_seq) { 3314 if (service->rloc16 < route_state->srp_server->rloc16) { 3315 num_less++; 3316 } 3317 } 3318 } 3319 3320 if (num_less >= MAX_ANYCAST_NUM) { 3321 INFO("our sequence number (0x%02x) wins, but there are %d other services published already", 3322 route_state->thread_sequence_number, num_less); 3323 goto publication; 3324 } 3325 3326 INFO("our sequence number (0x%02x) wins, and there are %d (<5) other services published already", 3327 route_state->thread_sequence_number, num_less); 3328 publish = true; 3329 publication: 3330 if (publish) { 3331 if (!route_state->advertising_srp_anycast_service) { 3332 INFO("advertising our anycast service with sequence number 0x%02x", route_state->thread_sequence_number); 3333 partition_start_advertising_anycast_service(route_state); 3334 route_state->partition_service_last_add_time = ioloop_timenow(); 3335 } else { 3336 INFO("already advertising our anycast service with sequence number 0x%x", 3337 route_state->thread_sequence_number); 3338 } 3339 } else { 3340 if (!route_state->advertising_srp_anycast_service) { 3341 INFO("not advertising our anycast service with sequence number 0x%02x", 3342 route_state->thread_sequence_number); 3343 } else { 3344 INFO("withdrawing our anycast service advertisement with sequence number 0x%02x", 3345 route_state->thread_sequence_number); 3346 partition_stop_advertising_anycast_service(route_state, route_state->thread_sequence_number); 3347 route_state->partition_service_last_add_time = ioloop_timenow(); 3348 } 3349 } 3350 } 3351 3352 static void 3353 partition_service_set_changed_callback(void *context) 3354 { 3355 route_state_t *route_state = context; 3356 service_tracker_t *tracker = route_state->srp_server->service_tracker; 3357 3358 // If we discover an advertised service with our rloc, but listening address or port does not 3359 // match, we need to remove it. 3360 for (thread_service_t *service = service_tracker_services_get(tracker); service != NULL; service = service->next) { 3361 if (service->ignore) { 3362 continue; 3363 } 3364 if (service->service_type == unicast_service) { 3365 if (service->user || (route_state->srp_server->have_rloc16 && service->rloc16 == route_state->srp_server->rloc16)) { 3366 uint16_t port = (service->u.unicast.port[0] << 8) | service->u.unicast.port[1]; 3367 if (in6addr_compare(&service->u.unicast.address, &route_state->srp_listener_ip_address) || 3368 port != route_state->srp_service_listen_port) 3369 { 3370 service_tracker_thread_service_note(tracker, service, "is ours, but stale"); 3371 partition_stop_advertising_service(route_state); 3372 service->ignore = true; 3373 } 3374 } 3375 } else if (service->service_type == anycast_service) { 3376 // If we discover an advertised service with our rloc, and either we aren't advertising an anycast service, 3377 // or the sequence number isn't the one we're supposed to be advertising, we need to remove it. 3378 if ((service->user || (route_state->srp_server->have_rloc16 && service->rloc16 == route_state->srp_server->rloc16)) && 3379 (!route_state->advertising_srp_anycast_service || 3380 service->u.anycast.sequence_number != route_state->thread_sequence_number)) 3381 { 3382 service_tracker_thread_service_note(tracker, service, "is ours, but stale"); 3383 partition_stop_advertising_anycast_service(route_state, service->u.anycast.sequence_number); 3384 service->ignore = true; 3385 } 3386 } 3387 } 3388 3389 partition_maybe_advertise_service(route_state); 3390 partition_maybe_advertise_anycast_service(route_state); 3391 } 3392 3393 static void 3394 partition_service_set_changed(void *context) 3395 { 3396 route_state_t *route_state = context; 3397 if (route_state->service_set_changed_wakeup == NULL) { 3398 route_state->service_set_changed_wakeup = ioloop_wakeup_create(); 3399 if (route_state->service_set_changed_wakeup == NULL) { 3400 ERROR("Can't schedule service list change wakeup: no memory!"); 3401 return; 3402 } 3403 } else { 3404 ioloop_cancel_wake_event(route_state->service_set_changed_wakeup); 3405 } 3406 int timeout = srp_random16() % 20000; // Randomly wait between zero and twenty seconds 3407 INFO("waiting %d milliseconds before processing service state change.", timeout); 3408 ioloop_add_wake_event(route_state->service_set_changed_wakeup, route_state, 3409 partition_service_set_changed_callback, NULL, timeout); 3410 } 3411 3412 static void partition_maybe_enable_services(route_state_t *route_state) 3413 { 3414 bool am_associated = route_state->current_thread_state == kCTI_NCPState_Associated; 3415 if (am_associated) { 3416 bool restart = false; 3417 INFO("Enabling service, which was disabled because of the thread role or state."); 3418 route_state->partition_may_offer_service = true; 3419 route_state->partition_can_provide_routing = true; 3420 route_refresh_interface_list(route_state); 3421 routing_policy_evaluate_all_interfaces(route_state, true); 3422 if (route_state->omr_watcher == NULL) { 3423 if (route_state->omr_publisher != NULL) { 3424 omr_publisher_cancel(route_state->omr_publisher); 3425 omr_publisher_release(route_state->omr_publisher); 3426 route_state->omr_publisher = NULL; 3427 } 3428 route_state->omr_watcher = omr_watcher_create(route_state, attempt_wpan_reconnect); 3429 if (route_state->omr_watcher == NULL) { 3430 ERROR("omr_watcher create failed"); 3431 return; 3432 } 3433 route_state->omr_watcher_callback = omr_watcher_callback_add(route_state->omr_watcher, 3434 route_omr_watcher_event, NULL, route_state); 3435 if (route_state->omr_watcher_callback == NULL) { 3436 ERROR("omr_watcher_callback add failed"); 3437 return; 3438 } 3439 restart = true; 3440 } 3441 if (route_state->omr_publisher == NULL) { 3442 route_state->omr_publisher = omr_publisher_create(route_state, "main"); 3443 if (route_state->omr_publisher == NULL) { 3444 ERROR("omr_publisher create failed"); 3445 return; 3446 } 3447 omr_publisher_set_omr_watcher(route_state->omr_publisher, route_state->omr_watcher); 3448 omr_publisher_set_reconnect_callback(route_state->omr_publisher, attempt_wpan_reconnect); 3449 restart = true; 3450 } 3451 if (restart) { 3452 omr_publisher_start(route_state->omr_publisher); 3453 omr_watcher_start(route_state->omr_watcher); 3454 } 3455 } else { 3456 INFO("Not enabling service: " PUB_S_SRP, 3457 am_associated ? "associated" : "!associated"); 3458 } 3459 } 3460 3461 static void partition_disable_service(route_state_t *route_state) 3462 { 3463 bool done_something = false; 3464 3465 // When our node type or state is such that we should no longer be publishing a prefix, the NCP will 3466 // automatically remove the published prefix. In case this happens, we do not want to remember the 3467 // prefix as already having been published. So drop our recollection of the published 3468 // prefix; this will get cleaned up when the network comes back if there's an inconsistency. 3469 if (route_state->omr_publisher != NULL) { 3470 omr_publisher_cancel(route_state->omr_publisher); 3471 omr_publisher_release(route_state->omr_publisher); 3472 route_state->omr_publisher = NULL; 3473 done_something = true; 3474 } 3475 if (route_state->omr_watcher != NULL) { 3476 if (route_state->omr_watcher_callback != NULL) { 3477 omr_watcher_callback_cancel(route_state->omr_watcher, route_state->omr_watcher_callback); 3478 route_state->omr_watcher_callback = NULL; 3479 } 3480 omr_watcher_cancel(route_state->omr_watcher); 3481 omr_watcher_release(route_state->omr_watcher); 3482 route_state->omr_watcher = NULL; 3483 done_something = true; 3484 } 3485 3486 // We want to always say something when we pass through this state. 3487 if (done_something) { 3488 INFO("did something"); 3489 } else { 3490 INFO("did nothing."); 3491 } 3492 3493 route_state->partition_may_offer_service = false; 3494 route_state->partition_can_provide_routing = false; 3495 } 3496 3497 void partition_block_anycast_service(route_state_t *route_state, bool block) 3498 { 3499 if (block) { 3500 if (!route_state->srp_server->srp_anycast_service_blocked) { 3501 route_state->srp_server->srp_anycast_service_blocked = block; 3502 partition_stop_advertising_anycast_service(route_state, route_state->thread_sequence_number); 3503 } 3504 } else { 3505 if (route_state->srp_server->srp_anycast_service_blocked) { 3506 route_state->srp_server->srp_anycast_service_blocked = block; 3507 partition_maybe_advertise_anycast_service(route_state); 3508 } 3509 } 3510 } 3511 3512 #endif // RA_TESTER 3513 3514 #if SRP_FEATURE_LOCAL_DISCOVERY 3515 int 3516 route_get_current_infra_interface_index(void) 3517 { 3518 extern srp_server_t *srp_servers; 3519 if (srp_servers == NULL) { 3520 INFO("no SRP servers"); 3521 return -1; 3522 } 3523 route_state_t *route_state = srp_servers->route_state; 3524 if (route_state == NULL) { 3525 INFO("no route state"); 3526 return -1; 3527 } 3528 for (interface_t *interface = route_state->interfaces; interface != NULL; interface = interface->next) { 3529 if (!interface->inactive && !interface->is_thread) { 3530 return (int)interface->index; // real interface indexes are always positive integers 3531 } 3532 } 3533 return -1; 3534 } 3535 #endif // SRP_FEATURE_LOCAL_DISCOVERY 3536 #endif // STUB_ROUTER 3537 3538 // Local Variables: 3539 // mode: C 3540 // tab-width: 4 3541 // c-file-style: "bsd" 3542 // c-basic-offset: 4 3543 // fill-column: 120 3544 // indent-tabs-mode: nil 3545 // End: 3546