TCP未完成隊列和完成隊列


已完成連接隊列(completed connection queue)
(1)三次握手已經完成,但還未被應用層接收(accept),但也處於ESTABLISHED狀態.
(2)隊列長度由listen的backlog參數和內核的 net.core.somaxconn 參數共同決定.
(3)當這個隊列滿了之後,不管未完成連接隊列是否已滿,是否啓用syncookie,都不在接收新的SYN請求.(該特性跟內核版本有關)
(4)如果client端向已完成連接隊列的socket發送包,內核將保存數據到socket的接收緩衝區,等應用層accept之後,傳給應用層.

未完成連接隊列(incomplete connection queue)
(1)半連接狀態,處於SEND_RCVD狀態.
(2)由內核參數 net.ipv4.tcp_max_syn_backlog 設置.
(3)如果啓用了syncookie,在未完成連接隊列滿了之後,新的SYN請求將使用syncookie機制.
服務器會重發SYN-ACK,重試次數爲:/proc/sys/net/ipv4/tcp_synack_retries

關於syn flood 攻擊轉載至:http://coolshell.cn/articles/11564.html
試想一下,如果server端接到了clien發的SYN後回了SYN-ACK後client掉線了,server端沒有收到client回來的ACK,那麼,這個連接處於一箇中間狀態,即沒成功,也沒失敗。於是,server端如果在一定時間內沒有收到的TCP會重發SYN-ACK。在Linux下,默認重試次數爲5次,重試的間隔時間從1s開始每次都翻售,5次的重試時間間隔爲1s, 2s, 4s, 8s, 16s,總共31s,第5次發出後還要等32s都知道第5次也超時了,所以,總共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 2^6 -1 = 63s,TCP纔會把斷開這個連接。
一些惡意的人就爲此製造了SYN Flood攻擊——給服務器發了一個SYN後,就下線了,於是服務器需要默認等63s纔會斷開連接,這樣,攻擊者就可以把服務器的syn連接的隊列耗盡,讓正常的連接請求不能處理。於是,Linux下給了一個叫tcp_syncookies的參數來應對這個事——當SYN隊列滿了後,TCP會通過源地址端口、目標地址端口和時間戳打造出一個特別的Sequence Number發回去(又叫cookie),如果是攻擊者則不會有響應,如果是正常連接,則會把這個 SYN Cookie發回來,然後服務端可以通過cookie建連接(即使你不在SYN隊列中)。請注意,請先千萬別用tcp_syncookies來處理正常的大負載的連接的情況。因爲,synccookies是妥協版的TCP協議,並不嚴謹。對於正常的請求,你應該調整三個TCP參數可供你選擇,第一個是:tcp_synack_retries 可以用他來減少重試次數;第二個是:tcp_max_syn_backlog,可以增大SYN連接數;第三個是:tcp_abort_on_overflow 處理不過來乾脆就直接拒絕連接了。
不懂用戶的程序員做不出好產品。
新浪微博:@安靜的發狂者
QQ:229675152
供職於聯想親友約團隊,專注於移動互聯網音視頻通信領域,歡迎交流。原創文章,歡迎拍磚,轉載請保留版權並聯系作者
kamailio/opensips技術交流QQ羣:118791050
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章