歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> tcp_tw_recycle檢查tcp_timestamps的內核代碼

tcp_tw_recycle檢查tcp_timestamps的內核代碼

日期:2017/2/28 14:00:13   编辑:Linux教程

注意:本文檔中的內核代碼的版本: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;

Copyright © Linux教程網 All Rights Reserved