Simplify payload length storage

This commit is contained in:
Jeremy Lakeman 2012-11-23 13:34:01 +10:30
parent a358d924d7
commit f159e15901
8 changed files with 19 additions and 137 deletions

View File

@ -1525,22 +1525,6 @@ int app_count_peers(int argc, const char *const *argv, struct command_line_optio
return 0;
}
int app_test_rfs(int argc, const char *const *argv, struct command_line_option *o, void *context)
{
if (debug & DEBUG_VERBOSE) DEBUG_argv("command", argc, argv);
printf("Testing that RFS coder works properly.\n");
int i;
for(i=0;i<65536;i++) {
unsigned char bytes[8];
rfs_encode(i, &bytes[0]);
int zero=0;
int r=rfs_decode(&bytes[0],&zero);
if (i != r)
printf("RFS encoding of %d decodes to %d: %s\n", i, r, alloca_tohex(bytes, sizeof bytes));
}
return 0;
}
int app_crypt_test(int argc, const char *const *argv, struct command_line_option *o, void *context)
{
if (debug & DEBUG_VERBOSE) DEBUG_argv("command", argc, argv);
@ -1940,8 +1924,6 @@ struct command_line_option command_line_options[]={
"Return a count of routable peers on the network"},
{app_reverse_lookup, {"reverse", "lookup", "<sid>", "[<timeout>]", NULL}, 0,
"Lookup the phone number and name of a given subscriber"},
{app_test_rfs,{"test","rfs",NULL},0,
"Test RFS field calculation"},
{app_monitor_cli,{"monitor",NULL},0,
"Interactive servald monitor interface."},
{app_crypt_test,{"crypt","test",NULL},0,

View File

@ -112,15 +112,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
/* QOS packet queue bits */
#define OF_QUEUE_BITS 0x03
#define RFS_PLUS250 0xfa
#define RFS_PLUS456 0xfb
#define RFS_PLUS762 0xfc
#define RFS_PLUS1018 0xfd
#define RFS_PLUS1274 0xfe
#define RFS_3BYTE 0xff
#define COMPUTE_RFS_LENGTH -1
/* 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.

View File

@ -165,7 +165,7 @@ int overlay_route_add_advertisements(struct decode_context *context, overlay_int
// no advertisements? don't bother to send the payload at all.
ob_rewind(e);
}else
ob_patch_rfs(e,COMPUTE_RFS_LENGTH);
ob_patch_rfs(e);
return 0;
}

View File

@ -255,24 +255,10 @@ int ob_append_ui32(struct overlay_buffer *b, uint32_t v)
int ob_append_rfs(struct overlay_buffer *b,int l)
{
/* Encode the specified length and append it to the buffer */
if (l<0||l>0xffff) return -1;
/* First work out how long the field needs to be, then write dummy bytes
and use ob_patch_rfs to set the value. That way we have only one
lot of code that does the encoding. */
b->var_length_offset=b->position;
b->var_length_bytes=rfs_length(l);
unsigned char c[3]={0,0,0};
if (ob_append_bytes(b,c,b->var_length_bytes)) {
b->var_length_offset=0;
return -1;
}
return ob_patch_rfs(b,l);
return ob_append_ui16(b,l);
}
@ -348,96 +334,18 @@ int ob_get(struct overlay_buffer *b){
return b->bytes[b->position++];
}
int rfs_length(int l)
int ob_set_ui16(struct overlay_buffer *b, int offset, uint16_t v)
{
if (l<0) return -1;
if (l<250) return 1;
else if (l<(255+250+(256*4))) return 2;
else if (l<=0xffff) return 3;
else return -1;
}
int rfs_encode(int l, unsigned char *b)
{
if (l<250) { b[0]=l; }
else if (l<(255+250+(256*4))) {
l-=250;
int page=(l>>8);
l&=0xff;
b[0]=RFS_PLUS250+page;
b[1]=l;
} else {
b[0]=RFS_3BYTE;
b[1]=l>>8;
b[2]=l&0xff;
}
return 0;
}
int rfs_decode(unsigned char *b,int *ofs)
{
int rfs=b[*ofs];
switch(rfs) {
case RFS_PLUS250: case RFS_PLUS456: case RFS_PLUS762: case RFS_PLUS1018: case RFS_PLUS1274:
rfs=250+256*(rfs-RFS_PLUS250)+b[++(*ofs)];
break;
case RFS_3BYTE: rfs=(b[(*ofs)+1]<<8)+b[(*ofs)+2]; (*ofs)+=2;
default: /* Length is natural value of field, so nothing to do */
break;
}
(*ofs)++;
return rfs;
}
// move the data at offset, by shift bytes
int ob_indel_space(struct overlay_buffer *b,int offset,int shift)
{
if (offset>=b->position) return -1;
if (shift>0 && ob_makespace(b, shift)) return -1;
bcopy(&b->bytes[offset],&b->bytes[offset+shift],b->position-offset);
b->position+=shift;
return 0;
}
int ob_patch_rfs(struct overlay_buffer *b,int l)
{
if (l==COMPUTE_RFS_LENGTH){
// assume the payload has been written, we can now calculate the actual length
l = b->position - (b->var_length_offset + b->var_length_bytes);
}
if (l<0||l>0xffff) return -1;
/* Adjust size of field */
int new_size=rfs_length(l);
int shift=new_size - b->var_length_bytes;
if (shift) {
if (debug&DEBUG_PACKETCONSTRUCTION) {
DEBUGF("Patching RFS for rfs_size=%d (was %d), so indel %d btyes",
new_size,b->var_length_bytes,shift);
dump("before indel",
&b->bytes[b->var_length_offset],
b->position-b->var_length_offset);
}
if (ob_indel_space(b, b->var_length_offset + b->var_length_bytes, shift)) return -1;
if (debug&DEBUG_PACKETCONSTRUCTION) {
dump("after indel",
&b->bytes[b->var_length_offset],
b->position-b->var_length_offset);
}
}
if (test_offset(b, offset, 2))
return -1;
if (rfs_encode(l,&b->bytes[b->var_length_offset])) return -1;
if (debug&DEBUG_PACKETCONSTRUCTION) {
dump("after patch",
&b->bytes[b->var_length_offset],
b->position-b->var_length_offset);
}
b->bytes[offset] = (v >> 8) & 0xFF;
b->bytes[offset+1] = v & 0xFF;
return 0;
}
int ob_patch_rfs(struct overlay_buffer *b){
return ob_set_ui16(b,b->var_length_offset,b->position - (b->var_length_offset + 2));
}
int asprintable(int c)

View File

@ -38,9 +38,8 @@ struct overlay_buffer {
// is this an allocated buffer? can it be resized? Should it be freed?
int allocated;
// length position and size for later patching
// length position for later patching
int var_length_offset;
int var_length_bytes;
};
struct overlay_buffer *ob_new(void);
@ -58,7 +57,7 @@ int ob_append_bytes(struct overlay_buffer *b,unsigned char *bytes,int count);
unsigned char *ob_append_space(struct overlay_buffer *b,int count);
int ob_append_ui16(struct overlay_buffer *b, uint16_t v);
int ob_append_ui32(struct overlay_buffer *b, uint32_t v);
int ob_patch_rfs(struct overlay_buffer *b,int l);
int ob_patch_rfs(struct overlay_buffer *b);
int ob_append_rfs(struct overlay_buffer *b,int l);
// get one byte, -ve number indicates failure
int ob_getbyte(struct overlay_buffer *b,int ofs);
@ -69,6 +68,7 @@ unsigned char * ob_get_bytes_ptr(struct overlay_buffer *b, int len);
uint32_t ob_get_ui32(struct overlay_buffer *b);
uint16_t ob_get_ui16(struct overlay_buffer *b);
int ob_dump(struct overlay_buffer *b,char *desc);
int ob_set_ui16(struct overlay_buffer *b, int offset, uint16_t v);
#endif

View File

@ -226,7 +226,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
f.ttl--;
/* Decode length of remainder of frame */
int payload_len=rfs_decode(b->bytes, &b->position);
int payload_len=ob_get_ui16(b);
if (payload_len <=0) {
/* assume we fell off the end of the packet */
@ -409,7 +409,7 @@ int overlay_add_selfannouncement(struct decode_context *context, int interface,s
if (ob_append_byte(b,interface))
return WHY("Could not add interface number to self-announcement");
ob_patch_rfs(b, COMPUTE_RFS_LENGTH);
ob_patch_rfs(b);
return 0;
}

View File

@ -98,7 +98,8 @@ int overlay_frame_append_payload(struct decode_context *context, overlay_interfa
int actual_len=addrs_len+p->payload->position;
if (debug&DEBUG_PACKETCONSTRUCTION)
DEBUGF("Patching RFS for actual_len=%d\n",actual_len);
ob_patch_rfs(headers,actual_len);
ob_set_ui16(headers,headers->var_length_offset,actual_len);
/* Write payload format plus total length of header bits */
if (ob_makespace(b,2+headers->position+p->payload->position)) {

View File

@ -317,7 +317,7 @@ int overlay_rhizome_add_advertisements(struct decode_context *context, int inter
}
}
ob_patch_rfs(e, COMPUTE_RFS_LENGTH);
ob_patch_rfs(e);
sqlite_set_debugmask(oldmask);
RETURN(0);