Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature #417: add support for configuration per host timeout value #654

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Makefile.am
Expand Up @@ -54,6 +54,7 @@ decode-tcp.c decode-tcp.h \
decode-teredo.c decode-teredo.h \
decode-udp.c decode-udp.h \
decode-vlan.c decode-vlan.h \
defrag-config.c defrag-config.h \
defrag.c defrag.h \
defrag-hash.c defrag-hash.h \
defrag-queue.c defrag-queue.h \
Expand Down
168 changes: 168 additions & 0 deletions src/defrag-config.c
@@ -0,0 +1,168 @@
/* Copyright (C) 2007-2013 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/

/**
* \file
*
* \author Giuseppe Longo <giuseppelng@gmail.com>
*
* Example config:
* defrag:
* memcap: 32mb
* hash-size: 65536
* trackers: 65535
* max-frags: 65535
* prealloc: yes
*
* default-config:
* timeout: 40
*
* host-config:
*
* - dmz:
* timeout: 30
* address: [192.168.1.0/24, 127.0.0.0/8, 1.1.1.0/24, 2.2.2.0/24, "1.1.1.1", "2.2.2.2", "::1"]
*
* - lan:
* timeout: 45
* address:
* - 192.168.0.0/24
* - 192.168.10.0/24
* - 172.16.14.0/24
*/

#include "suricata-common.h"
#include "queue.h"
#include "suricata.h"
#include "conf.h"
#include "util-debug.h"
#include "util-misc.h"
#include "defrag-config.h"

static SCRadixTree *defrag_tree = NULL;

static int default_timeout = 0;

static void DefragPolicyAddHostInfo(char *host_ip_range, uintmax_t *timeout)
{
uintmax_t *user_data = timeout;

if (strchr(host_ip_range, ':') != NULL) {
SCLogDebug("adding ipv6 host %s", host_ip_range);
if (SCRadixAddKeyIPV6String(host_ip_range, defrag_tree, user_data) == NULL) {
SCLogWarning(SC_ERR_INVALID_VALUE,
"failed to add ipv6 host %s", host_ip_range);
}
} else {
SCLogDebug("adding ipv4 host %s", host_ip_range);
if (SCRadixAddKeyIPV4String(host_ip_range, defrag_tree, user_data) == NULL) {
SCLogWarning(SC_ERR_INVALID_VALUE,
"failed to add ipv4 host %s", host_ip_range);
}
}
}

static int DefragPolicyGetIPv4HostTimeout(uint8_t *ipv4_addr)
{
SCRadixNode *node = SCRadixFindKeyIPV4BestMatch(ipv4_addr, defrag_tree);

if (node == NULL)
return -1;
else
return *((int *)node->prefix->user_data_result);
}

static int DefragPolicyGetIPv6HostTimeout(uint8_t *ipv6_addr)
{
SCRadixNode *node = SCRadixFindKeyIPV6BestMatch(ipv6_addr, defrag_tree);
if (node == NULL)
return -1;
else
return *((int *)node->prefix->user_data_result);
}

int DefragPolicyGetHostTimeout(Packet *p)
{
int timeout = 0;

if (PKT_IS_IPV4(p))
timeout = DefragPolicyGetIPv4HostTimeout((uint8_t *)GET_IPV4_DST_ADDR_PTR(p));
else if (PKT_IS_IPV6(p))
timeout = DefragPolicyGetIPv6HostTimeout((uint8_t *)GET_IPV6_DST_ADDR(p));
else
timeout = default_timeout;

return timeout;
}

static void DefragParseParameters(ConfNode *n)
{
ConfNode *si;
uintmax_t timeout = 0;

TAILQ_FOREACH(si, &n->head, next) {
if (strcasecmp("timeout", si->name) == 0) {
SCLogDebug("timeout value %s", si->val);
if (ParseSizeStringU64(si->val, &timeout) < 0) {
SCLogError(SC_ERR_SIZE_PARSE, "Error parsing timeout "
"from conf file");
}
}
if (strcasecmp("address", si->name) == 0) {
ConfNode *pval;
TAILQ_FOREACH(pval, &si->head, next) {
DefragPolicyAddHostInfo(pval->val, &timeout);
}
}
}
}

void DefragSetDefaultTimeout(intmax_t timeout)
{
default_timeout = timeout;
SCLogDebug("default timeout %d", default_timeout);
}

void DefragPolicyLoadFromConfig(void)
{
SCEnter();

defrag_tree = SCRadixCreateRadixTree(NULL, NULL);
if (defrag_tree == NULL) {
SCLogError(SC_ERR_MEM_ALLOC,
"Can't alloc memory for the defrag config tree.");
exit(EXIT_FAILURE);
}

ConfNode *server_config = ConfGetNode("defrag.host-config");
if (server_config == NULL) {
SCLogDebug("failed to read host config");
SCReturn;
}

SCLogDebug("configuring host config %p", server_config);
ConfNode *sc;

TAILQ_FOREACH(sc, &server_config->head, next) {
ConfNode *p = NULL;

TAILQ_FOREACH(p, &sc->head, next) {
SCLogDebug("parsing configuration for %s", p->name);
DefragParseParameters(p);
}
}
}
32 changes: 32 additions & 0 deletions src/defrag-config.h
@@ -0,0 +1,32 @@
/* Copyright (C) 2007-2013 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/

/**
* \file
*
* \author Giuseppe Longo <giuseppelng@gmail.com>
*
*/

#ifndef DEFRAG_CONFIG_H_
#define DEFRAG_CONFIG_H_

void DefragSetDefaultTimeout(intmax_t timeout);
void DefragPolicyLoadFromConfig(void);
int DefragPolicyGetHostTimeout(Packet *p);

#endif /* DEFRAG_CONFIG_H_ */
3 changes: 3 additions & 0 deletions src/defrag-hash.c
Expand Up @@ -19,6 +19,7 @@
#include "conf.h"
#include "defrag-hash.h"
#include "defrag-queue.h"
#include "defrag-config.h"
#include "util-random.h"
#include "util-byte.h"
#include "util-misc.h"
Expand Down Expand Up @@ -87,6 +88,8 @@ static void DefragTrackerInit(DefragTracker *dt, Packet *p) {
dt->af = AF_INET6;
}
dt->policy = DefragGetOsPolicy(p);
dt->host_timeout = DefragPolicyGetHostTimeout(p);

TAILQ_INIT(&dt->frags);
(void) DefragTrackerIncrUsecnt(dt);
}
Expand Down
7 changes: 6 additions & 1 deletion src/defrag.c
Expand Up @@ -53,6 +53,7 @@
#include "defrag.h"
#include "defrag-hash.h"
#include "defrag-queue.h"
#include "defrag-config.h"

#ifdef UNITTESTS
#include "util-unittest.h"
Expand Down Expand Up @@ -541,7 +542,7 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragTracker *tracker,
}

/* Update timeout. */
tracker->timeout = p->ts.tv_sec + defrag_context->timeout;
tracker->timeout = p->ts.tv_sec + tracker->host_timeout;

Frag *prev = NULL, *next;
int overlap = 0;
Expand Down Expand Up @@ -879,6 +880,9 @@ DefragInit(void)
tracker_pool_size = DEFAULT_DEFRAG_HASH_SIZE;
}

/* Load the defrag-per-host lookup. */
DefragPolicyLoadFromConfig();

/* Allocate the DefragContext. */
defrag_context = DefragContextNew();
if (defrag_context == NULL) {
Expand All @@ -887,6 +891,7 @@ DefragInit(void)
exit(EXIT_FAILURE);
}

DefragSetDefaultTimeout(defrag_context->timeout);
DefragInitConfig(FALSE);
}

Expand Down
1 change: 1 addition & 0 deletions src/defrag.h
Expand Up @@ -109,6 +109,7 @@ typedef struct DefragTracker_ {
Address dst_addr; /**< Destination address for this tracker. */

uint32_t timeout; /**< When this tracker will timeout. */
uint32_t host_timeout; /**< Host timeout, statically assigned from the yaml */

/** use cnt, reference counter */
SC_ATOMIC_DECLARE(unsigned int, use_cnt);
Expand Down