Don't ask for explanation of SIDs with dead routing links

This commit is contained in:
Jeremy Lakeman 2015-11-16 13:47:28 +10:30
parent a075a8edbc
commit 2ddbb86cb5
7 changed files with 87 additions and 54 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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))

View File

@ -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