mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-19 21:27:57 +00:00
Refactor overlay buffer interface to support simple parsing
This commit is contained in:
parent
22c6b530ed
commit
f6c899e107
@ -82,6 +82,7 @@ MONITORCLIENTOBJS= $(MONITORCLIENTSRCS:.c=.o)
|
||||
|
||||
HDRS= fifo.h \
|
||||
Makefile \
|
||||
overlay_buffer.h \
|
||||
rhizome.h \
|
||||
serval.h \
|
||||
strbuf.h \
|
||||
|
@ -1506,7 +1506,7 @@ int app_id_self(int argc, const char *const *argv, struct command_line_option *o
|
||||
a.addrlist.mode = MDP_ADDRLIST_MODE_ROUTABLE_PEERS; /* get routable (reachable) peers */
|
||||
else
|
||||
return WHYF("unsupported arg '%s'", argv[1]);
|
||||
a.addrlist.first_sid=-1;
|
||||
a.addrlist.first_sid=0;
|
||||
a.addrlist.last_sid=0x7fffffff;
|
||||
a.addrlist.frame_sid_count=MDP_MAX_SID_REQUEST;
|
||||
|
||||
|
@ -71,6 +71,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "serval.h"
|
||||
#include "rhizome.h"
|
||||
#include "strbuf.h"
|
||||
#include "overlay_buffer.h"
|
||||
|
||||
int overlayMode=0;
|
||||
|
||||
@ -199,8 +200,7 @@ int process_incoming_frame(time_ms_t now, struct overlay_interface *interface, o
|
||||
overlay_saw_mdp_containing_frame(f,now);
|
||||
break;
|
||||
default:
|
||||
DEBUGF("Unsupported f->type=0x%x",f->type);
|
||||
return WHY("Support for that f->type not yet implemented");
|
||||
return WHYF("Support for f->type=0x%x not yet implemented",f->type);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -214,7 +214,7 @@ int overlay_frame_process(struct overlay_interface *interface,overlay_frame *f)
|
||||
time_ms_t now = gettime_ms();
|
||||
|
||||
if (debug&DEBUG_OVERLAYFRAMES)
|
||||
DEBUGF(">>> Received frame (type=%02x, bytes=%d)",f->type,f->payload?f->payload->length:-1);
|
||||
DEBUGF(">>> Received frame (type=%02x, bytes=%d)",f->type,f->payload ? f->payload->sizeLimit:-1);
|
||||
|
||||
// only examine payloads that are broadcasts, or where I'm the next hop
|
||||
if (overlay_address_is_broadcast(f->nexthop)) {
|
||||
|
@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "serval.h"
|
||||
|
||||
#include "overlay_buffer.h"
|
||||
/*
|
||||
We use 256bit Curve25519 addresses in the overlay mesh. This means we have very large
|
||||
addresses to send around the place on a regular basis, which is bad.
|
||||
@ -240,17 +240,17 @@ int overlay_abbreviate_try_byindex(unsigned char *in,unsigned char *out,int *ofs
|
||||
return 1;
|
||||
}
|
||||
|
||||
int overlay_abbreviate_append_address(overlay_buffer *b,unsigned char *a)
|
||||
int overlay_abbreviate_append_address(struct overlay_buffer *b,unsigned char *a)
|
||||
{
|
||||
int count=0;
|
||||
ob_makespace(b,SID_SIZE+3);
|
||||
int r=overlay_abbreviate_address(a,&b->bytes[b->length],&count);
|
||||
int r=overlay_abbreviate_address(a,&b->bytes[b->position],&count);
|
||||
if (debug&DEBUG_PACKETCONSTRUCTION) {
|
||||
DEBUGF("address %s abbreviates as shown in this", alloca_tohex_sid(a));
|
||||
dump(NULL, &b->bytes[b->length], count);
|
||||
dump(NULL, &b->bytes[b->position], count);
|
||||
}
|
||||
if (r) return r;
|
||||
b->length+=count;
|
||||
b->position+=count;
|
||||
overlay_abbreviate_set_most_recent_address(a);
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#include "serval.h"
|
||||
#include "subscribers.h"
|
||||
#include "overlay_buffer.h"
|
||||
|
||||
/* List of prioritised advertisements */
|
||||
#define OVERLAY_MAX_ADVERTISEMENT_REQUESTS 16
|
||||
@ -59,7 +60,7 @@ int overlay_route_please_advertise(overlay_node *n)
|
||||
struct subscriber *last_advertised=NULL;
|
||||
|
||||
int add_advertisement(struct subscriber *subscriber, void *context){
|
||||
overlay_buffer *e=context;
|
||||
struct overlay_buffer *e=context;
|
||||
|
||||
if (subscriber->node){
|
||||
overlay_node *n=subscriber->node;
|
||||
@ -84,7 +85,7 @@ int add_advertisement(struct subscriber *subscriber, void *context){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_route_add_advertisements(overlay_buffer *e)
|
||||
int overlay_route_add_advertisements(struct overlay_buffer *e)
|
||||
{
|
||||
/* Construct a route advertisement frame and append it to e.
|
||||
|
||||
@ -113,12 +114,14 @@ int overlay_route_add_advertisements(overlay_buffer *e)
|
||||
*/
|
||||
int i;
|
||||
|
||||
ob_checkpoint(e);
|
||||
|
||||
if (ob_append_byte(e,OF_TYPE_NODEANNOUNCE))
|
||||
return WHY("could not add node advertisement header");
|
||||
ob_append_byte(e,1); /* TTL */
|
||||
|
||||
// assume we might fill the packet
|
||||
ob_append_rfs(e, e->sizeLimit - e->length);
|
||||
ob_append_rfs(e, e->sizeLimit - e->position);
|
||||
|
||||
/* Stuff in dummy address fields */
|
||||
ob_append_byte(e,OA_CODE_BROADCAST);
|
||||
@ -142,16 +145,22 @@ int overlay_route_add_advertisements(overlay_buffer *e)
|
||||
}
|
||||
*/
|
||||
struct subscriber *start = last_advertised;
|
||||
int start_pos = e->position;
|
||||
|
||||
// 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){
|
||||
if (start && e->sizeLimit - e->position >=8){
|
||||
enum_subscribers(NULL, add_advertisement, e);
|
||||
}
|
||||
|
||||
ob_patch_rfs(e,COMPUTE_RFS_LENGTH);
|
||||
|
||||
if (e->position == start_pos){
|
||||
// no advertisements? don't bother to send the payload at all.
|
||||
ob_rewind(e);
|
||||
overlay_abbreviate_clear_most_recent_address();
|
||||
}else
|
||||
ob_patch_rfs(e,COMPUTE_RFS_LENGTH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -168,26 +177,30 @@ int overlay_route_add_advertisements(overlay_buffer *e)
|
||||
*/
|
||||
int overlay_route_saw_advertisements(int i,overlay_frame *f, long long now)
|
||||
{
|
||||
int ofs=0;
|
||||
IN();
|
||||
while(ofs<f->payload->length)
|
||||
while(f->payload->position < f->payload->sizeLimit)
|
||||
{
|
||||
struct subscriber *subscriber;
|
||||
unsigned char *sid = ob_get_bytes_ptr(f->payload, 6);
|
||||
int score=ob_get(f->payload);
|
||||
int gateways_en_route=ob_get(f->payload);
|
||||
|
||||
// stop if hit end of payload
|
||||
if (!sid || score<0 || gateways_en_route<0)
|
||||
continue;
|
||||
|
||||
subscriber = find_subscriber(sid, 6, 0);
|
||||
|
||||
subscriber = find_subscriber(&f->payload->bytes[ofs], 6, 0);
|
||||
if (!subscriber){
|
||||
//WARN("Dispatch PLEASEEXPLAIN not implemented");
|
||||
goto next;
|
||||
continue;
|
||||
}
|
||||
|
||||
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(subscriber->sid)) {
|
||||
if (debug & DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("Ignore announcement about me (%s)", alloca_tohex_sid(subscriber->sid));
|
||||
goto next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Don't let nodes advertise paths to themselves!
|
||||
@ -195,7 +208,7 @@ int overlay_route_saw_advertisements(int i,overlay_frame *f, long long now)
|
||||
if (!memcmp(overlay_abbreviate_current_sender.b,subscriber->sid,SID_SIZE)){
|
||||
if (debug & DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("Ignore announcement about neighbour (%s)", alloca_tohex_sid(subscriber->sid));
|
||||
goto next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* File it */
|
||||
@ -206,8 +219,6 @@ int overlay_route_saw_advertisements(int i,overlay_frame *f, long long now)
|
||||
now-2500,now,
|
||||
score,gateways_en_route);
|
||||
|
||||
next:
|
||||
ofs+=8;
|
||||
}
|
||||
|
||||
RETURN(0);;
|
||||
|
343
overlay_buffer.c
343
overlay_buffer.c
@ -18,12 +18,23 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "serval.h"
|
||||
#include "overlay_buffer.h"
|
||||
|
||||
overlay_buffer *ob_new(int size)
|
||||
/*
|
||||
When writing to a buffer, sizeLimit may place an upper bound on the amount of space to use
|
||||
|
||||
When reading from a buffer, sizeLimit should first be set to the length of any existing data.
|
||||
|
||||
In either case, functions that don't take an offset use and advance the position.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
struct overlay_buffer *ob_new(void)
|
||||
{
|
||||
overlay_buffer *ret=calloc(sizeof(overlay_buffer),1);
|
||||
struct overlay_buffer *ret=calloc(sizeof(struct overlay_buffer),1);
|
||||
if (!ret) return NULL;
|
||||
|
||||
|
||||
ob_unlimitsize(ret);
|
||||
|
||||
return ret;
|
||||
@ -31,19 +42,52 @@ overlay_buffer *ob_new(int size)
|
||||
|
||||
// index an existing static buffer.
|
||||
// and allow other callers to use the ob_ convenience methods for reading and writing up to size bytes.
|
||||
overlay_buffer *ob_static(unsigned char *bytes, int size){
|
||||
overlay_buffer *ret=calloc(sizeof(overlay_buffer),1);
|
||||
struct overlay_buffer *ob_static(unsigned char *bytes, int size){
|
||||
struct overlay_buffer *ret=calloc(sizeof(struct overlay_buffer),1);
|
||||
if (!ret) return NULL;
|
||||
ret->bytes = bytes;
|
||||
ret->allocSize =-1;
|
||||
ret->sizeLimit=size;
|
||||
ret->allocSize = size;
|
||||
ret->allocated = 0;
|
||||
ob_unlimitsize(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ob_free(overlay_buffer *b)
|
||||
// create a new overlay buffer from an existing piece of another buffer.
|
||||
// Both buffers will point to the same memory region.
|
||||
// It is up to the caller to ensure this buffer is not used after the parent buffer is freed.
|
||||
struct overlay_buffer *ob_slice(struct overlay_buffer *b, int offset, int length){
|
||||
struct overlay_buffer *ret=calloc(sizeof(struct overlay_buffer),1);
|
||||
if (!ret) return NULL;
|
||||
|
||||
ret->bytes = b->bytes+offset;
|
||||
ret->allocSize = length;
|
||||
ret->allocated = 0;
|
||||
ob_unlimitsize(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct overlay_buffer *ob_dup(struct overlay_buffer *b){
|
||||
struct overlay_buffer *ret=calloc(sizeof(struct overlay_buffer),1);
|
||||
ret->sizeLimit = b->sizeLimit;
|
||||
ret->position = b->position;
|
||||
ret->checkpointLength = b->checkpointLength;
|
||||
|
||||
if (b->bytes){
|
||||
int byteCount = b->sizeLimit;
|
||||
if (byteCount > b->allocSize)
|
||||
byteCount = b->allocSize;
|
||||
|
||||
ob_append_bytes(ret, b->bytes, byteCount);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ob_free(struct overlay_buffer *b)
|
||||
{
|
||||
if (!b) return WHY("Asked to free NULL");
|
||||
if (b->bytes && b->allocSize>0) free(b->bytes);
|
||||
if (b->bytes && b->allocated) free(b->bytes);
|
||||
b->bytes=NULL;
|
||||
b->allocSize=0;
|
||||
b->sizeLimit=0;
|
||||
@ -51,109 +95,100 @@ int ob_free(overlay_buffer *b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ob_checkpoint(overlay_buffer *b)
|
||||
int ob_checkpoint(struct overlay_buffer *b)
|
||||
{
|
||||
if (!b) return WHY("Asked to checkpoint NULL");
|
||||
b->checkpointLength=b->length;
|
||||
b->checkpointLength=b->position;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ob_rewind(overlay_buffer *b)
|
||||
int ob_rewind(struct overlay_buffer *b)
|
||||
{
|
||||
if (!b) return WHY("Asked to rewind NULL");
|
||||
b->length=b->checkpointLength;
|
||||
b->position=b->checkpointLength;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ob_setlength(overlay_buffer *b,int bytes){
|
||||
if (bytes > b->sizeLimit) return WHY("Length exceeds size limit");
|
||||
if (b->allocSize>=0 && bytes > b->allocSize) return WHY("Length exceeds allocated size");
|
||||
b->length=bytes;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ob_limitsize(overlay_buffer *b,int bytes)
|
||||
int ob_limitsize(struct overlay_buffer *b,int bytes)
|
||||
{
|
||||
if (!b) return WHY("Asked to limit size of NULL");
|
||||
if (b->length>bytes) return WHY("Length of data in buffer already exceeds size limit");
|
||||
if (b->position>bytes) return WHY("Length of data in buffer already exceeds size limit");
|
||||
if (b->checkpointLength>bytes) return WHY("Checkpointed length of data in buffer already exceeds size limit");
|
||||
if (b->bytes && (!b->allocated) && bytes > b->allocSize) return WHY("Size limit exceeds buffer size");
|
||||
if (bytes<0) return WHY("Can't limit buffer to a negative size");
|
||||
if (b->allocSize<0) return WHY("Can't change the limit of a static buffer");
|
||||
b->sizeLimit=bytes;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ob_unlimitsize(overlay_buffer *b)
|
||||
int ob_unlimitsize(struct overlay_buffer *b)
|
||||
{
|
||||
if (!b) return WHY("b is NULL");
|
||||
if (b->allocSize<0) return WHY("Can't change the limit of a static buffer");
|
||||
b->sizeLimit=-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ob_makespace(overlay_buffer *b,int bytes)
|
||||
int ob_makespace(struct overlay_buffer *b,int bytes)
|
||||
{
|
||||
if (b->sizeLimit!=-1 && b->length+bytes>b->sizeLimit) {
|
||||
if (b->sizeLimit!=-1 && b->position+bytes>b->sizeLimit) {
|
||||
if (debug&DEBUG_PACKETFORMATS) WHY("Asked to make space beyond size limit");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (b->allocSize<0){
|
||||
return WHY("Can't resize a static buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// already enough space?
|
||||
if (b->position + bytes < b->allocSize)
|
||||
return 0;
|
||||
|
||||
if (b->bytes && !b->allocated)
|
||||
return WHY("Can't resize a static buffer");
|
||||
|
||||
if (0)
|
||||
DEBUGF("ob_makespace(%p,%d)\n b->bytes=%p,b->length=%d,b->allocSize=%d\n",
|
||||
b,bytes,b->bytes,b->length,b->allocSize);
|
||||
DEBUGF("ob_makespace(%p,%d)\n b->bytes=%p,b->position=%d,b->allocSize=%d\n",
|
||||
b,bytes,b->bytes,b->position,b->allocSize);
|
||||
|
||||
if (b->length+bytes>=b->allocSize)
|
||||
{
|
||||
int newSize=b->length+bytes;
|
||||
if (newSize<64) newSize=64;
|
||||
if (newSize&63) newSize+=64-(newSize&63);
|
||||
if (newSize>1024) {
|
||||
if (newSize&1023) newSize+=1024-(newSize&1023);
|
||||
}
|
||||
if (newSize>65536) {
|
||||
if (newSize&65535) newSize+=65536-(newSize&65535);
|
||||
}
|
||||
if (0) DEBUGF("realloc(b->bytes=%p,newSize=%d)", b->bytes,newSize);
|
||||
/* XXX OSX realloc() seems to be able to corrupt things if the heap is not happy when calling realloc(), making debugging memory corruption much harder.
|
||||
So will do a three-stage malloc,bcopy,free to see if we can tease the bug out that way. */
|
||||
/*
|
||||
unsigned char *r=realloc(b->bytes,newSize);
|
||||
if (!r) return WHY("realloc() failed");
|
||||
b->bytes=r;
|
||||
*/
|
||||
int newSize=b->position+bytes;
|
||||
if (newSize<64) newSize=64;
|
||||
if (newSize&63) newSize+=64-(newSize&63);
|
||||
if (newSize>1024) {
|
||||
if (newSize&1023) newSize+=1024-(newSize&1023);
|
||||
}
|
||||
if (newSize>65536) {
|
||||
if (newSize&65535) newSize+=65536-(newSize&65535);
|
||||
}
|
||||
if (0) DEBUGF("realloc(b->bytes=%p,newSize=%d)", b->bytes,newSize);
|
||||
/* XXX OSX realloc() seems to be able to corrupt things if the heap is not happy when calling realloc(), making debugging memory corruption much harder.
|
||||
So will do a three-stage malloc,bcopy,free to see if we can tease the bug out that way. */
|
||||
/*
|
||||
unsigned char *r=realloc(b->bytes,newSize);
|
||||
if (!r) return WHY("realloc() failed");
|
||||
b->bytes=r;
|
||||
*/
|
||||
#ifdef MALLOC_PARANOIA
|
||||
#warning adding lots of padding to try to catch overruns
|
||||
if (b->bytes) {
|
||||
int i;
|
||||
int corrupt=0;
|
||||
for(i=0;i<4096;i++) if (b->bytes[b->allocSize+i]!=0xbd) corrupt++;
|
||||
if (corrupt) {
|
||||
WHYF("!!!!!! %d corrupted bytes in overrun catch tray", corrupt);
|
||||
dump("overrun catch tray",&b->bytes[b->allocSize],4096);
|
||||
sleep(3600);
|
||||
}
|
||||
}
|
||||
unsigned char *new=malloc(newSize+4096);
|
||||
if (!new) return WHY("realloc() failed");
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<4096;i++) new[newSize+i]=0xbd;
|
||||
}
|
||||
#else
|
||||
unsigned char *new=malloc(newSize);
|
||||
#endif
|
||||
bcopy(b->bytes,new,b->length);
|
||||
if (b->bytes) free(b->bytes);
|
||||
b->bytes=new;
|
||||
b->allocSize=newSize;
|
||||
return 0;
|
||||
if (b->bytes) {
|
||||
int i;
|
||||
int corrupt=0;
|
||||
for(i=0;i<4096;i++) if (b->bytes[b->allocSize+i]!=0xbd) corrupt++;
|
||||
if (corrupt) {
|
||||
WHYF("!!!!!! %d corrupted bytes in overrun catch tray", corrupt);
|
||||
dump("overrun catch tray",&b->bytes[b->allocSize],4096);
|
||||
sleep(3600);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
unsigned char *new=malloc(newSize+4096);
|
||||
if (!new) return WHY("realloc() failed");
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<4096;i++) new[newSize+i]=0xbd;
|
||||
}
|
||||
#else
|
||||
unsigned char *new=malloc(newSize);
|
||||
#endif
|
||||
bcopy(b->bytes,new,b->position);
|
||||
if (b->bytes) free(b->bytes);
|
||||
b->bytes=new;
|
||||
b->allocated=1;
|
||||
b->allocSize=newSize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -162,44 +197,53 @@ int ob_makespace(overlay_buffer *b,int bytes)
|
||||
Functions that append data and increase the size of the buffer if possible / required
|
||||
*/
|
||||
|
||||
int ob_append_byte(overlay_buffer *b,unsigned char byte)
|
||||
int ob_append_byte(struct overlay_buffer *b,unsigned char byte)
|
||||
{
|
||||
if (ob_makespace(b,1)) return WHY("ob_makespace() failed");
|
||||
b->bytes[b->length++] = byte;
|
||||
b->bytes[b->position++] = byte;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char *ob_append_space(overlay_buffer *b,int count)
|
||||
unsigned char *ob_append_space(struct overlay_buffer *b,int count)
|
||||
{
|
||||
if (ob_makespace(b,count)) { WHY("ob_makespace() failed"); return NULL; }
|
||||
if (ob_makespace(b,count))
|
||||
return WHYNULL("ob_makespace() failed");
|
||||
|
||||
unsigned char *r=&b->bytes[b->length];
|
||||
b->length+=count;
|
||||
unsigned char *r=&b->bytes[b->position];
|
||||
b->position+=count;
|
||||
return r;
|
||||
}
|
||||
|
||||
int ob_append_bytes(overlay_buffer *b,unsigned char *bytes,int count)
|
||||
int ob_append_bytes(struct overlay_buffer *b,unsigned char *bytes,int count)
|
||||
{
|
||||
if (ob_makespace(b,count)) return WHY("ob_makespace() failed");
|
||||
|
||||
bcopy(bytes,&b->bytes[b->length],count);
|
||||
b->length+=count;
|
||||
bcopy(bytes,&b->bytes[b->position],count);
|
||||
b->position+=count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ob_append_short(overlay_buffer *b,unsigned short v)
|
||||
int ob_append_ui16(struct overlay_buffer *b, uint16_t v)
|
||||
{
|
||||
unsigned short s=htons(v);
|
||||
return ob_append_bytes(b,(unsigned char *)&s,sizeof(unsigned short));
|
||||
if (ob_makespace(b, 2)) return WHY("ob_makespace() failed");
|
||||
b->bytes[b->position] = (v >> 8) & 0xFF;
|
||||
b->bytes[b->position+1] = v & 0xFF;
|
||||
b->position+=2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ob_append_int(overlay_buffer *b,unsigned int v)
|
||||
int ob_append_ui32(struct overlay_buffer *b, uint32_t v)
|
||||
{
|
||||
unsigned int s=htonl(v);
|
||||
return ob_append_bytes(b,(unsigned char *)&s,sizeof(unsigned int));
|
||||
if (ob_makespace(b, 4)) return WHY("ob_makespace() failed");
|
||||
b->bytes[b->position] = (v >> 24) & 0xFF;
|
||||
b->bytes[b->position+1] = (v >> 16) & 0xFF;
|
||||
b->bytes[b->position+2] = (v >> 8) & 0xFF;
|
||||
b->bytes[b->position+3] = v & 0xFF;
|
||||
b->position+=4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ob_append_rfs(overlay_buffer *b,int l)
|
||||
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;
|
||||
@ -208,7 +252,7 @@ int ob_append_rfs(overlay_buffer *b,int l)
|
||||
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->length;
|
||||
b->var_length_offset=b->position;
|
||||
b->var_length_bytes=rfs_length(l);
|
||||
|
||||
unsigned char c[3]={0,0,0};
|
||||
@ -228,41 +272,70 @@ int ob_append_rfs(overlay_buffer *b,int l)
|
||||
*/
|
||||
|
||||
|
||||
|
||||
int test_offset(overlay_buffer *b,int start,int length){
|
||||
if (!b) FATAL("b is NULL");
|
||||
if (start<0) FATALF("passed illegal offset %d",start);
|
||||
if (b->sizeLimit>=0 && start+length>b->sizeLimit) FATALF("passed offset too large %d", start+length);
|
||||
if (b->allocSize>=0 && start+length>b->allocSize) FATALF("passed offset too large %d", start+length);
|
||||
// make sure a range of bytes is valid for reading
|
||||
int test_offset(struct overlay_buffer *b,int start,int length){
|
||||
if (!b) return -1;
|
||||
if (start<0) return -1;
|
||||
if (b->sizeLimit>=0 && start+length>b->sizeLimit) return -1;
|
||||
if (start+length>b->allocSize) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ob_setbyte(overlay_buffer *b,int ofs,unsigned char value)
|
||||
int ob_getbyte(struct overlay_buffer *b, int ofs)
|
||||
{
|
||||
test_offset(b, ofs, 1);
|
||||
b->bytes[ofs]=value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ob_getbyte(overlay_buffer *b,int ofs)
|
||||
{
|
||||
test_offset(b, ofs, 1);
|
||||
if (ofs >= b->length) FATALF("passed offset too large %d", ofs);
|
||||
if (test_offset(b, ofs, 1))
|
||||
return -1;
|
||||
|
||||
return b->bytes[ofs];
|
||||
}
|
||||
|
||||
unsigned int ob_get_int(overlay_buffer *b,int offset)
|
||||
{
|
||||
// TODO unsigned -1? FATAL?
|
||||
test_offset(b, offset, sizeof(unsigned int));
|
||||
int ob_get_bytes(struct overlay_buffer *b, unsigned char *buff, int len){
|
||||
if (test_offset(b, b->position, len))
|
||||
return -1;
|
||||
|
||||
bcopy(b->bytes + b->position, buff, len);
|
||||
b->position+=len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Some platforms require alignment
|
||||
if (((uintptr_t)&b->bytes[offset])&3) {
|
||||
union { unsigned char uc[4]; uint32_t ui32; } bb;
|
||||
bcopy(&b->bytes[offset], &bb.uc[0], 4);
|
||||
return ntohl(bb.ui32);
|
||||
} else
|
||||
return ntohl(*((uint32_t*)&b->bytes[offset]));
|
||||
unsigned char * ob_get_bytes_ptr(struct overlay_buffer *b, int len){
|
||||
if (test_offset(b, b->position, len))
|
||||
return NULL;
|
||||
|
||||
unsigned char *ret = b->bytes + b->position;
|
||||
b->position+=len;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t ob_get_ui32(struct overlay_buffer *b)
|
||||
{
|
||||
if (test_offset(b, b->position, 4))
|
||||
return 0xFFFFFFFF; // ... unsigned
|
||||
|
||||
uint32_t ret = b->bytes[b->position] << 24
|
||||
| b->bytes[b->position +1] << 16
|
||||
| b->bytes[b->position +2] << 8
|
||||
| b->bytes[b->position +3];
|
||||
b->position+=4;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16_t ob_get_ui16(struct overlay_buffer *b)
|
||||
{
|
||||
if (test_offset(b, b->position, 2))
|
||||
return 0xFFFF; // ... unsigned
|
||||
|
||||
uint16_t ret = b->bytes[b->position] << 8
|
||||
| b->bytes[b->position +1];
|
||||
b->position+=2;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ob_get(struct overlay_buffer *b){
|
||||
if (test_offset(b, b->position, 1))
|
||||
return -1;
|
||||
|
||||
return b->bytes[b->position++];
|
||||
}
|
||||
|
||||
int rfs_length(int l)
|
||||
@ -307,21 +380,21 @@ int rfs_decode(unsigned char *b,int *ofs)
|
||||
}
|
||||
|
||||
// move the data at offset, by shift bytes
|
||||
int ob_indel_space(overlay_buffer *b,int offset,int shift)
|
||||
int ob_indel_space(struct overlay_buffer *b,int offset,int shift)
|
||||
{
|
||||
if (offset>=b->length) return -1;
|
||||
if (offset>=b->position) return -1;
|
||||
if (shift>0 && ob_makespace(b, shift)) return -1;
|
||||
bcopy(&b->bytes[offset],&b->bytes[offset+shift],b->length-offset);
|
||||
b->length+=shift;
|
||||
bcopy(&b->bytes[offset],&b->bytes[offset+shift],b->position-offset);
|
||||
b->position+=shift;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ob_patch_rfs(overlay_buffer *b,int l)
|
||||
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->length - (b->var_length_offset + b->var_length_bytes);
|
||||
l = b->position - (b->var_length_offset + b->var_length_bytes);
|
||||
}
|
||||
if (l<0||l>0xffff) return -1;
|
||||
|
||||
@ -334,13 +407,13 @@ int ob_patch_rfs(overlay_buffer *b,int l)
|
||||
new_size,b->var_length_bytes,shift);
|
||||
dump("before indel",
|
||||
&b->bytes[b->var_length_offset],
|
||||
b->length-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->length-b->var_length_offset);
|
||||
b->position-b->var_length_offset);
|
||||
}
|
||||
|
||||
}
|
||||
@ -350,7 +423,7 @@ int ob_patch_rfs(overlay_buffer *b,int l)
|
||||
if (debug&DEBUG_PACKETCONSTRUCTION) {
|
||||
dump("after patch",
|
||||
&b->bytes[b->var_length_offset],
|
||||
b->length-b->var_length_offset);
|
||||
b->position-b->var_length_offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -364,10 +437,10 @@ int asprintable(int c)
|
||||
return c;
|
||||
}
|
||||
|
||||
int ob_dump(overlay_buffer *b,char *desc)
|
||||
int ob_dump(struct overlay_buffer *b,char *desc)
|
||||
{
|
||||
DEBUGF("overlay_buffer '%s' at %p : length=%d", desc, b, b->length);
|
||||
dump(NULL, b->bytes, b->length);
|
||||
DEBUGF("overlay_buffer '%s' at %p : length=%d", desc, b, b->position);
|
||||
dump(NULL, b->bytes, b->position);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
74
overlay_buffer.h
Normal file
74
overlay_buffer.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
Serval Daemon
|
||||
Copyright (C) 2012 Serval Project Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _SERVALD_OVERLAY_BUFFER_H
|
||||
#define _SERVALD_OVERLAY_BUFFER_H
|
||||
|
||||
struct overlay_buffer {
|
||||
unsigned char *bytes;
|
||||
|
||||
// remembered position for rewinding
|
||||
int checkpointLength;
|
||||
|
||||
// position of data read / written
|
||||
int position;
|
||||
|
||||
// maximum allowed bytes for reading / writing
|
||||
int sizeLimit;
|
||||
|
||||
// size of buffer
|
||||
int allocSize;
|
||||
|
||||
// is this an allocated buffer? can it be resized? Should it be freed?
|
||||
int allocated;
|
||||
|
||||
// length position and size for later patching
|
||||
int var_length_offset;
|
||||
int var_length_bytes;
|
||||
};
|
||||
|
||||
struct overlay_buffer *ob_new(void);
|
||||
struct overlay_buffer *ob_static(unsigned char *bytes, int size);
|
||||
struct overlay_buffer *ob_slice(struct overlay_buffer *b, int offset, int length);
|
||||
struct overlay_buffer *ob_dup(struct overlay_buffer *b);
|
||||
int ob_free(struct overlay_buffer *b);
|
||||
int ob_checkpoint(struct overlay_buffer *b);
|
||||
int ob_rewind(struct overlay_buffer *b);
|
||||
int ob_limitsize(struct overlay_buffer *b,int bytes);
|
||||
int ob_unlimitsize(struct overlay_buffer *b);
|
||||
int ob_makespace(struct overlay_buffer *b,int bytes);
|
||||
int ob_append_byte(struct overlay_buffer *b,unsigned char byte);
|
||||
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_append_rfs(struct overlay_buffer *b,int l);
|
||||
// get one byte, -ve number indicates failure
|
||||
int ob_getbyte(struct overlay_buffer *b,int ofs);
|
||||
// get one byte from the current position, -ve number indicates failure
|
||||
int ob_get(struct overlay_buffer *b);
|
||||
int ob_get_bytes(struct overlay_buffer *b, unsigned char *buff, int len);
|
||||
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);
|
||||
|
||||
|
||||
#endif
|
@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include <time.h>
|
||||
#include "serval.h"
|
||||
#include "strbuf.h"
|
||||
#include "overlay_buffer.h"
|
||||
|
||||
#ifdef HAVE_IFADDRS_H
|
||||
#include <ifaddrs.h>
|
||||
@ -52,7 +53,7 @@ struct profile_total sock_any_stats;
|
||||
struct outgoing_packet{
|
||||
overlay_interface *interface;
|
||||
int i;
|
||||
overlay_buffer *buffer;
|
||||
struct overlay_buffer *buffer;
|
||||
};
|
||||
|
||||
struct sched_ent next_packet;
|
||||
@ -925,7 +926,7 @@ static void
|
||||
overlay_init_packet(struct outgoing_packet *packet, int interface) {
|
||||
packet->i = interface;
|
||||
packet->interface = &overlay_interfaces[packet->i];
|
||||
packet->buffer=ob_new(packet->interface->mtu);
|
||||
packet->buffer=ob_new();
|
||||
ob_limitsize(packet->buffer, packet->interface->mtu);
|
||||
ob_append_bytes(packet->buffer,magic_header,4);
|
||||
|
||||
@ -1075,14 +1076,14 @@ overlay_fill_send_packet(struct outgoing_packet *packet, time_ms_t now) {
|
||||
|
||||
if(packet->buffer){
|
||||
// send the packet
|
||||
if (packet->buffer->length>=HEADERFIELDS_LEN){
|
||||
if (packet->buffer->position>=HEADERFIELDS_LEN){
|
||||
if (debug&DEBUG_PACKETCONSTRUCTION)
|
||||
dump("assembled packet",&packet->buffer->bytes[0],packet->buffer->length);
|
||||
dump("assembled packet",&packet->buffer->bytes[0],packet->buffer->position);
|
||||
|
||||
if (debug&DEBUG_OVERLAYINTERFACES)
|
||||
DEBUGF("Sending %d byte packet",packet->buffer->length);
|
||||
DEBUGF("Sending %d byte packet",packet->buffer->position);
|
||||
|
||||
overlay_broadcast_ensemble(packet->i,NULL,packet->buffer->bytes,packet->buffer->length);
|
||||
overlay_broadcast_ensemble(packet->i,NULL,packet->buffer->bytes,packet->buffer->position);
|
||||
}
|
||||
ob_free(packet->buffer);
|
||||
overlay_abbreviate_clear_most_recent_address();
|
||||
|
@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "serval.h"
|
||||
#include "strbuf.h"
|
||||
#include "subscribers.h"
|
||||
#include "overlay_buffer.h"
|
||||
|
||||
struct profile_total mdp_stats={.name="overlay_mdp_poll"};
|
||||
|
||||
@ -280,7 +281,7 @@ unsigned char *overlay_mdp_decrypt(overlay_frame *f, overlay_mdp_frame *mdp, int
|
||||
{
|
||||
IN();
|
||||
|
||||
*len=f->payload->length;
|
||||
*len=f->payload->sizeLimit;
|
||||
unsigned char *b = NULL;
|
||||
unsigned char plain_block[(*len)+16];
|
||||
|
||||
@ -288,7 +289,7 @@ unsigned char *overlay_mdp_decrypt(overlay_frame *f, overlay_mdp_frame *mdp, int
|
||||
case 0:
|
||||
/* get payload */
|
||||
b=&f->payload->bytes[0];
|
||||
*len=f->payload->length;
|
||||
*len=f->payload->sizeLimit;
|
||||
mdp->packetTypeAndFlags|=MDP_NOCRYPT|MDP_NOSIGN;
|
||||
break;
|
||||
case OF_CRYPTO_CIPHERED:
|
||||
@ -306,7 +307,7 @@ unsigned char *overlay_mdp_decrypt(overlay_frame *f, overlay_mdp_frame *mdp, int
|
||||
|
||||
/* get payload and following compacted signature */
|
||||
b=&f->payload->bytes[0];
|
||||
*len=f->payload->length-crypto_sign_edwards25519sha512batch_BYTES;
|
||||
*len=f->payload->sizeLimit-crypto_sign_edwards25519sha512batch_BYTES;
|
||||
|
||||
/* get hash */
|
||||
unsigned char hash[crypto_hash_sha512_BYTES];
|
||||
@ -344,7 +345,7 @@ unsigned char *overlay_mdp_decrypt(overlay_frame *f, overlay_mdp_frame *mdp, int
|
||||
if (!k) { WHY("I don't have the private key required to decrypt that");
|
||||
RETURN(NULL); }
|
||||
bzero(&plain_block[0],crypto_box_curve25519xsalsa20poly1305_ZEROBYTES-16);
|
||||
int cipher_len=f->payload->length-nb;
|
||||
int cipher_len=f->payload->sizeLimit-nb;
|
||||
bcopy(&f->payload->bytes[nb],&plain_block[16],cipher_len);
|
||||
if (0) {
|
||||
dump("nm bytes",k,crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES);
|
||||
@ -374,7 +375,7 @@ int overlay_saw_mdp_containing_frame(overlay_frame *f, time_ms_t now)
|
||||
Take payload from mdp frame itself.
|
||||
*/
|
||||
overlay_mdp_frame mdp;
|
||||
int len=f->payload->length;
|
||||
int len=f->payload->sizeLimit;
|
||||
|
||||
/* Get source and destination addresses */
|
||||
bcopy(f->destination,mdp.in.dst.sid,SID_SIZE);
|
||||
@ -750,13 +751,15 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
|
||||
case 0: /* crypted and signed (using CryptoBox authcryption primitive) */
|
||||
frame->modifiers=OF_CRYPTO_SIGNED|OF_CRYPTO_CIPHERED;
|
||||
/* Prepare payload */
|
||||
frame->payload=ob_new(1 /* frame type (MDP) */
|
||||
+1 /* MDP version */
|
||||
+4 /* dst port */
|
||||
+4 /* src port */
|
||||
+crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
|
||||
+crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
|
||||
+mdp->out.payload_length);
|
||||
frame->payload=ob_new();
|
||||
/*length should be;
|
||||
1 - frame type (MDP)
|
||||
+1 - MDP version
|
||||
+4 - dst port
|
||||
+4 - src port
|
||||
+crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
|
||||
+crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
|
||||
+mdp->out.payload_length*/
|
||||
{
|
||||
/* write cryptobox nonce */
|
||||
unsigned char nonce[crypto_box_curve25519xsalsa20poly1305_NONCEBYTES];
|
||||
@ -792,7 +795,7 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
|
||||
unsigned char *k=keyring_get_nm_bytes(&mdp->out.src,&mdp->out.dst);
|
||||
if (!k) { op_free(frame); RETURN(WHY("could not compute Curve25519(NxM)")); }
|
||||
/* Get pointer to place in frame where the ciphered text needs to go */
|
||||
int cipher_offset=frame->payload->length;
|
||||
int cipher_offset=frame->payload->position;
|
||||
unsigned char *cipher_text=ob_append_space(frame->payload,cipher_len);
|
||||
if (fe||(!cipher_text))
|
||||
{ op_free(frame); RETURN(WHY("could not make space for ciphered text")); }
|
||||
@ -803,16 +806,16 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
|
||||
/* now shuffle down 16 bytes to get rid of the temporary space that crypto_box
|
||||
uses. */
|
||||
bcopy(&cipher_text[16],&cipher_text[0],cipher_len-16);
|
||||
frame->payload->length-=16;
|
||||
frame->payload->position-=16;
|
||||
if (0) {
|
||||
DEBUG("authcrypted mdp frame");
|
||||
dump("nm bytes",k,crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES);
|
||||
dump("nonce",nonce,crypto_box_curve25519xsalsa20poly1305_NONCEBYTES);
|
||||
dump("plain text",&plain[16],cipher_len-16);
|
||||
dump("cipher text",cipher_text,cipher_len-16);
|
||||
DEBUGF("frame->payload->length=%d,cipher_len-16=%d,cipher_offset=%d", frame->payload->length,cipher_len-16,cipher_offset);
|
||||
DEBUGF("frame->payload->length=%d,cipher_len-16=%d,cipher_offset=%d", frame->payload->position,cipher_len-16,cipher_offset);
|
||||
dump("frame",&frame->payload->bytes[0],
|
||||
frame->payload->length);
|
||||
frame->payload->position);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -838,12 +841,15 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
|
||||
*/
|
||||
frame->modifiers=OF_CRYPTO_SIGNED;
|
||||
/* Prepare payload */
|
||||
frame->payload=ob_new(1 /* frame type (MDP) */
|
||||
+1 /* MDP version */
|
||||
+4 /* dst port */
|
||||
+4 /* src port */
|
||||
+crypto_sign_edwards25519sha512batch_BYTES
|
||||
+mdp->out.payload_length);
|
||||
frame->payload=ob_new();
|
||||
/* Length should be;
|
||||
1 - frame type (MDP)
|
||||
+1 - MDP version
|
||||
+4 - dst port
|
||||
+4 - src port
|
||||
+crypto_sign_edwards25519sha512batch_BYTES
|
||||
+mdp->out.payload_length
|
||||
*/
|
||||
{
|
||||
unsigned char *key=keyring_find_sas_private(keyring,mdp->out.src.sid,NULL);
|
||||
if (!key) { op_free(frame); RETURN(WHY("could not find signing key")); }
|
||||
@ -893,17 +899,20 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
|
||||
case MDP_NOSIGN|MDP_NOCRYPT: /* clear text and no signature */
|
||||
frame->modifiers=0;
|
||||
/* Copy payload body in */
|
||||
frame->payload=ob_new(1 /* frame type (MDP) */
|
||||
+1 /* MDP version */
|
||||
+4 /* dst port */
|
||||
+4 /* src port */
|
||||
+mdp->out.payload_length);
|
||||
frame->payload=ob_new();
|
||||
/* Length should be;
|
||||
1 - frame type (MDP)
|
||||
+1 - MDP version
|
||||
+4 - dst port
|
||||
+4 - src port
|
||||
+mdp->out.payload_length
|
||||
*/
|
||||
/* MDP version 1 */
|
||||
ob_append_byte(frame->payload,0x01);
|
||||
ob_append_byte(frame->payload,0x01);
|
||||
/* Destination port */
|
||||
ob_append_int(frame->payload,mdp->out.src.port);
|
||||
ob_append_int(frame->payload,mdp->out.dst.port);
|
||||
ob_append_ui32(frame->payload,mdp->out.src.port);
|
||||
ob_append_ui32(frame->payload,mdp->out.dst.port);
|
||||
ob_append_bytes(frame->payload,mdp->out.payload,mdp->out.payload_length);
|
||||
break;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#include "serval.h"
|
||||
#include "strbuf.h"
|
||||
#include "overlay_buffer.h"
|
||||
|
||||
struct sockaddr_in loopback = {
|
||||
.sin_family=0,
|
||||
@ -236,12 +237,10 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
|
||||
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.
|
||||
|
||||
|
||||
/* Create an overlay buffer, wrapping around this static packet */
|
||||
f.payload = ob_static(&packet[ofs], nextPayload - ofs);
|
||||
ob_setlength(f.payload, nextPayload - ofs);
|
||||
ob_limitsize(f.payload, nextPayload - ofs);
|
||||
|
||||
/* Finally process the frame */
|
||||
overlay_frame_process(interface,&f);
|
||||
@ -257,7 +256,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_add_selfannouncement(int interface,overlay_buffer *b)
|
||||
int overlay_add_selfannouncement(int interface,struct overlay_buffer *b)
|
||||
{
|
||||
|
||||
/* Pull the first record from the HLR database and turn it into a
|
||||
@ -351,9 +350,9 @@ int overlay_add_selfannouncement(int interface,overlay_buffer *b)
|
||||
// number: one millisecond ago.
|
||||
if (last_ms == -1)
|
||||
last_ms = now - 1;
|
||||
if (ob_append_int(b, last_ms))
|
||||
if (ob_append_ui32(b, last_ms))
|
||||
return WHY("Could not add low sequence number to self-announcement");
|
||||
if (ob_append_int(b, now))
|
||||
if (ob_append_ui32(b, now))
|
||||
return WHY("Could not add high sequence number to self-announcement");
|
||||
if (debug&DEBUG_OVERLAYINTERFACES)
|
||||
DEBUGF("interface #%d: last_tick_ms=%lld, now=%lld (delta=%lld)",
|
||||
|
@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "serval.h"
|
||||
#include "overlay_buffer.h"
|
||||
|
||||
int overlay_payload_verify(overlay_frame *p)
|
||||
{
|
||||
@ -27,7 +28,7 @@ int overlay_payload_verify(overlay_frame *p)
|
||||
return WHY("function not implemented");
|
||||
}
|
||||
|
||||
int op_append_type(overlay_buffer *headers,overlay_frame *p)
|
||||
int op_append_type(struct overlay_buffer *headers,overlay_frame *p)
|
||||
{
|
||||
unsigned char c[3];
|
||||
switch(p->type&OF_TYPE_FLAG_BITS)
|
||||
@ -59,16 +60,16 @@ int op_append_type(overlay_buffer *headers,overlay_frame *p)
|
||||
}
|
||||
|
||||
|
||||
int overlay_frame_package_fmt1(overlay_frame *p,overlay_buffer *b)
|
||||
int overlay_frame_package_fmt1(overlay_frame *p, struct overlay_buffer *b)
|
||||
{
|
||||
/* Convert a payload (frame) structure into a series of bytes.
|
||||
Assumes that any encryption etc has already been done.
|
||||
Will pick a next hop if one has not been chosen.
|
||||
*/
|
||||
|
||||
overlay_buffer *headers;
|
||||
struct overlay_buffer *headers;
|
||||
|
||||
headers=ob_new(256);
|
||||
headers=ob_new();
|
||||
|
||||
if (!headers) return WHY("could not allocate overlay buffer for headers");
|
||||
|
||||
@ -111,26 +112,26 @@ int overlay_frame_package_fmt1(overlay_frame *p,overlay_buffer *b)
|
||||
we rely on context for abbreviating the addresses. So we write it initially and then patch it
|
||||
after.
|
||||
*/
|
||||
int max_len=((SID_SIZE+3)*3+headers->length+p->payload->length);
|
||||
int max_len=((SID_SIZE+3)*3+headers->position+p->payload->position);
|
||||
if (debug&DEBUG_PACKETCONSTRUCTION)
|
||||
DEBUGF("Appending RFS for max_len=%d\n",max_len);
|
||||
ob_append_rfs(headers,max_len);
|
||||
|
||||
int addrs_start=headers->length;
|
||||
int addrs_start=headers->position;
|
||||
|
||||
/* Write out addresses as abbreviated as possible */
|
||||
overlay_abbreviate_append_address(headers,p->nexthop);
|
||||
overlay_abbreviate_append_address(headers,p->destination);
|
||||
overlay_abbreviate_append_address(headers,p->source);
|
||||
|
||||
int addrs_len=headers->length-addrs_start;
|
||||
int actual_len=addrs_len+p->payload->length;
|
||||
int addrs_len=headers->position-addrs_start;
|
||||
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);
|
||||
|
||||
/* Write payload format plus total length of header bits */
|
||||
if (ob_makespace(b,2+headers->length+p->payload->length)) {
|
||||
if (ob_makespace(b,2+headers->position+p->payload->position)) {
|
||||
/* Not enough space free in output buffer */
|
||||
if (debug&DEBUG_PACKETFORMATS)
|
||||
DEBUGF("Could not make enough space free in output buffer");
|
||||
@ -138,11 +139,11 @@ int overlay_frame_package_fmt1(overlay_frame *p,overlay_buffer *b)
|
||||
}
|
||||
|
||||
/* Package up headers and payload */
|
||||
if (ob_append_bytes(b,headers->bytes,headers->length)) {
|
||||
if (ob_append_bytes(b,headers->bytes,headers->position)) {
|
||||
WHY("could not append header");
|
||||
goto cleanup;
|
||||
}
|
||||
if (ob_append_bytes(b,p->payload->bytes,p->payload->length)) {
|
||||
if (ob_append_bytes(b,p->payload->bytes,p->payload->position)) {
|
||||
WHY("could not append payload");
|
||||
goto cleanup;
|
||||
}
|
||||
@ -156,13 +157,6 @@ cleanup:
|
||||
return -1;
|
||||
}
|
||||
|
||||
overlay_buffer *overlay_payload_unpackage(overlay_frame *b) {
|
||||
/* Extract the payload at the current location in the buffer. */
|
||||
|
||||
WHY("not implemented");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int dump_queue(char *msg,int q)
|
||||
{
|
||||
overlay_txqueue *qq=&overlay_tx[q];
|
||||
@ -191,7 +185,7 @@ int dump_payload(overlay_frame *p,char *message)
|
||||
message?message:"");
|
||||
DEBUGF(" next hop is %s",alloca_tohex_sid(p->nexthop));
|
||||
if (p->payload)
|
||||
dump("payload contents", &p->payload->bytes[0],p->payload->length);
|
||||
dump("payload contents", &p->payload->bytes[0],p->payload->position);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -204,8 +198,8 @@ int overlay_payload_enqueue(int q,overlay_frame *p,int forceBroadcastP)
|
||||
|
||||
Complain if there are too many frames in the queue.
|
||||
*/
|
||||
if (0)
|
||||
WHYF("Enqueuing packet for %s* (q[%d]length = %d)",
|
||||
if (debug&DEBUG_PACKETTX)
|
||||
DEBUGF("Enqueuing packet for %s* (q[%d]length = %d)",
|
||||
alloca_tohex(p->destination, 7),
|
||||
q,overlay_tx[q].length);
|
||||
|
||||
@ -274,16 +268,8 @@ overlay_frame *op_dup(overlay_frame *in)
|
||||
|
||||
/* copy main data structure */
|
||||
bcopy(in,out,sizeof(overlay_frame));
|
||||
out->payload=ob_new(in->payload->length);
|
||||
if (!out->payload) {
|
||||
free(out);
|
||||
return WHYNULL("ob_new() failed");
|
||||
}
|
||||
if (ob_append_bytes(out->payload,&in->payload->bytes[0],in->payload->length))
|
||||
{
|
||||
op_free(out);
|
||||
return WHYNULL("could not duplicate payload bytes");
|
||||
}
|
||||
|
||||
out->payload=ob_dup(in->payload);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "serval.h"
|
||||
#include "strbuf.h"
|
||||
#include "subscribers.h"
|
||||
#include "overlay_buffer.h"
|
||||
|
||||
/*
|
||||
Here we implement the actual routing algorithm which is heavily based on BATMAN.
|
||||
@ -349,6 +350,7 @@ int overlay_route_ack_selfannounce(overlay_frame *f,
|
||||
if (overlay_resolve_next_hop(out)) {
|
||||
/* no open path, so convert to broadcast */
|
||||
overlay_frame_set_broadcast_as_destination(out);
|
||||
out->isBroadcast = 1;
|
||||
out->ttl=2;
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUG("Broadcasting ack to selfannounce for hithero unroutable node");
|
||||
@ -368,13 +370,12 @@ int overlay_route_ack_selfannounce(overlay_frame *f,
|
||||
numbers means we can't just take the highest-numbered sequence number.
|
||||
So we need to take the observation which was most recently received.
|
||||
*/
|
||||
out->payload=ob_new(4+32*2+1); /* will grow if it isn't big enough, but let's try to
|
||||
avoid a realloc() if possible */
|
||||
out->payload=ob_new();
|
||||
|
||||
/* XXX - we should merge contiguous observation reports so that packet loss
|
||||
on the return path doesn't count against the link. */
|
||||
ob_append_int(out->payload,s1);
|
||||
ob_append_int(out->payload,s2);
|
||||
ob_append_ui32(out->payload,s1);
|
||||
ob_append_ui32(out->payload,s2);
|
||||
|
||||
/* The ack needs to contain the per-interface scores that we have built up
|
||||
for this neighbour.
|
||||
@ -552,9 +553,9 @@ int overlay_route_saw_selfannounce(overlay_frame *f, time_ms_t now)
|
||||
RETURN(-1);
|
||||
}
|
||||
|
||||
s1=ob_get_int(f->payload, 0);
|
||||
s2=ob_get_int(f->payload, 4);
|
||||
sender_interface=ob_getbyte(f->payload, 8);
|
||||
s1=ob_get_ui32(f->payload);
|
||||
s2=ob_get_ui32(f->payload);
|
||||
sender_interface=ob_get(f->payload);
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("Received self-announcement for sequence range [%08x,%08x] from interface %d",s1,s2,sender_interface);
|
||||
|
||||
@ -803,14 +804,14 @@ int overlay_route_saw_selfannounce_ack(overlay_frame *f,long long now)
|
||||
{
|
||||
IN();
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUGF("processing selfannounce ack (payload length=%d)",f->payload->length);
|
||||
DEBUGF("processing selfannounce ack (payload length=%d)",f->payload->sizeLimit);
|
||||
|
||||
if (f->payload->length<9)
|
||||
if (f->payload->sizeLimit<9)
|
||||
RETURN(WHY("FOO! selfannounce ack packet too short"));
|
||||
|
||||
unsigned int s1=ob_get_int(f->payload,0);
|
||||
unsigned int s2=ob_get_int(f->payload,4);
|
||||
int iface=ob_getbyte(f->payload,8);
|
||||
unsigned int s1=ob_get_ui32(f->payload);
|
||||
unsigned int s2=ob_get_ui32(f->payload);
|
||||
int iface=ob_get(f->payload);
|
||||
|
||||
// Call something like the following for each link
|
||||
overlay_route_node_can_hear_me(f->source,iface,s1,s2,now);
|
||||
|
@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "serval.h"
|
||||
#include "rhizome.h"
|
||||
#include <assert.h>
|
||||
#include "overlay_buffer.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
int rhizome_manifest_to_bar(rhizome_manifest *m,unsigned char *bar)
|
||||
@ -73,7 +74,7 @@ int rhizome_manifest_to_bar(rhizome_manifest *m,unsigned char *bar)
|
||||
|
||||
int bundles_available=-1;
|
||||
int bundle_offset[2]={0,0};
|
||||
int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
int overlay_rhizome_add_advertisements(int interface_number, struct overlay_buffer *e)
|
||||
{
|
||||
IN();
|
||||
int voice_mode=0;
|
||||
@ -93,13 +94,10 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
if (voice_mode) if (random()&3) { RETURN(0); }
|
||||
|
||||
int pass;
|
||||
int bytes=e->sizeLimit-e->length;
|
||||
int bytes=e->sizeLimit-e->position;
|
||||
int overhead=1+11+1+2+2; /* maximum overhead */
|
||||
int slots=(bytes-overhead)/RHIZOME_BAR_BYTES;
|
||||
if (slots>30) slots=30;
|
||||
int slots_used=0;
|
||||
int bytes_used=0;
|
||||
int bytes_available=bytes-overhead-1 /* one byte held for expanding RFS */;
|
||||
int bundles_advertised=0;
|
||||
|
||||
if (slots<1) { RETURN(WHY("No room for node advertisements")); }
|
||||
@ -110,7 +108,7 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
RETURN(WHY("could not add rhizome bundle advertisement header"));
|
||||
ob_append_byte(e, 1); /* TTL (1 byte) */
|
||||
|
||||
ob_append_rfs(e,1+11+1+2+RHIZOME_BAR_BYTES*slots_used/* RFS */);
|
||||
ob_append_rfs(e,1+11+1+2+RHIZOME_BAR_BYTES/* RFS */);
|
||||
|
||||
/* Stuff in dummy address fields (11 bytes) */
|
||||
ob_append_byte(e,OA_CODE_BROADCAST);
|
||||
@ -129,7 +127,7 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
*/
|
||||
ob_append_byte(e,3+skipmanifests);
|
||||
/* Rhizome HTTP server port number (2 bytes) */
|
||||
ob_append_short(e, rhizome_http_server_port);
|
||||
ob_append_ui16(e, rhizome_http_server_port);
|
||||
|
||||
/* XXX Should add priority bundles here.
|
||||
XXX Should prioritise bundles for subscribed groups, Serval-authorised files
|
||||
@ -165,6 +163,7 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
sqlite3_blob *blob=NULL;
|
||||
|
||||
for(pass=skipmanifests;pass<2;pass++) {
|
||||
ob_checkpoint(e);
|
||||
switch(pass) {
|
||||
case 0: /* Full manifests */
|
||||
statement = sqlite_prepare("SELECT MANIFEST,ROWID FROM MANIFESTS LIMIT %d,%d", bundle_offset[pass], slots);
|
||||
@ -175,9 +174,8 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
}
|
||||
if (!statement)
|
||||
RETURN(WHY("Could not prepare sql statement for fetching BARs for advertisement"));
|
||||
while( bytes_used < bytes_available
|
||||
&& sqlite_step_retry(&retry, statement) == SQLITE_ROW
|
||||
&& e->length + RHIZOME_BAR_BYTES <= e->sizeLimit
|
||||
while( sqlite_step_retry(&retry, statement) == SQLITE_ROW
|
||||
&& e->position+RHIZOME_BAR_BYTES<=e->sizeLimit
|
||||
) {
|
||||
int column_type=sqlite3_column_type(statement, 0);
|
||||
switch(column_type) {
|
||||
@ -214,77 +212,37 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* XXX This whole section is too hard to follow how the frame gets
|
||||
built up. In particular the calculations for space required etc
|
||||
are quite opaque... and I wrote it! */
|
||||
int overhead=0;
|
||||
int frameFull=0;
|
||||
if (!pass) overhead=2;
|
||||
if (0) DEBUGF("e=%p, e->bytes=%p,e->length=%d, e->allocSize=%d", e,e->bytes,e->length,e->allocSize);
|
||||
|
||||
if (ob_makespace(e,overhead+2+blob_bytes)) {
|
||||
if (0||debug&DEBUG_RHIZOME) {
|
||||
rhizome_manifest *m=rhizome_new_manifest();
|
||||
char mdata[blob_bytes]; mdata[0]=0; mdata[1]=0;
|
||||
sqlite3_blob_read(blob,&mdata[0],blob_bytes,0);
|
||||
rhizome_read_manifest_file(m,mdata, blob_bytes);
|
||||
long long version = rhizome_manifest_get_ll(m, "version");
|
||||
DEBUGF("Stop cramming %s advertisements: not enough space for %s*:v%lld (%d bytes, size limit=%d, used=%d)",
|
||||
pass?"BARs":"manifests",
|
||||
alloca_tohex(m->cryptoSignPublic, 8),
|
||||
version,
|
||||
blob_bytes,e->sizeLimit,e->length);
|
||||
rhizome_manifest_free(m);
|
||||
}
|
||||
frameFull=1;
|
||||
} else if (!pass) {
|
||||
/* put manifest length field and manifest ID */
|
||||
/* XXX why on earth is this being done this way, instead of
|
||||
with ob_append_byte() ??? */
|
||||
ob_setbyte(e,e->length,(blob_bytes>>8)&0xff);
|
||||
ob_setbyte(e,e->length+1,(blob_bytes>>0)&0xff);
|
||||
if (0&&debug&DEBUG_RHIZOME)
|
||||
DEBUGF("length bytes written at offset 0x%x",e->length);
|
||||
/* make sure there's enough room for the blob, its length,
|
||||
the 0xFF end marker and 1 spare for the rfs length to increase */
|
||||
if (ob_makespace(e,overhead+blob_bytes+2))
|
||||
goto stopStuffing;
|
||||
|
||||
if (!pass) {
|
||||
/* include manifest length field */
|
||||
ob_append_ui16(e, blob_bytes);
|
||||
}
|
||||
if (frameFull) {
|
||||
sqlite3_blob_close(blob);
|
||||
blob=NULL;
|
||||
|
||||
unsigned char *dest=ob_append_space(e, blob_bytes);
|
||||
if (!dest){
|
||||
WHY("Reading blob will overflow overlay_buffer");
|
||||
goto stopStuffing;
|
||||
}
|
||||
if (e->length+overhead+blob_bytes>=e->allocSize) {
|
||||
WHY("Reading blob will overflow overlay_buffer");
|
||||
sqlite3_blob_close(blob);
|
||||
blob=NULL;
|
||||
continue;
|
||||
}
|
||||
if (sqlite3_blob_read(blob,&e->bytes[e->length+overhead],blob_bytes,0) != SQLITE_OK) {
|
||||
|
||||
if (sqlite3_blob_read(blob,dest,blob_bytes,0) != SQLITE_OK) {
|
||||
WHYF("sqlite3_blob_read() failed, %s", sqlite3_errmsg(rhizome_db));
|
||||
sqlite3_blob_close(blob);
|
||||
blob=NULL;
|
||||
continue;
|
||||
goto stopStuffing;
|
||||
}
|
||||
|
||||
/* debug: show which BID/version combos we are advertising */
|
||||
if (0 && (!pass)) {
|
||||
rhizome_manifest *m = rhizome_new_manifest();
|
||||
rhizome_read_manifest_file(m, (char *)&e->bytes[e->length+overhead], blob_bytes);
|
||||
long long version = rhizome_manifest_get_ll(m, "version");
|
||||
DEBUGF("Advertising manifest %s* version %lld", alloca_tohex(m->cryptoSignPublic, 8), version);
|
||||
rhizome_manifest_free(m);
|
||||
}
|
||||
|
||||
e->length+=overhead+blob_bytes;
|
||||
if (e->length>e->allocSize) {
|
||||
sqlite3_blob_close(blob);
|
||||
blob=NULL;
|
||||
FATAL("e->length > e->size");
|
||||
}
|
||||
bytes_used+=overhead+blob_bytes;
|
||||
bundles_advertised++;
|
||||
bundle_offset[pass]++;
|
||||
|
||||
sqlite3_blob_close(blob);
|
||||
blob=NULL;
|
||||
|
||||
ob_checkpoint(e);
|
||||
}
|
||||
}
|
||||
stopStuffing:
|
||||
@ -294,23 +252,16 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
if (statement)
|
||||
sqlite3_finalize(statement);
|
||||
statement = NULL;
|
||||
|
||||
ob_rewind(e);
|
||||
|
||||
if (!pass) {
|
||||
/* Mark end of whole manifests by writing 0xff, which is more than the MSB
|
||||
of a manifest's length is allowed to be. */
|
||||
ob_append_byte(e,0xff);
|
||||
bytes_used++;
|
||||
}
|
||||
}
|
||||
|
||||
if (blob)
|
||||
sqlite3_blob_close(blob);
|
||||
blob = NULL;
|
||||
if (statement)
|
||||
sqlite3_finalize(statement);
|
||||
statement = NULL;
|
||||
|
||||
if (debug & DEBUG_RHIZOME)
|
||||
DEBUGF("Appended %d rhizome advertisements to packet using %d bytes", bundles_advertised, bytes_used);
|
||||
ob_patch_rfs(e, COMPUTE_RFS_LENGTH);
|
||||
|
||||
RETURN(0);
|
||||
@ -320,8 +271,7 @@ int overlay_rhizome_saw_advertisements(int i,overlay_frame *f, long long now)
|
||||
{
|
||||
IN();
|
||||
if (!f) { RETURN(-1); }
|
||||
int ofs=0;
|
||||
int ad_frame_type=f->payload->bytes[ofs++];
|
||||
int ad_frame_type=ob_get(f->payload);
|
||||
struct sockaddr_in httpaddr = *(struct sockaddr_in *)f->recvaddr;
|
||||
httpaddr.sin_port = htons(RHIZOME_HTTP_PORT);
|
||||
int manifest_length;
|
||||
@ -331,26 +281,26 @@ int overlay_rhizome_saw_advertisements(int i,overlay_frame *f, long long now)
|
||||
switch (ad_frame_type) {
|
||||
case 3:
|
||||
/* The same as type=1, but includes the source HTTP port number */
|
||||
httpaddr.sin_port = htons((f->payload->bytes[ofs] << 8) + f->payload->bytes[ofs + 1]);
|
||||
ofs += 2;
|
||||
httpaddr.sin_port = htons(ob_get_ui16(f->payload));
|
||||
// FALL THROUGH ...
|
||||
case 1:
|
||||
/* Extract whole manifests */
|
||||
while(ofs<f->payload->length) {
|
||||
manifest_length=(f->payload->bytes[ofs]<<8)+f->payload->bytes[ofs+1];
|
||||
if (manifest_length>=0xff00) {
|
||||
ofs++;
|
||||
while(f->payload->position < f->payload->sizeLimit) {
|
||||
if (ob_getbyte(f->payload, f->payload->position)==0xff){
|
||||
f->payload->position++;
|
||||
break;
|
||||
}
|
||||
if (manifest_length>f->payload->length - ofs) {
|
||||
assert(inet_ntop(AF_INET, &httpaddr.sin_addr, httpaddrtxt, sizeof(httpaddrtxt)) != NULL);
|
||||
WHYF("Illegal manifest length field in rhizome advertisement frame from %s:%d (%d vs %d)",
|
||||
httpaddrtxt, ntohs(httpaddr.sin_port), manifest_length, f->payload->length - ofs);
|
||||
break;
|
||||
}
|
||||
|
||||
ofs+=2;
|
||||
|
||||
manifest_length=ob_get_ui16(f->payload);
|
||||
if (manifest_length==0) continue;
|
||||
|
||||
unsigned char *data = ob_get_bytes_ptr(f->payload, manifest_length);
|
||||
if (!data) {
|
||||
assert(inet_ntop(AF_INET, &httpaddr.sin_addr, httpaddrtxt, sizeof(httpaddrtxt)) != NULL);
|
||||
WHYF("Illegal manifest length field in rhizome advertisement frame %d vs %d.",
|
||||
manifest_length, f->payload->sizeLimit - f->payload->position);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read manifest without verifying signatures (which would waste lots of
|
||||
energy, everytime we see a manifest that we already have).
|
||||
@ -364,12 +314,13 @@ int overlay_rhizome_saw_advertisements(int i,overlay_frame *f, long long now)
|
||||
WHY("Out of manifests");
|
||||
RETURN(0);
|
||||
}
|
||||
if (rhizome_read_manifest_file(m, (char *)&f->payload->bytes[ofs],
|
||||
manifest_length) == -1) {
|
||||
|
||||
if (rhizome_read_manifest_file(m, (char *)data, manifest_length) == -1) {
|
||||
WHY("Error importing manifest body");
|
||||
rhizome_manifest_free(m);
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
char manifest_id_prefix[RHIZOME_MANIFEST_ID_STRLEN + 1];
|
||||
if (rhizome_manifest_get(m, "id", manifest_id_prefix, sizeof manifest_id_prefix) == NULL) {
|
||||
WHY("Manifest does not contain 'id' field");
|
||||
@ -395,7 +346,7 @@ int overlay_rhizome_saw_advertisements(int i,overlay_frame *f, long long now)
|
||||
rhizome_manifest_free(m);
|
||||
RETURN(0);
|
||||
}
|
||||
int importManifest=0;
|
||||
|
||||
if (rhizome_ignore_manifest_check(m, &httpaddr))
|
||||
{
|
||||
/* Ignoring manifest that has caused us problems recently */
|
||||
@ -407,10 +358,12 @@ int overlay_rhizome_saw_advertisements(int i,overlay_frame *f, long long now)
|
||||
if (rhizome_manifest_version_cache_lookup(m)) {
|
||||
/* We already have this version or newer */
|
||||
if (debug & DEBUG_RHIZOME_RX) DEBUG("We already have that manifest or newer.");
|
||||
importManifest=0;
|
||||
} else {
|
||||
if (debug & DEBUG_RHIZOME_RX) DEBUG("Not seen before.");
|
||||
importManifest=1;
|
||||
|
||||
rhizome_suggest_queue_manifest_import(m, &httpaddr);
|
||||
// the above function will free the manifest structure, make sure we don't free it again
|
||||
m=NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -420,42 +373,10 @@ int overlay_rhizome_saw_advertisements(int i,overlay_frame *f, long long now)
|
||||
a minute. */
|
||||
rhizome_queue_ignore_manifest(m, &httpaddr, 60000);
|
||||
}
|
||||
if (m) rhizome_manifest_free(m);
|
||||
|
||||
if (m)
|
||||
rhizome_manifest_free(m);
|
||||
m=NULL;
|
||||
if (importManifest) {
|
||||
/* Okay, so the manifest looks like it is potentially interesting to us,
|
||||
i.e., we don't already have it or a later version of it.
|
||||
Now reread the manifest, this time verifying signatures */
|
||||
if ((m = rhizome_new_manifest()) == NULL)
|
||||
WHY("Out of manifests");
|
||||
else if (rhizome_read_manifest_file(m, (char *)&f->payload->bytes[ofs], manifest_length) == -1) {
|
||||
WHY("Error importing manifest body");
|
||||
rhizome_manifest_free(m);
|
||||
m = NULL;
|
||||
/* PGS @20120626 - Used to verify manifest here, which is before
|
||||
checking if we already have the bundle or newer. Trouble is
|
||||
that signature verification is VERY expensive (~400ms on the ideos
|
||||
phones), so we now defer it to inside
|
||||
rhizome_suggest_queue_manifest_import(), where it only gets called
|
||||
after checking that it is worth adding to the queue. */
|
||||
} else if (m->errors) {
|
||||
if (debug&DEBUG_RHIZOME) DEBUGF("Verifying manifest %s* revealed errors -- not storing.", manifest_id_prefix);
|
||||
rhizome_queue_ignore_manifest(m, &httpaddr, 60000);
|
||||
rhizome_manifest_free(m);
|
||||
m = NULL;
|
||||
} else {
|
||||
if (debug&DEBUG_RHIZOME) DEBUGF("Verifying manifest %s* revealed no errors -- will try to store.", manifest_id_prefix);
|
||||
/* Add manifest to import queue. We need to know originating IPv4 address
|
||||
so that we can transfer by HTTP. */
|
||||
if (0) DEBUG("Suggesting fetching of a bundle");
|
||||
rhizome_suggest_queue_manifest_import(m, &httpaddr);
|
||||
}
|
||||
}
|
||||
if (!manifest_length) {
|
||||
WHY("Infinite loop in packet decoding");
|
||||
break;
|
||||
}
|
||||
ofs+=manifest_length;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
45
serval.h
45
serval.h
@ -454,22 +454,6 @@ typedef struct overlay_peer {
|
||||
|
||||
extern overlay_peer overlay_peers[OVERLAY_MAX_PEERS];
|
||||
|
||||
typedef struct overlay_buffer {
|
||||
unsigned char *bytes;
|
||||
// position of data read / written
|
||||
int length;
|
||||
// allocated size of buffer
|
||||
int allocSize;
|
||||
// remembered position for rewinding
|
||||
int checkpointLength;
|
||||
// maximum allowed bytes for reading / writing
|
||||
int sizeLimit;
|
||||
int var_length_offset;
|
||||
int var_length_bytes;
|
||||
} overlay_buffer;
|
||||
|
||||
int ob_unlimitsize(overlay_buffer *b);
|
||||
|
||||
|
||||
typedef struct overlay_txqueue {
|
||||
struct overlay_frame *first;
|
||||
@ -627,27 +611,6 @@ int overlay_frame_resolve_addresses(overlay_frame *f);
|
||||
#define alloca_tohex_sid(sid) alloca_tohex((sid), SID_SIZE)
|
||||
#define alloca_tohex_sas(sas) alloca_tohex((sas), SAS_SIZE)
|
||||
|
||||
overlay_buffer *ob_new(int size);
|
||||
overlay_buffer *ob_static(unsigned char *bytes, int size);
|
||||
int ob_free(overlay_buffer *b);
|
||||
int ob_checkpoint(overlay_buffer *b);
|
||||
int ob_rewind(overlay_buffer *b);
|
||||
int ob_setlength(overlay_buffer *b,int bytes);
|
||||
int ob_limitsize(overlay_buffer *b,int bytes);
|
||||
int ob_unlimitsize(overlay_buffer *b);
|
||||
int ob_makespace(overlay_buffer *b,int bytes);
|
||||
int ob_append_byte(overlay_buffer *b,unsigned char byte);
|
||||
int ob_append_bytes(overlay_buffer *b,unsigned char *bytes,int count);
|
||||
unsigned char *ob_append_space(overlay_buffer *b,int count);
|
||||
int ob_append_short(overlay_buffer *b,unsigned short v);
|
||||
int ob_append_int(overlay_buffer *b,unsigned int v);
|
||||
int ob_patch_rfs(overlay_buffer *b,int l);
|
||||
int ob_append_rfs(overlay_buffer *b,int l);
|
||||
int ob_setbyte(overlay_buffer *b,int ofs,unsigned char value);
|
||||
int ob_getbyte(overlay_buffer *b,int ofs);
|
||||
int ob_dump(overlay_buffer *b,char *desc);
|
||||
unsigned int ob_get_int(overlay_buffer *b,int offset);
|
||||
|
||||
int op_free(overlay_frame *p);
|
||||
overlay_frame *op_dup(overlay_frame *f);
|
||||
|
||||
@ -657,11 +620,11 @@ int overlay_rx_messages();
|
||||
#define DEBUG_packet_visualise(M,P,N) logServalPacket(LOG_LEVEL_DEBUG, __HERE__, (M), (P), (N))
|
||||
|
||||
int overlay_add_selfannouncement();
|
||||
int overlay_frame_package_fmt1(overlay_frame *p,overlay_buffer *b);
|
||||
int overlay_frame_package_fmt1(overlay_frame *p, struct overlay_buffer *b);
|
||||
int overlay_interface_args(const char *arg);
|
||||
int overlay_get_nexthop(unsigned char *d,unsigned char *nexthop,int *interface);
|
||||
int overlay_sendto(struct sockaddr_in *recipientaddr,unsigned char *bytes,int len);
|
||||
int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e);
|
||||
int overlay_rhizome_add_advertisements(int interface_number,struct overlay_buffer *e);
|
||||
int overlay_add_local_identity(unsigned char *s);
|
||||
int overlay_address_is_local(unsigned char *s);
|
||||
void overlay_update_queue_schedule(overlay_txqueue *queue, overlay_frame *frame);
|
||||
@ -674,7 +637,7 @@ extern int overlay_local_identity_count;
|
||||
extern unsigned char *overlay_local_identities[OVERLAY_MAX_LOCAL_IDENTITIES];
|
||||
|
||||
int overlay_abbreviate_address(unsigned char *in,unsigned char *out,int *ofs);
|
||||
int overlay_abbreviate_append_address(overlay_buffer *b,unsigned char *a);
|
||||
int overlay_abbreviate_append_address(struct overlay_buffer *b,unsigned char *a);
|
||||
|
||||
int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char *out,int *ofs);
|
||||
int overlay_abbreviate_cache_address(unsigned char *sid);
|
||||
@ -731,7 +694,7 @@ 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_add_advertisements(overlay_buffer *e);
|
||||
int overlay_route_add_advertisements(struct overlay_buffer *e);
|
||||
int ovleray_route_please_advertise(overlay_node *n);
|
||||
int overlay_abbreviate_set_current_sender(unsigned char *in);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user