tcp: rfc 6298 & 7323: updating rto calculations and semantics
|Reported by:||a-star||Owned by:||axeld|
|Component:||Network & Internet/TCP||Version:||R1/Development|
|Keywords:||tcp, gsoc, slow start||Cc:|
|Has a Patch:||yes||Platform:||All|
Firstly I revamped the code and changed some variable names so that they more accurately represent the value they hold.
Added a fSendTime variable to keep track of when the first packet in a window of packets was sent.
Changes to the _UpdateRoundTripTime functions:
1) It now takes an additional parameter, “expectedSegments”.
Rationale: as per rfc 7323 (appendix G), Taking multiple RTT samples per window (mostly in case of timestamp RTTM) would shorten the history calculated by the RTO mechanism and cause alpha (1/8) and beta (1/4)to be inaccurate. So it suggests the following modifications:
ExpectedSamples = ceiling(FlightSize / (SMSS * 2)) alpha’ = alpha / ExpectedSamples beta’ = beta / ExpectedSamples
So expectedSamples is calculated in case of timestamp based RTTM in the _Acknowledged function and when timestamps are not used, 1 is passed because without timestamps we are not taking more than 1 sample per RTT.
2) The code inside the function was changed to the what is specified in rfc 6298:
a) On first measurement of RTT (i.e. fSmoothedRoundTripTime is 0)
SRTT = R, RTTVAR = R/2, RTO = SRTT + max(G, K*RTTVAR) where K = 4
b) On subsequent RTT measurements,
RTTVAR = (1-beta)*RTTVAR + beta*|SRTT – R'| SRTT = (1-alpha)*SRTT + alpha*R' the order of update matters alpha = 1/8, beta = ¼ RTO = SRTT + max(G, K*RTTVAR)
Also defined a new constant TCP_SYN_RETRANSMIT_TIMEOUT to be used in case of lost SYN or SYN+ACK. rfc 6298 says that in case of such a loss, RTO be reset to 3 seconds and cwnd to SMSSS.
Although rfc 6298 mandates a minimum RTO of 1 sec, many implementations (including Linux, FreeBSD) use a much lesser minimum value. I have read about the rationale for using such small values and am quite satisfied. Therefore I haven't changed the minimum RTO value of 200 msec defined in tcp.h.
Lastly, in the function _RetransmitTimer I have added a case to return back if the timer is still active. While testing, I came across a case wherein the retransmission timer expired when _SendQueued was being executed. _SendQueued had restarted the timer but by then the timer had already been expired. Now after _SendQueued returned, _Retransmit was called ignoring the fact that the timer has been restarted, resulting in unneccesary retransmission of a segment. To avoid such conditions, I have added the new case.
Change History (4)
by , 2 years ago
by , 2 years ago