From 2ddbb86cb59876b4966bd7eaf71c97bc4520ceba Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Mon, 16 Nov 2015 13:47:28 +1030 Subject: [PATCH] Don't ask for explanation of SIDs with dead routing links --- overlay_address.c | 71 +++++++++++++++++++++-------------------- overlay_address.h | 11 +++---- overlay_mdp_services.c | 4 +-- overlay_olsr.c | 6 ++-- overlay_packetformats.c | 10 +++--- route_link.c | 8 +++-- tests/routing | 31 +++++++++++++++++- 7 files changed, 87 insertions(+), 54 deletions(-) diff --git a/overlay_address.c b/overlay_address.c index 662971ca..e98d2386 100644 --- a/overlay_address.c +++ b/overlay_address.c @@ -259,7 +259,7 @@ void overlay_address_append(struct decode_context *context, struct overlay_buffe && !subscriber->send_full && subscriber == my_subscriber && context->point_to_point_device - && (context->encoding_header==0 || !context->interface->local_echo)) + && ((context->flags & DECODE_FLAG_ENCODING_HEADER)==0 || !context->interface->local_echo)) ob_append_byte(b, OA_CODE_P2P_ME); else if (context && subscriber==context->sender) ob_append_byte(b, OA_CODE_SELF); @@ -271,7 +271,7 @@ void overlay_address_append(struct decode_context *context, struct overlay_buffe subscriber->send_full=0; }else{ len=(subscriber->abbreviate_len+2)/2; - if (context && context->encoding_header) + if (context && (context->flags & DECODE_FLAG_ENCODING_HEADER)) len++; if (len>SID_SIZE) len=SID_SIZE; @@ -341,33 +341,34 @@ static int find_subscr_buffer(struct decode_context *context, struct overlay_buf if (!subscriber){ WARN("Could not resolve address, no buffer supplied"); - context->invalid_addresses=1; + context->flags|=DECODE_FLAG_INVALID_ADDRESS; return 0; } *subscriber=find_subscriber(id, len, 1); if (!*subscriber){ - context->invalid_addresses=1; + context->flags|=DECODE_FLAG_INVALID_ADDRESS; - // generate a please explain in the passed in context - - // add the abbreviation you told me about - if (!context->please_explain){ - context->please_explain = calloc(sizeof(struct overlay_frame),1); - if ((context->please_explain->payload = ob_new()) == NULL) - return -1; - ob_limitsize(context->please_explain->payload, MDP_MTU); + if ((context->flags & DECODE_FLAG_DONT_EXPLAIN) == 0){ + // generate a please explain in the passed in context + + // add the abbreviation you told me about + if (!context->please_explain){ + context->please_explain = calloc(sizeof(struct overlay_frame),1); + if ((context->please_explain->payload = ob_new()) == NULL) + return -1; + ob_limitsize(context->please_explain->payload, MDP_MTU); + } + + // And I'll tell you about any subscribers I know that match this abbreviation, + // so you don't try to use an abbreviation that's too short in future. + walk_tree(&root, 0, id, len, id, len, add_explain_response, context); + + INFOF("Asking for explanation of %s", alloca_tohex(id, len)); + ob_append_byte(context->please_explain->payload, len); + ob_append_bytes(context->please_explain->payload, id, len); } - - // And I'll tell you about any subscribers I know that match this abbreviation, - // so you don't try to use an abbreviation that's too short in future. - walk_tree(&root, 0, id, len, id, len, add_explain_response, context); - - INFOF("Asking for explanation of %s", alloca_tohex(id, len)); - ob_append_byte(context->please_explain->payload, len); - ob_append_bytes(context->please_explain->payload, id, len); - }else{ if (context) context->previous=*subscriber; @@ -395,7 +396,7 @@ int overlay_address_parse(struct decode_context *context, struct overlay_buffer context->previous=my_subscriber; }else{ WHYF("Could not resolve address on %s, this isn't a configured point to point link", context->interface->name); - context->invalid_addresses=1; + context->flags|=DECODE_FLAG_INVALID_ADDRESS; } return 0; @@ -404,24 +405,26 @@ int overlay_address_parse(struct decode_context *context, struct overlay_buffer *subscriber=context->point_to_point_device; context->previous=*subscriber; }else{ - // add the abbreviation you told me about - if (!context->please_explain){ - context->please_explain = calloc(sizeof(struct overlay_frame),1); - if ((context->please_explain->payload = ob_new()) == NULL) - return -1; - ob_limitsize(context->please_explain->payload, MDP_MTU); + if ((context->flags & DECODE_FLAG_DONT_EXPLAIN) == 0){ + // add the abbreviation you told me about + if (!context->please_explain){ + context->please_explain = calloc(sizeof(struct overlay_frame),1); + if ((context->please_explain->payload = ob_new()) == NULL) + return -1; + ob_limitsize(context->please_explain->payload, MDP_MTU); + } + + INFOF("Asking for explanation of YOU"); + ob_append_byte(context->please_explain->payload, OA_CODE_P2P_YOU); } - - INFOF("Asking for explanation of YOU"); - ob_append_byte(context->please_explain->payload, OA_CODE_P2P_YOU); - context->invalid_addresses=1; + context->flags|=DECODE_FLAG_INVALID_ADDRESS; } return 0; case OA_CODE_SELF: if (!context->sender){ INFO("Could not resolve address, sender has not been set"); - context->invalid_addresses=1; + context->flags|=DECODE_FLAG_INVALID_ADDRESS; }else{ *subscriber=context->sender; context->previous=context->sender; @@ -431,7 +434,7 @@ int overlay_address_parse(struct decode_context *context, struct overlay_buffer case OA_CODE_PREVIOUS: if (!context->previous){ INFO("Unable to decode previous address"); - context->invalid_addresses=1; + context->flags|=DECODE_FLAG_INVALID_ADDRESS; }else{ *subscriber=context->previous; } diff --git a/overlay_address.h b/overlay_address.h index 63f6fef0..e5c81f3a 100644 --- a/overlay_address.h +++ b/overlay_address.h @@ -93,18 +93,17 @@ struct broadcast{ unsigned char id[BROADCAST_LEN]; }; +#define DECODE_FLAG_ENCODING_HEADER (1<<0) +#define DECODE_FLAG_INVALID_ADDRESS (1<<1) +#define DECODE_FLAG_DONT_EXPLAIN (1<<2) + struct decode_context{ struct overlay_interface *interface; int sender_interface; int packet_version; int encapsulation; struct socket_address addr; - union{ - // only valid while decoding - int invalid_addresses; - // only valid while encoding - int encoding_header; - }; + uint8_t flags; struct overlay_frame *please_explain; struct subscriber *sender; struct subscriber *previous; diff --git a/overlay_mdp_services.c b/overlay_mdp_services.c index 6e419ae1..5e7ba762 100644 --- a/overlay_mdp_services.c +++ b/overlay_mdp_services.c @@ -289,7 +289,7 @@ static int overlay_mdp_service_trace(struct internal_mdp_header *header, struct ret=WHYF("Invalid destination SID"); goto end; } - if (context.invalid_addresses){ + if (context.flags & DECODE_FLAG_INVALID_ADDRESS){ ret=WHYF("Unknown address in trace packet"); goto end; } @@ -306,7 +306,7 @@ static int overlay_mdp_service_trace(struct internal_mdp_header *header, struct ret=WHYF("Invalid SID in packet payload"); goto end; } - if (context.invalid_addresses){ + if (context.flags & DECODE_FLAG_INVALID_ADDRESS){ ret=WHYF("Unknown SID in packet payload"); goto end; } diff --git a/overlay_olsr.c b/overlay_olsr.c index 9680e1f1..ebcb4e78 100644 --- a/overlay_olsr.c +++ b/overlay_olsr.c @@ -171,7 +171,7 @@ static void parse_frame(struct overlay_buffer *buff){ if (overlay_address_parse(&context, buff, &context.sender)) goto end; - if (context.invalid_addresses) + if (context.flags & DECODE_FLAG_INVALID_ADDRESS) goto end; // locate the interface we should send outgoing unicast packets to @@ -184,7 +184,7 @@ static void parse_frame(struct overlay_buffer *buff){ if (overlay_address_parse(&context, buff, &frame.source)) goto end; - if (context.invalid_addresses) + if (context.flags & DECODE_FLAG_INVALID_ADDRESS) goto end; // read source broadcast id @@ -192,7 +192,7 @@ static void parse_frame(struct overlay_buffer *buff){ if (overlay_broadcast_parse(buff, &frame.broadcast_id)) goto end; - if (context.invalid_addresses) + if (context.flags & DECODE_FLAG_INVALID_ADDRESS) goto end; frame.modifiers=ob_get(buff); diff --git a/overlay_packetformats.c b/overlay_packetformats.c index 9203d880..c5b3ed26 100644 --- a/overlay_packetformats.c +++ b/overlay_packetformats.c @@ -54,10 +54,10 @@ int overlay_packet_init_header(int packet_version, int encapsulation, && packet_version>=1 ) context->point_to_point_device = context->interface->other_device; - context->encoding_header=1; + context->flags = DECODE_FLAG_ENCODING_HEADER; overlay_address_append(context, buff, my_subscriber); - context->encoding_header=0; + context->flags = 0; context->sender = my_subscriber; int flags=0; @@ -156,7 +156,7 @@ int parseMdpPacketHeader(struct decode_context *context, struct overlay_frame *f if (flags & PAYLOAD_FLAG_SENDER_SAME){ if (!context->sender) - context->invalid_addresses=1; + context->flags |= DECODE_FLAG_INVALID_ADDRESS; frame->source = context->sender; }else{ int ret=overlay_address_parse(context, buffer, &frame->source); @@ -248,7 +248,7 @@ int parseMdpPacketHeader(struct decode_context *context, struct overlay_frame *f frame->packet_version = context->packet_version; // if we can't understand one of the addresses, skip processing the payload - if ((forward||process)&&context->invalid_addresses){ + if ((forward||process)&& (context->flags & DECODE_FLAG_INVALID_ADDRESS)){ if (IF_DEBUG(verbose)) DEBUG(overlayframes, "Don't process or forward with invalid addresses"); forward=process=0; @@ -397,7 +397,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s interface->recv_count++; while(ob_remaining(b)>0){ - context.invalid_addresses=0; + context.flags = 0; struct subscriber *nexthop=NULL; bzero(f.broadcast_id.id, BROADCAST_LEN); diff --git a/route_link.c b/route_link.c index f617a018..85789ca3 100644 --- a/route_link.c +++ b/route_link.c @@ -1338,8 +1338,6 @@ int link_receive(struct internal_mdp_header *header, struct overlay_buffer *payl char changed = 0; while(ob_remaining(payload)>0){ - context.invalid_addresses=0; - struct subscriber *receiver=NULL, *transmitter=NULL; struct overlay_interface *interface = NULL; size_t start_pos = ob_position(payload); @@ -1350,6 +1348,10 @@ int link_receive(struct internal_mdp_header *header, struct overlay_buffer *payl int flags = ob_get(payload); if (flags<0) break; + + // If the link is dead, and we don't understand the SID, don't ask about it. + // We don't want or need to know. + context.flags = (flags & FLAG_NO_PATH)?DECODE_FLAG_DONT_EXPLAIN:0; if (overlay_address_parse(&context, payload, &receiver)) break; int version = ob_get(payload); @@ -1392,7 +1394,7 @@ int link_receive(struct internal_mdp_header *header, struct overlay_buffer *payl // jump to the position of the next record, even if there's more data we don't understand payload->position = start_pos + length; - if (context.invalid_addresses) + if (context.flags & DECODE_FLAG_INVALID_ADDRESS) continue; if (IF_DEBUG(verbose) || IF_DEBUG(ack)) diff --git a/tests/routing b/tests/routing index 1c81f3d9..bfc31060 100755 --- a/tests/routing +++ b/tests/routing @@ -630,7 +630,7 @@ test_offline() { wait_until --timeout=30 instance_offline +C } -doc_lose_neighbours="Lose and regain neighbours due to turning off" +doc_lose_neighbours="Lose and regain neighbours due to network timeout" setup_lose_neighbours() { setup_servald assert_no_servald_processes @@ -687,6 +687,35 @@ finally_interfaceBounce() { simulator_quit } +doc_noLinkPollution="Don't ask for explanation of links to dead nodes" +setup_noLinkPollution() { + setup_servald + assert_no_servald_processes + start_simulator + simulator_command create "net1" "$SERVALD_VAR/dummy1/" +# TODO re-roll identities until there's no possible SID prefix collision? + foreach_instance +A +B +C +D create_single_identity + foreach_instance +A +B +C +D add_servald_interface 1 + foreach_instance +A +B +C start_servald_server + simulator_command up "net1" + wait_until path_exists +A +B + wait_until path_exists +A +C + foreach_instance +B +C stop_servald_server + set_instance +A + wait_until --timeout=30 instance_offline +B + wait_until --timeout=30 instance_offline +C + set_instance +D + start_servald_server + wait_until path_exists +A +D + wait_until path_exists +D +A +} +test_noLinkPollution() { + set_instance +D + executeOk_servald id allpeers + tfw_cat --stdout + assertStdoutLineCount '==' 3 +} + setup_multi_interface() { setup_servald assert_no_servald_processes