mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-20 21:53:12 +00:00
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:
parent
552d0095f0
commit
8aa57edee3
11
mphlr.h
11
mphlr.h
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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:
|
||||
|
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user