History

netfilter: conntrack: udp: only extend timeout to stream mode after 2s

Currently DNS resolvers that send both A and AAAA queries from same source port can trigger stream mode prematurely, which results in non-early-evictable conntrack entry for three minutes, even though DNS requests are done in a few milliseconds. Add a two second grace period where we continue to use the ordinary 30-second default timeout. Its enough for DNS request/response traffic, even if two request/reply packets are involved. ASSURED is still set, else conntrack (and thus a possible NAT mapping ...) gets zapped too in case conntrack table runs full.

Florian Westphal committed 7 years ago

Commit d535c8a1 parent 06aa1512 files · +18 −3Browse files

Unified · Split

2 files
  1. include/net/netfilter/nf_conntrack.h +5 −0
  2. net/netfilter/nf_conntrack_proto_udp.c +13 −3
include/net/netfilter/nf_conntrack.h+5−0
@@ -27,12 +27,17 @@ · 26 unmodified lines
27 27
28#include <net/netfilter/nf_conntrack_tuple.h>28#include <net/netfilter/nf_conntrack_tuple.h>
29 29
30struct nf_ct_udp {
31 unsigned long stream_ts;
32};
33
30/* per conntrack: protocol private data */34/* per conntrack: protocol private data */
31union nf_conntrack_proto {35union nf_conntrack_proto {
32 /* insert conntrack proto private data here */36 /* insert conntrack proto private data here */
33 struct nf_ct_dccp dccp;37 struct nf_ct_dccp dccp;
34 struct ip_ct_sctp sctp;38 struct ip_ct_sctp sctp;
35 struct ip_ct_tcp tcp;39 struct ip_ct_tcp tcp;
40 struct nf_ct_udp udp;
36 struct nf_ct_gre gre;41 struct nf_ct_gre gre;
37 unsigned int tmpl_padto;42 unsigned int tmpl_padto;
38};43};
net/netfilter/nf_conntrack_proto_udp.c+13−3
@@ -100,11 +100,21 @@ static int udp_packet(struct nf_conn *ct, · 99 unmodified lines
100 if (!timeouts)100 if (!timeouts)
101 timeouts = udp_get_timeouts(nf_ct_net(ct));101 timeouts = udp_get_timeouts(nf_ct_net(ct));
102 102
103 if (!nf_ct_is_confirmed(ct))
104 ct->proto.udp.stream_ts = 2 * HZ + jiffies;
105
103 /* If we've seen traffic both ways, this is some kind of UDP106 /* If we've seen traffic both ways, this is some kind of UDP
104 stream. Extend timeout. */107 * stream. Set Assured.
108 */
105 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {109 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
106 nf_ct_refresh_acct(ct, ctinfo, skb,110 unsigned long extra = timeouts[UDP_CT_UNREPLIED];
107 timeouts[UDP_CT_REPLIED]);111
112 /* Still active after two seconds? Extend timeout. */
113 if (time_after(jiffies, ct->proto.udp.stream_ts))
114 extra = timeouts[UDP_CT_REPLIED];
115
116 nf_ct_refresh_acct(ct, ctinfo, skb, extra);
117
108 /* Also, more likely to be important, and not a probe */118 /* Also, more likely to be important, and not a probe */
109 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))119 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
110 nf_conntrack_event_cache(IPCT_ASSURED, ct);120 nf_conntrack_event_cache(IPCT_ASSURED, ct);