Reduce packet header size for point-to-point links

- new interface.x.point_to_point config
- disable local echo for point to point dummy interfaces
- add ME and YOU sid abbreviation codes after learning other sid
This commit is contained in:
Jeremy Lakeman 2013-07-16 15:16:07 +09:30
parent ea2e55c62c
commit 49e0286b43
8 changed files with 101 additions and 15 deletions

View File

@ -443,6 +443,7 @@ ATOM(bool_t, send_broadcasts, 1, boolean,, "If false, don't send
ATOM(bool_t, default_route, 0, boolean,, "If true, use this interface as a default route") ATOM(bool_t, default_route, 0, boolean,, "If true, use this interface as a default route")
ATOM(bool_t, prefer_unicast, 0, boolean,, "If true, send unicast data as unicast IP packets if available") ATOM(bool_t, prefer_unicast, 0, boolean,, "If true, send unicast data as unicast IP packets if available")
ATOM(bool_t, debug, 0, boolean,, "If true, log details of every outgoing packet") ATOM(bool_t, debug, 0, boolean,, "If true, log details of every outgoing packet")
ATOM(bool_t, point_to_point, 0, boolean,, "If true, assume there will only be two devices on this interface")
ATOM(bool_t, ctsrts, 0, boolean,, "If true, enable CTS/RTS hardware handshaking") ATOM(bool_t, ctsrts, 0, boolean,, "If true, enable CTS/RTS hardware handshaking")
ATOM(int32_t, uartbps, 57600, int32_rs232baudrate,, "Speed of serial UART link speed (which may be different to serial device link speed)") ATOM(int32_t, uartbps, 57600, int32_rs232baudrate,, "Speed of serial UART link speed (which may be different to serial device link speed)")
END_STRUCT END_STRUCT

View File

@ -39,6 +39,8 @@ static struct broadcast bpilist[MAX_BPIS];
#define OA_CODE_SELF 0xff #define OA_CODE_SELF 0xff
#define OA_CODE_PREVIOUS 0xfe #define OA_CODE_PREVIOUS 0xfe
#define OA_CODE_P2P_YOU 0xfd
#define OA_CODE_P2P_ME 0xfc
// each node has 16 slots based on the next 4 bits of a subscriber id // each node has 16 slots based on the next 4 bits of a subscriber id
// each slot either points to another tree node or a struct subscriber. // each slot either points to another tree node or a struct subscriber.
@ -205,21 +207,36 @@ int overlay_address_append(struct decode_context *context, struct overlay_buffer
if (!subscriber) if (!subscriber)
return WHY("No address supplied"); return WHY("No address supplied");
if (context && subscriber==context->sender){ if(context
&& context->packet_version>=1
&& context->interface
&& subscriber == context->interface->other_device
&& context->interface->point_to_point){
if (ob_append_byte(b, OA_CODE_P2P_YOU))
return -1;
}else if(context
&& context->packet_version>=1
&& context->interface
&& !subscriber->send_full
&& subscriber == my_subscriber
&& context->interface->other_device
&& context->interface->point_to_point
&& (!context->encoding_header || !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)) if (ob_append_byte(b, OA_CODE_SELF))
return -1; return -1;
}else if(context && subscriber==context->previous){ }else if(context && subscriber==context->previous){
if (ob_append_byte(b, OA_CODE_PREVIOUS)) if (ob_append_byte(b, OA_CODE_PREVIOUS))
return -1; return -1;
}else{ }else{
int len=SID_SIZE; int len=SID_SIZE;
if (subscriber->send_full){ if (subscriber->send_full){
subscriber->send_full=0; subscriber->send_full=0;
}else{ }else{
len=(subscriber->abbreviate_len+2)/2; len=(subscriber->abbreviate_len+2)/2;
if (subscriber->reachable==REACHABLE_SELF) if (context && context->encoding_header)
len++; len++;
if (len>SID_SIZE) if (len>SID_SIZE)
len=SID_SIZE; len=SID_SIZE;
@ -328,6 +345,26 @@ int overlay_address_parse(struct decode_context *context, struct overlay_buffer
return WHY("Buffer too small"); return WHY("Buffer too small");
switch(len){ switch(len){
case OA_CODE_P2P_YOU:
if (context->interface && context->interface->point_to_point){
*subscriber=my_subscriber;
context->previous=my_subscriber;
}else{
WHYF("Could not resolve address on %s, this isn't a configured point to point link", context->interface->name);
context->invalid_addresses=1;
}
return 0;
case OA_CODE_P2P_ME:
if (context->interface && context->interface->point_to_point && context->interface->other_device){
*subscriber=context->interface->other_device;
context->previous=*subscriber;
}else{
WHYF("Could not resolve address on %s, I don't know who is on the other end of this link!", context->interface->name);
context->invalid_addresses=1;
}
return 0;
case OA_CODE_SELF: case OA_CODE_SELF:
if (!context->sender){ if (!context->sender){
INFO("Could not resolve address, sender has not been set"); INFO("Could not resolve address, sender has not been set");

View File

@ -106,7 +106,12 @@ struct decode_context{
int packet_version; int packet_version;
int encapsulation; int encapsulation;
struct sockaddr_in addr; struct sockaddr_in addr;
int invalid_addresses; union{
// only valid while decoding
int invalid_addresses;
// only valid while encoding
int encoding_header;
};
struct overlay_frame *please_explain; struct overlay_frame *please_explain;
struct subscriber *sender; struct subscriber *sender;
struct subscriber *previous; struct subscriber *previous;

View File

@ -392,6 +392,7 @@ overlay_interface_init(const char *name, struct in_addr src_addr, struct in_addr
interface->state=INTERFACE_STATE_DOWN; interface->state=INTERFACE_STATE_DOWN;
interface->alarm.poll.fd=0; interface->alarm.poll.fd=0;
interface->debug = ifconfig->debug; interface->debug = ifconfig->debug;
interface->point_to_point = ifconfig->point_to_point;
// How often do we announce ourselves on this interface? // How often do we announce ourselves on this interface?
int tick_ms=-1; int tick_ms=-1;
@ -469,12 +470,15 @@ overlay_interface_init(const char *name, struct in_addr src_addr, struct in_addr
interface->address.sin_addr = src_addr; interface->address.sin_addr = src_addr;
interface->broadcast_address.sin_addr = broadcast; interface->broadcast_address.sin_addr = broadcast;
interface->netmask = netmask; interface->netmask = netmask;
interface->local_echo = 1;
if (overlay_interface_init_socket(overlay_interface_count)) if (overlay_interface_init_socket(overlay_interface_count))
return WHY("overlay_interface_init_socket() failed"); return WHY("overlay_interface_init_socket() failed");
}else{ }else{
char read_file[1024]; char read_file[1024];
interface->local_echo = interface->point_to_point?0:1;
strbuf d = strbuf_local(read_file, sizeof read_file); strbuf d = strbuf_local(read_file, sizeof read_file);
strbuf_path_join(d, serval_instancepath(), config.server.interface_path, ifconfig->file, NULL); strbuf_path_join(d, serval_instancepath(), config.server.interface_path, ifconfig->file, NULL);
if (strbuf_overrun(d)) if (strbuf_overrun(d))
@ -643,8 +647,11 @@ static void interface_read_file(struct overlay_interface *interface)
if (config.debug.packetrx) if (config.debug.packetrx)
DEBUG_packet_visualise("Read from dummy interface", packet.payload, packet.payload_length); DEBUG_packet_visualise("Read from dummy interface", packet.payload, packet.payload_length);
if (!should_drop(interface, packet.dst_addr)){ 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));
}else{
if (packetOkOverlay(interface, packet.payload, packet.payload_length, -1, if (packetOkOverlay(interface, packet.payload, packet.payload_length, -1,
(struct sockaddr*)&packet.src_addr, sizeof(packet.src_addr))<0) { (struct sockaddr*)&packet.src_addr, sizeof(packet.src_addr))<0) {
if (config.debug.rejecteddata) { if (config.debug.rejecteddata) {
@ -653,8 +660,7 @@ static void interface_read_file(struct overlay_interface *interface)
dump("the malformed packet",packet.payload,packet.payload_length); dump("the malformed packet",packet.payload,packet.payload_length);
} }
} }
}else if (config.debug.packetrx) }
DEBUGF("Ignoring packet addressed to %s:%d", inet_ntoa(packet.dst_addr.sin_addr), ntohs(packet.dst_addr.sin_port));
} }
} }

View File

@ -47,9 +47,10 @@ int overlay_packet_init_header(int packet_version, int encapsulation,
return -1; return -1;
if (ob_append_byte(buff, encapsulation)) if (ob_append_byte(buff, encapsulation))
return -1; return -1;
context->encoding_header=1;
if (overlay_address_append(context, buff, my_subscriber)) if (overlay_address_append(context, buff, my_subscriber))
return -1; return -1;
context->encoding_header=0;
context->sender = my_subscriber; context->sender = my_subscriber;
int flags=0; int flags=0;
@ -258,7 +259,11 @@ int parseEnvelopeHeader(struct decode_context *context, struct overlay_interface
IN(); IN();
time_ms_t now = gettime_ms(); time_ms_t now = gettime_ms();
context->interface = interface;
context->sender_interface = 0;
context->packet_version = ob_get(buffer); context->packet_version = ob_get(buffer);
if (context->packet_version < 0 || context->packet_version > SUPPORTED_PACKET_VERSION) if (context->packet_version < 0 || context->packet_version > SUPPORTED_PACKET_VERSION)
RETURN(WHYF("Packet version %d not recognised.", context->packet_version)); RETURN(WHYF("Packet version %d not recognised.", context->packet_version));
@ -271,9 +276,6 @@ int parseEnvelopeHeader(struct decode_context *context, struct overlay_interface
int packet_flags = ob_get(buffer); int packet_flags = ob_get(buffer);
context->sender_interface = 0;
context->interface = interface;
int sender_seq = -1; int sender_seq = -1;
if (packet_flags & PACKET_INTERFACE) if (packet_flags & PACKET_INTERFACE)
@ -293,6 +295,11 @@ int parseEnvelopeHeader(struct decode_context *context, struct overlay_interface
if (context->sender->max_packet_version < context->packet_version) if (context->sender->max_packet_version < context->packet_version)
context->sender->max_packet_version = context->packet_version; context->sender->max_packet_version = context->packet_version;
if (interface->point_to_point && interface->other_device!=context->sender){
INFOF("Established point to point link with %s on %s", alloca_tohex_sid(context->sender->sid), interface->name);
context->interface->other_device = context->sender;
}
// TODO probe unicast links when we detect an address change. // TODO probe unicast links when we detect an address change.
// if this is a dummy announcement for a node that isn't in our routing table // if this is a dummy announcement for a node that isn't in our routing table

View File

@ -271,11 +271,13 @@ overlay_init_packet(struct outgoing_packet *packet, struct subscriber *destinati
int unicast, int packet_version, int unicast, int packet_version,
overlay_interface *interface, struct sockaddr_in addr){ overlay_interface *interface, struct sockaddr_in addr){
packet->interface = interface; packet->interface = interface;
packet->context.interface = interface;
packet->i = (interface - overlay_interfaces); packet->i = (interface - overlay_interfaces);
packet->dest=addr; packet->dest=addr;
packet->buffer=ob_new(); packet->buffer=ob_new();
packet->seq=-1; packet->seq=-1;
packet->packet_version = packet_version; packet->packet_version = packet_version;
packet->context.packet_version = packet_version;
if (unicast) if (unicast)
packet->unicast_subscriber = destination; packet->unicast_subscriber = destination;

View File

@ -403,7 +403,13 @@ typedef struct overlay_interface {
char prefer_unicast; char prefer_unicast;
// can we use this interface for routes to addresses in other subnets? // can we use this interface for routes to addresses in other subnets?
int default_route; int default_route;
// should we log more debug info on this interace? eg hex dumps of packets
char debug; char debug;
char local_echo;
// can we assume there will only be two devices on this interface?
char point_to_point;
struct subscriber *other_device;
/* Number of milli-seconds per tick for this interface, which is basically related to the /* Number of milli-seconds per tick for this interface, which is basically related to the
the typical TX range divided by the maximum expected speed of nodes in the network. the typical TX range divided by the maximum expected speed of nodes in the network.

View File

@ -185,6 +185,28 @@ test_mismatched_encap() {
tfw_cat --stdout --stderr tfw_cat --stdout --stderr
} }
doc_single_p2p="Start 2 instances on a point to point link"
setup_single_p2p() {
setup_servald
assert_no_servald_processes
foreach_instance +A +B create_single_identity
foreach_instance +A +B add_interface 1
foreach_instance +A +B \
executeOk_servald config \
set interfaces.1.debug 1 \
set interfaces.1.encapsulation single \
set interfaces.1.point_to_point on
foreach_instance +A +B start_routing_instance
}
test_single_p2p() {
wait_until path_exists +A +B
wait_until path_exists +B +A
assertGrep "$instance_servald_log" 'Established point to point link'
set_instance +A
executeOk_servald mdp ping --timeout=3 $SIDB 1
tfw_cat --stdout --stderr
}
doc_slip_encoding="Test slip encoding and decoding" doc_slip_encoding="Test slip encoding and decoding"
setup_slip_encoding() { setup_slip_encoding() {
setup_servald setup_servald