TCP Fast Open principle and use

TCP connection establishment requires a three-way handshake, as everyone knows. However, the three-way handshake will lead to a decrease in transmission efficiency, especially for short connection protocols such as HTTP. Although HTTP has keep-alive to improve the performance of some frequently requested HTTPs, avoiding some three-way handshake times, but still hope to bypass the three times. Handshaking improves efficiency, or doing the data transmission at the same time as the three-way handshake. This is what we are talking about this time, TCP Fast Open, or TFO for short.

First, let's review the process of the three-way handshake:
TCP three-way handshake
here the client can bring the first piece of data that it wants to send at the last ACK, so this is one of the optimization schemes made by TFO. Then I also refer to the HTTP login state process, using the Cookie scheme to let the server know that a certain client has "logged in" before, then the data it sends can be received directly, and it is not necessary to have a three-way handshake at the beginning Send the data later.
When the client connects to the server for the first time, there is no Cookie, so an empty Cookie will be sent, which means requesting a Cookie, as shown in the figure below: Then the
TFO 空 Cookie
server will return the Cookie to the client through the SYN+ACK path After the client saves it, it sends the last ACK of the three-way handshake to the server at the same time.
When the client disconnects, the next time it requests the same server, it will bring the previously stored Cookie and the data to be sent, and send them to the server along the SYN path, as shown in the following figure:
TFO Cookie
so that every time after the handshake At the same time, the data message was sent to advance the data transmission. As long as the server verifies the cookie, it will receive the sent data, otherwise it will discard and return a new cookie through the SYN+ACK path. This situation is generally caused by the cookie expiration.

TFO needs to be turned on, the opening parameters are:

/proc/sys/net/ipv4/tcp_fastopen
0:关闭
1:作为客户端使用Fast Open功能,默认值
2:作为服务端使用Fast Open功能
3:无论是客户端还是服务端都使用Fast Open功能

And if the previous code does not do this processing, it cannot be used. From the above flowchart, you can see that the client sends data during the connection process, but before the client calls connect successfully, Only use send to send data.

The server needs to set the following options for the listen socket:

//需要的头文件
#include <netinet/tcp.h>

......

int qlen = 5;	//fast open 队列
setsockopt(m_listen_socket, IPPROTO_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen));

The client directly uses the sendto method to connect and send data. The sample code is as follows:

#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

int main(){
    
    
	struct sockaddr_in serv_addr;
	struct hostent *server;
 
	const char *data = "Hello, tcp fast open";
	int data_len = strlen(data);    
	
	int sfd = socket(AF_INET, SOCK_STREAM, 0);
	server = gethostbyname("10.104.1.149");
	
	bzero((char *) &serv_addr, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	bcopy((char *)server->h_addr, 
		 (char *)&serv_addr.sin_addr.s_addr,
		 server->h_length);
	serv_addr.sin_port = htons(5556);

	int len = sendto(sfd, data, data_len, MSG_FASTOPEN/*MSG_FASTOPEN*/, 
				(struct sockaddr *) &serv_addr, sizeof(serv_addr));
	if(errno != 0){
    
    
		printf("error: %s\n", strerror(errno));
	}
	
	char buf[100] = {
    
    0};
	
	recv(sfd, buf, 100, 0);
	printf("%s\n", buf);
	
	close(sfd);

}

After experimentation, the cookie stored by the client is bound to the IP of the server, not to the process or port. When the client program sends to a process with the same IP but different ports, the same Cookie is used, and the server is also authenticated successfully.

Guess you like

Origin blog.csdn.net/wyb_robin/article/details/107129338