@@ -575,6 +575,18 @@ impl<'a> TcpSocket<'a> {
575
575
if !self . remote_endpoint . addr . is_unspecified ( ) &&
576
576
self . remote_endpoint . addr != ip_repr. src_addr ( ) { return Err ( Error :: Rejected ) }
577
577
578
+ // Consider how much the sequence number space differs from the transmit buffer space.
579
+ let ( sent_syn, sent_fin) = match self . state {
580
+ // In SYN-SENT or SYN-RECEIVED, we've just sent a SYN.
581
+ State :: SynSent | State :: SynReceived => ( true , false ) ,
582
+ // In FIN-WAIT-1, LAST-ACK, or CLOSING, we've just sent a FIN.
583
+ State :: FinWait1 | State :: LastAck | State :: Closing => ( false , true ) ,
584
+ // In all other states we've already got acknowledgemetns for
585
+ // all of the control flags we sent.
586
+ _ => ( false , false )
587
+ } ;
588
+ let control_len = ( sent_syn as usize ) + ( sent_fin as usize ) ;
589
+
578
590
// Reject unacceptable acknowledgements.
579
591
match ( self . state , repr) {
580
592
// The initial SYN (or whatever) cannot contain an acknowledgement.
@@ -609,16 +621,7 @@ impl<'a> TcpSocket<'a> {
609
621
return Err ( Error :: Malformed )
610
622
}
611
623
// Every acknowledgement must be for transmitted but unacknowledged data.
612
- ( state, TcpRepr { ack_number : Some ( ack_number) , .. } ) => {
613
- let control_len = match state {
614
- // In SYN-SENT or SYN-RECEIVED, we've just sent a SYN.
615
- State :: SynSent | State :: SynReceived => 1 ,
616
- // In FIN-WAIT-1, LAST-ACK, or CLOSING, we've just sent a FIN.
617
- State :: FinWait1 | State :: LastAck | State :: Closing => 1 ,
618
- // In all other states we've already got acknowledgemetns for
619
- // all of the control flags we sent.
620
- _ => 0
621
- } ;
624
+ ( _, TcpRepr { ack_number : Some ( ack_number) , .. } ) => {
622
625
let unacknowledged = self . tx_buffer . len ( ) + control_len;
623
626
if !( ack_number >= self . local_seq_no &&
624
627
ack_number <= ( self . local_seq_no + unacknowledged) ) {
@@ -708,7 +711,6 @@ impl<'a> TcpSocket<'a> {
708
711
709
712
// ACK packets in the SYN-RECEIVED state change it to ESTABLISHED.
710
713
( State :: SynReceived , TcpRepr { control : TcpControl :: None , .. } ) => {
711
- self . local_seq_no += 1 ;
712
714
self . set_state ( State :: Established ) ;
713
715
self . retransmit . reset ( ) ;
714
716
}
@@ -725,7 +727,6 @@ impl<'a> TcpSocket<'a> {
725
727
726
728
// ACK packets in FIN-WAIT-1 state change it to FIN-WAIT-2.
727
729
( State :: FinWait1 , TcpRepr { control : TcpControl :: None , .. } ) => {
728
- self . local_seq_no += 1 ;
729
730
self . set_state ( State :: FinWait2 ) ;
730
731
}
731
732
@@ -745,7 +746,6 @@ impl<'a> TcpSocket<'a> {
745
746
746
747
// ACK packets in CLOSING state change it to TIME-WAIT.
747
748
( State :: Closing , TcpRepr { control : TcpControl :: None , .. } ) => {
748
- self . local_seq_no += 1 ;
749
749
self . set_state ( State :: TimeWait ) ;
750
750
self . retransmit . reset ( ) ;
751
751
}
@@ -758,7 +758,6 @@ impl<'a> TcpSocket<'a> {
758
758
// Clear the remote endpoint, or we'll send an RST there.
759
759
self . set_state ( State :: Closed ) ;
760
760
self . remote_endpoint = IpEndpoint :: default ( ) ;
761
- self . local_seq_no += 1 ;
762
761
}
763
762
764
763
_ => {
@@ -770,13 +769,23 @@ impl<'a> TcpSocket<'a> {
770
769
771
770
// Dequeue acknowledged octets.
772
771
if let Some ( ack_number) = repr. ack_number {
773
- let ack_length = ack_number - self . local_seq_no ;
774
- if ack_length > 0 {
772
+ let mut ack_len = ack_number - self . local_seq_no ;
773
+ // There could have been no data sent before the SYN, so we always remove it
774
+ // from the sequence space.
775
+ if sent_syn {
776
+ ack_len -= 1
777
+ }
778
+ // We could've sent data before the FIN, so only remove FIN from the sequence
779
+ // space if all of that data is acknowledged.
780
+ if sent_fin && self . tx_buffer . len ( ) + 1 == ack_len {
781
+ ack_len -= 1
782
+ }
783
+ if ack_len > 0 {
775
784
net_trace ! ( "[{}]{}:{}: tx buffer: dequeueing {} octets (now {})" ,
776
785
self . debug_id, self . local_endpoint, self . remote_endpoint,
777
- ack_length , self . tx_buffer. len( ) - ack_length ) ;
786
+ ack_len , self . tx_buffer. len( ) - ack_len ) ;
778
787
}
779
- self . tx_buffer . advance ( ack_length ) ;
788
+ self . tx_buffer . advance ( ack_len ) ;
780
789
self . local_seq_no = ack_number;
781
790
}
782
791
@@ -1962,6 +1971,27 @@ mod test {
1962
1971
} ] )
1963
1972
}
1964
1973
1974
+ #[ test]
1975
+ fn test_mutual_close_with_data ( ) {
1976
+ let mut s = socket_established ( ) ;
1977
+ s. send_slice ( b"abcdef" ) . unwrap ( ) ;
1978
+ s. close ( ) ;
1979
+ assert_eq ! ( s. state, State :: FinWait1 ) ;
1980
+ recv ! ( s, [ TcpRepr {
1981
+ control: TcpControl :: Fin ,
1982
+ seq_number: LOCAL_SEQ + 1 ,
1983
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
1984
+ payload: & b"abcdef" [ ..] ,
1985
+ ..RECV_TEMPL
1986
+ } ] ) ;
1987
+ send ! ( s, TcpRepr {
1988
+ control: TcpControl :: Fin ,
1989
+ seq_number: REMOTE_SEQ + 1 ,
1990
+ ack_number: Some ( LOCAL_SEQ + 1 + 6 + 1 ) ,
1991
+ ..SEND_TEMPL
1992
+ } ) ;
1993
+ }
1994
+
1965
1995
// =========================================================================================//
1966
1996
// Tests for retransmission on packet loss.
1967
1997
// =========================================================================================//
0 commit comments