mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-21 09:51:50 +00:00
Simplify address abbreviation format and interface
This commit is contained in:
parent
54f9d9b0e0
commit
24a3ed1469
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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){
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user