Skip to content

Commit 546aba9

Browse files
committed
Restart retransmit timer on new data ACK
1 parent cc241fa commit 546aba9

File tree

1 file changed

+51
-15
lines changed

1 file changed

+51
-15
lines changed

src/socket/tcp.rs

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -337,19 +337,12 @@ impl Timer {
337337

338338
fn set_for_retransmit(&mut self, timestamp: Instant, delay: Duration) {
339339
match *self {
340-
Timer::Idle { .. } | Timer::FastRetransmit { .. } => {
340+
Timer::Idle { .. } | Timer::FastRetransmit { .. } | Timer::Retransmit { .. } => {
341341
*self = Timer::Retransmit {
342342
expires_at: timestamp + delay,
343343
delay,
344344
}
345345
}
346-
Timer::Retransmit { expires_at, delay } if timestamp >= expires_at => {
347-
*self = Timer::Retransmit {
348-
expires_at: timestamp + delay,
349-
delay: delay * 2,
350-
}
351-
}
352-
Timer::Retransmit { .. } => (),
353346
Timer::Close { .. } => (),
354347
}
355348
}
@@ -1842,11 +1835,14 @@ impl<'a> Socket<'a> {
18421835
self.timer.set_for_idle(cx.now(), self.keep_alive);
18431836
}
18441837

1845-
// ACK packets in ESTABLISHED state reset the retransmit timer,
1846-
// except for duplicate ACK packets which preserve it.
1838+
// RFC 6298: (5.2) ACK of all outstanding data turn off the retransmit timer.
1839+
// (5.3) ACK of new data in ESTABLISHED state restart the retransmit timer.
18471840
(State::Established, TcpControl::None) => {
1848-
if !self.timer.is_retransmit() || ack_all {
1841+
if ack_all {
18491842
self.timer.set_for_idle(cx.now(), self.keep_alive);
1843+
} else if ack_len > 0 {
1844+
self.timer
1845+
.set_for_retransmit(cx.now(), self.rtte.retransmission_timeout());
18501846
}
18511847
}
18521848

@@ -2528,9 +2524,10 @@ impl<'a> Socket<'a> {
25282524
.post_transmit(cx.now(), repr.segment_len());
25292525
}
25302526

2531-
if !self.seq_to_transmit(cx) && repr.segment_len() > 0 {
2532-
// If we've transmitted all data we could (and there was something at all,
2533-
// data or flag, to transmit, not just an ACK), wind up the retransmit timer.
2527+
if !self.seq_to_transmit(cx) && repr.segment_len() > 0 && !self.timer.is_retransmit() {
2528+
// RFC 6298: (5.1) If we've transmitted all data we could (and there was
2529+
// something at all, data or flag, to transmit, not just an ACK), start the
2530+
// retransmit timer if it is not already running.
25342531
self.timer
25352532
.set_for_retransmit(cx.now(), self.rtte.retransmission_timeout());
25362533
}
@@ -5678,6 +5675,45 @@ mod test {
56785675
recv_nothing!(s, time 1550);
56795676
}
56805677

5678+
#[test]
5679+
fn test_retransmit_timer_restart_on_partial_ack() {
5680+
let mut s = socket_established();
5681+
s.remote_mss = 6;
5682+
s.send_slice(b"abcdef012345").unwrap();
5683+
5684+
recv!(s, time 0, Ok(TcpRepr {
5685+
control: TcpControl::None,
5686+
seq_number: LOCAL_SEQ + 1,
5687+
ack_number: Some(REMOTE_SEQ + 1),
5688+
payload: &b"abcdef"[..],
5689+
..RECV_TEMPL
5690+
}), exact);
5691+
recv!(s, time 0, Ok(TcpRepr {
5692+
control: TcpControl::Psh,
5693+
seq_number: LOCAL_SEQ + 1 + 6,
5694+
ack_number: Some(REMOTE_SEQ + 1),
5695+
payload: &b"012345"[..],
5696+
..RECV_TEMPL
5697+
}), exact);
5698+
// Acknowledge the first packet
5699+
send!(s, time 600, TcpRepr {
5700+
seq_number: REMOTE_SEQ + 1,
5701+
ack_number: Some(LOCAL_SEQ + 1 + 6),
5702+
window_len: 6,
5703+
..SEND_TEMPL
5704+
});
5705+
// The ACK of the first packet should restart the retransmit timer and delay a retransmission.
5706+
recv_nothing!(s, time 1500);
5707+
// The second packet should be re-sent.
5708+
recv!(s, time 1600, Ok(TcpRepr {
5709+
control: TcpControl::Psh,
5710+
seq_number: LOCAL_SEQ + 1 + 6,
5711+
ack_number: Some(REMOTE_SEQ + 1),
5712+
payload: &b"012345"[..],
5713+
..RECV_TEMPL
5714+
}), exact);
5715+
}
5716+
56815717
#[test]
56825718
fn test_data_retransmit_bursts_half_ack_close() {
56835719
let mut s = socket_established();
@@ -7794,7 +7830,7 @@ mod test {
77947830
assert_eq!(r.should_retransmit(Instant::from_millis(1200)), None);
77957831
assert_eq!(
77967832
r.should_retransmit(Instant::from_millis(1301)),
7797-
Some(Duration::from_millis(300))
7833+
Some(Duration::from_millis(200))
77987834
);
77997835
r.set_for_idle(Instant::from_millis(1301), None);
78007836
assert_eq!(r.should_retransmit(Instant::from_millis(1350)), None);

0 commit comments

Comments
 (0)