Allow for out of order packets, reduce link state spam

This commit is contained in:
Jeremy Lakeman 2013-05-08 10:58:26 +09:30
parent c0b31a2774
commit a59b306173
4 changed files with 86 additions and 13 deletions

View File

@ -239,6 +239,8 @@ overlay_mdp_service_probe(overlay_mdp_frame *mdp)
struct overlay_interface *interface = &overlay_interfaces[probe.interface];
// if a peer is already reachable, and this probe would change the interface, ignore it
// TODO track unicast links better in route_link.c
if (peer->reachable & REACHABLE_INDIRECT)
RETURN(0);
if (peer->reachable & REACHABLE_DIRECT && peer->interface && peer->interface != interface)
RETURN(0);
@ -263,6 +265,8 @@ int overlay_send_probe(struct subscriber *peer, struct sockaddr_in addr, overlay
return WHY("I can't send a probe if the interface is down.");
// don't send a unicast probe unless its on the same interface that is already known to be reachable
if (peer && peer->reachable & REACHABLE_INDIRECT)
return -1;
if (peer && (peer->reachable & REACHABLE_DIRECT) && peer->interface && peer->interface != interface)
return -1;

View File

@ -243,7 +243,7 @@ overlay_init_packet(struct outgoing_packet *packet, struct subscriber *destinati
if (unicast)
packet->unicast_subscriber = destination;
else
seq = interface->sequence_number++;
seq = interface->sequence_number = (interface->sequence_number + 1)&0xFF;
ob_limitsize(packet->buffer, packet->interface->mtu);
overlay_packet_init_header(ENCAP_OVERLAY, &packet->context, packet->buffer,

View File

@ -549,7 +549,9 @@ static int link_send_neighbours(struct overlay_buffer *payload)
// send link details
static void link_send(struct sched_ent *alarm)
{
alarm->alarm=gettime_ms() + 10000;
time_ms_t now = gettime_ms();
alarm->alarm=now + 10000;
struct overlay_frame *frame=emalloc_zero(sizeof(struct overlay_frame));
frame->type=OF_TYPE_DATA;
@ -582,7 +584,7 @@ static void update_alarm(time_ms_t limit){
if (link_send_alarm.alarm>limit || link_send_alarm.alarm==0){
unschedule(&link_send_alarm);
link_send_alarm.alarm = limit;
link_send_alarm.deadline = limit;
link_send_alarm.deadline = limit+10;
schedule(&link_send_alarm);
}
}
@ -629,14 +631,25 @@ int link_received_packet(struct subscriber *subscriber, struct overlay_interface
if (sender_seq >=0){
if (link->ack_sequence != -1){
link->ack_mask = (link->ack_mask << 1) | 1;
while(1){
link->ack_sequence = (link->ack_sequence+1)&0xFF;
if (link->ack_sequence == sender_seq)
break;
// missed a packet? send a link state soon
link->ack_mask = link->ack_mask << 1;
next_update = now+100;
int offset = (link->ack_sequence - 1 - sender_seq)&0xFF;
if (offset < 32){
if (config.debug.verbose && config.debug.linkstate)
DEBUGF("LINK STATE; late seq %d from %s on %s",
link->ack_sequence, alloca_tohex_sid(subscriber->sid), interface->name);
link->ack_mask |= (1<<offset);
}else{
link->ack_mask = (link->ack_mask << 1) | 1;
while(1){
link->ack_sequence = (link->ack_sequence+1)&0xFF;
if (link->ack_sequence == sender_seq)
break;
// missed a packet? send a link state soon
if (config.debug.verbose && config.debug.linkstate)
DEBUGF("LINK STATE; missed seq %d from %s on %s",
link->ack_sequence, alloca_tohex_sid(subscriber->sid), interface->name);
link->ack_mask = link->ack_mask << 1;
next_update = now+100;
}
}
}else
link->ack_sequence = sender_seq;
@ -759,7 +772,7 @@ int link_receive(overlay_mdp_frame *mdp)
if (link && transmitter == my_subscriber){
// TODO combine our link stats with theirs
version = link->link_version;
if (drop_rate!=link->drop_rate)
if (abs(drop_rate - link->drop_rate)>1)
version++;
}
@ -781,6 +794,8 @@ int link_receive(overlay_mdp_frame *mdp)
if (link_send_alarm.alarm>now || link_send_alarm.alarm==0){
unschedule(&link_send_alarm);
link_send_alarm.alarm=now;
// read all incoming packets first
link_send_alarm.deadline=now+10;
schedule(&link_send_alarm);
}
}

View File

@ -340,7 +340,7 @@ test_multi_interface() {
wait_until multi_has_link $SIDA
}
doc_unreliable_links="Choose a longer, perfect path over an unreliable link"
doc_unreliable_links="Choose a longer, better path over an unreliable link"
setup_unreliable_links() {
setup_servald
assert_no_servald_processes
@ -350,9 +350,15 @@ setup_unreliable_links() {
foreach_instance +A +C add_interface 3
set_instance +A
executeOk_servald config \
set interfaces.1.drop_broadcasts 5 \
set interfaces.3.drop_broadcasts 70
set_instance +B
executeOk_servald config \
set interfaces.1.drop_broadcasts 5 \
set interfaces.2.drop_broadcasts 5
set_instance +C
executeOk_servald config \
set interfaces.2.drop_broadcasts 5 \
set interfaces.3.drop_broadcasts 70
foreach_instance +A +B +C start_routing_instance
}
@ -369,6 +375,54 @@ test_unreliable_links() {
assertStdoutGrep --matches=1 "^$SIDA:INDIRECT :"
}
doc_unreliable_links2="Choose the best multihop path with some unreliable links"
setup_unreliable_links2() {
setup_servald
assert_no_servald_processes
foreach_instance +A +B +C +D create_single_identity
foreach_instance +A +B add_interface 1
foreach_instance +A +C add_interface 2
foreach_instance +A +D add_interface 3
foreach_instance +B +C add_interface 4
foreach_instance +B +D add_interface 5
foreach_instance +C +D add_interface 6
set_instance +A
executeOk_servald config \
set interfaces.1.drop_broadcasts 5 \
set interfaces.2.drop_broadcasts 40 \
set interfaces.3.drop_broadcasts 90
set_instance +B
executeOk_servald config \
set interfaces.1.drop_broadcasts 5 \
set interfaces.4.drop_broadcasts 5 \
set interfaces.5.drop_broadcasts 40
set_instance +C
executeOk_servald config \
set interfaces.2.drop_broadcasts 40 \
set interfaces.4.drop_broadcasts 5 \
set interfaces.6.drop_broadcasts 5
set_instance +D
executeOk_servald config \
set interfaces.3.drop_broadcasts 90 \
set interfaces.5.drop_broadcasts 40 \
set interfaces.6.drop_broadcasts 5
foreach_instance +A +B +C +D start_routing_instance
}
test_unreliable_links2() {
foreach_instance +A +B +C +D \
wait_until has_seen_instances +A +B +C +D
set_instance +A
executeOk_servald mdp ping --timeout=3 $SIDD 5
tfw_cat --stdout --stderr
executeOk_servald route print
assertStdoutGrep --matches=1 "^$SIDC:INDIRECT :"
assertStdoutGrep --matches=1 "^$SIDD:INDIRECT :"
set_instance +D
executeOk_servald route print
assertStdoutGrep --matches=1 "^$SIDA:INDIRECT :"
assertStdoutGrep --matches=1 "^$SIDB:INDIRECT :"
}
setup_circle() {
setup_servald
assert_no_servald_processes