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