当前位置:网站首页>TCP half connection establishes connection with full connection queue and accept

TCP half connection establishes connection with full connection queue and accept

2020-12-07 17:08:28 osc_ o0u19uzc

We know that when the server is bound 、 After listening to the specified port , The kernel will usually be for every LISTEN State of socket Maintain two queues :

  1. SYN queue ( Semi connected queues ): from /proc/sys/net/ipv4/tcp_max_syn_backlog Appoint , To be in SYN_RECV Status queue
  2. ACCEPT queue ( Full connection queue ): from listen() The second parameter of the function backlog Appoint , The kernel is hard limited by net.core.somaxconn Limit , That is, the actual value is determined by min(backlog,somaxconn) To decide . Represents the queue that has completed the connection , Waiting to be accept The system call takes away .

 Picture description here

TCP How to shake hands three times with accept Interaction ?

Look at the picture below :

 Picture description here

Client side usage connect Send to server TCP Connect , Three handshakes happened . When 1.1 step The client first sends SYN After arriving at the server , The kernel will put the connection information into SYN In line , At the same time, return one SYN+ACK Package to client . After a while , The client sent again ACK After package , The kernel will take the connection from SYN Take out... From the queue , And put this connection in ACCEPT In line . Server calls accept when , In fact, it is directly from ACCEPT Take out the connection socket that has been established successfully from the queue .

And here's another picture TCP The process and queue of establishing connection during handshake :

 Picture description here


What happens when the team is full

Q: Why? Some application server processes , Will use a single thread to call accept To establish a connection between the server and the client , such as tomcat; And some have a thread that does everything , That is, after getting the connection, it will do I/O Other operations ?

A: First SYN Queue and ACCEPT The queues are not infinite , As mentioned above . Since the queue length is limited , Then there will be a full time . For example, when the steps in the figure above 1 The execution speed of is faster than that of 2 The speed of step execution ,SYN The queue will keep growing , Until the queue is full ; The first 2 The execution speed of step is much faster than that of step 3 Step speed ,ACCEPT The queue will also be full . The first 1、2 Steps are not program controlled , The first 3 Step is the behavior of the program .

Let's look at the first case :SYN The queue is full . If SYN The queue is full , The connection request will be discarded directly .
such as syn floods The attack is aimed at semi connected queues , The attacker keeps building connections , But when making a connection, only do the first step , In the second step, the attacker receives server Of syn+ack After deliberately throwing away nothing to do ,server It takes a timeout to disconnect this connection , Otherwise, a lot of these connections lead to server The queue is full of other normal requests and can't come in .

The second case :ACCEPT The queue is full . This seems to be a complicated situation , I checked the schoolmaster's blog , It was found that the elder had discussed this problem .accept The queue is full of discussions
If ACCEPT The queue is full ,server adopt /proc/sys/net/ipv4/tcp_abort_on_overflow To decide how to return :

  1. tcp_abort_on_overflow by 0, Will not connect from SYN Remove... From the queue ,server Send it again after a while syn+ack to client( This is the second step of the handshake ), Repeat it several times in this way , The number of times by /proc/sys/net/ipv4/tcp_synack_retries(centos The default is 5 ) Appoint , If you shake hands three times, step three ACCEPT The queue is always full , that server Throw away client Sending a ACK( stay server The end thinks that the connection has not been established );

  2. tcp_abort_on_overflow by 1 In the third step, if ACCEPT The queue is full ,server Send a RST Give it to client, It means to discard the handshake and the connection ( Originally server The connection has not been established yet ), The client will appear connection reset by peer It's abnormal .

PS: There's another fact , commonly overflowed Indicates the number of full connection queue overflows ,socket ignored Indicates the number of times a semi connection queue overflows , These two are added simultaneously ,overflow It will be socket ignored++.

So for the application server process , If ACCEPT There are already established TCP Connect , But they didn't take it out in time , In this way, once the two queues are full, the client will not be able to establish a new connection , Causing serious problems . therefore , such as tomcat Wait for the server to use a separate thread only to do accept Getting the connection , In case you can't go in time accept Get the connection .


Q: But we know things like Ngnix Wait for the server , Do it in a thread accept At the same time , And do other things IO operation , Why is that ? Doesn't it care about the above ?

A: Applications can put listen Set the listening socket to non blocking mode ( The default is blocking mode ), These two patterns lead to accept Methods have different behaviors .
Blocking sockets ,accept The behavior is as follows :

 Picture description here

It will always wait ACCEPT The queue is not empty ,ACCEPT Whether the queue is empty , Whether it is initiated by the client connect On request .

Non blocking socket ,accept The behavior is as follows :

 Picture description here

In non blocking mode , There is no waiting ACCEPT The stage where the queue is not empty , Go straight back to , Either return the connection socket , Either return the error .

therefore , Enterprise server process , If a thread uses both accept Get a new connection , Continue reading on this link again 、 Write character stream , that , The socket corresponding to this connection is usually set to non blocking .


Then the whole connection queue is full and I continue to think : Now client After the third step , So in client It seems that the connection has been established , however server It's not actually ready , If at this point client Send data to server,server How to deal with it ?
A:client Send a packet to server after ,server The connection on does not actually have ready,server There has been no reply , After a while client Think it's lost , And then retransmit the bag , Until the timeout ,client Take the initiative FIN Package disconnected .


Reference link :
1. About TCP Semi and full connection queues
2. accept Establishing a connection
3. Explore in depth Linux listen() function backlog The meaning of


版权声明
本文为[osc_ o0u19uzc]所创,转载请带上原文链接,感谢
https://chowdera.com/2020/12/202012071704341134.html