mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-20 09:26:37 +00:00
Various single-instance variable processing fixes for DNA.
Further work on overlay mesh routing.
This commit is contained in:
parent
6cec2207e1
commit
32a5f03073
30
hlrdata.c
30
hlrdata.c
@ -369,7 +369,7 @@ int hlrSetVariable(unsigned char *hlr,int hofs,int varid,int varinstance,
|
||||
if (debug>1) fprintf(stderr,"h->var_id=%02x, h->h->var_instance=%02x, h->entry_offset=%x\n",
|
||||
h->var_id,h->var_instance,h->entry_offset);
|
||||
if ((h->var_id<varid)
|
||||
||(h->var_id==varid&&h->var_instance<varinstance))
|
||||
||((h->var_id&0x80)&&(h->var_id==varid&&h->var_instance<varinstance)))
|
||||
{
|
||||
hlr_offset=h->entry_offset;
|
||||
if (debug>1) fprintf(stderr,"Found variable instance prior: hlr_offset=%d.\n",hlr_offset);
|
||||
@ -390,19 +390,19 @@ int hlrSetVariable(unsigned char *hlr,int hofs,int varid,int varinstance,
|
||||
if (h&&hlr_offset>-1)
|
||||
{
|
||||
if (debug>2) printf("hlr_offset=%d\n",hlr_offset);
|
||||
if (h&&h->var_id==varid&&h->var_instance==varinstance)
|
||||
if (h&&h->var_id==varid&&((h->var_instance==varinstance)||(!(h->var_id&0x80))))
|
||||
{
|
||||
int existing_size;
|
||||
int existing_size;
|
||||
/* Replace existing value */
|
||||
if (debug) fprintf(stderr,"Replacing value in HLR\n");
|
||||
existing_size=1+2+(h->var_id&0x80?1:0)+h->value_len;
|
||||
hlrMakeSpace(hlr,hofs,hlr_offset,1+2+len+(varid&0x80?1:0)-existing_size);
|
||||
if (debug) fprintf(stderr,"Replacing value in HLR:\n");
|
||||
existing_size=1+2+((h->var_id&0x80)?1:0)+h->value_len;
|
||||
hlrMakeSpace(hlr,hofs,hlr_offset,1+2+len+((varid&0x80)?1:0)-existing_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Insert value here */
|
||||
if (debug) fprintf(stderr,"Inserting value in HLR\n");
|
||||
hlrMakeSpace(hlr,hofs,hlr_offset,1+2+len+(varid&0x80?1:0));
|
||||
hlrMakeSpace(hlr,hofs,hlr_offset,1+2+len+((varid&0x80)?1:0));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -410,7 +410,7 @@ int hlrSetVariable(unsigned char *hlr,int hofs,int varid,int varinstance,
|
||||
/* HLR record has no entries, or this entry needs to go at the end,
|
||||
so insert value at end of the record */
|
||||
if (debug) fprintf(stderr,"Inserting value at end of HLR @ 0x%x\n",hlr_size);
|
||||
hlrMakeSpace(hlr,hofs,hlr_size,1+2+len+(varid&0x80?1:0));
|
||||
hlrMakeSpace(hlr,hofs,hlr_size,1+2+len+((varid&0x80)?1:0));
|
||||
hlr_offset=hlr_size;
|
||||
}
|
||||
|
||||
@ -435,14 +435,24 @@ int hlrStowValue(unsigned char *hlr,int hofs,int hlr_offset,
|
||||
int hlrMakeSpace(unsigned char *hlr,int hofs,int hlr_offset,int bytes)
|
||||
{
|
||||
int length;
|
||||
int shifted_bytes=hlr_size-(hofs+hlr_offset+bytes);
|
||||
/* Don't read past end of file */
|
||||
if (bytes<0) shifted_bytes+=bytes;
|
||||
|
||||
/* Deal with easy case first */
|
||||
if (!bytes) return 0;
|
||||
|
||||
if (debug>2) {
|
||||
fprintf(stderr,"hlrMakeSpace: Inserting %d bytes at offset %d with hofs=%d. shifted bytes=%d\n",
|
||||
bytes,hlr_offset,hofs,shifted_bytes);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
/* Shift rest of HLR up/down.
|
||||
If down, back-fill bytes with zeros. */
|
||||
bcopy(&hlr[hofs+hlr_offset],&hlr[hofs+hlr_offset+bytes],
|
||||
hlr_size-(hofs+hlr_offset+bytes));
|
||||
if (bytes<0) bzero(&hlr[hlr_size-bytes],0-bytes);
|
||||
shifted_bytes);
|
||||
if (bytes<0) bzero(&hlr[hlr_size+bytes],0-bytes);
|
||||
|
||||
/* Update record length */
|
||||
length=hlrGetRecordLength(hlr,hofs);
|
||||
|
36
mphlr.h
36
mphlr.h
@ -707,4 +707,40 @@ int rfs_length(int l);
|
||||
int rfs_encode(int l,unsigned char *b);
|
||||
int rfs_decode(unsigned char *b,int *offset);
|
||||
|
||||
#define OVERLAY_SENDER_PREFIX_LENGTH 12
|
||||
typedef struct overlay_node_observation {
|
||||
int valid;
|
||||
|
||||
/* 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. */
|
||||
int sequence_range_low;
|
||||
int sequence_range_high;
|
||||
long long rx_time;
|
||||
unsigned char sender_prefix[OVERLAY_SENDER_PREFIX_LENGTH];
|
||||
} overlay_node_observation;
|
||||
|
||||
/* Keep track of last 32 observations of a node.
|
||||
Hopefully this is enough, if not, we will increase */
|
||||
#define OVERLAY_MAX_OBSERVATIONS 32
|
||||
|
||||
typedef struct overlay_node {
|
||||
unsigned char sid[SID_SIZE];
|
||||
int neighbour_id; /* 0=not a neighbour */
|
||||
long long last_observation_time_ms;
|
||||
int most_recent_observation_id;
|
||||
overlay_node_observation observations[OVERLAY_MAX_OBSERVATIONS];
|
||||
} overlay_node;
|
||||
|
||||
long long overlay_gettime_ms();
|
||||
int overlay_route_init(int mb_ram);
|
||||
int overlay_route_saw_selfannounce_ack(overlay_frame *f,long long now);
|
||||
int overlay_route_recalc_node_metrics(overlay_node *n);
|
||||
int overlay_route_saw_selfannounce(overlay_frame *f,long long now);
|
||||
overlay_node *overlay_route_find_node(unsigned char *sid,int createP);
|
||||
unsigned int overlay_route_hash_sid(unsigned char *sid);
|
||||
int overlay_route_init(int mb_ram);
|
||||
|
@ -122,6 +122,8 @@ int overlay_frame_process(int interface,overlay_frame *f)
|
||||
{
|
||||
if (!f) return WHY("f==NULL");
|
||||
|
||||
long long now=overlay_gettime_ms();
|
||||
|
||||
/* 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
|
||||
@ -225,10 +227,10 @@ int overlay_frame_process(int interface,overlay_frame *f)
|
||||
switch(f->type)
|
||||
{
|
||||
case OF_TYPE_SELFANNOUNCE:
|
||||
overlay_route_saw_selfannounce(f);
|
||||
overlay_route_saw_selfannounce(f,now);
|
||||
break;
|
||||
case OF_TYPE_SELFANNOUNCE_ACK:
|
||||
overlay_route_saw_selfannounce_ack(f);
|
||||
overlay_route_saw_selfannounce_ack(f,now);
|
||||
break;
|
||||
default:
|
||||
return WHY("Support for that f->type not yet implemented");
|
||||
|
@ -25,7 +25,7 @@ time_t overlay_sequence_start_time;
|
||||
/* Do we need to repeat our abbreviation policy? */
|
||||
int overlay_interface_repeat_abbreviation_policy[OVERLAY_MAX_INTERFACES]={1};
|
||||
|
||||
int overlay_update_sequence_number()
|
||||
long long overlay_gettime_ms()
|
||||
{
|
||||
struct timeval nowtv;
|
||||
if (gettimeofday(&nowtv,NULL))
|
||||
@ -35,6 +35,12 @@ int overlay_update_sequence_number()
|
||||
long long now=(nowtv.tv_sec-overlay_sequence_start_time)*1000LL;
|
||||
now=now+nowtv.tv_usec/1000;
|
||||
|
||||
return now;
|
||||
}
|
||||
|
||||
int overlay_update_sequence_number()
|
||||
{
|
||||
long long now=overlay_gettime_ms();
|
||||
overlay_sequence_number=now&0xffffffff;
|
||||
return 0;
|
||||
}
|
||||
|
@ -100,33 +100,6 @@
|
||||
|
||||
*/
|
||||
|
||||
#define OVERLAY_SENDER_PREFIX_LENGTH 12
|
||||
typedef struct overlay_node_observation {
|
||||
int valid;
|
||||
|
||||
/* 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. */
|
||||
int sequence_range_low;
|
||||
int sequence_range_high;
|
||||
long long rx_time;
|
||||
unsigned char sender_prefix[OVERLAY_SENDER_PREFIX_LENGTH];
|
||||
} overlay_node_observation;
|
||||
|
||||
/* Keep track of last 32 observations of a node.
|
||||
Hopefully this is enough, if not, we will increase */
|
||||
#define OVERLAY_MAX_OBSERVATIONS 32
|
||||
|
||||
typedef struct overlay_node {
|
||||
unsigned char sid[SID_SIZE];
|
||||
int neighbour_id; /* 0=not a neighbour */
|
||||
int most_recent_observation_id;
|
||||
overlay_node_observation observations[OVERLAY_MAX_OBSERVATIONS];
|
||||
} overlay_node;
|
||||
|
||||
/* For fast handling we will have a number of bins that will be indexed by the
|
||||
first few bits of the peer's SIDs, and a number of entries in each bin to
|
||||
@ -395,9 +368,16 @@ overlay_node *overlay_route_find_node(unsigned char *sid,int createP)
|
||||
return &overlay_nodes[bin_number][free_slot];
|
||||
}
|
||||
|
||||
int overlay_route_saw_selfannounce(overlay_frame *f)
|
||||
int overlay_route_ack_selfannounce(overlay_frame *f)
|
||||
{
|
||||
return WHY("Not implemented");
|
||||
}
|
||||
|
||||
int overlay_route_saw_selfannounce(overlay_frame *f,long long now)
|
||||
{
|
||||
/* XXX send ack out even if we have no structures setup? */
|
||||
overlay_route_ack_selfannounce(f);
|
||||
|
||||
if (!overlay_neighbours) return 0;
|
||||
|
||||
/* Lookup node in node cache */
|
||||
@ -424,12 +404,22 @@ int overlay_route_saw_selfannounce(overlay_frame *f)
|
||||
n->observations[obs_index].valid=1;
|
||||
n->most_recent_observation_id=obs_index;
|
||||
|
||||
/* Recalculate link score for this node */
|
||||
n->last_observation_time_ms=now;
|
||||
|
||||
return WHY("Not implemented");
|
||||
/* Recalculate link score for this node */
|
||||
if (overlay_route_recalc_node_metrics(n)) return WHY("recalc_node_metrics() failed.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_route_saw_selfannounce_ack(overlay_frame *f)
|
||||
/* Recalculate node reachability metric. */
|
||||
int overlay_route_recalc_node_metrics(overlay_node *n)
|
||||
{
|
||||
return WHY("Not Implemented");
|
||||
|
||||
}
|
||||
|
||||
int overlay_route_saw_selfannounce_ack(overlay_frame *f,long long now)
|
||||
{
|
||||
if (!overlay_neighbours) return 0;
|
||||
return WHY("Not implemented");
|
||||
|
@ -277,9 +277,11 @@ int packetAddVariableRequest(unsigned char *packet,int packet_maxlen,int *packet
|
||||
return setReason("Requested unknown HLR variable");
|
||||
}
|
||||
itemId=vars[itemId].id;
|
||||
if (instance<-1) return setReason("Asked for illegal variable value instance");
|
||||
if (instance>0xfe) return setReason("Asked for illegal variable value instance");
|
||||
if ((itemId<0x80)&&instance) return setReason("Asked for secondary value of single-value variable");
|
||||
if (instance<-1) return setReason("Asked for illegal variable value instance (<-1)");
|
||||
if (instance>0xfe) return setReason("Asked for illegal variable value instance (>0xfe)");
|
||||
if ((instance!=-1)&&(itemId<0x80)&&instance) {
|
||||
return setReason("Asked for secondary value of single-value variable for read");
|
||||
}
|
||||
if (start_offset<0||start_offset>0xffff) return setReason("Asked for illegal variable value starting offset");
|
||||
if (bytes<0||(start_offset+bytes)>0xffff) {
|
||||
if (debug) fprintf(stderr,"Asked for %d bytes at offset %d\n",bytes,start_offset);
|
||||
@ -290,8 +292,7 @@ int packetAddVariableRequest(unsigned char *packet,int packet_maxlen,int *packet
|
||||
CHECK_PACKET_LEN(1+1+((itemId&0x80)?1:0)+2+2);
|
||||
packet[(*packet_len)++]=ACTION_GET;
|
||||
packet[(*packet_len)++]=itemId;
|
||||
if (instance==-1) instance=0xff;
|
||||
if (itemId&0x80) packet[(*packet_len)++]=instance;
|
||||
if (itemId&0x80) { packet[(*packet_len)++]=instance; }
|
||||
packet[(*packet_len)++]=start_offset>>8;
|
||||
packet[(*packet_len)++]=start_offset&0xff;
|
||||
packet[(*packet_len)++]=bytes>>8;
|
||||
@ -315,9 +316,11 @@ int packetAddVariableWrite(unsigned char *packet,int packet_maxlen,
|
||||
if (debug>1) printf("packetAddVariableWrite(start=%d,len=%d,flags=%d)\n",start_offset,value_len,flags);
|
||||
|
||||
/* Sanity check */
|
||||
if (instance<0) return setReason("Asked for illegal variable value instance");
|
||||
if (instance>0xfe) return setReason("Asked for illegal variable value instance");
|
||||
if ((itemId<0x80)&&instance) return setReason("Asked for secondary value of single-value variable");
|
||||
if (itemId&0x80) {
|
||||
if (instance<0) return setReason("Asked for illegal variable value instance (<0)");
|
||||
if (instance>0xfe) return setReason("Asked for illegal variable value instance (>0xfe)");
|
||||
}
|
||||
if ((itemId<0x80)&&instance&&(instance!=-1)) return setReason("Asked for secondary value of single-value variable for write");
|
||||
if (start_offset<0||start_offset>0xffff) return setReason("Asked for illegal variable value starting offset");
|
||||
if (max_offset<0||max_offset>0xffff) return setReason("Asked for illegal variable value ending offset");
|
||||
|
||||
@ -352,7 +355,7 @@ int extractRequest(unsigned char *packet,int *packet_ofs,int packet_len,
|
||||
|
||||
*itemId=packet[(*packet_ofs)++];
|
||||
|
||||
if ((*itemId)&0x80) *instance=packet[(*packet_ofs)++];
|
||||
if ((*itemId)&0x80) *instance=packet[(*packet_ofs)++]; else *instance=0;
|
||||
if (*instance==0xff) *instance=-1;
|
||||
|
||||
*start_offset=packet[(*packet_ofs)++]<<8;
|
||||
|
16
server.c
16
server.c
@ -306,13 +306,19 @@ int processRequest(unsigned char *packet,int len,
|
||||
unsigned char data[MAX_DATA_BYTES+16];
|
||||
int dlen=0;
|
||||
int sendDone=0;
|
||||
int var_id=packet[pofs+1];
|
||||
int instance=packet[pofs+2];
|
||||
int offset=(packet[pofs+3]<<8)+packet[pofs+4];
|
||||
|
||||
if (debug>2) dump("Request bytes",&packet[pofs],8);
|
||||
|
||||
pofs++;
|
||||
int var_id=packet[pofs];
|
||||
int instance=-1;
|
||||
if (var_id&0x80) instance=packet[++pofs];
|
||||
pofs++;
|
||||
int offset=(packet[pofs]<<8)+packet[pofs+1]; pofs+=2;
|
||||
char *hlr_sid=NULL;
|
||||
|
||||
pofs+=7;
|
||||
if (debug>2) dump("Request bytes",&packet[pofs],8);
|
||||
pofs+=3;
|
||||
|
||||
if (debug>1) fprintf(stderr,"Processing ACTION_GET (var_id=%02x, instance=%02x, pofs=0x%x, len=%d)\n",var_id,instance,pofs,len);
|
||||
|
||||
ofs=0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user