tcp_tw_reuse对客户端的作用

tcp_tw_reuse对客户端的作用

客户端频繁建立连接然后主动关闭连接,会产生大量TIME_WAIT,此时,如何快速利用TIME_WAIT呢?
必须满足下面所有条件:

客户端:

/proc/sys/net/ipv4/tcp_tw_reuse   为 1   #TIME_WAIT socket 生存时间超过1秒
/proc/sys/net/ipv4/tcp_timestamps 为 1  

服务端:

/proc/sys/net/ipv4/tcp_timestamps 为 1

缺点:如果网络整个访问路径存在防火墙或者lvs,则 还需要 确定他们 能否透传 TCP的tcp_timestamps,如果中间设备修改或者删除tcp_timestamps,那么即使client 和 server 都满足了条件,还是不能起效果。所以一旦出现开启了tcp_timestampstcp_tw_reuse但是客户端还是不能重用timewait的socket,建议在终端(客户端和最终server)抓包,对比报文。

内核源码:

int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
{
	const struct tcp_timewait_sock *tcptw = tcp_twsk(sktw);
	struct tcp_sock *tp = tcp_sk(sk);

	/* With PAWS, it is safe from the viewpoint
	   of data integrity. Even without PAWS it is safe provided sequence
	   spaces do not overlap i.e. at data rates <= 80Mbit/sec.

	   Actually, the idea is close to VJ's one, only timestamp cache is
	   held not per host, but per port pair and TW bucket is used as state
	   holder.

	   If TW bucket has been already destroyed we fall back to VJ's scheme
	   and use initial timestamp retrieved from peer table.
	 */
	//tcptw->tw_ts_recent_stamp 为1表示老的timewait socket 是携带时间戳的,即server端需要开启 tcp_timestamps。
	// sysctl_tcp_tw_reuse 表示本机开启了tcp_timestamps 
	// get_seconds() - tcptw->tw_ts_recent_stamp > 1,表示老的timewait socket已经超过1秒
	if (tcptw->tw_ts_recent_stamp &&
	    (twp == NULL || (sysctl_tcp_tw_reuse &&
			     get_seconds() - tcptw->tw_ts_recent_stamp > 1))) {
		tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
		if (tp->write_seq == 0)
			tp->write_seq = 1;
		tp->rx_opt.ts_recent	   = tcptw->tw_ts_recent;
		tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
		sock_hold(sktw);
		return 1;
	}

	return 0;
}
发布了122 篇原创文章 · 获赞 117 · 访问量 50万+

猜你喜欢

转载自blog.csdn.net/mrpre/article/details/86481253
今日推荐