TCP RTO calculation method and go implementation verification

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Overview

Recently in the study of TCP retransmission mechanism, TCP retransmission about three kinds, time-out retransmission (RTO), fast retransmission (fack), early retransmission (er). Today talk about RTO, and go to implement its algorithm, explore. Main reference Tcp/ip-guid

Basic concepts

RTO is timeout retransmission time
RTT Packet round-trip time
The mean deviation is the sum of the deviations (absolute values) of the individual measured values from the mean, divided by the number of measurements.

RTO Calculation algorithm

The RTO calculation relies on the RTT value, or a series of RTT values. Rto=f (RTT)
In Linux, the first implementation of a relatively simple classic algorithm RFC793, and later in 1988 proposed a new algorithm to calculate the RTO value, the document is RFC6298. Here's a comparison of the two algorithms.

Classic Algorithms

Original RFC

    An Example Retransmission Timeout Procedure      Measure the elapsed time between sending a data octet with a      particular sequence number and receiving an acknowledgment that      covers that sequence number (segments sent do not have to match      segments received).  This measured elapsed time is the Round Trip      Time (RTT).  Next compute a Smoothed Round Trip Time (SRTT) as:        SRTT = ( ALPHA * SRTT ) + ((1-ALPHA) * RTT)      and based on this, compute the retransmission timeout (RTO) as:        RTO = min[UBOUND,max[LBOUND,(BETA*SRTT)]]      where UBOUND is an upper bound on the timeout (e.g., 1 minute),      LBOUND is a lower bound on the timeout (e.g., 1 second), ALPHA is      a smoothing factor (e.g., .8 to .9), and BETA is a delay variance      factor (e.g., 1.3 to 2.0).

It explains the calculation formula for calculating RTO:

SRTT = ( ALPHA * SRTT ) + ((1-ALPHA) * RTT)  RTO = min[UBOUND,max[LBOUND,(BETA*SRTT)]]

Calculate the RTO value to qualify the maximum minimum RTO value by first calculating the SRTT (Smoothed Round trip time) smoothing RTT and then comparing the set maximum minimum RTO. Where Alpha is a smoothing factor with a value of 0.8 or 0.9,beta is also a factor, the recommendation is 1.3-2.0. This algorithm is very simple we use go to achieve, Alpha takes 0.8,beta 1.6.

Code implementation

Package Mainimport ("FMT") const (ALPHA = 0.8BETA = 1.6) const (LBOUND = 100UBOUND = 60000) type TCP struct {srtt Int32rto  Uint32}func Main () {tcp: = &tcp{}lastrto: = UInt32 (0) Rtts: = []int32{100, 103, 105, 102, 100, 103, 105, 100, 103, 105, 102, 100, 102, 105, 100, 103, 105, 104, 100, 103, 105,200, 203, 205, 202, 200, 203, 205, 200, 203, 205, 202, 200, 202, 20 5, 200, 203, 205, 204, 200, 203, 205,400, 403, 405, 404,100, 103, 105, 102, 100, 103, 105, 100, 103, 105, 102, 100, 102, 1 05, 100, 103, 105, 104, 100, 103, 105,//400, 403, 405, 400, 403, 405, 404, 400, 404, 405, 400, 403, 405, 404, 400, 403, 4 05,}for I, RTT: = Range Rtts {if Lastrto = = 0 {Lastrto = UInt32 (RTT)}rto: = Tcp.updatertt (RTT) if UInt32 (RTT) > Lastrto {FMT. Printf ("Warn:loss packet, Index:%d\n", i-1)}fmt. Printf ("Index:%d, RTT:%d, RTO:%d\n", I, RTT, RTO) Lastrto = Rto}}func (t *tcp) Updatertt (RTT int32) UInt32 {var rto uint 32if T.srtt = = 0 {T.srtt = Rttrto = UInt32 (RTT)} else {T.srtt = Int32 (Alpha*float32 (T.srtt) + ((1-alpha) * float32 (RTT))) RTO = min (UBOUND, Max (LBOUND, UInt32 (Beta*float32))) T.srtt}return min (A, b uint UInt32 {If a <= B {return a}return B}func max (A, b uint32) UInt32 {If a >= B {return A}return B}

running results

index:0, rtt:100, Rto:100warn:loss packet, Index:0index:1, rtt:103, Rto:160index:2, rtt:105, Rto:161index:3, R tt:102, Rto:161index:4, rtt:100, Rto:160index:5, rtt:103, Rto:160index:6, rtt:105, Rto:161index:7, rtt:100, R To:160index:8, rtt:103, Rto:160index:9, rtt:105, Rto:161index:10, rtt:102, Rto:161index:11, rtt:100, rto:160i Ndex:12, rtt:102, Rto:160index:13, rtt:105, rto:161index:14, rtt:100, rto:160index:15, rtt:103, Rto:160index: rtt:105, Rto:161index:17, rtt:104, rto:161index:18, rtt:100, rto:160index:19, rtt:103, rto:160index:20, RT t:105, Rto:161warn:loss Packet, index:20index:21, rtt:200, Rto:192warn:loss packet, index:21index:22, rtt:203, Rto:217index:23, rtt:205, rto:238index:24, rtt:202, rto:254index:25, rtt:200, rto:267index:26, rtt:203, Rto:2 78index:27, rtt:205, rto:288index:28, rtt:200, rto:294index:29, rtt:203, rto:299index:30, rtt:205, Rto:304inde X:31, rtt:202, rto:307index:32, rtt:200, rto:308index:33, rtt:202, rto:310index:34, rtt:205, rto:313index:35, rtt:200, Rto:313index : rtt:203, Rto:315index:37, rtt:205, rto:316index:38, rtt:204, rto:318index:39, rtt:200, rto:318index:40,  rtt:203, rto:318index:41, rtt:205, Rto:320warn:loss packet, index:41index:42, rtt:400, Rto:384warn:loss packet,  index:42index:43, rtt:403, rto:435index:44, rtt:405, rto:476index:45, rtt:404, rto:510index:46, rtt:100, RTO: 440index:47, rtt:103, rto:384index:48, rtt:105, rto:340index:49, rtt:102, rto:304index:50, rtt:100, rto:275in Dex:51, rtt:103, rto:252index:52, rtt:105, rto:235index:53, rtt:100, rto:219index:54, rtt:103, Rto:208index:5 5, rtt:105, rto:200index:56, rtt:102, rto:192index:57, rtt:100, rto:185index:58, rtt:102, rto:180index:59, RTT  : Rto:177index:60, rtt:100, rto:172index:61, rtt:103, rto:171index:62, rtt:105, rto:169index:63, rtt:104, rto:168index:64, RTT: Rto:166index:65, rtt:103, rto:164index:66, rtt:105, rto:164 

As can be seen from the results, this side of the loss of 5 packets, assuming there is no real loss of packets, but only the network jitter, then you can know that the algorithm anti-network jitter is very low.

Jacobaon/karels algorithm

This is a newer algorithm than the classic algorithm, of course, the performance is also better, and so will try it by hand, see the results will know.

Original RFC

The BASIC algorithm to compute of the current RTO, a TCP sender maintains-state variables, SRTT (smoothed round-trip  Time) and Rttvar (round-trip time variation).   In addition, we assume a clock granularity of G seconds. The rules governing the computation of SRTT, Rttvar, and RTO are as follows: (2.1) Until a round-trip time (RTT) Measu  Rement have been made for a segment sent between the sender and receiver, the sender should set RTO <-1         Second, though the "backing off" on repeated retransmission discussed in (5.5) still applies.  Note that the previous version of this document used an initial RTO of 3 seconds [PA00].  A TCP implementation may still use the this value (or any other value > 1 second).   The lower bound on the initial RTO are discussed in further detail in Appendix A. (2.2) When the first RTT measurement R is made, the host must set SRTT <-R Rttvar &Lt;-R/2 RTO <-SRTT + max (G, k*rttvar) where K = 4. (2.3) When a subsequent RTT measurement R ' is made, a host must set Rttvar <-(1-beta) * Rttvar + beta * |            Srtt-r ' | SRTT <-(1-alpha) * SRTT + Alpha * R ' the value of SRTT used in the update to Rttvar are its value BEF  Ore updating SRTT itself using the second assignment.         That's, updating Rttvar and SRTT must be computed in the above order.         The above should is computed using ALPHA=1/8 and BETA=1/4 (as suggested in [JK88]). After the computation, a host must update RTO <-SRTT + max (G, K*rttvar) (2.4) Whenever RTOs is computed, if         It was less than 1 second and then the RTO should was rounded up to 1 second.  Traditionally, TCP implementations use coarse grain clocks to measure the RTT and trigger the RTO, which imposes a  Large minimum value on the RTO.  The suggests that a large       Minimum RTO is needed to keep TCP conservative and avoid spurious retransmissions [AP99]. Therefore, this specification requires a large minimum rtos as a conservative approach, while at the same t         IME acknowledging that at some the future point, the I-may show, the smaller minimum RTO is acceptable or   Superior. (2.5) A maximum value may be placed on RTO provided it's at least seconds.

The calculation formula for RTO:

第一次rtt计算: SRTT = RRTTVAR = R/2RTO = SRTT + max (G, K*RTTVAR)之后:RTTVAR = (1 - beta) * RTTVAR + beta * |SRTT - R'|SRTT = (1 - alpha) * SRTT + alpha * R'RTO = SRTT + max (G, K*RTTVAR)

SRTT (smoothed round-trip time) smooth RTT times
Rttvar (round-trip time variation) RTT variable is actually the average RTT deviation
G represents the granularity of the system clock, which is generally small, US level. beta = 1⁄4, alpha = 1⁄8

Code implementation

Package Mainimport ("FMT") const (LBOUND = 100UBOUND = 60000) type TCP struct {srtt, rttvar int32rto uint32}func ma In () {tcp: = &tcp{}lastrto: = UInt32 (0) Rtts: = []int32{100, 103, 105, 102, 100, 103, 105, 100, 103, 105, 102, 100, 102 , 105, 100, 103, 105, 104, 100, 103, 105,200, 203, 205, 202, 200, 203, 205, 200, 203, 205, 202, 200, 202, 205, 200, 203, 2 05, 204, 200, 203, 205,400, 403, 405, 404,100, 103, 105, 102, 100, 103, 105, 100, 103, 105, 102, 100, 102, 105, 100, 103,  104, 103, 105,//, 403, 405, J, 403, 405, 404, +, 404, 405, +, 403, 405, 404, $, 403, 405,}for I, RTT : = Range Rtts {if Lastrto = = 0 {Lastrto = UInt32 (RTT)}rto: = Tcp.updatertt (RTT) if UInt32 (RTT) > Lastrto {fmt. Printf ("Warn:loss packet, Index:%d\n", i-1)}fmt. Printf ("Index:%d, RTT:%d, RTO:%d\n", I, RTT, RTO) Lastrto = Rto}}func (t *tcp) Updatertt (RTT int32) UInt32 {var rto uint 32if T.srtt = = 0 {T.srtt = Rttt.rttvar = RTT >> 1} else {delta: = Rtt-t.srttif Delta < 0 {DeltA =-delta}t.rttvar = (3*t.srtt + delta) >> 2t.srtt = (7*t.srtt + RTT) >> 3}rto = UInt32 (T.srtt + 4*t.rttvar) r to = min (UBOUND, Max (LBOUND, RTO)) return Rto}func min (A, b uint32) UInt32 {If a <= B {return a}return B}func max (A, b u Int32) UInt32 {if a >= B {return A}return B}

run result

index:0, rtt:100, Rto:300index:1, rtt:103, Rto:400index:2, rtt:105, Rto:404index:3, rtt:102, Rto:400index:4, rtt:100, Rto:400index:5, rtt:103, Rto:400index:6, rtt:105, Rto:404index:7, rtt:100, Rto:400index:8, rtt:103, Rto:400index:9, rtt:105, Rto:404index:10, rtt:102, Rto:400index:11, rtt:100, Rto:400index:12, rtt:102, rto:40 0index:13, rtt:105, rto:404index:14, rtt:100, rto:400index:15, rtt:103, Rto:400index:16, rtt:105, Rto:404index : rtt:104, Rto:404index:18, rtt:100, rto:400index:19, rtt:103, rto:400index:20, rtt:105, rto:404index:21, rtt:200, rto:512index:22, rtt:203, rto:547index:23, rtt:205, rto:581index:24, rtt:202, rto:609index:25, Rtt:2 XX, rto:628index:26, rtt:203, rto:650index:27, rtt:205, rto:672index:28, rtt:200, rto:685index:29, rtt:203, RT O:701index:30, rtt:205, rto:713index:31, rtt:202, rto:724index:32, rtt:200, rto:731index:33, rtt:202, rto:741 Index:34, rtt:205, RTO: 748index:35, rtt:200, rto:754index:36, rtt:203, rto:760index:37, rtt:205, rto:770index:38, rtt:204, rto:775i  ndex:39, rtt:200, rto:772index:40, rtt:203, rto:777index:41, rtt:205, rto:782index:42, rtt:400, Rto:1007index: rtt:403, rto:1082index:44, rtt:405, rto:1150index:45, rtt:404, rto:1207index:46, rtt:100, Rto:1272index:4 7, rtt:103, rto:1156index:48, rtt:105, rto:1055index:49, rtt:102, rto:976index:50, rtt:100, rto:907index:51, R tt:103, rto:840index:52, rtt:105, rto:782index:53, rtt:100, rto:741index:54, rtt:103, rto:693index:55, rtt:10 5, rto:651index:56, rtt:102, rto:625index:57, rtt:100, rto:599index:58, rtt:102, rto:566index:59, rtt:105, RTO : 538index:60, rtt:100, rto:526index:61, rtt:103, rto:503index:62, rtt:105, rto:485index:63, rtt:104, rto:479i ndex:64, rtt:100, rto:473index:65, rtt:103, rto:459index:66, rtt:105, rto:446

Even the same as the classic algorithm RTT sample, but did not appear any one drop packet, prove that its anti-network jitter is relatively strong, but there is also a problem, is calculated the RTO value is much larger than the real RTT value, if the network appears real drops, that retransmission will be much slower, resulting in very slow, I think in Linux should not be completely in accordance with this algorithm to calculate the RTO value, and the above RFC document that when the RTO is less than 1s, should let rto equals 1s, this should also be justified ah, rto equals 1s, will be a bit big, here also did not say combine fast retransmission, etc. It will slow down the retransmission rate by the RTO timeout.

RTO retransmission interval is exponentially increased

The above we introduce is the first retransmission of the RTO, if the retransmission has not received the other end of the response, the next retransmission of RTO will increase exponentially, for example, the first retransmission RTO is 1, after the 2,4,8,16 respectively .... This behavior is called the exponential avoidance strategy, so for TCP, when the packet loss rate is high, it is possible that a package will take a long time to get through.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.