MSS选项用于通知对端本端能接受的每个TCP分段中的最大数据长度,发送端TCP用接收到的MSS值作为决定所发送分段的最大大小的最大值。MSS选项的总长度为4字节,MSS值为16bit,最大为65535。MSS选项只能在有SYN标记的包中携带。
在初始化socket的时候就需要设置MSS相关信息,connect时:
2752 void tcp_connect_init(struct sock *sk)
2753 {
2754 const struct dst_entry *dst = __sk_dst_get(sk);
2755 struct tcp_sock *tp = tcp_sk(sk);
2756 __u8 rcv_wscale;
...
2778 tp->advmss = dst_metric_advmss(dst); //dst_metric_advmss到路由表中查询MSS,会利用到路径MTU探测的结果
2779 if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < tp->advmss)//tp->rx_opt.user_mss是TCP_MAXSEG socket选项设置的值
2780 tp->advmss = tp->rx_opt.user_mss; //取二者中最小的
...
发送SYN时:
828 static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
829 gfp_t gfp_mask)
830 {
831 const struct inet_connection_sock *icsk = inet_csk(sk);
832 struct inet_sock *inet;
833 struct tcp_sock *tp;
834 struct tcp_skb_cb *tcb;
835 struct tcp_out_options opts;
836 unsigned int tcp_options_size, tcp_header_size;
837 struct tcp_md5sig_key *md5;
838 struct tcphdr *th;
839 int err;
...
868 memset(&opts, 0, sizeof(opts));
869
870 if (unlikely(tcb->tcp_flags & TCPHDR_SYN))
871 tcp_options_size = tcp_syn_options(sk, skb, &opts, &md5);//将选项信息写入opts局部变量中
872 else
873 tcp_options_size = tcp_established_options(sk, skb, &opts,
874 &md5);
...
925 tcp_options_write((__be32 *)(th + 1), tp, &opts);//将opts中的选项信息写入报文的TCP头中
...
构建SYN|ACK时:
2654 struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2655 struct request_sock *req,
2656 struct tcp_fastopen_cookie *foc)
2657 {
2658 struct tcp_out_options opts;
2659 struct inet_request_sock *ireq = inet_rsk(req);
2660 struct tcp_sock *tp = tcp_sk(sk);
2661 struct tcphdr *th;
2662 struct sk_buff *skb;
2663 struct tcp_md5sig_key *md5;
2664 int tcp_header_size;
2665 int mss;
...
2678 mss = dst_metric_advmss(dst);
2679 if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss)
2680 mss = tp->rx_opt.user_mss;
...
2703 memset(&opts, 0, sizeof(opts));
2704 #ifdef CONFIG_SYN_COOKIES
2705 if (unlikely(req->cookie_ts))
2706 TCP_SKB_CB(