Chapter 13. TCP Connection Management¶
TCP is a unicast connection-oriented protocol. Before either end can send data to the other, a connection must be established between them. TCP detects and repairs essentially all the data transfer problems that may be introduced by packet loss, duplication, or errors at the IP layer (or below).
Because of its management of connection state (information about the connection kept by both endpoints), TCP is a considerably more complicated protocol than UDP (Chapter 10). UDP is a connectionless protocol that involves no connection establishment or termination. One of the major differences between the two is the amount of detail required to handle the various TCP states properly: when connections are created, terminated normally, and reset without warning. Other chapters discuss what happens once the connection is established and data is transferred.
During connection establishment, several options can be exchanged between the two endpoints regarding the parameters of the connection. Some options are allowed to be sent only when the connection is established, and others can be sent later. The TCP header has a limited space for holding options (40 bytes). (Chapter 12)
TCP Connection Establishment and Termination¶
A TCP connection is defined to be a 4-tuple consisting of two IP addresses and two port numbers. It is a pair of endpoints or sockets where each endpoint is identified by an (IP address, port number) pair.
A connection typically goes through three phases:
- Data transfer (called established)
- Teardown (closing).
Some of the difficulty in creating a robust TCP implementation is handling all of the transitions between and among these phases correctly.
A typical TCP connection establishment and close (without any data transfer) is shown below:
Connection Establishment *¶
To establish a TCP connection, the following events usually take place:
- The active opener (normally called the client) sends a SYN segment (a TCP/IP packet with the SYN bit field turned on in the TCP header) specifying the port number of the peer to which it wants to connect and the client’s initial sequence number or ISN(c) (Section 13.2.3). It typically sends one or more options at this point (Section 13.3). This is segment 1.
- The server responds with its own SYN segment containing its initial sequence number (ISN(s)). This is segment 2. The server also acknowledges the client’s SYN by ACKing ISN(c) plus 1. A SYN consumes one sequence number and is retransmitted if lost.
- The client must acknowledge this SYN from the server by ACKing ISN(s) plus 1. This is segment 3.
These three segments complete the connection establishment. This is often called the three-way handshake. Its main purposes are to let each end of the connection know that a connection is starting and the special details that are carried as options, and to exchange the ISNs.
The side that sends the first SYN is said to perform an active open. This is typically a client. The other side, which receives this SYN and sends the next SYN, performs a passive open. It is most commonly called the server. (Section 13.2.2 describes a supported but unusual simultaneous open when both sides can do an active open at the same time and become both clients and servers.
TCP supports the capability of carrying application data on SYN segments. This is rarely used, however, because the Berkeley sockets API does not support it.
Connection Termination *¶
The figure above also shows how a TCP connection is closed (also called cleared or terminated). Either end can initiate a close operation, and simultaneous closes are also supported but are rare. Traditionally, it was most common for the client to initiate a close. However, other servers (e.g., Web servers) initiate a close after they have completed a request. Usually a close operation starts with an application indicating its desire to terminate its connection (e.g., using the
close() system call). The closing TCP initiates the close operation by sending a FIN segment (a TCP segment with the FIN bit field set). The complete close operation occurs after both sides have completed the close:
- The active closer sends a FIN segment specifying the current sequence number the receiver expects to see (K in Figure 13-1). The FIN also includes an ACK for the last data sent in the other direction (labeled L in Figure 13-1).
- The passive closer responds by ACKing value K + 1 to indicate its successful receipt of the active closer’s FIN. At this point, the application is notified that the other end of its connection has performed a close. Typically this results in the application initiating its own close operation. The passive closer then effectively becomes another active closer and sends its own FIN. The sequence number is equal to L.
- To complete the close, the final segment contains an ACK for the last FIN. Note that if a FIN is lost, it is retransmitted until an ACK for it is received.
While it takes three segments to establish a connection, it takes four to terminate one. It is also possible for the connection to be in a half-open state, although this is not common. This reason is that TCP’s data communications model is bidirectional, meaning it is possible to have only one of the two directions operating. The half-close operation in TCP closes only a single direction of the data flow. Two half-close operations together close the entire connection. The rule is that either end can send a FIN when it is done sending data. When a TCP receives a FIN, it must notify the application that the other end has terminated that direction of data flow. The sending of a FIN is normally the result of the application issuing a close operation, which typically causes both directions to close.
The seven segments discussed are baseline overheads for any TCP connection that is established and cleared "gracefully". (There are more abrupt ways to tear down a TCP connection using special reset segments, which are covered later.) When a small amount of data needs to be exchanged, it is now apparent why some applications prefer to use UDP because of its ability to send and receive data without establishing connections. However, such applications are then faced with handling their own error repair features, congestion management, and flow control.
TCP supports a half-close operation. Few applications require this capability, so it is not common. To use this feature, the API must provide a way for the application to say, "I am done sending data, so send a FIN to the other end, but I still want to receive data from the other end, until it sends me a FIN."
The Berkeley sockets API supports half-close, if the application calls the
shutdown() function instead of calling the more typical
close() function. Most applications, however, terminate both directions of the connection by calling close. The figure below shows an example of a half-close being used. It shows the client on the left side initiating the half-close, but either end can do this.
The first two segments are the same as for a regular close: a FIN by the initiator, followed by an ACK of the FIN by the recipient. The operation then differs from Figure 13-1, because the side that receives the half-close can still send data. We show only one data segment, followed by an ACK, but any number of data segments can be sent. (The exchange of data segments and acknowledgments is detailed in Chapter 15.) When the end that received the half-close is done sending data, it closes its end of the connection, causing a FIN to be sent, and this delivers an end-of-file indication to the application that initiated the half-close. When this second FIN is acknowledged, the connection is completely closed.