diff --git a/overlay_address.c b/overlay_address.c index e70d551b..1018b44c 100644 --- a/overlay_address.c +++ b/overlay_address.c @@ -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)); diff --git a/overlay_address.h b/overlay_address.h index 6021b795..7dbb4e30 100644 --- a/overlay_address.h +++ b/overlay_address.h @@ -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 diff --git a/overlay_advertise.c b/overlay_advertise.c index a8a02deb..70004950 100644 --- a/overlay_advertise.c +++ b/overlay_advertise.c @@ -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); } diff --git a/overlay_olsr.c b/overlay_olsr.c index 1aba1fe7..7d06e79f 100644 --- a/overlay_olsr.c +++ b/overlay_olsr.c @@ -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) diff --git a/overlay_packetformats.c b/overlay_packetformats.c index 28fdd2af..7ea2cb2b 100644 --- a/overlay_packetformats.c +++ b/overlay_packetformats.c @@ -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){ diff --git a/overlay_payload.c b/overlay_payload.c index 39834d9e..274c833f 100644 --- a/overlay_payload.c +++ b/overlay_payload.c @@ -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; diff --git a/overlay_queue.c b/overlay_queue.c index 0db0c84e..5ee338ee 100644 --- a/overlay_queue.c +++ b/overlay_queue.c @@ -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)