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:
gardners 2011-08-15 13:50:30 +02:00
parent 02bf80246e
commit bd16fbbf5b
4 changed files with 105 additions and 48 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}