sack-based loss recovery
众里寻他千百度,还是 RFC 好读:
Upon the receipt of any ACK containing SACK information, the
scoreboard MUST be updated via the Update () routine.
Upon the receipt of the first (DupThresh - 1) duplicate ACKs, the
scoreboard is to be updated as normal. Note: The first and second
duplicate ACKs can also be used to trigger the transmission of
previously unsent segments using the Limited Transmit algorithm
[RFC3042].
When a TCP sender receives the duplicate ACK corresponding to
DupThresh ACKs, the scoreboard MUST be updated with the new SACK
information (via Update ()). If no previous loss event has occurred
on the connection or the cumulative acknowledgment point is beyond
the last value of RecoveryPoint, a loss recovery phase SHOULD be
initiated, per the fast retransmit algorithm outlined in [RFC2581].
The following steps MUST be taken:
(1) RecoveryPoint = HighData
When the TCP sender receives a cumulative ACK for this data octet
the loss recovery phase is terminated.
(2) ssthresh = cwnd = (FlightSize / 2)
The congestion window (cwnd) and slow start threshold (ssthresh)
are reduced to half of FlightSize per [RFC2581].
(3) Retransmit the first data segment presumed dropped -- the segment
starting with sequence number HighACK + 1. To prevent repeated
retransmission of the same data, set HighRxt to the highest
sequence number in the retransmitted segment.
(4) Run SetPipe ()
Set a "pipe" variable to the number of outstanding octets
currently "in the pipe"; this is the data which has been sent by
the TCP sender but for which no cumulative or selective
acknowledgment has been received and the data has not been
determined to have been dropped in the network. It is assumed
that the data is still traversing the network path.
(5) In order to take advantage of potential additional available
cwnd, proceed to step (C) below.
Once a TCP is in the loss recovery phase the following procedure MUST
be used for each arriving ACK:
(A) An incoming cumulative ACK for a sequence number greater than
RecoveryPoint signals the end of loss recovery and the loss
recovery phase MUST be terminated. Any information contained in
the scoreboard for sequence numbers greater than the new value of
HighACK SHOULD NOT be cleared when leaving the loss recovery
phase.
(B) Upon receipt of an ACK that does not cover RecoveryPoint the
following actions MUST be taken:
(B.1) Use Update () to record the new SACK information conveyed
by the incoming ACK.
(B.2) Use SetPipe () to re-calculate the number of octets still
in the network.
(C) If cwnd - pipe >= 1 SMSS the sender SHOULD transmit one or more
segments as follows:
(C.1) The scoreboard MUST be queried via NextSeg () for the
sequence number range of the next segment to transmit (if any),
and the given segment sent. If NextSeg () returns failure (no
data to send) return without sending anything (i.e., terminate
steps C.1 -- C.5).
(C.2) If any of the data octets sent in (C.1) are below HighData,
HighRxt MUST be set to the highest sequence number of the
retransmitted segment.
(C.3) If any of the data octets sent in (C.1) are above HighData,
HighData must be updated to reflect the transmission of
previously unsent data.
(C.4) The estimate of the amount of data outstanding in the
network must be updated by incrementing pipe by the number of
octets transmitted in (C.1).
(C.5) If cwnd - pipe >= 1 SMSS, return to (C.1)
Upon the receipt of any ACK containing SACK information, the
scoreboard MUST be updated via the Update () routine.
Upon the receipt of the first (DupThresh - 1) duplicate ACKs, the
scoreboard is to be updated as normal. Note: The first and second
duplicate ACKs can also be used to trigger the transmission of
previously unsent segments using the Limited Transmit algorithm
[RFC3042].
When a TCP sender receives the duplicate ACK corresponding to
DupThresh ACKs, the scoreboard MUST be updated with the new SACK
information (via Update ()). If no previous loss event has occurred
on the connection or the cumulative acknowledgment point is beyond
the last value of RecoveryPoint, a loss recovery phase SHOULD be
initiated, per the fast retransmit algorithm outlined in [RFC2581].
The following steps MUST be taken:
(1) RecoveryPoint = HighData
When the TCP sender receives a cumulative ACK for this data octet
the loss recovery phase is terminated.
(2) ssthresh = cwnd = (FlightSize / 2)
The congestion window (cwnd) and slow start threshold (ssthresh)
are reduced to half of FlightSize per [RFC2581].
(3) Retransmit the first data segment presumed dropped -- the segment
starting with sequence number HighACK + 1. To prevent repeated
retransmission of the same data, set HighRxt to the highest
sequence number in the retransmitted segment.
(4) Run SetPipe ()
Set a "pipe" variable to the number of outstanding octets
currently "in the pipe"; this is the data which has been sent by
the TCP sender but for which no cumulative or selective
acknowledgment has been received and the data has not been
determined to have been dropped in the network. It is assumed
that the data is still traversing the network path.
(5) In order to take advantage of potential additional available
cwnd, proceed to step (C) below.
Once a TCP is in the loss recovery phase the following procedure MUST
be used for each arriving ACK:
(A) An incoming cumulative ACK for a sequence number greater than
RecoveryPoint signals the end of loss recovery and the loss
recovery phase MUST be terminated. Any information contained in
the scoreboard for sequence numbers greater than the new value of
HighACK SHOULD NOT be cleared when leaving the loss recovery
phase.
(B) Upon receipt of an ACK that does not cover RecoveryPoint the
following actions MUST be taken:
(B.1) Use Update () to record the new SACK information conveyed
by the incoming ACK.
(B.2) Use SetPipe () to re-calculate the number of octets still
in the network.
(C) If cwnd - pipe >= 1 SMSS the sender SHOULD transmit one or more
segments as follows:
(C.1) The scoreboard MUST be queried via NextSeg () for the
sequence number range of the next segment to transmit (if any),
and the given segment sent. If NextSeg () returns failure (no
data to send) return without sending anything (i.e., terminate
steps C.1 -- C.5).
(C.2) If any of the data octets sent in (C.1) are below HighData,
HighRxt MUST be set to the highest sequence number of the
retransmitted segment.
(C.3) If any of the data octets sent in (C.1) are above HighData,
HighData must be updated to reflect the transmission of
previously unsent data.
(C.4) The estimate of the amount of data outstanding in the
network must be updated by incrementing pipe by the number of
octets transmitted in (C.1).
(C.5) If cwnd - pipe >= 1 SMSS, return to (C.1)