From 88d88e685c49f6547fd1539d75bbec896a165ede Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Mon, 8 Jul 2013 16:01:58 +0930 Subject: [PATCH] Improve backward compatibility for broadcasts & packet retries --- overlay_queue.c | 21 +++++++++++++-------- route_link.c | 15 +++++++++++---- serval.h | 2 +- tests/compatibility | 16 +++++++++++----- 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/overlay_queue.c b/overlay_queue.c index e7dfb5f9..e668903d 100644 --- a/overlay_queue.c +++ b/overlay_queue.c @@ -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=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;jinterface_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; } diff --git a/route_link.c b/route_link.c index a6d035df..2bb77aca 100644 --- a/route_link.c +++ b/route_link.c @@ -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; diff --git a/serval.h b/serval.h index a3f5953a..07aaa74c 100644 --- a/serval.h +++ b/serval.h @@ -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); diff --git a/tests/compatibility b/tests/compatibility index b5da0e91..22ccbf75 100755 --- a/tests/compatibility +++ b/tests/compatibility @@ -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 "$@"