Don't talk about SID's that don't match the whole abbreviation

This commit is contained in:
Jeremy Lakeman 2016-01-12 10:28:30 +10:30
parent bc1203c87c
commit 75523b7f3c
2 changed files with 26 additions and 36 deletions

View File

@ -111,7 +111,6 @@ void free_subscribers()
struct subscriber *_find_subscriber(struct __sourceloc __whence, const unsigned char *sidp, int len, int create) struct subscriber *_find_subscriber(struct __sourceloc __whence, const unsigned char *sidp, int len, int create)
{ {
IN(); IN();
DEBUGF(subscriber, "find_subscriber(sid=%s, create=%d)", alloca_tohex(sidp, len), create);
struct tree_node *ptr = &root; struct tree_node *ptr = &root;
int pos=0; int pos=0;
if (len!=SID_SIZE) if (len!=SID_SIZE)
@ -127,10 +126,7 @@ struct subscriber *_find_subscriber(struct __sourceloc __whence, const unsigned
ptr->subscribers[nibble] = ret; ptr->subscribers[nibble] = ret;
ret->sid = *(const sid_t *)sidp; ret->sid = *(const sid_t *)sidp;
ret->abbreviate_len = pos; ret->abbreviate_len = pos;
DEBUGF(subscriber, "set node[%.*s].subscribers[%c]=%p (sid=%s, abbrev_len=%d)", DEBUGF(subscriber, "Storing %s, abbrev_len=%d", alloca_tohex_sid_t(ret->sid), ret->abbreviate_len);
pos - 1, alloca_tohex(sidp, len), hexdigit_upper[nibble],
ret, alloca_tohex_sid_t(ret->sid), ret->abbreviate_len
);
} }
goto done; goto done;
}else{ }else{
@ -140,6 +136,8 @@ struct subscriber *_find_subscriber(struct __sourceloc __whence, const unsigned
goto done; goto done;
// if we need to insert this subscriber, we have to make a new tree node first // if we need to insert this subscriber, we have to make a new tree node first
if (!create) { if (!create) {
if (len != SID_SIZE)
DEBUGF(subscriber, "Prefix %s is not unique", alloca_tohex(sidp, len));
ret = NULL; ret = NULL;
goto done; goto done;
} }
@ -149,22 +147,17 @@ struct subscriber *_find_subscriber(struct __sourceloc __whence, const unsigned
ret = NULL; ret = NULL;
goto done; goto done;
} }
DEBUGF(subscriber, "create node[%.*s]", pos, alloca_tohex(sidp, len));
ptr->tree_nodes[nibble] = new; ptr->tree_nodes[nibble] = new;
ptr->is_tree |= (1<<nibble); ptr->is_tree |= (1<<nibble);
ptr = new; ptr = new;
nibble = get_nibble(ret->sid.binary, pos); nibble = get_nibble(ret->sid.binary, pos);
ptr->subscribers[nibble] = ret; ptr->subscribers[nibble] = ret;
ret->abbreviate_len = pos + 1; ret->abbreviate_len = pos + 1;
DEBUGF(subscriber, "set node[%.*s].subscribers[%c]=%p(sid=%s, abbrev_len=%d)", DEBUGF(subscriber, "Bumped %s, abbrev_len=%d", alloca_tohex_sid_t(ret->sid), ret->abbreviate_len);
pos, alloca_tohex(sidp, len), hexdigit_upper[nibble],
ret, alloca_tohex_sid_t(ret->sid), ret->abbreviate_len
);
// then go around the loop again to compare the next nibble against the sid until we find an empty slot. // then go around the loop again to compare the next nibble against the sid until we find an empty slot.
} }
} while(pos < len*2); } while(pos < len*2);
done: done:
DEBUGF(subscriber, "find_subscriber() return %p", ret);
RETURN(ret); RETURN(ret);
} }
@ -179,19 +172,18 @@ static int walk_tree(struct tree_node *node, int pos,
int(*callback)(struct subscriber *, void *), void *context){ int(*callback)(struct subscriber *, void *), void *context){
int i=0, e=16; int i=0, e=16;
if (start && pos < start_len*2){ if (start && pos < start_len*2)
i=get_nibble(start,pos); i=get_nibble(start,pos);
}
if (end && pos < end_len*2){ if (end && pos < end_len*2)
e=get_nibble(end,pos) +1; e=get_nibble(end,pos) +1;
}
for (;i<e;i++){ for (;i<e;i++){
if (node->is_tree & (1<<i)){ if (node->is_tree & (1<<i)){
if (walk_tree(node->tree_nodes[i], pos+1, start, start_len, end, end_len, callback, context)) if (walk_tree(node->tree_nodes[i], pos+1, start, start_len, end, end_len, callback, context))
return 1; return 1;
}else if(node->subscribers[i]){ }else if(node->subscribers[i]){
if (!start || memcmp(start, node->subscribers[i]->sid.binary, start_len)>=0)
if (callback(node->subscribers[i], context)) if (callback(node->subscribers[i], context))
return 1; return 1;
} }
@ -330,27 +322,22 @@ static int add_explain_response(struct subscriber *subscriber, void *context)
static int find_subscr_buffer(struct decode_context *context, struct overlay_buffer *b, int len, struct subscriber **subscriber) static int find_subscr_buffer(struct decode_context *context, struct overlay_buffer *b, int len, struct subscriber **subscriber)
{ {
if (len<=0 || len>SID_SIZE){ assert(subscriber);
if (len<=0 || len>SID_SIZE)
return WHYF("Invalid abbreviation length %d", len); return WHYF("Invalid abbreviation length %d", len);
}
unsigned char *id = ob_get_bytes_ptr(b, len); unsigned char *id = ob_get_bytes_ptr(b, len);
if (!id){ if (!id)
return WHY("Not enough space in buffer to parse address"); return WHY("Not enough space in buffer to parse address");
}
if (!subscriber){
WARN("Could not resolve address, no buffer supplied");
context->flags|=DECODE_FLAG_INVALID_ADDRESS;
return 0;
}
*subscriber=find_subscriber(id, len, 1); *subscriber=find_subscriber(id, len, 1);
if (!*subscriber){ if (!*subscriber){
context->flags|=DECODE_FLAG_INVALID_ADDRESS; context->flags|=DECODE_FLAG_INVALID_ADDRESS;
if ((context->flags & DECODE_FLAG_DONT_EXPLAIN) == 0){ if (context->flags & DECODE_FLAG_DONT_EXPLAIN){
DEBUGF(subscriber, "Ignoring prefix %s", alloca_tohex(id, len));
}else{
// generate a please explain in the passed in context // generate a please explain in the passed in context
// add the abbreviation you told me about // add the abbreviation you told me about
@ -365,7 +352,7 @@ static int find_subscr_buffer(struct decode_context *context, struct overlay_buf
// so you don't try to use an abbreviation that's too short in future. // 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); walk_tree(&root, 0, id, len, id, len, add_explain_response, context);
INFOF("Asking for explanation of %s", alloca_tohex(id, len)); DEBUGF(subscriber, "Asking for explanation of %s", alloca_tohex(id, len));
ob_append_byte(context->please_explain->payload, len); ob_append_byte(context->please_explain->payload, len);
ob_append_bytes(context->please_explain->payload, id, len); ob_append_bytes(context->please_explain->payload, id, len);
} }
@ -414,7 +401,7 @@ int overlay_address_parse(struct decode_context *context, struct overlay_buffer
ob_limitsize(context->please_explain->payload, MDP_MTU); ob_limitsize(context->please_explain->payload, MDP_MTU);
} }
INFOF("Asking for explanation of YOU"); DEBUGF(subscriber, "Asking for explanation of YOU");
ob_append_byte(context->please_explain->payload, OA_CODE_P2P_YOU); ob_append_byte(context->please_explain->payload, OA_CODE_P2P_YOU);
} }
context->flags|=DECODE_FLAG_INVALID_ADDRESS; context->flags|=DECODE_FLAG_INVALID_ADDRESS;
@ -423,7 +410,7 @@ int overlay_address_parse(struct decode_context *context, struct overlay_buffer
case OA_CODE_SELF: case OA_CODE_SELF:
if (!context->sender){ if (!context->sender){
INFO("Could not resolve address, sender has not been set"); DEBUGF(subscriber, "Could not resolve address, sender has not been set");
context->flags|=DECODE_FLAG_INVALID_ADDRESS; context->flags|=DECODE_FLAG_INVALID_ADDRESS;
}else{ }else{
*subscriber=context->sender; *subscriber=context->sender;
@ -433,7 +420,7 @@ int overlay_address_parse(struct decode_context *context, struct overlay_buffer
case OA_CODE_PREVIOUS: case OA_CODE_PREVIOUS:
if (!context->previous){ if (!context->previous){
INFO("Unable to decode previous address"); DEBUGF(subscriber, "Unable to decode previous address");
context->flags|=DECODE_FLAG_INVALID_ADDRESS; context->flags|=DECODE_FLAG_INVALID_ADDRESS;
}else{ }else{
*subscriber=context->previous; *subscriber=context->previous;
@ -516,16 +503,16 @@ int process_explain(struct overlay_frame *frame)
if (len==SID_SIZE){ if (len==SID_SIZE){
// This message is also used to inform people of previously unknown subscribers // This message is also used to inform people of previously unknown subscribers
// make sure we know this one // make sure we know this one
INFOF("Storing explain response for %s", alloca_tohex(sid, len)); DEBUGF(subscriber, "Storing explain response for %s", alloca_tohex(sid, len));
find_subscriber(sid,len,1); find_subscriber(sid,len,1);
}else{ }else{
// reply to the sender with all subscribers that match this abbreviation // reply to the sender with all subscribers that match this abbreviation
INFOF("Sending explain responses for %s", alloca_tohex(sid, len)); DEBUGF(subscriber, "Sending explain responses for %s", alloca_tohex(sid, len));
walk_tree(&root, 0, sid, len, sid, len, add_explain_response, &context); walk_tree(&root, 0, sid, len, sid, len, add_explain_response, &context);
} }
} }
if (context.please_explain) if (context.please_explain)
send_please_explain(&context, frame->destination, frame->source); send_please_explain(&context, frame->destination, frame->source);
DEBUG(subscriber, "No explain responses"); DEBUG(subscriber, "No explain responses?");
return 0; return 0;
} }

View File

@ -696,6 +696,7 @@ setup_noLinkPollution() {
# TODO re-roll identities until there's no possible SID prefix collision? # 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 create_single_identity
foreach_instance +A +B +C +D add_servald_interface 1 foreach_instance +A +B +C +D add_servald_interface 1
foreach_instance +A +B +C +D executeOk_servald config set debug.subscriber on
foreach_instance +A +B +C start_servald_server foreach_instance +A +B +C start_servald_server
simulator_command up "net1" simulator_command up "net1"
wait_until path_exists +A +B wait_until path_exists +A +B
@ -713,7 +714,9 @@ test_noLinkPollution() {
set_instance +D set_instance +D
executeOk_servald id allpeers executeOk_servald id allpeers
tfw_cat --stdout tfw_cat --stdout
assertStdoutLineCount '==' 3 # The test is considered a success if D doesn't find out about BOTH B and C
# There is still a chance that 3 ID's will have the same 16 bit prefix, but those are fairly slim odds
assertStdoutLineCount '<' 5
} }
setup_multi_interface() { setup_multi_interface() {