mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
Remember outgoing links
This commit is contained in:
parent
6ecfc952ed
commit
e3b616421f
@ -1030,6 +1030,8 @@ void overlay_interface_discover(struct sched_ent *alarm)
|
||||
const struct config_network_interface *ifconfig = NULL;
|
||||
for (i = 0; i < config.interfaces.ac; ++i, ifconfig = NULL) {
|
||||
ifconfig = &config.interfaces.av[i].value;
|
||||
if (ifconfig->exclude)
|
||||
continue;
|
||||
if (ifconfig->socket_type==SOCK_DGRAM) {
|
||||
detect_real_interfaces = 1;
|
||||
continue;
|
||||
|
88
route_link.c
88
route_link.c
@ -563,7 +563,7 @@ static void free_neighbour(struct neighbour **neighbour_ptr){
|
||||
while (out){
|
||||
struct link_out *l=out;
|
||||
out = l->_next;
|
||||
release_destination_ref(out->destination);
|
||||
release_destination_ref(l->destination);
|
||||
free(l);
|
||||
}
|
||||
|
||||
@ -595,18 +595,16 @@ static void clean_neighbours(time_ms_t now)
|
||||
}
|
||||
|
||||
struct link_out **out = &n->out_links;
|
||||
int alive=0;
|
||||
while(*out){
|
||||
struct link_out *link = *out;
|
||||
if (link->destination->interface->state!=INTERFACE_STATE_UP || link->timeout < now){
|
||||
if (link->destination->interface->state!=INTERFACE_STATE_UP){
|
||||
*out = link->_next;
|
||||
if (config.debug.linkstate)
|
||||
DEBUGF("LINK STATE; %s link_out expired for neighbour %s on interface %s",
|
||||
link->destination->unicast?"unicast":"broadcast",
|
||||
alloca_tohex_sid(n->subscriber->sid),
|
||||
link->destination->interface->name);
|
||||
release_destination_ref(link->destination);
|
||||
free(link);
|
||||
}else{
|
||||
if (link->timeout >= now)
|
||||
alive=1;
|
||||
out = &link->_next;
|
||||
}
|
||||
}
|
||||
@ -614,11 +612,11 @@ static void clean_neighbours(time_ms_t now)
|
||||
// when all links to a neighbour that we are routing through expire, force a routing calculation update
|
||||
struct link_state *state = get_link_state(n->subscriber);
|
||||
if (state->next_hop == n->subscriber &&
|
||||
(n->link_in_timeout < now || !n->links || !n->out_links) &&
|
||||
(n->link_in_timeout < now || !n->links || !alive) &&
|
||||
state->route_version == route_version)
|
||||
route_version++;
|
||||
|
||||
if (!n->links || !n->out_links){
|
||||
if (!n->links || !alive){
|
||||
free_neighbour(n_ptr);
|
||||
}else{
|
||||
n_ptr = &n->_next;
|
||||
@ -719,21 +717,16 @@ static int send_neighbour_link(struct neighbour *n)
|
||||
frame->send_context = n->subscriber;
|
||||
frame->resend=-1;
|
||||
|
||||
if (n->subscriber->reachable & REACHABLE_INDIRECT){
|
||||
if (n->subscriber->reachable & REACHABLE){
|
||||
frame->destination = n->subscriber;
|
||||
if (config.debug.linkstate && config.debug.verbose)
|
||||
DEBUGF("Sending link state ack indirectly");
|
||||
}else if (n->subscriber->reachable & REACHABLE){
|
||||
// we don't wont to address the next hop to this neighbour as that will force another reply ack
|
||||
// but we still want them to receive it.
|
||||
frame->destinations[frame->destination_count++].destination = add_destination_ref(n->subscriber->destination);
|
||||
}else{
|
||||
// no routing decision yet? send this packet to all probable destinations.
|
||||
if (config.debug.linkstate && config.debug.verbose)
|
||||
DEBUGF("Sending link state ack to all possibilities");
|
||||
struct link_out *out = n->out_links;
|
||||
while(out){
|
||||
frame->destinations[frame->destination_count++].destination = add_destination_ref(out->destination);
|
||||
if (out->timeout >= now)
|
||||
frame->destinations[frame->destination_count++].destination = add_destination_ref(out->destination);
|
||||
out = out->_next;
|
||||
}
|
||||
}
|
||||
@ -895,8 +888,9 @@ int link_add_destinations(struct overlay_frame *frame)
|
||||
struct neighbour *n = get_neighbour(frame->destination, 0);
|
||||
if (n){
|
||||
struct link_out *out = n->out_links;
|
||||
time_ms_t now = gettime_ms();
|
||||
while(out){
|
||||
if (frame->destination_count < MAX_PACKET_DESTINATIONS)
|
||||
if (out->timeout>=now && frame->destination_count < MAX_PACKET_DESTINATIONS)
|
||||
frame->destinations[frame->destination_count++].destination = add_destination_ref(out->destination);
|
||||
out = out->_next;
|
||||
}
|
||||
@ -1011,13 +1005,13 @@ 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;
|
||||
neighbour->out_links=ret;
|
||||
if (unicast)
|
||||
ret->destination = create_unicast_destination(addr, interface);
|
||||
ret->destination = create_unicast_destination(*addr, interface);
|
||||
else
|
||||
ret->destination = add_destination_ref(interface->destination);
|
||||
|
||||
@ -1033,15 +1027,22 @@ static struct link_out *create_out_link(struct neighbour *neighbour, overlay_int
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct link_out *find_out_link(struct neighbour *neighbour, overlay_interface *interface, char unicast){
|
||||
struct link_out *ret = neighbour->out_links;
|
||||
while(ret){
|
||||
if (ret->destination->interface==interface
|
||||
&& ret->destination->unicast==unicast)
|
||||
return ret;
|
||||
ret=ret->_next;
|
||||
static void create_out_links(struct neighbour *neighbour, overlay_interface *interface, struct sockaddr_in *addr){
|
||||
struct link_out *l = neighbour->out_links;
|
||||
while(l){
|
||||
if (l->destination->interface==interface)
|
||||
return;
|
||||
l=l->_next;
|
||||
}
|
||||
return NULL;
|
||||
// if this packet arrived in an IPv4 packet, assume we need to send them unicast packets
|
||||
if (addr && addr->sin_family==AF_INET && addr->sin_port!=0 && addr->sin_addr.s_addr!=0)
|
||||
create_out_link(neighbour, interface, addr, 1);
|
||||
|
||||
// if this packet arrived from the same IPv4 subnet, or a different type of network, assume they can hear our broadcasts
|
||||
if (!addr || addr->sin_family!=AF_INET ||
|
||||
(addr->sin_addr.s_addr & interface->netmask.s_addr)
|
||||
== (interface->address.sin_addr.s_addr & interface->netmask.s_addr))
|
||||
create_out_link(neighbour, interface, addr, 0);
|
||||
}
|
||||
|
||||
// track stats for receiving packets from this neighbour
|
||||
@ -1055,19 +1056,7 @@ int link_received_packet(struct decode_context *context, int sender_seq, char un
|
||||
struct link_in *link=get_neighbour_link(neighbour, context->interface, context->sender_interface, unicast);
|
||||
time_ms_t now = gettime_ms();
|
||||
|
||||
if (!neighbour->out_links){
|
||||
|
||||
// if this packet arrived in an IPv4 packet, assume we need to send them unicast packets
|
||||
if (context->addr.sin_family==AF_INET && context->addr.sin_port!=0 && context->addr.sin_addr.s_addr!=0)
|
||||
create_out_link(neighbour, context->interface, context->addr, 1);
|
||||
|
||||
// if this packet arrived from the same IPv4 subnet, or a different type of network, assume they can hear our broadcasts
|
||||
if (context->addr.sin_family!=AF_INET ||
|
||||
(context->addr.sin_addr.s_addr & context->interface->netmask.s_addr)
|
||||
== (context->interface->address.sin_addr.s_addr & context->interface->netmask.s_addr))
|
||||
create_out_link(neighbour, context->interface, context->addr, 0);
|
||||
|
||||
}
|
||||
create_out_links(neighbour, context->interface, &context->addr);
|
||||
|
||||
link->ack_counter --;
|
||||
|
||||
@ -1230,9 +1219,20 @@ int link_receive(struct overlay_frame *frame, overlay_mdp_frame *mdp)
|
||||
if (interface->state != INTERFACE_STATE_UP)
|
||||
continue;
|
||||
|
||||
struct link_out *out = find_out_link(neighbour, interface, flags&FLAG_UNICAST?1:0);
|
||||
if (!out)
|
||||
continue;
|
||||
struct link_out *out = neighbour->out_links;
|
||||
char unicast = flags&FLAG_UNICAST?1:0;
|
||||
while(out){
|
||||
if (out->destination->interface==interface
|
||||
&& out->destination->unicast==unicast)
|
||||
break;
|
||||
out=out->_next;
|
||||
}
|
||||
if (!out){
|
||||
if (flags&FLAG_UNICAST)
|
||||
continue;
|
||||
else
|
||||
out = create_out_link(neighbour, interface, NULL, 0);
|
||||
}
|
||||
// start sending sequence numbers when our neighbour has acked a packet
|
||||
if (out->destination->sequence_number<0)
|
||||
out->destination->sequence_number=0;
|
||||
|
@ -36,12 +36,16 @@ interface_up() {
|
||||
}
|
||||
|
||||
has_link() {
|
||||
interface_ex=".*"
|
||||
case "$1" in
|
||||
dummy*) interface_ex="$1"; shift;;
|
||||
esac
|
||||
set_instance $1
|
||||
executeOk_servald route print
|
||||
tfw_log "Looking for link from $1 to $2 ($4)"
|
||||
if ! grep "^${4}:\(BROADCAST\|UNICAST\):.*:0*\$" $_tfw_tmp/stdout; then
|
||||
if ! grep "^${4}:\(BROADCAST\|UNICAST\):${interface_ex}:0*\$" $_tfw_tmp/stdout; then
|
||||
tfw_log "Link not found"
|
||||
# tfw_log "^${4}:\(BROADCAST\|UNICAST\):.*:0*\$"
|
||||
# tfw_log "^${4}:\(BROADCAST\|UNICAST\):${interface_ex}:0*\$"
|
||||
# tfw_cat --stdout --stderr
|
||||
return 1
|
||||
fi
|
||||
@ -510,18 +514,22 @@ setup_multi_interface() {
|
||||
foreach_instance +A +B start_routing_instance
|
||||
}
|
||||
|
||||
multi_has_link() {
|
||||
executeOk_servald route print
|
||||
grep "^$1:BROADCAST:dummyeth" $_tfw_tmp/stdout || return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
doc_multi_interface="Multiple links of different types to the same neighbour"
|
||||
test_multi_interface() {
|
||||
set_instance +A
|
||||
wait_until multi_has_link $SIDB
|
||||
wait_until has_link dummyeth +A +B +B $SIDB $SIDB
|
||||
set_instance +B
|
||||
wait_until multi_has_link $SIDA
|
||||
wait_until has_link dummyeth +B +A +A $SIDA $SIDA
|
||||
set_instance +A
|
||||
executeOk_servald config set interfaces.2.exclude 1
|
||||
wait_until has_link dummywifi +A +B +B $SIDB $SIDB
|
||||
set_instance +B
|
||||
wait_until has_link dummywifi +B +A +A $SIDA $SIDA
|
||||
set_instance +A
|
||||
executeOk_servald config del interfaces.2.exclude
|
||||
wait_until has_link dummyeth +A +B +B $SIDB $SIDB
|
||||
set_instance +B
|
||||
wait_until has_link dummyeth +B +A +A $SIDA $SIDA
|
||||
}
|
||||
|
||||
# TODO assert that all packets arrive? assert that no duplicates arrive?
|
||||
|
Loading…
Reference in New Issue
Block a user