Lines Matching defs:publisher
1 /* omr-publisher.c
18 * prefix publisher state machine.
61 #include "service-publisher.h"
64 #include "omr-publisher.h"
101 omr_publisher_t *publisher = state_header->state_object
125 static void omr_publisher_discontinue_dhcp(omr_publisher_t *publisher);
126 static void omr_publisher_queue_prefix_update(omr_publisher_t *publisher, struct in6_addr *prefix_address,
131 omr_publisher_finalize(omr_publisher_t *publisher)
133 free(publisher->state_header.name);
134 free(publisher);
141 omr_publisher_t *publisher = context;
142 RELEASE_HERE(publisher, omr_publisher);
158 omr_publisher_t *publisher = context;
162 if (publisher->first_time && event_type == omr_watcher_event_prefix_added && prefix != NULL && prefix->user) {
165 if (publisher->published_prefix == NULL ||
166 in6addr_compare(&prefix->prefix, &publisher->published_prefix->prefix))
171 omr_publisher_queue_prefix_update(publisher, &prefix->prefix, omr_prefix_priority_low, false, want_delete);
188 state_machine_event_deliver(&publisher->state_header, event);
191 publisher->first_time = false;
196 omr_publisher_set_omr_watcher(omr_publisher_t *publisher, omr_watcher_t *watcher)
199 publisher->omr_watcher = watcher;
200 omr_watcher_retain(publisher->omr_watcher);
201 publisher->omr_watcher_callback = omr_watcher_callback_add(publisher->omr_watcher,
203 omr_publisher_context_release, publisher);
204 RETAIN_HERE(publisher, omr_publisher); // The omr watcher callback holds a reference to the publisher
208 void omr_publisher_set_reconnect_callback(omr_publisher_t *NONNULL publisher,
211 publisher->reconnect_callback = reconnect_callback;
215 omr_publisher_cancel(omr_publisher_t *publisher)
217 if (publisher->wakeup_timer != NULL) {
218 ioloop_cancel_wake_event(publisher->wakeup_timer);
219 ioloop_wakeup_release(publisher->wakeup_timer);
220 publisher->wakeup_timer = NULL;
222 if (publisher->omr_watcher_callback != NULL) {
223 omr_watcher_callback_cancel(publisher->omr_watcher, publisher->omr_watcher_callback);
224 publisher->omr_watcher_callback = NULL;
226 if (publisher->omr_watcher != NULL) {
227 omr_watcher_release(publisher->omr_watcher);
228 publisher->omr_watcher = NULL;
230 if (publisher->published_prefix != NULL) {
231 omr_publisher_unpublish_prefix(publisher);
233 if (publisher->dhcp_client) {
234 omr_publisher_discontinue_dhcp(publisher);
236 if (publisher->dhcp_interface != NULL) {
237 interface_release(publisher->dhcp_interface);
238 publisher->dhcp_interface = NULL;
240 state_machine_cancel(&publisher->state_header);
246 omr_publisher_t *ret = NULL, *publisher = calloc(1, sizeof(*publisher));
247 if (publisher == NULL) {
248 return publisher;
250 RETAIN_HERE(publisher, omr_publisher);
251 publisher->wakeup_timer = ioloop_wakeup_create();
252 if (publisher->wakeup_timer == NULL) {
257 if (!state_machine_header_setup(&publisher->state_header,
258 publisher, name,
266 publisher->route_state = route_state;
269 publisher->first_time = true;
270 publisher->min_start = OMR_PUBLISHER_MIN_START;
272 ret = publisher;
273 publisher = NULL;
275 if (publisher != NULL) {
276 RELEASE_HERE(publisher, omr_publisher);
282 omr_publisher_start(omr_publisher_t *publisher)
284 state_machine_next_state(&publisher->state_header, omr_publisher_state_startup);
288 omr_publisher_force_publication(omr_publisher_t *publisher, omr_prefix_priority_t priority)
290 publisher->force_publication = true;
291 if (publisher->state_header.state == omr_publisher_state_publishing_dhcp ||
292 publisher->state_header.state == omr_publisher_state_publishing_ula)
299 publisher->force_publication = true;
300 publisher->force_priority = priority;
301 state_machine_next_state(&publisher->state_header, omr_publisher_state_publishing_ula);
305 omr_publisher_published_prefix_get(omr_publisher_t *publisher)
307 return publisher->published_prefix;
313 omr_publisher_t *publisher = context;
319 state_machine_event_deliver(&publisher->state_header, event);
326 omr_publisher_t *publisher = context;
327 RELEASE_HERE(publisher, omr_publisher);
331 omr_publisher_send_dhcp_event(omr_publisher_t *publisher, struct in6_addr *prefix, int prefix_length, uint32_t preferred_lifetime)
339 SEGMENTED_IPv6_ADDR_GEN_SRP(&publisher->dhcp_prefix.s6_addr, prefix_buf);
341 SEGMENTED_IPv6_ADDR_PARAM_SRP(&publisher->dhcp_prefix.s6_addr, prefix_buf),
342 publisher->dhcp_prefix_length, preferred_lifetime);
343 in6addr_zero(&publisher->new_dhcp_prefix);
348 publisher->new_dhcp_prefix = *prefix;
350 publisher->new_dhcp_prefix_length = prefix_length;
351 publisher->new_dhcp_preferred_lifetime = preferred_lifetime;
352 state_machine_event_deliver(&publisher->state_header, event);
358 omr_publisher_initiate_dhcp(omr_publisher_t *publisher)
360 if (!publisher->dhcp_blocked) {
361 publisher->dhcp_wanted = true;
363 publisher->dhcp_client = (void *)-1;
367 omr_publisher_interface_configuration_changed(omr_publisher_t *publisher)
370 if (publisher->dhcp_interface != NULL) {
371 if (publisher->dhcp_interface->inactive || publisher->dhcp_interface->ineligible) {
373 if (publisher->dhcp_client != NULL) {
374 omr_publisher_dhcp_client_deactivate(publisher, (intptr_t)publisher->dhcp_client);
376 interface_release(publisher->dhcp_interface);
377 publisher->dhcp_interface = NULL;
380 if (publisher->dhcp_wanted && publisher->dhcp_client == NULL) {
382 omr_publisher_initiate_dhcp(publisher);
387 omr_publisher_discontinue_dhcp(omr_publisher_t *publisher)
390 omr_publisher_dhcp_client_deactivate(publisher, (intptr_t)publisher->dhcp_client);
391 publisher->dhcp_wanted = false;
395 omr_publisher_dhcp_prefix_available(omr_publisher_t *publisher)
397 if (publisher->new_dhcp_preferred_lifetime != 0 && publisher->new_dhcp_prefix_length <= 64) {
404 omr_publisher_dhcp_prefix_changed(omr_publisher_t *publisher)
406 if (publisher->new_dhcp_prefix_length != publisher->dhcp_prefix_length ||
407 publisher->new_dhcp_preferred_lifetime != publisher->dhcp_preferred_lifetime ||
408 in6addr_compare(&publisher->new_dhcp_prefix, &publisher->dhcp_prefix))
416 omr_publisher_dhcp_prefix_lost(omr_publisher_t *publisher)
418 if (publisher->new_dhcp_prefix_length == 0) {
425 omr_publisher_install_new_dhcp_prefix(omr_publisher_t *publisher)
427 publisher->dhcp_prefix = publisher->new_dhcp_prefix;
428 publisherpublisher->new_dhcp_prefix_length;
429 publisher->dhcp_preferred_lifetime = publisher->new_dhcp_preferred_lifetime;
433 omr_publisher_prefix_init_from_published(omr_publisher_t *publisher, struct in6_addr *prefix, int *prefix_length)
435 if (publisher->published_prefix != NULL) {
436 in6addr_copy(prefix, &publisher->published_prefix->prefix);
437 *prefix_length = publisher->published_prefix->prefix_length;
445 omr_publisher_prefix_present(omr_publisher_t *publisher, omr_prefix_priority_t priority)
449 if (publisher->omr_watcher == NULL) {
450 FAULT("expecting an omr_watcher to be on the publisher");
453 omr_publisher_prefix_init_from_published(publisher, &prefix, &prefix_length);
454 return omr_watcher_prefix_present(publisher->omr_watcher, priority, &prefix, prefix_length);
458 omr_publisher_high_prefix_present(omr_publisher_t *publisher)
460 bool ret = omr_publisher_prefix_present(publisher, omr_prefix_priority_high);
462 INFO("setting publisher->omr_priority to high");
463 publisher->omr_priority = omr_prefix_priority_high;
469 omr_publisher_medium_prefix_present(omr_publisher_t *publisher)
471 bool ret = omr_publisher_prefix_present(publisher, omr_prefix_priority_medium);
473 INFO("setting publisher->omr_priority to medium");
474 publisher->omr_priority = omr_prefix_priority_medium;
480 omr_publisher_medium_or_high_prefix_present(omr_publisher_t *publisher)
482 return omr_publisher_medium_prefix_present(publisher) || omr_publisher_high_prefix_present(publisher);
486 omr_publisher_low_prefix_present(omr_publisher_t *publisher)
488 return omr_publisher_prefix_present(publisher, omr_prefix_priority_low);
492 omr_publisher_prefix_wins(omr_publisher_t *publisher, omr_prefix_priority_t priority)
496 if (publisher->omr_watcher == NULL) {
497 FAULT("expecting an omr_watcher to be on the publisher");
500 omr_publisher_prefix_init_from_published(publisher, &prefix, &prefix_length);
501 return omr_watcher_prefix_wins(publisher->omr_watcher, priority, &prefix, prefix_length);
505 omr_publisher_medium_prefix_wins(omr_publisher_t *publisher)
507 return omr_publisher_prefix_wins(publisher, omr_prefix_priority_medium);
511 omr_publisher_low_prefix_wins(omr_publisher_t *publisher)
513 return omr_publisher_prefix_wins(publisher, omr_prefix_priority_low);
517 omr_publisher_publishing_dhcp(omr_publisher_t *publisher)
519 if (publisher->state_header.state == omr_publisher_state_publishing_dhcp)
527 omr_publisher_publishing_ula(omr_publisher_t *publisher)
529 if (publisher->state_header.state == omr_publisher_state_publishing_ula)
537 omr_publisher_publishing_prefix(omr_publisher_t *publisher)
539 return omr_publisher_publishing_dhcp(publisher) ||
540 omr_publisher_publishing_ula(publisher);
543 static void omr_publisher_queue_run(omr_publisher_t *publisher);
548 omr_publisher_t *publisher = context;
549 omr_prefix_t *prefix = publisher->publication_queue;
562 if (publisher->omr_watcher != NULL) {
563 omr_watcher_prefix_add(publisher->omr_watcher, &prefix->prefix, prefix->prefix_length, prefix->priority);
567 if (publisher->omr_watcher != NULL) {
568 omr_watcher_prefix_remove(publisher->omr_watcher, &prefix->prefix, prefix->prefix_length);
578 publisher->publication_queue = prefix->next;
580 omr_publisher_queue_run(publisher);
581 RELEASE_HERE(publisher, omr_publisher);
585 omr_publisher_queue_run(omr_publisher_t *publisher)
587 omr_prefix_t *prefix = publisher->publication_queue;
590 // The queue just became empty, so release its reference to the publisher.
591 RELEASE_HERE(publisher, omr_publisher);
599 cti_status_t status = cti_remove_prefix(publisher->route_state->srp_server, publisher,
610 RETAIN_HERE(publisher, omr_publisher); // for the callback
616 cti_status_t status = cti_add_prefix(publisher->route_state->srp_server, publisher,
622 publisher->publication_queue = prefix->next;
626 RETAIN_HERE(publisher, omr_publisher); // for the callback
633 publisher->publication_queue = prefix->next;
639 omr_publisher_queue_prefix_update(omr_publisher_t *publisher, struct in6_addr *prefix_address,
644 omr_prefix_t *prefix, **ppref, *old_queue = publisher->publication_queue;
647 if (publisher->published_prefix != NULL) {
658 publisher->published_prefix = prefix;
659 omr_prefix_retain(publisher->published_prefix);
662 for (ppref = &publisher->publication_queue; *ppref != NULL; ppref = &(*ppref)->next)
666 // prefix as publisher->published_prefix, so that retain is always explicit and this retain is always implicit.
669 // If there is anything in the queue, the queue holds a reference to the publisher, so that it will continue to
671 if (old_queue == NULL && publisher->publication_queue != NULL) {
672 RETAIN_HERE(publisher, omr_publisher);
674 omr_publisher_queue_run(publisher);
678 omr_publisher_publish_prefix(omr_publisher_t *publisher,
684 omr_publisher_queue_prefix_update(publisher, prefix_address, priority, preferred, want_add);
685 INFO("setting publisher->omr_priority to %d, " PUB_S_SRP "preferred", omr_prefix_priority_to_int(priority),
687 publisher->omr_priority = priority;
691 omr_publisher_unpublish_prefix(omr_publisher_t *publisher)
695 prefix = publisher->published_prefix;
696 publisher->published_prefix = NULL;
704 omr_publisher_queue_prefix_update(publisher, &prefix->prefix, prefix->priority, false, want_delete);
709 omr_publisher_publish_dhcp_prefix(omr_publisher_t *publisher)
711 omr_publisher_install_new_dhcp_prefix(publisher);
712 omr_publisher_publish_prefix(publisher, &publisher->dhcp_prefix, omr_prefix_priority_medium,
713 publisher->dhcp_preferred_lifetime == 0 ? false : true);
714 publisher->dhcp_prefix_published = true;
719 omr_publisher_unpublish_dhcp_prefix(omr_publisher_t *publisher)
721 omr_publisher_unpublish_prefix(publisher);
722 publisher->dhcp_prefix_published = false;
727 omr_publisher_publish_ula_prefix(omr_publisher_t *publisher)
729 if (publisher->route_state == NULL || !publisher->route_state->have_thread_prefix) {
734 if (publisher->force_publication) {
735 priority = publisher->force_priority;
739 omr_publisher_publish_prefix(publisher, &publisher->route_state->my_thread_ula_prefix, priority, true);
740 publisher->ula_prefix_published = true;
745 omr_publisher_unpublish_ula_prefix(omr_publisher_t *publisher)
747 omr_publisher_unpublish_prefix(publisher);
748 publisher->ula_prefix_published = false;
753 omr_publisher_have_routable_prefix(omr_publisher_t *publisher)
755 if ((publisher->published_prefix != NULL && omr_watcher_prefix_is_non_ula_prefix(publisher->published_prefix)) ||
756 (publisher->omr_watcher != NULL && omr_watcher_non_ula_prefix_present(publisher->omr_watcher)))
766 omr_publisher_dhcp_event(omr_publisher_t *publisher, state_machine_event_t *UNUSED event)
769 if (omr_publisher_dhcp_prefix_available(publisher)) {
770 if (!omr_publisher_medium_or_high_prefix_present(publisher)) {
777 omr_publisher_discontinue_dhcp(publisher);
790 BR_STATE_ANNOUNCE(publisher, event);
793 publisher->omr_priority = omr_prefix_priority_invalid;
794 if (publisher->wakeup_timer == NULL) {
795 publisher->wakeup_timer = ioloop_wakeup_create();
797 if (publisher->wakeup_timer == NULL) {
801 ioloop_add_wake_event(publisher->wakeup_timer, publisher, omr_publisher_wait_expired,
803 publisher->min_start + srp_random16() % OMR_PUBLISHER_START_WAIT);
804 publisher->min_start = 0; // Only need mandatory 3-second startup delay when first joining Thread network.
805 RETAIN_HERE(publisher, omr_publisher); // For wakeup
814 BR_UNEXPECTED_EVENT(publisher, event);
826 BR_STATE_ANNOUNCE(publisher, event);
829 if (publisher->wakeup_timer != NULL) {
830 ioloop_cancel_wake_event(publisher->wakeup_timer);
832 publisher->wakeup_timer = ioloop_wakeup_create();
834 if (publisher->wakeup_timer == NULL) {
838 ioloop_add_wake_event(publisher->wakeup_timer, publisher, omr_publisher_wait_expired,
840 RETAIN_HERE(publisher, omr_publisher); // for the wakeup timer
841 if (publisher->dhcp_client == NULL) {
842 omr_publisher_initiate_dhcp(publisher);
849 if (omr_publisher_low_prefix_present(publisher)) {
851 publisher->omr_priority = omr_prefix_priority_low;
853 } else if (omr_publisher_medium_or_high_prefix_present(publisher)) {
855 omr_publisher_discontinue_dhcp(publisher);
860 if (omr_publisher_medium_or_high_prefix_present(publisher)) {
863 if (publisher->dhcp_client != NULL) {
864 omr_publisher_discontinue_dhcp(publisher);
867 } else if (omr_publisher_low_prefix_present(publisher)) {
869 publisher->omr_priority = omr_prefix_priority_low;
875 return omr_publisher_dhcp_event(publisher, event);
877 BR_UNEXPECTED_EVENT(publisher, event);
885 BR_STATE_ANNOUNCE(publisher, event);
888 if (publisher->wakeup_timer != NULL) {
889 ioloop_cancel_wake_event(publisher->wakeup_timer);
893 if (!omr_publisher_medium_or_high_prefix_present(publisher)) {
894 if (publisher->dhcp_client == NULL) {
897 } else if (!omr_publisher_low_prefix_present(publisher)) {
903 if (publisher->dhcp_client != NULL) {
904 omr_publisher_discontinue_dhcp(publisher);
910 return omr_publisher_dhcp_event(publisher, event);
912 BR_UNEXPECTED_EVENT(publisher, event);
925 BR_STATE_ANNOUNCE(publisher, event);
928 omr_publisher_publish_dhcp_prefix(publisher);
931 if (omr_publisher_high_prefix_present(publisher)) {
933 omr_publisher_unpublish_dhcp_prefix(publisher);
934 omr_publisher_discontinue_dhcp(publisher);
936 } else if (omr_publisher_medium_prefix_present(publisher)) {
937 if (!omr_publisher_medium_prefix_wins(publisher)) {
939 omr_publisher_unpublish_dhcp_prefix(publisher);
940 omr_publisher_discontinue_dhcp(publisher);
947 if (omr_publisher_dhcp_prefix_lost(publisher)) {
949 omr_publisher_unpublish_dhcp_prefix(publisher);
951 } else if (omr_publisher_dhcp_prefix_changed(publisher)) {
953 omr_publisher_unpublish_dhcp_prefix(publisher);
954 omr_publisher_publish_dhcp_prefix(publisher);
959 BR_UNEXPECTED_EVENT(publisher, event);
973 BR_STATE_ANNOUNCE(publisher, event);
975 omr_publisher_publish_ula_prefix(publisher);
976 if (publisher->dhcp_client == NULL) {
978 omr_publisher_initiate_dhcp(publisher);
979 publisher->omr_priority = omr_prefix_priority_low;
983 if (publisher->force_publication) {
987 if (omr_publisher_medium_or_high_prefix_present(publisher)) {
989 omr_publisher_unpublish_ula_prefix(publisher);
991 } else if (omr_publisher_low_prefix_present(publisher)) {
992 if (!omr_publisher_low_prefix_wins(publisher)) {
994 omr_publisher_unpublish_ula_prefix(publisher);
995 publisher->omr_priority = omr_prefix_priority_low;
1002 if (publisher->force_publication) {
1005 } else if (omr_publisher_dhcp_prefix_available(publisher)) {
1007 omr_publisher_unpublish_ula_prefix(publisher);
1012 BR_UNEXPECTED_EVENT(publisher, event);
1017 omr_publisher_check_prefix(omr_publisher_t *publisher, struct in6_addr *prefix, int UNUSED len)
1019 if (publisher == NULL) {
1022 if (publisher->published_prefix == NULL) {
1026 if (!in6prefix_compare(&publisher->published_prefix->prefix, prefix, 8)) {
1027 if (!in6prefix_compare(&publisher->ula_prefix, prefix, 8)) {
1038 publisher->dhcp_wanted = false;
1039 publisher->dhcp_blocked = true;
1040 omr_publisher_dhcp_client_deactivate(publisher, (intptr_t)publisher->dhcp_client);
1041 omr_publisher_send_dhcp_event(publisher, NULL, 0, 0);