From de0258e30ff9a251a81a8043406b2f30ccc80993 Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Tue, 2 May 2017 12:52:07 +0930 Subject: [PATCH] Remove route structures from memory when all links are down --- overlay_address.c | 6 ++++-- route_link.c | 25 +++++++++++++++++++------ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/overlay_address.c b/overlay_address.c index b28de9ba..2439f021 100644 --- a/overlay_address.c +++ b/overlay_address.c @@ -89,9 +89,11 @@ static int free_node(void **record, void *UNUSED(context)) { struct subscriber *subscriber = (struct subscriber *)*record; if (subscriber->link_state || subscriber->destination) - FATAL("Can't free a subscriber that is being used in routing"); + FATALF("Can't free a subscriber that is being used in routing (%s, %p, %p)", + alloca_tohex_sid_t(subscriber->sid), subscriber->link_state, subscriber->destination); if (subscriber->sync_state) - FATAL("Can't free a subscriber that is being used by rhizome"); + FATALF("Can't free a subscriber that is being used by rhizome (%s, %p)", + alloca_tohex_sid_t(subscriber->sid), subscriber->sync_state); if (subscriber->identity) FATAL("Can't free a subscriber that is unlocked in the keyring"); free(subscriber); diff --git a/route_link.c b/route_link.c index 52e6d38a..a1befbf0 100644 --- a/route_link.c +++ b/route_link.c @@ -505,18 +505,30 @@ struct append_context{ struct decode_context context; }; +static int free_subscriber_link_state(void **record, void *UNUSED(context)) +{ + struct subscriber *subscriber = *record; + + if (subscriber->reachable && !(subscriber->reachable & REACHABLE_SELF)) + set_reachable(subscriber, NULL, NULL, 99, NULL); + + if (subscriber->link_state){ + free(subscriber->link_state); + subscriber->link_state = NULL; + } + return 0; +} + static int append_link(void **record, void *context) { struct subscriber *subscriber = *record; + if (subscriber == get_my_subscriber(1)) return 0; struct link_state *state = get_link_state(subscriber); struct link *best_link = find_best_link(subscriber); - if (!context) - return 0; - struct append_context *append_context = context; time_ms_t now = gettime_ms(); @@ -596,7 +608,8 @@ static void clean_neighbours(time_ms_t now) while(*list){ struct link_in *link = *list; if (link->interface->state!=INTERFACE_STATE_UP || link->link_timeout < now){ - DEBUGF(linkstate, "LINK STATE; link expired from neighbour %s on interface %s", + DEBUGF(linkstate, "LINK STATE; %s link expired from neighbour %s on interface %s", + link->unicast? "unicast":"broadcast", alloca_tohex_sid_t(subscriber->sid), link->interface->name); *list=link->_next; @@ -634,8 +647,8 @@ static void clean_neighbours(time_ms_t now) neighbour_count--; CALL_TRIGGER(nbr_change, subscriber, 0, neighbour_count); if (neighbour_count==0){ - // one last re-scan of network paths to clean up the routing table - enum_subscribers(NULL, append_link, NULL); + // clean up the routing table + enum_subscribers(NULL, free_subscriber_link_state, NULL); RESCHEDULE(&ALARM_STRUCT(link_send), TIME_MS_NEVER_WILL, TIME_MS_NEVER_WILL, TIME_MS_NEVER_WILL); }