什么是什么?
簡(jiǎn)介:TCP是一種面向鏈接的單播協(xié)議倘屹,載發(fā)送數(shù)據(jù)之前银亲,通信雙方必須必須在彼此間建立一條連接。所謂的“連接”纽匙,其實(shí)是客戶端和服務(wù)器的內(nèi)存里保存的一份關(guān)于對(duì)方的信息务蝠,如IP地址、端口號(hào)等烛缔。
TCP可以看成一種字節(jié)流馏段,他會(huì)處理IP層或以下的層的丟包、重復(fù)以及錯(cuò)誤問題践瓷。在連接的建立過程中院喜,雙方需要交換一些連接的參數(shù)。這些參數(shù)可以放在TCP頭部晕翠。
TCP提供了一種可靠喷舀、面向連接、字節(jié)流淋肾、傳輸層的服務(wù)硫麻,采用三次握手建立一個(gè)連接。采用四次揮手來關(guān)閉一個(gè)連接樊卓。
TCP服務(wù)模型
一個(gè)TCP連接由一個(gè)4元組構(gòu)成拿愧,分別是兩個(gè)IP地址和兩個(gè)端口號(hào)。一個(gè)TCP連接通常分為三個(gè)階段:?jiǎn)?dòng)碌尔、數(shù)據(jù)傳輸浇辜、退出(關(guān)閉)券敌。
當(dāng)TCP接受到另一端的數(shù)據(jù)時(shí),他會(huì)發(fā)送一個(gè)確認(rèn)奢赂,但是這個(gè)確認(rèn)不會(huì)立即發(fā)送陪白,一般會(huì)延遲一會(huì)兒。ACK是累積的膳灶,一個(gè)確認(rèn)字節(jié)號(hào)N的ACK表示所有直到N的字節(jié)(不包括N)已經(jīng)成功被接收了咱士。這樣的好出是如果一個(gè)ACK丟失,很可能后續(xù)的ACK就足以確認(rèn)前面的報(bào)文段了轧钓。
一個(gè)完整的TCP連接時(shí)雙向和對(duì)稱的序厉,數(shù)據(jù)可以在兩個(gè)方向上平等地流動(dòng)。給上層應(yīng)用程序提供一種雙工服務(wù)毕箍,一旦建立了一個(gè)連接弛房,這個(gè)連接的一個(gè)方向上的每個(gè)TCP報(bào)文段都包含了相反方向上的報(bào)文段的一個(gè)ACK。
序列號(hào)的作用是使得一個(gè)TCP接收端可丟棄重復(fù)的報(bào)文段而柑,記錄一雜亂次序到達(dá)的報(bào)文段文捶。因?yàn)門CP使用IP來傳輸報(bào)文段,而IP不提供重復(fù)消除或者保證次序正確的功能媒咳。另一方面粹排,TCP是一個(gè)字節(jié)流協(xié)議,絕不會(huì)以雜亂的次序給上層程序發(fā)送數(shù)據(jù)涩澡。一次TCP接收端會(huì)被迫先保持大序列號(hào)的數(shù)據(jù)不交給應(yīng)用程序顽耳,直到缺失的小序列號(hào)的報(bào)文段被填滿。
TCP頭部
[圖片上傳失敗...(image-5bdcd7-1635903834932)]
源端口和目的端口在TCP層確定雙方進(jìn)程妙同,序列號(hào)表示的是報(bào)文段數(shù)據(jù)中的的第一個(gè)字節(jié)號(hào)射富,ACK表示確認(rèn)號(hào),該確認(rèn)號(hào)的發(fā)送方期待接收的下一個(gè)序列號(hào)粥帚,即最后被成功接收的數(shù)據(jù)字節(jié)序列號(hào)加一胰耗,這個(gè)字段只有ACK位被啟用的時(shí)候才有效。
當(dāng)新建一個(gè)連接時(shí)芒涡,從客戶端發(fā)送到服務(wù)器端的第一個(gè)報(bào)文段的SYN位被啟用宪郊,這稱為SYN報(bào)文段,真實(shí)序列號(hào)字段包含了在本次連接的這個(gè)方向上要使用的第一個(gè)序列號(hào)拖陆,即初始序列號(hào)ISN,之后發(fā)送的數(shù)據(jù)是ISN加一懊亡,因此SYN位字段會(huì)消耗一個(gè)序列號(hào)依啰,這意味著使用重傳進(jìn)行可靠傳輸。而不消耗序列號(hào)的ACK則不是店枣。
頭部長(zhǎng)度(圖中的數(shù)據(jù)偏移)以32位字節(jié)為單位速警,也就是以4bytes為單位叹誉,它只有4位,最大為15闷旧,因此頭部最大長(zhǎng)度為60字節(jié)长豁,而其最小為5,也就是頭部最小為20字節(jié)(可變選項(xiàng)為空)忙灼。
ACK---確認(rèn)匠襟,使得確認(rèn)號(hào)有效。RST---重置連接(經(jīng)掣迷埃看到的reset by peer)就是此字段搞得鬼酸舍。SYN---用于初始化一個(gè)連接的序號(hào)列。FIN---該報(bào)文段的發(fā)送方已經(jīng)結(jié)束向?qū)Ψ桨l(fā)送數(shù)據(jù)里初。
當(dāng)一個(gè)連接被建立或被終止時(shí)啃勉,交換的報(bào)文段只包含TCP頭部,而沒有數(shù)據(jù)双妨。
狀態(tài)轉(zhuǎn)換
三次握手和四次揮手的狀態(tài)轉(zhuǎn)換如下圖淮阐。
[圖片上傳失敗...(image-4d5ebf-1635903834932)]
為什么要“三次握手、四次揮手”刁品?
三次握手
換個(gè)易于理解的視角來看為什么要3次握手泣特。
客戶端和服務(wù)器端通信前要進(jìn)行連接,“三次握手”的作用就是雙方都能明確自己和對(duì)方的收哑诊、發(fā)能力是正常的群扶。
第一次握手:客戶端發(fā)送網(wǎng)絡(luò)包,服務(wù)端收到了镀裤。這樣服務(wù)端就能得出結(jié)論:客戶端的發(fā)送能力竞阐、服務(wù)端的接收能力是正常的。
第二次握手:服務(wù)端發(fā)包暑劝,客戶端收到了骆莹。這樣客戶端就能得出結(jié)論:服務(wù)端的接收、發(fā)送能力担猛、客戶端的接收幕垦、發(fā)送能力是正常的。從客戶端的視角來看傅联,我接收到了服務(wù)端發(fā)送過來的響應(yīng)數(shù)據(jù)包先改,說明服務(wù)端接收到了我在第一次握手時(shí)發(fā)送的網(wǎng)絡(luò)包,并且成功發(fā)送了響應(yīng)數(shù)據(jù)包蒸走,這就說明仇奶,服務(wù)端的接收、發(fā)送能力正常比驻。而另一方面该溯,我自己的發(fā)送和接收能力也是正常的岛抄。
第三次握手:客戶端發(fā)包,服務(wù)端收到了狈茉。這樣服務(wù)端就能得出結(jié)論:客戶端的接收夫椭、發(fā)送能力,服務(wù)端的發(fā)送氯庆、接收能力是正常的蹭秋。第一、第二次握手后点晴,服務(wù)端并不知道客戶端的接受收能力以及自己的發(fā)送能力是否正常感凤。而在第三次握手時(shí),服務(wù)端收到了客戶端對(duì)第二次握手作的回應(yīng)粒督。從服務(wù)端的角度陪竿,我在第二次握手時(shí)的響應(yīng)數(shù)據(jù)發(fā)送出去了,客戶端接收到了屠橄。所以,我的發(fā)送能力是正常的锐墙。而客戶端的接收能力也是正常的。
經(jīng)歷了上面的三次握手過程溪北,客戶端和服務(wù)端都確認(rèn)了自己的接收、發(fā)送能力是正常的茉继。之后就可以正常通信了。
每次都是接收到數(shù)據(jù)包的一方可以得到一些結(jié)論烁竭。發(fā)送的一方其實(shí)沒有任何頭緒,我雖然有發(fā)包的動(dòng)作派撕,但是我怎么知道我有沒有發(fā)出去,而對(duì)方有沒有接收到呢睬魂?
而從上面的過程中可以看到终吼,最少是需要三次握手過程的。兩次達(dá)不到讓雙方都得出自己氯哮、對(duì)方接收衔峰、發(fā)送能力都正常的結(jié)論。其實(shí)每次收到網(wǎng)絡(luò)包的一方至少是可以得到:對(duì)方的發(fā)送、我方的接收是正常的垫卤。而每一步都是有關(guān)聯(lián)的,下一次的“響應(yīng)”是由于第一次的“請(qǐng)求”觸發(fā)出牧,因此每次握手其實(shí)是可以得到額外的結(jié)論的穴肘。比如第三次握手時(shí),服務(wù)端收到數(shù)據(jù)包舔痕,表明看服務(wù)端只能得到客戶端的發(fā)送能力评抚、服務(wù)端的接收的能力時(shí)正常的,但是結(jié)合第二次伯复,說明服務(wù)端在第二此發(fā)送的響應(yīng)包慨代,并且做出了響應(yīng),從而得到額外的結(jié)論:客戶端的接收啸如、服務(wù)端的發(fā)送時(shí)正常的侍匙。
用表格總結(jié)一下:
視角 | 客收 | 客發(fā) | 服收 | 服發(fā) |
---|---|---|---|---|
客視角 | 二 | 一+二 | 一+二 | 二 |
服視角 | 二+三 | 一 | 一 | 二+三 |
四次揮手
TCP連接是雙向傳輸?shù)膶?duì)等的模式,就是說雙方都可以同時(shí)向?qū)Ψ桨l(fā)送或接收數(shù)據(jù)叮雳。當(dāng)有一方要關(guān)閉連接時(shí)想暗,會(huì)發(fā)送指令告知對(duì)方,我要關(guān)閉連接了帘不。這是對(duì)方就會(huì)回一個(gè)ACK说莫,此時(shí)一個(gè)方向的連接關(guān)閉。但是另一個(gè)方向仍然可以繼續(xù)傳輸數(shù)據(jù)寞焙,等到發(fā)送完了所有的數(shù)據(jù)后储狭,會(huì)發(fā)送一個(gè)FIN段來關(guān)閉此方向上的連接。接收方發(fā)送ACK確認(rèn)關(guān)閉連接捣郊。
注意辽狈,接收到FIN報(bào)文的一方只能回復(fù)一個(gè)ACK,它是無法馬上返回對(duì)方一個(gè)FIN報(bào)文的模她,因?yàn)榻Y(jié)束數(shù)據(jù)傳輸?shù)摹爸噶睢笔巧蠈討?yīng)用層給出的,我只是一個(gè)“搬運(yùn)工”尊勿,我無法了解“上層的意志”元扔。
三次握手澎语、四次揮手怎么完成
其實(shí)3次握手的目的并不只是讓通信雙方都了解到一個(gè)連接正在建立擅羞,還在于利用數(shù)據(jù)包的選項(xiàng)來傳輸特殊的信息减俏,交換初始序列號(hào)ISN
三次握手是指發(fā)送了三個(gè)報(bào)文段娃承,四次握手是指發(fā)送了報(bào)文段历筝。注意梳猪,SYN和FIN段都是會(huì)利用重傳進(jìn)行可靠傳輸?shù)摹?/p>
[圖片上傳失敗...(image-b19708-1635903834932)]
三次握手
客戶端發(fā)送一個(gè)SYN段舔示,并指明客戶端的初始序列號(hào)惕稻,即ISN(s)俺祠。
服務(wù)端發(fā)送自己的SYN段作為應(yīng)答蜘渣,同樣指明自己的ISN(s)蔫缸。為了確認(rèn)客戶端的SYN拾碌,將ISN(s)校翔。為了確認(rèn)客戶端的SYN防症,將ISN(c)+1作為ACK數(shù)值。這樣炭玫,沒發(fā)送一個(gè)SYN础嫡,序列號(hào)就會(huì)加1,如果有丟失的情況伯诬,則會(huì)重傳哩陕。
為了確認(rèn)服務(wù)器端的SYN悍及,客戶端將ISN(s)+1作為返回的ACK數(shù)值心赶。
四次揮手
[圖片上傳失敗...(image-9ae80e-1635903834932)]
客戶端發(fā)送一個(gè)FIN段缨叫,并包含一個(gè)希望接收者看到的自己當(dāng)前的序列號(hào)K耻姥,同時(shí)還包含一個(gè)ACK表示確認(rèn)對(duì)方最近一次發(fā)過來的數(shù)據(jù)琐簇。
服務(wù)端將K值加1作為ACK序列號(hào)值婉商,表明收到了上一個(gè)包据某。這時(shí)上層的應(yīng)用程序會(huì)被告知另一端發(fā)起了關(guān)閉操作癣籽,通常這將引起應(yīng)用程序發(fā)起自己的關(guān)閉操作。
服務(wù)端發(fā)起自己的FIN段瓶籽,ACK=K+1,Seq=L4塑顺⊙暇埽客戶端確認(rèn)裤唠。ACK=L+1
為什么建立連接是三次握手种蘸,而關(guān)閉連接卻是四次揮手呢航瞭?
這是因?yàn)榉?wù)端在LISTEN狀態(tài)下刊侯,收到建立連接請(qǐng)求的SYN報(bào)文后滔吠,把ACK和SYN放在一個(gè)報(bào)文里發(fā)送給客戶端疮绷。而關(guān)閉連接時(shí)冬骚,當(dāng)收到對(duì)方的FIN報(bào)文時(shí)只冻,僅僅表示對(duì)方不在發(fā)送數(shù)據(jù)了但是還能接收數(shù)據(jù)喜德,己方是否現(xiàn)在關(guān)閉發(fā)送數(shù)據(jù)通道舍悯,需要上層應(yīng)用來決定萌衬,因此朴艰,己方ACK和FIN一般都會(huì)分開發(fā)送
三次握手祠墅,四次揮手進(jìn)階
ISN
三次握手的一個(gè)重要功能是客戶端和服務(wù)端交換ISN(Initial Sequence Number)饵隙,以便讓對(duì)方知道接下來接收數(shù)據(jù)的時(shí)候如何按序列號(hào)組裝數(shù)據(jù)。
如果ISN是固定的芯急,攻擊者很容易猜出后續(xù)的確認(rèn)號(hào)
ISN = M + F(localhost, localport, remotehost, remoteport)
M是一個(gè)計(jì)時(shí)器免姿,每隔4毫秒加1胚膊。F是一個(gè)Hash算法紊婉,根據(jù)源喻犁、目的IP肢础、源端口传轰、目的端口生成一個(gè)隨機(jī)數(shù)值谷婆。要保證hash算法不能被外部輕易推算得出。
序列號(hào)回繞
因?yàn)镮SN是隨機(jī)的身隐,所以序列號(hào)很容易就會(huì)超過2^31-1贾铝。而tcp對(duì)于丟包和亂序等問題的判斷都是依賴于序列號(hào)大小比較的埠帕。此時(shí)就出現(xiàn)了所謂的tcp序列號(hào)回繞(sequrence wraparound)問題茧痕。怎么解決避诽?
/** The next routines deal with comparing 32 bit unsigned ints
* and worry about wraparound (automatic with unsigned arithmetic).*/
static inline int before(__u32 seq1, __u32 seq2){
return (__s32)(seq1-seq2) < 0;}
#define after(seq2, seq1) before(seq1, seq2)
上述代碼是內(nèi)核中的解決回繞問題代碼狡蝶。s32是有符號(hào)整型的意思贪惹,而u32則是無符號(hào)整型。序列號(hào)發(fā)生回繞后枫绅,序列號(hào)變小并淋,相減之后预伺,把結(jié)果變成有符號(hào)數(shù)了酬诀,因此結(jié)果成了負(fù)數(shù)瞒御。
假設(shè)seq1=255肴裙, seq2=1(發(fā)生了回繞)。
seq1 = 1111 1111 seq2 = 0000 0001
我們希望比較結(jié)果是
seq1 - seq2=
1111 1111
-0000 0001
-----------
1111 1110
由于我們將結(jié)果轉(zhuǎn)化成了有符號(hào)數(shù)甜癞,由于最高位是1悠咱,因此結(jié)果是一個(gè)負(fù)數(shù)析既,負(fù)數(shù)的絕對(duì)值為
0000 0001 + 1 = 0000 0010 = 2
因此seq1 - seq2 < 0
syn flood攻擊
最基本的DoS攻擊就是利用合理的服務(wù)請(qǐng)求來占用過多的服務(wù)資源眼坏,從而是合法用戶無法得到服務(wù)的響應(yīng)宰译,syn flood屬于DoS攻擊的一種囤屹。
如果惡意的向某個(gè)服務(wù)器端口發(fā)送大量的SYN包,則可以是服務(wù)器打開大量的半開連接肃廓,分配TCB(Transmission Control Block)盲赊,從而消耗大量的服務(wù)器資源哀蘑,同時(shí)也使得正常的連接請(qǐng)求無法被響應(yīng)绘迁。當(dāng)開放了一個(gè)TCP端口后卒密,該端口就處于Listening狀態(tài)哮奇,不停地監(jiān)視發(fā)到該端口的SYN報(bào)文,一旦收到Client發(fā)來的SYN報(bào)文哲身,就需要為該請(qǐng)求分配一個(gè)TCB怔揩,通常一個(gè)TCB至少需要280個(gè)字節(jié)沧踏,在某些操作系統(tǒng)中TCB甚至需要1300個(gè)字節(jié)翘狱,并返回一個(gè)SYN ACK命令潦匈,立即轉(zhuǎn)為SYN-RECEIVED即半開連接狀態(tài)茬缩。系統(tǒng)會(huì)為此耗盡資源凰锡。
常見的防攻擊方法有:
無效連接的監(jiān)視釋放
監(jiān)視系統(tǒng)的半開連接和不活動(dòng)連接掂为,當(dāng)達(dá)到一定閾值時(shí)拆除這些連接,從而釋放系統(tǒng)資源欲诺,這種方法對(duì)于所有的連接一視同仁渺鹦,而且由于SYN Flood造成的半開連接數(shù)量很大迹恐,正常連接請(qǐng)求也被淹沒在其中被這種方式誤釋放掉殴边,因此這種方法屬于入門級(jí)的SYN Flood方法
延緩TCB分配方法
消耗服務(wù)器資源主要是因?yàn)楫?dāng)SYN數(shù)據(jù)報(bào)文一到達(dá)锤岸,系統(tǒng)立即分配TCB,從而占用了資源拳氢。而SYN Flood由于很難建立起正常連接,因此留特,當(dāng)正常連接建立起來后再分配TCB則可以有效地減輕服務(wù)器資源的消耗蜕青。常見的方法是使用Syn Cache和Syn Cookie技術(shù)。
- Syn Cache技術(shù):系統(tǒng)在收到一個(gè)SYN報(bào)文時(shí)贺喝,在一個(gè)專用HASH表中保存這種半連接信息躏鱼,直到收到正確的回應(yīng)ACK報(bào)文再分配TCB针炉。這個(gè)開銷遠(yuǎn)小于TCB的開銷。當(dāng)然還需要保存序列號(hào)扳抽。
- Syn Cookie技術(shù):Syn Cookie技術(shù)則完全不使用任何存儲(chǔ)資源篡帕,這種方法比較巧妙,它使用一種特殊的算法生成Sequence Number贸呢,這種算法考慮到了對(duì)方的IP镰烧、端口、己方IP楞陷、端口的固定信息怔鳖,以及對(duì)方無法知道而己方比較固定的的一些信息,如MSS(Maximum Segment Size固蛾,最大報(bào)文段大小,指的是TCP報(bào)文的最大數(shù)據(jù)報(bào)長(zhǎng)度,其中不包括TCP首部長(zhǎng)度。)、時(shí)間等叽粹,在所受到對(duì)方的ACK報(bào)文后,重新計(jì)算一遍每强,看其是否與對(duì)方回應(yīng)報(bào)文中的(Sequence Number-1)相同辨绊,從而決定是否分配TCB資源
使用SYN Proxy防火墻
一種方式是防火墻dqywb連接有效性后默蚌,防火墻才會(huì)向內(nèi)部服務(wù)器發(fā)起SYN請(qǐng)求攘轩。防火墻代服務(wù)器發(fā)出的SYN ACK包使用的序列號(hào)為c够傍,而真正的服務(wù)器回應(yīng)的序列號(hào)為c安聘,這樣脯宿,在每個(gè)數(shù)據(jù)報(bào)文經(jīng)過防火墻的時(shí)候進(jìn)行序列號(hào)的修改。另一種方式是防火墻確定了連接的安全后歉井,會(huì)發(fā)生一個(gè)safe reset命令紧索,client會(huì)進(jìn)行重新連接媳危,這時(shí)出現(xiàn)的SYN報(bào)文會(huì)會(huì)直接放行。這樣不需要修改序列號(hào)了。但是,client需要發(fā)起兩次握手過程泡挺,因此建立連接的時(shí)間將會(huì)延長(zhǎng)勘伺。
連接隊(duì)列
在外部請(qǐng)求到達(dá)時(shí),被服務(wù)程序最終感知到前,連接可能處于SYN_RCVD狀態(tài)或是ESTABLISHED狀態(tài),但還未被應(yīng)用程序接收摧冀。
[圖片上傳失敗...(image-cedb8e-1635903834932)]
對(duì)應(yīng)地框产,服務(wù)器端也會(huì)維護(hù)兩種隊(duì)列忱叭,處于SYN_RCVD狀態(tài)的半連接隊(duì)列实牡,而處于ESTABLISHED狀態(tài)但仍未被應(yīng)用程序accept的為全連接隊(duì)列。如果這兩個(gè)隊(duì)列滿了之后,就會(huì)出現(xiàn)各種丟包的情形跟畅。
# 查看是否有連接溢出
netstat -s | grep LISTEN
半連接隊(duì)列滿了
在三次握手協(xié)議中,服務(wù)器維護(hù)一個(gè)半連接隊(duì)列夹囚,該隊(duì)列為每個(gè)客戶端的SYN包開設(shè)一個(gè)條目(服務(wù)端在接收到SYN包的時(shí)候堰燎,就已經(jīng)創(chuàng)建了request_sock結(jié)構(gòu)洁灵,存儲(chǔ)在半連接隊(duì)列中)铐维,該條目表明服務(wù)器已收到SYN包,并向客戶發(fā)出確認(rèn)苛骨,正在等待客戶的確認(rèn)包请琳。這些條目所表示的連接在服務(wù)器處于Syn_RECV狀態(tài)俄精,當(dāng)服務(wù)器收到客戶的確認(rèn)包時(shí),刪除該條目,服務(wù)器進(jìn)入ESTABLISHED狀態(tài)挨约。
目前瘟判,linux下默認(rèn)會(huì)進(jìn)行5次重發(fā)SYN-ACK包赢笨,重試的間隔從1s開始,下次的重試間隔時(shí)間是前一次的雙倍展姐,5次的重試時(shí)間間隔為1s, 2s, 4s, 8s, 16s, 總共31s,稱位值數(shù)退避剖毯,第5次發(fā)出后還要等32s才知道第5次也超時(shí)了圾笨,所以,總共需要1s + 2s + 4s+ 8s+ 16s + 32s = 63s逊谋,TCP才會(huì)把斷開這個(gè)連接擂达。由于,SYN超時(shí)需要63s胶滋,那么就給攻擊者一個(gè)攻擊服務(wù)器的機(jī)會(huì)板鬓,攻擊者在短時(shí)間內(nèi)發(fā)送大量的SYN包給Server(俗稱SYN flood攻擊),用于耗盡Server的SYN的SYN隊(duì)列究恤。對(duì)于應(yīng)對(duì)SYN過多的問題俭令,linux提供了幾個(gè)TCP參數(shù):tcp_syncookies、tcp_synack_retries部宿、tcp_max_syn_backlog抄腔、tcp_abort_on_overflow來調(diào)整應(yīng)對(duì)。
[圖片上傳失敗...(image-541465-1635903834932)]
全連接隊(duì)列滿
當(dāng)三次握手時(shí)理张,當(dāng)server接收到ACK包之后妓柜,會(huì)進(jìn)入一個(gè)新的叫accept得隊(duì)列。
當(dāng)accept隊(duì)列滿了之后涯穷,即使client繼續(xù)向server發(fā)送ACK得包棍掐,也會(huì)不被響應(yīng),此時(shí)Listen Overflows+1拷况,同時(shí)server通過tcp_abort_on_overflow來決定如何返回作煌,0表示直接丟棄該ACK,1表示發(fā)送RST通知client赚瘦;相應(yīng)的粟誓,client則會(huì)分別返回read timeout 或者 connection reset by peer。另外起意,tcp_abort_on_overflow是0得話鹰服,server過一段時(shí)間再次發(fā)送syn+ack給client(也就是重新走握手的第二步),如果client超時(shí)等待比較短,就很容易異常了悲酷。而客戶端收到多個(gè)SYN ACK包套菜,則會(huì)認(rèn)為之前的ACK丟包了。于是促使客戶端再次發(fā)送ACK设易,在accept隊(duì)列有空閑的時(shí)候最終完成連接逗柴。若accept隊(duì)列始終滿員,則最終客戶端收到RST包(此時(shí)服務(wù)端發(fā)送syn+ack的次數(shù)超出了tcp_synack_retries)顿肺。
服務(wù)端僅僅只是創(chuàng)建一個(gè)定時(shí)器戏溺,以固定間隔重傳syn和ack到服務(wù)端;
[圖片上傳失敗...(image-e154ce-1635903834932)]
命令
netstat -s命令
[root@server ~]# netstat -s | egrep "listen|LISTEN"
667399 times the listen queue of a socket overflowed
667399 SYNs to LISTEN sockets ignored
上面看到的 667399 times屠尊,表示全連接隊(duì)列溢出的次數(shù)旷祸,間隔幾秒鐘執(zhí)行下,如果這個(gè)數(shù)字一直再增加的話肯定全連接隊(duì)列偶爾滿了
[root@server ~]# netstat -s | grep TCPBacklogDrop
查看Accept queque是否有溢出
ss命令
[root@server ~]# ss -lnt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:6379 *:*
LISTEN 0 128 *:22 *:*
如果State是listen狀態(tài)讼昆,Send-Q表示第三列的listen端口上的全連接隊(duì)列最大為50托享,第一列Recv-Q為全連接隊(duì)列當(dāng)前使用了多少。非LISTEN狀態(tài)中Recv-Q表示receive queue中的bytes數(shù)量控淡;Send-Q表示send queue 中的bytes數(shù)值嫌吠。
小結(jié)
當(dāng)外部連接請(qǐng)求到來時(shí)止潘,TCP模塊會(huì)首先查看max_syn_backlog掺炭,如果處于SYN_RCVD狀態(tài)的連接數(shù)目超過這一閾值,進(jìn)入的連接會(huì)被拒絕凭戴。根據(jù)tcp_abort_on_overflow字段來決定是直接丟棄涧狮,還是直接reset。
從服務(wù)端來說么夫,三次握手中者冤,第一步server接受到client的syn后,把相關(guān)信息放到半連接隊(duì)列中档痪,同時(shí)回復(fù)syn+ack給client涉枫。第三步當(dāng)收到客戶端的ack,將連接加入到全連接隊(duì)列腐螟。
一般愿汰,全連接隊(duì)列比較小,會(huì)先滿乐纸,此時(shí)半連接隊(duì)列還沒滿衬廷。如果這時(shí)收到syn報(bào)文,則會(huì)進(jìn)入半連接隊(duì)列汽绢,沒有問題吗跋。但是如果收到了三次握手中的第三步(ack),則會(huì)根據(jù)tcp_abort_on_overflow字段來決定是直接丟棄,還是直接reset跌宛。此時(shí)酗宋,客戶端發(fā)送了ACK,那么客戶端認(rèn)為三次握手完成秩冈,它認(rèn)為服務(wù)端已經(jīng)準(zhǔn)備好了接受數(shù)據(jù)的準(zhǔn)備本缠。但此時(shí)服務(wù)端可能因?yàn)槿B接隊(duì)列滿了而無法將連接放入,會(huì)重新發(fā)送第二步的syn+ack入问,如果這時(shí)有數(shù)據(jù)到來丹锹,服務(wù)器TCP模塊會(huì)將數(shù)據(jù)存入隊(duì)列中。一段時(shí)間后芬失,client端沒有收到回復(fù)楣黍,超時(shí),連接異常棱烂,client會(huì)主動(dòng)關(guān)閉連接租漂。