In TCP, what is the difference between closing a connection gracefully with FIN and aborting it with RST?
answer
- one says done, one says gone
- per direction versus whole connection
- queued data: delivered or discarded
- FIN takes a sequence number
- RST checked against the window
basics
~20 sFIN is an orderly close of one direction: data queued before it is still delivered, the peer acknowledges it, and the other direction stays open. RST aborts the whole connection at once, discarding queued data and state.
solid answer
~40 sA `FIN` means "I have no more data to send": everything sent before it is still delivered and retransmitted if needed, the `FIN` itself occupies one sequence number and is acknowledged, and the peer may keep sending until it closes its own direction. A graceful close therefore takes a FIN and an ACK in each direction and leaves the side that closed first in `TIME-WAIT`. An `RST` aborts: in RFC 9293 the ABORT call flushes queued and unacknowledged data, sends a reset carrying `SND.NXT`, deletes the connection record and enters `CLOSED`. The receiver accepts the reset only if its sequence number falls in the receive window, then reports "connection reset" to the application and discards its state. The application MUST be told which of the two ended the connection.
go deeper
Recall the one-line contrast: FIN is a graceful, per-direction close that still delivers queued data; RST aborts everything immediately and the peer sees a reset error.
Walk the four-step FIN exchange with the states on each side, explain that FIN consumes a sequence number, and describe what ABORT flushes and why a reset has no retransmission.
Explain where resets come from in production: closing with unread data, aborted closes, segments for vanished connections, and why the receiver validates a reset against its window before acting.
Frame the choice as data integrity versus speed: FIN guarantees delivery of what was sent, RST trades that for immediacy, so protocols built on TCP should never rely on abortive closes for correctness.
## Two ways a TCP connection ends RFC 9293, the current TCP specification (it obsoletes RFC 793), says a connection can terminate in exactly two ways: the **normal close**, a handshake of `FIN` segments, and an **abort**, in which one or more `RST` segments are sent and the connection state is discarded immediately. The two are not a fast and a slow version of the same thing. They make opposite promises about the data still in flight. Two terms first: - A **segment** is one TCP packet: a header plus optional data. - `FIN` ("finis") and `RST` ("reset") are **control bits** in the TCP header. Setting one changes what the segment means. ## The graceful close: FIN, one direction at a time A TCP connection is two independent byte streams, one in each direction. `FIN` closes only the stream of the endpoint that sends it. RFC 9293 defines the CLOSE operation as meaning **"I have no more data to send"**, not "I will not receive any more". In the specification's normal close sequence: 1. Endpoint A's application closes. A queues a `FIN` behind any data it still has to send and enters `FIN-WAIT-1`. 2. Endpoint B acknowledges the `FIN`, tells its application that the peer is closing, and enters `CLOSE-WAIT`. A moves to `FIN-WAIT-2`. 3. B's application eventually closes too. B sends its own `FIN` and enters `LAST-ACK`. 4. A acknowledges B's `FIN` and enters `TIME-WAIT`, where it stays for twice the maximum segment lifetime (2×MSL). B deletes the connection when that last ACK arrives. Three properties matter: - **Nothing is lost.** Every byte sent before the `FIN` is delivered, and retransmitted if necessary, before the close completes. - **The FIN is sequenced.** It occupies one sequence number, exactly as one data byte would, so it is acknowledged and retransmitted like data. The ACK for a FIN sent at sequence number 100 carries 101. - **It is per direction.** Between steps 2 and 3 the connection is *half-closed*: B may keep sending and A must keep receiving. ## The abort: RST `RST` ends both directions at once. RFC 9293's ABORT call aborts all pending sends and receives, flushes everything queued for transmission or retransmission, sends a single segment `<SEQ=SND.NXT><CTL=RST>`, deletes the connection record (the TCB) and enters `CLOSED`. No `FIN` exchange follows and the aborting side keeps no record of the connection. On the receiving side, a reset is first **validated**: in every state except `SYN-SENT`, it counts only if its sequence number lies inside the receive window (in `SYN-SENT`, only if it acknowledges the SYN). RFC 5961's optional mitigation, which RFC 9293 folds in, tightens this further: a reset whose sequence number is exactly the next expected one resets the connection, and one that is merely in the window draws a "challenge ACK" instead. A valid reset makes the receiver hand "connection reset" to any outstanding sends and receives, flush its queues and go to `CLOSED`. The abort path has no retransmission: the TCB that would retransmit is gone. If the reset is lost, the peer finds out when its next segment reaches an endpoint that no longer knows the connection and draws a fresh reset in reply. ## When TCP sends a reset - **A segment arrives for a connection that does not exist.** A `CLOSED` endpoint answers any incoming segment, except another reset, with `RST`. This is how a SYN to a port with no listener is refused. - **The application aborts.** The user asked for ABORT rather than CLOSE. - **Data would be lost on close.** A host may implement a "half-duplex" close in which an application that has closed cannot read any more. If such an application closes while received data is still unread, or data arrives after the close, the stack SHOULD send `RST` to show that data was lost (RFC 9293 §3.6.1). - **A close cannot finish.** If the closing side cannot get rid of its data before the user timeout, RFC 9293 says CLOSE turns into ABORT. - **An unacceptable ACK arrives before the connection is synchronized**: in `LISTEN`, `SYN-SENT` or `SYN-RECEIVED`, a segment acknowledging something never sent draws a reset. ## Side by side | | `FIN` (close) | `RST` (abort) | |---|---|---| | Scope | one direction | the whole connection | | Queued and unacknowledged data | delivered, retransmitted | discarded | | Uses a sequence number | yes, one | no; it is only validated against the window | | Acknowledged | yes | no | | Where the sender ends up | `FIN-WAIT-1`, later `TIME-WAIT` if it closed first | `CLOSED` at once | | What the peer's application sees | end of stream after all data | "connection reset" error | ## What the application sees RFC 9293 makes this a MUST: when the remote side ends the connection, the local application must be told whether it **closed normally or was aborted**. In the POSIX socket model a peer's `FIN` shows up as `recv` returning zero bytes after all earlier data, while a reset shows up as an error on the next call. That difference is the practical test: a FIN is a sentence finished, a reset is a line cut mid-word, and anything the peer had not yet read when the reset landed is gone.
- Why might an application's ordinary close put an RST on the wire instead of a FIN?RFC 9293 §3.6.1 allows a "half-duplex" close, where an application that has closed can no longer read. If it closes while received data is still unread, or data arrives after the close, the stack SHOULD send `RST` so the peer knows data was lost. A close that cannot finish sending before the user timeout also turns into an abort.
- Does a TCP endpoint accept any RST that carries the right addresses and ports?No. Outside `SYN-SENT`, RFC 9293 accepts a reset only if its sequence number is inside the receive window; in `SYN-SENT` it must acknowledge the SYN. With RFC 5961's mitigation, only an exact match on the next expected sequence number resets the connection, and an in-window near-miss draws a challenge ACK. How attackers still try to inject resets belongs to the in-window injection topic.
saying these in an interview costs you the question
- A FIN closes both directions, so the peer can no longer send anything
- An RST is just a faster FIN that still delivers the queued data
- An RST is acknowledged and retransmitted until the peer confirms it
- Any RST with the right addresses and ports resets the connection
- A FIN uses no sequence number because it carries no data