Linux內核TCP Metrics框架

TCP是一個複雜的協議,這種複雜來源於對報文傳輸的可靠性承諾。對每條TCP連接來說,除了有獨立的狀態機、定時器之外,還有擁塞控制相關的一些運行變量,比如RTTCWNDSSTHRESH等,這些運行參數同樣也是每連接(Per-Connection)的

Per-Connection意味着每條連接的這些參數互不影響,這是理所應當的!但是,想想這個情景:A與B之間已經建立了一條穩定的TCP連接,此時若新建一條新的連接,它的參數該如何設置呢?顯然,和原連接保持一致是個快速達到穩定的辦法。這就好比一個人要去一個陌生的地方,卻不知道該選擇哪種交通工具,也不知道該預估多少時間,對他來說,汲取去過的人的經驗總是一條捷徑。

這就是Linux內核中TCP Metrics框架的作用,它可以爲後續的連接提供指導。當主機之間需要頻繁建立拆除TCP連接時,它帶來的好處更加明顯。

TCP Metrics顯然不能是Per-Connection的,而應該是Per-Host的。也就是說,TCP Metrics表項應該是基於<源IP,目的IP>二元組的。從一臺主機的角度,到達另一個特定地址主機的網絡鏈路狀況應該是被兩臺主機之間的所有連接所共享的。

內核使用tcp_metrics_block表示一條Metrics表項,這些表項根據<源IP,目的IP>組織在tcp_metrics_hash衝突鏈表表中,記錄的值保存在內部tcpm_vals數組

struct tcp_metrics_block {
    struct tcp_metrics_block __rcu    *tcpm_next;
    struct inetpeer_addr        tcpm_saddr;
    struct inetpeer_addr        tcpm_daddr;
    ......
    u32                tcpm_vals[TCP_METRIC_MAX_KERNEL + 1];
    ......
};

當新建TCP連接時,內核使用下面的接口來爲TCP套接字設置TCP Metrics指導下的參數

void tcp_init_metrics(struct sock *sk)

當某條TCP連接收的運行參數發生變化時,比如重新計算RTT了,內核會使用下面的接口來更新它對應的TCP Metrics表項。切記,TCP Metrics表項是Per-Host的,因此,多條TCP連接的套接字可能會更新同一條表項。

void tcp_update_metrics(struct sock *sk)
內核同樣提供ip-tcp_metrics命令查看主機上的TCP Metrics表項.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章