@@ -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