注意:本文档中的内核代码的版本: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的内核代码
原文:http://blog.csdn.net/yygydjkthh/article/details/46886927