From c75b29c74f7566c5ee249eab816c6255f9f81212 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Wed, 18 May 2022 21:35:00 +0200 Subject: [PATCH] reputation: switch cidr handling to radix4/6 Splits the unified tree into a ipv4 specific and ipv6 specific tree. --- src/reputation.c | 59 +++++++++++++++++++----------------------------- src/reputation.h | 9 ++++---- 2 files changed, 28 insertions(+), 40 deletions(-) diff --git a/src/reputation.c b/src/reputation.c index 88ee1b7ce5..417b60a524 100644 --- a/src/reputation.c +++ b/src/reputation.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2019 Open Information Security Foundation +/* Copyright (C) 2007-2022 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 @@ -39,6 +39,8 @@ #include "util-print.h" #include "util-unittest.h" #include "util-validate.h" +#include "util-radix4-tree.h" +#include "util-radix6-tree.h" /** effective reputation version, atomic as the host * time out code will use it to check if a host's @@ -75,6 +77,9 @@ static void SRepCIDRFreeUserData(void *data) SCFree(data); } +static SCRadix4Config iprep_radix4_config = { SRepCIDRFreeUserData, NULL }; +static SCRadix6Config iprep_radix6_config = { SRepCIDRFreeUserData, NULL }; + static void SRepCIDRAddNetblock(SRepCIDRTree *cidr_ctx, char *ip, int cat, uint8_t value) { SReputation *user_data = NULL; @@ -86,34 +91,18 @@ static void SRepCIDRAddNetblock(SRepCIDRTree *cidr_ctx, char *ip, int cat, uint8 user_data->rep[cat] = value; if (strchr(ip, ':') != NULL) { - if (cidr_ctx->srepIPV6_tree[cat] == NULL) { - cidr_ctx->srepIPV6_tree[cat] = SCRadixCreateRadixTree(SRepCIDRFreeUserData, NULL); - if (cidr_ctx->srepIPV6_tree[cat] == NULL) { - SCLogDebug("Error initializing Reputation IPV6 with CIDR module for cat %d", cat); - exit(EXIT_FAILURE); - } - SCLogDebug("Reputation IPV6 with CIDR module for cat %d initialized", cat); - } - SCLogDebug("adding ipv6 host %s", ip); - if (!SCRadixAddKeyIPV6String(ip, cidr_ctx->srepIPV6_tree[cat], (void *)user_data)) { + if (!SCRadix6AddKeyIPV6String( + &cidr_ctx->srep_ipv6_tree[cat], &iprep_radix6_config, ip, (void *)user_data)) { SCFree(user_data); if (sc_errno != SC_EEXIST) SCLogWarning("failed to add ipv6 host %s", ip); } } else { - if (cidr_ctx->srepIPV4_tree[cat] == NULL) { - cidr_ctx->srepIPV4_tree[cat] = SCRadixCreateRadixTree(SRepCIDRFreeUserData, NULL); - if (cidr_ctx->srepIPV4_tree[cat] == NULL) { - SCLogDebug("Error initializing Reputation IPV4 with CIDR module for cat %d", cat); - exit(EXIT_FAILURE); - } - SCLogDebug("Reputation IPV4 with CIDR module for cat %d initialized", cat); - } - SCLogDebug("adding ipv4 host %s", ip); - if (!SCRadixAddKeyIPV4String(ip, cidr_ctx->srepIPV4_tree[cat], (void *)user_data)) { + if (!SCRadix4AddKeyIPV4String( + &cidr_ctx->srep_ipv4_tree[cat], &iprep_radix4_config, ip, (void *)user_data)) { SCFree(user_data); if (sc_errno != SC_EEXIST) SCLogWarning("failed to add ipv4 host %s", ip); @@ -124,7 +113,7 @@ static void SRepCIDRAddNetblock(SRepCIDRTree *cidr_ctx, char *ip, int cat, uint8 static int8_t SRepCIDRGetIPv4IPRep(SRepCIDRTree *cidr_ctx, uint8_t *ipv4_addr, uint8_t cat) { void *user_data = NULL; - (void)SCRadixFindKeyIPV4BestMatch(ipv4_addr, cidr_ctx->srepIPV4_tree[cat], &user_data); + (void)SCRadix4TreeFindBestMatch(&cidr_ctx->srep_ipv4_tree[cat], ipv4_addr, &user_data); if (user_data == NULL) return -1; @@ -135,7 +124,7 @@ static int8_t SRepCIDRGetIPv4IPRep(SRepCIDRTree *cidr_ctx, uint8_t *ipv4_addr, u static int8_t SRepCIDRGetIPv6IPRep(SRepCIDRTree *cidr_ctx, uint8_t *ipv6_addr, uint8_t cat) { void *user_data = NULL; - (void)SCRadixFindKeyIPV6BestMatch(ipv6_addr, cidr_ctx->srepIPV6_tree[cat], &user_data); + (void)SCRadix6TreeFindBestMatch(&cidr_ctx->srep_ipv6_tree[cat], ipv6_addr, &user_data); if (user_data == NULL) return -1; @@ -584,6 +573,12 @@ int SRepInit(DetectEngineCtx *de_ctx) de_ctx->srepCIDR_ctx = (SRepCIDRTree *)SCCalloc(1, sizeof(SRepCIDRTree)); if (de_ctx->srepCIDR_ctx == NULL) exit(EXIT_FAILURE); + + for (int i = 0; i < SREP_MAX_CATS; i++) { + de_ctx->srepCIDR_ctx->srep_ipv4_tree[i] = SCRadix4TreeInitialize(); + de_ctx->srepCIDR_ctx->srep_ipv6_tree[i] = SCRadix6TreeInitialize(); + } + SRepCIDRTree *cidr_ctx = de_ctx->srepCIDR_ctx; if (SRepGetVersion() == 0) { @@ -651,21 +646,13 @@ int SRepInit(DetectEngineCtx *de_ctx) return 0; } -void SRepDestroy(DetectEngineCtx *de_ctx) { +void SRepDestroy(DetectEngineCtx *de_ctx) +{ if (de_ctx->srepCIDR_ctx != NULL) { - int i; - for (i = 0; i < SREP_MAX_CATS; i++) { - if (de_ctx->srepCIDR_ctx->srepIPV4_tree[i] != NULL) { - SCRadixReleaseRadixTree(de_ctx->srepCIDR_ctx->srepIPV4_tree[i]); - de_ctx->srepCIDR_ctx->srepIPV4_tree[i] = NULL; - } - - if (de_ctx->srepCIDR_ctx->srepIPV6_tree[i] != NULL) { - SCRadixReleaseRadixTree(de_ctx->srepCIDR_ctx->srepIPV6_tree[i]); - de_ctx->srepCIDR_ctx->srepIPV6_tree[i] = NULL; - } + for (int i = 0; i < SREP_MAX_CATS; i++) { + SCRadix4TreeRelease(&de_ctx->srepCIDR_ctx->srep_ipv4_tree[i], &iprep_radix4_config); + SCRadix6TreeRelease(&de_ctx->srepCIDR_ctx->srep_ipv6_tree[i], &iprep_radix6_config); } - SCFree(de_ctx->srepCIDR_ctx); de_ctx->srepCIDR_ctx = NULL; } diff --git a/src/reputation.h b/src/reputation.h index d7009776ce..91285c340e 100644 --- a/src/reputation.h +++ b/src/reputation.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2019 Open Information Security Foundation +/* Copyright (C) 2007-2022 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 @@ -27,14 +27,15 @@ #define SURICATA_REPUTATION_H #include "host.h" -#include "util-radix-tree.h" +#include "util-radix4-tree.h" +#include "util-radix6-tree.h" #define SREP_MAX_CATS 60 #define SREP_MAX_VAL 127 typedef struct SRepCIDRTree_ { - SCRadixTree *srepIPV4_tree[SREP_MAX_CATS]; - SCRadixTree *srepIPV6_tree[SREP_MAX_CATS]; + SCRadix4Tree srep_ipv4_tree[SREP_MAX_CATS]; + SCRadix6Tree srep_ipv6_tree[SREP_MAX_CATS]; } SRepCIDRTree; typedef struct SReputation_ {