tcp timestamps

tcp timestamps

用于开启是否使用 timestamps.

在发起请求的时候在如下的位置会设置 OPTIONS_TS.


/* Compute TCP options for SYN packets. This is not the final
 * network wire format yet.
 */
static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb,
				struct tcp_out_options *opts,
				struct tcp_md5sig_key **md5)
{

......
	if (likely(sysctl_tcp_timestamps && !*md5)) {
		opts->options |= OPTION_TS;
		opts->tsval = tcp_skb_timestamp(skb) + tp->tsoffset;
		opts->tsecr = tp->rx_opt.ts_recent;
		remaining -= TCPOLEN_TSTAMP_ALIGNED;
	}
......
}

在收到的 syn 返回 synack 的情况下, 这个时候也就是一个协商的过程,
所以这里会检查收到的 syn 的选项是不是包含有 OPTION_TS.
这里的在 syn 的选项在解析到 OPTION_TS 的时间,
也只有 sysctl_tcp_timestamps 为 true 的时候可以正确识别.

tcp_make_synack –> tcp_options_write

static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
			      struct tcp_out_options *opts)
{
	u16 options = opts->options;	/* mungable copy */
.......

	if (likely(OPTION_TS & options)) {
		if (unlikely(OPTION_SACK_ADVERTISE & options)) {
			*ptr++ = htonl((TCPOPT_SACK_PERM << 24) |
				       (TCPOLEN_SACK_PERM << 16) |
				       (TCPOPT_TIMESTAMP << 8) |
				       TCPOLEN_TIMESTAMP);
			options &= ~OPTION_SACK_ADVERTISE;
		} else {
			*ptr++ = htonl((TCPOPT_NOP << 24) |
				       (TCPOPT_NOP << 16) |
				       (TCPOPT_TIMESTAMP << 8) |
				       TCPOLEN_TIMESTAMP);
		}
		*ptr++ = htonl(opts->tsval);
		*ptr++ = htonl(opts->tsecr);
	}
.......
}

另补充一个有意思的事情, 我们知道在 timestamp 开启的时候, 如果服务器开启了
tw_recycle 如果机器在 net 后面, 就有可能出错. 我在测试的时候发现.
virtualbox 的 net 会删除 tcp 的 timestamp 选项.


发表评论

邮箱地址不会被公开。 必填项已用*标注