The TCP Finite State Machine
In this context of discussion, a client is the peer that requests a connection; and a server is the peer that accepts a connection.
Handshake is a series of information exchanged between devices to ensure both ends are synchronized for data transmission and operation.
|Active open||A client socket initiates a connection by sending a SYN segment which contains the server’s port number and the client’s Initial Sequence Number (ISN). The client socket enters into the SYN_SENT state.|
|Passive open||Indicates a server socket is opened and listening or waiting for incoming SYN.|
|Active close||Initiated by the client socket when it finished receiving data. The client socket sends a FIN segment and enters into the FIN_WAIT_1 or FIN_WAIT_2 state. The connection is now a half-closed connection, where the client no longer sends data but still able to receive data from the server. |
The server socket enters into the passive close state upon receiving the FIN segment from the client.
|Passive close||Occurs when the server socket receives the FIN segment from the client active close. The server socket enters into the CLOSE_WAIT state. The server socket is waiting for the server application to close. The server sends its FIN when the server application is closed.|
|Simultaneous open||Occurs when both client and server applications send a SYN to each other to establish a TCP connection. However, the possibly is small, as the server required to know the port of the client host that the SYN should destined to. |
TCP simultaneous open is normally found in P2P applications.
|Simul. close||Occurs when both client and server applications perform active close.|
A connection goes through the following states during its lifetime:
|LISTEN||The server socket waits for a connection request from any remote client host.|
|SYN_SENT||The client socket waits for an acknowledgment after a connection request is sent.|
|SYN_RECEIVED||The server socket receives a connection request and pending to reply an acknowledgment to the client. The SYN Flood DoS attack would typically cause a lot of TCP connections in this state.|
|ESTABLISHED||Represents an established connection. Data communication is allowed. The normal state for the data transfer phase of a connection.|
|FIN_WAIT_1||The client socket has initiated active close and wait for an acknowledgment from the server after a connection termination request (FIN segment) is sent.|
|FIN_WAIT_2||The client socket has received an acknowledgment for its connection termination request but is still waiting for the connection termination request (FIN segment) from the server.|
|CLOSE_WAIT||The remote client socket is closed. The server socket enters into passive close state and waits for a connection termination request from the server application.|
|CLOSING||The client socket waiting for a connection termination acknowledgment from the remote server socket.|
|LAST_ACK||The server application and socket are closed. Waiting for the final ACK for the connection termination request from the remote client socket.|
|TIME_WAIT||The client socket waiting for enough time to pass to make sure the stray packets destined to the closed socket are flushed out from the network.|
Q: How does a client application enter the ESTABLISHED state from the CLOSED state?
A: The client application calls the connect() socket function, which causes TCP to send an empty segment with the SYN bit set and enters into the SYN_SENT state. The server then replies with an empty segment with the SYN and ACK bits set. When the client receives the SYN/ACK segment, it replies with and ACK segment, and reports a successful connection establishment to the client application.
Q: What is the normal TCP shutdown sequence?
A: TCP is a bidirectional protocol – the connection is shutdown in 2 identical phases, one for each direction. When the server finished sending data (the application protocol has finished using the connection, but TCP still has some works to perform), it sends a segment with the FIN bit set, which the client replies with a segment with ACK bit set. This sequence happens again when the server waits for the FIN segment from the client, and replies with an ACK segment to the client.
Note: This is the normal TCP shutdown sequence observed in application layer protocols (eg: HTTP and Telnet), which reverse the client and server roles in TCP, as TCP assumes that clients tend to initiate active close (by first sending a segment with the FIN bit set).
Q: What is the usage of the RST bit?
A: It represents an abnormal close, which happens under several circumstances. The 2 common TCP reset occurrences are “connection refused” and “connection terminated by remote host”. The 1st case happens when trying to connect to a non-open port on a remote host, while the 2nd case happens when the remote host interrupts the connection, the application crashes, or there is a malicious insertion of a segment with the correct IP and TCP information (eg: source and destination IP addresses, source and destination port numbers, sequence number) and RST bit set. A TCP session that ends with a TCP reset may not indicate a problem. Sometimes TCP resets indicate a network problem (misconfigured IPS), but there are cases in which a TCP reset is OK. Application developers may elect to issue a TCP reset instead of the exchange of FIN-ACK packets to free up resources more quickly when tearing down a connection-oriented TCP session.
Q: What’s wrong when connections keep getting into the FIN_WAIT_x state?
A: Either the application or remote host is not closing the connection properly. Since FIN_WAIT states often last up to 10 minutes, it is well worth the effort to find and fix the root cause.
Q: What’s wrong when there are many connections in the TIME_WAIT state?
A: Nothing wrong. TIME_WAIT is absolutely normal. Every socket that gets closed normally goes through this state after it is closed. This state is a safety mechanism that catches stray packets that are destined for a closed connection. Since the maximum time that such stray packets can exist is 2 times the maximum segment lifetime, hence the TIME_WAIT state lasts for 2 x MSL. However, there is no easy way to estimate MSL on the fly, so protocol stacks normally hard-code a value (15 – 60 sec) for it. Hence, TIME_WAIT usually lasts 30 – 120 sec.
|Stray packets||Duplicate packets that are still in the network when a connection is closed.|
|MSL||The maximum length of time a TCP segment can exist (or alive) in a network.|
|Stack||The software implementation of a network protocol suite (eg: TCP/IP).|
HTTP and TCP TIME_WAIT State
Due to the nature of TCP/IP, it is possible that after an active close has commenced, there are duplicate packets that traversing around the network and trying to reach their destination sockets. If a new socket binds to the same port before these old packets are flushed out from the network, old and new data could be mixed up.
In HTTP, active close always initiated by the server. A server socket enters the TIME_WAIT state when it receives the last FIN from the client and replies with an ACK.
Application protocol (eg: HTTP and Telnet) servers tend to initiates active close than clients, which reversed the client and server roles in TCP, as TCP assumes that clients tend to initiate active close. If that is the case, TIME_WAITs won’t be existed in a busy web server as they do. When the active close is initiated by clients, the TIME_WAIT state and the responsibility of keeping old and new data from intermixing would tend to be on the client sockets.