TCP狀態(tài)機

在網(wǎng)絡(luò)協(xié)議棧中褐隆, 目前只有tcp提供了一種面向連接的可靠性數(shù)據(jù)傳輸污它。 而可靠性庶弃,無非就是保證轨蛤,我發(fā)給你的,你一定要收到虫埂。確保中間的通信過程中祥山,不會丟失數(shù)據(jù)和亂序〉舴 在TCP保證可靠性數(shù)據(jù)傳輸?shù)膶崿F(xiàn)來看缝呕, 超時重傳澳窑、序列號及數(shù)據(jù)的應(yīng)答 這三個特征 就是實現(xiàn)可靠性的最基本保證,而對于tcp窗口大小等等設(shè)置供常,也是保證可靠性的一個方面摊聋。所有的目的只為一個,保證傳輸數(shù)據(jù)的完整性栈暇。 為了解決傳輸線路的不穩(wěn)定性造成數(shù)據(jù)包的丟失情況麻裁,tcp 使用了發(fā)送方超時重傳和接收方數(shù)據(jù)應(yīng)答的策略。概括而言源祈,就是一種“狀態(tài)協(xié)議“煎源,保證通信雙方數(shù)據(jù)收發(fā)的一致性。

tcp協(xié)議

報文結(jié)構(gòu)

源端口:表明發(fā)送端所使用的端口號香缺,用于目標(biāo)主機回應(yīng)手销。
目的端口:表明要連接的目標(biāo)主機的端口號。
序號:
表明發(fā)送的數(shù)據(jù)包的順序图张,一般為上次發(fā)送包中的順序號+1锋拖。
若該數(shù)據(jù)包是整個TCP連接中的第一個包(SYN包),則該值是隨機生成的祸轮。
確認(rèn)號:
表明本端TCP已經(jīng)接收到的數(shù)據(jù)兽埃,其值表示期待對端發(fā)送的下一個字節(jié)的序號。
實際上告訴對方适袜,在這個序號減1以前的字節(jié)已正確接收讲仰。
若該數(shù)據(jù)包是整個TCP連接中的第一個包(SYN包),則確認(rèn)號一般為0痪蝇。
數(shù)據(jù)偏移:
表示以32位(4字節(jié))為單位的TCP分組頭的總長度(首部長度)鄙陡,用于確定用戶數(shù)據(jù)區(qū)的起始位置。
在沒有可變內(nèi)容的情況下躏啰,TCP頭部的大小為20字節(jié)趁矾,對應(yīng)該值為5。
標(biāo)志位:
緊急標(biāo)志位(URG):開啟時表明此數(shù)據(jù)包處于緊急狀態(tài)應(yīng)該優(yōu)先處理
確認(rèn)標(biāo)志位(ACK):開啟時表明確認(rèn)號有效给僵,否則忽略確認(rèn)號
推送標(biāo)志位(PSH):開啟時表明應(yīng)該盡快交付給應(yīng)用進程毫捣,而不必等到緩存區(qū)填滿才推送,比如 telnet 的場景
復(fù)位標(biāo)志位(RST):開啟時表明TCP連接出現(xiàn)連接出現(xiàn)錯誤帝际,數(shù)據(jù)包非法拒絕連接
同步標(biāo)志位(SYN):開啟時表明連接建立的標(biāo)志
終止標(biāo)志位(FIN):開啟時表明釋放一個連接
窗口大新:表明期望接受到的數(shù)據(jù)包字節(jié)數(shù),用于擁塞控制蹲诀。
校驗和:實現(xiàn)對TCP報文頭以及數(shù)據(jù)區(qū)進行校驗斑粱。
緊急指針:在緊急狀態(tài)下(URG打開),指出窗口中緊急數(shù)據(jù)的位置(末端)脯爪。
選項(可變):用于支持一些特殊的變量则北,比如最大分組長度(MSS)矿微。
填充:用于保證可變選項為32 bit的整數(shù)倍。
備注:一般情況下TCP 頭部為20字節(jié)尚揣,加上20字節(jié)的 IP頭部涌矢,一個數(shù)據(jù)包至少包含40字節(jié)的頭部

tcp狀態(tài)機

image.png

下面簡析一下 TCP的各個狀態(tài)。

TCP_CLOSE:關(guān)閉狀態(tài)快骗, 一個新建的TCP socket 會處于該狀態(tài)娜庇。

TCP_LISTEN: 監(jiān)聽狀態(tài),一般服務(wù)器端套接字在調(diào)用Listen系統(tǒng)調(diào)用后即處于該狀態(tài)方篮。

TCP_SYN_SENT:同步信號已經(jīng)發(fā)送狀態(tài)名秀,這個狀態(tài)一般是指客戶端發(fā)送SYN(建立連接的同步)數(shù)據(jù)包后所處的狀態(tài)(tcp三次握手的第一個包)。在接收到遠(yuǎn)端服務(wù)器端的應(yīng)答后恭取,即從該狀態(tài)進入TCP_ESTABLISHED狀態(tài)泰偿。

TCP_SYN_RECEIVED:同步信號已經(jīng)接受狀態(tài)熄守,服務(wù)器端在接受到遠(yuǎn)端客戶端SYN數(shù)據(jù)包后蜈垮,進行相應(yīng)的處理(創(chuàng)建通信套接字等),然后發(fā)送應(yīng)答數(shù)據(jù)包(tcp三次握手的第二個包)裕照,并將新創(chuàng)建的通信套接字狀態(tài)設(shè)置為TCP_SYN_RECEIVED攒发,在接受到客戶端的應(yīng)答后,即進入TCP_ESTABLISED狀態(tài)晋南。

TCP_ESTABLISED:建立連接狀態(tài)惠猿,這是雙方進行正常通信所處的狀態(tài)。

TCP_FIN_WAIT_1:本地發(fā)送FIN(用于結(jié)束連接的)數(shù)據(jù)包后即可進入該狀態(tài)负间,等待對方的應(yīng)答偶妖。一般一端發(fā)送完其所要發(fā)送的數(shù)據(jù)后,即可發(fā)送FIN數(shù)據(jù)包政溃,此時發(fā)送通道被關(guān)閉趾访,但仍可繼續(xù)接受遠(yuǎn)端發(fā)送的數(shù)據(jù)包。在接受到遠(yuǎn)端發(fā)送的對于FIN數(shù)據(jù)包的應(yīng)答后董虱,將進入TCP_FIN_WAIT_2狀態(tài)扼鞋。

TCP_FIN_WAIT_2:進入該狀態(tài)表示本地已經(jīng)接受到遠(yuǎn)端發(fā)送的對于本地之前發(fā)送的FIN數(shù)據(jù)包的應(yīng)答。進入該狀態(tài)后愤诱,本地仍然可以繼續(xù)接受遠(yuǎn)端發(fā)送給本地的數(shù)據(jù)包云头。在接受到遠(yuǎn)端發(fā)送的FIN數(shù)據(jù)包后(表示遠(yuǎn)端也已經(jīng)發(fā)送完數(shù)據(jù)),本地將發(fā)送一個應(yīng)答數(shù)據(jù)包淫半,并進入TCP_TIME_WAIT狀態(tài)溃槐。TCP_TIME_WAIT狀態(tài)存在的時間被稱為2MSL時間,這一方面是為避免本地發(fā)送的應(yīng)答數(shù)據(jù)包丟失科吭,另一方面避免一個新創(chuàng)建的套接字接收到舊套接字中遺留的數(shù)據(jù)包竿痰。

TCP_TIME_WAIT:該轉(zhuǎn)狀態(tài)唄稱為2MSL等待狀態(tài)脆粥。如果在此期間接收到遠(yuǎn)端發(fā)送的FIN數(shù)據(jù)包,則表示之前在TCP_FIN_WAIT_2狀態(tài)發(fā)送的ACK應(yīng)答數(shù)據(jù)包在傳輸中丟失或者長時間被延遲影涉,從而造成了遠(yuǎn)端重新發(fā)送了FIN數(shù)據(jù)包变隔,此時重復(fù)ACK應(yīng)答數(shù)據(jù)包。一旦2MSL時間到期蟹倾,則將進入TCP_CLOSED狀態(tài)匣缘,即完成關(guān)閉操作。

TCP_CLOSE_WAIT:該狀態(tài)存在于后關(guān)閉的一端鲜棠。當(dāng)接收到遠(yuǎn)端發(fā)送的FIN數(shù)據(jù)包后肌厨,本地發(fā)送一個ACK應(yīng)答數(shù)據(jù)包,并將該套接字狀態(tài)從TCP_ESTABLISED設(shè)置為TCP_CLOSE_WAIT豁陆。本地可以繼續(xù)向遠(yuǎn)端發(fā)送數(shù)據(jù)包柑爸,在發(fā)送完所有的數(shù)據(jù)后,本地將發(fā)送一個FIN數(shù)據(jù)包關(guān)閉本地發(fā)送通道盒音,并將狀態(tài)設(shè)置為TCP_LAST_ACK狀態(tài)表鳍,等待遠(yuǎn)端對FIN數(shù)據(jù)包的應(yīng)答數(shù)據(jù)包。

TCP_CLOSING:如果通信雙方同時發(fā)送FIN數(shù)據(jù)包祥诽,則同時進行關(guān)閉操作譬圣,則雙方將同時進入TCP_CLOSING狀態(tài)。具體的雄坪,本地發(fā)送一個FIN數(shù)據(jù)包以結(jié)束本地數(shù)據(jù)包發(fā)送厘熟,如果在等待應(yīng)答期間,接收到遠(yuǎn)端發(fā)送的FIN數(shù)據(jù)包维哈,則本地將狀態(tài)設(shè)置為TCP_CLOSING狀態(tài)绳姨。在接收到應(yīng)答后,再繼續(xù)裝入到TCP_CLOSE_WAIT狀態(tài)阔挠。

TCP_LAST_ACK:作為后關(guān)閉的一方飘庄,在發(fā)送FIN數(shù)據(jù)包后,即進入TCP_LAST_ACK狀態(tài)谒亦。此時等待遠(yuǎn)端發(fā)送應(yīng)答數(shù)據(jù)包竭宰,在接收到應(yīng)答數(shù)據(jù)包后,即完成關(guān)閉操作份招,進入TCP_CLOSE狀態(tài)切揭。

關(guān)于tcp中time_wait狀態(tài)的4個問題

1.time_wait狀態(tài)是什么

簡單來說:time_wait狀態(tài)是四次揮手中server向client發(fā)送FIN終止連接后進入的狀態(tài)。下圖為tcp四次揮手過程



能夠看到time_wait狀態(tài)存在于client收到serverFin并返回ack包時的狀態(tài)
當(dāng)處于time_wait狀態(tài)時锁摔,我們無法創(chuàng)建新的連接廓旬,由于port被占用。

2.為什么會有time_wait狀態(tài)

time_wait存在的原因有兩點
1.可靠的終止TCP連接。
可靠的終止TCP連接孕豹,若處于time_wait的client發(fā)送給server確認(rèn)報文段丟失的話涩盾,server將在此又一次發(fā)送FIN報文段,那么client必須處于一個可接收的狀態(tài)就是time_wait而不是close狀態(tài)励背。
2.保證讓遲來的TCP報文段有足夠的時間被識別并丟棄春霍。
保證遲來的TCP報文段有足夠的時間被識別并丟棄,linux 中一個TCPport不能打開兩次或兩次以上叶眉。當(dāng)client處于time_wait狀態(tài)時我們將無法使用此port建立新連接址儒,假設(shè)不存在time_wait狀態(tài),新連接可能會收到舊連接的數(shù)據(jù)衅疙。

time_wait持續(xù)的時間是2MSL莲趣,保證舊的數(shù)據(jù)能夠丟棄。由于網(wǎng)絡(luò)中的數(shù)據(jù)最大存在MSL(maxinum segment lifetime)

3.哪一方會有time_wait狀態(tài)

time_wait狀態(tài)是一般有client的狀態(tài)饱溢。 并且會占用port喧伞,有時產(chǎn)生在server端,由于server主動斷開連接或者發(fā)生異常

4.怎樣避免time_wait狀態(tài)占用資源

假設(shè)是client绩郎,我們一般不用操心潘鲫,由于client一般選用暫時port。再次創(chuàng)建連接會新分配一個port嗽上。
除非指定client使用某port次舌,只是一般不須要這么做熄攘。
假設(shè)是server主動關(guān)閉連接后異常終止兽愤。則由于它總是使用用一個知名serverport號,所以連接的time_wait狀態(tài)將導(dǎo)致它不能重新啟動挪圾。只是我們能夠通過socket的選項SO_REUSEADDR來強制進程馬上使用處于time_wait狀態(tài)的連接占用的port浅萧。
通過socksetopt設(shè)置后,即使sock處于time_wait狀態(tài)哲思,與之綁定的socket地址也能夠馬上被重用洼畅。
此外也能夠通過改動內(nèi)核參數(shù)/proc/sys/net/ipv4/tcp_tw/recycle來高速回收被關(guān)閉的socket,從而是tcp連接根本不進入time_wait狀態(tài),進而同意應(yīng)用程序馬上重用本地的socket地址棚赔。

tcp攻擊

所謂SYN 洪泛攻擊帝簇,就是利用SYNACK 報文的時候,服務(wù)器會為客戶端請求分配緩存靠益,那么黑客(攻擊者)丧肴,就可以使用一批虛假的ip向服務(wù)器大量地發(fā)建立TCP 連接的請求,服務(wù)器為這些虛假ip分配了緩存后胧后,處在SYN_RCVD狀態(tài)芋浮,存放在半連接隊列中;另外壳快,服務(wù)器發(fā)送的請求又不可能得到回復(fù)(ip都是假的纸巷,能回復(fù)就有鬼了)镇草,只能不斷地重發(fā)請求,直到達(dá)到設(shè)定的時間/次數(shù)后瘤旨,才會關(guān)閉梯啤。

服務(wù)器不斷為這些半開連接分配資源(但從未使用),導(dǎo)致服務(wù)器的連接資源被消耗殆盡存哲,不過所幸条辟,我們可以使用SYN Cookie進行有效地防御。

所謂的SYN Cookie防御系統(tǒng)宏胯,與前面接收到SYN 報文就分配緩存不同羽嫡,此時暫不分配資源;同時利用SYN 報文的源和目的地IP和端口肩袍,以及服務(wù)器存儲的一個秘密數(shù)杭棵,使用它們進行散列,得到server_isn氛赐,然后附著在SYNACK 報文中發(fā)送給客戶端魂爪,接下來就是對ACK 報文進行判斷,如果其返回的ack字段正好等于server_isn + 1艰管,說明這是一個合法的ACK滓侍,那么服務(wù)器才會為其生成一個具有套接字的全開的連接。


cookie防御
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末牲芋,一起剝皮案震驚了整個濱河市撩笆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌缸浦,老刑警劉巖夕冲,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異裂逐,居然都是意外死亡歹鱼,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門卜高,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弥姻,“玉大人,你說我怎么就攤上這事掺涛⊥ザ兀” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵鸽照,是天一觀的道長螺捐。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么定血? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任赔癌,我火速辦了婚禮,結(jié)果婚禮上澜沟,老公的妹妹穿的比我還像新娘灾票。我一直安慰自己,他們只是感情好茫虽,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布刊苍。 她就那樣靜靜地躺著,像睡著了一般濒析。 火紅的嫁衣襯著肌膚如雪正什。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天号杏,我揣著相機與錄音婴氮,去河邊找鬼。 笑死盾致,一個胖子當(dāng)著我的面吹牛主经,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播庭惜,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼罩驻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了护赊?” 一聲冷哼從身側(cè)響起惠遏,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎百揭,沒想到半個月后爽哎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蜓席,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡器一,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了厨内。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祈秕。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖雏胃,靈堂內(nèi)的尸體忽然破棺而出请毛,到底是詐尸還是另有隱情,我是刑警寧澤瞭亮,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布方仿,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏仙蚜。R本人自食惡果不足惜此洲,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望委粉。 院中可真熱鬧呜师,春花似錦、人聲如沸贾节。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽栗涂。三九已至知牌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間斤程,已是汗流浹背送爸。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留暖释,地道東北人袭厂。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像球匕,于是被迫代替她去往敵國和親纹磺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容