Linux內核TCP Metrics框架

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

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

這就是Linux內核中TCP Metrics框架的做用,它能夠爲後續的鏈接提供指導。當主機之間須要頻繁創建拆除TCP鏈接時,它帶來的好處更加明顯。網絡

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

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

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-Destination的,所以,多條TCP鏈接的套接字可能會更新同一條表項。code

void tcp_update_metrics(struct sock *sk)
內核一樣提供 ip-tcp_metrics命令查看主機上的 TCP Metrics表項.
相關文章
相關標籤/搜索