mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-29 15:43:56 +00:00
Address lookup from cache works :)
This gets us a functional system once we add the code to send PLEASEEXPLAIN messages to request resolutions.
This commit is contained in:
parent
02bf80246e
commit
bd16fbbf5b
4
mphlr.h
4
mphlr.h
@ -654,6 +654,7 @@ int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *of
|
||||
int prefix_bytes,int index_bytes);
|
||||
int overlay_abbreviate_remember_index(int index_byte_count,unsigned char *in,unsigned char *index_bytes);
|
||||
extern int overlay_abbreviate_repeat_policy;
|
||||
int overlay_abbreviate_set_most_recent_address(unsigned char *in);
|
||||
|
||||
/* Return codes for resolution of abbreviated addressses */
|
||||
#define OA_UNINITIALISED 0 /* Nothing has been written into the field */
|
||||
@ -685,6 +686,8 @@ typedef struct overlay_frame {
|
||||
unsigned int type;
|
||||
unsigned int modifiers;
|
||||
|
||||
unsigned char ttl;
|
||||
|
||||
unsigned char nexthop[32];
|
||||
int nexthop_address_status;
|
||||
|
||||
@ -707,3 +710,4 @@ typedef struct overlay_frame {
|
||||
} overlay_frame;
|
||||
|
||||
int overlay_frame_process(int interface,overlay_frame *f);
|
||||
int overlay_frame_resolve_addresses(int interface,overlay_frame *f);
|
||||
|
15
overlay.c
15
overlay.c
@ -155,12 +155,25 @@ int overlay_frame_process(int interface,overlay_frame *f)
|
||||
if (i==SID_SIZE) forMe=1;
|
||||
|
||||
fprintf(stderr,"This frame is%s for me.\n",forMe?"":" not");
|
||||
|
||||
|
||||
/* Not for us? Then just ignore it */
|
||||
if (!forMe) return 0;
|
||||
|
||||
switch(f->type)
|
||||
{
|
||||
case OF_TYPE_SELFANNOUNCE:
|
||||
if (overlay_frame_resolve_addresses(interface,f))
|
||||
return WHY("Failed to resolve destination and sender addresses in frame");
|
||||
fprintf(stderr,"Destination for this frame is (resolve code=%d): ",f->destination_address_status);
|
||||
if (f->destination_address_status==OA_RESOLVED) for(i=0;i<SID_SIZE;i++) fprintf(stderr,"%02x",f->destination[i]); else fprintf(stderr,"???");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr,"Source for this frame is (resolve code=%d): ",f->source_address_status);
|
||||
if (f->source_address_status==OA_RESOLVED) for(i=0;i<SID_SIZE;i++) fprintf(stderr,"%02x",f->source[i]); else fprintf(stderr,"???");
|
||||
fprintf(stderr,"\n");
|
||||
|
||||
break;
|
||||
default:
|
||||
return WHY("Support for that f->type not yet implemented");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -133,32 +133,40 @@ sid overlay_abbreviate_previous_address={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
sid overlay_abbreviate_current_sender={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
|
||||
int overlay_abbreviate_current_sender_id=-1;
|
||||
|
||||
int overlay_abbreviate_cache_address(unsigned char *sid)
|
||||
int overlay_abbreviate_prepare_cache()
|
||||
{
|
||||
if ((!cache)&&OVERLAY_ADDRESS_CACHE_SIZE)
|
||||
if (OVERLAY_ADDRESS_CACHE_SIZE>0x1000000)
|
||||
exit(WHY("OVERLAY_ADDRESS_CACHE_SIZE must be no larger than 2^24."));
|
||||
if (OVERLAY_ADDRESS_CACHE_SIZE<0)
|
||||
exit(WHY("OVERLAY_ADDRESS_CACHE_SIZE must be larger than 0."));
|
||||
|
||||
/* Allocate cache */
|
||||
cache=calloc(sizeof(overlay_address_cache),1);
|
||||
if (!cache) return 0;
|
||||
|
||||
/* Allocate address cache */
|
||||
cache->size=OVERLAY_ADDRESS_CACHE_SIZE;
|
||||
cache->sids=calloc(sizeof(sid),cache->size);
|
||||
if (!cache->sids) { free(cache); return 0; }
|
||||
|
||||
/* Work out the number of bits to shift */
|
||||
cache->shift=0;
|
||||
while(cache->size>>(cache->shift+1)) cache->shift++;
|
||||
|
||||
if ((1<<cache->shift)!=cache->size)
|
||||
{
|
||||
if (OVERLAY_ADDRESS_CACHE_SIZE>0x1000000)
|
||||
exit(WHY("OVERLAY_ADDRESS_CACHE_SIZE must be no larger than 2^24."));
|
||||
if (OVERLAY_ADDRESS_CACHE_SIZE<0)
|
||||
exit(WHY("OVERLAY_ADDRESS_CACHE_SIZE must be larger than 0."));
|
||||
|
||||
/* Allocate cache */
|
||||
cache=calloc(sizeof(overlay_address_cache),1);
|
||||
if (!cache) return 0;
|
||||
|
||||
/* Allocate address cache */
|
||||
cache->size=OVERLAY_ADDRESS_CACHE_SIZE;
|
||||
cache->sids=calloc(sizeof(sid),cache->size);
|
||||
if (!cache->sids) { free(cache); return 0; }
|
||||
|
||||
/* Work out the number of bits to shift */
|
||||
cache->shift=0;
|
||||
while(cache->size>>cache->shift) cache->shift++;
|
||||
|
||||
if ((1<<cache->shift)!=cache->size)
|
||||
exit(WHY("OVERLAY_ADDRESS_CACHE_SIZE must be a power of two."));
|
||||
fprintf(stderr,"cache->size=%d, shift=%d\n",cache->size,cache->shift);
|
||||
exit(WHY("OVERLAY_ADDRESS_CACHE_SIZE must be a power of two."));
|
||||
}
|
||||
|
||||
cache->shift=24-cache->shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_abbreviate_cache_address(unsigned char *sid)
|
||||
{
|
||||
if ((!cache)&&OVERLAY_ADDRESS_CACHE_SIZE) overlay_abbreviate_prepare_cache();
|
||||
if (!cache) return 0;
|
||||
|
||||
/* Work out the index in the cache where this address would go */
|
||||
@ -261,7 +269,7 @@ int overlay_abbreviate_address(unsigned char *in,char *out,int *ofs)
|
||||
|
||||
int overlay_abbreviate_expand_address(int interface,unsigned char *in,int *inofs,unsigned char *out,int *ofs)
|
||||
{
|
||||
int bytes=0;
|
||||
int bytes=0,r;
|
||||
fprintf(stderr,"Address first byte/abbreviation code=%02x (input offset=%d)\n",in[*inofs],*inofs);
|
||||
switch(in[*inofs])
|
||||
{
|
||||
@ -273,40 +281,46 @@ int overlay_abbreviate_expand_address(int interface,unsigned char *in,int *inofs
|
||||
case OA_CODE_INDEX: /* single byte index look up */
|
||||
WHY("Unimplemented address abbreviation code");
|
||||
overlay_interface_repeat_abbreviation_policy[interface]=1;
|
||||
break;
|
||||
return OA_UNSUPPORTED;
|
||||
case OA_CODE_PREVIOUS: /* Same as last address */
|
||||
(*inofs)++;
|
||||
bcopy(&overlay_abbreviate_previous_address.b[0],&out[*ofs],SID_SIZE);
|
||||
(*ofs)+=SID_SIZE;
|
||||
overlay_abbreviate_set_most_recent_address(&out[*ofs]);
|
||||
return OA_RESOLVED;
|
||||
break;
|
||||
case OA_CODE_PREFIX3: case OA_CODE_PREFIX3_INDEX1: /* 3-byte prefix */
|
||||
if (in[*inofs]==0x09) bytes=1;
|
||||
r=overlay_abbreviate_cache_lookup(&in[(*inofs)+1],out,ofs,3,bytes);
|
||||
(*inofs)+=3+bytes;
|
||||
return overlay_abbreviate_cache_lookup(&in[1],out,ofs,3,bytes);
|
||||
overlay_abbreviate_set_most_recent_address(&out[*ofs]);
|
||||
return r;
|
||||
case OA_CODE_PREFIX7: case OA_CODE_PREFIX7_INDEX1: /* 7-byte prefix */
|
||||
if (in[*inofs]==OA_CODE_PREFIX7_INDEX1) bytes=1;
|
||||
r=overlay_abbreviate_cache_lookup(&in[(*inofs)+1],out,ofs,7,bytes);
|
||||
(*inofs)+=7+bytes;
|
||||
WHY("Resolving address from 7-byte prefix");
|
||||
return overlay_abbreviate_cache_lookup(&in[(*inofs)+1],out,ofs,7,bytes);
|
||||
overlay_abbreviate_set_most_recent_address(&out[*ofs]);
|
||||
return r;
|
||||
case OA_CODE_PREFIX11: case OA_CODE_PREFIX11_INDEX1: case OA_CODE_PREFIX11_INDEX2: /* 11-byte prefix */
|
||||
if (in[*inofs]==OA_CODE_PREFIX11_INDEX1) bytes=1;
|
||||
if (in[*inofs]==OA_CODE_PREFIX11_INDEX2) bytes=2;
|
||||
r=overlay_abbreviate_cache_lookup(&in[(*inofs)+1],out,ofs,11,bytes);
|
||||
(*inofs)+=11+bytes;
|
||||
return overlay_abbreviate_cache_lookup(&in[(*inofs)+1],out,ofs,11,bytes);
|
||||
overlay_abbreviate_set_most_recent_address(&out[*ofs]);
|
||||
return r;
|
||||
case OA_CODE_BROADCAST: /* broadcast */
|
||||
memset(&out[*ofs],0xff,SID_SIZE);
|
||||
(*inofs)++;
|
||||
WHY("Resolved address (broadcast)");
|
||||
overlay_abbreviate_set_most_recent_address(&out[*ofs]);
|
||||
return OA_RESOLVED;
|
||||
case OA_CODE_FULL_INDEX1: case OA_CODE_FULL_INDEX2:
|
||||
default: /* Full address, optionally followed by index for us to remember */
|
||||
if (in[*inofs]==OA_CODE_FULL_INDEX1) bytes=1;
|
||||
if (in[*inofs]==OA_CODE_FULL_INDEX2) bytes=2;
|
||||
bcopy(&in,&out[*ofs],SID_SIZE);
|
||||
bcopy(&in[*inofs],&out[*ofs],SID_SIZE);
|
||||
if (bytes) overlay_abbreviate_remember_index(bytes,in,&in[(*inofs)+SID_SIZE]);
|
||||
overlay_abbreviate_cache_address(&in[*inofs]);
|
||||
overlay_abbreviate_set_most_recent_address(&out[*ofs]);
|
||||
(*inofs)+=SID_SIZE+bytes;
|
||||
WHY("Resolved address (full address provided)");
|
||||
return OA_RESOLVED;
|
||||
}
|
||||
}
|
||||
@ -328,13 +342,15 @@ int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *of
|
||||
int prefix_bytes,int index_bytes)
|
||||
{
|
||||
/* Lookup this entry from the cache, and also assign it the specified prefix */
|
||||
|
||||
if ((!cache)&&OVERLAY_ADDRESS_CACHE_SIZE) overlay_abbreviate_prepare_cache();
|
||||
if (!cache) return OA_PLEASEEXPLAIN; /* No cache? Then ask for address in full */
|
||||
|
||||
/* Work out the index in the cache where this address would live */
|
||||
int index=((in[0]<<16)|(in[0]<<8)|in[2])>>cache->shift;
|
||||
|
||||
int i;
|
||||
fprintf(stderr,"Looking in cache slot #%d for: ",index);
|
||||
for(i=0;i<prefix_bytes;i++) fprintf(stderr,"%02x",cache->sids[index].b[i]);
|
||||
for(i=0;i<prefix_bytes;i++) fprintf(stderr,"%02x",in[i]);
|
||||
fprintf(stderr,"*\n");
|
||||
|
||||
/* So is it there? */
|
||||
@ -366,14 +382,14 @@ int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *of
|
||||
return OA_RESOLVED;
|
||||
}
|
||||
|
||||
int overlay_abbreviate_set_current_sender(char *in)
|
||||
int overlay_abbreviate_set_current_sender(unsigned char *in)
|
||||
{
|
||||
bcopy(in,&overlay_abbreviate_current_sender.b[0],SID_SIZE);
|
||||
overlay_abbreviate_current_sender_id=-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_abbreviate_set_most_recent_address(char *in)
|
||||
int overlay_abbreviate_set_most_recent_address(unsigned char *in)
|
||||
{
|
||||
bcopy(in,&overlay_abbreviate_previous_address.b[0],SID_SIZE);
|
||||
return 0;
|
||||
|
@ -23,6 +23,7 @@ int packetOkOverlay(int interface,unsigned char *packet,int len,unsigned char *t
|
||||
All frames have the following fields:
|
||||
|
||||
Frame type (8bits)
|
||||
TTL (8bits)
|
||||
Remaining frame size (RFS) (8bits for <256 bytes, 16bits for <510 bytes etc)
|
||||
Next hop (variable length due to address abbreviation)
|
||||
Destination (variable length due to address abbreviation)*
|
||||
@ -115,6 +116,9 @@ int packetOkOverlay(int interface,unsigned char *packet,int len,unsigned char *t
|
||||
ofs++;
|
||||
break;
|
||||
}
|
||||
/* Get time to live */
|
||||
f.ttl=packet[ofs++];
|
||||
|
||||
/* Get length of remainder of frame */
|
||||
f.rfs=packet[ofs];
|
||||
while (packet[ofs]==0xff&&(ofs<len)&&(f.rfs<16384)) f.rfs+=packet[++ofs];
|
||||
@ -134,7 +138,7 @@ int packetOkOverlay(int interface,unsigned char *packet,int len,unsigned char *t
|
||||
frame may not be for us, so there is no point wasting time and energy if we don't have
|
||||
to.
|
||||
*/
|
||||
f.bytes=&packet[ofs];
|
||||
f.bytes=&packet[offset];
|
||||
f.bytecount=f.rfs-(offset-ofs);
|
||||
|
||||
/* Finally process the frame */
|
||||
@ -149,6 +153,23 @@ int packetOkOverlay(int interface,unsigned char *packet,int len,unsigned char *t
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_frame_resolve_addresses(int interface,overlay_frame *f)
|
||||
{
|
||||
/* Get destination and source addresses and set pointers to payload appropriately */
|
||||
int alen=0;
|
||||
int offset=0;
|
||||
|
||||
overlay_abbreviate_set_most_recent_address(f->nexthop);
|
||||
f->destination_address_status=overlay_abbreviate_expand_address(interface,f->bytes,&offset,f->destination,&alen);
|
||||
alen=0;
|
||||
f->source_address_status=overlay_abbreviate_expand_address(interface,f->bytes,&offset,f->source,&alen);
|
||||
f->payload=&f->bytes[offset];
|
||||
f->payloadlength=f->bytes-offset;
|
||||
if (f->payloadlength<0) return WHY("Abbreviated ddresses run past end of packet");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_add_selfannouncement(int interface,overlay_buffer *b)
|
||||
{
|
||||
/* Pull the first record from the HLR database and turn it into a
|
||||
@ -182,10 +203,20 @@ int overlay_add_selfannouncement(int interface,overlay_buffer *b)
|
||||
return WHY("ob_append_bytes() could not add self-announcement header");
|
||||
|
||||
int send_prefix=(overlay_interfaces[interface].ticks_since_sent_full_address<4);
|
||||
|
||||
/* A TTL for this frame.
|
||||
XXX - BATMAN uses various TTLs, but I think that it may just be better to have all TTL=1,
|
||||
and have the onward nodes selectively choose which nodes to on-announce. If we prioritise
|
||||
newly arrived nodes somewhat (or at least reserve some slots for them), then we can still
|
||||
get the good news travels fast property of BATMAN, but without having to flood in the formal
|
||||
sense. */
|
||||
c=1;
|
||||
if (ob_append_bytes(b,&c,1))
|
||||
return WHY("ob_append_bytes() could not add TTL to self-announcement");
|
||||
|
||||
/* Add space for Remaining Frame Size field. This will always be a single byte
|
||||
for self-announcments as they are always <256 bytes. */
|
||||
c=1+1+(send_prefix?(1+7):SID_SIZE)+4+1;
|
||||
c=1+1+(send_prefix?(1+7):SID_SIZE)+4;
|
||||
if (ob_append_bytes(b,&c,1))
|
||||
return WHY("ob_append_bytes() could not add RFS for self-announcement frame");
|
||||
|
||||
@ -225,15 +256,8 @@ int overlay_add_selfannouncement(int interface,overlay_buffer *b)
|
||||
if (ob_append_int(b,overlay_interfaces[interface].sequence_number))
|
||||
return WHY("ob_append_int() could not add sequence number to self-announcement");
|
||||
|
||||
/* A TTL for this frame?
|
||||
XXX - BATMAN uses various TTLs, but I think that it may just be better to have all TTL=1,
|
||||
and have the onward nodes selectively choose which nodes to on-announce. If we prioritise
|
||||
newly arrived nodes somewhat (or at least reserve some slots for them), then we can still
|
||||
get the good news travels fast property of BATMAN, but without having to flood in the formal
|
||||
sense. */
|
||||
c=1;
|
||||
if (ob_append_bytes(b,&c,1))
|
||||
return WHY("ob_append_bytes() could not add TTL to self-announcement");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user