Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5772062
  • 博文数量: 675
  • 博客积分: 20301
  • 博客等级: 上将
  • 技术积分: 7671
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-31 16:15
文章分类

全部博文(675)

文章存档

2012年(1)

2011年(20)

2010年(14)

2009年(63)

2008年(118)

2007年(141)

2006年(318)

分类: LINUX

2008-01-11 17:55:27

看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) |
给主人留下些什么吧!~~