您的位置:首页 > 理论基础 > 计算机网络

tcp_tw_recycle检查tcp_timestamps的内核代码

2017-06-16 19:14 141 查看
注意:本文档中的内核代码的版本号:linux-4.0.5

/[b]*************************************************[/b]

* 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

* [b]***********************************************[/b]/

两者的关系

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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: