tcp_tw_recycle检查tcp_timestamps的内核代码

注意:本文档中的内核代码的版本:linux-4.0.5 /************************************************* * Author : Samson * Date : 07/14/2015 * Test platform: * gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2 * GNU bash, 4.3.11(1)-release (x86_64-pc-linux-gnu) * Nginx version: * Nginx 1.6.2 * Nginx 1.8.0 * ***********************************************/

两者的关系net.ipv4.tcp_tw_recycle是与net.ipv4.tcp_timestamps是密切相关的,而net.ipv4.tcp_timestamps默认是开启的,当tcp_tw_recycle和tcp_timestamps同时打开时会激活TCP的一种隐藏属性:缓存连接的时间戳。60秒内,同一源IP的后续请求的时间戳小于缓存中的时间戳,内核就会丢弃该请求。

那么在内核中对应的代码是怎样处理的呢?在内核代码中net/ipv4/tcp_input.c中的tcp_conn_request函数的代码:

if (tcp_death_row.sysctl_tw_recycle) { bool strict;

dst = af_ops->route_req(sk, &fl, req, &strict);

if (dst && strict && !tcp_peer_is_proven(req, dst, true, tmp_opt.saw_tstamp)) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED); goto drop_and_release; } }

//tcp_peer_is_proven函数的实现

bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst, bool paws_check, bool timestamps){ struct tcp_metrics_block *tm; bool ret; if (!dst) return false; rcu_read_lock(); tm = __tcp_get_metrics_req(req, dst); if (paws_check) { if (tm && (u32)get_seconds() – tm->tcpm_ts_stamp < TCP_PAWS_MSL && ((s32)(tm->tcpm_ts – req->ts_recent) > TCP_PAWS_WINDOW || !timestamps)) ret = false; else ret = true; } else { if (tm && tcp_metric_get(tm, TCP_METRIC_RTT) && tm->tcpm_ts_stamp) ret = true; else ret = false; } rcu_read_unlock();

return ret;}

主要参数说明tmp_opt.saw_tstamp:该socket支持tcp_timestamp, tcp_death_row.sysctl_tw_recycle:本机系统开启tcp_tw_recycle选项 TCP_PAWS_MSL:/* Per-host timestamps are invalidated * after this time. It should be equal * (or greater than) TCP_TIMEWAIT_LEN * to provide reliability equal to one * provided by timewait state. */ 60s,该条件判断表示该源ip的上次tcp通讯发生在60s内;

TCP_PAWS_WINDOW:/* Replay window for per-host * timestamps. It must be less than * minimal timewait lifetime. */ 1,该条件判断表示该源ip的上次tcp通讯的timestamp 大于本次tcp;

丢弃请求的关键代码(u32)get_seconds() – tm->tcpm_ts_stamp < TCP_PAWS_MSL表示若当前请求的时间戳小于60S,则返回false,则跳转到goto drop_and_release;进行连接请求的丢弃及资源的回收;

drop_and_release: dst_release(dst); drop_and_free: reqsk_free(req); drop: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); return 0;

本文永久更新链接地址:

,我们首先去了象鼻山,那里景色秀丽神奇,

tcp_tw_recycle检查tcp_timestamps的内核代码

相关文章:

你感兴趣的文章:

标签云: