當前位置:首頁 > 公眾號精選 > 小林coding
[導讀]??大家好,我是小林。之前我在「實戰(zhàn)!我用“大白鯊”讓你看見TCP」這篇文章里做了TCP三次握手的三個實驗:實驗一:模擬TCP第一次握手的SYN丟包;實驗二:模擬TCP第二次握手的SYN、ACK丟包;實驗三:模擬TCP第三次握手的ACK包丟;這篇文章在知乎還挺高贊的,超過1000...

?

?大家好,我是小林。之前我在「實戰(zhàn)!我用“大白鯊”讓你看見 TCP」這篇文章里做了 TCP 三次握手的三個實驗:
  • 實驗一:模擬 TCP 第一次握手的 SYN 丟包;

  • 實驗二:模擬 TCP 第二次握手的 SYN、ACK 丟包;

  • 實驗三:模擬 TCP 第三次握手的 ACK 包丟;

這篇文章在知乎還挺高贊的,超過 1000 贊了。不過,實驗二分析的過程中,之前有個讀者反饋給我說,我說的有問題。實驗二我是在客戶端的防火墻加入了屏蔽服務端所有的數(shù)據(jù)包來模擬第二次握手丟失的現(xiàn)象,先給大家看看當時的實驗圖,以及我說分析過程。圖中紅色框起來的那句話有問題,正確來說:第二次握手的 SYN、ACK 報文的重傳定時器并不會因為收到 SYN 包后被重置,因為第二次握手的包需要被第三次握手的 ACK 確認后,才會重置重傳定時器。
我也把 TCP 三次握手模擬異常情況的實驗過程整理了下,大家有興趣可以模仿我這篇文章的實驗步驟來做實驗。5000字的車,坐穩(wěn)了!

TCP 三次握手異常情況實戰(zhàn)分析

TCP 三次握手的過程相信大家都背的滾瓜爛熟,那么你有沒有想過這三個異常情況:
  • TCP 第一次握手的 SYN 丟包了,會發(fā)生了什么?

  • TCP 第二次握手的 SYN、ACK 丟包了,會發(fā)生什么?

  • TCP 第三次握手的 ACK 包丟了,會發(fā)生什么?

有的小伙伴可能說:“很簡單呀,包丟了就會重傳嘛?!蹦俏以诶^續(xù)問你:
  • 那會重傳幾次?

  • 超時重傳的時間 RTO 會如何變化?

  • 在 Linux 下如何設置重傳次數(shù)?

  • ….

是不是啞口無言,無法回答?不知道沒關(guān)系,接下里我用三個實驗案例,帶大家一起探究探究這三種異常。

實驗場景

本次實驗用了兩臺虛擬機,一臺作為服務端,一臺作為客戶端,它們的關(guān)系如下:
實驗環(huán)境
  • 客戶端和服務端都是 CentOs 6.5 Linux,Linux 內(nèi)核版本 2.6.32

  • 服務端 192.168.12.36,apache web 服務

  • 客戶端 192.168.12.37

實驗一:TCP 第一次握手 SYN 丟包

為了模擬 TCP 第一次握手 SYN 丟包的情況,我是在拔掉服務器的網(wǎng)線后,立刻在客戶端執(zhí)行 curl 命令:
其間 tcpdump 抓包的命令如下:
過了一會, curl 返回了超時連接的錯誤:
date 返回的時間,可以發(fā)現(xiàn)在超時接近 1 分鐘的時間后,curl 返回了錯誤。接著,把 tcp_sys_timeout.pcap 文件用 Wireshark 打開分析,顯示如下圖:
SYN 超時重傳五次
從上圖可以發(fā)現(xiàn), 客戶端發(fā)起了 SYN 包后,一直沒有收到服務端的 ACK ,所以一直超時重傳了 5 次,并且每次 RTO 超時時間是不同的:
  • 第一次是在 1 秒超時重傳

  • 第二次是在 3 秒超時重傳

  • 第三次是在 7 秒超時重傳

  • 第四次是在 15 秒超時重傳

  • 第五次是在 31 秒超時重傳

可以發(fā)現(xiàn),每次超時時間 RTO 是指數(shù)(翻倍)上漲的,當超過最大重傳次數(shù)后,客戶端不再發(fā)送 SYN 包。在 Linux 中,第一次握手的 SYN 超時重傳次數(shù),是如下內(nèi)核參數(shù)指定的:$?cat?/proc/sys/net/ipv4/tcp_syn_retries
5
tcp_syn_retries 默認值為 5,也就是 SYN 最大重傳次數(shù)是 5 次。接下來,我們繼續(xù)做實驗,把 tcp_syn_retries 設置為 2 次:$?echo?2?>?/proc/sys/net/ipv4/tcp_syn_retries
重傳抓包后,用 Wireshark 打開分析,顯示如下圖:
SYN 超時重傳兩次
實驗一的實驗小結(jié)
通過實驗一的實驗結(jié)果,我們可以得知,當客戶端發(fā)起的 TCP 第一次握手 SYN 包,在超時時間內(nèi)沒收到服務端的 ACK,就會在超時重傳 SYN 數(shù)據(jù)包,每次超時重傳的 RTO 是翻倍上漲的,直到 SYN 包的重傳次數(shù)到達 tcp_syn_retries 值后,客戶端不再發(fā)送 SYN 包。
SYN 超時重傳

實驗二:TCP 第二次握手 SYN、ACK 丟包

為了模擬客戶端收不到服務端第二次握手 SYN、ACK 包,我的做法是在客戶端加上防火墻限制,直接粗暴的把來自服務端的數(shù)據(jù)都丟棄,防火墻的配置如下:
接著,在客戶端執(zhí)行 curl 命令:
date 返回的時間前后,可以算出大概 1 分鐘后,curl 報錯退出了??蛻舳嗽谶@其間抓取的數(shù)據(jù)包,用 Wireshark 打開分析,顯示的時序圖如下:
從圖中可以發(fā)現(xiàn):
  • 客戶端發(fā)起 SYN 后,由于防火墻屏蔽了服務端的所有數(shù)據(jù)包,所以 curl 是無法收到服務端的 SYN、ACK 包,當發(fā)生超時后,就會重傳 SYN 包

  • 服務端收到客戶的 SYN 包后,就會回 SYN、ACK 包,但是客戶端一直沒有回 ACK,服務端在超時后,重傳了 SYN、ACK 包,接著一會,客戶端超時重傳的 SYN 包又抵達了服務端,服務端收到后,然后回了 SYN、ACK 包,但是SYN、ACK包的重傳定時器并沒有重置,還持續(xù)在重傳,因為第二次握手在沒收到第三次握手的 ACK 確認報文時,就會重傳到最大次數(shù)。

  • 最后,客戶端 SYN 超時重傳次數(shù)達到了 5 次(tcp_syn_retries 默認值 5 次),就不再繼續(xù)發(fā)送 SYN 包了。

所以,我們可以發(fā)現(xiàn),當?shù)诙挝帐值?SYN、ACK 丟包時,客戶端會超時重發(fā) SYN 包,服務端也會超時重傳 SYN、ACK 包。
咦?客戶端設置了防火墻,屏蔽了服務端的網(wǎng)絡包,為什么 tcpdump 還能抓到服務端的網(wǎng)絡包?
添加 iptables 限制后, tcpdump 是否能抓到包 ,這要看添加的 iptables 限制條件:
  • 如果添加的是 INPUT 規(guī)則,則可以抓得到包

  • 如果添加的是 OUTPUT 規(guī)則,則抓不到包

網(wǎng)絡包進入主機后的順序如下:
  • 進來的順序 Wire -> NIC -> tcpdump -> netfilter/iptables

  • 出去的順序 iptables -> tcpdump -> NIC -> Wire

tcp_syn_retries 是限制 SYN 重傳次數(shù),那第二次握手 SYN、ACK 限制最大重傳次數(shù)是多少?
TCP 第二次握手 SYN、ACK 包的最大重傳次數(shù)是通過 tcp_synack_retries 內(nèi)核參數(shù)限制的,其默認值如下:$?cat?/proc/sys/net/ipv4/tcp_synack_retries
5
是的,TCP 第二次握手 SYN、ACK 包的最大重傳次數(shù)默認值是 5 次。為了驗證 SYN、ACK 包最大重傳次數(shù)是 5 次,我們繼續(xù)做下實驗,我們先把客戶端的 tcp_syn_retries 設置為 1,表示客戶端 SYN 最大超時次數(shù)是 1 次,目的是為了防止多次重傳 SYN,把服務端 SYN、ACK 超時定時器重置。接著,還是如上面的步驟:
  1. 客戶端配置防火墻屏蔽服務端的數(shù)據(jù)包

  2. 客戶端 tcpdump 抓取 curl 執(zhí)行時的數(shù)據(jù)包

把抓取的數(shù)據(jù)包,用 Wireshark 打開分析,顯示的時序圖如下:
從上圖,我們可以分析出:
  • 客戶端的 SYN 只超時重傳了 1 次,因為 tcp_syn_retries 值為 1

  • 服務端應答了客戶端超時重傳的 SYN 包后,由于一直收不到客戶端的 ACK 包,所以服務端一直在超時重傳 SYN、ACK 包,每次的 RTO 也是指數(shù)上漲的,一共超時重傳了 5 次,因為 tcp_synack_retries 值為 5

接著,我把 tcp_synack_retries 設置為 2,tcp_syn_retries 依然設置為 1:$?echo?2?>?/proc/sys/net/ipv4/tcp_synack_retries
$?echo?1?>?/proc/sys/net/ipv4/tcp_syn_retries
依然保持一樣的實驗步驟進行操作,接著把抓取的數(shù)據(jù)包,用 Wireshark 打開分析,顯示的時序圖如下:
可見:
  • 客戶端的 SYN 包只超時重傳了 1 次,符合 tcp_syn_retries 設置的值;

  • 服務端的 SYN、ACK 超時重傳了 2 次,符合 tcp_synack_retries 設置的值

實驗二的實驗小結(jié)
通過實驗二的實驗結(jié)果,我們可以得知,當 TCP 第二次握手 SYN、ACK 包丟了后,客戶端 SYN 包會發(fā)生超時重傳,服務端 SYN、ACK 也會發(fā)生超時重傳??蛻舳?SYN 包超時重傳的最大次數(shù),是由 tcp_syn_retries 決定的,默認值是 5 次;服務端 SYN、ACK 包時重傳的最大次數(shù),是由 tcp_synack_retries 決定的,默認值是 5 次。

實驗三:TCP 第三次握手 ACK 丟包

為了模擬 TCP 第三次握手 ACK 包丟,我的實驗方法是在服務端配置防火墻,屏蔽客戶端 TCP 報文中標志位是 ACK 的包,也就是當服務端收到客戶端的 TCP ACK 的報文時就會丟棄,iptables 配置命令如下:
接著,在客戶端執(zhí)行如下 tcpdump 命令:
然后,客戶端向服務端發(fā)起 telnet,因為 telnet 命令是會發(fā)起 TCP 連接,所以用此命令做測試:
此時,由于服務端收不到第三次握手的 ACK 包,所以一直處于 SYN_RECV 狀態(tài):
而客戶端是已完成 TCP 連接建立,處于 ESTABLISHED 狀態(tài):
過了 1 分鐘后,觀察發(fā)現(xiàn)服務端的 TCP 連接不見了:
過了 30 分別,客戶端依然還是處于 ESTABLISHED 狀態(tài):
接著,在剛才客戶端建立的 telnet 會話,輸入 123456 字符,進行發(fā)送:
持續(xù)「好長」一段時間,客戶端的 telnet 才斷開連接:
以上就是本次的實現(xiàn)三的現(xiàn)象,這里存在兩個疑點:
  • 為什么服務端原本處于 SYN_RECV 狀態(tài)的連接,過 1 分鐘后就消失了?

  • 為什么客戶端 telnet 輸入 123456 字符后,過了好長一段時間,telnet 才斷開連接?

不著急,我們把剛抓的數(shù)據(jù)包,用 Wireshark 打開分析,顯示的時序圖如下:
上圖的流程:
  • 客戶端發(fā)送 SYN 包給服務端,服務端收到后,回了個 SYN、ACK 包給客戶端,此時服務端的 TCP 連接處于 SYN_RECV 狀態(tài);

  • 客戶端收到服務端的 ?SYN、ACK 包后,給服務端回了個 ACK 包,此時客戶端的 TCP 連接處于 ESTABLISHED 狀態(tài);

  • 由于服務端配置了防火墻,屏蔽了客戶端的 ACK 包,所以服務端一直處于 SYN_RECV 狀態(tài),沒有進入 ?ESTABLISHED 狀態(tài),tcpdump 之所以能抓到客戶端的 ACK 包,是因為數(shù)據(jù)包進入系統(tǒng)的順序是先進入 tcpudmp,后經(jīng)過 iptables;

  • 接著,服務端超時重傳了 SYN、ACK 包,重傳了 5 次后,也就是超過 tcp_synack_retries 的值(默認值是 5),然后就沒有繼續(xù)重傳了,此時服務端的 TCP 連接主動中止了,所以剛才處于 SYN_RECV 狀態(tài)的 TCP 連接斷開了,而客戶端依然處于ESTABLISHED 狀態(tài);

  • 雖然服務端 TCP 斷開了,但過了一段時間,發(fā)現(xiàn)客戶端依然處于ESTABLISHED 狀態(tài),于是就在客戶端的 telnet 會話輸入了 123456 字符;

  • 此時由于服務端已經(jīng)斷開連接,客戶端發(fā)送的數(shù)據(jù)報文,一直在超時重傳,每一次重傳,RTO 的值是指數(shù)增長的,所以持續(xù)了好長一段時間,客戶端的 telnet 才報錯退出了,此時共重傳了 15 次。

通過這一波分析,剛才的兩個疑點已經(jīng)解除了:
  • 服務端在重傳 SYN、ACK 包時,超過了最大重傳次數(shù) tcp_synack_retries,于是服務端的 TCP 連接主動斷開了。

  • 客戶端向服務端發(fā)送數(shù)據(jù)包時,由于服務端的 TCP 連接已經(jīng)退出了,所以數(shù)據(jù)包一直在超時重傳,共重傳了 15 次, telnet 就斷開了連接。

TCP 第一次握手的 SYN 包超時重傳最大次數(shù)是由 tcp_syn_retries 指定,TCP 第二次握手的 SYN、ACK 包超時重傳最大次數(shù)是由 tcp_synack_retries 指定,那 TCP 建立連接后的數(shù)據(jù)包最大超時重傳次數(shù)是由什么參數(shù)指定呢?
TCP 建立連接后的數(shù)據(jù)包傳輸,最大超時重傳次數(shù)是由 tcp_retries2 指定,默認值是 15 次,如下:$?cat?/proc/sys/net/ipv4/tcp_retries2
15
如果 15 次重傳都做完了,TCP 就會告訴應用層說:“搞不定了,包怎么都傳不過去!”
那如果客戶端不發(fā)送數(shù)據(jù),什么時候才會斷開處于 ESTABLISHED 狀態(tài)的連接?
這里就需要提到 TCP 的 ?;顧C制。這個機制的原理是這樣的:定義一個時間段,在這個時間段內(nèi),如果沒有任何連接相關(guān)的活動,TCP 保活機制會開始作用,每隔一個時間間隔,發(fā)送一個「探測報文」,該探測報文包含的數(shù)據(jù)非常少,如果連續(xù)幾個探測報文都沒有得到響應,則認為當前的 TCP 連接已經(jīng)死亡,系統(tǒng)內(nèi)核將錯誤信息通知給上層應用程序。在 Linux 內(nèi)核可以有對應的參數(shù)可以設置保活時間、保活探測的次數(shù)、?;钐綔y的時間間隔,以下都為默認值:net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_keepalive_intvl=75??
net.ipv4.tcp_keepalive_probes=9
  • tcp_keepalive_time=7200:表示?;顣r間是 7200 秒(2小時),也就 2 小時內(nèi)如果沒有任何連接相關(guān)的活動,則會啟動?;顧C制

  • tcp_keepalive_intvl=75:表示每次檢測間隔 75 秒;

  • tcp_keepalive_probes=9:表示檢測 9 次無響應,認為對方是不可達的,從而中斷本次的連接。

也就是說在 Linux 系統(tǒng)中,最少需要經(jīng)過 2 小時 11 分 15 秒才可以發(fā)現(xiàn)一個「死亡」連接。
這個時間是有點長的,所以如果我抓包足夠久,或許能抓到探測報文。
實驗三的實驗小結(jié)
在建立 TCP 連接時,如果第三次握手的 ACK,服務端無法收到,則服務端就會短暫處于 SYN_RECV 狀態(tài),而客戶端會處于 ESTABLISHED 狀態(tài)。由于服務端一直收不到 TCP 第三次握手的 ACK,則會一直重傳 SYN、ACK 包,直到重傳次數(shù)超過 tcp_synack_retries 值(默認值 5 次)后,服務端就會斷開 TCP 連接。而客戶端則會有兩種情況:
  • 如果客戶端沒發(fā)送數(shù)據(jù)包,一直處于 ESTABLISHED 狀態(tài),然后經(jīng)過 2 小時 11 分 15 秒才可以發(fā)現(xiàn)一個「死亡」連接,于是客戶端連接就會斷開連接。

  • 如果客戶端發(fā)送了數(shù)據(jù)包,一直沒有收到服務端對該數(shù)據(jù)包的確認報文,則會一直重傳該數(shù)據(jù)包,直到重傳次數(shù)超過 tcp_retries2 值(默認值 15 次)后,客戶端就會斷開 TCP 連接。

好了,這次就分享到這了。小林周末會寫一篇協(xié)程,大家敬請期待哈。??

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉