mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-07 19:14:17 +00:00
Refactor packet envelope and sid abbreviation reading and writing
This commit is contained in:
parent
7fb1fd7938
commit
ddba8033e4
312
overlay.c
312
overlay.c
@ -182,238 +182,124 @@ int overlay_frame_process(struct overlay_interface *interface,overlay_frame *f)
|
||||
|
||||
long long now=overlay_gettime_ms();
|
||||
|
||||
if (f->source_address_status==OA_RESOLVED&&overlay_address_is_local(f->source))
|
||||
RETURN(WHY("Dropping frame claiming to come from myself."));
|
||||
if (debug&DEBUG_OVERLAYFRAMES)
|
||||
DEBUGF(">>> Received frame (type=%02x, bytes=%d)",f->type,f->payload?f->payload->length:-1);
|
||||
|
||||
if (debug&DEBUG_OVERLAYFRAMES) DEBUGF(">>> Received frame (type=%02x, bytes=%d)",f->type,f->payload?f->payload->length:-1);
|
||||
|
||||
/* First order of business is whether the nexthop address has been resolved.
|
||||
If not, we need to think about asking for it to be resolved.
|
||||
The trouble is that we do not want to trigger a Hanson Event (a storm of
|
||||
please explains/resolution requests). Yet, we do not want to delay
|
||||
communications unnecessarily.
|
||||
|
||||
The simple solution for now is to queue the address for resolution request
|
||||
in our next tick. If we see another resolution request for the same
|
||||
address in the mean time, then we can cancel our request */
|
||||
switch (f->nexthop_address_status)
|
||||
{
|
||||
case OA_UNINITIALISED:
|
||||
/* Um? Right. */
|
||||
RETURN(WHY("frame passed with ununitialised nexthop address"));
|
||||
break;
|
||||
case OA_RESOLVED:
|
||||
/* Great, we have the address, so we can get on with things */
|
||||
break;
|
||||
case OA_PLEASEEXPLAIN:
|
||||
RETURN(-1); // WHY("Address cannot be resolved -- aborting packet processing.");
|
||||
/* XXX Should send a please explain to get this address resolved. */
|
||||
break;
|
||||
case OA_UNSUPPORTED:
|
||||
default:
|
||||
// TODO tell the sender
|
||||
/* If we don't support the address format, we should probably tell
|
||||
the sender. Again, we queue this up, and cancel it if someone else
|
||||
tells them in the meantime to avoid an Opposition Event (like a Hanson
|
||||
Event, but repeatedly berating any node that holds a different policy
|
||||
to itself. */
|
||||
WHY("Packet with unsupported address format");
|
||||
RETURN(-1);
|
||||
break;
|
||||
// only examine payloads that are broadcasts, or where I'm the next hop
|
||||
if (overlay_address_is_broadcast(f->nexthop)) {
|
||||
if (overlay_broadcast_drop_check(f->nexthop)){
|
||||
if (debug&DEBUG_OVERLAYFRAMES)
|
||||
DEBUGF("Dropping frame, duplicate broadcast %s", alloca_tohex_sid(f->nexthop));
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
/* Okay, nexthop is valid, so let's see if it is us */
|
||||
int forMe=0,i;
|
||||
}else if (!overlay_address_is_local(f->nexthop)){
|
||||
if (debug&DEBUG_OVERLAYFRAMES)
|
||||
DEBUGF("Dropping frame, not addressed to me %s", alloca_tohex_sid(f->nexthop));
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
int broadcast=overlay_address_is_broadcast(f->destination);
|
||||
int ultimatelyForMe=0;
|
||||
int broadcast=0;
|
||||
int nhbroadcast=overlay_address_is_broadcast(f->nexthop);
|
||||
int duplicateBroadcast=0;
|
||||
|
||||
if (nhbroadcast) {
|
||||
if (overlay_broadcast_drop_check(f->nexthop)) duplicateBroadcast=1;
|
||||
|
||||
forMe=1; }
|
||||
if (overlay_address_is_local(f->nexthop)) forMe=1;
|
||||
|
||||
if (forMe) {
|
||||
/* It's for us, so resolve the addresses */
|
||||
if (overlay_frame_resolve_addresses(f))
|
||||
RETURN(WHY("Failed to resolve destination and sender addresses in frame"));
|
||||
broadcast=overlay_address_is_broadcast(f->destination);
|
||||
if (debug&DEBUG_OVERLAYFRAMES) {
|
||||
strbuf b = strbuf_alloca(1024);
|
||||
strbuf_sprintf(b, "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++)
|
||||
strbuf_sprintf(b, "%02x", f->destination[i]);
|
||||
else
|
||||
strbuf_puts(b, "???");
|
||||
DEBUG(strbuf_str(b));
|
||||
strbuf_reset(b);
|
||||
strbuf_sprintf(b, "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++)
|
||||
strbuf_sprintf(b, "%02x", f->source[i]);
|
||||
else
|
||||
strbuf_puts(b, "???");
|
||||
DEBUG(strbuf_str(b));
|
||||
}
|
||||
|
||||
if (f->source_address_status!=OA_RESOLVED) {
|
||||
if (debug&DEBUG_OVERLAYFRAMES) WHY("Source address could not be resolved, so dropping frame.");
|
||||
RETURN(-1);
|
||||
}
|
||||
if (overlay_address_is_local(f->source))
|
||||
{
|
||||
/* not that noteworthy, as when listening to a broadcast socket
|
||||
you hear everything you send. */
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
WHY("Dropping frame claiming to come from myself.");
|
||||
RETURN(-1);
|
||||
}
|
||||
|
||||
if (f->destination_address_status==OA_RESOLVED) {
|
||||
if (overlay_address_is_broadcast(f->destination))
|
||||
{ ultimatelyForMe=1; broadcast=1; }
|
||||
if (overlay_address_is_local(f->destination)) ultimatelyForMe=1;
|
||||
} else {
|
||||
if (debug&DEBUG_OVERLAYFRAMES) WHY("Destination address could not be resolved, so dropping frame.");
|
||||
RETURN(WHY("could not resolve destination address"));
|
||||
}
|
||||
}
|
||||
|
||||
if (debug&DEBUG_OVERLAYFRAMES) {
|
||||
DEBUGF("This frame does%s have me listed as next hop.", forMe?"":" not");
|
||||
DEBUGF("This frame is%s for me.", ultimatelyForMe?"":" not");
|
||||
DEBUGF("This frame is%s%s broadcast.", broadcast?"":" not",duplicateBroadcast?" a duplicate":"");
|
||||
}
|
||||
|
||||
if (duplicateBroadcast) {
|
||||
if (0) DEBUG("Packet is duplicate broadcast");
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
/* Not for us? Then just ignore it */
|
||||
if (!forMe) {
|
||||
RETURN(0);
|
||||
|
||||
if (broadcast){
|
||||
ultimatelyForMe = 1;
|
||||
// Note that we assume a broadcast destination address is the same as the broadcast nexthop address
|
||||
// we should decide to drop the packet based on the nexthop address.
|
||||
}else{
|
||||
if (overlay_address_is_local(f->destination))
|
||||
ultimatelyForMe = 1;
|
||||
}
|
||||
|
||||
f->ttl--;
|
||||
|
||||
// Never ever forward these types
|
||||
if ((f->type==OF_TYPE_SELFANNOUNCE)
|
||||
||(f->type==OF_TYPE_RHIZOME_ADVERT))
|
||||
f->ttl=0;
|
||||
|
||||
/* Is this a frame we have to forward on? */
|
||||
if (((!ultimatelyForMe)||broadcast)&&(f->ttl>1))
|
||||
if (((!ultimatelyForMe)||broadcast)&&(f->ttl>0))
|
||||
{
|
||||
/* Yes, it is. */
|
||||
|
||||
if (broadcast&&(!duplicateBroadcast)&&
|
||||
((f->type==OF_TYPE_SELFANNOUNCE)
|
||||
||(f->type==OF_TYPE_RHIZOME_ADVERT)
|
||||
))
|
||||
{
|
||||
// Don't forward broadcast self-announcement packets as that is O(n^2) with
|
||||
// traffic. We have other means to propagating the mesh topology information.
|
||||
// Similarly, rhizome advertisement traffic is always link local, so don't
|
||||
// forward that either.
|
||||
if (debug&DEBUG_BROADCASTS)
|
||||
if (duplicateBroadcast)
|
||||
DEBUG("Dropping broadcast frame (BPI seen before)");
|
||||
} else {
|
||||
if (debug&DEBUG_OVERLAYFRAMES) DEBUG("Forwarding frame");
|
||||
int dontForward=0;
|
||||
if (!broadcast) {
|
||||
if (overlay_get_nexthop(f->destination,f->nexthop,&f->nexthop_interface))
|
||||
WHYF("Could not find next hop for %s* - dropping frame",
|
||||
alloca_tohex(f->destination, 7));
|
||||
dontForward=1;
|
||||
}
|
||||
f->ttl--;
|
||||
int forward=1;
|
||||
|
||||
if (!broadcast)
|
||||
{
|
||||
if (overlay_get_nexthop(f->destination,f->nexthop,&f->nexthop_interface))
|
||||
WHYF("Could not find next hop for %s* - dropping frame",
|
||||
alloca_tohex(f->destination, 7));
|
||||
forward=0;
|
||||
}
|
||||
|
||||
if (0)
|
||||
DEBUGF("considering forwarding frame to %s (forme=%d, bcast=%d, dup=%d)",
|
||||
alloca_tohex_sid(f->destination),ultimatelyForMe,broadcast,
|
||||
duplicateBroadcast);
|
||||
if (0)
|
||||
DEBUGF("considering forwarding frame to %s (forme=%d, bcast=%d)",
|
||||
alloca_tohex_sid(f->destination),ultimatelyForMe,broadcast);
|
||||
|
||||
if (overlay_address_is_broadcast(f->destination))
|
||||
{
|
||||
/* if nexthop and destination address are the same, and nexthop was shown
|
||||
not to be a duplicate, then we don't need to test the destination
|
||||
address for being a duplicate broadcast. */
|
||||
int sameAsNextHop=1,i;
|
||||
for(i=0;i<SID_SIZE;i++)
|
||||
if (f->nexthop[i]!=f->destination[i])
|
||||
{ sameAsNextHop=0; break; }
|
||||
|
||||
if ((!sameAsNextHop)&&overlay_broadcast_drop_check(f->destination))
|
||||
duplicateBroadcast=1;
|
||||
if (duplicateBroadcast) {
|
||||
DEBUGF("reject src is %s", alloca_tohex_sid(f->source));
|
||||
DEBUGF("reject nexthop is %s", alloca_tohex_sid(f->nexthop));
|
||||
DEBUGF("reject destination is %s", alloca_tohex_sid(f->destination));
|
||||
RETURN(WHY("Not forwarding or reading duplicate broadcast"));
|
||||
}
|
||||
if (forward) {
|
||||
if (debug&DEBUG_OVERLAYFRAMES)
|
||||
DEBUG("Forwarding frame");
|
||||
|
||||
/* Queue frame for dispatch.
|
||||
Don't forget to put packet in the correct queue based on type.
|
||||
(e.g., mesh management, voice, video, ordinary or opportunistic).
|
||||
|
||||
But the really important bit is to clone the frame, since the
|
||||
structure we are looking at here must be left as is and returned
|
||||
to the caller to do as they please */
|
||||
overlay_frame *qf=op_dup(f);
|
||||
if (!qf) WHY("Could not clone frame for queuing");
|
||||
else {
|
||||
int qn=OQ_ORDINARY;
|
||||
/* Make sure voice traffic gets priority */
|
||||
if ((qf->type&OF_TYPE_BITS)==OF_TYPE_DATA_VOICE) {
|
||||
qn=OQ_ISOCHRONOUS_VOICE;
|
||||
rhizome_saw_voice_traffic();
|
||||
}
|
||||
|
||||
if (!dontForward) {
|
||||
/* Queue frame for dispatch.
|
||||
Don't forget to put packet in the correct queue based on type.
|
||||
(e.g., mesh management, voice, video, ordinary or opportunistic).
|
||||
|
||||
But the really important bit is to clone the frame, since the
|
||||
structure we are looking at here must be left as is and returned
|
||||
to the caller to do as they please */
|
||||
overlay_frame *qf=op_dup(f);
|
||||
if (!qf) WHY("Could not clone frame for queuing");
|
||||
else {
|
||||
int qn=OQ_ORDINARY;
|
||||
/* Make sure voice traffic gets priority */
|
||||
if ((qf->type&OF_TYPE_BITS)==OF_TYPE_DATA_VOICE) {
|
||||
qn=OQ_ISOCHRONOUS_VOICE;
|
||||
rhizome_saw_voice_traffic();
|
||||
}
|
||||
if (0) WHY("queuing frame for forwarding");
|
||||
if (overlay_payload_enqueue(qn,qf,0)) {
|
||||
WHY("failed to enqueue forwarded payload");
|
||||
op_free(qf);
|
||||
}
|
||||
if (0) WHY("queuing frame for forwarding");
|
||||
if (overlay_payload_enqueue(qn,qf,0)) {
|
||||
WHY("failed to enqueue forwarded payload");
|
||||
op_free(qf);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the frame was a broadcast frame, then we need to hang around
|
||||
so that we can process it, since we are one of the recipients.
|
||||
Otherwise, return triumphant. */
|
||||
if (!broadcast) RETURN(0);
|
||||
}
|
||||
}
|
||||
|
||||
int id = (interface - overlay_interfaces);
|
||||
switch(f->type)
|
||||
{
|
||||
case OF_TYPE_SELFANNOUNCE:
|
||||
overlay_route_saw_selfannounce(f,now);
|
||||
break;
|
||||
case OF_TYPE_SELFANNOUNCE_ACK:
|
||||
overlay_route_saw_selfannounce_ack(f,now);
|
||||
break;
|
||||
case OF_TYPE_NODEANNOUNCE:
|
||||
overlay_route_saw_advertisements(id,f,now);
|
||||
break;
|
||||
case OF_TYPE_RHIZOME_ADVERT:
|
||||
overlay_rhizome_saw_advertisements(id,f,now);
|
||||
break;
|
||||
case OF_TYPE_DATA:
|
||||
case OF_TYPE_DATA_VOICE:
|
||||
if (0) {
|
||||
DEBUG("saw mdp containing frame");
|
||||
DEBUGF(" src = %s\n", alloca_tohex_sid(f->source));
|
||||
DEBUGF(" nxt = %s\n", alloca_tohex_sid(f->nexthop));
|
||||
DEBUGF(" dst = %s\n", alloca_tohex_sid(f->destination));
|
||||
dump("payload", f->payload->bytes, f->payload->length);
|
||||
// process payloads with broadcast or our sid as destination
|
||||
if (ultimatelyForMe){
|
||||
int id = (interface - overlay_interfaces);
|
||||
switch(f->type)
|
||||
{
|
||||
case OF_TYPE_SELFANNOUNCE:
|
||||
overlay_route_saw_selfannounce(f,now);
|
||||
break;
|
||||
case OF_TYPE_SELFANNOUNCE_ACK:
|
||||
overlay_route_saw_selfannounce_ack(f,now);
|
||||
break;
|
||||
case OF_TYPE_NODEANNOUNCE:
|
||||
overlay_route_saw_advertisements(id,f,now);
|
||||
break;
|
||||
case OF_TYPE_RHIZOME_ADVERT:
|
||||
overlay_rhizome_saw_advertisements(id,f,now);
|
||||
break;
|
||||
case OF_TYPE_DATA:
|
||||
case OF_TYPE_DATA_VOICE:
|
||||
if (0) {
|
||||
DEBUG("saw mdp containing frame");
|
||||
DEBUGF(" src = %s\n", alloca_tohex_sid(f->source));
|
||||
DEBUGF(" nxt = %s\n", alloca_tohex_sid(f->nexthop));
|
||||
DEBUGF(" dst = %s\n", alloca_tohex_sid(f->destination));
|
||||
dump("payload", f->payload->bytes, f->payload->length);
|
||||
}
|
||||
overlay_saw_mdp_containing_frame(f,now);
|
||||
break;
|
||||
default:
|
||||
DEBUGF("Unsupported f->type=0x%x",f->type);
|
||||
RETURN(WHY("Support for that f->type not yet implemented"));
|
||||
break;
|
||||
}
|
||||
overlay_saw_mdp_containing_frame(f,now);
|
||||
break;
|
||||
default:
|
||||
DEBUGF("Unsupported f->type=0x%x",f->type);
|
||||
RETURN(WHY("Support for that f->type not yet implemented"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RETURN(0);
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ int overlay_abbreviate_cache_address(unsigned char *sid)
|
||||
/* Work out the index in the cache where this address would go.
|
||||
The XOR 1 is to make sure that all zeroes address doesn't live in index 0,
|
||||
which would otherwise result in it being detected as already present. */
|
||||
int index=(((sid[0]<<16)|(sid[0]<<8)|sid[2])>>cache->shift)^1;
|
||||
int index=(((sid[0]<<16)|(sid[1]<<8)|sid[2])>>cache->shift)^1;
|
||||
|
||||
/* Does the stored address match the one we have been passed? */
|
||||
if (!memcmp(sid,&cache->sids[index].b[0],SID_SIZE))
|
||||
@ -183,10 +183,7 @@ int overlay_abbreviate_cache_address(unsigned char *sid)
|
||||
/* Not yet in cache, so store it */
|
||||
bcopy(sid,&cache->sids[index].b[0],SID_SIZE);
|
||||
if (debug&DEBUG_OVERLAYABBREVIATIONS) {
|
||||
fprintf(stderr,"Cached address ");
|
||||
int i;
|
||||
for(i=0;i<SID_SIZE;i++) fprintf(stderr,"%02x",cache->sids[index].b[i]);
|
||||
fprintf(stderr,"\n");
|
||||
DEBUGF("Cached address %s", alloca_tohex_sid(sid));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -235,6 +232,7 @@ int overlay_abbreviate_append_address(overlay_buffer *b,unsigned char *a)
|
||||
}
|
||||
if (r) return r;
|
||||
b->length+=count;
|
||||
overlay_abbreviate_set_most_recent_address(a);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -246,11 +244,25 @@ int overlay_abbreviate_address(unsigned char *in,unsigned char *out,int *ofs)
|
||||
if (!in) return WHY("in==NULL");
|
||||
if (in[0]<0x10) return WHY("Invalid address - 0x00-0x0f are reserved prefixes.");
|
||||
|
||||
/* Is this the same as the current sender? */
|
||||
if (overlay_abbreviate_current_sender_set){
|
||||
for(i=0;i<SID_SIZE;i++)
|
||||
if (in[i]!=overlay_abbreviate_current_sender.b[i])
|
||||
break;
|
||||
if (i==SID_SIZE) {
|
||||
out[(*ofs)++]=OA_CODE_SELF;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try repeating previous address */
|
||||
for(i=0;i<SID_SIZE;i++) if (in[i]!=overlay_abbreviate_previous_address.b[i]) break;
|
||||
for(i=0;i<SID_SIZE;i++)
|
||||
if (in[i]!=overlay_abbreviate_previous_address.b[i])
|
||||
break;
|
||||
if (i==SID_SIZE) {
|
||||
out[(*ofs)++]=OA_CODE_PREVIOUS;
|
||||
return 0; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Is it a broadcast address? */
|
||||
if (overlay_address_is_broadcast(in)) {
|
||||
@ -332,7 +344,8 @@ int overlay_abbreviate_address(unsigned char *in,unsigned char *out,int *ofs)
|
||||
int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char *out,int *ofs)
|
||||
{
|
||||
int bytes=0,r;
|
||||
if (debug&DEBUG_OVERLAYABBREVIATIONS) DEBUGF("Address first byte/abbreviation code=%02x (input offset=%d)\n",in[*inofs],*inofs);
|
||||
if (debug&DEBUG_OVERLAYABBREVIATIONS)
|
||||
DEBUGF("Address first byte/abbreviation code=%02x (input offset=%d)\n",in[*inofs],*inofs);
|
||||
switch(in[*inofs])
|
||||
{
|
||||
case OA_CODE_02: case OA_CODE_04: case OA_CODE_0C:
|
||||
@ -352,7 +365,7 @@ int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char
|
||||
(*ofs)+=SID_SIZE;
|
||||
return OA_RESOLVED;
|
||||
} else {
|
||||
if (debug&DEBUG_OVERLAYABBREVIATIONS) DEBUGF("Cannot resolve OA_CODE_SELF until we can resolve sender's address.\n");
|
||||
WARN("Cannot resolve OA_CODE_SELF if the packet doesn't start with a self announcement.\n");
|
||||
return OA_UNINITIALISED;
|
||||
}
|
||||
case OA_CODE_INDEX: /* single byte index look up */
|
||||
@ -361,7 +374,8 @@ int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char
|
||||
r=overlay_abbreviate_cache_lookup(overlay_neighbours[overlay_abbreviate_current_sender_id].one_byte_index_address_prefixes[in[*inofs]],
|
||||
out,ofs,OVERLAY_SENDER_PREFIX_LENGTH,0);
|
||||
(*inofs)++;
|
||||
overlay_abbreviate_set_most_recent_address(&out[*ofs]);
|
||||
if (r==OA_RESOLVED)
|
||||
overlay_abbreviate_set_most_recent_address(&out[*ofs]);
|
||||
(*inofs)++;
|
||||
return r;
|
||||
case OA_CODE_PREVIOUS: /* Same as last address */
|
||||
@ -374,13 +388,15 @@ int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char
|
||||
if (in[*inofs]==0x09) bytes=1;
|
||||
r=overlay_abbreviate_cache_lookup(&in[(*inofs)+1],out,ofs,3,bytes);
|
||||
(*inofs)+=1+3+bytes;
|
||||
overlay_abbreviate_set_most_recent_address(&out[(*ofs)-SID_SIZE]);
|
||||
if (r==OA_RESOLVED)
|
||||
overlay_abbreviate_set_most_recent_address(&out[(*ofs)-SID_SIZE]);
|
||||
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)+=1+7+bytes;
|
||||
overlay_abbreviate_set_most_recent_address(&out[(*ofs)-SID_SIZE]);
|
||||
if (r==OA_RESOLVED)
|
||||
overlay_abbreviate_set_most_recent_address(&out[(*ofs)-SID_SIZE]);
|
||||
return r;
|
||||
case OA_CODE_PREFIX11: case OA_CODE_PREFIX11_INDEX1: case OA_CODE_PREFIX11_INDEX2: /* 11-byte prefix */
|
||||
bytes=0;
|
||||
@ -388,7 +404,8 @@ int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char
|
||||
if (in[*inofs]==OA_CODE_PREFIX11_INDEX2) bytes=2;
|
||||
r=overlay_abbreviate_cache_lookup(&in[(*inofs)+1],out,ofs,11,bytes);
|
||||
(*inofs)+=1+11+bytes;
|
||||
overlay_abbreviate_set_most_recent_address(&out[(*ofs)-SID_SIZE]);
|
||||
if (r==OA_RESOLVED)
|
||||
overlay_abbreviate_set_most_recent_address(&out[(*ofs)-SID_SIZE]);
|
||||
return r;
|
||||
case OA_CODE_BROADCAST: /* broadcast */
|
||||
memset(&out[*ofs],0xff,SID_SIZE-8);
|
||||
@ -396,7 +413,7 @@ int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char
|
||||
/* Copy Broadcast Packet Identifier */
|
||||
{ int i; for(i=0;i<8;i++) out[(*ofs)+24+i]=in[(*inofs)+i]; }
|
||||
if (debug&DEBUG_BROADCASTS)
|
||||
fprintf(stderr,"Expanded broadcast address with "
|
||||
DEBUGF("Expanded broadcast address with "
|
||||
"BPI=%02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
in[(*inofs)+0],in[(*inofs)+1],in[(*inofs)+2],in[(*inofs)+3],
|
||||
in[(*inofs)+4],in[(*inofs)+5],in[(*inofs)+6],in[(*inofs)+7]);
|
||||
@ -411,7 +428,7 @@ int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char
|
||||
bcopy(&in[*inofs],&out[*ofs],SID_SIZE);
|
||||
if (bytes) overlay_abbreviate_remember_index(bytes,&in[*inofs],&in[(*inofs)+SID_SIZE]);
|
||||
overlay_abbreviate_cache_address(&in[*inofs]);
|
||||
overlay_abbreviate_set_most_recent_address(&out[*ofs]);
|
||||
overlay_abbreviate_set_most_recent_address(&in[*inofs]);
|
||||
(*inofs)+=SID_SIZE+bytes;
|
||||
return OA_RESOLVED;
|
||||
}
|
||||
@ -419,6 +436,8 @@ int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char
|
||||
|
||||
int overlay_abbreviate_lookup_sender_id()
|
||||
{
|
||||
if (!overlay_abbreviate_current_sender_set)
|
||||
return WHY("Sender has not been set");
|
||||
overlay_neighbour *neh=overlay_route_get_neighbour_structure(overlay_abbreviate_current_sender.b,SID_SIZE,1 /* create if needed */);
|
||||
if (!neh) { overlay_abbreviate_current_sender_id=-1; return WHY("Could not find sender in neighbour list"); }
|
||||
/* Okay, so the following is a little tortuous in asking our parent who we are instead of just knowing,
|
||||
@ -457,7 +476,7 @@ int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *of
|
||||
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)^1;
|
||||
int index=(((in[0]<<16)|(in[1]<<8)|in[2])>>cache->shift)^1;
|
||||
|
||||
int i;
|
||||
if (debug&DEBUG_OVERLAYABBREVIATIONS) {
|
||||
@ -469,7 +488,7 @@ int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *of
|
||||
if (in[0]<0x10) {
|
||||
/* Illegal address */
|
||||
if (debug&DEBUG_OVERLAYABBREVIATIONS)
|
||||
fprintf(stderr,"Passed an illegal address (first byte <0x10)\n");
|
||||
DEBUGF("Passed an illegal address (first byte <0x10)");
|
||||
return OA_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -488,7 +507,7 @@ int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *of
|
||||
->keypairs[kp]->public_key,prefix_bytes))
|
||||
{
|
||||
if (debug&DEBUG_OVERLAYABBREVIATIONS)
|
||||
WHY("Found reference to local address.");
|
||||
DEBUG("Found reference to local address.");
|
||||
bcopy(&keyring->contexts[cn]->identities[id]
|
||||
->keypairs[kp]->public_key[0],&out[(*ofs)],SID_SIZE);
|
||||
(*ofs)+=SID_SIZE;
|
||||
@ -497,7 +516,7 @@ int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *of
|
||||
}
|
||||
|
||||
if (debug&DEBUG_OVERLAYABBREVIATIONS)
|
||||
WHY("Encountered unresolvable address -- are we asking for explanation?");
|
||||
DEBUG("Encountered unresolvable address -- are we asking for explanation?");
|
||||
return OA_PLEASEEXPLAIN;
|
||||
}
|
||||
|
||||
@ -505,11 +524,9 @@ int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *of
|
||||
colliding prefixes and ask the sender to resolve them for us, or better yet dynamically
|
||||
size the prefix length based on whether any given short prefix has collided */
|
||||
|
||||
if (debug&DEBUG_OVERLAYABBREVIATIONS) {
|
||||
/* It is here, so let's return it */
|
||||
fprintf(stderr,"I think I looked up the following: ");
|
||||
for(i=0;i<SID_SIZE;i++) fprintf(stderr,"%02x",cache->sids[index].b[i]);
|
||||
fprintf(stderr,"\n");
|
||||
/* It is here, so let's return it */
|
||||
if (debug&DEBUG_OVERLAYABBREVIATIONS) {
|
||||
DEBUGF("I think I looked up the following: %s", alloca_tohex_sid(cache->sids[index].b));
|
||||
}
|
||||
|
||||
bcopy(&cache->sids[index].b[0],&out[(*ofs)],SID_SIZE);
|
||||
|
@ -101,7 +101,9 @@ int overlay_route_add_advertisements(overlay_buffer *e)
|
||||
ob_append_byte(e,OA_CODE_BROADCAST);
|
||||
for(i=0;i<8;i++) ob_append_byte(e,random()&0xff); /* random BPI */
|
||||
ob_append_byte(e,OA_CODE_PREVIOUS);
|
||||
ob_append_byte(e,OA_CODE_SELF);
|
||||
|
||||
overlay_abbreviate_clear_most_recent_address();
|
||||
overlay_abbreviate_append_address(e, overlay_get_my_sid());
|
||||
|
||||
while (slots>0&&oad_request_count) {
|
||||
oad_request_count--;
|
||||
@ -195,32 +197,41 @@ int overlay_route_saw_advertisements(int i,overlay_frame *f, long long now)
|
||||
=overlay_abbreviate_cache_lookup(&f->payload->bytes[ofs],to,&out_len,
|
||||
6 /* prefix length */,
|
||||
0 /* no index code to process */);
|
||||
if (r==OA_PLEASEEXPLAIN) {
|
||||
/* Unresolved address -- TODO ask someone to resolve it for us. */
|
||||
WARN("Dispatch PLEASEEXPLAIN not implemented");
|
||||
goto next;
|
||||
}
|
||||
|
||||
int score=f->payload->bytes[6];
|
||||
int gateways_en_route=f->payload->bytes[7];
|
||||
|
||||
/* Don't record routes to ourselves */
|
||||
if (overlay_address_is_local(to)) {
|
||||
if (debug & DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("Ignore announcement about me (%s)", alloca_tohex_sid(to));
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* Don't let nodes advertise paths to themselves!
|
||||
(paths to self get detected through selfannouncements and selfannouncement acks) */
|
||||
if (memcmp(&overlay_abbreviate_current_sender.b[0],to,SID_SIZE))
|
||||
{
|
||||
/* Discount score by score to sender */
|
||||
score*=sender_score;
|
||||
score=score>>8;
|
||||
|
||||
if (r==OA_RESOLVED) {
|
||||
/* File it */
|
||||
overlay_route_record_link(now,to,&overlay_abbreviate_current_sender.b[0],
|
||||
i,
|
||||
/* time range that this advertisement covers.
|
||||
XXX - Make it up for now. */
|
||||
now-2500,now,
|
||||
score,gateways_en_route);
|
||||
} else if (r==OA_PLEASEEXPLAIN) {
|
||||
/* Unresolved address -- ask someone to resolve it for us. */
|
||||
WARN("Dispatch PLEASEEXPLAIN not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
if (!memcmp(&overlay_abbreviate_current_sender.b[0],to,SID_SIZE)){
|
||||
if (debug & DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("Ignore announcement about neighbour (%s)", alloca_tohex_sid(to));
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (r==OA_RESOLVED) {
|
||||
/* File it */
|
||||
overlay_route_record_link(now,to,&overlay_abbreviate_current_sender.b[0],
|
||||
i,
|
||||
/* time range that this advertisement covers.
|
||||
XXX - Make it up for now. */
|
||||
now-2500,now,
|
||||
score,gateways_en_route);
|
||||
}
|
||||
|
||||
next:
|
||||
ofs+=8;
|
||||
}
|
||||
|
||||
|
@ -365,7 +365,8 @@ void overlay_interface_poll(struct sched_ent *alarm)
|
||||
if (debug&DEBUG_OVERLAYINTERFACES) DEBUGF("Received %d bytes on interface %s",plen,interface->name);
|
||||
if (packetOk(interface,packet,plen,NULL,recvttl,&src_addr,addrlen,1)) {
|
||||
WHY("Malformed packet");
|
||||
serval_packetvisualise(open_logging(), "Malformed packet", packet,plen);
|
||||
// Do we really want to attempt to parse it again?
|
||||
//serval_packetvisualise(open_logging(), "Malformed packet", packet,plen);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -456,7 +457,7 @@ int overlay_broadcast_ensemble(int interface_number,
|
||||
unsigned char *bytes,int len)
|
||||
{
|
||||
struct sockaddr_in s;
|
||||
|
||||
|
||||
if (debug&DEBUG_PACKETTX)
|
||||
{
|
||||
DEBUGF("Sending this packet via interface #%d",interface_number);
|
||||
@ -733,19 +734,20 @@ int overlay_queue_dump(overlay_txqueue *q)
|
||||
}
|
||||
|
||||
int overlay_resolve_next_hop(overlay_frame *frame){
|
||||
IN();
|
||||
if (frame->nexthop_address_status==OA_RESOLVED)
|
||||
return 0;
|
||||
RETURN(0);
|
||||
|
||||
if (frame->isBroadcast)
|
||||
bcopy(&frame->destination,&frame->nexthop,SID_SIZE);
|
||||
else if (overlay_get_nexthop((unsigned char *)frame->destination,frame->nexthop,&frame->nexthop_interface)){
|
||||
// TODO new code?
|
||||
frame->nexthop_address_status=OA_UNSUPPORTED;
|
||||
return -1;
|
||||
RETURN(-1);
|
||||
}
|
||||
|
||||
frame->nexthop_address_status=OA_RESOLVED;
|
||||
return 0;
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
void overlay_init_packet(struct outgoing_packet *packet, int interface){
|
||||
@ -754,6 +756,9 @@ void overlay_init_packet(struct outgoing_packet *packet, int interface){
|
||||
packet->buffer=ob_new(packet->interface->mtu);
|
||||
ob_limitsize(packet->buffer, packet->interface->mtu);
|
||||
ob_append_bytes(packet->buffer,magic_header,4);
|
||||
|
||||
overlay_abbreviate_clear_most_recent_address();
|
||||
overlay_abbreviate_unset_current_sender();
|
||||
}
|
||||
|
||||
// update the alarm time and return 1 if changed
|
||||
@ -908,6 +913,7 @@ int overlay_fill_send_packet(struct outgoing_packet *packet, long long now){
|
||||
overlay_broadcast_ensemble(packet->i,NULL,packet->buffer->bytes,packet->buffer->length);
|
||||
}
|
||||
ob_free(packet->buffer);
|
||||
overlay_abbreviate_clear_most_recent_address();
|
||||
RETURN(1);
|
||||
}
|
||||
RETURN(0);
|
||||
@ -925,7 +931,6 @@ void overlay_send_packet(struct sched_ent *alarm){
|
||||
void overlay_update_queue_schedule(overlay_txqueue *queue, overlay_frame *frame){
|
||||
if (overlay_calc_queue_time(queue, frame)){
|
||||
unschedule(&next_packet);
|
||||
DEBUGF("Scheduled next packet in %dms", next_packet.alarm - overlay_gettime_ms());
|
||||
schedule(&next_packet);
|
||||
}
|
||||
}
|
||||
|
@ -922,7 +922,6 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
|
||||
overlay_frame_set_broadcast_as_destination(frame);
|
||||
else{
|
||||
bcopy(&mdp->out.dst.sid[0],frame->destination,SID_SIZE);
|
||||
frame->destination_address_status=OA_RESOLVED;
|
||||
}
|
||||
|
||||
int q=OQ_ORDINARY;
|
||||
|
@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "serval.h"
|
||||
|
||||
#include "strbuf.h"
|
||||
|
||||
struct sockaddr_in loopback = {
|
||||
.sin_family=0,
|
||||
@ -101,9 +101,12 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
|
||||
|
||||
bzero(&f,sizeof(overlay_frame));
|
||||
|
||||
if (recvaddr->sa_family==AF_INET)
|
||||
if (recvaddr->sa_family==AF_INET){
|
||||
f.recvaddr=recvaddr;
|
||||
else {
|
||||
if (debug&DEBUG_OVERLAYFRAMES)
|
||||
DEBUG("Received overlay packet");
|
||||
|
||||
} else {
|
||||
if (interface->fileP) {
|
||||
/* dummy interface, so tell to use 0.0.0.0 */
|
||||
f.recvaddr=(struct sockaddr *)&loopback;
|
||||
@ -114,21 +117,18 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
|
||||
|
||||
overlay_abbreviate_unset_current_sender();
|
||||
|
||||
// TODO put sender of packet and sequence number in envelope header
|
||||
// Then we can quickly drop reflected broadcast packets
|
||||
// currently we see annoying errors as we attempt to parse each payload
|
||||
// plus with a sequence number we can detect dropped packets and nack them for retransmission
|
||||
|
||||
/* Skip magic bytes and version */
|
||||
for(ofs=4;ofs<len;)
|
||||
{
|
||||
/* Clear out the data structure ready for next frame */
|
||||
f.nexthop_address_status=OA_UNINITIALISED;
|
||||
f.destination_address_status=OA_UNINITIALISED;
|
||||
f.source_address_status=OA_UNINITIALISED;
|
||||
|
||||
/* Get normal form of packet type and modifiers */
|
||||
f.type=packet[ofs]&OF_TYPE_BITS;
|
||||
f.modifiers=packet[ofs]&OF_MODIFIER_BITS;
|
||||
|
||||
if (debug&DEBUG_PACKETFORMATS)
|
||||
DEBUGF("f.type=0x%02x, f.modifiers=0x%02x, ofs=%d", f.type, f.modifiers, ofs);
|
||||
|
||||
switch(packet[ofs]&OF_TYPE_BITS)
|
||||
{
|
||||
case OF_TYPE_EXTENDED20:
|
||||
@ -162,63 +162,124 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
|
||||
break;
|
||||
}
|
||||
|
||||
if (f.rfs > len - ofs)
|
||||
return WHYF("Payload length %d is too long for the remaining packet buffer %d", f.rfs, len - ofs);
|
||||
int payloadStart = ofs;
|
||||
int nextPayload = ofs+f.rfs;
|
||||
|
||||
if (nextPayload > len){
|
||||
WHYF("Payload length %d is too long for the remaining packet buffer %d", f.rfs, len - ofs);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Always attempt to resolve all of the addresses in a packet, or we could fail to understand an important payload
|
||||
eg, peer sends two payloads travelling in opposite directions;
|
||||
[Next, Dest, Sender] forwarding a payload we just send, so Sender == Me
|
||||
[Next, Dest, Sender] delivering a payload to us so Next == Me
|
||||
|
||||
But Next would be encoded as OA_CODE_PREVIOUS, so we must parse all three addresses,
|
||||
even if Next is obviously not intended for us
|
||||
*/
|
||||
|
||||
/* Now extract the next hop address */
|
||||
int alen=0;
|
||||
int offset=ofs;
|
||||
f.nexthop_address_status=overlay_abbreviate_expand_address(packet,&offset,f.nexthop,&alen);
|
||||
if (debug&DEBUG_PACKETFORMATS) {
|
||||
if (f.nexthop_address_status==OA_RESOLVED)
|
||||
DEBUGF("next hop address is %s", alloca_tohex_sid(f.nexthop));
|
||||
int nexthop_address_status=overlay_abbreviate_expand_address(packet,&ofs,f.nexthop,&alen);
|
||||
if (ofs>nextPayload){
|
||||
WARN("Next hop address didn't fit in payload");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Now just make the rest of the frame available via the received frame structure, as the
|
||||
frame may not be for us, so there is no point wasting time and energy if we don't have
|
||||
to.
|
||||
*/
|
||||
f.bytes=&packet[offset];
|
||||
f.bytecount=f.rfs-(offset-ofs);
|
||||
if (f.bytecount<0) {
|
||||
f.bytecount=0;
|
||||
if (debug&DEBUG_PACKETFORMATS) DEBUGF("f.rfs=%02x, offset=%02x, ofs=%02x", f.rfs, offset, ofs);
|
||||
return WHY("negative residual byte count after extracting addresses from frame header");
|
||||
}
|
||||
|
||||
/* Finally process the frame */
|
||||
overlay_frame_process(interface,&f);
|
||||
|
||||
/* Skip the rest of the bytes in this frame so that we can examine the next one in this
|
||||
ensemble */
|
||||
if (debug&DEBUG_PACKETFORMATS) DEBUGF("next ofs=%d, f.rfs=%d, len=%d", ofs, f.rfs, len);
|
||||
ofs+=f.rfs;
|
||||
alen=0;
|
||||
int destination_address_status=overlay_abbreviate_expand_address(packet,&ofs,f.destination,&alen);
|
||||
if (ofs>nextPayload){
|
||||
WARN("Destination address didn't fit in payload");
|
||||
break;
|
||||
}
|
||||
|
||||
alen=0;
|
||||
int source_address_status=overlay_abbreviate_expand_address(packet,&ofs,f.source,&alen);
|
||||
if (ofs>nextPayload){
|
||||
WARN("Source address didn't fit in payload");
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO respond with OA_PLEASEEXPLAIN's?
|
||||
|
||||
if (debug&DEBUG_OVERLAYFRAMES) {
|
||||
DEBUGF("Type=0x%02x", f.type);
|
||||
strbuf b = strbuf_alloca(1024);
|
||||
strbuf_sprintf(b, "Next Hop for this frame is (resolve code=%d): ", nexthop_address_status);
|
||||
if (nexthop_address_status==OA_RESOLVED)
|
||||
strbuf_sprintf(b, "%s", alloca_tohex_sid(f.nexthop));
|
||||
else
|
||||
strbuf_puts(b, "???");
|
||||
DEBUG(strbuf_str(b));
|
||||
strbuf_reset(b);
|
||||
strbuf_sprintf(b, "Destination for this frame is (resolve code=%d): ", destination_address_status);
|
||||
if (destination_address_status==OA_RESOLVED)
|
||||
strbuf_sprintf(b, "%s", alloca_tohex_sid(f.destination));
|
||||
else
|
||||
strbuf_puts(b, "???");
|
||||
DEBUG(strbuf_str(b));
|
||||
strbuf_reset(b);
|
||||
strbuf_sprintf(b, "Source for this frame is (resolve code=%d): ", source_address_status);
|
||||
if (source_address_status==OA_RESOLVED)
|
||||
strbuf_sprintf(b, "%s", alloca_tohex_sid(f.source));
|
||||
else
|
||||
strbuf_puts(b, "???");
|
||||
DEBUG(strbuf_str(b));
|
||||
}
|
||||
|
||||
if (f.nexthop[0]==0 || f.destination[0]==0 || f.source[0]==0){
|
||||
WHY("Addresses expanded incorrectly");
|
||||
dump("Addresses expanded incorrectly", &packet[payloadStart], ofs - payloadStart);
|
||||
break;
|
||||
}
|
||||
|
||||
if (nexthop_address_status!=OA_RESOLVED
|
||||
|| destination_address_status!=OA_RESOLVED
|
||||
|| source_address_status!=OA_RESOLVED){
|
||||
WARN("Unable to resolve all payload addresses");
|
||||
// we have to stop now as we can't be certain about the destination of any other payloads in this packet.
|
||||
break;
|
||||
}
|
||||
|
||||
/* not that noteworthy, as when listening to a broadcast socket
|
||||
you hear everything you send. */
|
||||
if (overlay_address_is_local(f.source)){
|
||||
// skip the remainder of any packet that we know we sent
|
||||
// TODO add our id to the header
|
||||
if (f.type==OF_TYPE_SELFANNOUNCE)
|
||||
break;
|
||||
}else{
|
||||
|
||||
// TODO refactor all packet parsing to only allocate additional memory for the payload
|
||||
// if it needs to be queued for forwarding.
|
||||
if (!f.payload)
|
||||
f.payload=ob_new(nextPayload - ofs);
|
||||
else
|
||||
f.payload->length=0;
|
||||
|
||||
if (!f.payload){
|
||||
WHY("calloc(overlay_buffer) failed.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (ob_append_bytes(f.payload,&packet[ofs],nextPayload - ofs)){
|
||||
WHY("ob_append_bytes() failed.");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Finally process the frame */
|
||||
overlay_frame_process(interface,&f);
|
||||
}
|
||||
|
||||
/* Jump to the next payload offset */
|
||||
ofs = nextPayload;
|
||||
}
|
||||
if (0) INFOF("Finished processing overlay packet");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_frame_resolve_addresses(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(f->bytes,&offset,f->destination,&alen);
|
||||
alen=0;
|
||||
f->source_address_status=overlay_abbreviate_expand_address(f->bytes,&offset,f->source,&alen);
|
||||
if (debug&DEBUG_OVERLAYABBREVIATIONS)
|
||||
DEBUGF("Wrote %d bytes into source address: %s", alen, alloca_tohex(f->source, alen));
|
||||
|
||||
/* Copy payload into overlay_buffer structure */
|
||||
if (f->bytecount-offset<0) return WHY("Abbreviated ddresses run past end of packet");
|
||||
if (!f->payload) f->payload=ob_new(f->bytecount-offset); else f->payload->length=0;
|
||||
if (!f->payload) return WHY("calloc(overlay_buffer) failed.");
|
||||
if (ob_append_bytes(f->payload,&f->bytes[offset],f->bytecount-offset))
|
||||
return WHY("ob_append_bytes() failed.");
|
||||
|
||||
if (f.payload)
|
||||
ob_free(f.payload);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -307,7 +368,9 @@ int overlay_add_selfannouncement(int interface,overlay_buffer *b)
|
||||
}
|
||||
/* Make note that this is the most recent address we have set */
|
||||
overlay_abbreviate_set_most_recent_address(sid);
|
||||
|
||||
/* And the sender for any other addresses in this packet */
|
||||
overlay_abbreviate_set_current_sender(sid);
|
||||
|
||||
/* Sequence number range. Based on one tick per milli-second. */
|
||||
|
||||
if (ob_append_int(b,overlay_interfaces[interface].last_tick_ms))
|
||||
|
@ -148,11 +148,8 @@ int overlay_frame_package_fmt1(overlay_frame *p,overlay_buffer *b)
|
||||
|
||||
/* Write out addresses as abbreviated as possible */
|
||||
overlay_abbreviate_append_address(headers,p->nexthop);
|
||||
overlay_abbreviate_set_most_recent_address(p->nexthop);
|
||||
overlay_abbreviate_append_address(headers,p->destination);
|
||||
overlay_abbreviate_set_most_recent_address(p->destination);
|
||||
overlay_abbreviate_append_address(headers,p->source);
|
||||
overlay_abbreviate_set_most_recent_address(p->source);
|
||||
|
||||
int addrs_len=headers->length-addrs_start;
|
||||
int actual_len=addrs_len+p->payload->length;
|
||||
@ -332,8 +329,6 @@ int overlay_frame_set_neighbour_as_source(overlay_frame *f,overlay_neighbour *n)
|
||||
{
|
||||
if (!n) return WHY("Neighbour was null");
|
||||
bcopy(n->node->sid,f->source,SID_SIZE);
|
||||
f->source_address_status=OA_RESOLVED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -341,16 +336,12 @@ int overlay_frame_set_neighbour_as_destination(overlay_frame *f,overlay_neighbou
|
||||
{
|
||||
if (!n) return WHY("Neighbour was null");
|
||||
bcopy(n->node->sid,f->destination,SID_SIZE);
|
||||
f->destination_address_status=OA_RESOLVED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_frame_set_broadcast_as_destination(overlay_frame *f)
|
||||
{
|
||||
overlay_broadcast_generate_address(f->destination);
|
||||
f->destination_address_status=OA_RESOLVED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -378,8 +369,5 @@ int overlay_frame_set_me_as_source(overlay_frame *f)
|
||||
unsigned char *sid=overlay_get_my_sid();
|
||||
if (!sid) return WHY("overlay_get_my_sid() failed.");
|
||||
bcopy(sid,f->source,SID_SIZE);
|
||||
|
||||
f->source_address_status=OA_RESOLVED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
308
overlay_route.c
308
overlay_route.c
@ -367,6 +367,12 @@ int overlay_get_nexthop(unsigned char *d,unsigned char *nexthop,int *interface)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (*d==0){
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("No open path to %s, invalid sid",alloca_tohex_sid(d));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (overlay_broadcast_drop_check(d)) return WHY("I have sent that broadcast frame before");
|
||||
if (overlay_address_is_broadcast(d)) {
|
||||
bcopy(&d[0],&nexthop[0],SID_SIZE);
|
||||
@ -375,65 +381,71 @@ int overlay_get_nexthop(unsigned char *d,unsigned char *nexthop,int *interface)
|
||||
|
||||
if (!overlay_neighbours) return WHY("I have no neighbours");
|
||||
|
||||
overlay_neighbour *direct_neighbour=overlay_route_get_neighbour_structure(d,SID_SIZE,
|
||||
0 /* don't create if
|
||||
missing */);
|
||||
|
||||
if (direct_neighbour) {
|
||||
overlay_node *n=overlay_route_find_node(d,SID_SIZE,0 /* don't create if missing */ );
|
||||
if (!n){
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("No open path to %s, unknown peer",alloca_tohex_sid(d));
|
||||
return -1;
|
||||
}
|
||||
|
||||
long long now = overlay_gettime_ms();
|
||||
overlay_neighbour *direct_neighbour=NULL;
|
||||
|
||||
if (n->neighbour_id){
|
||||
direct_neighbour = &overlay_neighbours[n->neighbour_id];
|
||||
overlay_route_recalc_neighbour_metrics(direct_neighbour, now);
|
||||
/* Is a direct neighbour.
|
||||
So in the absence of any better indirect route, we pick the interface that
|
||||
we can hear this neighbour on the most reliably, and then send the frame
|
||||
via that interface and directly addressed to the recipient. */
|
||||
bcopy(d,nexthop,SID_SIZE);
|
||||
|
||||
*interface=0;
|
||||
for(i=1;i<OVERLAY_MAX_INTERFACES;i++) {
|
||||
if (direct_neighbour->scores[i]>direct_neighbour->scores[*interface]) *interface=i;
|
||||
}
|
||||
if (direct_neighbour->scores[*interface]>0) {
|
||||
if (0) DEBUGF("nexthop is %s",alloca_tohex_sid(nexthop));
|
||||
return 0;
|
||||
bcopy(d,nexthop,SID_SIZE);
|
||||
if (0) DEBUGF("nexthop is %s",alloca_tohex_sid(nexthop));
|
||||
return 0;
|
||||
}
|
||||
// otherwise fall through
|
||||
}
|
||||
|
||||
{
|
||||
/* Is not a direct neighbour.
|
||||
XXX - Very simplistic for now. */
|
||||
overlay_node *n=overlay_route_find_node(d,SID_SIZE,0 /* don't create if missing */ );
|
||||
if (n) {
|
||||
int o;
|
||||
int best_score=0;
|
||||
int best_o=-1;
|
||||
for(o=0;o<OVERLAY_MAX_OBSERVATIONS;o++) {
|
||||
int score=n->observations[o].observed_score;
|
||||
overlay_neighbour *neighbour
|
||||
=overlay_route_get_neighbour_structure
|
||||
(n->observations[o].sender_prefix,OVERLAY_SENDER_PREFIX_LENGTH,0);
|
||||
if (neighbour && neighbour!=direct_neighbour) {
|
||||
for(i=1;i<OVERLAY_MAX_INTERFACES;i++) {
|
||||
if (neighbour->scores[i]*score>best_score) {
|
||||
bcopy(&neighbour->node->sid[0],&nexthop[0],SID_SIZE);
|
||||
*interface=i;
|
||||
best_o=o;
|
||||
best_score=score;
|
||||
}
|
||||
}
|
||||
/* Is not a direct neighbour.
|
||||
XXX - Very simplistic for now. */
|
||||
int o;
|
||||
int best_score=0;
|
||||
int best_o=-1;
|
||||
for(o=0;o<OVERLAY_MAX_OBSERVATIONS;o++) {
|
||||
int score=n->observations[o].observed_score;
|
||||
|
||||
if (!score)
|
||||
continue;
|
||||
|
||||
overlay_neighbour *neighbour
|
||||
=overlay_route_get_neighbour_structure
|
||||
(n->observations[o].sender_prefix,OVERLAY_SENDER_PREFIX_LENGTH,0);
|
||||
|
||||
if (neighbour && neighbour!=direct_neighbour) {
|
||||
overlay_route_recalc_neighbour_metrics(neighbour, now);
|
||||
|
||||
for(i=1;i<OVERLAY_MAX_INTERFACES;i++) {
|
||||
if (neighbour->scores[i]*score>best_score) {
|
||||
bcopy(&neighbour->node->sid[0],&nexthop[0],SID_SIZE);
|
||||
*interface=i;
|
||||
best_o=o;
|
||||
best_score=score;
|
||||
}
|
||||
}
|
||||
if (best_o>-1) {
|
||||
return 0;
|
||||
} else {
|
||||
if (1||debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("No open path to %s, no good neighbour observations",alloca_tohex_sid(d));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (1||debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("No open path to %s, unknown peer",alloca_tohex_sid(d));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (best_o>-1) {
|
||||
return 0;
|
||||
} else {
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("No open path to %s, no good neighbour observations",alloca_tohex_sid(d));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int overlay_route_hash_sid(const unsigned char *sid)
|
||||
@ -451,20 +463,19 @@ unsigned int overlay_route_hash_sid(const unsigned char *sid)
|
||||
|
||||
/* Mask out extranous bits to return only a valid bin number */
|
||||
bin&=(overlay_bin_count-1);
|
||||
if (debug&DEBUG_OVERLAYROUTING) {
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("Address %s resolves to bin #%d", alloca_tohex_sid(sid), bin);
|
||||
int zeroes=0;
|
||||
for (i=0;i<SID_SIZE;i++)
|
||||
if (!sid[i])
|
||||
zeroes++;
|
||||
if (zeroes>8)
|
||||
DEBUG("Looks like corrupt memory or packet!");
|
||||
}
|
||||
|
||||
return bin;
|
||||
}
|
||||
|
||||
overlay_node *overlay_route_find_node(const unsigned char *sid, int prefixLen, int createP)
|
||||
{
|
||||
if (*sid==0 || prefixLen<overlay_route_hash_bytes){
|
||||
INFOF("Sid %s/%d cannot ever become a node!", alloca_tohex_sid(sid), prefixLen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int bin_number = overlay_route_hash_sid(sid);
|
||||
if (bin_number < 0) {
|
||||
WHY("negative bin number");
|
||||
@ -472,15 +483,24 @@ overlay_node *overlay_route_find_node(const unsigned char *sid, int prefixLen, i
|
||||
}
|
||||
|
||||
int free_slot = -1;
|
||||
overlay_node *found=NULL;
|
||||
{
|
||||
int slot;
|
||||
for (slot = 0; slot < overlay_bin_size; slot++)
|
||||
if (memcmp(sid, overlay_nodes[bin_number][slot].sid, prefixLen) == 0)
|
||||
return &overlay_nodes[bin_number][slot];
|
||||
else if (overlay_nodes[bin_number][slot].sid[0]==0)
|
||||
if (overlay_nodes[bin_number][slot].sid[0]==0)
|
||||
free_slot = slot;
|
||||
else if (memcmp(sid, overlay_nodes[bin_number][slot].sid, prefixLen) == 0){
|
||||
if (found){
|
||||
INFOF("SID prefix %d %s is not unique", prefixLen, alloca_tohex_sid(sid));
|
||||
return NULL;
|
||||
}
|
||||
found = &overlay_nodes[bin_number][slot];
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
return found;
|
||||
|
||||
/* Didn't find it */
|
||||
if (!createP) return NULL;
|
||||
|
||||
@ -565,10 +585,7 @@ int overlay_route_ack_selfannounce(overlay_frame *f,
|
||||
has not yet begun to be built), then we need to set the nexthop to broadcast. */
|
||||
out->nexthop_address_status=OA_UNINITIALISED;
|
||||
{
|
||||
unsigned char nexthop[SID_SIZE];
|
||||
int next_hop_interface=-1;
|
||||
int r=overlay_get_nexthop(out->destination,nexthop,&next_hop_interface);
|
||||
if (r) {
|
||||
if (overlay_resolve_next_hop(out)) {
|
||||
/* no open path, so convert to broadcast */
|
||||
int i;
|
||||
for(i=0;i<(SID_SIZE-8);i++) out->nexthop[i]=0xff;
|
||||
@ -678,23 +695,31 @@ int overlay_route_make_neighbour(overlay_node *n)
|
||||
overlay_neighbour *overlay_route_get_neighbour_structure(unsigned char *packed_sid,
|
||||
int prefixLen,int createP)
|
||||
{
|
||||
IN();
|
||||
if (overlay_address_is_local(packed_sid)) {
|
||||
WHY("asked for neighbour structure for myself");
|
||||
return NULL;
|
||||
RETURN(NULL);
|
||||
}
|
||||
|
||||
overlay_node *n=overlay_route_find_node(packed_sid,prefixLen,createP);
|
||||
if (!n) {
|
||||
// WHY("Could not find node record for observed node");
|
||||
return NULL;
|
||||
RETURN(NULL);
|
||||
}
|
||||
|
||||
/* Check if node is already a neighbour, or if not, make it one */
|
||||
if (!n->neighbour_id) if (overlay_route_make_neighbour(n)) { WHY("overlay_route_make_neighbour() failed"); return NULL; }
|
||||
if (!n->neighbour_id){
|
||||
if (!createP)
|
||||
RETURN(NULL);
|
||||
|
||||
if (overlay_route_make_neighbour(n)) {
|
||||
WHY("overlay_route_make_neighbour() failed");
|
||||
RETURN(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get neighbour structure */
|
||||
return &overlay_neighbours[n->neighbour_id];
|
||||
|
||||
RETURN(&overlay_neighbours[n->neighbour_id]);
|
||||
}
|
||||
|
||||
int overlay_route_i_can_hear_node(unsigned char *who,int sender_interface,
|
||||
@ -715,44 +740,24 @@ int overlay_route_node_can_hear_me(unsigned char *who,int sender_interface,
|
||||
2. Replace oldest observation with this observation.
|
||||
3. Update score of how reliably we can hear this node */
|
||||
|
||||
/* Ignore traffic from ourselves. */
|
||||
if (overlay_address_is_local(who))
|
||||
{
|
||||
DEBUGF("I can hear myself. How odd");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find node, or create entry if it hasn't been seen before */
|
||||
overlay_node *n=overlay_route_find_node(who,SID_SIZE,1 /* create if necessary */);
|
||||
if (!n) return WHY("Could not find node record for observed node");
|
||||
|
||||
/* Check if node is already a neighbour, or if not, make it one */
|
||||
if (!n->neighbour_id) if (overlay_route_make_neighbour(n)) return WHY("overlay_route_make_neighbour() failed");
|
||||
|
||||
/* Get neighbour structure */
|
||||
if (n->neighbour_id<0||n->neighbour_id>overlay_max_neighbours)
|
||||
{ WHY("n->neighbour_id set to illegal value");
|
||||
return -1;
|
||||
}
|
||||
overlay_neighbour *neh=&overlay_neighbours[n->neighbour_id];
|
||||
|
||||
overlay_neighbour *neh=overlay_route_get_neighbour_structure(who,SID_SIZE,1 /* create if necessary */);
|
||||
if (!neh)
|
||||
return -1;
|
||||
|
||||
int obs_index=neh->most_recent_observation_id;
|
||||
int mergedP=0;
|
||||
int merge=0;
|
||||
|
||||
/* See if this observation is contiguous with a previous one, if so, merge.
|
||||
This not only reduces the number of observation slots we need, but dramatically speeds up
|
||||
the scanning of recent observations when re-calculating observation scores. */
|
||||
while (neh->observations[obs_index].valid&&(neh->observations[obs_index].s2>=(s1-1)))
|
||||
while (neh->observations[obs_index].valid && (neh->observations[obs_index].s2>=(s1-1)))
|
||||
{
|
||||
if (neh->observations[obs_index].sender_interface==sender_interface)
|
||||
{
|
||||
if (0) DEBUGF("merging observation in slot #%d",obs_index);
|
||||
if (!neh->observations[obs_index].s1)
|
||||
neh->observations[obs_index].s1=neh->observations[obs_index].s2;
|
||||
neh->observations[obs_index].s2=s2;
|
||||
neh->observations[obs_index].sender_interface=sender_interface;
|
||||
neh->observations[obs_index].time_ms=now;
|
||||
mergedP=1;
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("merging observation in slot #%d",obs_index);
|
||||
merge=1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -760,25 +765,28 @@ int overlay_route_node_can_hear_me(unsigned char *who,int sender_interface,
|
||||
if (obs_index<0) obs_index=OVERLAY_MAX_OBSERVATIONS-1;
|
||||
}
|
||||
|
||||
if (!mergedP) {
|
||||
if (!merge) {
|
||||
/* Replace oldest observation with this one */
|
||||
obs_index=neh->most_recent_observation_id+1;
|
||||
if (obs_index>=OVERLAY_MAX_OBSERVATIONS) obs_index=0;
|
||||
if (0) DEBUGF("storing observation in slot #%d",obs_index);
|
||||
neh->observations[obs_index].valid=0;
|
||||
neh->observations[obs_index].time_ms=now;
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("storing observation in slot #%d",obs_index);
|
||||
neh->observations[obs_index].s1=s1;
|
||||
neh->observations[obs_index].s2=s2;
|
||||
neh->observations[obs_index].sender_interface=sender_interface;
|
||||
neh->observations[obs_index].valid=1;
|
||||
}
|
||||
|
||||
neh->observations[obs_index].s2=s2;
|
||||
neh->observations[obs_index].sender_interface=sender_interface;
|
||||
neh->observations[obs_index].time_ms=now;
|
||||
neh->observations[obs_index].valid=1;
|
||||
|
||||
neh->most_recent_observation_id=obs_index;
|
||||
neh->last_observation_time_ms=now;
|
||||
/* force updating of stats for neighbour if we have added an observation */
|
||||
neh->last_metric_update=0;
|
||||
|
||||
/* Update reachability metrics for node */
|
||||
if (overlay_route_recalc_neighbour_metrics(neh,now)) WHY("overlay_route_recalc_neighbour_metrics() failed");
|
||||
if (overlay_route_recalc_neighbour_metrics(neh,now))
|
||||
return -1;
|
||||
|
||||
if (debug&DEBUG_OVERLAYROUTEMONITOR) overlay_route_dump();
|
||||
return 0;
|
||||
@ -786,25 +794,20 @@ int overlay_route_node_can_hear_me(unsigned char *who,int sender_interface,
|
||||
|
||||
int overlay_route_saw_selfannounce(overlay_frame *f,long long now)
|
||||
{
|
||||
if (overlay_address_is_local(f->source)) return 0;
|
||||
|
||||
IN();
|
||||
unsigned int s1,s2;
|
||||
unsigned char sender_interface;
|
||||
overlay_neighbour *n=overlay_route_get_neighbour_structure(f->source,SID_SIZE,
|
||||
1 /* make neighbour if not yet one */);
|
||||
|
||||
if (!n) return WHY("overlay_route_get_neighbour_structure() failed");
|
||||
if (!n){
|
||||
RETURN(-1);
|
||||
}
|
||||
|
||||
/* Record current sender for reference by addresses in subsequent frames in the
|
||||
ensemble */
|
||||
overlay_abbreviate_set_current_sender(f->source);
|
||||
|
||||
/* Ignore self announcements from ourselves */
|
||||
if (overlay_address_is_local(f->source)) {
|
||||
if(0) DEBUG("Ignoring selfannouncement from myself");
|
||||
return 0;
|
||||
}
|
||||
|
||||
s1=ntohl(*((int*)&f->payload->bytes[0]));
|
||||
s2=ntohl(*((int*)&f->payload->bytes[4]));
|
||||
sender_interface=f->payload->bytes[8];
|
||||
@ -815,17 +818,9 @@ int overlay_route_saw_selfannounce(overlay_frame *f,long long now)
|
||||
|
||||
overlay_route_i_can_hear_node(f->source,sender_interface,s1,s2,now);
|
||||
|
||||
/* Ignore self-announcements from ourself. */
|
||||
if (overlay_address_is_local(&f->source[0]))
|
||||
{
|
||||
// XXX But we should make note that we have loop-back to this interface
|
||||
WHY("One or more interfaces loops back to this one, or someone is naughtily forwarding packets between interfaces.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
overlay_route_ack_selfannounce(f,s1,s2,sender_interface,n);
|
||||
|
||||
return 0;
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
/* XXX Think about scheduling this node's score for readvertising? */
|
||||
@ -908,9 +903,16 @@ int overlay_route_recalc_neighbour_metrics(overlay_neighbour *n,long long now)
|
||||
int i;
|
||||
long long most_recent_observation=0;
|
||||
|
||||
if (!n->node)
|
||||
return 0;
|
||||
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("Updating neighbour metrics for %s", alloca_tohex_sid(n->node->sid));
|
||||
|
||||
/* Only update every half-second */
|
||||
if ((now-n->last_metric_update)<500) {
|
||||
if (0) DEBUGF("refusing to update metric too often (last at %lldms, now=%lldms)",
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("refusing to update metric too often (last at %lldms, now=%lldms)",
|
||||
n->last_metric_update,now);
|
||||
return 0;
|
||||
}
|
||||
@ -939,7 +941,8 @@ int overlay_route_recalc_neighbour_metrics(overlay_neighbour *n,long long now)
|
||||
|
||||
/* Check the observation age, and ignore if too old */
|
||||
int obs_age=now-n->observations[i].time_ms;
|
||||
if (0) DEBUGF("tallying obs: %dms old, %dms long", obs_age,interval);
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("tallying obs: %dms old, %dms long", obs_age,interval);
|
||||
if (obs_age>200000) continue;
|
||||
|
||||
/* Ignore very large intervals (>1hour) as being likely to be erroneous.
|
||||
@ -950,7 +953,7 @@ int overlay_route_recalc_neighbour_metrics(overlay_neighbour *n,long long now)
|
||||
on an expensive BGAN satellite link.
|
||||
*/
|
||||
if (interval<3600000) {
|
||||
if (debug&DEBUG_VERBOSE_IO)
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("adding %dms (interface %d '%s')",
|
||||
interval,n->observations[i].sender_interface,
|
||||
overlay_interfaces[n->observations[i].sender_interface].name);
|
||||
@ -959,8 +962,9 @@ int overlay_route_recalc_neighbour_metrics(overlay_neighbour *n,long long now)
|
||||
if (n->observations[i].sender_interface<OVERLAY_MAX_INTERFACES)
|
||||
{
|
||||
ms_observed_200sec[n->observations[i].sender_interface]+=interval;
|
||||
if (obs_age<=5000)
|
||||
ms_observed_5sec[n->observations[i].sender_interface]+=interval;
|
||||
if (obs_age<=5000){
|
||||
ms_observed_5sec[n->observations[i].sender_interface]+=(interval>5000?5000:interval);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -987,19 +991,19 @@ int overlay_route_recalc_neighbour_metrics(overlay_neighbour *n,long long now)
|
||||
int contrib_200=ms_observed_200sec[i]/(200000/128);
|
||||
int contrib_5=ms_observed_5sec[i]/(5000/128);
|
||||
|
||||
if (contrib_5<1) score=contrib_200/2; else
|
||||
score=contrib_5+contrib_200;
|
||||
if (contrib_5<1)
|
||||
score=contrib_200/2;
|
||||
else
|
||||
score=contrib_5+contrib_200;
|
||||
|
||||
/* Deal with invalid sequence number ranges */
|
||||
if (score<0) score=0; if (score>255) score=255;
|
||||
if (score<1) score=1;
|
||||
if (score>255) score=255;
|
||||
}
|
||||
|
||||
/* Reduce score by 1 point for each second we have not seen anything from it */
|
||||
score-=(now-most_recent_observation)/1000;
|
||||
if (score<0) score=0;
|
||||
|
||||
n->scores[i]=score;
|
||||
if ((debug&DEBUG_OVERLAYROUTING)&&score) DEBUGF("Neighbour score on interface #%d = %d (observations for %dms)",i,score,ms_observed_200sec[i]);
|
||||
if ((debug&DEBUG_OVERLAYROUTING)&&score)
|
||||
DEBUGF("Neighbour score on interface #%d = %d (observations for %dms)",i,score,ms_observed_200sec[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1029,9 +1033,12 @@ int overlay_route_recalc_neighbour_metrics(overlay_neighbour *n,long long now)
|
||||
*/
|
||||
int overlay_route_saw_selfannounce_ack(overlay_frame *f,long long now)
|
||||
{
|
||||
if (0) DEBUGF("processing selfannounce ack (payload length=%d)",f->payload->length);
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("processing selfannounce ack (payload length=%d)",f->payload->length);
|
||||
|
||||
if (!overlay_neighbours) {
|
||||
if (0) DEBUG("no neighbours, so returning immediately");
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUG("no neighbours, so returning immediately");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1043,15 +1050,8 @@ int overlay_route_saw_selfannounce_ack(overlay_frame *f,long long now)
|
||||
int iface=f->payload->bytes[8];
|
||||
|
||||
// Call something like the following for each link
|
||||
if (f->source_address_status==OA_RESOLVED&&
|
||||
f->destination_address_status==OA_RESOLVED) {
|
||||
if (0) DEBUGF("f->source=%s, f->destination=%s",
|
||||
alloca_tohex_sid(f->source),alloca_tohex_sid(f->destination));
|
||||
overlay_route_record_link(now,f->source,f->source,iface,s1,s2,
|
||||
0 /* no associated score */,
|
||||
0 /* no gateways in between */);
|
||||
} else WHY("address(es) not resolved");
|
||||
|
||||
overlay_route_node_can_hear_me(f->source,iface,s1,s2,now);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1068,25 +1068,9 @@ int overlay_route_record_link(long long now,unsigned char *to,
|
||||
score, gateways_en_route
|
||||
);
|
||||
|
||||
if (sender_interface>OVERLAY_MAX_INTERFACES) return 0;
|
||||
|
||||
/* Don't record routes to ourselves */
|
||||
if (overlay_address_is_local(to)) {
|
||||
if (sender_interface>OVERLAY_MAX_INTERFACES || score == 0) {
|
||||
if (debug & DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("Ignore self announce ack addressed to me (%s)", alloca_tohex_sid(to));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (memcmp(to, via, SID_SIZE) == 0) {
|
||||
/* It's a neighbour observation */
|
||||
if (debug & DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("%s is my neighbour", alloca_tohex_sid(to));
|
||||
overlay_route_node_can_hear_me(to,sender_interface,s1,s2,now);
|
||||
}
|
||||
|
||||
if (score == 0) {
|
||||
if (debug & DEBUG_OVERLAYROUTING)
|
||||
DEBUG("non-scoring report");
|
||||
DEBUG("invalid report");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1250,6 +1234,9 @@ void overlay_route_tick(struct sched_ent *alarm)
|
||||
overlay_route_tick_node_bundle_size,overlay_route_tick_next_node_bin_id);
|
||||
|
||||
/* Go through some of neighbour list */
|
||||
|
||||
// TODO This doesn't seem to be reliable
|
||||
// note that neighbour metrics are now re-calculated in overlay_get_nexthop when we need them
|
||||
n=overlay_route_tick_neighbour_bundle_size;
|
||||
if (n<1) n=1;
|
||||
while(n--)
|
||||
@ -1318,8 +1305,9 @@ void overlay_route_tick(struct sched_ent *alarm)
|
||||
taking into account the age of the most recent observation */
|
||||
int overlay_route_tick_neighbour(int neighbour_id,long long now)
|
||||
{
|
||||
if (overlay_route_recalc_neighbour_metrics(&overlay_neighbours[neighbour_id],now))
|
||||
WHY("overlay_route_recalc_neighbour_metrics() failed");
|
||||
if (neighbour_id>0)
|
||||
if (overlay_route_recalc_neighbour_metrics(&overlay_neighbours[neighbour_id],now))
|
||||
WHY("overlay_route_recalc_neighbour_metrics() failed");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -115,7 +115,8 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
ob_append_byte(e,OA_CODE_BROADCAST);
|
||||
{ int i; for(i=0;i<8;i++) ob_append_byte(e,random()&0xff); } /* BPI for broadcast */
|
||||
ob_append_byte(e,OA_CODE_PREVIOUS);
|
||||
ob_append_byte(e,OA_CODE_SELF);
|
||||
overlay_abbreviate_clear_most_recent_address();
|
||||
overlay_abbreviate_append_address(e, overlay_get_my_sid());
|
||||
|
||||
/* Randomly choose whether to advertise manifests or BARs first. */
|
||||
int skipmanifests=random()&1;
|
||||
|
8
serval.h
8
serval.h
@ -445,19 +445,13 @@ typedef struct overlay_frame {
|
||||
int nexthop_interface; /* which interface the next hop should be attempted on */
|
||||
|
||||
unsigned char destination[32];
|
||||
int destination_address_status;
|
||||
|
||||
unsigned char source[32];
|
||||
int source_address_status;
|
||||
|
||||
/* IPv4 node frame was received from (if applicable) */
|
||||
struct sockaddr *recvaddr;
|
||||
|
||||
/* Frame content from destination address onwards */
|
||||
int bytecount;
|
||||
unsigned char *bytes;
|
||||
|
||||
/* Actual payload */
|
||||
// TODO refactor *all* packet parsing so that the payload is not copied or allocated unless it must be forwarded.
|
||||
struct overlay_buffer *payload;
|
||||
|
||||
int rfs; /* remainder of frame size */
|
||||
|
Loading…
x
Reference in New Issue
Block a user