Simplify address abbreviation format and interface

This commit is contained in:
Jeremy Lakeman 2012-11-26 15:28:13 +10:30
parent 54f9d9b0e0
commit 24a3ed1469
7 changed files with 60 additions and 146 deletions

View File

@ -327,12 +327,9 @@ int overlay_broadcast_drop_check(struct broadcast *addr)
}
}
int overlay_broadcast_append(struct decode_context *context, struct overlay_buffer *b, struct broadcast *broadcast)
int overlay_broadcast_append(struct overlay_buffer *b, struct broadcast *broadcast)
{
if (ob_append_byte(b, OA_CODE_BROADCAST)) return -1;
if (ob_append_bytes(b, broadcast->id, BROADCAST_LEN)) return -1;
context->previous=NULL;
return 0;
return ob_append_bytes(b, broadcast->id, BROADCAST_LEN);
}
// append an appropriate abbreviation into the address
@ -344,21 +341,19 @@ int overlay_address_append(struct decode_context *context, struct overlay_buffer
}else if(context && subscriber==context->previous){
ob_append_byte(b, OA_CODE_PREVIOUS);
}else if(subscriber->send_full || subscriber->abbreviate_len >= 20){
subscriber->send_full=0;
ob_append_bytes(b, subscriber->sid, SID_SIZE);
}else if(subscriber->abbreviate_len <= 4){
ob_append_byte(b, OA_CODE_PREFIX3);
ob_append_bytes(b, subscriber->sid, 3);
}else if(subscriber->abbreviate_len <= 12){
ob_append_byte(b, OA_CODE_PREFIX7);
ob_append_bytes(b, subscriber->sid, 7);
}else{
ob_append_byte(b, OA_CODE_PREFIX11);
ob_append_bytes(b, subscriber->sid, 11);
int len=SID_SIZE;
if (subscriber->send_full){
subscriber->send_full=0;
}else{
len=(subscriber->abbreviate_len+2)/2;
if (subscriber->reachable==REACHABLE_SELF)
len++;
if (len>SID_SIZE)
len=SID_SIZE;
}
ob_append_byte(b, len);
ob_append_bytes(b, subscriber->sid, len);
}
if (context)
context->previous = subscriber;
@ -380,12 +375,14 @@ static int add_explain_response(struct subscriber *subscriber, void *context){
// add the whole subscriber id to the payload, stop if we run out of space
DEBUGF("Adding full sid by way of explanation %s", alloca_tohex_sid(subscriber->sid));
if (ob_append_byte(response->please_explain->payload, SID_SIZE))
return 1;
if (ob_append_bytes(response->please_explain->payload, subscriber->sid, SID_SIZE))
return 1;
return 0;
}
int find_subscr_buffer(struct decode_context *context, struct overlay_buffer *b, int code, int len, int create, struct subscriber **subscriber){
int find_subscr_buffer(struct decode_context *context, struct overlay_buffer *b, int len, struct subscriber **subscriber){
unsigned char *id = ob_get_bytes_ptr(b, len);
if (!id)
return WHY("Not enough space in buffer to parse address");
@ -396,7 +393,7 @@ int find_subscr_buffer(struct decode_context *context, struct overlay_buffer *b,
return 0;
}
*subscriber=find_subscriber(id, len, create);
*subscriber=find_subscriber(id, len, 1);
if (!*subscriber){
context->invalid_addresses=1;
@ -415,46 +412,28 @@ int find_subscr_buffer(struct decode_context *context, struct overlay_buffer *b,
walk_tree(&root, 0, id, len, id, len, add_explain_response, context);
INFOF("Asking for explanation of %s", alloca_tohex(id, len));
if (code>=0)
ob_append_byte(context->please_explain->payload, code);
ob_append_byte(context->please_explain->payload, len);
ob_append_bytes(context->please_explain->payload, id, len);
}else{
context->previous=*subscriber;
context->previous_broadcast=NULL;
}
return 0;
}
// returns 0 = success, -1 = fatal parsing error, 1 = unable to identify address
int overlay_address_parse(struct decode_context *context, struct overlay_buffer *b, struct broadcast *broadcast, struct subscriber **subscriber)
int overlay_broadcast_parse(struct overlay_buffer *b, struct broadcast *broadcast)
{
int code = ob_getbyte(b,b->position);
if (code<0)
return -1;
DEBUGF("Decoding address code %d",code);
switch(code){
case OA_CODE_BROADCAST:
b->position++;
if (subscriber)
*subscriber=NULL;
if (!broadcast){
context->invalid_addresses=1;
}else{
if (ob_get_bytes(b, broadcast->id, BROADCAST_LEN))
return -1;
}
context->previous_broadcast=broadcast;
context->previous=NULL;
return 0;
return ob_get_bytes(b, broadcast->id, BROADCAST_LEN);
}
// returns 0 = success, -1 = fatal parsing error, 1 = unable to identify address
int overlay_address_parse(struct decode_context *context, struct overlay_buffer *b, struct subscriber **subscriber)
{
int len = ob_get(b);
switch(len){
case OA_CODE_SELF:
b->position++;
if (!subscriber){
WARN("Could not resolve address, no buffer supplied");
context->invalid_addresses=1;
}else if (!context->sender){
if (!context->sender){
INFO("Could not resolve address, sender has not been set");
context->invalid_addresses=1;
}else{
@ -464,45 +443,16 @@ int overlay_address_parse(struct decode_context *context, struct overlay_buffer
return 0;
case OA_CODE_PREVIOUS:
b->position++;
// previous may be null, if the previous address was a broadcast.
// In this case we want the subscriber to be null as well and not report an error,
if (!subscriber){
WARN("Could not resolve address, no buffer supplied");
context->invalid_addresses=1;
}else if (context->previous){
*subscriber=context->previous;
}else if (context->previous_broadcast){
*subscriber=NULL;
// not an error if broadcast is NULL, as the previous OA_CODE_BROADCAST address must have been valid.
if (broadcast)
bcopy(context->previous_broadcast->id, broadcast->id, BROADCAST_LEN);
}else{
if (!context->previous){
INFO("Unable to decode previous address");
context->invalid_addresses=1;
}else{
*subscriber=context->previous;
}
return 0;
case OA_CODE_PREFIX3:
b->position++;
return find_subscr_buffer(context, b, code, 3,0,subscriber);
case OA_CODE_PREFIX7:
b->position++;
return find_subscr_buffer(context, b, code, 7,0,subscriber);
case OA_CODE_PREFIX11:
b->position++;
return find_subscr_buffer(context, b, code, 11,0,subscriber);
}
// we must assume that we wont be able to understand the rest of the packet
if (code<=0x0f || context->abbreviations_only)
return WHYF("Unsupported abbreviation code %d", code);
return find_subscr_buffer(context, b, -1, SID_SIZE,1,subscriber);
return find_subscr_buffer(context, b, len, subscriber);
}
// once we've finished parsing a packet, complete and send a please explain if required.
@ -526,7 +476,6 @@ int send_please_explain(struct decode_context *context, struct subscriber *sourc
overlay_broadcast_generate_address(&context->please_explain->broadcast_id);
}
DEBUGF("Queued please explain");
context->please_explain->queue=OQ_MESH_MANAGEMENT;
if (!overlay_payload_enqueue(context->please_explain))
RETURN(0);
@ -542,36 +491,17 @@ int process_explain(struct overlay_frame *frame){
bzero(&context, sizeof context);
while(b->position < b->sizeLimit){
int code = ob_getbyte(b,b->position);
int len=SID_SIZE;
switch(code){
case OA_CODE_PREFIX3:
len=3;
b->position++;
break;
case OA_CODE_PREFIX7:
len=7;
b->position++;
break;
case OA_CODE_PREFIX11:
len=11;
b->position++;
break;
}
if (len==SID_SIZE && code<=0x0f)
return WHYF("Unsupported abbreviation code %d", code);
int len = ob_get(b);
if (len<=0 || len>SID_SIZE)
return WHY("Badly formatted explain message");
unsigned char *sid = ob_get_bytes_ptr(b, len);
if (!sid)
return WHY("Badly formatted explain message");
return WHY("Ran past end of buffer");
if (len==SID_SIZE){
// This message is also used to inform people of previously unknown subscribers
// make sure we know this one
find_subscriber(sid,len,1);
INFOF("Now know about %s", alloca_tohex(sid, len));
}else{
// reply to the sender with all subscribers that match this abbreviation
INFOF("Sending responses for %s", alloca_tohex(sid, len));

View File

@ -43,25 +43,8 @@
#define REACHABLE_DEFAULT_ROUTE 6
/* Codes used to describe abbreviated addresses.
Values 0x10 - 0xff are the first byte of, and implicit indicators of addresses written in full */
#define OA_CODE_SELF 0x00
#define OA_CODE_INDEX 0x01
#define OA_CODE_02 0x02
#define OA_CODE_PREVIOUS 0x03
#define OA_CODE_04 0x04
#define OA_CODE_PREFIX3 0x05
#define OA_CODE_PREFIX7 0x06
#define OA_CODE_PREFIX11 0x07
#define OA_CODE_FULL_INDEX1 0x08
#define OA_CODE_PREFIX3_INDEX1 0x09
#define OA_CODE_PREFIX7_INDEX1 0x0a
#define OA_CODE_PREFIX11_INDEX1 0x0b
#define OA_CODE_0C 0x0c
#define OA_CODE_PREFIX11_INDEX2 0x0d
#define OA_CODE_FULL_INDEX2 0x0e
/* The TTL field in a frame is used to differentiate between link-local and wide-area broadcasts */
#define OA_CODE_BROADCAST 0x0f
#define OA_CODE_SELF 0xff
#define OA_CODE_PREVIOUS 0xfe
#define BROADCAST_LEN 8
@ -105,12 +88,10 @@ struct broadcast{
};
struct decode_context{
int abbreviations_only;
int invalid_addresses;
struct overlay_frame *please_explain;
struct subscriber *sender;
struct subscriber *previous;
struct broadcast *previous_broadcast;
};
extern struct subscriber *my_subscriber;
@ -127,10 +108,11 @@ int process_explain(struct overlay_frame *frame);
int overlay_broadcast_drop_check(struct broadcast *addr);
int overlay_broadcast_generate_address(struct broadcast *addr);
int overlay_broadcast_append(struct decode_context *context, struct overlay_buffer *b, struct broadcast *broadcast);
int overlay_broadcast_append(struct overlay_buffer *b, struct broadcast *broadcast);
int overlay_address_append(struct decode_context *context, struct overlay_buffer *b, struct subscriber *subscriber);
int overlay_address_parse(struct decode_context *context, struct overlay_buffer *b, struct broadcast *broadcast, struct subscriber **subscriber);
int overlay_broadcast_parse(struct overlay_buffer *b, struct broadcast *broadcast);
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);
#endif

View File

@ -175,7 +175,6 @@ int overlay_route_add_advertisements(struct decode_context *context, overlay_int
int overlay_route_saw_advertisements(int i, struct overlay_frame *f, struct decode_context *context, time_ms_t now)
{
IN();
context->abbreviations_only=1;
struct subscriber *previous=context->previous;
// minimum record length is (address code, 3 byte sid, score, gateways)
while(f->payload->position < f->payload->sizeLimit)
@ -183,15 +182,19 @@ int overlay_route_saw_advertisements(int i, struct overlay_frame *f, struct deco
struct subscriber *subscriber;
context->invalid_addresses=0;
if (overlay_address_parse(context, f->payload, NULL, &subscriber))
if (overlay_address_parse(context, f->payload, &subscriber)){
WHY("Failed to parse address");
break;
}
int score=ob_get(f->payload);
int gateways_en_route=ob_get(f->payload);
// stop if hit end of payload
if (score<0 || gateways_en_route<0)
if (score<0 || gateways_en_route<0){
WHY("Unexpected end of payload");
break;
}
// skip if we can't parse the subscriber id
if (context->invalid_addresses || !subscriber)
@ -215,6 +218,5 @@ int overlay_route_saw_advertisements(int i, struct overlay_frame *f, struct deco
}
// restore the previous subscriber id for parsing the next header
context->previous=previous;
context->abbreviations_only=0;
RETURN(0);
}

View File

@ -141,7 +141,7 @@ static void parse_frame(struct overlay_buffer *buff){
addr = (struct in_addr *)ob_get_bytes_ptr(buff, addr_len);
// read subscriber id of transmitter
if (overlay_address_parse(&context, buff, NULL, &context.sender))
if (overlay_address_parse(&context, buff, &context.sender))
goto end;
if (context.invalid_addresses)
@ -162,7 +162,7 @@ static void parse_frame(struct overlay_buffer *buff){
}
// read subscriber id of payload origin
if (overlay_address_parse(&context, buff, NULL, &frame.source))
if (overlay_address_parse(&context, buff, &frame.source))
goto end;
if (context.invalid_addresses)
@ -170,7 +170,7 @@ static void parse_frame(struct overlay_buffer *buff){
// read source broadcast id
// assume each packet may arrive multiple times due to routing loops between servald overlay and olsr.
if (overlay_address_parse(&context, buff, &frame.broadcast_id, NULL))
if (overlay_broadcast_parse(buff, &frame.broadcast_id))
goto end;
if (context.invalid_addresses)
@ -274,7 +274,7 @@ int olsr_send(struct overlay_frame *frame){
overlay_address_append(&context, b, my_subscriber);
overlay_address_append(&context, b, frame->source);
overlay_broadcast_append(&context, b, &frame->broadcast_id);
overlay_broadcast_append(b, &frame->broadcast_id);
ob_append_byte(b, frame->modifiers);
if (debug&DEBUG_OVERLAYINTERFACES)

View File

@ -202,7 +202,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
f.recvaddr=NULL;
}
overlay_address_parse(&context, b, NULL, &context.sender);
overlay_address_parse(&context, b, &context.sender);
if (context.sender && context.sender->reachable==REACHABLE_SELF){
ob_free(b);
@ -220,7 +220,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
if (flags & PAYLOAD_FLAG_SENDER_SAME){
f.source = context.sender;
}else{
if (overlay_address_parse(&context, b, NULL, &f.source))
if (overlay_address_parse(&context, b, &f.source))
break;
if (!f.source || f.source->reachable==REACHABLE_SELF)
process=forward=0;
@ -228,7 +228,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
if (flags & PAYLOAD_FLAG_TO_BROADCAST){
if (!(flags & PAYLOAD_FLAG_ONE_HOP)){
if (overlay_address_parse(&context, b, &f.broadcast_id, NULL))
if (overlay_broadcast_parse(b, &f.broadcast_id))
break;
if (overlay_broadcast_drop_check(&f.broadcast_id)){
process=forward=0;
@ -238,7 +238,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
}
f.destination=NULL;
}else{
if (overlay_address_parse(&context, b, NULL, &f.destination))
if (overlay_address_parse(&context, b, &f.destination))
break;
if (!f.destination || f.destination->reachable!=REACHABLE_SELF){
@ -246,7 +246,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
}
if (!(flags & PAYLOAD_FLAG_ONE_HOP)){
if (overlay_address_parse(&context, b, NULL, &nexthop))
if (overlay_address_parse(&context, b, &nexthop))
break;
if (!nexthop || nexthop->reachable!=REACHABLE_SELF){

View File

@ -48,7 +48,7 @@ int overlay_frame_build_header(struct decode_context *context, struct overlay_bu
if (flags & PAYLOAD_FLAG_TO_BROADCAST){
if (!(flags & PAYLOAD_FLAG_ONE_HOP)){
if (overlay_broadcast_append(context, buff, broadcast)) return -1;
if (overlay_broadcast_append(buff, broadcast)) return -1;
}
}else{
if (overlay_address_append(context, buff, destination)) return -1;

View File

@ -164,7 +164,7 @@ int overlay_payload_enqueue(struct overlay_frame *p)
if (p->destination){
int r = subscriber_is_reachable(p->destination);
if (r == REACHABLE_SELF || r == REACHABLE_NONE)
return WHYF("Destination %s is unreachable (%d)", alloca_tohex_sid(p->destination->sid), r);
return WHYF("Cannot send %x packet, destination %s is %s", p->type, alloca_tohex_sid(p->destination->sid), r==REACHABLE_SELF?"myself":"unreachable");
}
if (p->queue>=OQ_MAX)