public class SenderStateFastRecovery extends SenderState
Sender.dupACKthreshold
duplicate acknowledgments were received (and the sender entered
this state).SenderReno
Modifier and Type | Field and Description |
---|---|
protected boolean |
firstPartialACK
Parameter that indicates whether this is the first
partial ACK of the data that were outstanding when
a data loss was detected.
Used in TCP NewReno, in method calcCongWinAfterNewAck(int, int)
if the "Impatient variant" of the NewReno sender is implemented. |
after3xDupACKstate, congestionAvoidanceState, sender, slowStartState
Constructor and Description |
---|
SenderStateFastRecovery(Sender sender,
SenderState slowStartState,
SenderState congestionAvoidanceState)
Constructor for the fast recovery state of a TCP Reno sender.
|
Modifier and Type | Method and Description |
---|---|
protected int |
calcCongWinAfterNewAck(int ackSequenceNumber_,
int lastByteAcked_)
Helper method to calculate the new value of the congestion
window after a "new ACK" is received that acknowledges
data never acknowledged before.
This is where old TCP Reno and TCP NewReno differ. This method also resets the RTO timer for any outstanding segments. |
SenderState |
handleDupACK(Segment dupAck_)
This method handles a duplicate acknowledgment
during fast recovery.
|
protected SenderState |
lookupNextStateAfterNewAck()
Helper method to return the next state after a "new ACK".
|
handleNewACK, handleRTOtimeout
protected boolean firstPartialACK
calcCongWinAfterNewAck(int, int)
if the "Impatient variant" of the NewReno sender is implemented.
(see RFC 3782).public SenderStateFastRecovery(Sender sender, SenderState slowStartState, SenderState congestionAvoidanceState)
sender
- slowStartState
- Slow start statecongestionAvoidanceState
- Congestion avoidance stateprotected int calcCongWinAfterNewAck(int ackSequenceNumber_, int lastByteAcked_)
RFC 2581 for
TCP Reno in Section 3.2 Fast Retransmit/Fast Recovery
in Step 5 says:
“When the next ACK arrives that acknowledges new data,
... this ACK should acknowledge all the intermediate
segments sent between the lost segment and the receipt of the
third duplicate ACK, if none of these were lost.”
But, it does't say what if this is not true.
The answer is that the old Reno simply exits fast recovery when it receives an ACK for previously unacknowledged data (known as a "recovery ACK"), and that is what RFC 2581 says about processing new ACKs during Fast Recovery.
Unlike this, TCP NewReno sender
distinguishes "partial acknowledgments"
as defined in RFC 3782
(ACKs that cover previously unacknowledged data, but
not all the data outstanding when loss was detected). The sender
remains in Fast Recovery until a new ACK acknowledges all
the data outstanding at the time when Sender.dupACKthreshold
dupACKs were received.
Only when the NewReno sender receives a "full ACK",
it behaves the same as old Reno, and exits Fast Recovery.
Whether the new ACK is "partial" or "full" is determined
by comparing it to the parameter
Sender.lastByteSentBefore3xDupAcksRecvd
.
RFC 5681
(in Section 3.2) states that the retransmit timer should be reset
only for the first partial ACK that arrives during fast recovery
(applies only to TCP NewReno).
Timer management in NewReno is discussed in more detail in Section 4 of RFC 5681.
Our simplified implementation resets the RTO timer for every partial ACK.
calcCongWinAfterNewAck
in class SenderState
ackSequenceNumber_
- acknowledged data sequence numberlastByteAcked_
- last byte previously acknowledged (not yet updated with this new ACK!)public SenderState handleDupACK(Segment dupAck_)
SenderState.handleDupACK(Segment)
.handleDupACK
in class SenderState
dupAck_
- The duplicate acknowledgment to process.protected SenderState lookupNextStateAfterNewAck()
lookupNextStateAfterNewAck
in class SenderState