mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-19 21:27:57 +00:00
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:
parent
9cdf053320
commit
a9ccd38adc
@ -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
|
||||
|
@ -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,, "")
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
347
overlay_buffer.c
347
overlay_buffer.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
109
route_link.c
109
route_link.c
@ -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",
|
||||
|
2
serval.h
2
serval.h
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user