net.ipv4.tcp_timestamps


設計目的

tcp_timestamps設計目的是為了記錄數據包的發送時間,過程如下

  1. 發送方在發送數據包時,在TCP協議中的TSopt選項記錄當前的發送的時間戳TSval中
  2. 接收方收到數據包,進行拆封並把發送的時間戳TSval記錄在TSecr返回給發送方一個ack
  3. 發送包收接收方的ack包,用當前時間戳 - ack中的TSecr時間戳就可以得到精確的RTT

數據結構

  • 數據包結構
    Kind: 8             // 標記唯一的選項類型,比如window scale是3
    Length: 10 bytes    // 標記Timestamps選項的字節數
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    | Kind=8 | Length=10 | TS Value (TSval) | TS ECho Reply (TSecr) |
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        1          1             4                       4

    值得注意,tcp_timestamps必須需要雙方都要開啟方可生效,這是前提條件,如果有一方沒有開啟則雙方進行數據發送接收時該功能不起作用(比如client端發送的SYN包中帶有timestamp選項,但server端並沒有開啟該選項。則回復的SYN-ACK將不帶timestamp選項,同時client后續回復的ACK也不會帶有timestamp選項。當然,如果client發送的SYN包中就不帶timestamp,雙向都將停用timestamp

  • 該參數內核默認是啟用的,即為 1

功能作用

摘抄網絡

如果沒有tcp_timestamps,看一下RTT是如何計算的

  1. TCP層在發送出一個SKB時,使用skb->when記錄發送出去的時間
  2. TCP層在收到SKB數據包的確認時,使用now - skb->when來計算RTT

但如果發生丟包事件后,該如何計算

  1. TCP層第一次發送SKB的時間是send_time1, TCP層重傳一個數據包的時間是send_time2
  2.  當TCP層收到SKB的確認包的時間是recv_time

但是RTT應該是 (recv_time - send_time1)呢,還是(recv_time - send_time2)呢?

以上兩種方式都不可取!因為無法判斷出recv_time對應的ACK是確認第一次數據包的發送還是確認重傳數據包。因此TCP協議棧只能選擇非重傳數據包進行RTT采樣。但是當出現嚴重丟包(比如整個窗口全部丟失)時,就完全沒有數據包可以用於RTT采樣。這樣后續計算SRTT和RTO就會出現較大的偏差

timestamp選項很好的解決了上述問題,因為ACK包里面帶的TSecr值,一定是觸發這個ACK的數據包在發送端發送的時間。不管數據包是否重傳都能准確的計算RTT(前提是TSecr遵循RTTM中的計算原則)。

當然timestamp不僅解決了RTT計算的問題,還很好的為PAWS機制提供的信息依據。

什么是 RTT & RTO

  • RTO (Rerrtransmission TimeOut)即,數據包重傳超時時間

官方RFC2988文中定義 

The Transmission Control Protocol (TCP) [Pos81] uses a retransmission
timer to ensure data delivery in the absence of any feedback from the
remote data receiver.  The duration of this timer is referred to as
RTO (retransmission timeout).  RFC 1122 [Bra89] specifies that the
RTO should be calculated as outlined in [Jac88]

TCP超時與重傳中的一個相當重要的部分,是對一個已知連接的RTT時間的測量,由於網絡波動則會根據實際的情況相應的調整RTO時間

  • RTT (Round Trip Time)即數據報文在整個鏈路的傳播時間(從發送開始到返回的時間的差值)

RTT由三個部分組成

  1. 鏈路的傳播時間
  2. 末端系統處理時間
  3. 路由器緩存隊列及處理時間

具體測量方法,實際測量方法有二種(tcp_timestamps & 重傳隊列中數據包TCP控制塊),只介紹tcp_timestamps

RTT= 數據包返回的當前時間 - 返回數據包中的TSecr中的echo時間戳

什么是PAWS

PAWS(Protect Againest Wrapped Sequence numbers)

中文理解,目的是解決在高帶寬,高流速情況下,解決TCP序號重復排列帶來的問題(默認情況下60s內同一源ip主機的socket connect請求中的timestamp必須是遞增的

PAWS同樣也依賴於tcp_timestamps,假設在一個TCP傳輸流中,按序列接收到所有報文的中timestamp值也是線性遞增的,在正常情況下,每個數據報文都是按序發送攜帶的timestamp值同樣是線性增加的

  1. 字段名詞解釋
    Per-Connection State Variables
        TS.Recent:       Latest received Timestamp
        Last.ACK.sent:   Last ACK field sent
    
    Option Fields in Current Segment
        SEG.TSval:   TSval field from TSopt in current segment.
        SEG.TSecr:   TSecr field from TSopt in current segment.

    TS.Recent存放着按序達到的所有TCP數據包的最晚的一個時間戳,即只有在SEG.SEQ <= Last.ACK.sent < SEG.SEG + SEG.LEN(有新的數據被按序確認了)時,才會更新數據包中的TS.Recent的值

    假設三個數據包的*第一次*發送時間分別是A,B和C(A < B < C),但A和C含有相同的序列號。
    而A數據包由於某種原因,在阻塞在了網絡中,因此發送方進行了重傳,重傳時間為A2

    PAWS要解決的主要問題就是:
        當接收端在接收到A2后,又接着確認到了數據包B,下一個想接收的數據是數據包C
        此時如果收到了數據包A(A從阻塞中恢復過來了,但並未真的丟失),
        由於A與C的序列號是相同的。如果沒有別的保護措施就會出現數據紊亂,沒有做到可靠傳輸

PAWS的做法就是,如果收到的一個TCP數據包的timestamp值小於TS.Recnt,則會丟棄該數據包。  因此數據包A到達接收方后,接收方的TS.Recent應該是數據包B中的timestamp而A < B,故A包就會被丟棄。而真正有效的數據C到達接收后,由於B < C,因此能被正常接收

英文解釋

  1. It is recommended that RST segments NOT carry timestamps, and thatRST segments be acceptable regardless of their timestamp.
  2. PAWS is defined strictly within a single connection; the last timestamp is TS.Recent is kept in the connection control block, and  discarded when a connection is closed.
  3. An additional mechanism could be added to the TCP, a per-host cache of the last timestamp received from any connection. This value could then be used in the PAWS mechanism to reject old duplicate segments from earlier incarnations of the connection, if the timestamp clock can be guaranteed to have ticked at least once since the old connection was open.

 第三點說明,如果per-host使用PAWS機制的話,可以很好的解決在TIME_WAIT上一次數據報文在下一次傳輸在被視為有效的報文,只要等待足夠的RTO,處理好需要重傳最后一個ack包,於是衍生出下列機制

同時啟用tw_recycle & tcp_timestamps時,可以達到快速回收TIME_WAIT的連接,但是這樣並沒有真正的有效解決,在互聯網中,由其主動訪問的終端(辦公室這種環境,很多情況下都是通過NAT上網,這樣無法確保發送的TCP報文中的時間戳是線性遞增的,也無法確保終端的時間是一一致的,如果發送時間戳不是線性遞增的,A B C 很有可能C的時間戳小於B,則被服務端丟棄,不符合PAWS的運行機制)

總結

  1. tcp_timestamps主要作用如下更精准的度量TCP連接數據報文傳輸過程中的RTT值,尤其在丟包情況下(RTTM在ACK被重傳的數據時,應該使用重傳數據包中的TSval進行回復)
  2. 加強PAWS在特殊情況的下(時間戳非線性遞增,seq重復使用)確保TCP可靠傳輸

參考文獻


https://perthcharles.github.io/2015/08/27/timestamp-intro/

https://blog.csdn.net/sinat_20184565/article/details/105000868

https://blog.csdn.net/zhangskd/article/details/7196707


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM