@@ -1493,6 +1493,7 @@ impl<'a> TcpSocket<'a> {
1493
1493
// from the sequence space.
1494
1494
let mut ack_len = 0 ;
1495
1495
let mut ack_of_fin = false ;
1496
+ let mut ack_all = false ;
1496
1497
if repr. control != TcpControl :: Rst {
1497
1498
if let Some ( ack_number) = repr. ack_number {
1498
1499
// Sequence number corresponding to the first byte in `tx_buffer`.
@@ -1514,6 +1515,8 @@ impl<'a> TcpSocket<'a> {
1514
1515
) ;
1515
1516
ack_of_fin = true ;
1516
1517
}
1518
+
1519
+ ack_all = self . remote_last_seq == ack_number
1517
1520
}
1518
1521
1519
1522
self . rtte . on_ack ( cx. now ( ) , ack_number) ;
@@ -1643,7 +1646,7 @@ impl<'a> TcpSocket<'a> {
1643
1646
// ACK packets in ESTABLISHED state reset the retransmit timer,
1644
1647
// except for duplicate ACK packets which preserve it.
1645
1648
( State :: Established , TcpControl :: None ) => {
1646
- if !self . timer . is_retransmit ( ) || ack_len != 0 {
1649
+ if !self . timer . is_retransmit ( ) || ack_all {
1647
1650
self . timer . set_for_idle ( cx. now ( ) , self . keep_alive ) ;
1648
1651
}
1649
1652
}
@@ -1662,7 +1665,9 @@ impl<'a> TcpSocket<'a> {
1662
1665
if ack_of_fin {
1663
1666
self . set_state ( State :: FinWait2 ) ;
1664
1667
}
1665
- self . timer . set_for_idle ( cx. now ( ) , self . keep_alive ) ;
1668
+ if ack_all {
1669
+ self . timer . set_for_idle ( cx. now ( ) , self . keep_alive ) ;
1670
+ }
1666
1671
}
1667
1672
1668
1673
// FIN packets in FIN-WAIT-1 state change it to CLOSING, or to TIME-WAIT
@@ -1997,7 +2002,12 @@ impl<'a> TcpSocket<'a> {
1997
2002
_ => false ,
1998
2003
} ;
1999
2004
2000
- if self . nagle && data_in_flight && !can_send_full {
2005
+ // If we're applying the Nagle algorithm we don't want to send more
2006
+ // until one of:
2007
+ // * There's no data in flight
2008
+ // * We can send a full packet
2009
+ // * We have all the data we'll ever send (we're closing send)
2010
+ if self . nagle && data_in_flight && !can_send_full && !want_fin {
2001
2011
can_send = false ;
2002
2012
}
2003
2013
@@ -5137,6 +5147,85 @@ mod test {
5137
5147
recv ! ( s, time 1550 , Err ( Error :: Exhausted ) ) ;
5138
5148
}
5139
5149
5150
+ #[ test]
5151
+ fn test_data_retransmit_bursts_half_ack ( ) {
5152
+ let mut s = socket_established ( ) ;
5153
+ s. remote_mss = 6 ;
5154
+ s. send_slice ( b"abcdef012345" ) . unwrap ( ) ;
5155
+
5156
+ recv ! ( s, time 0 , Ok ( TcpRepr {
5157
+ control: TcpControl :: None ,
5158
+ seq_number: LOCAL_SEQ + 1 ,
5159
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
5160
+ payload: & b"abcdef" [ ..] ,
5161
+ ..RECV_TEMPL
5162
+ } ) , exact) ;
5163
+ recv ! ( s, time 0 , Ok ( TcpRepr {
5164
+ control: TcpControl :: Psh ,
5165
+ seq_number: LOCAL_SEQ + 1 + 6 ,
5166
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
5167
+ payload: & b"012345" [ ..] ,
5168
+ ..RECV_TEMPL
5169
+ } ) , exact) ;
5170
+ // Acknowledge the first packet
5171
+ send ! ( s, time 5 , TcpRepr {
5172
+ seq_number: REMOTE_SEQ + 1 ,
5173
+ ack_number: Some ( LOCAL_SEQ + 1 + 6 ) ,
5174
+ window_len: 6 ,
5175
+ ..SEND_TEMPL
5176
+ } ) ;
5177
+ // The second packet should be re-sent.
5178
+ recv ! ( s, time 1500 , Ok ( TcpRepr {
5179
+ control: TcpControl :: Psh ,
5180
+ seq_number: LOCAL_SEQ + 1 + 6 ,
5181
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
5182
+ payload: & b"012345" [ ..] ,
5183
+ ..RECV_TEMPL
5184
+ } ) , exact) ;
5185
+
5186
+ recv ! ( s, time 1550 , Err ( Error :: Exhausted ) ) ;
5187
+ }
5188
+
5189
+ #[ test]
5190
+ fn test_data_retransmit_bursts_half_ack_close ( ) {
5191
+ let mut s = socket_established ( ) ;
5192
+ s. remote_mss = 6 ;
5193
+ s. send_slice ( b"abcdef012345" ) . unwrap ( ) ;
5194
+ s. close ( ) ;
5195
+
5196
+ recv ! ( s, time 0 , Ok ( TcpRepr {
5197
+ control: TcpControl :: None ,
5198
+ seq_number: LOCAL_SEQ + 1 ,
5199
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
5200
+ payload: & b"abcdef" [ ..] ,
5201
+ ..RECV_TEMPL
5202
+ } ) , exact) ;
5203
+ recv ! ( s, time 0 , Ok ( TcpRepr {
5204
+ control: TcpControl :: Fin ,
5205
+ seq_number: LOCAL_SEQ + 1 + 6 ,
5206
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
5207
+ payload: & b"012345" [ ..] ,
5208
+ ..RECV_TEMPL
5209
+ } ) , exact) ;
5210
+ // Acknowledge the first packet
5211
+ send ! ( s, time 5 , TcpRepr {
5212
+ seq_number: REMOTE_SEQ + 1 ,
5213
+ ack_number: Some ( LOCAL_SEQ + 1 + 6 ) ,
5214
+ window_len: 6 ,
5215
+ ..SEND_TEMPL
5216
+ } ) ;
5217
+ // The second packet should be re-sent.
5218
+ recv ! ( s, time 1500 , Ok ( TcpRepr {
5219
+ control: TcpControl :: Fin ,
5220
+ seq_number: LOCAL_SEQ + 1 + 6 ,
5221
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
5222
+ payload: & b"012345" [ ..] ,
5223
+ ..RECV_TEMPL
5224
+ } ) , exact) ;
5225
+
5226
+ recv ! ( s, time 1550 , Err ( Error :: Exhausted ) ) ;
5227
+ }
5228
+
5140
5229
#[ test]
5141
5230
fn test_send_data_after_syn_ack_retransmit ( ) {
5142
5231
let mut s = socket_syn_received ( ) ;
@@ -6916,6 +7005,29 @@ mod test {
6916
7005
) ;
6917
7006
}
6918
7007
7008
+ #[ test]
7009
+ fn test_final_packet_in_stream_doesnt_wait_for_nagle ( ) {
7010
+ let mut s = socket_established ( ) ;
7011
+ s. remote_mss = 6 ;
7012
+ s. send_slice ( b"abcdef0" ) . unwrap ( ) ;
7013
+ s. socket . close ( ) ;
7014
+
7015
+ recv ! ( s, time 0 , Ok ( TcpRepr {
7016
+ control: TcpControl :: None ,
7017
+ seq_number: LOCAL_SEQ + 1 ,
7018
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
7019
+ payload: & b"abcdef" [ ..] ,
7020
+ ..RECV_TEMPL
7021
+ } ) , exact) ;
7022
+ recv ! ( s, time 0 , Ok ( TcpRepr {
7023
+ control: TcpControl :: Fin ,
7024
+ seq_number: LOCAL_SEQ + 1 + 6 ,
7025
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
7026
+ payload: & b"0" [ ..] ,
7027
+ ..RECV_TEMPL
7028
+ } ) , exact) ;
7029
+ }
7030
+
6919
7031
// =========================================================================================//
6920
7032
// Tests for packet filtering.
6921
7033
// =========================================================================================//
0 commit comments