Remove bogus ERROR messages from Batphone log

Improve overlay buffer primitives to eliminate bugus logged ERRORs
"ob_makespace() failed" and "could not append payload of N bytes" and
also add buffer overflow checks to more packet construction code.

Fix link state timing logic to eliminate logged ERROR "Alarm `link_send`
tried to schedule a deadline 1343871867115ms ago"

Improve debug logging of some MDP and dummy interface read/write code

Add 'debug.overlaybuffer' and 'debug.subscriber' config options
This commit is contained in:
Andrew Bettison 2013-11-26 15:44:16 +10:30
commit 56349b962e
26 changed files with 768 additions and 580 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,, "")
@ -269,6 +270,7 @@ ATOM(bool_t, rhizome_rx, 0, boolean,, "")
ATOM(bool_t, rhizome_ads, 0, boolean,, "")
ATOM(bool_t, rhizome_nohttptx, 0, boolean,, "")
ATOM(bool_t, rhizome_mdp_rx, 0, boolean,, "")
ATOM(bool_t, subscriber, 0, boolean,, "")
ATOM(bool_t, throttling, 0, boolean,, "")
ATOM(bool_t, meshms, 0, boolean,, "")
ATOM(bool_t, manifests, 0, boolean,, "")

View File

@ -108,7 +108,7 @@ int _schedule(struct __sourceloc __whence, struct sched_ent *alarm)
if (now - alarm->deadline > 1000){
// 1000ms ago? thats silly, if you keep doing it noone else will get a turn.
WHYF("Alarm %s tried to schedule a deadline %"PRId64"ms ago",
FATALF("Alarm %s tried to schedule a deadline %"PRId64"ms ago",
alloca_alarm_name(alarm),
(now - alarm->deadline)
);

View File

@ -80,14 +80,15 @@ int fd_checkalarms();
int fd_func_enter(struct __sourceloc, struct call_stats *this_call);
int fd_func_exit(struct __sourceloc, struct call_stats *this_call);
void dump_stack(int log_level);
unsigned fd_depth();
#define IN() static struct profile_total _aggregate_stats={NULL,0,__FUNCTION__,0,0,0}; \
struct call_stats _this_call={.totals=&_aggregate_stats}; \
fd_func_enter(__HERE__, &_this_call);
#define OUT() fd_func_exit(__HERE__, &_this_call)
#define RETURN(X) do { OUT(); return (X); } while (0);
#define RETURNNULL do { OUT(); return (NULL); } while (0);
#define RETURNVOID do { OUT(); return; } while (0);
#define RETURN(X) do { OUT(); return (X); } while (0)
#define RETURNNULL(X) do { X; OUT(); return (NULL); } while (0)
#define RETURNVOID do { OUT(); return; } while (0)
#endif // __SERVALDNA__FDQUEUE_H

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"
@ -103,57 +104,69 @@ void free_subscribers()
}
// find a subscriber struct from a whole or abbreviated subscriber id
struct subscriber *find_subscriber(const unsigned char *sidp, int len, int create)
struct subscriber *_find_subscriber(struct __sourceloc __whence, const unsigned char *sidp, int len, int create)
{
IN();
if (config.debug.subscriber)
DEBUGF("find_subscriber(sid=%s, create=%d)", alloca_tohex(sidp, len), create);
struct tree_node *ptr = &root;
int pos=0;
if (len!=SID_SIZE)
create =0;
do{
struct subscriber *ret = NULL;
do {
unsigned char nibble = get_nibble(sidp, pos++);
if (ptr->is_tree & (1<<nibble)){
ptr = ptr->tree_nodes[nibble];
}else if(!ptr->subscribers[nibble]){
// subscriber is not yet known
if (create){
struct subscriber *ret=(struct subscriber *)malloc(sizeof(struct subscriber));
memset(ret,0,sizeof(struct subscriber));
ptr->subscribers[nibble]=ret;
if (create && (ret = (struct subscriber *) emalloc_zero(sizeof(struct subscriber)))) {
ptr->subscribers[nibble] = ret;
ret->sid = *(const sid_t *)sidp;
ret->abbreviate_len=pos;
ret->abbreviate_len = pos;
if (config.debug.subscriber)
DEBUGF("set node[%.*s].subscribers[%c]=%p (sid=%s, abbrev_len=%d)",
pos - 1, alloca_tohex(sidp, len), hexdigit_upper[nibble],
ret, alloca_tohex_sid_t(ret->sid), ret->abbreviate_len
);
}
return ptr->subscribers[nibble];
goto done;
}else{
// there's a subscriber in this slot, does it match the rest of the sid we've been given?
struct subscriber *ret = ptr->subscribers[nibble];
ret = ptr->subscribers[nibble];
if (memcmp(ret->sid.binary, sidp, len) == 0)
return ret;
goto done;
// if we need to insert this subscriber, we have to make a new tree node first
if (!create)
return NULL;
if (!create) {
ret = NULL;
goto done;
}
// create a new tree node and move the existing subscriber into it
struct tree_node *new=(struct tree_node *)malloc(sizeof(struct tree_node));
memset(new,0,sizeof(struct tree_node));
ptr->tree_nodes[nibble]=new;
struct tree_node *new = (struct tree_node *) emalloc_zero(sizeof(struct tree_node));
if (new == NULL) {
ret = NULL;
goto done;
}
if (config.debug.subscriber)
DEBUGF("create node[%.*s]", pos, alloca_tohex(sidp, len));
ptr->tree_nodes[nibble] = new;
ptr->is_tree |= (1<<nibble);
ptr=new;
nibble=get_nibble(ret->sid.binary, pos);
ptr->subscribers[nibble]=ret;
ret->abbreviate_len=pos+1;
ptr = new;
nibble = get_nibble(ret->sid.binary, pos);
ptr->subscribers[nibble] = ret;
ret->abbreviate_len = pos + 1;
if (config.debug.subscriber)
DEBUGF("set node[%.*s].subscribers[%c]=%p(sid=%s, abbrev_len=%d)",
pos, alloca_tohex(sidp, len), hexdigit_upper[nibble],
ret, alloca_tohex_sid_t(ret->sid), ret->abbreviate_len
);
// then go around the loop again to compare the next nibble against the sid until we find an empty slot.
}
}while(pos < len*2);
// abbreviation is not unique
return NULL;
} while(pos < len*2);
done:
if (config.debug.subscriber)
DEBUGF("find_subscriber() return %p", ret);
RETURN(ret);
}
/*
@ -234,35 +247,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 +279,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 +296,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);
}
@ -301,6 +310,8 @@ static int add_explain_response(struct subscriber *subscriber, void *context){
// the header of this packet must include our full sid.
if (subscriber->reachable==REACHABLE_SELF){
if (subscriber==my_subscriber){
if (config.debug.subscriber)
DEBUGF("Explaining SELF sid=%s", alloca_tohex_sid_t(subscriber->sid));
response->please_explain->source_full=1;
return 0;
}
@ -308,18 +319,22 @@ 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))
if (config.debug.subscriber)
DEBUGF("Explaining sid=%s", alloca_tohex_sid_t(subscriber->sid));
ob_checkpoint(response->please_explain->payload);
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)) {
ob_rewind(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;
}
static int find_subscr_buffer(struct decode_context *context, struct overlay_buffer *b, int len, struct subscriber **subscriber){
static int find_subscr_buffer(struct decode_context *context, struct overlay_buffer *b, int len, struct subscriber **subscriber)
{
if (len<=0 || len>SID_SIZE){
return WHYF("Invalid abbreviation length %d", len);
}
@ -345,7 +360,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 +412,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);
}
@ -430,11 +447,13 @@ int overlay_address_parse(struct decode_context *context, struct overlay_buffer
}
// once we've finished parsing a packet, complete and send a please explain if required.
int send_please_explain(struct decode_context *context, struct subscriber *source, struct subscriber *destination){
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 +485,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);
@ -474,7 +493,8 @@ int send_please_explain(struct decode_context *context, struct subscriber *sourc
}
// process an incoming request for explanation of subscriber abbreviations
int process_explain(struct overlay_frame *frame){
int process_explain(struct overlay_frame *frame)
{
struct overlay_buffer *b=frame->payload;
struct decode_context context;
@ -499,14 +519,17 @@ int process_explain(struct overlay_frame *frame){
if (len==SID_SIZE){
// This message is also used to inform people of previously unknown subscribers
// make sure we know this one
INFOF("Storing explain response for %s", alloca_tohex(sid, len));
find_subscriber(sid,len,1);
}else{
// reply to the sender with all subscribers that match this abbreviation
INFOF("Sending responses for %s", alloca_tohex(sid, len));
INFOF("Sending explain responses for %s", alloca_tohex(sid, len));
walk_tree(&root, 0, sid, len, sid, len, add_explain_response, &context);
}
}
send_please_explain(&context, frame->destination, frame->source);
if (context.please_explain)
send_please_explain(&context, frame->destination, frame->source);
else if (config.debug.subscriber)
DEBUG("No explain responses");
return 0;
}

View File

@ -110,7 +110,9 @@ struct decode_context{
extern struct subscriber *my_subscriber;
extern struct subscriber *directory_service;
struct subscriber *find_subscriber(const unsigned char *sid, int len, int create);
struct subscriber *_find_subscriber(struct __sourceloc, const unsigned char *sid, int len, int create);
#define find_subscriber(sid, len, create) _find_subscriber(__WHENCE__, sid, len, create)
void enum_subscribers(struct subscriber *start, int(*callback)(struct subscriber *, void *), void *context);
int set_reachable(struct subscriber *subscriber, struct network_destination *destination, struct subscriber *next_hop);
int load_subscriber_address(struct subscriber *subscriber);
@ -119,8 +121,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,64 @@ 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 *_ob_new(struct __sourceloc __whence)
{
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 (config.debug.overlaybuffer)
DEBUGF("ob_new() return %p", ret);
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(struct __sourceloc __whence, unsigned char *bytes, int size)
{
struct overlay_buffer *ret = emalloc_zero(sizeof(struct overlay_buffer));
if (config.debug.overlaybuffer)
DEBUGF("ob_static(bytes=%p, size=%d) return %p", bytes, size, ret);
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 __sourceloc __whence, 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 (config.debug.overlaybuffer)
DEBUGF("ob_slice(b=%p, offset=%d, length=%d) return %p", b, offset, length, ret);
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 __sourceloc __whence, struct overlay_buffer *b)
{
struct overlay_buffer *ret = emalloc_zero(sizeof(struct overlay_buffer));
if (config.debug.overlaybuffer)
DEBUGF("ob_dup(b=%p) return %p", b, ret);
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 +96,109 @@ 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 __sourceloc __whence, 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 (config.debug.overlaybuffer)
DEBUGF("ob_free(b=%p)", b);
if (b->allocated)
free(b->allocated);
free(b);
}
int _ob_checkpoint(struct __sourceloc __whence, struct overlay_buffer *b)
{
assert(b != NULL);
b->checkpointLength = b->position;
if (config.debug.overlaybuffer)
DEBUGF("ob_checkpoint(b=%p) checkpointLength=%d", b, b->checkpointLength);
return 0;
}
int ob_checkpoint(struct overlay_buffer *b)
int _ob_rewind(struct __sourceloc __whence, struct overlay_buffer *b)
{
if (!b) return WHY("Asked to checkpoint NULL");
b->checkpointLength=b->position;
assert(b != NULL);
b->position = b->checkpointLength;
if (config.debug.overlaybuffer)
DEBUGF("ob_rewind(b=%p) position=%d", b, b->position);
return 0;
}
int ob_rewind(struct overlay_buffer *b)
void _ob_limitsize(struct __sourceloc __whence, struct overlay_buffer *b, int bytes)
{
if (!b) return WHY("Asked to rewind NULL");
b->position=b->checkpointLength;
return 0;
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;
if (config.debug.overlaybuffer)
DEBUGF("ob_limitsize(b=%p, bytes=%d) sizeLimit=%d", b, bytes, b->sizeLimit);
}
int ob_limitsize(struct overlay_buffer *b,int bytes)
void _ob_unlimitsize(struct __sourceloc __whence, struct overlay_buffer *b)
{
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");
b->sizeLimit=bytes;
return 0;
assert(b != NULL);
b->sizeLimit = -1;
if (config.debug.overlaybuffer)
DEBUGF("ob_unlimitsize(b=%p) sizeLimit=%d", b, b->sizeLimit);
}
int ob_unlimitsize(struct overlay_buffer *b)
void _ob_flip(struct __sourceloc __whence, struct overlay_buffer *b)
{
if (!b) return WHY("b is NULL");
b->sizeLimit=-1;
return 0;
if (config.debug.overlaybuffer)
DEBUGF("ob_flip(b=%p) checkpointLength=0 position=0", b);
b->checkpointLength = 0;
ob_limitsize(b, b->position);
b->position = 0;
}
int ob_flip(struct overlay_buffer *b)
{
b->checkpointLength=0;
if (ob_limitsize(b, b->position))
return -1;
b->position=0;
return 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 __sourceloc __whence, struct overlay_buffer *b, size_t bytes)
{
assert(b != NULL);
if (config.debug.overlaybuffer)
DEBUGF("ob_makespace(b=%p, bytes=%d) b->bytes=%p b->position=%d b->allocSize=%d",
b, bytes, b->bytes, b->position, b->allocSize);
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) {
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)
DEBUGF("ob_makespace(): asked for space to %u, beyond size limit of %u", b->position + bytes, b->sizeLimit);
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);
}
if (b->position + bytes <= b->allocSize)
return 1;
// Don't realloc a static buffer.
if (b->bytes && b->allocated == NULL) {
if (config.debug.packetformats)
DEBUGF("ob_makespace(): asked for space to %u, beyond static buffer size of %u", b->position + bytes, b->allocSize);
return 0;
}
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 +216,130 @@ 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 __sourceloc __whence, 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;
if (config.debug.overlaybuffer)
DEBUGF("ob_append_byte(b=%p, byte=0x%02x) %p[%d]=%02x position=%d", b, byte, b->bytes, b->position, byte, b->position + bytes);
} else {
if (config.debug.overlaybuffer)
DEBUGF("ob_append_byte(b=%p, byte=0x%02x) OVERRUN position=%d", b, byte, b->position + bytes);
}
b->position += bytes;
}
unsigned char *_ob_append_space(struct __sourceloc __whence, struct overlay_buffer *b,int count)
unsigned char *_ob_append_space(struct __sourceloc __whence, 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;
if (config.debug.overlaybuffer)
DEBUGF("ob_append_space(b=%p, count=%d) position=%d return %p", b, count, b->position, r);
return r;
}
int _ob_append_bytes(struct __sourceloc __whence, struct overlay_buffer *b, const unsigned char *bytes, int count)
void _ob_append_bytes(struct __sourceloc __whence, 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);
if (config.debug.overlaybuffer)
DEBUGF("ob_append_bytes(b=%p, bytes=%p, count=%d) position=%d return %p", b, bytes, count, b->position + count, r);
} else {
if (config.debug.overlaybuffer)
DEBUGF("ob_append_bytes(b=%p, bytes=%p, count=%d) OVERRUN position=%d return NULL", b, bytes, count, b->position + count);
}
if (config.debug.overlaybuffer)
dump("ob_append_bytes", bytes, count);
b->position += 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 _ob_append_buffer(struct __sourceloc __whence, 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 __sourceloc __whence, 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;
if (config.debug.overlaybuffer)
DEBUGF("ob_append_ui16(b=%p, v=%u) %p[%d]=%s position=%d", b, v, b->bytes, b->position, alloca_tohex(&b->bytes[b->position], bytes), b->position + bytes);
} else {
if (config.debug.overlaybuffer)
DEBUGF("ob_append_ui16(b=%p, v=%u) OVERRUN position=%d", b, v, b->position + bytes);
}
b->position += bytes;
}
int _ob_append_ui32(struct __sourceloc __whence, struct overlay_buffer *b, uint32_t v)
void _ob_append_ui32(struct __sourceloc __whence, 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;
if (config.debug.overlaybuffer)
DEBUGF("ob_append_ui32(b=%p, v=%"PRIu32") %p[%d]=%s position=%d",
b, v, b->bytes, b->position, alloca_tohex(&b->bytes[b->position], bytes), b->position + bytes);
} else {
if (config.debug.overlaybuffer)
DEBUGF("ob_append_ui32(b=%p, v=%"PRIu32") OVERRUN position=%d", b, v, b->position + bytes);
}
b->position += bytes;
}
int _ob_append_ui64(struct __sourceloc __whence, struct overlay_buffer *b, uint64_t v)
void _ob_append_ui64(struct __sourceloc __whence, 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;
if (config.debug.overlaybuffer)
DEBUGF("ob_append_ui64(b=%p, v=%"PRIu64") %p[%d]=%s position=%d",
b, v, b->bytes, b->position, alloca_tohex(&b->bytes[b->position], bytes), b->position + bytes);
} else {
if (config.debug.overlaybuffer)
DEBUGF("ob_append_ui64(b=%p, v=%"PRIu64") OVERRUN position=%d", b, v, b->position + bytes);
}
b->position += bytes;
}
int measure_packed_uint(uint64_t v){
@ -320,36 +376,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 __sourceloc __whence, 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 __sourceloc __whence, 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 __sourceloc __whence, 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 +407,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;
@ -464,46 +513,75 @@ uint64_t ob_get_packed_ui64(struct overlay_buffer *b)
return ret;
}
int ob_get(struct overlay_buffer *b){
int ob_get(struct overlay_buffer *b)
{
if (test_offset(b, b->position, 1))
return -1;
return b->bytes[b->position++];
}
int ob_set_ui16(struct overlay_buffer *b, int offset, uint16_t v)
void _ob_set_ui16(struct __sourceloc __whence, struct overlay_buffer *b, int offset, uint16_t v)
{
if (test_offset(b, offset, 2))
return -1;
const int bytes = 2;
assert(b != NULL);
assert(offset >= 0);
if (b->sizeLimit != -1)
assert(offset + bytes <= b->sizeLimit);
assert(offset + bytes <= b->allocSize);
b->bytes[offset] = (v >> 8) & 0xFF;
b->bytes[offset+1] = v & 0xFF;
return 0;
if (config.debug.overlaybuffer)
DEBUGF("ob_set_ui16(b=%p, offset=%d, v=%u) %p[%d]=%s", b, offset, v, b->bytes, offset, alloca_tohex(&b->bytes[offset], bytes));
}
int ob_set(struct overlay_buffer *b, int ofs, unsigned char byte)
void _ob_set(struct __sourceloc __whence, struct overlay_buffer *b, int offset, unsigned char byte)
{
if (test_offset(b, ofs, 1))
return -1;
b->bytes[ofs] = byte;
return 0;
const int bytes = 1;
assert(b != NULL);
assert(offset >= 0);
if (b->sizeLimit != -1)
assert(offset + bytes <= b->sizeLimit);
assert(offset + bytes <= b->allocSize);
b->bytes[offset] = byte;
if (config.debug.overlaybuffer)
DEBUGF("ob_set(b=%p, offset=%d, byte=0x%02x) %p[%d]=%s", b, offset, byte, b->bytes, offset, alloca_tohex(&b->bytes[offset], bytes));
}
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 __sourceloc __whence, 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 __sourceloc __whence, struct overlay_buffer *b)
{
assert(b->allocSize >= 0);
if (b->sizeLimit != -1)
assert(b->sizeLimit >= 0);
int ret = b->position > (b->sizeLimit != -1 && b->sizeLimit < b->allocSize ? b->sizeLimit : b->allocSize);
if (config.debug.overlaybuffer)
DEBUGF("ob_overrun(b=%p) return %d", b, ret);
return ret;
}
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;
@ -42,31 +42,47 @@ struct overlay_buffer {
int var_length_offset;
};
struct overlay_buffer *ob_new(void);
struct overlay_buffer *ob_static(unsigned char *bytes, int size);
struct overlay_buffer *ob_slice(struct overlay_buffer *b, int offset, int length);
struct overlay_buffer *ob_dup(struct overlay_buffer *b);
int ob_free(struct overlay_buffer *b);
int ob_checkpoint(struct overlay_buffer *b);
int ob_rewind(struct overlay_buffer *b);
int ob_limitsize(struct overlay_buffer *b,int bytes);
int ob_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);
struct overlay_buffer *_ob_new(struct __sourceloc __whence);
struct overlay_buffer *_ob_static(struct __sourceloc __whence, unsigned char *bytes, int size);
struct overlay_buffer *_ob_slice(struct __sourceloc __whence, struct overlay_buffer *b, int offset, int length);
struct overlay_buffer *_ob_dup(struct __sourceloc __whence, struct overlay_buffer *b);
void _ob_free(struct __sourceloc __whence, struct overlay_buffer *b);
int _ob_checkpoint(struct __sourceloc __whence, struct overlay_buffer *b);
int _ob_rewind(struct __sourceloc __whence, struct overlay_buffer *b);
void _ob_limitsize(struct __sourceloc __whence, struct overlay_buffer *b,int bytes);
void _ob_flip(struct __sourceloc __whence, struct overlay_buffer *b);
void _ob_unlimitsize(struct __sourceloc __whence, struct overlay_buffer *b);
ssize_t _ob_makespace(struct __sourceloc whence, struct overlay_buffer *b, size_t bytes);
void _ob_set(struct __sourceloc __whence, struct overlay_buffer *b, int ofs, unsigned char byte);
void _ob_set_ui16(struct __sourceloc __whence, struct overlay_buffer *b, int offset, uint16_t v);
void _ob_patch_rfs(struct __sourceloc __whence, 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);
void _ob_append_byte(struct __sourceloc whence, struct overlay_buffer *b,unsigned char byte);
void _ob_append_bytes(struct __sourceloc whence, struct overlay_buffer *b,const unsigned char *bytes,int count);
void _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_ui16(struct __sourceloc whence, struct overlay_buffer *b, uint16_t v);
void _ob_append_ui32(struct __sourceloc whence, struct overlay_buffer *b, uint32_t v);
void _ob_append_ui64(struct __sourceloc whence, struct overlay_buffer *b, uint64_t v);
void _ob_append_packed_ui32(struct __sourceloc whence, struct overlay_buffer *b, uint32_t v);
void _ob_append_packed_ui64(struct __sourceloc whence, struct overlay_buffer *b, uint64_t v);
void _ob_append_rfs(struct __sourceloc whence, struct overlay_buffer *b,int l);
#define ob_new() _ob_new(__WHENCE__)
#define ob_static(bytes, size) _ob_static(__WHENCE__, bytes, size)
#define ob_slice(b, off, len) _ob_slice(__WHENCE__, b, off, len)
#define ob_dup(b) _ob_dup(__WHENCE__, b)
#define ob_free(b) _ob_free(__WHENCE__, b)
#define ob_checkpoint(b) _ob_checkpoint(__WHENCE__, b)
#define ob_rewind(b) _ob_rewind(__WHENCE__, b)
#define ob_limitsize(b, size) _ob_limitsize(__WHENCE__, b, size)
#define ob_flip(b) _ob_flip(__WHENCE__, b)
#define ob_unlimitsize(b) _ob_unlimitsize(__WHENCE__, b)
#define ob_makespace(b, bytes) _ob_makespace(__WHENCE__, b, bytes)
#define ob_set(b, off, byte) _ob_set(__WHENCE__, b, off, byte)
#define ob_set_ui16(b, off, v) _ob_set_ui16(__WHENCE__, b, off, v)
#define ob_patch_rfs(b) _ob_patch_rfs(__WHENCE__, b)
#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)
@ -78,7 +94,6 @@ int _ob_append_rfs(struct __sourceloc whence, struct overlay_buffer *b,int l);
#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 +104,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 +112,9 @@ 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 __sourceloc, struct overlay_buffer *b);
unsigned char* ob_ptr(struct overlay_buffer *b);
#endif
#define ob_overrun(b) _ob_overrun(__WHENCE__, b)
#endif //__SERVALD__OVERLAY_BUFFER_H

View File

@ -657,9 +657,6 @@ static void interface_read_file(struct overlay_interface *interface)
return;
}
if (config.debug.overlayinterfaces)
DEBUGF("Read interface %s (size=%"PRId64") at offset=%d",interface->name, (int64_t)length, interface->recv_offset);
ssize_t nread = read(interface->alarm.poll.fd, &packet, sizeof packet);
if (nread == -1){
WHY_perror("read");
@ -668,11 +665,22 @@ static void interface_read_file(struct overlay_interface *interface)
}
if (nread == sizeof packet) {
if (config.debug.overlayinterfaces)
DEBUGF("Read from interface %s (filesize=%"PRId64") at offset=%d: src_addr=%s dst_addr=%s pid=%d length=%d",
interface->name, (int64_t)length, interface->recv_offset,
alloca_sockaddr(&packet.src_addr, sizeof packet.src_addr),
alloca_sockaddr(&packet.dst_addr, sizeof packet.dst_addr),
packet.pid,
packet.payload_length
);
interface->recv_offset += nread;
if (should_drop(interface, packet.dst_addr) || (packet.pid == getpid() && !interface->local_echo)){
if (config.debug.packetrx)
DEBUGF("Ignoring packet from %d, addressed to %s:%d", packet.pid,
inet_ntoa(packet.dst_addr.sin_addr), ntohs(packet.dst_addr.sin_port));
DEBUGF("Ignoring packet from pid=%d src_addr=%s dst_addr=%s",
packet.pid,
alloca_sockaddr_in(&packet.src_addr),
alloca_sockaddr_in(&packet.dst_addr)
);
}else{
packetOkOverlay(interface, packet.payload, packet.payload_length, -1,
(struct sockaddr*)&packet.src_addr, (socklen_t) sizeof(packet.src_addr));
@ -961,9 +969,21 @@ int overlay_broadcast_ensemble(struct network_destination *destination, struct o
not support seeking. */
if (errno != ESPIPE)
return WHY_perror("lseek");
DEBUGF("Write to interface %s at unknown offset", interface->name);
DEBUGF("Write to interface %s at offset unknown: src_addr=%s dst_addr=%s pid=%d length=%d",
interface->name,
alloca_sockaddr(&packet.src_addr, sizeof packet.src_addr),
alloca_sockaddr(&packet.dst_addr, sizeof packet.dst_addr),
packet.pid,
packet.payload_length
);
} else
DEBUGF("Write to interface %s at offset=%"PRId64, interface->name, (int64_t)fsize);
DEBUGF("Write to interface %s at offset=%"PRId64": src_addr=%s dst_addr=%s pid=%d length=%d",
interface->name, (int64_t)fsize,
alloca_sockaddr(&packet.src_addr, sizeof packet.src_addr),
alloca_sockaddr(&packet.dst_addr, sizeof packet.dst_addr),
packet.pid,
packet.payload_length
);
}
ssize_t nwrite = write(interface->alarm.poll.fd, &packet, sizeof(packet));
if (nwrite == -1)

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)
@ -449,6 +445,9 @@ static int overlay_saw_mdp_frame(struct overlay_frame *frame, overlay_mdp_frame
if (len == -1)
RETURN(WHY("unsupported MDP packet type"));
socklen_t addrlen = sizeof addr.sun_family + mdp_bindings[match].name_len;
if (config.debug.mdprequests)
DEBUGF("Resolved bound socket on port %"PRImdp_port_t", addr=%s",
mdp_bindings[match].port, alloca_sockaddr(&addr, addrlen));
ssize_t r = sendto(mdp_sock.poll.fd, mdp, (size_t)len, 0, (struct sockaddr*)&addr, addrlen);
if ((size_t)r != (size_t)len) {
if (r == -1) {
@ -463,6 +462,7 @@ static int overlay_saw_mdp_frame(struct overlay_frame *frame, overlay_mdp_frame
RETURN(WHY("Failed to pass received MDP frame to client"));
}
} else {
DEBUGF("No socket bound to port %"PRImdp_port_t", try internal service", mdp->out.dst.port);
/* No socket is bound, ignore the packet ... except for magic sockets */
RETURN(overlay_mdp_try_interal_services(frame, mdp));
}
@ -478,6 +478,13 @@ static int overlay_saw_mdp_frame(struct overlay_frame *frame, overlay_mdp_frame
int overlay_mdp_dnalookup_reply(const sockaddr_mdp *dstaddr, const sid_t *resolved_sidp, const char *uri, const char *did, const char *name)
{
if (config.debug.mdprequests)
DEBUGF("MDP_PORT_DNALOOKUP resolved_sid=%s uri=%s did=%s name=%s",
alloca_tohex_sid_t(*resolved_sidp),
alloca_str_toprint(uri),
alloca_str_toprint(did),
alloca_str_toprint(name)
);
overlay_mdp_frame mdpreply;
bzero(&mdpreply, sizeof mdpreply);
mdpreply.packetTypeAndFlags = MDP_TX; // outgoing MDP message
@ -529,26 +536,22 @@ 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(
struct subscriber *source,
struct subscriber *dest,
const unsigned char *buffer, int cipher_len){
int nm=crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES;
const unsigned char *buffer,
int cipher_len)
{
int zb=crypto_box_curve25519xsalsa20poly1305_ZEROBYTES;
int nb=crypto_box_curve25519xsalsa20poly1305_NONCEBYTES;
int cz=crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES;
@ -564,13 +567,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);
@ -591,30 +596,31 @@ static struct overlay_buffer * encrypt_payload(
}
/* Actually authcrypt the payload */
if (crypto_box_curve25519xsalsa20poly1305_afternm
(cipher_text,plain,cipher_len,nonce,k)){
if (crypto_box_curve25519xsalsa20poly1305_afternm(cipher_text, plain,cipher_len, nonce, k)) {
ob_free(ret);
WHY("crypto_box_afternm() failed");
return NULL;
}
if (0) {
#if 0
if (config.debug.crypto) {
DEBUG("authcrypted mdp frame");
dump("nm",k,nm);
dump("nm",k,crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES);
dump("plain text",plain,sizeof(plain));
dump("nonce",nonce,nb);
dump("cipher text",cipher_text,cipher_len);
}
#endif
/* now shuffle down to get rid of the temporary space that crypto_box
uses.
/* now shuffle down to get rid of the temporary space that crypto_box uses.
TODO extend overlay buffer so we don't need this.
*/
bcopy(&cipher_text[cz],&cipher_text[0],cipher_len-cz);
ret->position-=cz;
if (0){
#if 0
if (config.debug.crypto)
dump("frame", &ret->bytes[0], ret->position);
}
#endif
return ret;
}
@ -639,16 +645,25 @@ int overlay_send_frame(struct overlay_frame *frame, struct overlay_buffer *plain
op_free(frame);
return -1;
}
#if 0
if (config.debug.crypto)
dump("Frame signed ciphertext", ob_ptr(frame->payload), ob_position(frame->payload));
#endif
break;
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)
|| crypto_sign_message(frame->source, ob_ptr(frame->payload), frame->payload->allocSize, &frame->payload->position) == -1
) {
op_free(frame);
return -1;
}
#if 0
if (config.debug.crypto)
dump("Frame signed plaintext", ob_ptr(frame->payload), ob_position(frame->payload));
#endif
break;
case 0:
@ -678,6 +693,17 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
struct sockaddr_un *recvaddr, socklen_t recvaddrlen)
{
IN();
unsigned __d = 0;
if (config.debug.mdprequests) {
__d = fd_depth();
DEBUGF("[%u] src=%s*:%"PRImdp_port_t", dst=%s*:%"PRImdp_port_t", userGen=%d, recv=%s",
__d,
alloca_tohex_sid_t_trunc(mdp->out.src.sid, 14), mdp->out.src.port,
alloca_tohex_sid_t_trunc(mdp->out.dst.sid, 14), mdp->out.dst.port,
userGeneratedFrameP,
recvaddr ? alloca_sockaddr(recvaddr, recvaddrlen) : "NULL"
);
}
if (mdp->out.payload_length > sizeof(mdp->out.payload))
FATAL("Payload length is past the end of the buffer");
@ -715,6 +741,8 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
/* Work out if destination is broadcast or not */
if (is_sid_t_broadcast(mdp->out.dst.sid)){
if (config.debug.mdprequests)
DEBUGF("[%u] Broadcast packet", __d);
/* broadcast packets cannot be encrypted, so complain if MDP_NOCRYPT
flag is not set. Also, MDP_NOSIGN must also be applied, until
NaCl cryptobox keys can be used for signing. */
@ -736,12 +764,15 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
if (mdp->out.queue == 0)
mdp->out.queue = OQ_ORDINARY;
if (!destination || destination->reachable == REACHABLE_SELF){
if (config.debug.mdprequests)
DEBUGF("[%u] destination->sid=%s", __d, destination ? alloca_tohex_sid_t(destination->sid) : "NULL");
if (!destination || destination->reachable == REACHABLE_SELF) {
/* Packet is addressed to us / broadcast, we should process it first. */
overlay_saw_mdp_frame(NULL,mdp,gettime_ms());
if (destination) {
/* Is local, and is not broadcast, so shouldn't get sent out
on the wire. */
/* Is local, and is not broadcast, so shouldn't get sent out on the wire. */
if (config.debug.mdprequests)
DEBUGF("[%u] Local packet, not transmitting", __d);
RETURN(0);
}
}
@ -773,17 +804,23 @@ 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)) {
if (config.debug.mdprequests)
DEBUGF("[%u] Frame overrun: position=%d allocSize=%d sizeLimit=%d", __d,
plaintext->position, plaintext->allocSize, plaintext->sizeLimit);
ob_free(plaintext);
RETURN(-1);
}
if (config.debug.mdprequests) {
DEBUGF("[%u] Send frame %zu bytes", __d, ob_position(plaintext));
dump("Frame plaintext", ob_ptr(plaintext), ob_position(plaintext));
}
/* Prepare the overlay frame for dispatch */
struct overlay_frame *frame = emalloc_zero(sizeof(struct overlay_frame));
@ -829,7 +866,8 @@ static int search_subscribers(struct subscriber *subscriber, void *context){
return 0;
}
int overlay_mdp_address_list(overlay_mdp_addrlist *request, overlay_mdp_addrlist *response){
int overlay_mdp_address_list(overlay_mdp_addrlist *request, overlay_mdp_addrlist *response)
{
if (config.debug.mdprequests)
DEBUGF("MDP_GETADDRS first_sid=%u mode=%d", request->first_sid, request->mode);

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,30 +151,25 @@ 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)
DEBUGF("Enqueuing packet for %s* (q[%d]length = %d)",
DEBUGF("Enqueuing packet for %s* (q[%d].length = %d)",
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

@ -208,6 +208,15 @@ void dump_stack(int log_level)
}
}
unsigned fd_depth()
{
unsigned depth = 0;
struct call_stats *call;
for (call = current_call; call; call = call->prev)
++depth;
return depth;
}
int fd_func_enter(struct __sourceloc __whence, struct call_stats *this_call)
{
if (config.debug.profiling)

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

@ -255,6 +255,7 @@ static struct neighbour *get_neighbour(struct subscriber *subscriber, char creat
n->mdp_ack_sequence = -1;
// TODO measure min/max rtt
n->rtt = 120;
n->next_neighbour_update = gettime_ms() + 10;
neighbours = n;
if (config.debug.linkstate)
DEBUGF("LINK STATE; new neighbour %s", alloca_tohex_sid_t(n->subscriber->sid));
@ -467,48 +468,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 +690,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 +770,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 +812,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,30 +872,31 @@ 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){
static void update_alarm(struct __sourceloc __whence, time_ms_t limit)
{
if (limit == 0)
FATALF("limit == 0");
if (link_send_alarm.alarm>limit || link_send_alarm.alarm==0){
unschedule(&link_send_alarm);
link_send_alarm.alarm = limit;
@ -928,7 +916,7 @@ int link_stop_routing(struct subscriber *subscriber)
if (subscriber->link_state){
struct link_state *state = get_link_state(subscriber);
state->next_update = gettime_ms();
update_alarm(state->next_update);
update_alarm(__WHENCE__, state->next_update);
}
return 0;
}
@ -1047,7 +1035,8 @@ int link_state_should_forward_broadcast(struct subscriber *transmitter)
}
// when we receive a packet from a neighbour with ourselves as the next hop, make sure we send an ack soon(ish)
int link_state_ack_soon(struct subscriber *subscriber){
int link_state_ack_soon(struct subscriber *subscriber)
{
IN();
struct neighbour *neighbour = get_neighbour(subscriber, 0);
if (!neighbour)
@ -1062,8 +1051,8 @@ int link_state_ack_soon(struct subscriber *subscriber){
if (config.debug.ack)
DEBUGF("Asking for next ACK Real Soon Now");
}
update_alarm(__WHENCE__, neighbour->next_neighbour_update);
}
update_alarm(neighbour->next_neighbour_update);
OUT();
return 0;
}
@ -1104,7 +1093,8 @@ int link_unicast_ack(struct subscriber *subscriber, struct overlay_interface *in
return 0;
}
static struct link_out *create_out_link(struct neighbour *neighbour, overlay_interface *interface, struct sockaddr_in *addr, char unicast){
static struct link_out *create_out_link(struct neighbour *neighbour, overlay_interface *interface, struct sockaddr_in *addr, char unicast)
{
struct link_out *ret=emalloc_zero(sizeof(struct link_out));
if (ret){
ret->_next=neighbour->out_links;
@ -1113,15 +1103,14 @@ 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",
alloca_tohex_sid_t(neighbour->subscriber->sid),
interface->name);
ret->timeout = gettime_ms()+ret->destination->tick_ms*3;
update_alarm(gettime_ms()+5);
time_ms_t now = gettime_ms();
ret->timeout = now + ret->destination->tick_ms * 3;
update_alarm(__WHENCE__, now + 5);
}
return ret;
}
@ -1209,7 +1198,7 @@ int link_received_packet(struct decode_context *context, int sender_seq, char un
send_neighbour_link(neighbour);
}
update_alarm(neighbour->next_neighbour_update);
update_alarm(__WHENCE__, neighbour->next_neighbour_update);
return 0;
}
@ -1388,7 +1377,7 @@ int link_receive(struct overlay_frame *frame, overlay_mdp_frame *mdp)
if (config.debug.ack)
DEBUGF("LINK STATE; neighbour %s missed ack %d, queue another", alloca_tohex_sid_t(sender->sid), neighbour->last_update_seq);
neighbour->next_neighbour_update=now+5;
update_alarm(neighbour->next_neighbour_update);
update_alarm(__WHENCE__, neighbour->next_neighbour_update);
}
}
}
@ -1429,8 +1418,8 @@ void link_explained(struct subscriber *subscriber)
{
time_ms_t now = gettime_ms();
struct link_state *state = get_link_state(subscriber);
state->next_update = now+5;
update_alarm(now+5);
state->next_update = now + 5;
update_alarm(__WHENCE__, now + 5);
}
void link_interface_down(struct overlay_interface *interface)

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;

View File

@ -316,7 +316,7 @@ strbuf strbuf_append_socket_type(strbuf sb, int type)
strbuf strbuf_append_in_addr(strbuf sb, const struct in_addr *addr)
{
strbuf_sprintf(sb, " %u.%u.%u.%u",
strbuf_sprintf(sb, "%u.%u.%u.%u",
((unsigned char *) &addr->s_addr)[0],
((unsigned char *) &addr->s_addr)[1],
((unsigned char *) &addr->s_addr)[2],
@ -324,13 +324,21 @@ strbuf strbuf_append_in_addr(strbuf sb, const struct in_addr *addr)
return sb;
}
strbuf strbuf_append_sockaddr_in(strbuf sb, const struct sockaddr_in *addr)
{
assert(addr->sin_family == AF_INET);
strbuf_puts(sb, "AF_INET:");
strbuf_append_in_addr(sb, &addr->sin_addr);
strbuf_sprintf(sb, ":%u", ntohs(addr->sin_port));
return sb;
}
strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *addr, socklen_t addrlen)
{
strbuf_append_socket_domain(sb, addr->sa_family);
switch (addr->sa_family) {
case AF_UNIX: {
strbuf_puts(sb, "AF_UNIX:");
size_t len = addrlen > sizeof addr->sa_family ? addrlen - sizeof addr->sa_family : 0;
strbuf_putc(sb, ' ');
if (addr->sa_data[0]) {
strbuf_toprint_quoted_len(sb, "\"\"", addr->sa_data, len);
if (len < 2)
@ -347,18 +355,19 @@ strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *addr, socklen_t
break;
case AF_INET: {
const struct sockaddr_in *addr_in = (const struct sockaddr_in *) addr;
strbuf_putc(sb, ' ');
strbuf_append_in_addr(sb, &addr_in->sin_addr);
strbuf_sprintf(sb, ":%u", ntohs(addr_in->sin_port));
strbuf_append_sockaddr_in(sb, addr_in);
if (addrlen != sizeof(struct sockaddr_in))
strbuf_sprintf(sb, " (addrlen=%d should be %zd)", (int)addrlen, sizeof(struct sockaddr_in));
}
break;
default: {
strbuf_append_socket_domain(sb, addr->sa_family);
size_t len = addrlen > sizeof addr->sa_family ? addrlen - sizeof addr->sa_family : 0;
int i;
for (i = 0; i < len; ++i)
strbuf_sprintf(sb, " %02x", addr->sa_data[i]);
for (i = 0; i < len; ++i) {
strbuf_putc(sb, i ? ',' : ':');
strbuf_sprintf(sb, "%02x", addr->sa_data[i]);
}
}
break;
}

View File

@ -128,6 +128,13 @@ strbuf strbuf_append_in_addr(strbuf sb, const struct in_addr *addr);
/* Append a textual description of a struct sockaddr_in.
* @author Andrew Bettison <andrew@servalproject.com>
*/
struct sockaddr_in;
strbuf strbuf_append_sockaddr_in(strbuf sb, const struct sockaddr_in *addr);
#define alloca_sockaddr_in(addr) strbuf_str(strbuf_append_sockaddr_in(strbuf_alloca(45), (const struct sockaddr_in *)(addr)))
/* Append a textual description of a struct sockaddr.
* @author Andrew Bettison <andrew@servalproject.com>
*/
struct sockaddr;
strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *addr, socklen_t addrlen);
#define alloca_sockaddr(addr, addrlen) strbuf_str(strbuf_append_sockaddr(strbuf_alloca(200), (const struct sockaddr *)(addr), (addrlen)))

View File

@ -47,8 +47,10 @@ set_server_vars() {
set log.console.show_time on \
set mdp.iftype.wifi.tick_ms 100 \
set rhizome.enable No \
set debug.overlayinterfaces Yes \
set debug.overlayinterfaces No \
set debug.overlaybuffer No \
set debug.packetformats No \
set debug.overlayframes No \
set debug.overlayrouting No \
set debug.packettx No \
set debug.packetrx No \

View File

@ -81,6 +81,7 @@ start_routing_instance() {
set debug.mdprequests yes \
set debug.linkstate yes \
set debug.verbose yes \
set debug.subscriber yes \
set debug.overlayrouting yes \
set log.console.level debug \
set log.console.show_pid on \