Shift all payload header writing to one place

This commit is contained in:
Jeremy Lakeman 2012-11-23 16:25:32 +10:30
parent 6d958f3bf3
commit 627e86fb73
7 changed files with 94 additions and 107 deletions

2
log.c
View File

@ -397,6 +397,7 @@ ssize_t get_self_executable_path(char *buf, size_t len)
int log_backtrace(struct __sourceloc whence)
{
#if 0
open_logging();
char execpath[MAXPATHLEN];
if (get_self_executable_path(execpath, sizeof execpath) == -1)
@ -494,5 +495,6 @@ int log_backtrace(struct __sourceloc whence)
strbuf_append_exit_status(b, status);
logMessage(LOG_LEVEL_DEBUG, __NOWHERE__, "gdb %s", buf);
unlink(tempfile);
#endif
return 0;
}

View File

@ -460,7 +460,7 @@ int overlay_address_parse(struct decode_context *context, struct overlay_buffer
int code = ob_getbyte(b,b->position);
if (code<0)
return -1;
DEBUGF("Decoding address code %d",code);
switch(code){
case OA_CODE_BROADCAST:
b->position++;
@ -535,8 +535,9 @@ 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){
IN();
if (!context->please_explain)
return 0;
RETURN(0);
context->please_explain->type = OF_TYPE_PLEASEEXPLAIN;
@ -556,9 +557,9 @@ int send_please_explain(struct decode_context *context, struct subscriber *sourc
DEBUGF("Queued please explain");
context->please_explain->queue=OQ_MESH_MANAGEMENT;
if (!overlay_payload_enqueue(context->please_explain))
return 0;
RETURN(0);
op_free(context->please_explain);
return 0;
RETURN(0);
}
// process an incoming request for explanation of subscriber abbreviations

View File

@ -122,18 +122,14 @@ int overlay_route_add_advertisements(struct decode_context *context, overlay_int
ob_checkpoint(e);
// assume we might fill the whole packet
if (overlay_packet_append_header(e, OF_TYPE_NODEANNOUNCE, 1, e->sizeLimit - e->position))
return WHY("could not add node advertisement header");
/* Add address fields */
struct broadcast broadcast;
overlay_broadcast_generate_address(&broadcast);
overlay_broadcast_append(context,e,&broadcast);
ob_append_byte(e,OA_CODE_PREVIOUS);
overlay_address_append(context, e, my_subscriber);
if (overlay_frame_build_header(context, e,
0, OF_TYPE_NODEANNOUNCE, 0, 1,
&broadcast, NULL,
NULL, my_subscriber))
return -1;
// TODO high priority advertisements first....
/*

View File

@ -37,6 +37,7 @@ int overlay_packet_init_header(struct overlay_interface *interface, struct decod
// a frame destined for one of our local addresses, or broadcast, has arrived. Process it.
int process_incoming_frame(time_ms_t now, struct overlay_interface *interface, struct overlay_frame *f, struct decode_context *context){
IN();
int id = (interface - overlay_interfaces);
switch(f->type)
{
@ -75,16 +76,16 @@ int process_incoming_frame(time_ms_t now, struct overlay_interface *interface, s
process_explain(f);
break;
default:
return WHYF("Support for f->type=0x%x not yet implemented",f->type);
break;
RETURN(WHYF("Support for f->type=0x%x not yet implemented",f->type));
}
return 0;
RETURN(0);
}
// duplicate the frame and queue it
int overlay_forward_payload(struct overlay_frame *f){
IN();
if (f->ttl<=0)
return 0;
RETURN(0);
if (debug&DEBUG_OVERLAYFRAMES)
DEBUGF("Forwarding payload for %s, ttl=%d",
@ -100,7 +101,7 @@ int overlay_forward_payload(struct overlay_frame *f){
to the caller to do as they please */
struct overlay_frame *qf=op_dup(f);
if (!qf)
return WHY("Could not clone frame for queuing");
RETURN(WHY("Could not clone frame for queuing"));
/* Make sure voice traffic gets priority */
if (qf->type==OF_TYPE_DATA_VOICE) {
@ -110,15 +111,16 @@ int overlay_forward_payload(struct overlay_frame *f){
if (overlay_payload_enqueue(qf)) {
op_free(qf);
return WHY("failed to enqueue forwarded payload");
RETURN(WHY("failed to enqueue forwarded payload"));
}
return 0;
RETURN(0);
}
int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, size_t len,
int recvttl, struct sockaddr *recvaddr, size_t recvaddrlen)
{
IN();
/*
This function decodes overlay packets which have been assembled for delivery overy IP networks.
IP based wireless networks have a high, but limited rate of packets that can be sent. In order
@ -171,9 +173,8 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
*/
struct overlay_frame f;
struct decode_context context={
.please_explain=NULL,
};
struct decode_context context;
bzero(&context, sizeof context);
if (len<HEADERFIELDS_LEN)
return WHY("Packet is too short");
@ -207,7 +208,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
if (context.sender && context.sender->reachable==REACHABLE_SELF){
ob_free(b);
return 0;
RETURN(0);
}
while(b->position < b->sizeLimit){
@ -228,11 +229,12 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
/* Decode length of remainder of frame */
int payload_len=ob_get_ui16(b);
if (payload_len <=0) {
/* assume we fell off the end of the packet */
if (payload_len <=0)
/* we fell off the end of the packet? */
break;
}
dump("decoding header", b->bytes + b->position, payload_len);
int next_payload = b->position + payload_len;
/* Always attempt to resolve all of the addresses in a packet, or we could fail to understand an important payload
@ -251,7 +253,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
if (overlay_address_parse(&context, b, &f.broadcast_id, &nexthop)
|| overlay_address_parse(&context, b, NULL, &f.destination)
|| overlay_address_parse(&context, b, NULL, &f.source)){
goto next;
break;
}
// if we can't understand one of the addresses, skip processing the payload
@ -316,7 +318,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
b->position=next_payload;
}
if (context.sender){
if (context.sender && recvaddr){
struct sockaddr_in *addr=(struct sockaddr_in *)recvaddr;
// always update the IP address we heard them from, even if we don't need to use it right now
@ -332,10 +334,11 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
}
}
send_please_explain(&context, my_subscriber, context.sender);
ob_free(b);
send_please_explain(&context, my_subscriber, context.sender);
return 0;
RETURN(0);
}
int overlay_add_selfannouncement(struct decode_context *context, int interface,struct overlay_buffer *b)
@ -362,28 +365,13 @@ int overlay_add_selfannouncement(struct decode_context *context, int interface,s
time_ms_t now = gettime_ms();
/* XXX - BATMAN uses various TTLs, but I think that it may just be better to have all TTL=1,
and have the onward nodes selectively choose which nodes to on-announce. If we prioritise
newly arrived nodes somewhat (or at least reserve some slots for them), then we can still
get the good news travels fast property of BATMAN, but without having to flood in the formal
sense. */
/* Add space for Remaining Frame Size field. This will always be a single byte
for self-announcments as they are always <256 bytes. */
if (overlay_packet_append_header(b, OF_TYPE_SELFANNOUNCE, 1, 1+8+1+SID_SIZE+4+4+1))
return WHY("Could not add self-announcement header");
/* Add next-hop address. Always link-local broadcast for self-announcements */
struct broadcast broadcast_id;
overlay_broadcast_generate_address(&broadcast_id);
if (overlay_broadcast_append(context, b, &broadcast_id))
return WHY("Could not write broadcast address to self-announcement");
/* Add final destination. Always broadcast for self-announcments. */
if (ob_append_byte(b, OA_CODE_PREVIOUS))
return WHY("Could not add self-announcement header");
/* Add our SID to the announcement as sender */
if (overlay_address_append_self(context, &overlay_interfaces[interface], b))
if (overlay_frame_build_header(context, b,
0, OF_TYPE_SELFANNOUNCE, 0, 1,
&broadcast_id, NULL,
NULL, my_subscriber))
return -1;
/* Sequence number range. Based on one tick per millisecond. */

View File

@ -22,10 +22,42 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "overlay_buffer.h"
#include "overlay_packet.h"
int overlay_packet_append_header(struct overlay_buffer *buff, int type, int ttl, int approx_size){
if (ob_append_byte(buff, type)) return -1;
int overlay_frame_build_header(struct decode_context *context, struct overlay_buffer *buff,
int queue, int type, int modifiers, int ttl,
struct broadcast *broadcast, struct subscriber *next_hop,
struct subscriber *destination, struct subscriber *source){
int x = buff->position;
int q_bits = queue;
if (q_bits>0) q_bits--;
if (q_bits>3) q_bits=3;
int type_byte = type|modifiers|q_bits;
if (ttl>64)
ttl=64;
if (ob_append_byte(buff, type_byte)) return -1;
if (ob_append_byte(buff, ttl)) return -1;
return ob_append_rfs(buff, approx_size);
if (ob_append_rfs(buff, 2)) return -1;
if (broadcast){
if (overlay_broadcast_append(context, buff, broadcast)) return -1;
}else{
if (overlay_address_append(context, buff, next_hop)) return -1;
}
if (destination){
if (overlay_address_append(context, buff, destination)) return -1;
}else{
if (ob_append_byte(buff, OA_CODE_PREVIOUS)) return -1;
}
if (overlay_address_append(context, buff, source)) return -1;
dump("written header", buff->bytes + x, buff->position - x);
return 0;
}
int overlay_frame_append_payload(struct decode_context *context, overlay_interface *interface,
@ -53,53 +85,17 @@ int overlay_frame_append_payload(struct decode_context *context, overlay_interfa
dump("payload contents", &p->payload->bytes[0],p->payload->position);
}
/* Build header */
{
int q_bits = p->queue;
if (q_bits>0) q_bits--;
if (q_bits>3) q_bits=3;
int type = p->type|p->modifiers|q_bits;
if (p->ttl>64)
p->ttl=64;
/* Length. This is the fun part, because we cannot calculate how many bytes we need until
we have abbreviated the addresses, and the length encoding we use varies according to the
length encoded. The simple option of running the abbreviations twice won't work because
we rely on context for abbreviating the addresses. So we write it initially and then patch it
after.
*/
int max_len=((SID_SIZE+3)*3+headers->position+p->payload->position);
if (overlay_packet_append_header(headers, type, p->ttl, max_len))
goto cleanup;
}
if (overlay_frame_build_header(context, headers,
p->queue, p->type, p->modifiers, p->ttl,
(p->sendBroadcast?&p->broadcast_id:NULL), next_hop,
p->destination, p->source))
goto cleanup;
int addrs_start=headers->position;
/* Write out addresses as abbreviated as possible */
if (p->sendBroadcast){
overlay_broadcast_append(context, headers, &p->broadcast_id);
}else{
overlay_address_append(context, headers, next_hop);
}
if (p->destination)
overlay_address_append(context, headers,p->destination);
else
ob_append_byte(headers, OA_CODE_PREVIOUS);
if (p->source==my_subscriber){
overlay_address_append_self(context, interface, headers);
}else{
overlay_address_append(context, headers,p->source);
}
int addrs_len=headers->position-addrs_start;
int actual_len=addrs_len+p->payload->position;
int hdr_len=headers->position - (headers->var_length_offset +2);
if (debug&DEBUG_PACKETCONSTRUCTION)
DEBUGF("Patching RFS for actual_len=%d\n",actual_len);
DEBUGF("Patching RFS for actual_len=%d\n",hdr_len + p->payload->position);
ob_set_ui16(headers,headers->var_length_offset,actual_len);
ob_set_ui16(headers,headers->var_length_offset,hdr_len + p->payload->position);
/* Write payload format plus total length of header bits */
if (ob_makespace(b,2+headers->position+p->payload->position)) {

View File

@ -157,16 +157,15 @@ int overlay_rhizome_add_advertisements(struct decode_context *context, int inter
if (slots<1) { RETURN(WHY("No room for node advertisements")); }
if (overlay_packet_append_header(e, OF_TYPE_RHIZOME_ADVERT, 1, (1+11+1+2+RHIZOME_BAR_BYTES)))
RETURN(WHY("could not add rhizome bundle advertisement header"));
/* Stuff in dummy address fields (11 bytes) */
struct broadcast broadcast_id;
overlay_broadcast_generate_address(&broadcast_id);
overlay_broadcast_append(context, e, &broadcast_id);
ob_append_byte(e, OA_CODE_PREVIOUS);
overlay_address_append_self(context, &overlay_interfaces[interface_number], e);
if (overlay_frame_build_header(context, e,
0, OF_TYPE_RHIZOME_ADVERT, 0, 1,
&broadcast_id, NULL,
NULL, my_subscriber))
return -1;
/* Randomly choose whether to advertise manifests or BARs first. */
int skipmanifests=random()&1;
/* Version of rhizome advert block (1 byte):

View File

@ -330,6 +330,8 @@ struct sched_ent{
struct overlay_buffer;
struct overlay_frame;
struct broadcast;
#define STRUCT_SCHED_ENT_UNUSED ((struct sched_ent){NULL, NULL, NULL, NULL, {-1, 0, 0}, 0LL, 0LL, NULL, -1})
extern int overlayMode;
@ -444,7 +446,10 @@ int overlay_frame_append_payload(struct decode_context *context, overlay_interfa
struct overlay_frame *p, struct subscriber *next_hop, struct overlay_buffer *b);
int overlay_packet_init_header(struct overlay_interface *interface, struct decode_context *context,
struct overlay_buffer *buff);
int overlay_packet_append_header(struct overlay_buffer *buff, int type, int ttl, int approx_size);
int overlay_frame_build_header(struct decode_context *context, struct overlay_buffer *buff,
int queue, int type, int modifiers, int ttl,
struct broadcast *broadcast, struct subscriber *next_hop,
struct subscriber *destination, struct subscriber *source);
int overlay_interface_args(const char *arg);
int overlay_rhizome_add_advertisements(struct decode_context *context, int interface_number, struct overlay_buffer *e);
int overlay_add_local_identity(unsigned char *s);