使用Wireshark研究網絡協議

常見的網絡問題

小包問題也叫愚笨窗口綜合症(Silly Window Syndrome)

常常會有這樣的情況,應用層傳遞給TCP傳輸層的數據很小,要比TCP(20Bytes)+ IP(20Byte)頭部的大小還要小,這樣其實是一種浪費,我們把這樣的問題叫愚笨窗口綜合症,也叫小包問題。

延遲確認(Delayed ACK) 與 Nagle 算法

延遲確認是一種常見的TCP交互式場景策略,常見的例子(愚笨窗口綜合症)就是SSH與遠程服務器建立連接之後在命令行輸入的每一個字母在發送方打開延遲確認的TCP選項之後,發送方發給接收方的網絡包中如果除了確認收到報文之外沒有什麼信息需要回復給發送方,那麼接收方就會等待一個超時的時間(TCP協議規定這個值應當小於500ms rfc1122 ,不同的操作系統中這個值有所不同)之後在回覆確認報文。本質上是通過在網絡信道中減少網絡包的發送來優化網絡。

Nagle算法是通過在發送方維護一個“buffer”,將發送包體大小積累到一個MSS之後發送網絡包。

<code>if there is new data to send then
if the window size ≥ MSS and available data is ≥ MSS then
send complete MSS segment now
else
if there is unconfirmed data still in the pipe then
enqueue data in the buffer until an acknowledge is received
else
send data immediately

end if
end if
end if
/<code>

本質上也是通過在信道中減少網絡包的發送數量來優化網絡傳輸。

聽起來兩種機制都是沒有什麼問題的,都是在解決特定環境下的特定問題。但是如果發送方開啟了Nagle算法與此同時接收方也開啟了延遲確認,在發送方出現write-write-read這樣的報文組合的時候就有可能出現等待到一個延遲確認超時時間後的網絡等待。

如何解決延遲確認與Nagle算法衝突的問題

兩種思路:

  • 在應用層,避免出現 write-wirte-read這樣的網絡調用
  • 在傳輸協議層,在發送方關閉Nagle算法機制或者在接收方關閉DelayACK

對於關閉DelayedACK:

<code>TCP_QUICKACK
tcp_delack_min
/<code>
<code># echo 1 > /proc/sys/net/ipv4/tcp_delack_min
/<code>

RHEL - realtime tuning - Reduce TCP Delayed ack timeout

對於關閉 Nagle 算法:

在TCP連接選項中選擇 TCP_NO_DELAY

網絡包重傳

協議中的重傳場景:

超時重傳

出現擁塞,當發送方的原包發出後經過一個RTO的超時等待時間後就會重傳這個網絡包。

超時重傳之後,擁塞窗口(發送窗口)的大小也需要調整,協議中建議 cnwnd = min ( traffic_in_flight / 2, 2)。

快速重傳

如果接收方收到一組亂序的網絡包,按照協議它應當連續發送3個重複ack,當發送方收到這樣的ACK後需要啟動快速重傳機制。

具體細節詳見下面wireshark抓包分析截圖:

使用Wireshark研究網絡協議

網絡包亂序

接收方收到亂序包需要根據協議發送重複的3個ACK確認包,隨後發送方會有快速重傳的機制將接收方的ACK包重傳,而無視RTO的超時限制。

細節參見上方快速重傳Wireshark抓包分析截圖。

網絡傳輸慢速

慢啟動與網絡擁塞點

計劃使用FTP協議傳輸大文件,進行網絡抓包分析,得出類似下面的 time/sequence graph(steven):

// TODO

使用Wireshark研究網絡協議

TCP發送窗口

LRO(Large Recieve offload)

WireShark 如何解決

查看超時重傳的方法

<code>Analysis -> Expert information
/<code>

Note 類信息中Summary 部分為 “this frame is a (suspected) retransmission “

使用Wireshark自動分析

  • 查看分析的摘要信息
<code>Analysis -> Expert information
/<code>
  • 選定需要查看的TCP連接,查看TCP stream Graph 等統計信息
<code>Statistics -> TCP Stream Graph
/<code>

Time-Sequence Graph(steven)

有用的幾個WireShark配置

常用的幾個網絡命令

  • 使用ICMP發送指定大小的網絡包(macOS)
<code>ping  -s <packa> -D -c <repeat>
/<repeat>/<packa>
/<code>

其中 -D 參數表示 在 IP 包中flag設置中 DF(Don’t Fragment) 標誌

  • WireShark中列出超過200ms的ack報文(查詢疑似延遲確認報文)
<code>tcp.analysis.ack_rtt>0.1 and tcp.len==0
/<code>

文中名詞解釋

MSS(Maximum Segment Size)

TCP的3次握手會將雙方的MSS值告訴對方,將MSS值加上TCP頭和IP頭的長度就知道了下面的MTU的大小。

MTU(Maximum Trasmission Unit)

MTU = MSS + TCP Head length(一般是20Bytes) + IP Head leagth(20Bytes)

通常的大多數網絡中MTU的大小在 1500 Bytes,而開啟了巨幀(Jumbo Frame)的網絡MTU的大小在 9000 Bytes。


分享到:


相關文章: