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: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a97a6f1077
commit
ae375044d3
|
@ -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;
|
||||||
|
|
|
@ -68,6 +68,7 @@ static const char *const tcp_conntrack_names[] = {
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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[] = {
|
||||||
.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",
|
||||||
|
|
Loading…
Reference in New Issue