Skip to content

Commit ee0ee5f

Browse files
bors[bot]SquidDev
andauthored
Merge #662
662: Only clear retransmit timer when all packets are acked r=Dirbaio a=SquidDev Fixes #660. While I've tested this on several physical devices, and can confirm they behave as expected, I'm definitely not familiar with the intricacies of smoltcp (or TCP in general!), so not sure what potential regressions there might be here. Happy to make any and all changes needed! Co-authored-by: Jonathan Coates <jonathan.coates@oxionics.com>
2 parents f21bf07 + a25c9f2 commit ee0ee5f

File tree

1 file changed

+86
-2
lines changed

1 file changed

+86
-2
lines changed

src/socket/tcp.rs

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,6 +1460,7 @@ impl<'a> Socket<'a> {
14601460
// from the sequence space.
14611461
let mut ack_len = 0;
14621462
let mut ack_of_fin = false;
1463+
let mut ack_all = false;
14631464
if repr.control != TcpControl::Rst {
14641465
if let Some(ack_number) = repr.ack_number {
14651466
// Sequence number corresponding to the first byte in `tx_buffer`.
@@ -1477,6 +1478,8 @@ impl<'a> Socket<'a> {
14771478
tcp_trace!("received ACK of FIN");
14781479
ack_of_fin = true;
14791480
}
1481+
1482+
ack_all = self.remote_last_seq == ack_number
14801483
}
14811484

14821485
self.rtte.on_ack(cx.now(), ack_number);
@@ -1585,7 +1588,7 @@ impl<'a> Socket<'a> {
15851588
// ACK packets in ESTABLISHED state reset the retransmit timer,
15861589
// except for duplicate ACK packets which preserve it.
15871590
(State::Established, TcpControl::None) => {
1588-
if !self.timer.is_retransmit() || ack_len != 0 {
1591+
if !self.timer.is_retransmit() || ack_all {
15891592
self.timer.set_for_idle(cx.now(), self.keep_alive);
15901593
}
15911594
}
@@ -1604,7 +1607,9 @@ impl<'a> Socket<'a> {
16041607
if ack_of_fin {
16051608
self.set_state(State::FinWait2);
16061609
}
1607-
self.timer.set_for_idle(cx.now(), self.keep_alive);
1610+
if ack_all {
1611+
self.timer.set_for_idle(cx.now(), self.keep_alive);
1612+
}
16081613
}
16091614

16101615
// FIN packets in FIN-WAIT-1 state change it to CLOSING, or to TIME-WAIT
@@ -4979,6 +4984,85 @@ mod test {
49794984
recv_nothing!(s, time 1550);
49804985
}
49814986

4987+
#[test]
4988+
fn test_data_retransmit_bursts_half_ack() {
4989+
let mut s = socket_established();
4990+
s.remote_mss = 6;
4991+
s.send_slice(b"abcdef012345").unwrap();
4992+
4993+
recv!(s, time 0, Ok(TcpRepr {
4994+
control: TcpControl::None,
4995+
seq_number: LOCAL_SEQ + 1,
4996+
ack_number: Some(REMOTE_SEQ + 1),
4997+
payload: &b"abcdef"[..],
4998+
..RECV_TEMPL
4999+
}), exact);
5000+
recv!(s, time 0, Ok(TcpRepr {
5001+
control: TcpControl::Psh,
5002+
seq_number: LOCAL_SEQ + 1 + 6,
5003+
ack_number: Some(REMOTE_SEQ + 1),
5004+
payload: &b"012345"[..],
5005+
..RECV_TEMPL
5006+
}), exact);
5007+
// Acknowledge the first packet
5008+
send!(s, time 5, TcpRepr {
5009+
seq_number: REMOTE_SEQ + 1,
5010+
ack_number: Some(LOCAL_SEQ + 1 + 6),
5011+
window_len: 6,
5012+
..SEND_TEMPL
5013+
});
5014+
// The second packet should be re-sent.
5015+
recv!(s, time 1500, Ok(TcpRepr {
5016+
control: TcpControl::Psh,
5017+
seq_number: LOCAL_SEQ + 1 + 6,
5018+
ack_number: Some(REMOTE_SEQ + 1),
5019+
payload: &b"012345"[..],
5020+
..RECV_TEMPL
5021+
}), exact);
5022+
5023+
recv_nothing!(s, time 1550);
5024+
}
5025+
5026+
#[test]
5027+
fn test_data_retransmit_bursts_half_ack_close() {
5028+
let mut s = socket_established();
5029+
s.remote_mss = 6;
5030+
s.send_slice(b"abcdef012345").unwrap();
5031+
s.close();
5032+
5033+
recv!(s, time 0, Ok(TcpRepr {
5034+
control: TcpControl::None,
5035+
seq_number: LOCAL_SEQ + 1,
5036+
ack_number: Some(REMOTE_SEQ + 1),
5037+
payload: &b"abcdef"[..],
5038+
..RECV_TEMPL
5039+
}), exact);
5040+
recv!(s, time 0, Ok(TcpRepr {
5041+
control: TcpControl::Fin,
5042+
seq_number: LOCAL_SEQ + 1 + 6,
5043+
ack_number: Some(REMOTE_SEQ + 1),
5044+
payload: &b"012345"[..],
5045+
..RECV_TEMPL
5046+
}), exact);
5047+
// Acknowledge the first packet
5048+
send!(s, time 5, TcpRepr {
5049+
seq_number: REMOTE_SEQ + 1,
5050+
ack_number: Some(LOCAL_SEQ + 1 + 6),
5051+
window_len: 6,
5052+
..SEND_TEMPL
5053+
});
5054+
// The second packet should be re-sent.
5055+
recv!(s, time 1500, Ok(TcpRepr {
5056+
control: TcpControl::Fin,
5057+
seq_number: LOCAL_SEQ + 1 + 6,
5058+
ack_number: Some(REMOTE_SEQ + 1),
5059+
payload: &b"012345"[..],
5060+
..RECV_TEMPL
5061+
}), exact);
5062+
5063+
recv_nothing!(s, time 1550);
5064+
}
5065+
49825066
#[test]
49835067
fn test_send_data_after_syn_ack_retransmit() {
49845068
let mut s = socket_syn_received();

0 commit comments

Comments
 (0)