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; 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){ if (p->destination_resolved){
p->interface_sent_sequence[p->interface - overlay_interfaces]=FRAME_NOT_SENT; p->interface_sent_sequence[p->interface - overlay_interfaces]=FRAME_NOT_SENT;
}else{ }else{
@ -217,11 +221,15 @@ int overlay_payload_enqueue(struct overlay_frame *p)
if (overlay_interfaces[i].state!=INTERFACE_STATE_UP if (overlay_interfaces[i].state!=INTERFACE_STATE_UP
|| !overlay_interfaces[i].send_broadcasts) || !overlay_interfaces[i].send_broadcasts)
continue; 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) if (config.debug.verbose && config.debug.overlayframes)
DEBUGF("Skipping broadcast on interface %s, as we have no neighbours", overlay_interfaces[i].name); DEBUGF("Skipping broadcast on interface %s, as we have no neighbours", overlay_interfaces[i].name);
continue; 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; p->interface_sent_sequence[i]=FRAME_NOT_SENT;
interface_copies++; interface_copies++;
} }
@ -245,9 +253,6 @@ int overlay_payload_enqueue(struct overlay_frame *p)
p->next=NULL; p->next=NULL;
p->enqueued_at=gettime_ms(); p->enqueued_at=gettime_ms();
p->mdp_sequence = -1; 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; queue->last=p;
if (!queue->first) queue->first=p; if (!queue->first) queue->first=p;
queue->length++; 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) if (overlay_interfaces[i].state!=INTERFACE_STATE_UP)
continue; continue;
if ((!frame->destination) && (frame->interface_sent_sequence[i]==FRAME_DONT_SEND || 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; continue;
time_ms_t next_packet = limit_next_allowed(&overlay_interfaces[i].transfer_limit); time_ms_t next_packet = limit_next_allowed(&overlay_interfaces[i].transfer_limit);
if (next_packet < frame->interface_dont_send_until[i]) 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 || if (overlay_interfaces[i].state!=INTERFACE_STATE_UP ||
frame->interface_sent_sequence[i]==FRAME_DONT_SEND || 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; continue;
keep=1; keep=1;
if (frame->interface_dont_send_until[i] >now) 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; int i;
for(i=0;i<OVERLAY_MAX_INTERFACES;i++){ for(i=0;i<OVERLAY_MAX_INTERFACES;i++){
if (overlay_interfaces[i].state==INTERFACE_STATE_UP && 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){ frame->interface_sent_sequence[i]!=FRAME_DONT_SEND){
goto skip; 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++){ for(j=0;j<OVERLAY_MAX_INTERFACES;j++){
if (overlay_interfaces[j].state==INTERFACE_STATE_UP && if (overlay_interfaces[j].state==INTERFACE_STATE_UP &&
frame->interface_sent_sequence[j]!=FRAME_DONT_SEND && 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; discard = 0;
break; break;
} }

View File

@ -739,16 +739,19 @@ struct neighbour_link * get_neighbour_link(struct neighbour *neighbour, struct o
return link; 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; struct neighbour *neighbour = neighbours;
int packet_version =-1;
while(neighbour){ while(neighbour){
if (neighbour->best_link && neighbour->best_link->interface == interface) if (neighbour->best_link && neighbour->best_link->interface == interface &&
return 1; (neighbour->subscriber->max_packet_version < packet_version || packet_version == -1)){
packet_version = neighbour->subscriber->max_packet_version;
}
neighbour = neighbour->_next; neighbour = neighbour->_next;
} }
return 0; return packet_version;
} }
// do we need to forward any broadcast packets transmitted by this neighbour? // 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... // give this link a high cost, we aren't going to route through it anyway...
link->drop_rate = 32; 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->legacy_protocol = 1;
neighbour->neighbour_link_timeout = now + link->interface->tick_ms * 5; 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); void link_interface_down(struct overlay_interface *interface);
int link_state_announce_links(); int link_state_announce_links();
int link_state_legacy_ack(struct overlay_frame *frame, time_ms_t now); 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_ack_soon(struct subscriber *sender);
int link_state_should_forward_broadcast(struct subscriber *transmitter); int link_state_should_forward_broadcast(struct subscriber *transmitter);

View File

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