Forward RTO-Recovery (F-RTO): An Algorithm for Detecting Spurious Retransmission Timeouts with TCP
updates
- rfc-4138 — Forward RTO-Recovery (F-RTO): An Algorithm for Detecting Spurious Retransmission Timeouts with TCP and the Stream Control Transmission Protocol (SCTP)
Extracted elements (26)
F-RTO blocks algorithm entry when an earlier RTO recovery is underway (recover ≥ SND.UNA check) because acknowledgments for retransmitted segments could falsely lead the sender to declare the timeout spurious; the exception is multiple consecutive RTO expirations for the same segment.
F-RTO has a beneficial side effect on RTT measurement: by avoiding unnecessary retransmissions it can take RTT samples on delayed segments without retransmission ambiguity, yielding more accurate and larger RTO estimates — an advantage in networks prone to delay spikes.
F-RTO is a TCP sender-only algorithm requiring no TCP options. Unlike Eifel (which requires TCP timestamps) and DSACK-based algorithms (which require SACK with DSACK extension), F-RTO can be deployed with sender-side modifications only, broadening its applicability.
In step 2a, if the first ACK covers 'recover' but not beyond, the timeout cannot be declared spurious because there is insufficient evidence that a non-retransmitted segment arrived; this correctly handles the common case where a fast retransmission is lost and then retransmitted after an RTO.
The F-RTO sender is allowed to transmit up to two new segments in step 2b because a conventional TCP sender would also transmit two segments when the first new ACK arrives after an RTO retransmission; this is consistent with TCP congestion control requirements and does not inject extra traffic.
The SACK-enhanced F-RTO leverages the assumption that when a genuine RTO occurs in steady state there are no segments left in the pipe; if ACKs for pre-timeout segments arrive in response to the two new segments sent at step 2, normal TCP operation was merely delayed and the timeout is spurious.
When a spurious timeout is declared, 'recover' is reset to SND.UNA so that subsequent duplicate ACKs can trigger fast retransmit. Because F-RTO only retransmits the segment that triggered the timeout, the NewReno problem of unnecessary multiple fast retransmits cannot occur.
When the receiver window prevents new transmissions in step 2b, reverting to conventional RTO recovery is recommended to prevent the transfer from stalling: without new segments the pipe drains and no further ACKs arrive. Appendix A discusses alternative window-limited strategies.
F-RTO detects spurious RTOs only following an RTO event. Eifel (using TCP timestamps) and DSACK-based algorithms can additionally detect spurious retransmissions caused by other events such as packet reordering, providing broader detection coverage.
If a spurious RTO occurs during fast recovery, F-RTO often cannot detect it because segments transmitted before the fast-recovery trigger generate duplicate ACKs. In those cases F-RTO falls back to conventional slow-start retransmissions, performing the same as regular RTO recovery.
The F-RTO algorithm for SCTP was specified in RFC 4138 and remains at Experimental status; this document covers TCP only and advances F-RTO for TCP to Standards Track, replacing the TCP portion of RFC 4138.
When packet reordering or duplication affects the segment that triggered the spurious timeout, the basic F-RTO algorithm may fail to detect the spurious timeout due to incoming duplicate ACKs. The SACK-enhanced version handles most such cases by using SACK information to identify new data.
A TCP sender implementing the basic F-RTO algorithm MUST take the specified steps after the retransmission timer expires. If the retransmission timer expires again during F-RTO execution, the sender MUST restart the algorithm from step 1.
A TCP sender MAY apply the SACK-enhanced F-RTO algorithm when SACK is enabled; if it does, it MUST follow the specified steps. The SACK-enhanced algorithm SHOULD NOT be applied if the sender is already in loss recovery when the retransmission timeout occurs.
If no specific spurious-RTO response algorithm is implemented, the TCP sender SHOULD respond to a spurious timeout conservatively by applying the TCP congestion control specification (RFC 5681).
If the sender implements a loss recovery algorithm other than Reno or NewReno, the F-RTO algorithm SHOULD NOT be entered when an earlier fast recovery is underway.
In F-RTO step 2b, when the first post-RTO ACK advances the window without covering 'recover', the sender transmits up to two new (previously unsent) segments and MAY override the Nagle algorithm to immediately send a segment if needed.
The TCP sender SHOULD ignore acknowledgments that neither advance the cumulative acknowledgment nor are duplicate ACKs, waiting instead for a qualifying segment.
The 'recover' variable (inherited from NewReno) is used by the basic F-RTO algorithm to store the highest sequence number transmitted so far; it is reset to SND.UNA upon declaring a spurious timeout, re-enabling fast retransmit on subsequent duplicate ACKs.
The 'RecoveryPoint' variable, used by the SACK-enhanced F-RTO, records the highest sequence number transmitted so far at key algorithm checkpoints; it is set to SND.UNA when a spurious timeout is declared, permitting fast recovery on incoming duplicate acknowledgments.
The 'SpuriousRecovery' variable tracks F-RTO detection outcome: SPUR_TO indicates a spurious retransmission timeout was detected; FALSE indicates the timeout is not declared spurious and conventional RTO recovery should continue. This variable can serve as input to a corresponding response algorithm.
A malicious receiver can acknowledge data it has not received, causing F-RTO step 3 to declare a spurious timeout. However, the sender's resulting incorrect state means it cannot retransmit the undelivered segment, limiting the practical benefit of this attack to the receiver.
A malicious receiver can delay acknowledgment of a segment until after the sender enters F-RTO step 3, causing a genuine timeout to be falsely declared spurious. Mitigation: when an RTO occurs during fast recovery the sender should reduce the congestion window to 1 rather than fully reverting it.
The primary security threat of F-RTO is a receiver misleading the sender into setting an excessively large congestion window after an RTO. Loss of the unnecessary RTO retransmission cannot be detected without an explicit acknowledgment scheme such as DSACK, a limitation shared with Eifel and regular TCP without DSACK.
The basic F-RTO algorithm has three steps triggered by RTO expiry: Step 1 retransmits the first unacknowledged segment and sets SpuriousRecovery=FALSE; Step 2 processes the first post-RTO ACK (revert to conventional recovery on duplicate ACK or 'recover'-covering ACK, else send two new segments); Step 3 processes the second ACK (declare SPUR_TO if the window advances on non-retransmitted data, else set cwnd ≤ 3*MSS and retransmit in slow start).
The SACK-enhanced F-RTO operates in three steps: Step 1 fires on RTO expiry (reset SACK scoreboard, check RecoveryPoint vs. SND.UNA); Step 2 waits for the cumulative ACK of retransmitted data while updating the scoreboard from SACKs; Step 3 declares SPUR_TO if cumulative ACK or SACK acknowledges previously unacknowledged data not transmitted after the timeout, otherwise reverts to conventional recovery.