mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-07 19:40:21 +00:00
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:
parent
ea2e55c62c
commit
49e0286b43
@ -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
|
||||||
|
@ -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");
|
||||||
|
@ -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;
|
||||||
|
@ -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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
6
serval.h
6
serval.h
@ -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.
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user