Skip to content

Commit fe0b4d1

Browse files
authored
Merge pull request #1002 from lrh2000/mtu-ack
Send immediate ACKs after RMSS bytes of data
2 parents b8fb01c + a27c017 commit fe0b4d1

File tree

1 file changed

+55
-24
lines changed

1 file changed

+55
-24
lines changed

src/socket/tcp.rs

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,20 +2073,20 @@ impl<'a> Socket<'a> {
20732073

20742074
// Handle delayed acks
20752075
if let Some(ack_delay) = self.ack_delay {
2076-
if self.ack_to_transmit() || self.window_to_update() {
2076+
if self.ack_to_transmit() {
20772077
self.ack_delay_timer = match self.ack_delay_timer {
20782078
AckDelayTimer::Idle => {
20792079
tcp_trace!("starting delayed ack timer");
2080-
20812080
AckDelayTimer::Waiting(cx.now() + ack_delay)
20822081
}
2083-
// RFC1122 says "in a stream of full-sized segments there SHOULD be an ACK
2084-
// for at least every second segment".
2085-
// For now, we send an ACK every second received packet, full-sized or not.
2086-
AckDelayTimer::Waiting(_) => {
2082+
AckDelayTimer::Waiting(_) if self.immediate_ack_to_transmit() => {
20872083
tcp_trace!("delayed ack timer already started, forcing expiry");
20882084
AckDelayTimer::Immediate
20892085
}
2086+
timer @ AckDelayTimer::Waiting(_) => {
2087+
tcp_trace!("waiting until delayed ack timer expires");
2088+
timer
2089+
}
20902090
AckDelayTimer::Immediate => {
20912091
tcp_trace!("delayed ack timer already force-expired");
20922092
AckDelayTimer::Immediate
@@ -2199,6 +2199,24 @@ impl<'a> Socket<'a> {
21992199
}
22002200
}
22012201

2202+
/// Return whether to send ACK immediately due to the amount of unacknowledged data.
2203+
///
2204+
/// RFC 9293 states "An ACK SHOULD be generated for at least every second full-sized segment or
2205+
/// 2*RMSS bytes of new data (where RMSS is the MSS specified by the TCP endpoint receiving the
2206+
/// segments to be acknowledged, or the default value if not specified) (SHLD-19)."
2207+
///
2208+
/// Note that the RFC above only says "at least 2*RMSS bytes", which is not a hard requirement.
2209+
/// In practice, we follow the Linux kernel's empirical value of sending an ACK for every RMSS
2210+
/// byte of new data. For details, see
2211+
/// <https://elixir.bootlin.com/linux/v6.11.4/source/net/ipv4/tcp_input.c#L5747>.
2212+
fn immediate_ack_to_transmit(&self) -> bool {
2213+
if let Some(remote_last_ack) = self.remote_last_ack {
2214+
remote_last_ack + self.remote_mss < self.remote_seq_no + self.rx_buffer.len()
2215+
} else {
2216+
false
2217+
}
2218+
}
2219+
22022220
/// Return whether we should send ACK immediately due to significant window updates.
22032221
///
22042222
/// ACKs with significant window updates should be sent immediately to let the sender know that
@@ -7493,15 +7511,15 @@ mod test {
74937511
}
74947512

74957513
#[test]
7496-
fn test_delayed_ack_every_second_packet() {
7497-
let mut s = socket_established();
7514+
fn test_delayed_ack_every_rmss() {
7515+
let mut s = socket_established_with_buffer_sizes(DEFAULT_MSS * 2, DEFAULT_MSS * 2);
74987516
s.set_ack_delay(Some(ACK_DELAY_DEFAULT));
74997517
send!(
75007518
s,
75017519
TcpRepr {
75027520
seq_number: REMOTE_SEQ + 1,
75037521
ack_number: Some(LOCAL_SEQ + 1),
7504-
payload: &b"abc"[..],
7522+
payload: &[0; DEFAULT_MSS - 1],
75057523
..SEND_TEMPL
75067524
}
75077525
);
@@ -7512,35 +7530,48 @@ mod test {
75127530
send!(
75137531
s,
75147532
TcpRepr {
7515-
seq_number: REMOTE_SEQ + 1 + 3,
7533+
seq_number: REMOTE_SEQ + 1 + (DEFAULT_MSS - 1),
75167534
ack_number: Some(LOCAL_SEQ + 1),
7517-
payload: &b"def"[..],
7535+
payload: &b"a"[..],
75187536
..SEND_TEMPL
75197537
}
75207538
);
75217539

7522-
// Every 2nd packet, ACK is sent without delay.
7540+
// No ACK is immediately sent.
7541+
recv_nothing!(s);
7542+
7543+
send!(
7544+
s,
7545+
TcpRepr {
7546+
seq_number: REMOTE_SEQ + 1 + DEFAULT_MSS,
7547+
ack_number: Some(LOCAL_SEQ + 1),
7548+
payload: &b"a"[..],
7549+
..SEND_TEMPL
7550+
}
7551+
);
7552+
7553+
// RMSS+1 bytes of data has been received, so ACK is sent without delay.
75237554
recv!(
75247555
s,
75257556
Ok(TcpRepr {
75267557
seq_number: LOCAL_SEQ + 1,
7527-
ack_number: Some(REMOTE_SEQ + 1 + 6),
7528-
window_len: 58,
7558+
ack_number: Some(REMOTE_SEQ + 1 + (DEFAULT_MSS + 1)),
7559+
window_len: (DEFAULT_MSS - 1) as u16,
75297560
..RECV_TEMPL
75307561
})
75317562
);
75327563
}
75337564

75347565
#[test]
7535-
fn test_delayed_ack_three_packets() {
7536-
let mut s = socket_established();
7566+
fn test_delayed_ack_every_rmss_or_more() {
7567+
let mut s = socket_established_with_buffer_sizes(DEFAULT_MSS * 2, DEFAULT_MSS * 2);
75377568
s.set_ack_delay(Some(ACK_DELAY_DEFAULT));
75387569
send!(
75397570
s,
75407571
TcpRepr {
75417572
seq_number: REMOTE_SEQ + 1,
75427573
ack_number: Some(LOCAL_SEQ + 1),
7543-
payload: &b"abc"[..],
7574+
payload: &[0; DEFAULT_MSS],
75447575
..SEND_TEMPL
75457576
}
75467577
);
@@ -7551,30 +7582,30 @@ mod test {
75517582
send!(
75527583
s,
75537584
TcpRepr {
7554-
seq_number: REMOTE_SEQ + 1 + 3,
7585+
seq_number: REMOTE_SEQ + 1 + DEFAULT_MSS,
75557586
ack_number: Some(LOCAL_SEQ + 1),
7556-
payload: &b"def"[..],
7587+
payload: &b"a"[..],
75577588
..SEND_TEMPL
75587589
}
75597590
);
75607591

75617592
send!(
75627593
s,
75637594
TcpRepr {
7564-
seq_number: REMOTE_SEQ + 1 + 6,
7595+
seq_number: REMOTE_SEQ + 1 + (DEFAULT_MSS + 1),
75657596
ack_number: Some(LOCAL_SEQ + 1),
7566-
payload: &b"ghi"[..],
7597+
payload: &b"b"[..],
75677598
..SEND_TEMPL
75687599
}
75697600
);
75707601

7571-
// Every 2nd (or more) packet, ACK is sent without delay.
7602+
// RMSS+2 bytes of data has been received, so ACK is sent without delay.
75727603
recv!(
75737604
s,
75747605
Ok(TcpRepr {
75757606
seq_number: LOCAL_SEQ + 1,
7576-
ack_number: Some(REMOTE_SEQ + 1 + 9),
7577-
window_len: 55,
7607+
ack_number: Some(REMOTE_SEQ + 1 + (DEFAULT_MSS + 2)),
7608+
window_len: (DEFAULT_MSS - 2) as u16,
75787609
..RECV_TEMPL
75797610
})
75807611
);

0 commit comments

Comments
 (0)