Improve overlay buffer ob_xxx() primitives

All ob_append_xxx(b,...) functions return void

ob_makespace() returns 1 if successful, 0 if not

Add ob_overrun(b) predicate to check for overrun after any number of
appends
This commit is contained in:
Andrew Bettison 2013-11-25 16:43:32 +10:30
parent 9cdf053320
commit a9ccd38adc
18 changed files with 458 additions and 493 deletions

View File

@ -1101,24 +1101,25 @@ int app_trace(const struct cli_parsed *parsed, struct cli_context *context)
mdp.out.dst.port=MDP_PORT_TRACE;
mdp.packetTypeAndFlags=MDP_TX;
struct overlay_buffer *b = ob_static(mdp.out.payload, sizeof(mdp.out.payload));
ob_append_byte(b, SID_SIZE);
ob_append_bytes(b, srcsid.binary, SID_SIZE);
ob_append_byte(b, SID_SIZE);
ob_append_bytes(b, dstsid.binary, SID_SIZE);
mdp.out.payload_length = ob_position(b);
cli_printf(context, "Tracing the network path from %s to %s",
alloca_tohex_sid_t(srcsid), alloca_tohex_sid_t(dstsid));
cli_delim(context, "\n");
cli_flush(context);
int ret=overlay_mdp_send(mdp_sockfd, &mdp, MDP_AWAITREPLY, 5000);
int ret;
if (ob_overrun(b))
ret = WHY("overlay buffer overrun");
else {
mdp.out.payload_length = ob_position(b);
cli_printf(context, "Tracing the network path from %s to %s",
alloca_tohex_sid_t(srcsid), alloca_tohex_sid_t(dstsid));
cli_delim(context, "\n");
cli_flush(context);
ret = overlay_mdp_send(mdp_sockfd, &mdp, MDP_AWAITREPLY, 5000);
if (ret)
WHYF("overlay_mdp_send returned %d", ret);
}
ob_free(b);
if (ret)
WHYF("overlay_mdp_send returned %d", ret);
else{
if (ret == 0) {
int offset=0;
{
// skip the first two sid's

View File

@ -246,6 +246,7 @@ ATOM(bool_t, mavlink, 0, boolean,, "")
ATOM(bool_t, mavlink_payloads, 0, boolean,, "")
ATOM(bool_t, mavlinkfsm, 0, boolean,, "")
ATOM(bool_t, peers, 0, boolean,, "")
ATOM(bool_t, overlaybuffer, 0, boolean,, "")
ATOM(bool_t, overlayframes, 0, boolean,, "")
ATOM(bool_t, overlayabbreviations, 0, boolean,, "")
ATOM(bool_t, overlayrouting, 0, boolean,, "")

View File

@ -141,7 +141,7 @@ int decode_rs_8(data_t *data, int *eras_pos, int no_eras, int pad);
int mavlink_encode_packet(struct overlay_interface *interface)
{
int count = ob_remaining(interface->tx_packet);
int startP = !ob_position(interface->tx_packet);
int startP = (ob_position(interface->tx_packet) == 0);
int endP = 1;
if (count+6+32 > 255){
count = 255-6-32;

View File

@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
since for things like number resolution we are happy to send repeat requests.
*/
#include <assert.h>
#include "serval.h"
#include "conf.h"
#include "str.h"
@ -234,35 +235,28 @@ int overlay_broadcast_drop_check(struct broadcast *addr)
}
}
int overlay_broadcast_append(struct overlay_buffer *b, struct broadcast *broadcast)
void overlay_broadcast_append(struct overlay_buffer *b, struct broadcast *broadcast)
{
return ob_append_bytes(b, broadcast->id, BROADCAST_LEN);
ob_append_bytes(b, broadcast->id, BROADCAST_LEN);
}
// append an appropriate abbreviation into the address
int overlay_address_append(struct decode_context *context, struct overlay_buffer *b, struct subscriber *subscriber)
void overlay_address_append(struct decode_context *context, struct overlay_buffer *b, struct subscriber *subscriber)
{
if (!subscriber)
return WHY("No address supplied");
if(context
&& subscriber == context->point_to_point_device){
if (ob_append_byte(b, OA_CODE_P2P_YOU))
return -1;
}else if(context
assert(subscriber != NULL);
if (context && subscriber == context->point_to_point_device)
ob_append_byte(b, OA_CODE_P2P_YOU);
else if(context
&& !subscriber->send_full
&& subscriber == my_subscriber
&& context->point_to_point_device
&& (context->encoding_header==0 || !context->interface->local_echo)){
if (ob_append_byte(b, OA_CODE_P2P_ME))
return -1;
}else if (context && subscriber==context->sender){
if (ob_append_byte(b, OA_CODE_SELF))
return -1;
}else if(context && subscriber==context->previous){
if (ob_append_byte(b, OA_CODE_PREVIOUS))
return -1;
}else{
&& (context->encoding_header==0 || !context->interface->local_echo))
ob_append_byte(b, OA_CODE_P2P_ME);
else if (context && subscriber==context->sender)
ob_append_byte(b, OA_CODE_SELF);
else if (context && subscriber==context->previous)
ob_append_byte(b, OA_CODE_PREVIOUS);
else {
int len=SID_SIZE;
if (subscriber->send_full){
subscriber->send_full=0;
@ -273,17 +267,15 @@ int overlay_address_append(struct decode_context *context, struct overlay_buffer
if (len>SID_SIZE)
len=SID_SIZE;
}
if (ob_append_byte(b, len))
return -1;
if (ob_append_bytes(b, subscriber->sid.binary, len))
return -1;
ob_append_byte(b, len);
ob_append_bytes(b, subscriber->sid.binary, len);
}
if (context)
context->previous = subscriber;
return 0;
}
static int add_explain_response(struct subscriber *subscriber, void *context){
static int add_explain_response(struct subscriber *subscriber, void *context)
{
struct decode_context *response = context;
// only explain a SID once every half second.
time_ms_t now = gettime_ms();
@ -292,8 +284,13 @@ static int add_explain_response(struct subscriber *subscriber, void *context){
subscriber->last_explained = now;
if (!response->please_explain){
response->please_explain = calloc(sizeof(struct overlay_frame),1);
response->please_explain->payload=ob_new();
if ((response->please_explain = emalloc_zero(sizeof(struct overlay_frame))) == NULL)
return 1; // stop walking
if ((response->please_explain->payload = ob_new()) == NULL) {
free(response->please_explain);
response->please_explain = NULL;
return 1; // stop walking
}
ob_limitsize(response->please_explain->payload, 1024);
}
@ -309,11 +306,10 @@ static int add_explain_response(struct subscriber *subscriber, void *context){
// add the whole subscriber id to the payload, stop if we run out of space
DEBUGF("Adding full sid by way of explanation %s", alloca_tohex_sid_t(subscriber->sid));
if (ob_append_byte(response->please_explain->payload, SID_SIZE))
ob_append_byte(response->please_explain->payload, SID_SIZE);
ob_append_bytes(response->please_explain->payload, subscriber->sid.binary, SID_SIZE);
if (ob_overrun(response->please_explain->payload))
return 1;
if (ob_append_bytes(response->please_explain->payload, subscriber->sid.binary, SID_SIZE))
return 1;
// let the routing engine know that we had to explain this sid, we probably need to re-send routing info
link_explained(subscriber);
return 0;
@ -345,7 +341,8 @@ static int find_subscr_buffer(struct decode_context *context, struct overlay_buf
// add the abbreviation you told me about
if (!context->please_explain){
context->please_explain = calloc(sizeof(struct overlay_frame),1);
context->please_explain->payload=ob_new();
if ((context->please_explain->payload = ob_new()) == NULL)
return -1;
ob_limitsize(context->please_explain->payload, MDP_MTU);
}
@ -396,7 +393,8 @@ int overlay_address_parse(struct decode_context *context, struct overlay_buffer
// add the abbreviation you told me about
if (!context->please_explain){
context->please_explain = calloc(sizeof(struct overlay_frame),1);
context->please_explain->payload=ob_new();
if ((context->please_explain->payload = ob_new()) == NULL)
return -1;
ob_limitsize(context->please_explain->payload, MDP_MTU);
}
@ -433,8 +431,9 @@ int overlay_address_parse(struct decode_context *context, struct overlay_buffer
int send_please_explain(struct decode_context *context, struct subscriber *source, struct subscriber *destination){
IN();
struct overlay_frame *frame=context->please_explain;
if (!frame)
if (frame == NULL)
RETURN(0);
assert(frame->payload != NULL);
frame->type = OF_TYPE_PLEASEEXPLAIN;
if (source)
@ -466,7 +465,7 @@ int send_please_explain(struct decode_context *context, struct subscriber *sourc
}
frame->queue=OQ_MESH_MANAGEMENT;
if (!overlay_payload_enqueue(frame))
if (overlay_payload_enqueue(frame) != -1)
RETURN(0);
op_free(frame);
RETURN(-1);

View File

@ -119,8 +119,8 @@ int process_explain(struct overlay_frame *frame);
int overlay_broadcast_drop_check(struct broadcast *addr);
int overlay_broadcast_generate_address(struct broadcast *addr);
int overlay_broadcast_append(struct overlay_buffer *b, struct broadcast *broadcast);
int overlay_address_append(struct decode_context *context, struct overlay_buffer *b, struct subscriber *subscriber);
void overlay_broadcast_append(struct overlay_buffer *b, struct broadcast *broadcast);
void overlay_address_append(struct decode_context *context, struct overlay_buffer *b, struct subscriber *subscriber);
int overlay_broadcast_parse(struct overlay_buffer *b, struct broadcast *broadcast);
int overlay_address_parse(struct decode_context *context, struct overlay_buffer *b, struct subscriber **subscriber);

View File

@ -17,6 +17,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <assert.h>
#include "serval.h"
#include "conf.h"
#include "mem.h"
@ -30,57 +31,56 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
In either case, functions that don't take an offset use and advance the position.
*/
struct overlay_buffer *ob_new(void)
{
struct overlay_buffer *ret=calloc(sizeof(struct overlay_buffer),1);
if (!ret) return NULL;
struct overlay_buffer *ret = emalloc_zero(sizeof(struct overlay_buffer));
if (ret == NULL)
return NULL;
ob_unlimitsize(ret);
return ret;
}
// index an existing static buffer.
// and allow other callers to use the ob_ convenience methods for reading and writing up to size bytes.
struct overlay_buffer *ob_static(unsigned char *bytes, int size){
struct overlay_buffer *ret=calloc(sizeof(struct overlay_buffer),1);
if (!ret) return NULL;
struct overlay_buffer *ob_static(unsigned char *bytes, int size)
{
struct overlay_buffer *ret = emalloc_zero(sizeof(struct overlay_buffer));
if (ret == NULL)
return NULL;
ret->bytes = bytes;
ret->allocSize = size;
ret->allocated = NULL;
ob_unlimitsize(ret);
return ret;
}
// 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 *ob_slice(struct overlay_buffer *b, int offset, int length)
{
if (offset+length > b->allocSize) {
WHY("Buffer isn't long enough to slice");
return NULL;
return NULL;
}
struct overlay_buffer *ret=calloc(sizeof(struct overlay_buffer),1);
if (!ret)
struct overlay_buffer *ret = emalloc_zero(sizeof(struct overlay_buffer));
if (ret == NULL)
return NULL;
ret->bytes = b->bytes+offset;
ret->allocSize = length;
ret->allocated = NULL;
ob_unlimitsize(ret);
return ret;
}
struct overlay_buffer *ob_dup(struct overlay_buffer *b){
struct overlay_buffer *ret=calloc(sizeof(struct overlay_buffer),1);
struct overlay_buffer *ob_dup(struct overlay_buffer *b)
{
struct overlay_buffer *ret = emalloc_zero(sizeof(struct overlay_buffer));
if (ret == NULL)
return NULL;
ret->sizeLimit = b->sizeLimit;
ret->position = b->position;
ret->checkpointLength = b->checkpointLength;
if (b->bytes && b->allocSize){
// duplicate any bytes that might be relevant
int byteCount = b->sizeLimit;
@ -88,97 +88,88 @@ struct overlay_buffer *ob_dup(struct overlay_buffer *b){
byteCount = b->position;
if (byteCount > b->allocSize)
byteCount = b->allocSize;
ob_append_bytes(ret, b->bytes, byteCount);
if (byteCount)
ob_append_bytes(ret, b->bytes, byteCount);
}
return ret;
}
int ob_free(struct overlay_buffer *b)
void ob_free(struct overlay_buffer *b)
{
if (!b) return WHY("Asked to free NULL");
if (b->bytes && b->allocated) free(b->allocated);
// we're about to free this anyway, why are we clearing it?
b->bytes=NULL;
b->allocated=NULL;
b->allocSize=0;
b->sizeLimit=0;
assert(b != NULL);
if (b->allocated)
free(b->allocated);
free(b);
return 0;
}
int ob_checkpoint(struct overlay_buffer *b)
{
if (!b) return WHY("Asked to checkpoint NULL");
b->checkpointLength=b->position;
assert(b != NULL);
b->checkpointLength = b->position;
return 0;
}
int ob_rewind(struct overlay_buffer *b)
{
if (!b) return WHY("Asked to rewind NULL");
b->position=b->checkpointLength;
assert(b != NULL);
b->position = b->checkpointLength;
return 0;
}
int ob_limitsize(struct overlay_buffer *b,int bytes)
void ob_limitsize(struct overlay_buffer *b, int bytes)
{
if (!b) return WHY("Asked to limit size of NULL");
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");
assert(b != NULL);
assert(bytes >= 0);
assert(b->position >= 0);
assert(b->position <= bytes);
assert(b->checkpointLength <= bytes);
if (b->bytes && b->allocated == NULL)
assert(bytes <= b->allocSize);
b->sizeLimit=bytes;
return 0;
}
int ob_unlimitsize(struct overlay_buffer *b)
void ob_unlimitsize(struct overlay_buffer *b)
{
if (!b) return WHY("b is NULL");
b->sizeLimit=-1;
return 0;
assert(b != NULL);
b->sizeLimit = -1;
}
int ob_flip(struct overlay_buffer *b)
void ob_flip(struct overlay_buffer *b)
{
b->checkpointLength=0;
if (ob_limitsize(b, b->position))
return -1;
b->position=0;
return 0;
b->checkpointLength = 0;
ob_limitsize(b, b->position);
b->position = 0;
}
int _ob_makespace(struct __sourceloc __whence, struct overlay_buffer *b,int bytes)
/* Return 1 if space is available, 0 if not.
*/
ssize_t ob_makespace(struct overlay_buffer *b, size_t bytes)
{
if (b->sizeLimit != -1 && b->position + bytes > b->sizeLimit) {
if (config.debug.packetformats)
DEBUGF("asked for space to %u, beyond size limit of %u", b->position + bytes, b->sizeLimit);
return -1;
}
// already enough space?
if (b->position + bytes <= b->allocSize)
assert(b != NULL);
assert(b->position >= 0);
if (b->sizeLimit != -1)
assert(b->sizeLimit >= 0);
assert(b->allocSize >= 0);
if (b->position)
assert(b->bytes != NULL);
if (b->sizeLimit != -1 && b->position + bytes > b->sizeLimit)
return 0;
if (b->position + bytes <= b->allocSize)
return 1;
// Don't realloc a static buffer.
if (b->bytes && b->allocated == NULL)
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->position=%d,b->allocSize=%d\n",
b,bytes,b->bytes,b->position,b->allocSize);
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);
if (newSize>1024 && (newSize&1023))
newSize+=1024-(newSize&1023);
if (newSize>65536 && (newSize&65535))
newSize+=65536-(newSize&65535);
if (config.debug.overlaybuffer)
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 bugs out that way. */
So will do a three-stage malloc,bcopy,free to see if we can tease bugs out that way. */
/*
unsigned char *r=realloc(b->bytes,newSize);
if (!r) return WHY("realloc() failed");
@ -196,94 +187,99 @@ int _ob_makespace(struct __sourceloc __whence, struct overlay_buffer *b,int byte
sleep_ms(36000000);
}
}
unsigned char *new=malloc(newSize+4096);
if (!new) return WHY("realloc() failed");
unsigned char *new = emalloc(newSize+4096);
{
int i;
for(i=0;i<4096;i++) new[newSize+i]=0xbd;
}
#else
unsigned char *new=malloc(newSize);
unsigned char *new = emalloc(newSize);
#endif
if (!new)
return 0;
bcopy(b->bytes,new,b->position);
if (b->allocated) free(b->allocated);
if (b->allocated) {
assert(b->allocated == b->bytes);
free(b->allocated);
}
b->bytes=new;
b->allocated=new;
b->allocSize=newSize;
return 0;
return 1;
}
/*
Functions that append data and increase the size of the buffer if possible / required
*/
int _ob_append_byte(struct __sourceloc __whence, struct overlay_buffer *b,unsigned char byte)
void ob_append_byte(struct overlay_buffer *b,unsigned char byte)
{
if (_ob_makespace(__whence, b,1)) return WHY("ob_makespace() failed");
b->bytes[b->position++] = byte;
return 0;
const int bytes = 1;
if (ob_makespace(b, bytes))
b->bytes[b->position] = byte;
b->position += bytes;
}
unsigned char *_ob_append_space(struct __sourceloc __whence, struct overlay_buffer *b,int count)
unsigned char *ob_append_space(struct overlay_buffer *b, int count)
{
if (_ob_makespace(__whence, b,count)) {
WHY("ob_makespace() failed");
return NULL;
}
unsigned char *r=&b->bytes[b->position];
b->position+=count;
assert(count > 0);
unsigned char *r = ob_makespace(b, count) ? &b->bytes[b->position] : NULL;
b->position += count;
return r;
}
int _ob_append_bytes(struct __sourceloc __whence, struct overlay_buffer *b, const unsigned char *bytes, int count)
void ob_append_bytes(struct overlay_buffer *b, const unsigned char *bytes, int count)
{
if (_ob_makespace(__whence, b,count)) return WHY("ob_makespace() failed");
bcopy(bytes,&b->bytes[b->position],count);
b->position+=count;
return 0;
assert(count > 0);
unsigned char *r = ob_makespace(b, count) ? &b->bytes[b->position] : NULL;
if (r)
bcopy(bytes, r, count);
b->position += count;
if (r)
bcopy(bytes, r, count);
}
int _ob_append_buffer(struct __sourceloc __whence, struct overlay_buffer *b, struct overlay_buffer *s){
return _ob_append_bytes(__whence, b, s->bytes, s->position);
void append_buffer(struct overlay_buffer *b, struct overlay_buffer *s)
{
ob_append_bytes(b, s->bytes, s->position);
}
int _ob_append_ui16(struct __sourceloc __whence, struct overlay_buffer *b, uint16_t v)
void ob_append_ui16(struct overlay_buffer *b, uint16_t v)
{
if (_ob_makespace(__whence, 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;
const int bytes = 2;
if (ob_makespace(b, bytes)) {
b->bytes[b->position] = (v >> 8) & 0xFF;
b->bytes[b->position+1] = v & 0xFF;
}
b->position += bytes;
}
int _ob_append_ui32(struct __sourceloc __whence, struct overlay_buffer *b, uint32_t v)
void ob_append_ui32(struct overlay_buffer *b, uint32_t v)
{
if (_ob_makespace(__whence, 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;
const int bytes = 4;
if (ob_makespace(b, bytes)) {
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 += bytes;
}
int _ob_append_ui64(struct __sourceloc __whence, struct overlay_buffer *b, uint64_t v)
void ob_append_ui64(struct overlay_buffer *b, uint64_t v)
{
if (_ob_makespace(__whence, b, 8)) return WHY("ob_makespace() failed");
b->bytes[b->position] = (v >> 56) & 0xFF;
b->bytes[b->position+1] = (v >> 48) & 0xFF;
b->bytes[b->position+2] = (v >> 40) & 0xFF;
b->bytes[b->position+3] = (v >> 32) & 0xFF;
b->bytes[b->position+4] = (v >> 24) & 0xFF;
b->bytes[b->position+5] = (v >> 16) & 0xFF;
b->bytes[b->position+6] = (v >> 8) & 0xFF;
b->bytes[b->position+7] = v & 0xFF;
b->position+=8;
return 0;
const int bytes = 8;
if (ob_makespace(b, bytes)) {
b->bytes[b->position] = (v >> 56) & 0xFF;
b->bytes[b->position+1] = (v >> 48) & 0xFF;
b->bytes[b->position+2] = (v >> 40) & 0xFF;
b->bytes[b->position+3] = (v >> 32) & 0xFF;
b->bytes[b->position+4] = (v >> 24) & 0xFF;
b->bytes[b->position+5] = (v >> 16) & 0xFF;
b->bytes[b->position+6] = (v >> 8) & 0xFF;
b->bytes[b->position+7] = v & 0xFF;
}
b->position += bytes;
}
int measure_packed_uint(uint64_t v){
@ -320,36 +316,28 @@ int unpack_uint(unsigned char *buffer, int buff_size, uint64_t *v){
return i;
}
int _ob_append_packed_ui32(struct __sourceloc __whence, struct overlay_buffer *b, uint32_t v)
void ob_append_packed_ui32(struct overlay_buffer *b, uint32_t v)
{
do{
if (_ob_append_byte(__whence, b, (v&0x7f) | (v>0x7f?0x80:0)))
return -1;
v = v>>7;
}while(v!=0);
return 0;
do {
ob_append_byte(b, (v&0x7f) | (v>0x7f?0x80:0));
v = v >> 7;
} while (v != 0);
}
int _ob_append_packed_ui64(struct __sourceloc __whence, struct overlay_buffer *b, uint64_t v)
void ob_append_packed_ui64(struct overlay_buffer *b, uint64_t v)
{
do{
if (ob_append_byte(b, (v&0x7f) | (v>0x7f?0x80:0)))
return -1;
v = v>>7;
}while(v!=0);
return 0;
do {
ob_append_byte(b, (v&0x7f) | (v>0x7f?0x80:0));
v = v >> 7;
} while (v != 0);
}
int _ob_append_rfs(struct __sourceloc __whence, struct overlay_buffer *b, int l)
void ob_append_rfs(struct overlay_buffer *b, int l)
{
if (l<0||l>0xffff) return -1;
b->var_length_offset=b->position;
return _ob_append_ui16(__whence, b,l);
assert(l >= 0);
assert(l <= 0xffff);
b->var_length_offset = b->position;
ob_append_ui16(b, l);
}
@ -359,7 +347,8 @@ int _ob_append_rfs(struct __sourceloc __whence, struct overlay_buffer *b, int l)
// make sure a range of bytes is valid for reading
int test_offset(struct overlay_buffer *b,int start,int length){
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;
@ -471,39 +460,59 @@ int ob_get(struct overlay_buffer *b){
return b->bytes[b->position++];
}
int ob_set_ui16(struct overlay_buffer *b, int offset, uint16_t v)
void ob_set_ui16(struct overlay_buffer *b, int offset, uint16_t v)
{
if (test_offset(b, offset, 2))
return -1;
assert(b != NULL);
assert(offset >= 0);
if (b->sizeLimit != -1)
assert(offset + 2 <= b->sizeLimit);
assert(offset + 2 <= b->allocSize);
b->bytes[offset] = (v >> 8) & 0xFF;
b->bytes[offset+1] = v & 0xFF;
return 0;
}
int ob_set(struct overlay_buffer *b, int ofs, unsigned char byte)
void ob_set(struct overlay_buffer *b, int offset, unsigned char byte)
{
if (test_offset(b, ofs, 1))
return -1;
b->bytes[ofs] = byte;
return 0;
assert(b != NULL);
assert(offset >= 0);
if (b->sizeLimit != -1)
assert(offset + 1 <= b->sizeLimit);
assert(offset + 1 <= b->allocSize);
b->bytes[offset] = byte;
}
int ob_patch_rfs(struct overlay_buffer *b){
return ob_set_ui16(b,b->var_length_offset,b->position - (b->var_length_offset + 2));
void ob_patch_rfs(struct overlay_buffer *b)
{
ob_set_ui16(b,b->var_length_offset,b->position - (b->var_length_offset + 2));
}
int ob_position(struct overlay_buffer *b){
int ob_position(struct overlay_buffer *b)
{
return b->position;
}
int ob_limit(struct overlay_buffer *b){
int ob_limit(struct overlay_buffer *b)
{
return b->sizeLimit;
}
int ob_remaining(struct overlay_buffer *b){
int ob_remaining(struct overlay_buffer *b)
{
assert(b->sizeLimit != -1);
return b->sizeLimit - b->position;
}
unsigned char *ob_ptr(struct overlay_buffer *b){
int ob_overrun(struct overlay_buffer *b)
{
assert(b->allocSize >= 0);
if (b->sizeLimit != -1)
assert(b->sizeLimit >= 0);
return b->position > (b->sizeLimit != -1 && b->sizeLimit < b->allocSize ? b->sizeLimit : b->allocSize);
}
unsigned char *ob_ptr(struct overlay_buffer *b)
{
return b->bytes;
}

View File

@ -17,8 +17,8 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _SERVALD_OVERLAY_BUFFER_H
#define _SERVALD_OVERLAY_BUFFER_H
#ifndef __SERVALD__OVERLAY_BUFFER_H
#define __SERVALD__OVERLAY_BUFFER_H
struct overlay_buffer {
unsigned char *bytes;
@ -46,39 +46,28 @@ 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);
void 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_flip(struct overlay_buffer *b);
int ob_unlimitsize(struct overlay_buffer *b);
int _ob_makespace(struct __sourceloc whence, struct overlay_buffer *b,int bytes);
int ob_set(struct overlay_buffer *b, int ofs, unsigned char byte);
void ob_limitsize(struct overlay_buffer *b,int bytes);
void ob_flip(struct overlay_buffer *b);
void ob_unlimitsize(struct overlay_buffer *b);
ssize_t ob_makespace(struct overlay_buffer *b, size_t bytes);
void ob_set(struct overlay_buffer *b, int ofs, unsigned char byte);
void ob_set_ui16(struct overlay_buffer *b, int offset, uint16_t v);
void ob_patch_rfs(struct overlay_buffer *b);
int _ob_append_byte(struct __sourceloc whence, struct overlay_buffer *b,unsigned char byte);
int _ob_append_bytes(struct __sourceloc whence, struct overlay_buffer *b,const unsigned char *bytes,int count);
int _ob_append_buffer(struct __sourceloc whence, struct overlay_buffer *b,struct overlay_buffer *s);
unsigned char *_ob_append_space(struct __sourceloc whence, struct overlay_buffer *b,int count);
int _ob_append_ui16(struct __sourceloc whence, struct overlay_buffer *b, uint16_t v);
int _ob_append_ui32(struct __sourceloc whence, struct overlay_buffer *b, uint32_t v);
int _ob_append_ui64(struct __sourceloc whence, struct overlay_buffer *b, uint64_t v);
int _ob_append_packed_ui32(struct __sourceloc whence, struct overlay_buffer *b, uint32_t v);
int _ob_append_packed_ui64(struct __sourceloc whence, struct overlay_buffer *b, uint64_t v);
int _ob_append_rfs(struct __sourceloc whence, struct overlay_buffer *b,int l);
void ob_append_byte(struct overlay_buffer *b,unsigned char byte);
void ob_append_bytes(struct overlay_buffer *b,const unsigned char *bytes,int count);
void ob_append_buffer(struct overlay_buffer *b,struct overlay_buffer *s);
unsigned char *ob_append_space(struct overlay_buffer *b,int count);
void ob_append_ui16(struct overlay_buffer *b, uint16_t v);
void ob_append_ui32(struct overlay_buffer *b, uint32_t v);
void ob_append_ui64(struct overlay_buffer *b, uint64_t v);
void ob_append_packed_ui32(struct overlay_buffer *b, uint32_t v);
void ob_append_packed_ui64(struct overlay_buffer *b, uint64_t v);
void ob_append_rfs(struct overlay_buffer *b,int l);
#define ob_makespace(b, bytes) _ob_makespace(__WHENCE__, b, bytes)
#define ob_append_byte(b, byte) _ob_append_byte(__WHENCE__, b, byte)
#define ob_append_bytes(b, bytes, count) _ob_append_bytes(__WHENCE__, b, bytes, count)
#define ob_append_buffer(b, s) _ob_append_buffer(__WHENCE__, b, s)
#define ob_append_space(b, count) _ob_append_space(__WHENCE__, b, count)
#define ob_append_ui16(b, v) _ob_append_ui16(__WHENCE__, b, v)
#define ob_append_ui32(b, v) _ob_append_ui32(__WHENCE__, b, v)
#define ob_append_ui64(b, v) _ob_append_ui64(__WHENCE__, b, v)
#define ob_append_packed_ui32(b, v) _ob_append_packed_ui32(__WHENCE__, b, v)
#define ob_append_packed_ui64(b, v) _ob_append_packed_ui64(__WHENCE__, b, v)
#define ob_append_rfs(b, l) _ob_append_rfs(__WHENCE__, b, l)
int ob_patch_rfs(struct overlay_buffer *b);
// 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
@ -89,7 +78,6 @@ uint64_t ob_get_ui64(struct overlay_buffer *b);
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);
uint32_t ob_get_packed_ui32(struct overlay_buffer *b);
uint64_t ob_get_packed_ui64(struct overlay_buffer *b);
@ -98,5 +86,7 @@ uint64_t ob_get_packed_ui64(struct overlay_buffer *b);
int ob_position(struct overlay_buffer *b);
int ob_limit(struct overlay_buffer *b);
int ob_remaining(struct overlay_buffer *b);
int ob_overrun(struct overlay_buffer *b);
unsigned char* ob_ptr(struct overlay_buffer *b);
#endif
#endif //__SERVALD__OVERLAY_BUFFER_H

View File

@ -1,3 +1,4 @@
#include <assert.h>
#include "serval.h"
#include "conf.h"
#include "str.h"
@ -222,14 +223,14 @@ int overlay_send_probe(struct subscriber *peer, struct network_destination *dest
frame->ttl=1;
frame->queue=queue;
frame->destinations[frame->destination_count++].destination=add_destination_ref(destination);
frame->payload = ob_new();
frame->source_full = 1;
// TODO call mdp payload encryption / signing without calling overlay_mdp_dispatch...
if (overlay_mdp_encode_ports(frame->payload, MDP_PORT_ECHO, MDP_PORT_PROBE)){
if ((frame->payload = ob_new()) == NULL) {
op_free(frame);
return -1;
}
frame->source_full = 1;
// TODO call mdp payload encryption / signing without calling overlay_mdp_dispatch...
overlay_mdp_encode_ports(frame->payload, MDP_PORT_ECHO, MDP_PORT_PROBE);
// not worried about byte order here as we are the only node that should be parsing the contents.
unsigned char *dst=ob_append_space(frame->payload, sizeof(struct probe_contents));
if (!dst){
@ -254,25 +255,21 @@ int overlay_send_probe(struct subscriber *peer, struct network_destination *dest
}
// append the address of a unicast link into a packet buffer
static int overlay_append_unicast_address(struct subscriber *subscriber, struct overlay_buffer *buff)
static void overlay_append_unicast_address(struct subscriber *subscriber, struct overlay_buffer *buff)
{
if (subscriber->destination
&& subscriber->destination->unicast
&& subscriber->destination->address.sin_family==AF_INET){
if (overlay_address_append(NULL, buff, subscriber))
return -1;
if (ob_append_ui32(buff, subscriber->destination->address.sin_addr.s_addr))
return -1;
if (ob_append_ui16(buff, subscriber->destination->address.sin_port))
return -1;
ob_checkpoint(buff);
if ( subscriber->destination
&& subscriber->destination->unicast
&& subscriber->destination->address.sin_family==AF_INET
) {
overlay_address_append(NULL, buff, subscriber);
ob_append_ui32(buff, subscriber->destination->address.sin_addr.s_addr);
ob_append_ui16(buff, subscriber->destination->address.sin_port);
if (config.debug.overlayrouting)
DEBUGF("Added STUN info for %s", alloca_tohex_sid_t(subscriber->sid));
}else{
if (config.debug.overlayrouting)
DEBUGF("Unable to give address of %s, %d", alloca_tohex_sid_t(subscriber->sid),subscriber->reachable);
}
return 0;
}
int overlay_mdp_service_stun_req(overlay_mdp_frame *mdp)
@ -296,22 +293,20 @@ int overlay_mdp_service_stun_req(overlay_mdp_frame *mdp)
struct overlay_buffer *replypayload = ob_static(reply.out.payload, sizeof(reply.out.payload));
ob_checkpoint(replypayload);
while(ob_remaining(payload)>0){
while (ob_remaining(payload) > 0) {
struct subscriber *subscriber=NULL;
if (overlay_address_parse(NULL, payload, &subscriber))
break;
if (!subscriber){
if (config.debug.overlayrouting)
DEBUGF("Unknown subscriber");
continue;
}
if (overlay_append_unicast_address(subscriber, replypayload))
overlay_append_unicast_address(subscriber, replypayload);
if (ob_overrun(payload))
break;
ob_checkpoint(replypayload);
}
ob_rewind(replypayload);
reply.out.payload_length=ob_position(replypayload);
@ -388,11 +383,12 @@ int overlay_send_stun_request(struct subscriber *server, struct subscriber *requ
struct overlay_buffer *payload = ob_static(mdp.out.payload, sizeof(mdp.out.payload));
overlay_address_append(NULL, payload, request);
mdp.out.payload_length=ob_position(payload);
if (config.debug.overlayrouting)
DEBUGF("Sending STUN request to %s", alloca_tohex_sid_t(server->sid));
overlay_mdp_dispatch(&mdp,0 /* system generated */,
NULL,0);
if (!ob_overrun(payload)) {
mdp.out.payload_length=ob_position(payload);
if (config.debug.overlayrouting)
DEBUGF("Sending STUN request to %s", alloca_tohex_sid_t(server->sid));
overlay_mdp_dispatch(&mdp, 0 /* system generated */, NULL,0);
}
ob_free(payload);
return 0;
}

View File

@ -267,9 +267,7 @@ static int overlay_mdp_decode_header(struct overlay_buffer *buff, overlay_mdp_fr
if (!same)
port = ob_get_packed_ui32(buff);
mdp->in.src.port = port;
int len=ob_remaining(buff);
int len = ob_remaining(buff);
if (len<0)
return WHY("MDP payload is too short");
mdp->in.payload_length=len;
@ -316,10 +314,8 @@ int overlay_mdp_decrypt(struct overlay_frame *f, overlay_mdp_frame *mdp)
if (!k)
RETURN(WHY("I don't have the private key required to decrypt that"));
if (0){
dump("frame",&f->payload->bytes[f->payload->position],
ob_remaining(f->payload));
}
if (0)
dump("frame",&f->payload->bytes[f->payload->position], ob_remaining(f->payload));
unsigned char *nonce=ob_get_bytes_ptr(f->payload, nb);
if (!nonce)
@ -529,18 +525,14 @@ int overlay_mdp_check_binding(struct subscriber *subscriber, mdp_port_t port, in
);
}
int overlay_mdp_encode_ports(struct overlay_buffer *plaintext, mdp_port_t dst_port, mdp_port_t src_port)
void overlay_mdp_encode_ports(struct overlay_buffer *plaintext, mdp_port_t dst_port, mdp_port_t src_port)
{
mdp_port_t port = dst_port << 1;
if (dst_port == src_port)
port |= 1;
if (ob_append_packed_ui32(plaintext, port))
return -1;
if (dst_port != src_port){
if (ob_append_packed_ui32(plaintext, src_port))
return -1;
}
return 0;
ob_append_packed_ui32(plaintext, port);
if (dst_port != src_port)
ob_append_packed_ui32(plaintext, src_port);
}
static struct overlay_buffer * encrypt_payload(
@ -564,13 +556,15 @@ static struct overlay_buffer * encrypt_payload(
cipher_len+=zb;
struct overlay_buffer *ret = ob_new();
if (ret == NULL)
return NULL;
unsigned char *nonce = ob_append_space(ret, nb+cipher_len);
unsigned char *cipher_text = nonce + nb;
if (!nonce){
ob_free(ret);
return NULL;
}
unsigned char *cipher_text = nonce + nb;
if (generate_nonce(nonce,nb)){
ob_free(ret);
@ -644,8 +638,9 @@ int overlay_send_frame(struct overlay_frame *frame, struct overlay_buffer *plain
case OF_CRYPTO_SIGNED:
// Lets just append some space into the existing payload buffer for the signature, without copying it.
frame->payload = plaintext;
ob_makespace(frame->payload,SIGNATURE_BYTES);
if (crypto_sign_message(frame->source, ob_ptr(frame->payload), frame->payload->allocSize, &frame->payload->position)){
if ( ob_makespace(frame->payload, SIGNATURE_BYTES) != SIGNATURE_BYTES
|| crypto_sign_message(frame->source, ob_ptr(frame->payload), frame->payload->allocSize, &frame->payload->position) == -1
) {
op_free(frame);
return -1;
}
@ -773,14 +768,13 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
// copy the plain text message into a new buffer, with the wire encoded port numbers
struct overlay_buffer *plaintext=ob_new();
if (!plaintext)
if (plaintext == NULL)
RETURN(-1);
if (overlay_mdp_encode_ports(plaintext, mdp->out.dst.port, mdp->out.src.port)){
ob_free(plaintext);
RETURN (-1);
}
if (ob_append_bytes(plaintext, mdp->out.payload, mdp->out.payload_length)){
overlay_mdp_encode_ports(plaintext, mdp->out.dst.port, mdp->out.src.port);
if (mdp->out.payload_length)
ob_append_bytes(plaintext, mdp->out.payload, mdp->out.payload_length);
if (ob_overrun(plaintext)) {
ob_free(plaintext);
RETURN(-1);
}

View File

@ -334,15 +334,14 @@ static int overlay_mdp_service_trace(overlay_mdp_frame *mdp){
ob_unlimitsize(b);
// always write a full sid into the payload
my_subscriber->send_full=1;
if (overlay_address_append(&context, b, my_subscriber)){
overlay_address_append(&context, b, my_subscriber);
if (ob_overrun(b)) {
ret = WHYF("Unable to append my address to the trace");
goto end;
}
mdp->out.payload_length = ob_position(b);
mdp->out.src.sid = my_subscriber->sid;
mdp->out.dst.sid = next->sid;
ret = overlay_mdp_dispatch(mdp, 0, NULL, 0);
end:
ob_free(b);

View File

@ -253,6 +253,8 @@ int olsr_send(struct overlay_frame *frame){
struct decode_context context;
bzero(&context, sizeof context);
struct overlay_buffer *b=ob_new();
if (b == NULL)
return 0;
// build olsr specific frame header
ob_append_byte(b, PACKET_FORMAT_NUMBER);
@ -260,7 +262,6 @@ int olsr_send(struct overlay_frame *frame){
// address the packet as transmitted by me
overlay_address_append(&context, b, my_subscriber);
overlay_address_append(&context, b, frame->source);
overlay_broadcast_append(b, &frame->broadcast_id);
ob_append_byte(b, frame->modifiers);

View File

@ -42,20 +42,16 @@ int overlay_packet_init_header(int packet_version, int encapsulation,
if (encapsulation !=ENCAP_OVERLAY && encapsulation !=ENCAP_SINGLE)
return WHY("Invalid packet encapsulation");
if (ob_append_byte(buff, packet_version))
return -1;
if (ob_append_byte(buff, encapsulation))
return -1;
ob_append_byte(buff, packet_version);
ob_append_byte(buff, encapsulation);
if (context->interface->point_to_point
&& context->interface->other_device
&& packet_version>=1)
if ( context->interface->point_to_point
&& context->interface->other_device
&& packet_version>=1
)
context->point_to_point_device = context->interface->other_device;
context->encoding_header=1;
if (overlay_address_append(context, buff, my_subscriber))
return -1;
overlay_address_append(context, buff, my_subscriber);
context->encoding_header=0;
context->sender = my_subscriber;

View File

@ -51,34 +51,28 @@ static int overlay_frame_build_header(int packet_version, struct decode_context
if (type!=OF_TYPE_DATA)
flags |= PAYLOAD_FLAG_LEGACY_TYPE;
if (ob_append_byte(buff, flags)) return -1;
ob_append_byte(buff, flags);
if (!(flags & PAYLOAD_FLAG_SENDER_SAME)){
if (overlay_address_append(context, buff, source)) return -1;
}
if (!(flags & PAYLOAD_FLAG_SENDER_SAME))
overlay_address_append(context, buff, source);
if (flags & PAYLOAD_FLAG_TO_BROADCAST){
if (!(flags & PAYLOAD_FLAG_ONE_HOP)){
if (overlay_broadcast_append(buff, broadcast)) return -1;
}
}else{
if (overlay_address_append(context, buff, destination)) return -1;
if (!(flags & PAYLOAD_FLAG_ONE_HOP)){
if (overlay_address_append(context, buff, next_hop)) return -1;
}
if (!(flags & PAYLOAD_FLAG_ONE_HOP))
overlay_broadcast_append(buff, broadcast);
} else {
overlay_address_append(context, buff, destination);
if (!(flags & PAYLOAD_FLAG_ONE_HOP))
overlay_address_append(context, buff, next_hop);
}
if (!(flags & PAYLOAD_FLAG_ONE_HOP)){
if (ob_append_byte(buff, ttl | ((queue&3)<<5))) return -1;
}
if (!(flags & PAYLOAD_FLAG_ONE_HOP))
ob_append_byte(buff, ttl | ((queue&3)<<5));
if (flags & PAYLOAD_FLAG_LEGACY_TYPE){
if (ob_append_byte(buff, type)) return -1;
}
if (flags & PAYLOAD_FLAG_LEGACY_TYPE)
ob_append_byte(buff, type);
if (packet_version >= 1)
if (ob_append_byte(buff, sequence))
return -1;
ob_append_byte(buff, sequence);
return 0;
}
@ -112,20 +106,17 @@ int overlay_frame_append_payload(struct decode_context *context, int encapsulati
p->queue, p->type, p->modifiers, will_retransmit,
p->ttl, p->mdp_sequence&0xFF,
broadcast, p->next_hop,
p->destination, p->source))
p->destination, p->source) == -1)
goto cleanup;
if (encapsulation == ENCAP_OVERLAY){
if (ob_append_ui16(b, ob_position(p->payload)))
goto cleanup;
}
if (encapsulation == ENCAP_OVERLAY)
ob_append_ui16(b, ob_position(p->payload));
if (ob_append_bytes(b, ob_ptr(p->payload), ob_position(p->payload))) {
WHYF("could not append payload of %u bytes", ob_position(p->payload));
goto cleanup;
}
return 0;
if (ob_position(p->payload))
ob_append_bytes(b, ob_ptr(p->payload), ob_position(p->payload));
if (!ob_overrun(b))
return 0;
cleanup:
ob_rewind(b);
@ -150,13 +141,18 @@ struct overlay_frame *op_dup(struct overlay_frame *in)
if (!in) return NULL;
/* clone the frame */
struct overlay_frame *out=malloc(sizeof(struct overlay_frame));
if (!out) { WHY("malloc() failed"); return NULL; }
struct overlay_frame *out = emalloc(sizeof(struct overlay_frame));
if (out == NULL)
return NULL;
/* copy main data structure */
bcopy(in,out,sizeof(struct overlay_frame));
if (in->payload)
out->payload=ob_dup(in->payload);
if (in->payload) {
if ((out->payload = ob_dup(in->payload)) == NULL) {
free(out);
return NULL;
}
}
return out;
}

View File

@ -17,6 +17,7 @@
*/
#include <assert.h>
#include "serval.h"
#include "conf.h"
#include "overlay_buffer.h"
@ -150,11 +151,9 @@ int overlay_payload_enqueue(struct overlay_frame *p)
Complain if there are too many frames in the queue.
*/
if (!p) return WHY("Cannot queue NULL");
if (p->queue>=OQ_MAX)
return WHY("Invalid queue specified");
assert(p != NULL);
assert(p->queue < OQ_MAX);
assert(p->payload != NULL);
overlay_txqueue *queue = &overlay_tx[p->queue];
if (config.debug.packettx)
@ -162,18 +161,15 @@ int overlay_payload_enqueue(struct overlay_frame *p)
p->destination?alloca_tohex_sid_t_trunc(p->destination->sid, 14): alloca_tohex(p->broadcast_id.id, BROADCAST_LEN),
p->queue, queue->length);
if (p->payload && ob_remaining(p->payload)<0){
// HACK, maybe should be done in each caller
// set the size of the payload based on the position written
ob_limitsize(p->payload,ob_position(p->payload));
}
if (ob_overrun(p->payload))
return WHY("Packet content overrun -- not queueing");
if (ob_position(p->payload) >= MDP_MTU)
FATAL("Queued packet is too big");
if (queue->length>=queue->maxLength)
return WHYF("Queue #%d congested (size = %d)",p->queue,queue->maxLength);
if (ob_position(p->payload)>=MDP_MTU)
FATAL("Queued packet is too big");
// it should be safe to try sending all packets with an mdp sequence
if (p->packet_version<=0)
p->packet_version=1;
@ -226,11 +222,13 @@ int overlay_payload_enqueue(struct overlay_frame *p)
return 0;
}
static void
static int
overlay_init_packet(struct outgoing_packet *packet, int packet_version,
struct network_destination *destination){
struct network_destination *destination)
{
packet->context.interface = destination->interface;
packet->buffer=ob_new();
if ((packet->buffer = ob_new()) == NULL)
return -1;
packet->packet_version = packet_version;
packet->context.packet_version = packet_version;
packet->destination = add_destination_ref(destination);
@ -238,20 +236,24 @@ overlay_init_packet(struct outgoing_packet *packet, int packet_version,
packet->seq=-1;
else
packet->seq = destination->sequence_number = (destination->sequence_number + 1) & 0xFFFF;
ob_limitsize(packet->buffer, destination->interface->mtu);
int i=destination->interface - overlay_interfaces;
overlay_packet_init_header(packet_version, destination->encapsulation,
&packet->context, packet->buffer,
destination->unicast,
i, packet->seq);
int i = destination->interface - overlay_interfaces;
if (overlay_packet_init_header(packet_version, destination->encapsulation,
&packet->context, packet->buffer,
destination->unicast,
i, packet->seq) == -1
) {
ob_free(packet->buffer);
packet->buffer = NULL;
return -1;
}
packet->header_length = ob_position(packet->buffer);
if (config.debug.overlayframes)
DEBUGF("Creating %d packet for interface %s, seq %d, %s",
packet_version,
destination->interface->name, destination->sequence_number,
destination->unicast?"unicast":"broadcast");
return 0;
}
int overlay_queue_schedule_next(time_ms_t next_allowed_packet){
@ -331,8 +333,9 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim
while(frame){
if (frame->enqueued_at + queue->latencyTarget < now){
if (config.debug.overlayframes)
DEBUGF("Dropping frame type %x for %s due to expiry timeout",
frame->type, frame->destination?alloca_tohex_sid_t(frame->destination->sid):"All");
DEBUGF("Dropping frame type %x (length %d) for %s due to expiry timeout",
frame->type, frame->payload->checkpointLength,
frame->destination?alloca_tohex_sid_t(frame->destination->sid):"All");
frame = overlay_queue_remove(queue, frame);
continue;
}
@ -411,11 +414,11 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim
// send a packet to this destination
if (frame->source_full)
my_subscriber->send_full=1;
overlay_init_packet(packet, frame->packet_version, dest);
destination_index=i;
frame->destinations[i].sent_sequence = dest->sequence_number;
break;
if (overlay_init_packet(packet, frame->packet_version, dest) != -1) {
destination_index=i;
frame->destinations[i].sent_sequence = dest->sequence_number;
break;
}
}
}
}
@ -532,12 +535,12 @@ static void overlay_send_packet(struct sched_ent *alarm){
overlay_fill_send_packet(&packet, gettime_ms());
}
int overlay_send_tick_packet(struct network_destination *destination){
int overlay_send_tick_packet(struct network_destination *destination)
{
struct outgoing_packet packet;
bzero(&packet, sizeof(struct outgoing_packet));
overlay_init_packet(&packet, 0, destination);
overlay_fill_send_packet(&packet, gettime_ms());
if (overlay_init_packet(&packet, 0, destination) != -1)
overlay_fill_send_packet(&packet, gettime_ms());
return 0;
}

View File

@ -168,11 +168,12 @@ static int append_bars(struct overlay_buffer *e, sqlite_retry_state *retry, cons
DEBUG("Found a BAR that is the wrong size - ignoring");
continue;
}
if (ob_append_bytes(e, (unsigned char *)data, blob_bytes)){
if (ob_remaining(e) < blob_bytes) {
// out of room
count--;
break;
}
ob_append_bytes(e, (unsigned char *)data, blob_bytes);
*last_rowid=rowid;
}
if (statement)
@ -184,7 +185,8 @@ static int append_bars(struct overlay_buffer *e, sqlite_retry_state *retry, cons
Always advertise the most recent 3 manifests in the table, cycle through the rest of the table, adding 17 BAR's at a time
*/
int64_t bundles_available=0;
void overlay_rhizome_advertise(struct sched_ent *alarm){
void overlay_rhizome_advertise(struct sched_ent *alarm)
{
bundles_available=0;
static int64_t bundle_last_rowid=INT64_MAX;
@ -197,7 +199,7 @@ void overlay_rhizome_advertise(struct sched_ent *alarm){
int (*oldfunc)() = sqlite_set_tracefunc(is_debug_rhizome_ads);
sqlite_retry_state retry = SQLITE_RETRY_STATE_DEFAULT;
// DEPRECATE REST OF THIS CODE WHICH SEEMS TO BE CAUSING TOO MUCH CHATTER
// TODO: DEPRECATE REST OF THIS CODE WHICH SEEMS TO BE CAUSING TOO MUCH CHATTER
// ESPECIALLY FOR PACKET-RADIO
goto end;
@ -216,31 +218,28 @@ void overlay_rhizome_advertise(struct sched_ent *alarm){
frame->source = my_subscriber;
frame->ttl = 1;
frame->queue = OQ_OPPORTUNISTIC;
frame->payload = ob_new();
if ((frame->payload = ob_new()) == NULL) {
op_free(frame);
goto end;
}
ob_limitsize(frame->payload, 800);
ob_append_byte(frame->payload, 2);
ob_append_ui16(frame->payload, rhizome_http_server_port);
int64_t rowid=0;
int count = append_bars(frame->payload, &retry,
"SELECT BAR,ROWID FROM MANIFESTS ORDER BY ROWID DESC LIMIT 3",
&rowid);
if (count>=3){
if (bundle_last_rowid>rowid || bundle_last_rowid<=0)
bundle_last_rowid=rowid;
count = append_bars(frame->payload, &retry,
"SELECT BAR,ROWID FROM MANIFESTS WHERE ROWID < ? ORDER BY ROWID DESC LIMIT 17",
&bundle_last_rowid);
if (count<17)
bundle_last_rowid=INT64_MAX;
}
if (overlay_payload_enqueue(frame))
if (overlay_payload_enqueue(frame) == -1)
op_free(frame);
end:
sqlite_set_tracefunc(oldfunc);
alarm->alarm = gettime_ms()+config.rhizome.advertise.interval;
@ -262,21 +261,20 @@ int rhizome_advertise_manifest(struct subscriber *dest, rhizome_manifest *m){
else
frame->ttl = 1;
frame->queue = OQ_OPPORTUNISTIC;
frame->payload = ob_new();
if ((frame->payload = ob_new()) == NULL)
goto error;
ob_limitsize(frame->payload, 800);
if (ob_append_byte(frame->payload, HAS_PORT|HAS_MANIFESTS)) goto error;
if (ob_append_ui16(frame->payload, is_rhizome_http_enabled()?rhizome_http_server_port:0)) goto error;
if (ob_append_ui16(frame->payload, m->manifest_all_bytes)) goto error;
if (ob_append_bytes(frame->payload, m->manifestdata, m->manifest_all_bytes)) goto error;
ob_append_byte(frame->payload, HAS_PORT|HAS_MANIFESTS);
ob_append_ui16(frame->payload, is_rhizome_http_enabled()?rhizome_http_server_port:0);
ob_append_ui16(frame->payload, m->manifest_all_bytes);
ob_append_bytes(frame->payload, m->manifestdata, m->manifest_all_bytes);
ob_append_byte(frame->payload, 0xFF);
if (overlay_payload_enqueue(frame)) goto error;
if (overlay_payload_enqueue(frame) == -1)
goto error;
if (config.debug.rhizome_ads)
DEBUGF("Advertising manifest %s %"PRId64" to %s",
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic), m->version, dest?alloca_tohex_sid_t(dest->sid):"broadcast");
return 0;
error:
op_free(frame);
return -1;

View File

@ -321,21 +321,16 @@ static void sync_process_bar_list(struct subscriber *subscriber, struct rhizome_
}
static int append_response(struct overlay_buffer *b, uint64_t token, const unsigned char *bar)
static void append_response(struct overlay_buffer *b, uint64_t token, const unsigned char *bar)
{
if (ob_append_packed_ui64(b, token))
return -1;
if (bar){
if (ob_append_bytes(b, bar, RHIZOME_BAR_BYTES))
return -1;
}else{
ob_append_packed_ui64(b, token);
if (bar)
ob_append_bytes(b, bar, RHIZOME_BAR_BYTES);
else{
unsigned char *ptr = ob_append_space(b, RHIZOME_BAR_BYTES);
if (!ptr)
return -1;
bzero(ptr, RHIZOME_BAR_BYTES);
if (ptr)
bzero(ptr, RHIZOME_BAR_BYTES);
}
ob_checkpoint(b);
return 0;
}
static uint64_t max_token=0;
@ -400,24 +395,26 @@ static void sync_send_response(struct subscriber *dest, int forwards, uint64_t t
// make sure we include the exact rowid that was requested, even if we just deleted / replaced the manifest
if (count==0 && rowid!=token){
if (token!=HEAD_FLAG){
if (append_response(b, token, NULL))
ob_checkpoint(b);
append_response(b, token, NULL);
if (ob_overrun(b))
ob_rewind(b);
else{
else {
count++;
last = token;
}
}else
token = rowid;
}
if (append_response(b, rowid, bar))
ob_checkpoint(b);
append_response(b, rowid, bar);
if (ob_overrun(b))
ob_rewind(b);
else {
last = rowid;
count++;
}
}
if (count >= max_count && rowid <= max_token)
break;
}
@ -427,7 +424,9 @@ static void sync_send_response(struct subscriber *dest, int forwards, uint64_t t
// send a zero lower bound if we reached the end of our manifest list
if (count && count < max_count && !forwards){
if (append_response(b, 0, NULL))
ob_checkpoint(b);
append_response(b, 0, NULL);
if (ob_overrun(b))
ob_rewind(b);
else {
last = 0;

View File

@ -467,48 +467,27 @@ static int append_link_state(struct overlay_buffer *payload, char flags,
flags|=FLAG_HAS_ACK;
if (drop_rate!=-1)
flags|=FLAG_HAS_DROP_RATE;
int length_pos = ob_position(payload);
if (ob_append_byte(payload, 0))
return -1;
if (ob_append_byte(payload, flags))
return -1;
if (overlay_address_append(NULL, payload, receiver))
return -1;
if (ob_append_byte(payload, version))
return -1;
ob_append_byte(payload, 0);
ob_append_byte(payload, flags);
overlay_address_append(NULL, payload, receiver);
ob_append_byte(payload, version);
if (transmitter)
if (overlay_address_append(NULL, payload, transmitter))
return -1;
if (interface!=-1)
if (ob_append_byte(payload, interface))
return -1;
if (ack_sequence!=-1){
if (ob_append_byte(payload, ack_sequence))
return -1;
if (ob_append_ui32(payload, ack_mask))
return -1;
overlay_address_append(NULL, payload, transmitter);
if (interface != -1)
ob_append_byte(payload, interface);
if (ack_sequence != -1){
ob_append_byte(payload, ack_sequence);
ob_append_ui32(payload, ack_mask);
}
if (drop_rate!=-1)
if (ob_append_byte(payload, drop_rate))
return -1;
if (drop_rate != -1)
ob_append_byte(payload, drop_rate);
// TODO insert future fields here
if (ob_overrun(payload))
return -1;
// patch the record length
int end_pos = ob_position(payload);
if (ob_set(payload, length_pos, end_pos - length_pos))
return -1;
ob_set(payload, length_pos, end_pos - length_pos);
ob_checkpoint(payload);
return 0;
}
@ -710,12 +689,15 @@ static int send_legacy_self_announce_ack(struct neighbour *neighbour, struct lin
frame->ttl = 6;
frame->destination = neighbour->subscriber;
frame->source = my_subscriber;
frame->payload = ob_new();
if ((frame->payload = ob_new()) == NULL) {
op_free(frame);
return -1;
}
ob_append_ui32(frame->payload, neighbour->last_update);
ob_append_ui32(frame->payload, now);
ob_append_byte(frame->payload, link->neighbour_interface);
frame->queue=OQ_MESH_MANAGEMENT;
if (overlay_payload_enqueue(frame)){
if (overlay_payload_enqueue(frame) == -1) {
op_free(frame);
return -1;
}
@ -787,12 +769,16 @@ static int send_neighbour_link(struct neighbour *n)
send_legacy_self_announce_ack(n, n->best_link, now);
n->last_update = now;
} else {
struct overlay_frame *frame=emalloc_zero(sizeof(struct overlay_frame));
struct overlay_frame *frame = emalloc_zero(sizeof(struct overlay_frame));
frame->type=OF_TYPE_DATA;
frame->source=my_subscriber;
frame->ttl=1;
frame->queue=OQ_MESH_MANAGEMENT;
frame->payload = ob_new();
if ((frame->payload = ob_new()) == NULL) {
op_free(frame);
RETURN(-1);
}
frame->send_hook = neighbour_link_sent;
frame->send_context = n->subscriber;
frame->resend=-1;
@ -825,7 +811,7 @@ static int send_neighbour_link(struct neighbour *n)
append_link_state(frame->payload, flags, n->subscriber, my_subscriber, n->best_link->neighbour_interface, 1,
n->best_link->ack_sequence, n->best_link->ack_mask, -1);
if (overlay_payload_enqueue(frame))
if (overlay_payload_enqueue(frame) == -1)
op_free(frame);
n->best_link->ack_counter = ACK_WINDOW;
@ -885,27 +871,25 @@ static void link_send(struct sched_ent *alarm)
frame->source=my_subscriber;
frame->ttl=1;
frame->queue=OQ_MESH_MANAGEMENT;
frame->payload = ob_new();
ob_limitsize(frame->payload, 400);
overlay_mdp_encode_ports(frame->payload, MDP_PORT_LINKSTATE, MDP_PORT_LINKSTATE);
ob_checkpoint(frame->payload);
int pos = ob_position(frame->payload);
enum_subscribers(NULL, append_link, frame->payload);
ob_rewind(frame->payload);
if (ob_position(frame->payload) == pos)
op_free(frame);
else if (overlay_payload_enqueue(frame))
op_free(frame);
if (neighbours){
alarm->deadline = alarm->alarm;
schedule(alarm);
}else
alarm->alarm=0;
if ((frame->payload = ob_new()) == NULL)
WHY("Cannot send link details");
else {
ob_limitsize(frame->payload, 400);
overlay_mdp_encode_ports(frame->payload, MDP_PORT_LINKSTATE, MDP_PORT_LINKSTATE);
ob_checkpoint(frame->payload);
int pos = ob_position(frame->payload);
enum_subscribers(NULL, append_link, frame->payload);
ob_rewind(frame->payload);
if (ob_position(frame->payload) == pos)
op_free(frame);
else if (overlay_payload_enqueue(frame))
op_free(frame);
if (neighbours){
alarm->deadline = alarm->alarm;
schedule(alarm);
}else
alarm->alarm=0;
}
}
static void update_alarm(time_ms_t limit){
@ -1113,7 +1097,6 @@ static struct link_out *create_out_link(struct neighbour *neighbour, overlay_int
ret->destination = create_unicast_destination(*addr, interface);
else
ret->destination = add_destination_ref(interface->destination);
if (config.debug.linkstate)
DEBUGF("LINK STATE; Create possible %s link_out for neighbour %s on interface %s",
unicast?"unicast":"broadcast",

View File

@ -576,7 +576,7 @@ int overlay_mdp_reply(int sock,struct sockaddr_un *recvaddr, socklen_t recvaddrl
overlay_mdp_frame *mdpreply);
int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
struct sockaddr_un *recvaddr, socklen_t recvaddrlen);
int overlay_mdp_encode_ports(struct overlay_buffer *plaintext, mdp_port_t dst_port, mdp_port_t src_port);
void overlay_mdp_encode_ports(struct overlay_buffer *plaintext, mdp_port_t dst_port, mdp_port_t src_port);
int overlay_mdp_dnalookup_reply(const sockaddr_mdp *dstaddr, const sid_t *resolved_sidp, const char *uri, const char *did, const char *name);
struct vomp_call_state;