#13633: tcp: rfc 6298 & 7323: updating rto calculations and semantics
------------------------------------+------------------------------
Reporter: a-star | Owner: axeld
Type: bug | Status: new
Priority: normal | Milestone: Unscheduled
Component: Network & Internet/TCP | Version: R1/Development
Keywords: tcp, gsoc, slow start | Blocked By:
Blocking: | Has a Patch: 0
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.
--
Ticket URL: <https://dev.haiku-os.org/ticket/13633>
Haiku <https://dev.haiku-os.org>
The Haiku operating system.