Skip to content

Commit 032094e

Browse files
authored
Merge pull request #1001 from lrh2000/sim-open
Support TCP simultaneous open
2 parents 45fa984 + 06eb8b7 commit 032094e

File tree

1 file changed

+140
-8
lines changed

1 file changed

+140
-8
lines changed

src/socket/tcp.rs

Lines changed: 140 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,18 +1508,17 @@ impl<'a> Socket<'a> {
15081508
(State::Listen, _, None) => (),
15091509
// This case is handled in `accepts()`.
15101510
(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-
}
15161511
// SYN|ACK in the SYN-SENT state must have the exact ACK number.
15171512
(State::SynSent, TcpControl::Syn, Some(ack_number)) => {
15181513
if ack_number != self.local_seq_no + 1 {
15191514
net_debug!("unacceptable SYN|ACK in response to initial SYN");
15201515
return Some(Self::rst_reply(ip_repr, repr));
15211516
}
15221517
}
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) => (),
15231522
// ACKs in the SYN-SENT state are invalid.
15241523
(State::SynSent, TcpControl::None, Some(ack_number)) => {
15251524
// If the sequence number matches, ignore it instead of RSTing.
@@ -1543,6 +1542,11 @@ impl<'a> Socket<'a> {
15431542
net_debug!("expecting a SYN|ACK");
15441543
return None;
15451544
}
1545+
// Every packet after the initial SYN must be an acknowledgement.
1546+
(_, _, None) => {
1547+
net_debug!("expecting an ACK");
1548+
return None;
1549+
}
15461550
// ACK in the SYN-RECEIVED state must have the exact ACK number, or we RST it.
15471551
(State::SynReceived, _, Some(ack_number)) => {
15481552
if ack_number != self.local_seq_no + 1 {
@@ -1722,7 +1726,10 @@ impl<'a> Socket<'a> {
17221726
(State::Listen, TcpControl::Rst) => return None,
17231727

17241728
// 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 => {
17261733
tcp_trace!("received RST");
17271734
self.tuple = None;
17281735
self.set_state(State::Listen);
@@ -1789,8 +1796,13 @@ impl<'a> Socket<'a> {
17891796
}
17901797

17911798
// 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.
17921800
(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+
}
17941806
if let Some(max_seg_size) = repr.max_seg_size {
17951807
if max_seg_size == 0 {
17961808
tcp_trace!("received SYNACK with zero MSS, ignoring");
@@ -1816,7 +1828,11 @@ impl<'a> Socket<'a> {
18161828
self.tsval_generator = None;
18171829
}
18181830

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+
}
18201836
self.timer.set_for_idle(cx.now(), self.keep_alive);
18211837
}
18221838

@@ -2333,6 +2349,7 @@ impl<'a> Socket<'a> {
23332349
// We transmit a SYN|ACK in the SYN-RECEIVED state.
23342350
State::SynSent | State::SynReceived => {
23352351
repr.control = TcpControl::Syn;
2352+
repr.seq_number = self.local_seq_no;
23362353
// window len must NOT be scaled in SYNs.
23372354
repr.window_len = u16::try_from(self.rx_buffer.window()).unwrap_or(u16::MAX);
23382355
if self.state == State::SynSent {
@@ -3537,6 +3554,78 @@ mod test {
35373554
sanity!(s, socket_established());
35383555
}
35393556

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+
35403629
#[test]
35413630
fn test_syn_sent_syn_ack_not_incremented() {
35423631
let mut s = socket_syn_sent();
@@ -3573,6 +3662,49 @@ mod test {
35733662
assert_eq!(s.state, State::SynSent);
35743663
}
35753664

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+
35763708
#[test]
35773709
fn test_syn_sent_rst() {
35783710
let mut s = socket_syn_sent();

0 commit comments

Comments
 (0)