TCP協(xié)議的超時詳解

眾所周知,TCP協(xié)議是一個可靠的的協(xié)議。TCP的可靠性依賴于大量的 Timer 和 Retransmission ∑恚現(xiàn)在咱們就來細(xì)說一下TCP協(xié)議的那些Timer

tcp-state-transition.png

Connection-Establishment Timer

在TCP三次握手創(chuàng)建一個連接時,以下兩種情況會發(fā)生超時:

1.client發(fā)送SYN后幻枉,進入SYN_SENT狀態(tài)剑梳,等待server的SYN+ACK苗傅。
2.server收到連接創(chuàng)建的SYN,回應(yīng)SYN+ACK后缸浦,進入SYN_RECD狀態(tài)夕冲,等待client的ACK。
當(dāng)超時發(fā)生時裂逐,就會重傳歹鱼,一直到75s還沒有收到任何回應(yīng),便會放棄卜高,終止連接的創(chuàng)建弥姻。但是在Linux實現(xiàn)中南片,并不是依靠超時總時間來判斷是否終止連接。而是依賴重傳次數(shù):

tcp_syn_retries (integer; default: 5; since Linux 2.2)

The maximum number of times initial SYNs for an active TCP connection attempt will be retransmitted. This value should not be higher than 255. The default value is 5, which corresponds to approximately 180 seconds.

tcp_synack_retries (integer; default: 5; since Linux 2.2)

The maximum number of times a SYN/ACK segment for a passive TCP connection will be retransmitted. This number should not be higher than 255.

Retransmission Timer

當(dāng)三次握手成功庭敦,連接建立疼进,發(fā)送TCP segment,等待ACK確認(rèn)秧廉。如果在指定時間內(nèi)伞广,沒有得到ACK,就會重傳疼电,一直重傳到放棄為止赔癌。Linux中也有相關(guān)變量來設(shè)置這里的重傳次數(shù)的:

tcp_retries1 (integer; default: 3; since Linux 2.2)

The number of times TCP will attempt to retransmit a packet on an established connection normally, without the extra effort of getting the network layers involved. Once we exceed this number of retransmits, we first have the network layer update the route if possible before each new retransmit. The default is the RFC specified minimum of 3.

tcp_retries2 (integer; default: 15; since Linux 2.2)

The maximum number of times a TCP packet is retransmitted in established state before giving up. The default value is 15, which corresponds to a duration of approxi‐mately between 13 to 30 minutes, depending on the retransmission timeout. The RFC 1122 specified minimum limit of 100 seconds is typically deemed too short.

Delayed ACK Timer

當(dāng)一方接受到TCP segment,需要回應(yīng)ACK澜沟。但是不需要 立即 發(fā)送灾票,而是等上一段時間,看看是否有其他數(shù)據(jù)可以 捎帶 一起發(fā)送茫虽。這段時間便是 Delayed ACK Timer 刊苍,一般為200ms。

Persist Timer

如果某一時刻濒析,一方發(fā)現(xiàn)自己的 socket read buffer 滿了正什,無法接受更多的TCP data,此時就是在接下來的發(fā)送包中指定通告窗口的大小為0号杏,這樣對方就不能接著發(fā)送TCP data了婴氮。如果socket read buffer有了空間,可以重設(shè)通告窗口的大小在接下來的 TCP segment 中告知對方盾致≈骶可是萬一這個 TCP segment 不附帶任何data,所以即使這個segment丟失也不會知曉(ACKs are not acknowledged, only data is acknowledged)庭惜。對方?jīng)]有接受到罩驻,便不知通告窗口的大小發(fā)生了變化,也不會發(fā)送TCP data护赊。這樣雙方便會一直僵持下去惠遏。

TCP協(xié)議采用這個機制避免這種問題:對方即使知道當(dāng)前不能發(fā)送TCP data,當(dāng)有data發(fā)送時骏啰,過一段時間后节吮,也應(yīng)該嘗試發(fā)送一個字節(jié)。這段時間便是 Persist Timer 判耕。

Keepalive Timer

TCP socket 的 SO_KEEPALIVE option透绩,主要適用于這種場景:連接的雙方一般情況下沒有數(shù)據(jù)要發(fā)送,僅僅就想嘗試確認(rèn)對方是否依然在線。目前vipbar網(wǎng)吧渺贤,判斷當(dāng)前客戶端是否依然在線雏胃,就用的是這個option请毛。

具體實現(xiàn)方法:TCP每隔一段時間(tcp_keepalive_intvl)會發(fā)送一個特殊的 Probe Segment志鞍,強制對方回應(yīng),如果沒有在指定的時間內(nèi)回應(yīng)方仿,便會重傳固棚,一直到重傳次數(shù)達到 tcp_keepalive_probes 便認(rèn)為對方已經(jīng)crash了。

tcp_keepalive_intvl (integer; default: 75; since Linux 2.4)

The number of seconds between TCP keep-alive probes.

tcp_keepalive_probes (integer; default: 9; since Linux 2.2)

The maximum number of TCP keep-alive probes to send before giving up and killing the connection if no response is obtained from the other end.

tcp_keepalive_time (integer; default: 7200; since Linux 2.2)

The number of seconds a connection needs to be idle before TCP begins sending out keep-alive probes. Keep-alives are only sent when the SO_KEEPALIVE socket option is enabled. The default value is 7200 seconds (2 hours). An idle connection is terminated after approximately an additional 11 minutes (9 probes an interval of 75 sec‐onds apart) when keep-alive is enabled.

Note that underlying connection tracking mechanisms and application timeouts may be much shorter.

FIN_WAIT_2 Timer

當(dāng)主動關(guān)閉方想關(guān)閉TCP connection仙蚜,發(fā)送FIN并且得到相應(yīng)ACK此洲,從FIN_WAIT_1狀態(tài)進入FIN_WAIT_2狀態(tài),此時不能發(fā)送任何data了委粉,只等待對方發(fā)送FIN呜师。可以萬一對方一直不發(fā)送FIN呢贾节?這樣連接就一直處于FIN_WAIT_2狀態(tài)汁汗,也是很經(jīng)典的一個DoS。因此需要一個Timer栗涂,超過這個時間知牌,就放棄這個TCP connection了。

tcp_fin_timeout (integer; default: 60; since Linux 2.2)

This specifies how many seconds to wait for a final FIN packet before the socket is forcibly closed. This is strictly a violation of the TCP specification, but required to prevent denial-of-service attacks. In Linux 2.2, the default value was 180.

TIME_WAIT Timer

TIME_WAIT Timer存在的原因和必要性斤程,主要是兩個方面:

主動關(guān)閉方發(fā)送了一個ACK給對方角寸,假如這個ACK發(fā)送失敗,并導(dǎo)致對方重發(fā)FIN信息忿墅,那么這時候就需要TIME_WAIT狀態(tài)來維護這次連接扁藕,因為假如沒有TIME_WAIT,當(dāng)重傳的FIN到達時疚脐,TCP連接的信息已經(jīng)不存在纹磺,所以就會重新啟動消息應(yīng)答,會導(dǎo)致對方進入錯誤的狀態(tài)而不是正常的終止?fàn)顟B(tài)亮曹。假如主動關(guān)閉方這時候處于TIME_WAIT橄杨,那么仍有記錄這次連接的信息,就可以正確響應(yīng)對方重發(fā)的FIN了照卦。
一個數(shù)據(jù)報在發(fā)送途中或者響應(yīng)過程中有可能成為殘余的數(shù)據(jù)報式矫,因此必須等待足夠長的時間避免新的連接會收到先前連接的殘余數(shù)據(jù)報,而造成狀態(tài)錯誤役耕。
但是我至今疑惑的是:為什么這個超時時間的值為2MSL采转?如果為了保證雙方向的TCP包要么全部響應(yīng)完畢,要么全部丟棄不對新連接造成干擾,這個時間應(yīng)該是:

被動關(guān)閉方LAST_ACK的超時時間 + 1MSL

因為被動關(guān)閉方進入LAST_ACK狀態(tài)后故慈,假設(shè)一直沒有收到最后一個ACK板熊,會一直重傳FIN,一直重傳次數(shù)到達TCP_RETRIES放棄察绷,將這個時間定義為「被動關(guān)閉方LAST_ACK的超時時間」干签,接著必須等待最后一個重傳的FIN失效,需要一個MSL的時間拆撼。這樣才能保證所有重傳的FIN包失效容劳,不干擾新連接吧。


References & Resources

TCP/IP Illustrated

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末闸度,一起剝皮案震驚了整個濱河市竭贩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌莺禁,老刑警劉巖留量,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異哟冬,居然都是意外死亡楼熄,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門柒傻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來孝赫,“玉大人,你說我怎么就攤上這事红符∏啾” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵预侯,是天一觀的道長致开。 經(jīng)常有香客問我,道長萎馅,這世上最難降的妖魔是什么双戳? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮糜芳,結(jié)果婚禮上飒货,老公的妹妹穿的比我還像新娘。我一直安慰自己峭竣,他們只是感情好塘辅,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著皆撩,像睡著了一般扣墩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天呻惕,我揣著相機與錄音荆责,去河邊找鬼。 笑死亚脆,一個胖子當(dāng)著我的面吹牛做院,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播型酥,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼山憨,長吁一口氣:“原來是場噩夢啊……” “哼查乒!你這毒婦竟也來了弥喉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤玛迄,失蹤者是張志新(化名)和其女友劉穎由境,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蓖议,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡虏杰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了勒虾。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纺阔。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖修然,靈堂內(nèi)的尸體忽然破棺而出笛钝,到底是詐尸還是另有隱情,我是刑警寧澤愕宋,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布玻靡,位于F島的核電站,受9級特大地震影響中贝,放射性物質(zhì)發(fā)生泄漏囤捻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一邻寿、第九天 我趴在偏房一處隱蔽的房頂上張望蝎土。 院中可真熱鬧,春花似錦绣否、人聲如沸誊涯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽醋拧。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間丹壕,已是汗流浹背庆械。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留菌赖,地道東北人缭乘。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像琉用,于是被迫代替她去往敵國和親堕绩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348