From bf4269e98e0b9fa5ea4e835c99cac5cf6168f3dd Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Thu, 29 Aug 2013 15:05:32 +0930 Subject: [PATCH] Adjust retransmission delay based on measured RTT --- overlay_packet.h | 4 ++-- overlay_queue.c | 49 +++++++++++++++++++++++++++++++++++++++--------- route_link.c | 1 + serval.h | 4 ++++ 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/overlay_packet.h b/overlay_packet.h index 9188bd2d..aa105b25 100644 --- a/overlay_packet.h +++ b/overlay_packet.h @@ -31,8 +31,8 @@ struct packet_destination{ // if we've sent this packet once, what was the envelope sequence number? int sent_sequence; - // delay the next transmission. if we don't get an ack, send it again. - time_ms_t delay_until; + // track when we last sent this packet. if we don't get an ack, send it again. + time_ms_t transmit_time; // the actual out going stream for this packet struct network_destination *destination; }; diff --git a/overlay_queue.c b/overlay_queue.c index 1d8fa97f..89faffcb 100644 --- a/overlay_queue.c +++ b/overlay_queue.c @@ -201,9 +201,10 @@ int overlay_payload_enqueue(struct overlay_frame *p) p->resend = 1; } - if (config.debug.verbose && config.debug.overlayframes){ - int i=0; - for (i=0;idestination_count;i++) + int i=0; + for (i=0;idestination_count;i++){ + p->destinations[i].sent_sequence=-1; + if (config.debug.verbose && config.debug.overlayframes) DEBUGF("Sending %s on interface %s", p->destinations[i].destination->unicast?"unicast":"broadcast", p->destinations[i].destination->interface->name); @@ -288,8 +289,11 @@ overlay_calc_queue_time(overlay_txqueue *queue, struct overlay_frame *frame){ for(i=0;idestination_count;i++) { time_ms_t next_packet = limit_next_allowed(&frame->destinations[i].destination->transfer_limit); - if (next_packet < frame->destinations[i].delay_until) - next_packet = frame->destinations[i].delay_until; + if (frame->destinations[i].transmit_time){ + time_ms_t delay_until = frame->destinations[i].transmit_time + frame->destinations[i].destination->resend_delay; + if (next_packet < delay_until) + next_packet = delay_until; + } if (next_allowed_packet==0||next_packet < next_allowed_packet) next_allowed_packet = next_packet; } @@ -350,6 +354,15 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim if (frame->destination_count==0 && frame->destination){ link_add_destinations(frame); + int i=0; + for (i=0;idestination_count;i++){ + frame->destinations[i].sent_sequence=-1; + if (config.debug.verbose && config.debug.overlayframes) + DEBUGF("Sending %s on interface %s", + frame->destinations[i].destination->unicast?"unicast":"broadcast", + frame->destinations[i].destination->interface->name); + } + // degrade packet version if required to reach the destination if (frame->packet_version > frame->next_hop->max_packet_version) frame->packet_version = frame->next_hop->max_packet_version; @@ -370,7 +383,8 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim continue; } - if (frame->destinations[i].delay_until>now) + if (frame->destinations[i].transmit_time && + frame->destinations[i].transmit_time + frame->destinations[i].destination->resend_delay > now) continue; if (packet->buffer){ @@ -437,9 +451,13 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim frame->delay_until = now + 5; goto skip; } - - frame->destinations[destination_index].sent_sequence = frame->destinations[destination_index].destination->sequence_number; - frame->destinations[destination_index].delay_until = now+200; + + { + struct packet_destination *dest = &frame->destinations[destination_index]; + dest->sent_sequence = dest->destination->sequence_number; + dest->transmit_time = now; + } + frame->transmit_count++; if (config.debug.overlayframes){ @@ -539,6 +557,19 @@ int overlay_queue_ack(struct subscriber *neighbour, struct network_destination * char acked = (seq_delta==0 || (seq_delta <= 32 && ack_mask&(1<<(seq_delta-1))))?1:0; if (acked){ + int rtt = now - frame->destinations[j].transmit_time; + if (!destination->min_rtt || rtt < destination->min_rtt){ + destination->min_rtt = rtt; + int delay = rtt * 2 + 40; + if (delay < destination->resend_delay){ + destination->resend_delay = delay; + if (config.debug.linkstate) + DEBUGF("Adjusting resend delay to %d", destination->resend_delay); + } + } + if (!destination->max_rtt || rtt > destination->max_rtt) + destination->max_rtt = rtt; + if (config.debug.overlayframes) DEBUGF("Packet %p to %s sent by seq %d, acked with seq %d", frame, alloca_tohex_sid(neighbour->sid), frame_seq, ack_seq); diff --git a/route_link.c b/route_link.c index f8587a38..2ac8e366 100644 --- a/route_link.c +++ b/route_link.c @@ -163,6 +163,7 @@ struct network_destination * new_destination(struct overlay_interface *interface ret->_ref_count=1; ret->encapsulation = encapsulation; ret->interface = interface; + ret->resend_delay = 1000; // DEBUGF("Create ref %p, %d - %s", ret, ret->_ref_count, ret->interface->name); } return ret; diff --git a/serval.h b/serval.h index 5061a6c0..62e75590 100644 --- a/serval.h +++ b/serval.h @@ -403,6 +403,10 @@ struct network_destination { // time last packet was sent time_ms_t last_tx; + + int min_rtt; + int max_rtt; + int resend_delay; // sequence number of last packet sent to this destination. // Used to allow NACKs that can request retransmission of recent packets.