From 3feed855a6b7c9b7d5d27231b4dd3c997eebb1ac Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 19 Mar 2018 17:10:12 +0100 Subject: conntrackd: add TCP flags support Back in 2008, there was no TCP flags support in the kernel, hence the workaround was to infer the flags from the TCP state. This patch is implicitly fixing a problem, since the existing RETRANS and UNACK TCP conntrack states plus the _CLOSE_INIT flag that is bogusly infered (to be frank, it was correctly infered back in 2008, but after adding new TCP states, it was not). Let's just use the flags that we get via synchronization messages. Signed-off-by: Pablo Neira Ayuso --- src/netlink.c | 56 +++++++++++++++++++------------------------------------- 1 file changed, 19 insertions(+), 37 deletions(-) (limited to 'src/netlink.c') diff --git a/src/netlink.c b/src/netlink.c index 189f55a..ddf4cf4 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -216,12 +216,26 @@ int nl_get_conntrack(struct nfct_handle *h, const struct nf_conntrack *ct) return ret; } +static void ctd_force_tcp_be_liberal(struct nf_conntrack *ct) +{ + int attrs[4] = { ATTR_TCP_FLAGS_ORIG, ATTR_TCP_MASK_ORIG, + ATTR_TCP_FLAGS_REPL, ATTR_TCP_MASK_REPL }; + unsigned int i; + uint8_t flags; + + for (i = 0; i < ARRAY_SIZE(attrs); i++) { + flags = nfct_get_attr_u8(ct, attrs[i]); + nfct_set_attr_u8(ct, attrs[i], + flags | IP_CT_TCP_FLAG_BE_LIBERAL); + } +} + int nl_create_conntrack(struct nfct_handle *h, const struct nf_conntrack *orig, int timeout) { - int ret; struct nf_conntrack *ct; + int ret; ct = nfct_clone(orig); if (ct == NULL) @@ -240,24 +254,8 @@ int nl_create_conntrack(struct nfct_handle *h, nfct_setobjopt(ct, NFCT_SOPT_SETUP_REPLY); /* disable TCP window tracking for recovered connections if required */ - if (nfct_attr_is_set(ct, ATTR_TCP_STATE)) { - uint8_t flags = IP_CT_TCP_FLAG_SACK_PERM; - - if (!CONFIG(sync).tcp_window_tracking) - flags |= IP_CT_TCP_FLAG_BE_LIBERAL; - else - flags |= IP_CT_TCP_FLAG_WINDOW_SCALE; - - /* FIXME: workaround, we should send TCP flags in updates */ - if (nfct_get_attr_u8(ct, ATTR_TCP_STATE) >= - TCP_CONNTRACK_TIME_WAIT) { - flags |= IP_CT_TCP_FLAG_CLOSE_INIT; - } - nfct_set_attr_u8(ct, ATTR_TCP_FLAGS_ORIG, flags); - nfct_set_attr_u8(ct, ATTR_TCP_MASK_ORIG, flags); - nfct_set_attr_u8(ct, ATTR_TCP_FLAGS_REPL, flags); - nfct_set_attr_u8(ct, ATTR_TCP_MASK_REPL, flags); - } + if (!CONFIG(sync).tcp_window_tracking) + ctd_force_tcp_be_liberal(ct); ret = nfct_query(h, NFCT_Q_CREATE, ct); nfct_destroy(ct); @@ -307,24 +305,8 @@ int nl_update_conntrack(struct nfct_handle *h, } /* disable TCP window tracking for recovered connections if required */ - if (nfct_attr_is_set(ct, ATTR_TCP_STATE)) { - uint8_t flags = IP_CT_TCP_FLAG_SACK_PERM; - - if (!CONFIG(sync).tcp_window_tracking) - flags |= IP_CT_TCP_FLAG_BE_LIBERAL; - else - flags |= IP_CT_TCP_FLAG_WINDOW_SCALE; - - /* FIXME: workaround, we should send TCP flags in updates */ - if (nfct_get_attr_u8(ct, ATTR_TCP_STATE) >= - TCP_CONNTRACK_TIME_WAIT) { - flags |= IP_CT_TCP_FLAG_CLOSE_INIT; - } - nfct_set_attr_u8(ct, ATTR_TCP_FLAGS_ORIG, flags); - nfct_set_attr_u8(ct, ATTR_TCP_MASK_ORIG, flags); - nfct_set_attr_u8(ct, ATTR_TCP_FLAGS_REPL, flags); - nfct_set_attr_u8(ct, ATTR_TCP_MASK_REPL, flags); - } + if (!CONFIG(sync).tcp_window_tracking) + ctd_force_tcp_be_liberal(ct); ret = nfct_query(h, NFCT_Q_UPDATE, ct); nfct_destroy(ct); -- cgit v1.2.3