diff --git a/mphlr.h b/mphlr.h index 6cc3c35b..40bde832 100644 --- a/mphlr.h +++ b/mphlr.h @@ -372,6 +372,36 @@ int packetSendRequest(int method,unsigned char *packet,int packet_len,int batchP unsigned char *transaction_id,struct sockaddr *recvaddr, struct response_set *responses); +typedef struct overlay_address_table { + unsigned char epoch; + char sids[256][SID_SIZE]; + /* 0x00 = not set, which thus limits us to using only 255 (0x01-0xff) of the indexes for + storing addresses. + By spending an extra 256 bytes we reduce, but not eliminate the problem of collisions. + Will think about a complete solution later. + */ + unsigned char byfirstbyte[256][2]; + /* next free entry in sid[] */ + unsigned char next_free; +} overlay_address_table; + +typedef struct sid { + unsigned char b[SID_SIZE]; +} sid; + +typedef struct overlay_address_cache { + int size; + int shift; /* Used to calculat lookup function, which is (b[0].b[1].b[2]>>shift) */ + sid *sids; /* one entry per bucket, to keep things simple. */ + /* XXX Should have a means of changing the hash function so that naughty people can't try + to force our cache to flush with duplicate addresses? + But we must use only the first 24 bits of the address due to abbreviation policies, + so our options are limited. + For now the hash will be the first k bits. + */ +} overlay_address_cache; + +extern sid overlay_abbreviate_current_sender; typedef struct overlay_frame { struct overlay_frame *prev; @@ -812,3 +842,5 @@ extern int overlay_bin_count; extern int overlay_bin_size; /* associativity, i.e., entries per bin */ extern int overlay_bin_bytes; extern overlay_node **overlay_nodes; + +int overlay_route_saw_advertisements(int i,overlay_frame *f, long long now); diff --git a/overlay.c b/overlay.c index e4ef142d..a6505fc2 100644 --- a/overlay.c +++ b/overlay.c @@ -250,6 +250,9 @@ int overlay_frame_process(int interface,overlay_frame *f) case OF_TYPE_SELFANNOUNCE_ACK: overlay_route_saw_selfannounce_ack(interface,f,now); break; + case OF_TYPE_NODEANNOUNCE: + overlay_route_saw_advertisements(interface,f,now); + break; default: fprintf(stderr,"Unsupported f->type=0x%x\n",f->type); return WHY("Support for that f->type not yet implemented"); @@ -258,3 +261,4 @@ int overlay_frame_process(int interface,overlay_frame *f) return 0; } + diff --git a/overlay_abbreviations.c b/overlay_abbreviations.c index 8151c8a7..aab48a67 100644 --- a/overlay_abbreviations.c +++ b/overlay_abbreviations.c @@ -100,35 +100,6 @@ */ -typedef struct overlay_address_table { - unsigned char epoch; - char sids[256][SID_SIZE]; - /* 0x00 = not set, which thus limits us to using only 255 (0x01-0xff) of the indexes for - storing addresses. - By spending an extra 256 bytes we reduce, but not eliminate the problem of collisions. - Will think about a complete solution later. - */ - unsigned char byfirstbyte[256][2]; - /* next free entry in sid[] */ - unsigned char next_free; -} overlay_address_table; - -typedef struct sid { - unsigned char b[SID_SIZE]; -} sid; - -typedef struct overlay_address_cache { - int size; - int shift; /* Used to calculat lookup function, which is (b[0].b[1].b[2]>>shift) */ - sid *sids; /* one entry per bucket, to keep things simple. */ - /* XXX Should have a means of changing the hash function so that naughty people can't try - to force our cache to flush with duplicate addresses? - But we must use only the first 24 bits of the address due to abbreviation policies, - so our options are limited. - For now the hash will be the first k bits. - */ -} overlay_address_cache; - overlay_address_table *abbrs=NULL; overlay_address_cache *cache=NULL; diff --git a/overlay_advertise.c b/overlay_advertise.c index bb01602e..879376ec 100644 --- a/overlay_advertise.c +++ b/overlay_advertise.c @@ -144,3 +144,65 @@ int overlay_route_add_advertisements(int interface,overlay_buffer *e) return 0; } + +/* Pull out the advertisements and update our routing table accordingly. + Because we are using a non-standard abbreviation scheme, we have to extract + and search for the nodes ourselves. + + Also, we need to discount the scores based on the score of the sender. + We can either do this once now (more computationally efficient), or have + a rather complicated scheme whereby we attempt to trace through the list + of nodes from here to there. That seems silly, and is agains't the BATMAN + approach of each node just knowing single-hop information. + */ +int overlay_route_saw_advertisements(int i,overlay_frame *f, long long now) +{ + int ofs=0; + + /* lookup score of current sender */ + overlay_node *sender=overlay_route_find_node(f->source,0); + int sender_score=sender->best_link_score; + fprintf(stderr,"score to reach %s is %d\n", + overlay_render_sid(f->source),sender_score); + + while(ofspayload->length) + { + unsigned char to[SID_SIZE]; + int out_len=0; + int r + =overlay_abbreviate_cache_lookup(&f->payload->bytes[ofs],to,&out_len, + 6 /* prefix length */, + 0 /* no index code to process */); + int score=f->payload->bytes[6]; + int gateways_en_route=f->payload->bytes[7]; + + + /* 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], + time(0) /* XXX should this be in senders timeframe? + Should we be sending time stamps around + so that we know when the last actual + sighting of a node really was? + (probably a waste of time since we decay + scores from stale observations) */, + score,gateways_en_route); + } else if (r==OA_PLEASEEXPLAIN) { + /* Unresolved address -- ask someone to resolve it for us. */ + WHY("Dispatch PLEASEEXPLAIN not implemented"); + } + } + + ofs+=8; + } + + return 0; +} diff --git a/overlay_route.c b/overlay_route.c index f2ae266e..0128b6e1 100644 --- a/overlay_route.c +++ b/overlay_route.c @@ -684,6 +684,18 @@ int overlay_route_recalc_node_metrics(overlay_node *n,long long now) } } + if (n->neighbour_id) + { + /* Node is also a direct neighbour, so check score that way */ + int i; + for(i=0;ineighbour_id].scores[i]>best_score) + { + best_score=overlay_neighbours[n->neighbour_id].scores[i]; + best_observation=-1; + } + } + /* Think about scheduling this node's score for readvertising if its score has changed a lot? Really what we probably want is to advertise when the score goes up, since @@ -934,7 +946,8 @@ int overlay_route_dump() { if (!overlay_nodes[bin][slot].sid[0]) continue; - fprintf(stderr," %s* :",overlay_render_sid_prefix(overlay_nodes[bin][slot].sid,7)); + fprintf(stderr," %s* : %d :",overlay_render_sid_prefix(overlay_nodes[bin][slot].sid,7), + overlay_nodes[bin][slot].best_link_score); for(o=0;o