Home > Experiential Learning > Experiential Learning of Networking Technologies: Understanding TCP States – Part 2

Experiential Learning of Networking Technologies: Understanding TCP States – Part 2

As long as the application running on $H_{2}$ has more data to send, the data will be sent over the connection (5) and it is received (5) and acknowledged by $H_{1}$ (6). This acknowledgement will be received by $H_{2}$ (6). As soon as the application running on $H_{2}$ determines that no more data is to be sent, it sends a FIN message (3). When this is received by $H_{1}$ (3), the TCP connection state on $H_{1}$ moves from FIN_WAIT2 to TIME_WAIT and an ACK (4) is transmitted. Note that the TCP connection state on $H_{1}$ does not move directly to the CLOSED state because, as discussed in detail in [8], it is necessary to ensure that no new connection with same TCP tuple (i.e. source IP address, source port number, destination IP address, destination port number) is used until all packets corresponding to an earlier such connection could be lingering in the network. This waiting time is known as 2MSL (twice the maximum segment lifetime) and is typically 120s. Another reason is that if there is no TIME_WAIT state (i.e., if $H_{1}$ directly enters the CLOSED state) and if the ACK (4) message gets lost, then $H_{2}$ will remain in the LAST_ACK state until timeout occurs. When $H_{2}$ retransmits the FIN message again, there may be no connection state on $H_{1}$, and thus $H_{1}$ will respond with TCP Reset (indicating an error condition), which leads to ungraceful connection termination [8].

Let us consider the typical case of TCP connection teardown, which occurs when there is no network abnormality (as is usually the case). Suppose the application running on $H_{2}$ invokes the close() call. This application will follow the TCP state transitions corresponding to active close (left side of Figure 2) whereas the application on $H_{1}$ will follow the TCP state transitions corresponding to passive close (right side of Figure 2). Thus, $H_{2}$ will send the FIN (1) message and move its TCP connection state to FIN_WAIT1. When $H_{1}$ receives the FIN (1) message, it sends the ACK (2) message and moves its TCP connection state to CLOSE_WAIT. When this ACK (2) message is received by $H_{2}$, it moves to the FIN_WAIT2 state. At this point, let us suppose that the application on $H_{1}$ has no further need for the connection. Thus, immediately after sending the ACK (2) message, it sends its own FIN (3) message and moves to the LAST_ACK state. When $H_{2}$ receives the FIN (3) message, it responds with ACK (4) and moves the state from FIN_WAIT2 to TIME_WAIT. When $H_{1}$ receives the ACK (4) message, its releases all the resources associated with this connection and completely closes this connection. This is depicted by the CLOSED state, which essentially implies that no connection exists. However, the application on $H_{2}$ remains in the TIME_WAIT state for 2MSL (two times Max Segment Lifetime), as discussed in detail in [8] and corresponding program details in [9].

In the screenshots below, the names of the machines $H_{1}$ and $H_{2}$ are part of the command prompts and are preceded by the date/time to show the order in which commands were issued. Command windows are also split into an upper and a lower panel to improve clarity. The upper panel in each figure shows the command to invoke the application, initiate data transfer, and connection termination whereas the lower panel is used to display the TCP connection state and any firewall rule(s) that need to be configured. We assume that all experiments begin with no firewall rules set. To ensure this, we recommend issuing the command sudo iptables -F on the machines before each experiment.

Experiment 1:
TCP State transition for normal TCP application closure.

The following experiment demonstrates this typical teardown scenario in Figure 3 and Figure 4. In Figure 3, the application on $H_{2}$ moves the TCP connection state from LISTEN to ESTABLISHED and then, via intermediate transient states (as discussed above), to TIME_WAIT as shown by the last line of the lower panel of this figure.

Figure 3: TCP state for a general application initiating termination
Figure 4: TCP state for a general application receiving termination from other side

The states followed by the application on $H_{1}$ similarly shown in Figure 4. Thus, from the ESTABLISHED state, the TCP connection follows intermediate transient states of CLOSE_WAIT and LAST_ACK before completely releasing all the associated resource.

Under normal circumstances, the TCP connection closure follows the expected path and there is little reason for developers to have this detailed understanding of state changes. However, in some critical service function applications, the branding image and possibly the revenue of the service provider could be impacted if users perceive unsuccessful or delayed connection. For such applications, it is imperative that developers understand the details of various TCP termination states and the general conditions that lead to these states. We will now consider the situation where network failures during the teardown phase cause problems that can be diagnosed and rectified using our detailed understanding.

4 TCP Connection Closure FIN_WAIT1 state

Experiment 2:
TCP State FIN_WAIT1 ($H_{1}$) and ESTABLISHED ($H_{2}$)

In the absence of network faults, when $H_{1}$ sends a FIN message and moves to state FIN_WAIT1, it can expect to get an ACK almost immediately (i.e., within a few milliseconds) and thus move to state FIN_WAIT2. Thus, to observe $H_{1}$ in the transient state FIN_WAIT1, we need to simulate a network fault. As in our previous article [8], we will make use of the iptables utility to create abnormal network conditions.

In Figure 2, observe that $H_{1}$’s TCP connection state will remain in FIN_WAIT1 if it sends a FIN message but does not receive an ACK. This can occur either because the FIN message was lost in the network or the FIN was received but the ACK did not reach the application initiating connection close. The upper panel in Figure 5 shows an application on machine $H_{2}$ starting to run on TCP port 7777 at time 16:28:53, and the first line in the lower panel shows that the TCP connection state is LISTEN at time 16:28:57 (as described in detail in [8]). The application on machine $H_{1}$ connects to the application on machine $H_{2}$ at 16:30:22, as shown in the upper panel of Figure 6. The TCP connection state becomes ESTABLISHED, as shown by the output of the first command (issued at 16:30:41). Next, the text message “Hello” is exchanged, as shown in the upper panels of both these figures. To mimic the scenario where the FIN message is lost in the network, an iptables command is issued on $H_{1}$ to drop all FIN packets sent from $H_{1}$ with the destination port 7777 (shown by the third command in the lower panel of Figure 6). Now the application on $H_{1}$ is terminated by pressing Ctrl-C, as shown by the fourth line in the upper panel of Figure 6. When the TCP state is subsequently checked (fourth command in the lower panel of Figure 6), it is FIN_WAIT1 at time 16:31:48. Since $H_{2}$ does not receive the FIN message (because of the iptables command on $H_{1}$), the TCP connection remains in the ESTABLISHED state, as shown by the last command in the lower panel of Figure 5 at time 16:31:55.

Figure 5: Server states for understanding FIN_WAIT1
Figure 6: Client state for understanding FIN_WAIT1

Pages ( 2 of 5 ): « Previous1 2 345Next »

Leave a Comment:

Your email address will not be published. Required fields are marked *