TCP Connection Management

When any communication occurs, at least one side participating in the communication makes a communication request to determine whether the other side is available. it is the same in the TCP protocol, the initiating process is known as Synchronization, due to TCP provides the application layer reliable byte stream data transmission, it will asign each byte of the application layer data a sequence number, actually the number of the first byte known as ISN (Initial Sequence Number) is not started with 0 or 1, but generated by a specific algorithm, ISN value in the range of [0, 2^32-1]. The two sides of TCP communication need to swap each other’s ISN to control the transmission of the byte stream. The process of exchanging the ISN is called the TCP connection establishment process, and is also called the virtual connection or virtual circuit establishment process. When communication finishing, both ends also need to have a specific interaction process to release the connection. Why do you need to change the ISN to create a connection? Why doesn’t ISN start with 0 or 1? How does full duplex TCP communication control disconnection? This section focuses on TCP connection management and all these problems.

ISN

Select a proper ISN

Why doesn’t the ISN starting with 0 or 1, and why later RFC changes RFC793 to generate the ISN according to time. There are two main reasons for this. The first reason is to prevent data from being mixed up between TCP’s incarnation connections (that is, using the same quadrics to establish a TCP connection again). The second reason, for security considerations, is to prevent network attacks that predicting TCP segment Numbers.

References
RFC0793 TRANSMISSION CONTROL PROTOCOL
RFC6528 Defending against Sequence Number Attacks
TCP_sequence_prediction_attack
A Weakness in the 4.2BSD Unix† TCP/IP Software

Why both endpoints exchange ISN

Establishing a TCP connection is not a matter of establishing a true physical path, but rather a logical level of connection. The client needs to send the byte stream to the server side, after the server receives the byte stream, it has to sort the bytes in right order because that the IP packets that carry the byte stream will not arrive in the orgnizied order. So the first question for the server side is, which byte is the first byte sent by the client side? So before communication begins, the client must tell the server what the sequence number of the first byte will be. Since TCP is a two-way communication, the client also needs to know the first byte sequence number of the byte stream sent by the server. The two processes complete the swap of ISN are handshakes.

Three-way-handshake

It’s require 3 handshake stages to establish a TCP connection. This procedure happened at the second stage of 《tcp comminication model》

Run the Server process with GDB, single step to function Accept(). Run the Client process, single st ep to Connect(), sniff the TCP segment with Wireshark, [1.SYN],[2.SYN,ACK],[3.ACK].

Segment [1.SYN], ISN is 209863725. Among the flags bits, SYN is set to 1 to identify this one is a SYN segment.

The details of TCP segment data [2.syn, ACK] are as follows: its own ISN is 354358497, and the ACK of [1.syn] is 209863726. The flag bit SYN and the ACK is set to 1.

[3.ACK] acknowledege the [2.SYN] ISN, the ack number is 354358498. At this moment both sides know the ISN of each other.

During the communication establishing process, except the exchanging of ISN, there are some other parameters exchanging and discussion, like the communication window size , the fast retransmittion, the time stamps etc, which will be discussed later.

A normal communication, data back and forth

After the communication connection is established, the process begins to send and receive the application layer data. The server blocks and waits to receive the request message from the client. After the client sends the request, it waits for the response from the server. The server sends the response message.

1
2
3
4
5
6
7
8
9
10
11
12
13
//server.c
//服务端Server接收Client进程的消息
Readline(connectfd, requestbuf, sizeof(requestbuf));

//client.c
//客户端Client进程发送请求消息
Write(sockfd, l(char*) request, strlen(request));
//阻塞等待从Server进程接收一行响应消息
Readline(sockfd, response, MAXLINE);

//server.c
//Server进程返回响应消息给Client进程,消息格式为"response, <hostname>\r\n"
Write(connectfd, responsbuf, strlen(responsbuf));

I debug running the Server and Client with GDB and check the TCP segments with Wireshark. [4.request],[5.ACK],[6.reponse],[7.ACK].

[4.request] is the first TCP segment which carries the application layer data. The first byte sequence number is ISN+1=209863726. The data lenth is 18Bytes as known as “request,hostname”.

[5.ACK] is the ack from server to the client. ACK number is 209863744, which means all the 18 bytes have been received.

[6.reponse] is the reponse message from server to client.14Bytes length, the content is “response,guru”.

[7.ACK] is the ack from client to server, ACK number is 209863744.

Disconnection

When the application layer communication ends, the application layer calls the function Close() to close the file descriptor or the process itself ends and results in the automatic release of the file descriptor. This behavior will trigger the TCP module to send disconnection TCP segment data AKA FIN segment. When the FIN segment is received by the other end, the kernel of the other end will translate the FIN segment into EOF (End of file) to the receiving process.

1
2
3
4
5
6
7
//client.c
//关闭socketfd,向服务进程发送FIN段
Close(sockfd);

//server.c
//关闭connectfd,向客户进程发送FIN段
Close(conectfd);

It’s easy to find out that up to 4 interactions is required to release a TCP connection.In some cases [9.ACK] and [10.FIN] can be sent together. Why does TCP use four interactions for the disconnection process? Because TCP is to send and receive data can be simultaneously full-duplex, equivalent to that a connection is established, there are two one-way data pipelines connecting the two communication process, one of these processes can only know if there are any data to be sent to the counter part, but cannot decide whether the other end has data to send to itself. So TCP supports one-way pipeline shutdowns, and if a one-way shutdown is required explicitly, the function shutdown() can be used, with the file descriptor still available.

Run sever and client to Close() with GDB, observe the segments with Wireshark. [8.FIN],[9.ACK],[10.FIN],[11.ACK].

[8.FIN], there are no data at the client process. The client call Close() to close the socket fd. The client os makes a FIN to send.

[9.ACK], Acknowledge of the first FIN. No more data will be received now, but maybe there are data to be sent.

[10.FIN], The server makes it clear that no more data is sent to the client.

[11.ACK], The client confirms the [10.FIN] notification sent by the server, and 1 TCP communication ends.

The above process is a complete TCP communication process. The communication process is a client-server model, and the client terminates the communication first. In the communication process, there is no abnormal situation, no host downtime, process abnormal exit and other events happen, which is the most common communication process.