看tcp_sync_mss前面的注释,应该可以对这三个mss变量有所了解.
user_mss是使用TCP_MAXSEG选项的setsockopt/getsockopt函数设置的。
mss_clamp用在TCP连接建立时协商时候使用的,取接收到的SYN包的mss值和user_mss的最小值。
mss_cache是当前有效的发送mss。
tp->rx_opt.user_mss is mss set by user by TCP_MAXSEG. It does NOT counts
for TCP options, but includes only bare TCP header.
tp->rx_opt.mss_clamp is mss negotiated at connection setup.
It is minimum of user_mss and mss received with SYN.
It also does not include TCP options.
inet_csk(sk)->icsk_pmtu_cookie is last pmtu, seen by this function.
tp->mss_cache is current effective sending mss, including
all tcp options except for SACKs. It is evaluated,
taking into account current pmtu, but never exceeds
tp->rx_opt.mss_clamp.
NOTE1. rfc1122 clearly states that advertised MSS
DOES NOT include either tcp or ip options.
NOTE2. inet_csk(sk)->icsk_pmtu_cookie and tp->mss_cache
are READ ONLY outside this function. --ANK (980731)
参考:
http://oss.sgi.com/archives/netdev/2000-08/msg00039.html
下面,我们看一下一些代码:
tcp_mtu_to_mss根据pmtu(路径最大传输单元)来计算mss(最大消息传输段),pmtu-IP头部-TCP头部-IP选项-TCP选项,(其中IP选项和TCP选项的长度可能都为0)。
/* Not accounting for SACKs here. */
int tcp_mtu_to_mss(struct sock *sk, int pmtu)
{
struct tcp_sock *tp = tcp_sk(sk);
struct inet_connection_sock *icsk = inet_csk(sk);
int mss_now;
/* Calculate base mss without TCP options:
It is MMS_S - sizeof(tcphdr) of rfc1122
*/
/* ipv4_specific.net_header_len = sizeof(struct iphdr),*/
mss_now = pmtu - icsk->icsk_af_ops->net_header_len - sizeof(struct tcphdr);
/* Clamp it (mss_clamp does not include tcp options) */
if (mss_now > tp->rx_opt.mss_clamp)
mss_now = tp->rx_opt.mss_clamp;
/* Now subtract optional transport overhead */
/*In tcp_v4_connect(),inet_csk(sk)->icsk_ext_hdr_len = inet->opt->optlen;*/
mss_now -= icsk->icsk_ext_hdr_len;
/* Then reserve room for full set of TCP options and 8 bytes of data */
if (mss_now < 48)
mss_now = 48;
/* Now subtract TCP options size, not including SACKs */
mss_now -= tp->tcp_header_len - sizeof(struct tcphdr);
return mss_now;
}
同理,将mss转化为mtu的tcp_mss_to_mtu函数,就是在mss+TCP头部+TCP选项+IP头+IP选项。
int tcp_mss_to_mtu(struct sock *sk, int mss)
{
struct tcp_sock *tp = tcp_sk(sk);
struct inet_connection_sock *icsk = inet_csk(sk);
int mtu;
/*tcp_header_len = TCP Header + TCP Options*/
mtu = mss +
tp->tcp_header_len +
icsk->icsk_ext_hdr_len +
icsk->icsk_af_ops->net_header_len;
return mtu;
}
阅读(2442) | 评论(0) | 转发(0) |