Various single-instance variable processing fixes for DNA.

Further work on overlay mesh routing.
This commit is contained in:
gardners 2011-08-29 16:20:27 +09:30
parent 6cec2207e1
commit 32a5f03073
7 changed files with 111 additions and 58 deletions

View File

@ -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
View File

@ -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);

View File

@ -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");

View File

@ -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;
}

View File

@ -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");

View File

@ -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;

View File

@ -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;