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;

时间: 2024-10-13 16:47:12

tcp_tw_recycle检查tcp_timestamps的内核代码的相关文章

tcp_tw_recycle和tcp_timestamps的文章汇总

临近年关,人会变得浮躁,期间写的代码可谓乱七八糟.不过出来混始终是要还的,这不最近就发现一个PHP脚本时常连不上服务器. 遇到这类问题,我习惯于先用strace命令跟踪了一下看看: shell> strace php /path/to/file EADDRNOTAVAIL (Cannot assign requested address) 从字面结果看似乎是网络资源相关问题.这里顺便介绍一点小技巧:在调试的时候一般是从后往前看strace命令的结果,这样更容易找到有价值的信息. 查看一下当前的网

驱动相关的内核代码分析

arch\arm\include\asm\Io.h #define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force   *)(a)) #define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force   *)(a) = (v)) 注:(volatile unsigned int __force   *)指针强制转换为unsigne

Linux0.11内核剖析--内核代码(kernel)--sched.c

1.概述 linux/kernel/目录下共包括 10 个 C 语言文件和 2 个汇编语言文件以及一个 kernel 下编译文件的管理配置文件 Makefile.其中三个子目录中代码注释的将放在后面的文章进行.本文主要对这 13 个代码文件进行注释. 首先我们对所有程序的基本功能进行概括性地总体介绍, 以便一开始就对这 12 个文件所实现的功能和它们之间的相互调用关系有个大致的了解,然后逐一对代码进行详细地注释.本文地址:http://www.cnblogs.com/archimedes/p/l

(转):从内核代码聊聊pipe的实现

来源: http://luodw.cc/2016/07/09/pipeof/ 用linux也有两年多了,从命令,系统调用,到内核原理一路学过来,我发现我是深深喜欢上这个系统:使用起来就是一个字"爽":当初在看 linux内核原理时,对linux内核源码有种敬畏的心理,不敢涉入,主要是看不懂,直到最近实习的时候,在某次分享会上,某位老师分享了OOM机制, 我很感兴趣,就去看内核代码,发现,原来我能看懂了:所以想写篇博客,分享下从内核代码分析pipe的实现: 这部分内容说简单也很简单,说难

[转] LINUX内核代码编程规范

这是一个简短的文档,描述了linux内核的首选代码风格.代码风格是因人而异的,而且我 不愿意把我的观点强加给任何人,不过这里所讲述的是我必须要维护的代码所遵守的风格, 并且我也希望绝大多数其他代码也能遵守这个风格.请在写代码时至少考虑一下本文所述的 风格. 首先,我建议你打印一份GNU代码规范,然后不要读它.烧了它,这是一个具有重大象征性 意义的动作. 不管怎样,现在我们开始: 第一章:缩进 制表符是8个字符,所以缩进也是8个字符.有些异端运动试图将缩进变为4(乃至2)个字符 深,这几乎相当于尝

debian内核代码执行流程(三)

接续<debian内核代码执行流程(二)>未完成部分 下面这行输出信息是启动udevd进程产生的输出信息: [ 3.306217] udevd[49]: starting version 175 175是udevd的版本号. 根据<essential linux device drivers>中关于udev的说明(英文书140页),设备可以分成热插拔和冷插拔. 热插拔是在已经运行的系统中连接的设备,冷插拔是系统启动前插入的设备. 当系统检测到热插拔设备时,系统使用netlink s

tcp_tw_recycle和tcp_timestamps导致connect失败问题

把服务里面的net.ipv4.tcp_timestamps这个参数设置为0后已经可以正常telnet通了. 具体设置方法: 在/etc/sysctl.conf  里面加入 net.ipv4.tcp_timestamps =0 让后使用sysctl -p 生效就可以了. 原理是主机client1和client2通过NAT网关(1个ip地址)访问serverN,由于timestamp时间为系统启动到当前的时间,因此,client1和client2的timestamp不相同:根据上述syn包处理源码,

请善用工具审核您的内核代码:)

在写内核代码时.代码风格(coding style)是一个非常重要的部分,否则内核代码将变的混乱不堪. 那么什么样的代码算美丽的代码?什么样的代码符合c99这种标准?此外,程序写完之后,有什么工具可以帮我们检查代码有没有指针错误?客官且随我看看这三个工具: 1. 代码风格篇 想开发一个内核程序?你的电脑有内核源代码么?无论是以前用来编译内核或者你自己查阅资料,假设您的电脑上有内核源代码,好的,本节将介绍一个非常多人都不知道的强大的工具 -- checkpatch. So, where is it

[转] Linux内核代码风格 CodingStyle [CH]

from:http://blog.csdn.net/jiang_dlut/article/details/8163731 中文版维护者: 张乐 Zhang Le <[email protected]> 中文版翻译者: 张乐 Zhang Le <[email protected]> 中文版校译者: 王聪 Wang Cong <[email protected]>                wheelz <[email protected]>