Free subscriber entries after all commands

This commit is contained in:
Jeremy Lakeman 2013-11-06 15:36:21 +10:30
parent b84925f4ed
commit 7629f24d3f
4 changed files with 45 additions and 7 deletions

View File

@ -250,6 +250,7 @@ int parseCommandLine(struct cli_context *context, const char *argv0, int argc, c
/* clean up after ourselves */ /* clean up after ourselves */
rhizome_close_db(); rhizome_close_db();
free_subscribers();
OUT(); OUT();
if (config.debug.timing) if (config.debug.timing)

View File

@ -46,7 +46,7 @@ static struct broadcast bpilist[MAX_BPIS];
// each slot either points to another tree node or a struct subscriber. // each slot either points to another tree node or a struct subscriber.
struct tree_node{ struct tree_node{
// bit flags for the type of object each element points to // bit flags for the type of object each element points to
int is_tree; uint16_t is_tree;
union{ union{
struct tree_node *tree_nodes[16]; struct tree_node *tree_nodes[16];
@ -66,6 +66,42 @@ static unsigned char get_nibble(const unsigned char *sidp, int pos)
return byte&0xF; return byte&0xF;
} }
static void free_subscriber(struct subscriber *subscriber)
{
if (subscriber->link_state || subscriber->destination)
FATAL("Can't free a subscriber that is being used in routing");
if (subscriber->sync_state)
FATAL("Can't free a subscriber that is being used by rhizome");
if (subscriber->identity)
FATAL("Can't free a subscriber that is unlocked in the keyring");
free(subscriber);
}
static void free_children(struct tree_node *parent)
{
int i;
for (i=0;i<16;i++){
if (parent->is_tree & (1<<i)){
free_children(parent->tree_nodes[i]);
free(parent->tree_nodes[i]);
parent->tree_nodes[i]=NULL;
}else if(parent->subscribers[i]){
free_subscriber(parent->subscribers[i]);
parent->subscribers[i]=NULL;
}
}
parent->is_tree=0;
}
void free_subscribers()
{
// don't attempt to free anything if we're running as a server
// who knows where subscriber ptr's may have leaked to.
if (serverMode)
FATAL("Freeing subscribers from a running daemon is not supported");
free_children(&root);
}
// find a subscriber struct from a whole or abbreviated subscriber id // find a subscriber struct from a whole or abbreviated subscriber id
struct subscriber *find_subscriber(const unsigned char *sidp, int len, int create) struct subscriber *find_subscriber(const unsigned char *sidp, int len, int create)
{ {

View File

@ -57,9 +57,6 @@ struct subscriber{
int max_packet_version; int max_packet_version;
// overlay routing information
struct overlay_node *node;
// link state routing information // link state routing information
struct link_state *link_state; struct link_state *link_state;
@ -129,4 +126,6 @@ int overlay_broadcast_parse(struct overlay_buffer *b, struct broadcast *broadcas
int overlay_address_parse(struct decode_context *context, struct overlay_buffer *b, struct subscriber **subscriber); int overlay_address_parse(struct decode_context *context, struct overlay_buffer *b, struct subscriber **subscriber);
int send_please_explain(struct decode_context *context, struct subscriber *source, struct subscriber *destination); int send_please_explain(struct decode_context *context, struct subscriber *source, struct subscriber *destination);
void free_subscribers();
#endif #endif

View File

@ -924,9 +924,11 @@ int link_stop_routing(struct subscriber *subscriber)
subscriber->identity=NULL; subscriber->identity=NULL;
if (subscriber==my_subscriber) if (subscriber==my_subscriber)
my_subscriber=NULL; my_subscriber=NULL;
if (subscriber->link_state){
struct link_state *state = get_link_state(subscriber); struct link_state *state = get_link_state(subscriber);
state->next_update = gettime_ms(); state->next_update = gettime_ms();
update_alarm(state->next_update); update_alarm(state->next_update);
}
return 0; return 0;
} }