mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-19 05:07:56 +00:00
Refactor routing node information to use new subscriber tree
This commit is contained in:
parent
30d5ed2b6d
commit
aa5706f9d7
@ -1704,8 +1704,9 @@ int app_node_info(int argc, const char *const *argv, struct command_line_option
|
||||
}
|
||||
|
||||
cli_printf("record"); cli_delim(":");
|
||||
cli_printf("%d",mdp.nodeinfo.index); cli_delim(":");
|
||||
cli_printf("%d",mdp.nodeinfo.count); cli_delim(":");
|
||||
// TODO remove these two unused output fields
|
||||
cli_printf("%d",1); cli_delim(":");
|
||||
cli_printf("%d",1); cli_delim(":");
|
||||
cli_printf("%s",mdp.nodeinfo.foundP?"found":"noresult"); cli_delim(":");
|
||||
cli_printf("%s", alloca_tohex_sid(mdp.nodeinfo.sid)); cli_delim(":");
|
||||
cli_printf("%s",mdp.nodeinfo.resolve_did?mdp.nodeinfo.did:"did-not-resolved");
|
||||
|
@ -248,8 +248,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#define COMPUTE_RFS_LENGTH -1
|
||||
|
||||
#define OVERLAY_SENDER_PREFIX_LENGTH 12
|
||||
|
||||
/* Keep track of last 32 observations of a node.
|
||||
Hopefully this is enough, if not, we will increase.
|
||||
To keep the requirement down we will collate contigious neighbour observations on each interface.
|
||||
|
26
monitor.c
26
monitor.c
@ -409,28 +409,10 @@ int monitor_process_command(struct monitor_context *c)
|
||||
else if (sscanf(cmd,"lookup match %s %d %s %s",sid,&port,localDid,remoteDid)>=3) {
|
||||
monitor_send_lookup_response(sid,port,localDid,remoteDid);
|
||||
}else if (sscanf(cmd,"call %s %s %s",sid,localDid,remoteDid)==3) {
|
||||
int gotSid = 0;
|
||||
if (sid[0]=='*') {
|
||||
/* For testing, pick any peer and call them */
|
||||
int bin, slot;
|
||||
for (bin = 0; bin < overlay_bin_count; bin++)
|
||||
for (slot = 0; slot < overlay_bin_size; slot++) {
|
||||
if (overlay_nodes[bin][slot].sid[0]) {
|
||||
memcpy(sid, overlay_nodes[bin][slot].sid, SID_SIZE);
|
||||
gotSid = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!gotSid)
|
||||
write_str(c->alarm.poll.fd,"\nERROR:no known peers, so cannot place call\n");
|
||||
} else {
|
||||
// pack the binary representation of the sid into the same buffer.
|
||||
if (stowSid((unsigned char*)sid, 0, sid) == -1)
|
||||
write_str(c->alarm.poll.fd,"\nERROR:invalid SID, so cannot place call\n");
|
||||
else
|
||||
gotSid = 1;
|
||||
}
|
||||
if (gotSid) {
|
||||
// pack the binary representation of the sid into the same buffer.
|
||||
if (stowSid((unsigned char*)sid, 0, sid) == -1)
|
||||
write_str(c->alarm.poll.fd,"\nERROR:invalid SID, so cannot place call\n");
|
||||
else {
|
||||
int cn=0, in=0, kp=0;
|
||||
if (!keyring_next_identity(keyring, &cn, &in, &kp))
|
||||
write_str(c->alarm.poll.fd,"\nERROR:no local identity, so cannot place call\n");
|
||||
|
@ -125,9 +125,6 @@ int overlayServerMode()
|
||||
of wifi latency anyway, so we'll live with it. Larger values will affect voice transport,
|
||||
and smaller values would affect CPU and energy use, and make the simulation less realistic. */
|
||||
|
||||
/* Create structures to use 1MB of RAM for testing */
|
||||
overlay_route_init(1);
|
||||
|
||||
#define SCHEDULE(X, Y, D) { \
|
||||
static struct sched_ent _sched_##X; \
|
||||
static struct profile_total _stats_##X; \
|
||||
@ -261,7 +258,7 @@ int overlay_frame_process(struct overlay_interface *interface,overlay_frame *f)
|
||||
if (!broadcast)
|
||||
{
|
||||
if (overlay_get_nexthop(f->destination,f->nexthop,&f->nexthop_interface))
|
||||
WHYF("Could not find next hop for %s* - dropping frame",
|
||||
INFOF("Could not find next hop for %s* - dropping frame",
|
||||
alloca_tohex(f->destination, 7));
|
||||
forward=0;
|
||||
}
|
||||
|
@ -156,8 +156,6 @@ sid overlay_abbreviate_previous_address={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
it on most occassions.
|
||||
*/
|
||||
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_set=0;
|
||||
int overlay_abbreviate_current_sender_id=-1;
|
||||
|
||||
int overlay_abbreviate_prepare_cache()
|
||||
{
|
||||
@ -266,15 +264,13 @@ int overlay_abbreviate_address(unsigned char *in,unsigned char *out,int *ofs)
|
||||
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;
|
||||
}
|
||||
}
|
||||
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++)
|
||||
@ -369,7 +365,7 @@ int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char
|
||||
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:
|
||||
case OA_CODE_02: case OA_CODE_04: case OA_CODE_0C: case OA_CODE_INDEX:
|
||||
/* Unsupported codes, so tell the sender
|
||||
if the frame was addressed to us as next-hop */
|
||||
(*inofs)++;
|
||||
@ -380,8 +376,9 @@ int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char
|
||||
used to encode the sender's address there ;) */
|
||||
(*inofs)++;
|
||||
if (debug&DEBUG_OVERLAYABBREVIATIONS) DEBUGF("Resolving OA_CODE_SELF.\n");
|
||||
if (overlay_abbreviate_current_sender_set) {
|
||||
bcopy(&overlay_abbreviate_current_sender.b[0],&out[*ofs],SID_SIZE);
|
||||
|
||||
if (overlay_abbreviate_current_sender.b[0]) {
|
||||
bcopy(overlay_abbreviate_current_sender.b,&out[*ofs],SID_SIZE);
|
||||
overlay_abbreviate_set_most_recent_address(&out[*ofs]);
|
||||
(*ofs)+=SID_SIZE;
|
||||
return OA_RESOLVED;
|
||||
@ -389,17 +386,6 @@ int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char
|
||||
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 */
|
||||
/* Lookup sender's neighbour ID */
|
||||
if (overlay_abbreviate_current_sender_id == -1 && overlay_abbreviate_lookup_sender_id() == -1)
|
||||
return WHY("could not lookup neighbour ID of packet sender");
|
||||
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)++;
|
||||
if (r==OA_RESOLVED)
|
||||
overlay_abbreviate_set_most_recent_address(&out[*ofs]);
|
||||
(*inofs)++;
|
||||
return r;
|
||||
case OA_CODE_PREVIOUS: /* Same as last address */
|
||||
(*inofs)++;
|
||||
bcopy(&overlay_abbreviate_previous_address.b[0],&out[*ofs],SID_SIZE);
|
||||
@ -448,7 +434,6 @@ int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char
|
||||
if (in[*inofs]==OA_CODE_FULL_INDEX2) bytes=2;
|
||||
if (bytes) (*inofs)++; /* Skip leading control code if present */
|
||||
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(&in[*inofs]);
|
||||
(*inofs)+=SID_SIZE+bytes;
|
||||
@ -456,37 +441,6 @@ 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,
|
||||
but it will do for now */
|
||||
if (!neh->node) return WHY("neighbour structure has no associated node");
|
||||
overlay_abbreviate_current_sender_id=neh->node->neighbour_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_abbreviate_remember_index(int index_byte_count,unsigned char *sid_to_remember,unsigned char *index_bytes)
|
||||
{
|
||||
int index=index_bytes[0];
|
||||
if (index_byte_count>1) index=(index<<8)|index_bytes[1];
|
||||
|
||||
/* Lookup sender's neighbour ID */
|
||||
if (overlay_abbreviate_current_sender_id == -1 && overlay_abbreviate_lookup_sender_id() == -1)
|
||||
return WHY("could not lookup neighbour ID of packet sender");
|
||||
|
||||
if (debug&DEBUG_OVERLAYABBREVIATIONS) {
|
||||
DEBUGF("index=%d", index);
|
||||
DEBUGF("remember that sender #%d has assigned index #%d to sid=[%s]", overlay_abbreviate_current_sender_id, index, alloca_tohex_sid(sid_to_remember));
|
||||
}
|
||||
|
||||
bcopy(sid_to_remember,overlay_neighbours[overlay_abbreviate_current_sender_id].one_byte_index_address_prefixes[index],OVERLAY_SENDER_PREFIX_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *ofs,
|
||||
int prefix_bytes,int index_bytes)
|
||||
{
|
||||
@ -546,13 +500,6 @@ int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *of
|
||||
bcopy(&cache->sids[index].b[0],&out[(*ofs)],SID_SIZE);
|
||||
(*ofs)+=SID_SIZE;
|
||||
if (index_bytes) {
|
||||
/* We need to remember it as well, so do that.
|
||||
If this process fails, it is okay, as we can still resolve the address now.
|
||||
It will probably result in waste later though when we get asked to look it up,
|
||||
however the alternative definitely wastes bandwidth now, so let us defer the
|
||||
corrective action in case it is never required.
|
||||
*/
|
||||
overlay_abbreviate_remember_index(index_bytes,&cache->sids[index].b[0],&in[prefix_bytes]);
|
||||
(*ofs)+=index_bytes;
|
||||
}
|
||||
if (debug&DEBUG_OVERLAYABBREVIATIONS)
|
||||
@ -564,14 +511,12 @@ int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *of
|
||||
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;
|
||||
overlay_abbreviate_current_sender_set=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_abbreviate_unset_current_sender()
|
||||
{
|
||||
overlay_abbreviate_current_sender_set=0;
|
||||
overlay_abbreviate_current_sender.b[0]=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "serval.h"
|
||||
#include "subscribers.h"
|
||||
|
||||
/* List of prioritised advertisements */
|
||||
#define OVERLAY_MAX_ADVERTISEMENT_REQUESTS 16
|
||||
@ -55,6 +56,34 @@ int overlay_route_please_advertise(overlay_node *n)
|
||||
else return 1;
|
||||
}
|
||||
|
||||
struct subscriber *last_advertised=NULL;
|
||||
|
||||
int add_advertisement(struct subscriber *subscriber, void *context){
|
||||
overlay_buffer *e=context;
|
||||
|
||||
if (subscriber->node){
|
||||
overlay_node *n=subscriber->node;
|
||||
|
||||
ob_append_bytes(e,subscriber->sid,6);
|
||||
ob_append_byte(e,n->best_link_score);
|
||||
ob_append_byte(e,n->observations[n->best_observation].gateways_en_route);
|
||||
|
||||
// stop if we run out of space
|
||||
if (ob_makespace(e,8)!=0){
|
||||
last_advertised=subscriber;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// or we've been called twice and looped around
|
||||
if (subscriber == last_advertised){
|
||||
last_advertised = NULL;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_route_add_advertisements(overlay_buffer *e)
|
||||
{
|
||||
/* Construct a route advertisement frame and append it to e.
|
||||
@ -83,19 +112,13 @@ int overlay_route_add_advertisements(overlay_buffer *e)
|
||||
which gives us 30 available advertisement slots per packet.
|
||||
*/
|
||||
int i;
|
||||
int bytes=e->sizeLimit-e->length;
|
||||
int overhead=1+8+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 */
|
||||
|
||||
ob_append_rfs(e,1+8+1+1+8*slots_used);
|
||||
// assume we might fill the packet
|
||||
ob_append_rfs(e, e->sizeLimit - e->length);
|
||||
|
||||
/* Stuff in dummy address fields */
|
||||
ob_append_byte(e,OA_CODE_BROADCAST);
|
||||
@ -105,9 +128,11 @@ int overlay_route_add_advertisements(overlay_buffer *e)
|
||||
overlay_abbreviate_clear_most_recent_address();
|
||||
overlay_abbreviate_append_address(e, overlay_get_my_sid());
|
||||
|
||||
// TODO high priority advertisements first....
|
||||
/*
|
||||
while (slots>0&&oad_request_count) {
|
||||
oad_request_count--;
|
||||
ob_append_bytes(e,oad_requests[oad_request_count]->sid,6);
|
||||
ob_append_bytes(e,oad_requests[oad_request_count]->subscriber->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]
|
||||
@ -115,51 +140,17 @@ int overlay_route_add_advertisements(overlay_buffer *e)
|
||||
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<oad_request_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;
|
||||
}
|
||||
*/
|
||||
struct subscriber *start = last_advertised;
|
||||
|
||||
// append announcements starting from the last node we advertised
|
||||
enum_subscribers(start, add_advertisement, e);
|
||||
|
||||
// if we didn't start at the beginning and still have space, start again from the beginning
|
||||
if (start && e->sizeLimit - e->length >=8){
|
||||
enum_subscribers(NULL, add_advertisement, e);
|
||||
}
|
||||
|
||||
ob_patch_rfs(e,COMPUTE_RFS_LENGTH);
|
||||
|
||||
return 0;
|
||||
@ -178,62 +169,46 @@ int overlay_route_add_advertisements(overlay_buffer *e)
|
||||
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, SID_SIZE, 0);
|
||||
if (sender == NULL) {
|
||||
WARNF("Cannot advertise %s -- overlay node not found", alloca_tohex_sid(f->source));
|
||||
return -1;
|
||||
}
|
||||
int sender_score=sender->best_link_score;
|
||||
if (debug&DEBUG_OVERLAYROUTEMONITOR)
|
||||
DEBUGF("score to reach %s is %d", alloca_tohex_sid(f->source),sender_score);
|
||||
|
||||
IN();
|
||||
while(ofs<f->payload->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 */);
|
||||
if (r==OA_PLEASEEXPLAIN) {
|
||||
/* Unresolved address -- TODO ask someone to resolve it for us. */
|
||||
WARN("Dispatch PLEASEEXPLAIN not implemented");
|
||||
struct subscriber *subscriber;
|
||||
|
||||
subscriber = find_subscriber(&f->payload->bytes[ofs], 6, 0);
|
||||
if (!subscriber){
|
||||
//WARN("Dispatch PLEASEEXPLAIN not implemented");
|
||||
goto next;
|
||||
}
|
||||
|
||||
int score=f->payload->bytes[6];
|
||||
int gateways_en_route=f->payload->bytes[7];
|
||||
int score=f->payload->bytes[ofs+6];
|
||||
int gateways_en_route=f->payload->bytes[ofs+7];
|
||||
|
||||
/* Don't record routes to ourselves */
|
||||
if (overlay_address_is_local(to)) {
|
||||
if (overlay_address_is_local(subscriber->sid)) {
|
||||
if (debug & DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("Ignore announcement about me (%s)", alloca_tohex_sid(to));
|
||||
DEBUGF("Ignore announcement about me (%s)", alloca_tohex_sid(subscriber->sid));
|
||||
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)){
|
||||
if (!memcmp(overlay_abbreviate_current_sender.b,subscriber->sid,SID_SIZE)){
|
||||
if (debug & DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("Ignore announcement about neighbour (%s)", alloca_tohex_sid(to));
|
||||
DEBUGF("Ignore announcement about neighbour (%s)", alloca_tohex_sid(subscriber->sid));
|
||||
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);
|
||||
}
|
||||
/* File it */
|
||||
overlay_route_record_link(now,subscriber->sid,overlay_abbreviate_current_sender.b,
|
||||
i,
|
||||
/* time range that this advertisement covers.
|
||||
XXX - Make it up for now. */
|
||||
now-2500,now,
|
||||
score,gateways_en_route);
|
||||
|
||||
next:
|
||||
ofs+=8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
RETURN(0);;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include <sys/stat.h>
|
||||
#include "serval.h"
|
||||
#include "strbuf.h"
|
||||
#include "subscribers.h"
|
||||
|
||||
struct profile_total mdp_stats={.name="overlay_mdp_poll"};
|
||||
|
||||
@ -937,6 +938,29 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
|
||||
}
|
||||
}
|
||||
|
||||
struct search_state{
|
||||
overlay_mdp_frame *mdp;
|
||||
overlay_mdp_frame *mdpreply;
|
||||
int first;
|
||||
int max;
|
||||
int index;
|
||||
int count;
|
||||
};
|
||||
|
||||
int search_subscribers(struct subscriber *subscriber, void *context){
|
||||
struct search_state *state = context;
|
||||
if (!subscriber->node)
|
||||
return 0;
|
||||
int score = subscriber->node->best_link_score;
|
||||
|
||||
if (state->mdp->addrlist.mode == MDP_ADDRLIST_MODE_ALL_PEERS || score >= 1) {
|
||||
if (state->count++ >= state->first && state->index < state->max) {
|
||||
memcpy(state->mdpreply->addrlist.sids[state->index++], subscriber->sid, SID_SIZE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void overlay_mdp_poll(struct sched_ent *alarm)
|
||||
{
|
||||
unsigned char buffer[16384];
|
||||
@ -1014,27 +1038,16 @@ void overlay_mdp_poll(struct sched_ent *alarm)
|
||||
case MDP_ADDRLIST_MODE_ROUTABLE_PEERS:
|
||||
case MDP_ADDRLIST_MODE_ALL_PEERS: {
|
||||
/* from peer list */
|
||||
i = count = 0;
|
||||
int bin, slot;
|
||||
for (bin = 0; bin < overlay_bin_count; ++bin) {
|
||||
for (slot = 0; slot < overlay_bin_size; ++slot) {
|
||||
const unsigned char *sid = overlay_nodes[bin][slot].sid;
|
||||
if (sid[0]) {
|
||||
const char *sidhex = alloca_tohex_sid(sid);
|
||||
int score = overlay_nodes[bin][slot].best_link_score;
|
||||
if (debug & DEBUG_MDPREQUESTS)
|
||||
DEBUGF("bin=%d slot=%d sid=%s best_link_score=%d", bin, slot, sidhex, score);
|
||||
if (mdp->addrlist.mode == MDP_ADDRLIST_MODE_ALL_PEERS || score >= 1) {
|
||||
if (count++ >= sid_num && i < max_sids) {
|
||||
if (debug & DEBUG_MDPREQUESTS) DEBUGF("send sid=%s", sidhex);
|
||||
memcpy(mdpreply.addrlist.sids[i++], sid, SID_SIZE);
|
||||
} else {
|
||||
if (debug & DEBUG_MDPREQUESTS) DEBUGF("skip sid=%s", sidhex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
struct search_state state={
|
||||
.mdp=mdp,
|
||||
.mdpreply=&mdpreply,
|
||||
.first=sid_num,
|
||||
.max=max_sid,
|
||||
};
|
||||
|
||||
enum_subscribers(NULL, search_subscribers, &state);
|
||||
i=state.index;
|
||||
count=state.count;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -213,11 +213,8 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
|
||||
DEBUG(strbuf_str(b));
|
||||
}
|
||||
|
||||
if (f.nexthop[0]==0 || f.destination[0]==0 || f.source[0]==0){
|
||||
WHY("Addresses expanded incorrectly");
|
||||
dump(NULL, &packet[payloadStart], ofs - payloadStart);
|
||||
if (f.nexthop[0]==0 || f.destination[0]==0 || f.source[0]==0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (nexthop_address_status!=OA_RESOLVED
|
||||
|| destination_address_status!=OA_RESOLVED
|
||||
@ -236,6 +233,11 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
|
||||
break;
|
||||
}else{
|
||||
|
||||
/* Record current sender for reference by addresses in subsequent frames in the
|
||||
ensemble */
|
||||
if (f.type==OF_TYPE_SELFANNOUNCE)
|
||||
overlay_abbreviate_set_current_sender(f.source);
|
||||
|
||||
// TODO refactor all packet parsing to only allocate additional memory for the payload
|
||||
// if it needs to be queued for forwarding.
|
||||
|
||||
|
@ -315,20 +315,6 @@ overlay_frame *op_dup(overlay_frame *in)
|
||||
return out;
|
||||
}
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_frame_set_neighbour_as_destination(overlay_frame *f,overlay_neighbour *n)
|
||||
{
|
||||
if (!n) return WHY("Neighbour was null");
|
||||
bcopy(n->node->sid,f->destination,SID_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_frame_set_broadcast_as_destination(overlay_frame *f)
|
||||
{
|
||||
overlay_broadcast_generate_address(f->destination);
|
||||
|
803
overlay_route.c
803
overlay_route.c
File diff suppressed because it is too large
Load Diff
56
serval.h
56
serval.h
@ -689,21 +689,6 @@ int rfs_length(int l);
|
||||
int rfs_encode(int l,unsigned char *b);
|
||||
int rfs_decode(unsigned char *b,int *offset);
|
||||
|
||||
typedef struct overlay_neighbour_observation {
|
||||
/* Sequence numbers are handled as ranges because the tick
|
||||
rate can vary between interfaces, and we want to be able to
|
||||
estimate the reliability of links to nodes that may have
|
||||
several available interfaces.
|
||||
We don't want sequence numbers to wrap too often, but we
|
||||
would also like to support fairly fast ticking interfaces,
|
||||
e.g., for gigabit type links. So lets go with 1ms granularity. */
|
||||
unsigned int s1;
|
||||
unsigned int s2;
|
||||
time_ms_t time_ms;
|
||||
unsigned char sender_interface;
|
||||
unsigned char valid;
|
||||
} overlay_neighbour_observation;
|
||||
|
||||
typedef struct overlay_node_observation {
|
||||
unsigned char observed_score; /* serves as validty check also */
|
||||
unsigned char corrected_score;
|
||||
@ -711,12 +696,12 @@ typedef struct overlay_node_observation {
|
||||
unsigned char RESERVED; /* for alignment */
|
||||
unsigned char interface;
|
||||
time_ms_t rx_time;
|
||||
unsigned char sender_prefix[OVERLAY_SENDER_PREFIX_LENGTH];
|
||||
struct subscriber *sender;
|
||||
} overlay_node_observation;
|
||||
|
||||
|
||||
typedef struct overlay_node {
|
||||
unsigned char sid[SID_SIZE];
|
||||
struct subscriber *subscriber;
|
||||
int neighbour_id; /* 0=not a neighbour */
|
||||
int most_recent_observation_id;
|
||||
int best_link_score;
|
||||
@ -730,37 +715,13 @@ typedef struct overlay_node {
|
||||
overlay_node_observation observations[OVERLAY_MAX_OBSERVATIONS];
|
||||
} overlay_node;
|
||||
|
||||
typedef struct overlay_neighbour {
|
||||
time_ms_t last_observation_time_ms;
|
||||
time_ms_t last_metric_update;
|
||||
int most_recent_observation_id;
|
||||
overlay_neighbour_observation observations[OVERLAY_MAX_OBSERVATIONS];
|
||||
overlay_node *node;
|
||||
|
||||
/* Scores of visibility from each of the neighbours interfaces.
|
||||
This is so that the sender knows which interface to use to reach us.
|
||||
*/
|
||||
unsigned char scores[OVERLAY_MAX_INTERFACES];
|
||||
|
||||
/* One-byte index entries for address abbreviation */
|
||||
unsigned char one_byte_index_address_prefixes[256][OVERLAY_SENDER_PREFIX_LENGTH];
|
||||
} overlay_neighbour;
|
||||
extern overlay_neighbour *overlay_neighbours;
|
||||
|
||||
int overlay_route_init(int mb_ram);
|
||||
int overlay_route_saw_selfannounce_ack(overlay_frame *f, time_ms_t now);
|
||||
int overlay_route_recalc_node_metrics(overlay_node *n, time_ms_t now);
|
||||
int overlay_route_recalc_neighbour_metrics(overlay_neighbour *n, time_ms_t now);
|
||||
int overlay_route_saw_selfannounce(overlay_frame *f, time_ms_t now);
|
||||
overlay_node *overlay_route_find_node(const unsigned char *sid,int prefixLen,int createP);
|
||||
unsigned int overlay_route_hash_sid(const unsigned char *sid);
|
||||
int overlay_route_init(int mb_ram);
|
||||
overlay_neighbour *overlay_route_get_neighbour_structure(unsigned char *packed_sid,
|
||||
int prefixLen,int createP);
|
||||
|
||||
unsigned char *overlay_get_my_sid();
|
||||
int overlay_frame_set_me_as_source(overlay_frame *f);
|
||||
int overlay_frame_set_neighbour_as_source(overlay_frame *f,overlay_neighbour *n);
|
||||
int overlay_frame_set_neighbour_as_destination(overlay_frame *f,overlay_neighbour *n);
|
||||
int overlay_frame_set_broadcast_as_destination(overlay_frame *f);
|
||||
int overlay_broadcast_generate_address(unsigned char *a);
|
||||
int packetEncipher(unsigned char *packet,int maxlen,int *len,int cryptoflags);
|
||||
@ -771,17 +732,10 @@ int overlay_route_record_link( time_ms_t now,unsigned char *to,
|
||||
unsigned char *via,int sender_interface,
|
||||
unsigned int s1,unsigned int s2,int score,int gateways_en_route);
|
||||
int overlay_route_dump();
|
||||
int overlay_route_tick_neighbour(int neighbour_id, time_ms_t now);
|
||||
int overlay_route_tick_node(int bin,int slot, time_ms_t now);
|
||||
int overlay_route_add_advertisements(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;
|
||||
|
||||
int overlay_route_saw_advertisements(int i,overlay_frame *f, time_ms_t now);
|
||||
int overlay_rhizome_saw_advertisements(int i,overlay_frame *f, time_ms_t now);
|
||||
int overlay_route_please_advertise(overlay_node *n);
|
||||
@ -916,7 +870,7 @@ typedef struct overlay_mdp_vompevent {
|
||||
|
||||
typedef struct overlay_mdp_nodeinfo {
|
||||
unsigned char sid[SID_SIZE];
|
||||
int sid_prefix_length; /* allow wildcard matching */
|
||||
int sid_prefix_length; /* must be long enough to be unique */
|
||||
char did[64];
|
||||
char name[64];
|
||||
int foundP;
|
||||
@ -926,8 +880,6 @@ typedef struct overlay_mdp_nodeinfo {
|
||||
int interface_number;
|
||||
int resolve_did;
|
||||
time_ms_t time_since_last_observation;
|
||||
int index; /* which record to return or was returned (incase there are multiple matches) */
|
||||
int count; /* number of matching records */
|
||||
} overlay_mdp_nodeinfo;
|
||||
|
||||
typedef struct overlay_mdp_frame {
|
||||
|
@ -43,7 +43,7 @@ unsigned char get_nibble(const unsigned char *sid, int pos){
|
||||
|
||||
// find a subscriber struct from a subscriber id
|
||||
// TODO find abreviated sid's
|
||||
struct subscriber *find(const unsigned char *sid, int len, int create){
|
||||
struct subscriber *find_subscriber(const unsigned char *sid, int len, int create){
|
||||
struct tree_node *ptr = &root;
|
||||
int pos=0;
|
||||
if (len!=SID_SIZE)
|
||||
@ -60,6 +60,7 @@ struct subscriber *find(const unsigned char *sid, int len, int create){
|
||||
|
||||
if (create){
|
||||
struct subscriber *ret=(struct subscriber *)malloc(sizeof(struct subscriber));
|
||||
memset(ret,0,sizeof(struct subscriber));
|
||||
ptr->subscribers[nibble]=ret;
|
||||
bcopy(sid, ret->sid, SID_SIZE);
|
||||
ret->abbreviate_len=pos;
|
||||
@ -95,18 +96,34 @@ struct subscriber *find(const unsigned char *sid, int len, int create){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void dump_subscriber_tree(struct tree_node *node, int depth){
|
||||
int i;
|
||||
for (i=0;i<16;i++){
|
||||
/*
|
||||
Walk the subscriber tree, calling the callback function for each subscriber.
|
||||
if start is a valid pointer, the first entry returned will be after this subscriber
|
||||
if the callback returns non-zero, the process will stop.
|
||||
*/
|
||||
int walk_tree(struct tree_node *node, int pos, struct subscriber *start,
|
||||
int(*callback)(struct subscriber *, void *), void *context){
|
||||
int i=0;
|
||||
|
||||
if (start){
|
||||
i=get_nibble(start->sid,pos);
|
||||
}
|
||||
|
||||
for (;i<16;i++){
|
||||
if (node->is_tree & (1<<i)){
|
||||
DEBUGF("%d, %x",depth,i);
|
||||
dump_subscriber_tree(node->tree_nodes[i],depth+1);
|
||||
}else if(node->subscribers[i]){
|
||||
DEBUGF("%d, %x, %s", node->subscribers[i]->abbreviate_len, i, alloca_tohex_sid(node->subscribers[i]->sid));
|
||||
if (walk_tree(node->tree_nodes[i], pos+1, start, callback, context))
|
||||
return 1;
|
||||
}else if(node->subscribers[i] && node->subscribers[i] != start){
|
||||
if (callback(node->subscribers[i], context))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dump_subscribers(){
|
||||
dump_subscriber_tree(&root,0);
|
||||
/*
|
||||
walk the tree, starting at start, calling the callback function
|
||||
*/
|
||||
void enum_subscribers(struct subscriber *start, int(*callback)(struct subscriber *, void *), void *context){
|
||||
walk_tree(&root, 0, start, callback, context);
|
||||
}
|
||||
|
@ -14,10 +14,11 @@ struct subscriber{
|
||||
unsigned char sid[SID_SIZE];
|
||||
// minimum abbreviation length, in 4bit nibbles.
|
||||
int abbreviate_len;
|
||||
overlay_node *node;
|
||||
};
|
||||
|
||||
struct subscriber *find(const unsigned char *sid, int len, int create);
|
||||
void dump_subscribers();
|
||||
|
||||
struct subscriber *find_subscriber(const unsigned char *sid, int len, int create);
|
||||
void enum_subscribers(struct subscriber *start, int(*callback)(struct subscriber *, void *), void *context);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user