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;
最新文章
- ASP.NET MVC5中的Model验证
- HDU2653 BFS+优先队列
- iOS 面试题(二):什么时候在 block 中不需要使用 weakSelf --转自唐巧
- iPhone SDK 包含哪些东西?
- How Big Is A Petabyte, Exabyte, Zettabyte, Or A Yottabyte?
- VB操作Excel
- Away3d 骨骼动画优化
- Android笔记(一):从this关键字发散
- Effective Java2读书笔记-对于所有对象都通用的方法(三)
- 在javascript中关于变量与函数的提升
- 深入理解Java虚拟机--下
- Learning ROS for Robotics Programming Second Edition学习笔记(三) 补充 hector_slam
- 图 总结 AI
- MySQL查询where条件的顺序对查询效率的影响<;转>;
- [Android]Android数据的四种存储方式
- JedisConnectionPool scala
- js数据类型--对象&;数组
- 解决小米手机不能运行Android Studio程序的问题
- jmeter接口测试注意点
- 洛谷P3764 签到题 III
热门文章
- rest_framework-权限-总结完结篇
- rest_framework 认证功能
- [poj 2912] Rochambeau 解题报告 (带权并查集)
- js中 &#39;枚举&#39; 的使用
- 开源映射平台Mapzen加入了Linux基金会的项目
- 人在IT,关于计算机专业的杂谈PPT
- 紫书 习题 10-5 UVa 1213(01背包变形)
- uvalive 6669 hidden tree(好壮压dp)
- POJ 1152 An Easy Problem! (取模运算性质)
- UVA 12716 GCD XOR(数论+枚举+打表)