What happens in TCP when two endpoints send each other a SYN at the same time, and how many segments does that simultaneous open take?
answer
- both sides make an active open
- a SYN without ACK in SYN-SENT
- SYN-SENT, then SYN-RECEIVED
- one connection, not two
basics
~20 sEach side, in SYN-SENT, receives a SYN without an ACK, moves to SYN-RECEIVED and sends a SYN-ACK repeating its own ISN. Each SYN-ACK moves its receiver to ESTABLISHED: four segments, one connection. RFC 9293 requires every TCP to support it.
solid answer
~40 sA simultaneous open needs both endpoints to actively open toward each other with matching addresses and ports, so both SYNs belong to the same four-tuple. Each side sends a `SYN` and enters `SYN-SENT`. Each then receives the other's `SYN`, which carries no ACK; RFC 9293 has it record the peer's ISN, move to `SYN-RECEIVED` and send a `SYN-ACK` whose sequence number is its original ISN and whose acknowledgment is the peer's ISN plus one. When each SYN-ACK arrives, its receiver moves to `ESTABLISHED`. That is four segments, two SYNs and two SYN-ACKs, and one connection, not two. RFC 9293 makes support mandatory (MUST-10) and requires a stack to remember whether it reached `SYN-RECEIVED` from a passive or an active open (MUST-11), because a reset then returns it to `LISTEN` or closes it.
go deeper
Know that TCP can open a connection when both sides send a SYN at once, and that the result is one connection, not two.
Trace both sides through SYN-SENT, SYN-RECEIVED and ESTABLISHED, count the four segments, and note that each SYN-ACK repeats the original ISN.
Explain the four-tuple precondition that makes this deliberate, and why RFC 9293 requires tracking passive versus active entry into SYN-RECEIVED for reset handling.
Relate simultaneous open to peer-to-peer designs where neither side can accept unsolicited connections, and weigh relying on it against relaying traffic through a reachable intermediary.
## The precondition In ordinary client-server traffic a simultaneous open practically never happens by accident. The server only listens; it never sends a SYN toward the client. The client usually connects from a local port chosen for that attempt. A simultaneous open needs **both** applications to actively open a connection toward each other, each from the local port the other is targeting, so that both SYNs name the same **four-tuple**. That makes it a deliberate technique, used where neither side can simply accept an unsolicited connection from the other. ## The trace RFC 9293 Figure 7 shows the exchange (sequence numbers are the RFC's example values): | Line | Peer A state | Segment | Peer B state | |---|---|---|---| | 1 | `CLOSED` | none | `CLOSED` | | 2 | `SYN-SENT` | A to B: SEQ=100, `SYN` | (in flight) | | 3 | `SYN-RECEIVED` | B to A: SEQ=300, `SYN` | `SYN-SENT` | | 4 | | A's SYN arrives at B | `SYN-RECEIVED` | | 5 | `SYN-RECEIVED` | A to B: SEQ=100, ACK=301, `SYN`,`ACK` | | | 6 | `ESTABLISHED` | B to A: SEQ=300, ACK=101, `SYN`,`ACK` | `SYN-RECEIVED` | | 7 | | A's SYN-ACK arrives at B | `ESTABLISHED` | The rule behind lines 3 and 4 comes from RFC 9293's processing for `SYN-SENT`: if a SYN arrives and it does not acknowledge our own SYN, **enter `SYN-RECEIVED` and send `<SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK>`**. Note `SEQ=ISS`: the SYN-ACK repeats the side's original ISN; no new ISN is chosen. ## Why four segments and one connection - **One four-tuple.** A's local address and port are B's remote address and port, and vice versa, so both sides are describing the same connection. - **Four segments.** Two SYNs cross; then two SYN-ACKs cross. Each SYN-ACK acknowledges the SYN received from the other side. - **Each side's ISN is still confirmed.** The four logical steps of synchronisation (send my ISN, have it acknowledged, in each direction) all happen; they are just spread over four segments instead of folded into three. | | Ordinary open | Simultaneous open | |---|---|---| | Active opens | one (client) | two (both) | | Segments | 3: SYN, SYN-ACK, ACK | 4: SYN, SYN, SYN-ACK, SYN-ACK | | Path through states | client `SYN-SENT` to `ESTABLISHED`; server `LISTEN` to `SYN-RECEIVED` to `ESTABLISHED` | both `SYN-SENT` to `SYN-RECEIVED` to `ESTABLISHED` | | `LISTEN` involved | yes, on the server | no | ## What the specification requires - **MUST-10:** a TCP implementation MUST support simultaneous open attempts. - **MUST-11:** it MUST track whether a connection reached `SYN-RECEIVED` from a passive open (`LISTEN`) or an active open (`SYN-SENT`). MUST-11 matters when a valid `RST` arrives in `SYN-RECEIVED`: 1. Reached from `LISTEN`: the connection returns to `LISTEN`, so the server keeps listening, and the user need not be told. 2. Reached from `SYN-SENT`: there is nothing to return to; RFC 9293 signals "connection refused" to the user and the connection goes to `CLOSED`. ## A look-alike: the delayed duplicate SYN RFC 9293 warns that an **old duplicate SYN** arriving at a peer that is in `SYN-SENT` can make it appear that a simultaneous open is in progress. The handshake's acknowledgment checks and resets sort this out: a SYN-ACK that acknowledges something the other side never sent in this attempt draws a `RST`, and the stale attempt is discarded while the real one proceeds. ## Why interviewers ask - It checks whether a candidate knows the state machine or only the three-segment picture: "which states does each side visit" has a different answer here. - It shows why `SYN-RECEIVED` is not a server-only state. - It shows the difference between the logical four-step synchronisation and the three-segment optimisation of the usual case.
- Why doesn't a TCP simultaneous open happen by accident between an ordinary client and server?It needs both SYNs to name the same four-tuple. A server does not actively open toward its clients at all, and a client normally connects from a local port chosen for that attempt, so there is no second SYN to cross with the first. Both applications must deliberately connect to each other from agreed local ports.
- What does a TCP endpoint in SYN-RECEIVED do with a valid RST, and why must it know how it got there?If it reached SYN-RECEIVED from LISTEN, a passive open, it returns to LISTEN so the server keeps accepting. If it came from SYN-SENT, an active open as in a simultaneous open, there is no listener to go back to, so RFC 9293 reports the connection refused and moves to CLOSED. MUST-11 makes the stack track which case applies.
saying these in an interview costs you the question
- Two SYNs that cross create two separate TCP connections.
- A simultaneous open fails because one side must be in LISTEN.
- Each side picks a new ISN for the SYN-ACK in a simultaneous open.
- A simultaneous open still takes three segments, like a normal handshake.
- Supporting simultaneous open is optional for TCP implementations.