提交 ae375044 编写于 作者: P Patrick McHardy 提交者: David S. Miller

netfilter: nf_conntrack_tcp: decrease timeouts while data in unacknowledged

In order to time out dead connections quicker, keep track of outstanding data
and cap the timeout.

Suggested by Herbert Xu.
Signed-off-by: NPatrick McHardy <kaber@trash.net>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 a97a6f10
...@@ -30,6 +30,9 @@ enum tcp_conntrack { ...@@ -30,6 +30,9 @@ enum tcp_conntrack {
/* Be liberal in window checking */ /* Be liberal in window checking */
#define IP_CT_TCP_FLAG_BE_LIBERAL 0x08 #define IP_CT_TCP_FLAG_BE_LIBERAL 0x08
/* Has unacknowledged data */
#define IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED 0x10
struct nf_ct_tcp_flags { struct nf_ct_tcp_flags {
u_int8_t flags; u_int8_t flags;
u_int8_t mask; u_int8_t mask;
......
...@@ -67,7 +67,8 @@ static const char *const tcp_conntrack_names[] = { ...@@ -67,7 +67,8 @@ static const char *const tcp_conntrack_names[] = {
/* RFC1122 says the R2 limit should be at least 100 seconds. /* RFC1122 says the R2 limit should be at least 100 seconds.
Linux uses 15 packets as limit, which corresponds Linux uses 15 packets as limit, which corresponds
to ~13-30min depending on RTO. */ to ~13-30min depending on RTO. */
static unsigned int nf_ct_tcp_timeout_max_retrans __read_mostly = 5 MINS; static unsigned int nf_ct_tcp_timeout_max_retrans __read_mostly = 5 MINS;
static unsigned int nf_ct_tcp_timeout_unacknowledged __read_mostly = 5 MINS;
static unsigned int tcp_timeouts[TCP_CONNTRACK_MAX] __read_mostly = { static unsigned int tcp_timeouts[TCP_CONNTRACK_MAX] __read_mostly = {
[TCP_CONNTRACK_SYN_SENT] = 2 MINS, [TCP_CONNTRACK_SYN_SENT] = 2 MINS,
...@@ -625,8 +626,10 @@ static bool tcp_in_window(const struct nf_conn *ct, ...@@ -625,8 +626,10 @@ static bool tcp_in_window(const struct nf_conn *ct,
swin = win + (sack - ack); swin = win + (sack - ack);
if (sender->td_maxwin < swin) if (sender->td_maxwin < swin)
sender->td_maxwin = swin; sender->td_maxwin = swin;
if (after(end, sender->td_end)) if (after(end, sender->td_end)) {
sender->td_end = end; sender->td_end = end;
sender->flags |= IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
}
/* /*
* Update receiver data. * Update receiver data.
*/ */
...@@ -637,6 +640,8 @@ static bool tcp_in_window(const struct nf_conn *ct, ...@@ -637,6 +640,8 @@ static bool tcp_in_window(const struct nf_conn *ct,
if (win == 0) if (win == 0)
receiver->td_maxend++; receiver->td_maxend++;
} }
if (ack == receiver->td_end)
receiver->flags &= ~IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
/* /*
* Check retransmissions. * Check retransmissions.
...@@ -951,9 +956,16 @@ static int tcp_packet(struct nf_conn *ct, ...@@ -951,9 +956,16 @@ static int tcp_packet(struct nf_conn *ct,
if (old_state != new_state if (old_state != new_state
&& new_state == TCP_CONNTRACK_FIN_WAIT) && new_state == TCP_CONNTRACK_FIN_WAIT)
ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT; ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
timeout = ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans
&& tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans if (ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans &&
? nf_ct_tcp_timeout_max_retrans : tcp_timeouts[new_state]; tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans)
timeout = nf_ct_tcp_timeout_max_retrans;
else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) &
IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED &&
tcp_timeouts[new_state] > nf_ct_tcp_timeout_unacknowledged)
timeout = nf_ct_tcp_timeout_unacknowledged;
else
timeout = tcp_timeouts[new_state];
write_unlock_bh(&tcp_lock); write_unlock_bh(&tcp_lock);
nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
...@@ -1235,6 +1247,13 @@ static struct ctl_table tcp_sysctl_table[] = { ...@@ -1235,6 +1247,13 @@ static struct ctl_table tcp_sysctl_table[] = {
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec_jiffies, .proc_handler = &proc_dointvec_jiffies,
}, },
{
.procname = "nf_conntrack_tcp_timeout_unacknowledged",
.data = &nf_ct_tcp_timeout_unacknowledged,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = &proc_dointvec_jiffies,
},
{ {
.ctl_name = NET_NF_CONNTRACK_TCP_LOOSE, .ctl_name = NET_NF_CONNTRACK_TCP_LOOSE,
.procname = "nf_conntrack_tcp_loose", .procname = "nf_conntrack_tcp_loose",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册