Rearrange interface config to support unicast settings

This commit is contained in:
Jeremy Lakeman 2015-03-16 12:22:38 +10:30
parent 4b234fbfbd
commit f7dbe06836
15 changed files with 203 additions and 230 deletions

View File

@ -1030,10 +1030,10 @@ int vld_network_interface(const struct cf_om_node *parent, struct config_network
int nodei_drop=-1;
if (nifp->drop_packets)
nodei_drop=cf_om_get_child(parent, "drop_packets", NULL);
if (nifp->drop_broadcasts)
nodei_drop=cf_om_get_child(parent, "drop_broadcasts", NULL);
if (nifp->drop_unicasts)
nodei_drop=cf_om_get_child(parent, "drop_unicasts", NULL);
if (nifp->broadcast.drop)
nodei_drop=cf_om_get_child(parent, "broadcast", NULL);
if (nifp->unicast.drop)
nodei_drop=cf_om_get_child(parent, "unicast", NULL);
if (nodei_drop!=-1){
int nodei_socket_type=cf_om_get_child(parent, "socket_type", NULL);
cf_warn_incompatible(parent->nodv[nodei_socket_type], parent->nodv[nodei_drop]);

View File

@ -327,18 +327,17 @@ ATOM(uint32_t, uid, 0, uint32_nonzero,, "Allowed UID for mon
END_STRUCT
STRUCT(mdp_iftype)
ATOM(int32_t, tick_ms, -1, int32_nonneg,, "Tick interval")
ATOM(int32_t, mtu, 1200, int32_nonneg,, "Maximum transmision size")
ATOM(int32_t, tick_ms, -1, int32_nonneg,, "Keep alive interval")
ATOM(int32_t, packet_interval, -1, int32_nonneg,, "Minimum interval between packets in microseconds")
ATOM(int32_t, reachable_timeout_ms, -1, int32_nonneg,, "Inactivity timeout after which node considered unreachable")
ATOM(bool_t, drop, 0, boolean,, "If true, drop all incoming packets")
ATOM(bool_t, send, 1, boolean,, "If false, don't send any packets")
ATOM(bool_t, route, 1, boolean,, "If false, do not advertise any links")
ATOM(short, encapsulation, ENCAP_OVERLAY, encapsulation,, "Type of packet encapsulation")
END_STRUCT
ARRAY(mdp_iftypelist, NO_DUPLICATES)
KEY_ATOM(short, interface_type)
VALUE_SUB_STRUCT(mdp_iftype)
END_ARRAY(5)
STRUCT(mdp)
SUB_STRUCT(mdp_iftypelist, iftype,)
ATOM(bool_t, enable_inet, 0, boolean,, "If true, allow mdp clients to connect over loopback UDP")
STRING(256, filter_rules_path, "", str_nonempty,, "Path of file containing MDP filter rules, either absolute or relative to instance directory")
END_STRUCT
@ -449,20 +448,16 @@ STRUCT(network_interface, VALIDATOR(vld_network_interface))
ATOM(bool_t, exclude, 0, boolean,, "If true, do not use matching interfaces")
ATOM(struct pattern_list, match, PATTERN_LIST_EMPTY, pattern_list,, "Names that match network interface")
ATOM(short, socket_type, SOCK_UNSPECIFIED, socket_type,, "Type of network socket; stream, dgram or file")
ATOM(short, encapsulation, ENCAP_OVERLAY, encapsulation,, "Type of packet encapsulation")
STRING(256, file, "", str_nonempty,, "Path of interface file, absolute or relative to server.interface_path")
ATOM(struct in_addr, dummy_address, hton_in_addr(INADDR_LOOPBACK), in_addr,, "Dummy interface address")
ATOM(struct in_addr, dummy_netmask, hton_in_addr(0xFFFFFF00), in_addr,, "Dummy interface netmask")
ATOM(uint16_t, port, PORT_DNA, uint16_nonzero,, "Port number for network interface")
ATOM(bool_t, drop_broadcasts, 0, boolean,, "If true, drop all incoming broadcast packets")
ATOM(bool_t, drop_unicasts, 0, boolean,, "If true, drop all incoming unicast packets")
ATOM(uint16_t, drop_packets, 0, uint16_nonzero,, "Percentage of incoming packets that should be dropped for testing purposes")
ATOM(short, type, OVERLAY_INTERFACE_WIFI, interface_type,, "Type of network interface")
ATOM(short, radiotype, RADIO_TYPE_RFD900, radio_type,, "Type of packet radio interface")
SUB_STRUCT(mdp_iftype, mdp,)
ATOM(bool_t, send_broadcasts, 1, boolean,, "If false, don't send any broadcast packets")
SUB_STRUCT(mdp_iftype, broadcast,)
SUB_STRUCT(mdp_iftype, unicast,)
ATOM(bool_t, default_route, 0, boolean,, "If true, use this interface as a default route")
ATOM(bool_t, dont_route, 0, boolean,, "If true, do not advertise any links discovered on this interface")
ATOM(bool_t, prefer_unicast, 1, boolean,, "If true, send data as unicast IP packets if available")
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")

View File

@ -110,7 +110,7 @@ void interface_state_html(struct strbuf *b, struct overlay_interface *interface)
strbuf_puts(b, "Interface Down");
return;
}
switch(interface->type){
switch(interface->ifconfig.type){
case OVERLAY_INTERFACE_PACKETRADIO:
strbuf_puts(b, "Type: Packet Radio<br>");
radio_link_state_html(b, interface);
@ -125,7 +125,7 @@ void interface_state_html(struct strbuf *b, struct overlay_interface *interface)
case OVERLAY_INTERFACE_UNKNOWN:
strbuf_puts(b, "Type: Unknown<br>");
}
switch(interface->socket_type){
switch(interface->ifconfig.socket_type){
case SOCK_STREAM:
strbuf_puts(b, "Socket: Stream<br>");
break;
@ -215,7 +215,7 @@ error:
overlay_interface * overlay_interface_get_default(){
int i;
for (i=0;i<OVERLAY_MAX_INTERFACES;i++){
if (overlay_interfaces[i].state==INTERFACE_STATE_UP && overlay_interfaces[i].default_route)
if (overlay_interfaces[i].state==INTERFACE_STATE_UP && overlay_interfaces[i].ifconfig.default_route)
return &overlay_interfaces[i];
}
return NULL;
@ -253,7 +253,7 @@ overlay_interface * overlay_interface_find(struct in_addr addr, int return_defau
}
// check if this is a default interface
if (return_default && overlay_interfaces[i].default_route) {
if (return_default && overlay_interfaces[i].ifconfig.default_route) {
ret=&overlay_interfaces[i];
if (config.debug.overlayinterfaces) {
DEBUGF("in_addr=0x%08x is being deemed to default-route interface #%d (interface mask=0x%08x, interface addr=0x%08x)\n",
@ -314,8 +314,8 @@ int overlay_interface_compare(overlay_interface *one, overlay_interface *two)
{
if (one==two)
return 0;
int p1 = interface_type_priority(one->type);
int p2 = interface_type_priority(two->type);
int p1 = interface_type_priority(one->ifconfig.type);
int p2 = interface_type_priority(two->ifconfig.type);
if (p1<p2)
return -1;
if (p2<p1)
@ -414,7 +414,7 @@ overlay_interface_init_socket(overlay_interface *interface)
But there may be some platforms that need some other combination for everything to work.
*/
overlay_interface_init_any(interface->port);
overlay_interface_init_any(interface->ifconfig.port);
interface->alarm.poll.fd = overlay_bind_socket(&interface->address);
@ -432,35 +432,15 @@ overlay_interface_init_socket(overlay_interface *interface)
return 0;
}
int overlay_interface_configure(struct overlay_interface *interface, const struct config_network_interface *ifconfig)
int overlay_destination_configure(struct network_destination *dest, const struct config_mdp_iftype *ifconfig)
{
// copy ifconfig values
interface->drop_broadcasts = ifconfig->drop_broadcasts;
interface->drop_unicasts = ifconfig->drop_unicasts;
interface->drop_packets = ifconfig->drop_packets;
interface->type = ifconfig->type;
interface->send_broadcasts = ifconfig->send_broadcasts;
interface->dont_route = ifconfig->dont_route;
interface->prefer_unicast = ifconfig->prefer_unicast;
interface->default_route = ifconfig->default_route;
interface->destination->encapsulation = ifconfig->encapsulation;
interface->port = ifconfig->port;
interface->socket_type = ifconfig->socket_type;
interface->uartbps = ifconfig->uartbps;
interface->ctsrts = ifconfig->ctsrts;
interface->point_to_point = ifconfig->point_to_point;
interface->debug = ifconfig->debug;
/* Pick a reasonable default MTU.
This will ultimately get tuned by the bandwidth and other properties of the interface */
interface->mtu = 1200;
dest->ifconfig = *ifconfig;
// How often do we announce ourselves on this interface?
int tick_ms=-1;
int packet_interval=-1;
int reachable_timeout_ms = -1;
// hard coded defaults:
switch (ifconfig->type) {
switch(dest->interface->ifconfig.type){
case OVERLAY_INTERFACE_PACKETRADIO:
tick_ms = 15000;
packet_interval = 1000;
@ -478,44 +458,46 @@ int overlay_interface_configure(struct overlay_interface *interface, const struc
packet_interval = 100;
break;
}
// configurable defaults per interface
{
int i = config_mdp_iftypelist__get(&config.mdp.iftype, &ifconfig->type);
if (i != -1){
if (config.mdp.iftype.av[i].value.tick_ms>=0)
tick_ms = config.mdp.iftype.av[i].value.tick_ms;
if (config.mdp.iftype.av[i].value.packet_interval>=0)
packet_interval=config.mdp.iftype.av[i].value.packet_interval;
if (config.mdp.iftype.av[i].value.reachable_timeout_ms >= 0)
reachable_timeout_ms = config.mdp.iftype.av[i].value.reachable_timeout_ms;
}
}
// specific value for this interface
if (ifconfig->mdp.tick_ms>=0)
tick_ms = ifconfig->mdp.tick_ms;
if (ifconfig->mdp.packet_interval>=0)
packet_interval=ifconfig->mdp.packet_interval;
if (ifconfig->mdp.reachable_timeout_ms >= 0)
reachable_timeout_ms = ifconfig->mdp.reachable_timeout_ms;
if (packet_interval<0)
return WHYF("Invalid packet interval %d specified for interface %s", packet_interval, interface->name);
if (packet_interval==0){
INFOF("Interface %s is not sending any traffic!", interface->name);
tick_ms=0;
}else if (!interface->send_broadcasts){
INFOF("Interface %s is not sending any broadcast traffic!", interface->name);
}else if (tick_ms==0)
INFOF("Interface %s is running tickless", interface->name);
if (dest->ifconfig.tick_ms<0)
dest->ifconfig.tick_ms = tick_ms;
if (dest->ifconfig.packet_interval<0)
dest->ifconfig.packet_interval = packet_interval;
if (dest->ifconfig.packet_interval<0)
return WHYF("Invalid packet interval %d specified for destination",
dest->ifconfig.packet_interval);
if (dest->ifconfig.packet_interval==0){
INFOF("Destination is not sending any traffic!");
dest->ifconfig.tick_ms=0;
}else if (!dest->ifconfig.send){
INFOF("Destination is not sending any traffic!");
}else if (dest->ifconfig.tick_ms==0)
INFOF("Destination is running tickless");
if (tick_ms<0)
return WHYF("No tick interval specified for interface %s", interface->name);
if (dest->ifconfig.tick_ms<0)
return WHYF("No tick interval specified for destination");
if (dest->ifconfig.reachable_timeout_ms<0)
dest->ifconfig.reachable_timeout_ms = tick_ms>0 ? tick_ms * 5 : 2500;
if (dest->ifconfig.mtu < 400)
dest->ifconfig.encapsulation=ENCAP_SINGLE;
limit_init(&dest->transfer_limit, dest->ifconfig.packet_interval);
return 0;
}
interface->destination->tick_ms = tick_ms;
interface->destination->reachable_timeout_ms = reachable_timeout_ms >= 0 ? reachable_timeout_ms : tick_ms > 0 ? tick_ms * 5 : 2500;
limit_init(&interface->destination->transfer_limit, packet_interval);
int overlay_interface_configure(struct overlay_interface *interface, const struct config_network_interface *ifconfig)
{
// copy ifconfig values
interface->ifconfig = *ifconfig;
overlay_destination_configure(interface->destination, &interface->ifconfig.broadcast);
if (ifconfig->socket_type==SOCK_STREAM)
interface->ifconfig.unicast.send=0;
return 0;
}
@ -569,7 +551,7 @@ overlay_interface_init(const char *name, struct socket_address *addr,
switch(ifconfig->socket_type){
case SOCK_DGRAM:
if (ifconfig->drop_broadcasts || ifconfig->drop_unicasts || ifconfig->drop_packets)
if (ifconfig->broadcast.drop || ifconfig->unicast.drop || ifconfig->drop_packets)
FATALF("Invalid interface definition. We only support dropping packets on dummy file interfaces");
if (netmask)
interface->netmask = netmask->inet.sin_addr;
@ -590,7 +572,7 @@ overlay_interface_init(const char *name, struct socket_address *addr,
case SOCK_FILE:
{
char read_file[1024];
interface->local_echo = interface->point_to_point?0:1;
interface->local_echo = ifconfig->point_to_point?0:1;
if (!FORMF_SERVAL_TMP_PATH(read_file, "%s/%s", config.server.interface_path, ifconfig->file))
return -1;
if ((interface->alarm.poll.fd = open(read_file, O_APPEND|O_RDWR)) == -1) {
@ -694,21 +676,21 @@ struct file_packet{
};
static int should_drop(struct overlay_interface *interface, struct socket_address *addr){
if (interface->drop_packets>=100)
if (interface->ifconfig.drop_packets>=100)
return 1;
if (cmp_sockaddr(addr, &interface->address)==0){
if (interface->drop_unicasts)
if (interface->ifconfig.unicast.drop)
return 1;
}else if (cmp_sockaddr(addr, &interface->destination->address)==0){
if (interface->drop_broadcasts)
if (interface->ifconfig.broadcast.drop)
return 1;
}else
return 1;
if (interface->drop_packets <= 0)
if (interface->ifconfig.drop_packets <= 0)
return 0;
if (rand()%100 >= interface->drop_packets)
if (rand()%100 >= interface->ifconfig.drop_packets)
return 0;
return 1;
}
@ -812,23 +794,23 @@ static void overlay_interface_poll(struct sched_ent *alarm)
alarm->alarm=-1;
if (interface->state==INTERFACE_STATE_UP
&& interface->destination->tick_ms>0
&& interface->send_broadcasts
&& interface->destination->ifconfig.tick_ms>0
&& interface->destination->ifconfig.send
&& !radio_link_is_busy(interface)){
if (now >= interface->destination->last_tx+interface->destination->tick_ms)
if (now >= interface->destination->last_tx+interface->destination->ifconfig.tick_ms)
overlay_send_tick_packet(interface->destination);
time_ms_t interval = interface->destination->tick_ms;
time_ms_t interval = interface->destination->ifconfig.tick_ms;
// only tick every 5s if we have no neighbours here
if (interval < 5000 && !link_interface_has_neighbours(interface))
interval = 5000;
alarm->alarm=interface->destination->last_tx+interval;
alarm->deadline=alarm->alarm+interface->destination->tick_ms/2;
alarm->deadline=alarm->alarm+interface->destination->ifconfig.tick_ms/2;
}
switch(interface->socket_type){
switch(interface->ifconfig.socket_type){
case SOCK_STREAM:
radio_link_tx(interface);
return;
@ -845,14 +827,14 @@ static void overlay_interface_poll(struct sched_ent *alarm)
if (alarm->alarm!=-1 && interface->state==INTERFACE_STATE_UP) {
if (alarm->alarm < now) {
alarm->alarm = now;
alarm->deadline = alarm->alarm + interface->destination->tick_ms / 2;
alarm->deadline = alarm->alarm + interface->destination->ifconfig.tick_ms / 2;
}
schedule(alarm);
}
}
if (alarm->poll.revents & POLLOUT){
switch(interface->socket_type){
switch(interface->ifconfig.socket_type){
case SOCK_STREAM:
radio_link_tx(interface);
return;
@ -865,7 +847,7 @@ static void overlay_interface_poll(struct sched_ent *alarm)
}
if (alarm->poll.revents & POLLIN) {
switch(interface->socket_type){
switch(interface->ifconfig.socket_type){
case SOCK_DGRAM:
interface_read_dgram(interface);
break;
@ -954,14 +936,14 @@ int overlay_broadcast_ensemble(struct network_destination *destination, struct o
return WHYF("Cannot send to interface %s as it is down", interface->name);
}
if (config.debug.overlayinterfaces || interface->debug)
if (config.debug.overlayinterfaces || interface->ifconfig.debug)
DEBUGF("Sending %zu byte overlay frame on %s to %s [%s]",
(size_t)len, interface->name, alloca_socket_address(&destination->address),
alloca_tohex(bytes, len>64?64:len));
interface->tx_count++;
switch(interface->socket_type){
switch(interface->ifconfig.socket_type){
case SOCK_STREAM:
return radio_link_queue_packet(interface, buffer);
@ -1145,7 +1127,7 @@ void overlay_interface_discover(struct sched_ent *alarm)
}
unsigned j;
for (j = 0; j < OVERLAY_MAX_INTERFACES; j++){
if (overlay_interfaces[j].socket_type == ifconfig->socket_type &&
if (overlay_interfaces[j].ifconfig.socket_type == ifconfig->socket_type &&
strcasecmp(overlay_interfaces[j].name, ifconfig->file) == 0 &&
overlay_interfaces[j].state==INTERFACE_STATE_DETECTING){
overlay_interfaces[j].state=INTERFACE_STATE_UP;

View File

@ -47,9 +47,8 @@ struct network_destination {
char packet_version;
// should we aggregate packets, or send one at a time
char encapsulation;
struct config_mdp_iftype ifconfig;
// time last packet was sent
time_ms_t last_tx;
@ -64,25 +63,6 @@ struct network_destination {
// rate limit for outgoing packets
struct limit_state transfer_limit;
/* 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. This means that short-range communications
* has a higher bandwidth requirement than long-range communications because
* the tick interval has to be shorter to still allow fast-convergence time
* to allow for mobility.
*
* For wifi (nominal range 100m) it is usually 500ms.
* For ~100K ISM915MHz (nominal range 1000m) it will probably be about 5000ms.
* For ~10K ISM915MHz (nominal range ~3000m) it will probably be about 15000ms.
*
* These figures will be refined over time, and we will allow people to set
* them per-interface.
*/
unsigned tick_ms;
// Number of milliseconds of no packets until we assume the link is dead.
unsigned reachable_timeout_ms;
};
typedef struct overlay_interface {
@ -97,33 +77,12 @@ typedef struct overlay_interface {
struct radio_link_state *radio_link_state;
// copy of ifconfig flags
uint16_t drop_packets;
char drop_broadcasts;
char drop_unicasts;
int port;
int type;
int socket_type;
char send_broadcasts;
char dont_route;
char prefer_unicast;
/* Not necessarily the real MTU, but the largest frame size we are willing to TX.
For radio links the actual maximum and the maximum that is likely to be delivered reliably are
potentially two quite different values. */
int mtu;
// can we use this interface for routes to addresses in other subnets?
int default_route;
// should we log more debug info on this interace? eg hex dumps of packets
char debug;
struct config_network_interface ifconfig;
char local_echo;
unsigned int uartbps; // set serial port speed (which might be different from link speed)
int ctsrts; // enabled hardware flow control if non-zero
struct network_destination *destination;
// can we assume that we will only receive packets from one device?
char point_to_point;
struct subscriber *other_device;
// the actual address of the interface.
@ -151,8 +110,12 @@ int set_destination_ref(struct network_destination **ptr, struct network_destina
DECLARE_ALARM(overlay_interface_discover);
struct config_mdp_iftype;
int overlay_destination_configure(struct network_destination *dest, const struct config_mdp_iftype *ifconfig);
struct config_network_interface;
int overlay_interface_configure(struct overlay_interface *interface, const struct config_network_interface *ifconfig);
int
overlay_interface_init(const char *name, struct socket_address *addr,
struct socket_address *netmask,

View File

@ -174,14 +174,10 @@ overlay_mdp_service_probe(struct internal_mdp_header *header, struct overlay_buf
}
int overlay_send_probe(struct subscriber *peer, struct network_destination *destination, int queue){
// never send unicast probes over a stream interface
if (destination->interface->socket_type==SOCK_STREAM)
return 0;
time_ms_t now = gettime_ms();
// though unicast probes don't typically use the same network destination,
// we should still try to throttle when we can
if (destination->last_tx + destination->tick_ms > now)
if (destination->last_tx + destination->ifconfig.tick_ms > now)
return -1;
// TODO enhance overlay_send_frame to support pre-supplied network destinations

View File

@ -49,7 +49,7 @@ int overlay_packet_init_header(int packet_version, int encapsulation,
ob_append_byte(buff, packet_version);
ob_append_byte(buff, encapsulation);
if ( context->interface->point_to_point
if ( context->interface->ifconfig.point_to_point
&& context->interface->other_device
&& packet_version>=1
)
@ -262,7 +262,7 @@ int parseEnvelopeHeader(struct decode_context *context, struct overlay_interface
IN();
context->interface = interface;
if (interface->point_to_point && interface->other_device)
if (interface->ifconfig.point_to_point && interface->other_device)
context->point_to_point_device = interface->other_device;
context->sender_interface = 0;
@ -302,7 +302,7 @@ int parseEnvelopeHeader(struct decode_context *context, struct overlay_interface
if (context->packet_version > context->sender->max_packet_version)
context->sender->max_packet_version=context->packet_version;
if (interface->point_to_point && interface->other_device!=context->sender){
if (interface->ifconfig.point_to_point && interface->other_device!=context->sender){
INFOF("Established point to point link with %s on %s", alloca_tohex_sid_t(context->sender->sid), interface->name);
context->point_to_point_device = context->interface->other_device = context->sender;
}
@ -374,7 +374,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
the source having received the frame from elsewhere.
*/
if (config.debug.packetrx || interface->debug) {
if (config.debug.packetrx || interface->ifconfig.debug) {
DEBUGF("Received on %s, len %d", interface->name, (int)len);
DEBUG_packet_visualise("Received packet",packet,len);
}

View File

@ -31,7 +31,7 @@ int overlay_packetradio_setup_port(overlay_interface *interface)
if (tcgetattr(interface->alarm.poll.fd, &t))
WHY_perror("Failed to get terminal parameters");
speed_t baud_rate;
switch(interface->uartbps){
switch(interface->ifconfig.uartbps){
case 0: baud_rate = B0; break;
case 50: baud_rate = B50; break;
case 75: baud_rate = B75; break;
@ -77,10 +77,10 @@ int overlay_packetradio_setup_port(overlay_interface *interface)
// Enable/disable CTS/RTS flow control
#ifndef CNEW_RTSCTS
if (interface->ctsrts) t.c_cflag |= CRTSCTS;
if (interface->ifconfig.ctsrts) t.c_cflag |= CRTSCTS;
else t.c_cflag &= ~CRTSCTS;
#else
if (interface->ctsrts) t.c_cflag |= CNEW_RTSCTS;
if (interface->ifconfig.ctsrts) t.c_cflag |= CNEW_RTSCTS;
else t.c_cflag &= ~CNEW_RTSCTS;
#endif

View File

@ -241,9 +241,9 @@ 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);
ob_limitsize(packet->buffer, destination->ifconfig.mtu);
int i = destination->interface - overlay_interfaces;
if (overlay_packet_init_header(packet_version, destination->encapsulation,
if (overlay_packet_init_header(packet_version, destination->ifconfig.encapsulation,
&packet->context, packet->buffer,
destination->unicast,
i, packet->seq) == -1
@ -355,7 +355,7 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim
if (frame->delay_until > now)
goto skip;
if (packet->buffer && packet->destination->encapsulation==ENCAP_SINGLE)
if (packet->buffer && packet->destination->ifconfig.encapsulation==ENCAP_SINGLE)
goto skip;
// quickly skip payloads that have no chance of fitting
@ -423,7 +423,7 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim
if (radio_link_is_busy(dest->interface))
continue;
// can we send a packet on this interface now?
// can we send a packet to this destination now?
if (limit_is_allowed(&dest->transfer_limit))
continue;
@ -466,7 +466,7 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim
if (frame->packet_version<1 || frame->resend<=0 || packet->seq==-1)
will_retransmit=0;
if (overlay_frame_append_payload(&packet->context, packet->destination->encapsulation, frame,
if (overlay_frame_append_payload(&packet->context, packet->destination->ifconfig.encapsulation, frame,
frame->destinations[destination_index].next_hop, packet->buffer, will_retransmit)){
// payload was not queued, delay the next attempt slightly
frame->delay_until = now + 5;

View File

@ -276,7 +276,7 @@ int radio_link_tx(struct overlay_interface *interface)
unschedule(&interface->alarm);
interface->alarm.alarm = 0;
time_ms_t next_tick = interface->destination->last_tx+interface->destination->tick_ms;
time_ms_t next_tick = interface->destination->last_tx+interface->destination->ifconfig.tick_ms;
time_ms_t now = gettime_ms();
while(1){

View File

@ -19,12 +19,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <assert.h>
#include "serval.h"
#include "conf.h"
#include "overlay_address.h"
#include "overlay_buffer.h"
#include "overlay_interface.h"
#include "overlay_packet.h"
#include "str.h"
#include "conf.h"
#include "keyring.h"
#include "server.h"
#include "mdp_client.h"
@ -199,13 +199,13 @@ struct network_destination * create_unicast_destination(struct socket_address *a
}
if (addr->addr.sa_family == AF_INET && (addr->inet.sin_addr.s_addr==0 || addr->inet.sin_port==0))
return NULL;
if (!interface->ifconfig.unicast.send)
return NULL;
struct network_destination *ret = new_destination(interface);
if (ret){
ret->encapsulation = ENCAP_OVERLAY;
ret->address = *addr;
ret->unicast = 1;
ret->tick_ms = interface->destination->tick_ms;
overlay_destination_configure(ret, &interface->ifconfig.unicast);
}
return ret;
}
@ -557,8 +557,9 @@ static int append_link(struct subscriber *subscriber, void *context)
if (subscriber->identity)
keyring_send_unlock(subscriber);
if (best_link && best_link->destination && best_link->destination->interface->dont_route){
// don't talk about links across interfaces with dont_route
if (best_link && best_link->destination
&& !best_link->destination->ifconfig.route){
// never mention links we shouldn't advertise
state->next_update = TIME_MS_NEVER_WILL;
}else{
if (state->next_update - 20 <= now){
@ -884,7 +885,7 @@ static int send_neighbour_link(struct neighbour *n)
n->best_link->ack_counter = ACK_WINDOW;
n->last_update = now;
}
n->next_neighbour_update = n->last_update + n->best_link->interface->destination->tick_ms;
n->next_neighbour_update = n->last_update + n->best_link->interface->destination->ifconfig.tick_ms;
if (config.debug.ack)
DEBUGF("Next update for %s in %"PRId64"ms", alloca_tohex_sid_t(n->subscriber->sid), n->next_neighbour_update - gettime_ms());
OUT();
@ -908,11 +909,11 @@ static int link_send_neighbours()
struct link_out *out = n->out_links;
while(out){
if (out->destination->tick_ms>0 && out->destination->unicast){
if (out->destination->last_tx + out->destination->tick_ms < now)
if (out->destination->ifconfig.tick_ms>0 && out->destination->unicast){
if (out->destination->last_tx + out->destination->ifconfig.tick_ms < now)
overlay_send_tick_packet(out->destination);
if (out->destination->last_tx + out->destination->tick_ms < ALARM_STRUCT(link_send).alarm)
ALARM_STRUCT(link_send).alarm = out->destination->last_tx + out->destination->tick_ms;
if (out->destination->last_tx + out->destination->ifconfig.tick_ms < ALARM_STRUCT(link_send).alarm)
ALARM_STRUCT(link_send).alarm = out->destination->last_tx + out->destination->ifconfig.tick_ms;
}
out=out->_next;
}
@ -995,7 +996,7 @@ struct link_in * get_neighbour_link(struct neighbour *neighbour, struct overlay_
{
struct link_in *link = neighbour->links;
if (unicast){
if (interface->prefer_unicast)
if (interface->ifconfig.prefer_unicast)
unicast=1;
else
unicast=-1;
@ -1071,26 +1072,35 @@ int link_add_destinations(struct overlay_frame *frame)
struct neighbour *neighbour = neighbours;
for(;neighbour;neighbour = neighbour->_next){
// TODO, send broadcast packets to neighbours before link establishment?
if (neighbour->subscriber->reachable&REACHABLE_DIRECT){
struct network_destination *dest = neighbour->subscriber->destination;
// TODO move packet version flag to destination struct?
if (frame->packet_version > neighbour->subscriber->max_packet_version)
frame->packet_version = neighbour->subscriber->max_packet_version;
if (!dest->unicast){
if (!dest->interface->send_broadcasts)
continue;
// make sure we only add each broadcast interface once
unsigned id = dest->interface - overlay_interfaces;
if (added_interface[id]){
if (added_interface[id])
continue;
}
added_interface[id]=1;
}
if (frame->destination_count < MAX_PACKET_DESTINATIONS)
frame->destinations[frame->destination_count++].destination=add_destination_ref(dest);
}else if(!(neighbour->subscriber->reachable & REACHABLE)){
// send broadcast packets to neighbours before link establishment
struct link_out *out = neighbour->out_links;
time_ms_t now = gettime_ms();
while(out){
if (out->timeout>=now && frame->destination_count < MAX_PACKET_DESTINATIONS){
unsigned dest = frame->destination_count++;
frame->destinations[dest].destination = add_destination_ref(out->destination);
}
out = out->_next;
}
}
}
}
@ -1175,23 +1185,29 @@ int link_unicast_ack(struct subscriber *UNUSED(subscriber), struct overlay_inter
static struct link_out *create_out_link(struct neighbour *neighbour, overlay_interface *interface, struct socket_address *addr, char unicast)
{
struct network_destination *dest = NULL;
if (unicast)
dest = create_unicast_destination(addr, interface);
else
dest = add_destination_ref(interface->destination);
if (!dest)
return NULL;
struct link_out *ret=emalloc_zero(sizeof(struct link_out));
if (ret){
ret->_next=neighbour->out_links;
neighbour->out_links=ret;
if (unicast)
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);
time_ms_t now = gettime_ms();
ret->timeout = now + ret->destination->tick_ms * 3;
update_alarm(__WHENCE__, now + 5);
}
if (!ret)
return NULL;
ret->_next=neighbour->out_links;
neighbour->out_links=ret;
ret->destination=dest;
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);
time_ms_t now = gettime_ms();
ret->timeout = now + ret->destination->ifconfig.tick_ms * 3;
update_alarm(__WHENCE__, now + 5);
return ret;
}
@ -1264,7 +1280,7 @@ int link_received_packet(struct decode_context *context, int sender_seq, char un
if (neighbour->next_neighbour_update > now + 10)
neighbour->next_neighbour_update = now + 10;
}
link->link_timeout = now + (context->interface->destination->tick_ms *5);
link->link_timeout = now + (context->interface->destination->ifconfig.tick_ms *5);
// force an update soon when we need to promptly ack packets
if (neighbour->using_us && link->ack_counter <=0){
@ -1411,13 +1427,14 @@ int link_receive(struct internal_mdp_header *header, struct overlay_buffer *payl
if (!out){
if (flags&FLAG_UNICAST)
continue;
else
out = create_out_link(neighbour, interface, NULL, 0);
out = create_out_link(neighbour, interface, NULL, 0);
if (!out)
continue;
}
// start sending sequence numbers when our neighbour has acked a packet
if (out->destination->sequence_number<0)
out->destination->sequence_number=0;
out->timeout=now + out->destination->tick_ms * 5;
out->timeout=now + out->destination->ifconfig.tick_ms * 5;
destination = out->destination;
}else if(transmitter == my_subscriber){
@ -1450,7 +1467,7 @@ int link_receive(struct internal_mdp_header *header, struct overlay_buffer *payl
changed = 1;
version++;
}
neighbour->link_in_timeout = now + interface->destination->reachable_timeout_ms;
neighbour->link_in_timeout = now + interface->destination->ifconfig.reachable_timeout_ms;
if (drop_rate != link->drop_rate || transmitter != link->transmitter)
version++;
@ -1560,10 +1577,10 @@ int link_state_legacy_ack(struct overlay_frame *frame, time_ms_t now)
// track the incoming link so we remember to send broadcasts
struct link_in *nl = get_neighbour_link(neighbour, frame->interface, iface, 0);
nl->link_timeout = now + (link->destination->tick_ms *5);
nl->link_timeout = now + (link->destination->ifconfig.tick_ms *5);
neighbour->legacy_protocol = 1;
neighbour->link_in_timeout = now + link->destination->reachable_timeout_ms;
neighbour->link_in_timeout = now + link->destination->ifconfig.reachable_timeout_ms;
if (changed){
route_version++;

View File

@ -104,9 +104,9 @@ configure_node() {
set debug.overlayframes Yes \
set interfaces.0.file dummy1 \
set interfaces.0.socket_type file \
set interfaces.0.send_broadcasts 0 \
set interfaces.0.dont_route 1 \
set interfaces.0.drop_broadcasts on \
set interfaces.0.broadcast.send off \
set interfaces.0.broadcast.drop on \
set interfaces.0.unicast.route off \
set interfaces.0.default_route 1 \
set interfaces.0.dummy_address 10.0.${instance_number}.1 \
set interfaces.0.dummy_netmask 255.255.255.0

View File

@ -43,8 +43,7 @@ configure_servald_server() {
set debug.rhizome on \
set debug.httpd on \
set debug.rhizome_tx on \
set debug.rhizome_rx on \
set mdp.iftype.wifi.tick_ms 500
set debug.rhizome_rx on
}
setup_common() {

View File

@ -45,8 +45,7 @@ default_config() {
set debug.rhizome_manifest on \
set debug.rhizome_ads on \
set debug.rhizome_tx on \
set debug.rhizome_rx on \
set mdp.iftype.wifi.tick_ms 500
set debug.rhizome_rx on
}
# Called by start_servald_instances for each instance.
@ -209,7 +208,7 @@ setup_UnicastTransfer() {
set_instance +B
add_servald_interface --file
executeOk_servald config \
set interfaces.1.drop_broadcasts on
set interfaces.1.broadcast.drop on
start_servald_instances +A +B
foreach_instance +A assert_peers_are_instances +B
foreach_instance +B assert_peers_are_instances +A
@ -775,9 +774,9 @@ start_radio_instance() {
set log.console.show_pid on \
set log.console.show_time on \
set interfaces.1.type CATEAR \
set interfaces.1.mdp.tick_ms 5000 \
set interfaces.1.broadcast.tick_ms 5000 \
set interfaces.1.socket_type STREAM \
set interfaces.1.encapsulation SINGLE \
set interfaces.1.broadcast.encapsulation SINGLE \
set interfaces.1.point_to_point on
start_servald_server
wait_until interface_up

View File

@ -138,8 +138,7 @@ setup_StressRhizomeDirect() {
set debug.rhizome off \
set debug.httpd off \
set debug.rhizome_tx off \
set debug.rhizome_rx off \
set mdp.iftype.wifi.tick_ms 500
set debug.rhizome_rx off
local sidvar="SID$instance_name"
for ((n = 0; n < $files_per_instance; ++n)); do
create_file file-$i-$n 10000

View File

@ -218,7 +218,9 @@ setup_single_mdp() {
assert_no_servald_processes
foreach_instance +A +B create_single_identity
foreach_instance +A +B add_servald_interface 1
foreach_instance +A +B executeOk_servald config set interfaces.1.encapsulation single
foreach_instance +A +B executeOk_servald config \
set interfaces.1.broadcast.encapsulation single \
set interfaces.1.unicast.encapsulation single
foreach_instance +A +B start_servald_server
}
test_single_mdp() {
@ -235,7 +237,9 @@ setup_mismatched_encap() {
assert_no_servald_processes
foreach_instance +A +B create_single_identity
foreach_instance +A +B add_servald_interface 1
foreach_instance +A executeOk_servald config set interfaces.1.encapsulation single
foreach_instance +A executeOk_servald config \
set interfaces.1.broadcast.encapsulation single \
set interfaces.1.unicast.encapsulation single
foreach_instance +A +B start_servald_server
}
test_mismatched_encap() {
@ -254,7 +258,8 @@ setup_single_p2p() {
foreach_instance +A +B add_servald_interface 1
foreach_instance +A +B \
executeOk_servald config \
set interfaces.1.encapsulation single \
set interfaces.1.broadcast.encapsulation single \
set interfaces.1.unicast.send off \
set interfaces.1.point_to_point on
foreach_instance +A +B start_servald_server
}
@ -295,9 +300,9 @@ setup_simulate_extender() {
set debug.packetradio on \
set debug.radio_link on \
set interfaces.1.type CATEAR \
set interfaces.1.mdp.tick_ms 5000 \
set interfaces.1.broadcast.tick_ms 5000 \
set interfaces.1.socket_type STREAM \
set interfaces.1.encapsulation SINGLE \
set interfaces.1.broadcast.encapsulation SINGLE \
set interfaces.1.point_to_point on
foreach_instance +A +B start_servald_server
}
@ -315,6 +320,27 @@ teardown_simulate_extender() {
tfw_cat "$SERVALD_VAR/radioerr"
}
doc_lowband_broadcast="Link detection over very low bandwith links"
setup_lowband_broadcast() {
setup_servald
foreach_instance +A +B create_single_identity
foreach_instance +A +B add_servald_interface 1
foreach_instance +A +B executeOk_servald config \
set interfaces.1.broadcast.packet_interval 10000000 \
set interfaces.1.broadcast.tick_ms 15000 \
set interfaces.1.broadcast.mtu 180 \
set interfaces.1.broadcast.route off \
set interfaces.1.unicast.send off
foreach_instance +A +B start_servald_server
}
test_lowband_broadcast() {
#wait_until path_exists +A +B
#wait_until path_exists +B +A
set_instance +A
executeOk_servald mdp ping --interval=5 --timeout=30 $SIDB 5
tfw_cat --stdout --stderr
}
_simulator() {
# TODO timeout & failure reporting?
executeOk --error-on-fail $servald_build_root/simulator <$SIM_IN
@ -381,7 +407,7 @@ setup_scan() {
foreach_instance +A +B +C add_servald_interface --file 1
foreach_instance +A +B +C \
executeOk_servald config \
set interfaces.1.drop_broadcasts on
set interfaces.1.broadcast.drop on
foreach_instance +A +B +C start_servald_server
foreach_instance +A +B +C \
wait_until interface_up
@ -433,10 +459,10 @@ setup_single_filter() {
foreach_instance +A +B add_servald_interface --file 1
set_instance +B
executeOk_servald config \
set interfaces.1.drop_broadcasts on
set interfaces.1.broadcast.drop on
set_instance +A
executeOk_servald config \
set interfaces.1.drop_unicasts on
set interfaces.1.unicast.drop on
foreach_instance +A +B start_servald_server
}
test_single_filter() {
@ -559,11 +585,11 @@ setup_unicast_route() {
foreach_instance +C +D add_servald_interface --file 3
set_instance +A
executeOk_servald config \
set interfaces.1.drop_broadcasts on
set interfaces.1.broadcast.drop on
set_instance +C
executeOk_servald config \
set interfaces.2.drop_broadcasts on \
set interfaces.3.drop_broadcasts on
set interfaces.2.broadcast.drop on \
set interfaces.3.broadcast.drop on
foreach_instance +A +B +C +D start_servald_server
}
test_unicast_route() {
@ -929,9 +955,6 @@ setup_crowded_mess() {
foreach_instance +D +F add_servald_interface 5
foreach_instance +E +G add_servald_interface 6
foreach_instance +F +G +H add_servald_interface 7
foreach_instance +A +B +C +D +E +F +G +H \
executeOk_servald config \
set mdp.iftype.wifi.reachable_timeout_ms 60000
foreach_instance +A +B +C +D +E +F +G +H start_servald_server
}