TCP的全連接和半連接隊列

TCP的全連接和半連接隊列

當服務端調用listen函數監聽端口的時候,內核會爲每個監聽的socket創建兩個隊列:

  • 半連接隊列(syn queue):客戶端發送SYN包,服務端收到後回覆SYN+ACK後,服務端進入SYN_RCVD狀態,這個時候的socket會放到半連接隊列。

  • 全連接隊列(accept queue):當服務端收到客戶端的ACK後,socket會從半連接隊列移出到全連接隊列。當調用accpet函數的時候,會從全連接隊列的頭部返回可用socket給用戶進程。

半連接隊列

半連接隊列的大小由/proc/sys/net/ipv4/tcp_max_syn_backlog控制,Linux的默認是1024。

當服務端發送SYN_ACK後將會開啓一個定時器,如果超時沒有收到客戶端的ACK,將會重發SYN_ACK包。重傳的次數由/proc/sys/net/ipv4/tcp_synack_retries控制,默認是5次。

全連接隊列

全連接隊列的大小通過/proc/sys/net/core/somaxconn指定,在使用listen函數時,內核會根據傳入的backlog參數與系統參數somaxconn,取二者的較小值。

listen函數

  • ounter(line
int listen(int sockfd, int backlog)

Nginx和Redis默認的backlog值等於511,Linux默認的backlog 爲 128,Java默認的backlog等於50

默認情況下,全連接隊列滿以後,服務端會忽略客戶端的 ACK,隨後會重傳SYN+ACK,也可以修改這種行爲,這個值由/proc/sys/net/ipv4/tcp_abort_on_overflow決定。

  • tcp_abort_on_overflow爲0表示三次握手最後一步全連接隊列滿以後服務端會丟掉客戶端發過來的ACK,服務端隨後會進行重傳SYN+ACK
  • tcp_abort_on_overflow爲1表示全連接隊列滿以後服務端發送RST給客戶端,直接釋放資源。

syn_flood攻擊

深入淺出TCP中的SYN-Cookies

命令查看

netstat -s

  • ounter(line
  • ounter(line
  • ounter(line
  • ounter(line
  • ounter(line
netstat -s | egrep "listen|LISTEN" // 全連接隊列溢出次數667399 times the listen queue of a socket overflowed // 半連接隊列溢出次數667399 SYNs to LISTEN sockets dropped

ss -lnt

  • ounter(line
  • ounter(line
  • ounter(line
[root@mcs opt]# ss -lntState      Recv-Q Send-Q                        Local Address:Port                                       Peer Address:Port              LISTEN     0      100                                       *:8080                                                  *:* 

listen狀態下,Send-Q表示全連接隊列大小的最大值,Recv-Q表示全連接隊列的使用大小,超過最大值則會溢出。

ss命令和Recv-Q和Send-Q狀態

關注作者微信公衆號:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章