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表项.
相关文章
相关标签/搜索