@@ -1508,18 +1508,17 @@ impl<'a> Socket<'a> {
1508
1508
( State :: Listen , _, None ) => ( ) ,
1509
1509
// This case is handled in `accepts()`.
1510
1510
( State :: Listen , _, Some ( _) ) => unreachable ! ( ) ,
1511
- // Every packet after the initial SYN must be an acknowledgement.
1512
- ( _, _, None ) => {
1513
- net_debug ! ( "expecting an ACK" ) ;
1514
- return None ;
1515
- }
1516
1511
// SYN|ACK in the SYN-SENT state must have the exact ACK number.
1517
1512
( State :: SynSent , TcpControl :: Syn , Some ( ack_number) ) => {
1518
1513
if ack_number != self . local_seq_no + 1 {
1519
1514
net_debug ! ( "unacceptable SYN|ACK in response to initial SYN" ) ;
1520
1515
return Some ( Self :: rst_reply ( ip_repr, repr) ) ;
1521
1516
}
1522
1517
}
1518
+ // TCP simultaneous open.
1519
+ // This is required by RFC 9293, which states "A TCP implementation MUST support
1520
+ // simultaneous open attempts (MUST-10)."
1521
+ ( State :: SynSent , TcpControl :: Syn , None ) => ( ) ,
1523
1522
// ACKs in the SYN-SENT state are invalid.
1524
1523
( State :: SynSent , TcpControl :: None , Some ( ack_number) ) => {
1525
1524
// If the sequence number matches, ignore it instead of RSTing.
@@ -1543,6 +1542,11 @@ impl<'a> Socket<'a> {
1543
1542
net_debug ! ( "expecting a SYN|ACK" ) ;
1544
1543
return None ;
1545
1544
}
1545
+ // Every packet after the initial SYN must be an acknowledgement.
1546
+ ( _, _, None ) => {
1547
+ net_debug ! ( "expecting an ACK" ) ;
1548
+ return None ;
1549
+ }
1546
1550
// ACK in the SYN-RECEIVED state must have the exact ACK number, or we RST it.
1547
1551
( State :: SynReceived , _, Some ( ack_number) ) => {
1548
1552
if ack_number != self . local_seq_no + 1 {
@@ -1722,7 +1726,10 @@ impl<'a> Socket<'a> {
1722
1726
( State :: Listen , TcpControl :: Rst ) => return None ,
1723
1727
1724
1728
// RSTs in SYN-RECEIVED flip the socket back to the LISTEN state.
1725
- ( State :: SynReceived , TcpControl :: Rst ) => {
1729
+ // Here we need to additionally check `listen_endpoint`, because we want to make sure
1730
+ // that SYN-RECEIVED was actually converted from the LISTEN state (another possible
1731
+ // reason is TCP simultaneous open).
1732
+ ( State :: SynReceived , TcpControl :: Rst ) if self . listen_endpoint . port != 0 => {
1726
1733
tcp_trace ! ( "received RST" ) ;
1727
1734
self . tuple = None ;
1728
1735
self . set_state ( State :: Listen ) ;
@@ -1789,8 +1796,13 @@ impl<'a> Socket<'a> {
1789
1796
}
1790
1797
1791
1798
// SYN|ACK packets in the SYN-SENT state change it to ESTABLISHED.
1799
+ // SYN packets in the SYN-SENT state change it to SYN-RECEIVED.
1792
1800
( State :: SynSent , TcpControl :: Syn ) => {
1793
- tcp_trace ! ( "received SYN|ACK" ) ;
1801
+ if repr. ack_number . is_some ( ) {
1802
+ tcp_trace ! ( "received SYN|ACK" ) ;
1803
+ } else {
1804
+ tcp_trace ! ( "received SYN" ) ;
1805
+ }
1794
1806
if let Some ( max_seg_size) = repr. max_seg_size {
1795
1807
if max_seg_size == 0 {
1796
1808
tcp_trace ! ( "received SYNACK with zero MSS, ignoring" ) ;
@@ -1816,7 +1828,11 @@ impl<'a> Socket<'a> {
1816
1828
self . tsval_generator = None ;
1817
1829
}
1818
1830
1819
- self . set_state ( State :: Established ) ;
1831
+ if repr. ack_number . is_some ( ) {
1832
+ self . set_state ( State :: Established ) ;
1833
+ } else {
1834
+ self . set_state ( State :: SynReceived ) ;
1835
+ }
1820
1836
self . timer . set_for_idle ( cx. now ( ) , self . keep_alive ) ;
1821
1837
}
1822
1838
@@ -2333,6 +2349,7 @@ impl<'a> Socket<'a> {
2333
2349
// We transmit a SYN|ACK in the SYN-RECEIVED state.
2334
2350
State :: SynSent | State :: SynReceived => {
2335
2351
repr. control = TcpControl :: Syn ;
2352
+ repr. seq_number = self . local_seq_no ;
2336
2353
// window len must NOT be scaled in SYNs.
2337
2354
repr. window_len = u16:: try_from ( self . rx_buffer . window ( ) ) . unwrap_or ( u16:: MAX ) ;
2338
2355
if self . state == State :: SynSent {
@@ -3537,6 +3554,78 @@ mod test {
3537
3554
sanity ! ( s, socket_established( ) ) ;
3538
3555
}
3539
3556
3557
+ #[ test]
3558
+ fn test_syn_sent_syn_received_ack ( ) {
3559
+ let mut s = socket_syn_sent ( ) ;
3560
+ recv ! (
3561
+ s,
3562
+ [ TcpRepr {
3563
+ control: TcpControl :: Syn ,
3564
+ seq_number: LOCAL_SEQ ,
3565
+ ack_number: None ,
3566
+ max_seg_size: Some ( BASE_MSS ) ,
3567
+ window_scale: Some ( 0 ) ,
3568
+ sack_permitted: true ,
3569
+ ..RECV_TEMPL
3570
+ } ]
3571
+ ) ;
3572
+
3573
+ // A SYN packet changes the SYN-SENT state to SYN-RECEIVED.
3574
+ send ! (
3575
+ s,
3576
+ TcpRepr {
3577
+ control: TcpControl :: Syn ,
3578
+ seq_number: REMOTE_SEQ ,
3579
+ ack_number: None ,
3580
+ max_seg_size: Some ( BASE_MSS - 80 ) ,
3581
+ window_scale: Some ( 0 ) ,
3582
+ ..SEND_TEMPL
3583
+ }
3584
+ ) ;
3585
+ assert_eq ! ( s. state, State :: SynReceived ) ;
3586
+
3587
+ // The socket will then send a SYN|ACK packet.
3588
+ recv ! (
3589
+ s,
3590
+ [ TcpRepr {
3591
+ control: TcpControl :: Syn ,
3592
+ seq_number: LOCAL_SEQ ,
3593
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
3594
+ max_seg_size: Some ( BASE_MSS ) ,
3595
+ window_scale: Some ( 0 ) ,
3596
+ ..RECV_TEMPL
3597
+ } ]
3598
+ ) ;
3599
+ recv_nothing ! ( s) ;
3600
+
3601
+ // The socket may retransmit the SYN|ACK packet.
3602
+ recv ! (
3603
+ s,
3604
+ time 1001 ,
3605
+ Ok ( TcpRepr {
3606
+ control: TcpControl :: Syn ,
3607
+ seq_number: LOCAL_SEQ ,
3608
+ ack_number: Some ( REMOTE_SEQ + 1 ) ,
3609
+ max_seg_size: Some ( BASE_MSS ) ,
3610
+ window_scale: Some ( 0 ) ,
3611
+ ..RECV_TEMPL
3612
+ } )
3613
+ ) ;
3614
+
3615
+ // An ACK packet changes the SYN-RECEIVED state to ESTABLISHED.
3616
+ send ! (
3617
+ s,
3618
+ TcpRepr {
3619
+ control: TcpControl :: None ,
3620
+ seq_number: REMOTE_SEQ + 1 ,
3621
+ ack_number: Some ( LOCAL_SEQ + 1 ) ,
3622
+ ..SEND_TEMPL
3623
+ }
3624
+ ) ;
3625
+ assert_eq ! ( s. state, State :: Established ) ;
3626
+ sanity ! ( s, socket_established( ) ) ;
3627
+ }
3628
+
3540
3629
#[ test]
3541
3630
fn test_syn_sent_syn_ack_not_incremented ( ) {
3542
3631
let mut s = socket_syn_sent ( ) ;
@@ -3573,6 +3662,49 @@ mod test {
3573
3662
assert_eq ! ( s. state, State :: SynSent ) ;
3574
3663
}
3575
3664
3665
+ #[ test]
3666
+ fn test_syn_sent_syn_received_rst ( ) {
3667
+ let mut s = socket_syn_sent ( ) ;
3668
+ recv ! (
3669
+ s,
3670
+ [ TcpRepr {
3671
+ control: TcpControl :: Syn ,
3672
+ seq_number: LOCAL_SEQ ,
3673
+ ack_number: None ,
3674
+ max_seg_size: Some ( BASE_MSS ) ,
3675
+ window_scale: Some ( 0 ) ,
3676
+ sack_permitted: true ,
3677
+ ..RECV_TEMPL
3678
+ } ]
3679
+ ) ;
3680
+
3681
+ // A SYN packet changes the SYN-SENT state to SYN-RECEIVED.
3682
+ send ! (
3683
+ s,
3684
+ TcpRepr {
3685
+ control: TcpControl :: Syn ,
3686
+ seq_number: REMOTE_SEQ ,
3687
+ ack_number: None ,
3688
+ max_seg_size: Some ( BASE_MSS - 80 ) ,
3689
+ window_scale: Some ( 0 ) ,
3690
+ ..SEND_TEMPL
3691
+ }
3692
+ ) ;
3693
+ assert_eq ! ( s. state, State :: SynReceived ) ;
3694
+
3695
+ // A RST packet changes the SYN-RECEIVED state to CLOSED.
3696
+ send ! (
3697
+ s,
3698
+ TcpRepr {
3699
+ control: TcpControl :: Rst ,
3700
+ seq_number: REMOTE_SEQ + 1 ,
3701
+ ack_number: Some ( LOCAL_SEQ ) ,
3702
+ ..SEND_TEMPL
3703
+ }
3704
+ ) ;
3705
+ assert_eq ! ( s. state, State :: Closed ) ;
3706
+ }
3707
+
3576
3708
#[ test]
3577
3709
fn test_syn_sent_rst ( ) {
3578
3710
let mut s = socket_syn_sent ( ) ;
0 commit comments