Improve backward compatibility for broadcasts & packet retries

This commit is contained in:
Jeremy Lakeman 2013-07-08 16:01:58 +09:30
parent 62a4cd407d
commit 88d88e685c
4 changed files with 36 additions and 18 deletions

View File

@ -198,6 +198,10 @@ int overlay_payload_enqueue(struct overlay_frame *p)
p->interface_sent_sequence[i]=FRAME_DONT_SEND;
}
// it should be safe to try sending all packets with an mdp sequence
if (p->packet_version<=0)
p->packet_version=1;
if (p->destination_resolved){
p->interface_sent_sequence[p->interface - overlay_interfaces]=FRAME_NOT_SENT;
}else{
@ -217,11 +221,15 @@ int overlay_payload_enqueue(struct overlay_frame *p)
if (overlay_interfaces[i].state!=INTERFACE_STATE_UP
|| !overlay_interfaces[i].send_broadcasts)
continue;
if (!link_state_interface_has_neighbour(&overlay_interfaces[i])){
int oldest_version = link_state_interface_oldest_neighbour(&overlay_interfaces[i]);
if (oldest_version <0){
if (config.debug.verbose && config.debug.overlayframes)
DEBUGF("Skipping broadcast on interface %s, as we have no neighbours", overlay_interfaces[i].name);
continue;
}
// make sure all neighbours can hear this packet
if (oldest_version < p->packet_version)
p->packet_version = oldest_version;
p->interface_sent_sequence[i]=FRAME_NOT_SENT;
interface_copies++;
}
@ -245,9 +253,6 @@ int overlay_payload_enqueue(struct overlay_frame *p)
p->next=NULL;
p->enqueued_at=gettime_ms();
p->mdp_sequence = -1;
// it should be safe to try sending all packets with an mdp sequence
if (p->packet_version==0)
p->packet_version=1;
queue->last=p;
if (!queue->first) queue->first=p;
queue->length++;
@ -332,7 +337,7 @@ overlay_calc_queue_time(overlay_txqueue *queue, struct overlay_frame *frame){
if (overlay_interfaces[i].state!=INTERFACE_STATE_UP)
continue;
if ((!frame->destination) && (frame->interface_sent_sequence[i]==FRAME_DONT_SEND ||
!link_state_interface_has_neighbour(&overlay_interfaces[i])))
link_state_interface_oldest_neighbour(&overlay_interfaces[i])<0))
continue;
time_ms_t next_packet = limit_next_allowed(&overlay_interfaces[i].transfer_limit);
if (next_packet < frame->interface_dont_send_until[i])
@ -449,7 +454,7 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim
{
if (overlay_interfaces[i].state!=INTERFACE_STATE_UP ||
frame->interface_sent_sequence[i]==FRAME_DONT_SEND ||
!link_state_interface_has_neighbour(&overlay_interfaces[i]))
link_state_interface_oldest_neighbour(&overlay_interfaces[i])<0)
continue;
keep=1;
if (frame->interface_dont_send_until[i] >now)
@ -578,7 +583,7 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim
int i;
for(i=0;i<OVERLAY_MAX_INTERFACES;i++){
if (overlay_interfaces[i].state==INTERFACE_STATE_UP &&
link_state_interface_has_neighbour(&overlay_interfaces[i]) &&
link_state_interface_oldest_neighbour(&overlay_interfaces[i])>=0 &&
frame->interface_sent_sequence[i]!=FRAME_DONT_SEND){
goto skip;
}
@ -669,7 +674,7 @@ int overlay_queue_ack(struct subscriber *neighbour, struct overlay_interface *in
for(j=0;j<OVERLAY_MAX_INTERFACES;j++){
if (overlay_interfaces[j].state==INTERFACE_STATE_UP &&
frame->interface_sent_sequence[j]!=FRAME_DONT_SEND &&
link_state_interface_has_neighbour(&overlay_interfaces[j])){
link_state_interface_oldest_neighbour(&overlay_interfaces[j])>=0){
discard = 0;
break;
}

View File

@ -739,16 +739,19 @@ struct neighbour_link * get_neighbour_link(struct neighbour *neighbour, struct o
return link;
}
int link_state_interface_has_neighbour(struct overlay_interface *interface)
int link_state_interface_oldest_neighbour(struct overlay_interface *interface)
{
struct neighbour *neighbour = neighbours;
int packet_version =-1;
while(neighbour){
if (neighbour->best_link && neighbour->best_link->interface == interface)
return 1;
if (neighbour->best_link && neighbour->best_link->interface == interface &&
(neighbour->subscriber->max_packet_version < packet_version || packet_version == -1)){
packet_version = neighbour->subscriber->max_packet_version;
}
neighbour = neighbour->_next;
}
return 0;
return packet_version;
}
// do we need to forward any broadcast packets transmitted by this neighbour?
@ -1110,6 +1113,10 @@ int link_state_legacy_ack(struct overlay_frame *frame, time_ms_t now)
// give this link a high cost, we aren't going to route through it anyway...
link->drop_rate = 32;
// track the incoming link so we remember to send broadcasts
struct neighbour_link *nl = get_neighbour_link(neighbour, frame->interface, iface, 0);
nl->link_timeout = now + (frame->interface->tick_ms *5);
neighbour->legacy_protocol = 1;
neighbour->neighbour_link_timeout = now + link->interface->tick_ms * 5;

View File

@ -818,7 +818,7 @@ void link_explained(struct subscriber *subscriber);
void link_interface_down(struct overlay_interface *interface);
int link_state_announce_links();
int link_state_legacy_ack(struct overlay_frame *frame, time_ms_t now);
int link_state_interface_has_neighbour(struct overlay_interface *interface);
int link_state_interface_oldest_neighbour(struct overlay_interface *interface);
int link_state_ack_soon(struct subscriber *sender);
int link_state_should_forward_broadcast(struct subscriber *transmitter);

View File

@ -28,8 +28,8 @@ teardown() {
report_all_servald_servers
}
doc_ping_090_version="Ping version of servald in Serval Mesh 0.90"
setup_ping_090_version() {
doc_dna_090_version="Dna lookup of servald in Serval Mesh 0.90"
setup_dna_090_version() {
setup_servald
if ! [ -x "$SERVALD_090" ]; then
error "SERVALD_090 must point to a build being tested for compatibility"
@ -46,18 +46,22 @@ start_servald_090() {
executeOk_servald keyring add
assert [ -e "$SERVALINSTANCE_PATH/serval.keyring" ]
extract_stdout_keyvalue SIDA sid "$rexp_sid"
DIDA=5550001
NAMEA="Agent A. Smith"
executeOk_servald set did $SIDA $DIDA "$NAMEA"
SERVALD_SERVER_CHDIR="$instance_dir" SERVALD_LOG_FILE="$instance_servald_log" executeOk_servald start
wait_until grep "[Ii]nterface .* is up" "$instance_servald_log"
}
test_ping_090_version() {
test_dna_090_version() {
local DUMMYNET="$SERVALD_VAR/dummy"
>$DUMMYNET
set_instance +A
executeOk_servald config \
set interfaces.0.dummy "$DUMMYNET" \
set monitor.socket "org.servalproject.servald.monitor.socket.$TFWUNIQUE.$instance_name" \
set mdp.socket "org.servalproject.servald.mdp.socket.$TFWUNIQUE.$instance_name"
set mdp.socket "org.servalproject.servald.mdp.socket.$TFWUNIQUE.$instance_name" \
set debug.overlayframes on
start_servald_090
set_instance +B
executeOk_servald config \
@ -72,7 +76,7 @@ test_ping_090_version() {
wait_until grep "REACHABLE VIA BROADCAST sid=$SIDA" "$instance_servald_log"
executeOk_servald route print
tfw_cat --stdout --stderr
assertStdoutGrep --stdout --matches=1 "^${SIDA}:BROADCAST :$DUMMYNET:0*\$"
assertStdoutGrep --stdout --matches=1 "^${SIDA}:BROADCAST .*:$DUMMYNET:0*\$"
set_instance +A
wait_until grep "PEER REACHABLE, sid=$SIDB" "$instance_servald_log"
executeOk_servald route print
@ -83,6 +87,8 @@ test_ping_090_version() {
set_instance +B
executeOk_servald mdp ping $SIDA 1
tfw_cat --stdout --stderr
executeOk_servald dna lookup $DIDA
tfw_cat --stdout --stderr
}
runTests "$@"