Added code to add node advertisements to interface tick packets.

Looks like it works.  No code to decode it yet.
This commit is contained in:
gardners 2011-09-13 04:52:52 +09:30
parent 552d0095f0
commit 8aa57edee3
6 changed files with 165 additions and 7 deletions

11
mphlr.h
View File

@ -629,7 +629,7 @@ extern int overlay_interface_count;
1 byte channel/port indicator for each end */
#define OF_TYPE_RHIZOME_ADVERT 0x50 /* Advertisment of file availability via Rhizome */
#define OF_TYPE_PLEASEEXPLAIN 0x60 /* Request for resolution of an abbreviated address */
#define OF_TYPE_RESERVED_07 0x70
#define OF_TYPE_NODEANNOUNCE 0x70
#define OF_TYPE_RESERVED_08 0x80
#define OF_TYPE_RESERVED_09 0x90
#define OF_TYPE_RESERVED_0a 0xa0
@ -683,7 +683,7 @@ int overlay_abbreviate_set_most_recent_address(unsigned char *in);
/* Codes used to describe abbreviated addresses.
Values 0x10 - 0xff are the first byte of, and implicit indicators of addresses written in full */
#define OA_CODE_00 0x00
#define OA_CODE_SELF 0x00
#define OA_CODE_INDEX 0x01
#define OA_CODE_02 0x02
#define OA_CODE_PREVIOUS 0x03
@ -805,3 +805,10 @@ int overlay_route_tick();
int overlay_route_tick_neighbour(int neighbour_id,long long now);
int overlay_route_tick_node(int bin,int slot,long long now);
int overlay_route_add_advertisements(int interface,overlay_buffer *e);
int ovleray_route_please_advertise(overlay_node *n);
int overlay_abbreviate_set_current_sender(unsigned char *in);
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;

View File

@ -324,12 +324,20 @@ int overlay_abbreviate_expand_address(int interface,unsigned char *in,int *inofs
if (debug>3) fprintf(stderr,"Address first byte/abbreviation code=%02x (input offset=%d)\n",in[*inofs],*inofs);
switch(in[*inofs])
{
case OA_CODE_00: case OA_CODE_02: case OA_CODE_04: case OA_CODE_0C:
case OA_CODE_02: case OA_CODE_04: case OA_CODE_0C:
/* Unsupported codes, so tell the sender
if the frame was addressed to us as next-hop */
(*inofs)++;
WHY("Reserved address abbreviation code");
return OA_UNSUPPORTED;
case OA_CODE_SELF: /* address matches the sender who produced the
selfannounce in this packet. Naturally it cannot be
used to encode the sender's address there ;) */
(*inofs)++;
bcopy(&overlay_abbreviate_current_sender.b[0],&out[*ofs],SID_SIZE);
overlay_abbreviate_set_most_recent_address(&out[*ofs]);
(*ofs)+=SID_SIZE;
return OA_RESOLVED;
case OA_CODE_INDEX: /* single byte index look up */
/* Lookup sender's neighbour ID */
if (overlay_abbreviate_current_sender_id==-1) if (overlay_abbreviate_lookup_sender_id()) return WHY("could not lookup neighbour ID of packet sender");

View File

@ -1,12 +1,146 @@
#include "mphlr.h"
/* List of prioritised advertisements */
#define OVERLAY_MAX_ADVERTISEMENT_REQUESTS 16
overlay_node *oad_requests[OVERLAY_MAX_ADVERTISEMENT_REQUESTS];
int oad_request_count=0;
/* Where we are up to in the node list for round-robin advertising */
int oad_bin=0;
int oad_slot=0;
/* Which round of the node list we are up to.
This is used for reducing the advertisement rate for stable nodes.
Initially this will just mean advertising higher-scoring nodes
less often.
Our goal is to advertise all nodes often enough to maintain connectivity,
without wasting any packets.
Basically high-scoring nodes can be advertised less often than low-scoring
nodes.
Let's advertise nodes <100 every round, <200 every 2 rounds, and >=200
every 4th round.
*/
int oad_round=0;
/* Request that this node be advertised as a matter of priority */
int overlay_route_please_advertise(overlay_node *n)
{
return WHY("Not implemented");
if (oad_request_count<OVERLAY_MAX_ADVERTISEMENT_REQUESTS)
{
oad_requests[oad_request_count++]=n;
return 0;
}
else return 1;
}
int overlay_route_add_advertisements(int interface,overlay_buffer *e)
{
return WHY("Not implemented");
/* Construct a route advertisement frame and append it to e.
Work out available space in packet for advertisments, and fit the
highest scoring nodes from the current portion in.
Each advertisement consists of an address prefix followed by score.
We will use 6 bytes of prefix to make it reasonably hard to generate
collisions, including by birthday paradox (good for networks upto about
20million nodes), and one byte each for score gateways_en_route.
XXX - We need to send full addresses sometimes so that receiver can
resolve them. Either that or we need to start supporting the PLEASEEXPLAIN
packets, which is probably a better solution.
The receiver will discount the score based on their measured reliability
for packets to arrive from us; we just repeat what discounted score
we have remembered.
Hacking the frame together this way is less flexible, but much faster
than messing about with malloc() and setting address fields.
The src,dst and nexthop can each be encoded with a single byte.
Thus using a fixed 1-byte RFS field we are limited to RFS<0xfa,
which gives us 30 available advertisement slots per packet.
*/
int i;
int bytes=e->sizeLimit-e->length;
int overhead=1+1+3+32+1+1; /* maximum overhead */
int slots=(bytes-overhead)/8;
if (slots>30) slots=30;
int slots_used=0;
if (slots<1) return WHY("No room for node advertisements");
if (ob_append_byte(e,OF_TYPE_NODEANNOUNCE))
return WHY("could not add node advertisement header");
ob_append_byte(e,1); /* TTL */
int rfs_offset=e->length; /* remember where the RFS byte gets stored
so that we can patch it later */
ob_append_byte(e,1+1+1+8*slots_used/* RFS */);
/* Stuff in dummy address fields */
ob_append_byte(e,OA_CODE_BROADCAST);
ob_append_byte(e,OA_CODE_BROADCAST);
ob_append_byte(e,OA_CODE_SELF);
int count;
while (slots>0&&oad_request_count) {
oad_request_count--;
ob_append_bytes(e,oad_requests[oad_request_count]->sid,6);
ob_append_byte(e,oad_requests[oad_request_count]->best_link_score);
ob_append_byte(e,oad_requests[oad_request_count]
->observations[oad_requests[oad_request_count]
->best_observation].gateways_en_route);
slots--;
slots_used++;
}
while(slots>0)
{
/* find next node */
int bin=oad_bin;
int slot=oad_slot;
/* XXX Skipping priority advertised nodes could be done faster, e.g.,
by adding a flag to the overlay_node structure to indicate if it
has been sent priority, and if so, skip it.
The flags could then be reset at the end of this function.
But this will do for now.
*/
int skip=0;
for(i=0;i<count;i++)
if (oad_requests[i]==&overlay_nodes[oad_bin][oad_slot])
skip=1;
if (!skip)
{
if(overlay_nodes[oad_bin][oad_slot].sid[0]) {
overlay_node *n=&overlay_nodes[oad_bin][oad_slot];
ob_append_bytes(e,n->sid,6);
ob_append_byte(e,n->best_link_score);
ob_append_byte(e,n->observations[n->best_observation].gateways_en_route);
slots--;
slots_used++;
}
}
/* Find next node */
oad_slot++;
if (oad_slot>=overlay_bin_size) { oad_slot=0; oad_bin++; }
/* Stop stuffing if we get to the end of the node list so that
we can implement an appropriate pause between rounds to avoid
unneeded repeated TX of nodes. */
if (oad_bin>=overlay_bin_count) { oad_bin=0; oad_round++; break; }
/* Stop if we have advertised everyone */
if (oad_bin==bin&&oad_slot==slot) break;
}
e->bytes[rfs_offset]=1+1+1+8*slots_used;
return 0;
}

View File

@ -541,7 +541,7 @@ int overlay_tick_interface(int i, long long now)
XXX we should also take account of the volume of data likely to be in the TX buffer. */
overlay_buffer *e=ob_new(overlay_interfaces[i].mtu);
if (!e) return WHY("ob_new() failed");
ob_limitsize(e,overlay_interfaces[i].mtu);
ob_limitsize(e,overlay_interfaces[i].mtu/4);
/* 0. Setup Serval Mesh frame header. We do not use an explicit length field for these, as the various
component payloads are all self-authenticating, or at least that is the theory. */
@ -557,14 +557,19 @@ int overlay_tick_interface(int i, long long now)
/* 2. Add any queued high-priority isochronous data (i.e. voice) to the frame. */
overlay_stuff_packet_from_queue(i,e,OQ_ISOCHRONOUS_VOICE,now,pax,&frame_pax,MAX_FRAME_PAX);
ob_limitsize(e,overlay_interfaces[i].mtu/2);
/* 3. Add some mesh reachability reports (unlike BATMAN we announce reachability to peers progressively).
Give priority to newly observed nodes so that good news travels quickly to help roaming.
XXX - Don't forget about PONGing reachability reports to allow use of monodirectional links.
*/
overlay_stuff_packet_from_queue(i,e,OQ_MESH_MANAGEMENT,now,pax,&frame_pax,MAX_FRAME_PAX);
ob_limitsize(e,overlay_interfaces[i].mtu*3/4);
overlay_route_add_advertisements(i,e);
ob_limitsize(e,overlay_interfaces[i].mtu);
/* 4. XXX Add lower-priority queued data */
/* 5. XXX Fill the packet up to a suitable size with anything that seems a good idea */

View File

@ -106,7 +106,7 @@ int packetOkOverlay(int interface,unsigned char *packet,int len,unsigned char *t
f.modifiers=0;
ofs+=2;
break;
case OF_TYPE_RESERVED_07:
case OF_TYPE_NODEANNOUNCE:
case OF_TYPE_RESERVED_08:
case OF_TYPE_RESERVED_09:
case OF_TYPE_RESERVED_0a:

View File

@ -646,6 +646,10 @@ int overlay_route_saw_selfannounce(int interface,overlay_frame *f,long long now)
if (!n) return WHY("overlay_route_get_neighbour_structure() failed");
/* Record current sender for reference by addresses in subsequent frames in the
ensemble */
overlay_abbreviate_set_current_sender(f->source);
s1=ntohl(*((int*)&f->payload->bytes[0]));
s2=ntohl(*((int*)&f->payload->bytes[4]));
sender_interface=f->payload->bytes[8];