"Allow unauthenticated requests from these addresses", | "Allow unauthenticated requests from these addresses", | ||||
&ctx->secure_map, | &ctx->secure_map, | ||||
NULL, | NULL, | ||||
worker); | |||||
worker, "controller secure ip"); | |||||
} | } | ||||
ctx->lang_det = ctx->cfg->lang_det; | ctx->lang_det = ctx->cfg->lang_det; |
if (ctx->update_map != NULL) { | if (ctx->update_map != NULL) { | ||||
rspamd_config_radix_from_ucl (worker->srv->cfg, ctx->update_map, | rspamd_config_radix_from_ucl (worker->srv->cfg, ctx->update_map, | ||||
"Allow fuzzy updates from specified addresses", | "Allow fuzzy updates from specified addresses", | ||||
&ctx->update_ips, NULL, worker); | |||||
&ctx->update_ips, NULL, worker, "fuzzy update"); | |||||
} | } | ||||
if (ctx->skip_map != NULL) { | if (ctx->skip_map != NULL) { | ||||
"Block fuzzy requests from the specific IPs", | "Block fuzzy requests from the specific IPs", | ||||
&ctx->blocked_ips, | &ctx->blocked_ips, | ||||
NULL, | NULL, | ||||
worker); | |||||
worker, "fuzzy blocked"); | |||||
} | } | ||||
/* Create radix trees */ | /* Create radix trees */ | ||||
"Skip ratelimits from specific ip addresses/networks", | "Skip ratelimits from specific ip addresses/networks", | ||||
&ctx->ratelimit_whitelist, | &ctx->ratelimit_whitelist, | ||||
NULL, | NULL, | ||||
worker); | |||||
worker, "fuzzy ratelimit whitelist"); | |||||
} | } | ||||
if (!isnan (ctx->delay) && ctx->delay_whitelist_map != NULL) { | if (!isnan (ctx->delay) && ctx->delay_whitelist_map != NULL) { | ||||
rspamd_config_radix_from_ucl (worker->srv->cfg, ctx->delay_whitelist_map, | rspamd_config_radix_from_ucl (worker->srv->cfg, ctx->delay_whitelist_map, | ||||
"Skip delay from the following ips", | "Skip delay from the following ips", | ||||
&ctx->delay_whitelist, NULL, worker); | |||||
&ctx->delay_whitelist, NULL, worker, | |||||
"fuzzy delayed whitelist"); | |||||
} | } | ||||
/* Ratelimits */ | /* Ratelimits */ |
*/ | */ | ||||
struct rspamd_radix_map_helper; | struct rspamd_radix_map_helper; | ||||
gboolean rspamd_config_radix_from_ucl (struct rspamd_config *cfg, | |||||
const ucl_object_t *obj, | |||||
const gchar *description, | |||||
struct rspamd_radix_map_helper **target, | |||||
GError **err, | |||||
struct rspamd_worker *worker); | |||||
gboolean rspamd_config_radix_from_ucl (struct rspamd_config *cfg, const ucl_object_t *obj, const gchar *description, | |||||
struct rspamd_radix_map_helper **target, GError **err, | |||||
struct rspamd_worker *worker, const gchar *map_name); | |||||
/** | /** | ||||
* Adds new settings id to be preprocessed | * Adds new settings id to be preprocessed |
} | } | ||||
gboolean | gboolean | ||||
rspamd_config_radix_from_ucl (struct rspamd_config *cfg, | |||||
const ucl_object_t *obj, | |||||
const gchar *description, | |||||
struct rspamd_radix_map_helper **target, | |||||
GError **err, | |||||
struct rspamd_worker *worker) | |||||
rspamd_config_radix_from_ucl (struct rspamd_config *cfg, const ucl_object_t *obj, const gchar *description, | |||||
struct rspamd_radix_map_helper **target, GError **err, | |||||
struct rspamd_worker *worker, const gchar *map_name) | |||||
{ | { | ||||
ucl_type_t type; | ucl_type_t type; | ||||
ucl_object_iter_t it = NULL; | ucl_object_iter_t it = NULL; | ||||
else { | else { | ||||
/* Just a list */ | /* Just a list */ | ||||
if (!*target) { | if (!*target) { | ||||
*target = rspamd_map_helper_new_radix (NULL); | |||||
*target = rspamd_map_helper_new_radix ( | |||||
rspamd_map_add_fake (cfg, description, map_name)); | |||||
} | } | ||||
rspamd_map_helper_insert_radix_resolve (*target, str, ""); | rspamd_map_helper_insert_radix_resolve (*target, str, ""); | ||||
str = ucl_object_tostring (cur); | str = ucl_object_tostring (cur); | ||||
if (!*target) { | if (!*target) { | ||||
*target = rspamd_map_helper_new_radix (NULL); | |||||
*target = rspamd_map_helper_new_radix ( | |||||
rspamd_map_add_fake (cfg, description, map_name)); | |||||
} | } | ||||
rspamd_map_helper_insert_radix_resolve (*target, str, ""); | rspamd_map_helper_insert_radix_resolve (*target, str, ""); | ||||
if (cfg->local_addrs) { | if (cfg->local_addrs) { | ||||
rspamd_config_radix_from_ucl (cfg, cfg->local_addrs, | rspamd_config_radix_from_ucl (cfg, cfg->local_addrs, | ||||
"Local addresses", | "Local addresses", | ||||
(struct rspamd_radix_map_helper **)ctx->local_addrs, | |||||
(struct rspamd_radix_map_helper **) ctx->local_addrs, | |||||
NULL, | NULL, | ||||
NULL); | |||||
NULL, "local addresses"); | |||||
} | } | ||||
rspamd_free_zstd_dictionary (ctx->in_dict); | rspamd_free_zstd_dictionary (ctx->in_dict); |
"IP addresses for which debug logs are enabled", | "IP addresses for which debug logs are enabled", | ||||
&logger->debug_ip, | &logger->debug_ip, | ||||
NULL, | NULL, | ||||
NULL); | |||||
NULL, "debug ip"); | |||||
} | } | ||||
if (cfg->log_encryption_key) { | if (cfg->log_encryption_key) { |
return map; | return map; | ||||
} | } | ||||
struct rspamd_map * | |||||
rspamd_map_add_fake (struct rspamd_config *cfg, | |||||
const gchar *description, | |||||
const gchar *name) | |||||
{ | |||||
struct rspamd_map *map; | |||||
map = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (struct rspamd_map)); | |||||
map->cfg = cfg; | |||||
map->id = rspamd_random_uint64_fast (); | |||||
map->name = rspamd_mempool_strdup (cfg->cfg_pool, name); | |||||
map->user_data = (void **)↦ /* to prevent null pointer dereferencing */ | |||||
if (description != NULL) { | |||||
map->description = rspamd_mempool_strdup (cfg->cfg_pool, description); | |||||
} | |||||
return map; | |||||
} | |||||
static inline void | static inline void | ||||
rspamd_map_add_backend (struct rspamd_map *map, struct rspamd_map_backend *bk) | rspamd_map_add_backend (struct rspamd_map *map, struct rspamd_map_backend *bk) | ||||
{ | { |
struct rspamd_worker *worker, | struct rspamd_worker *worker, | ||||
int flags); | int flags); | ||||
/** | |||||
* Adds a fake map structure (for logging purposes mainly) | |||||
* @param cfg | |||||
* @param description | |||||
* @return | |||||
*/ | |||||
struct rspamd_map *rspamd_map_add_fake (struct rspamd_config *cfg, | |||||
const gchar *description, | |||||
const gchar *name); | |||||
enum rspamd_map_watch_type { | enum rspamd_map_watch_type { | ||||
RSPAMD_MAP_WATCH_MIN = 9, | RSPAMD_MAP_WATCH_MIN = 9, | ||||
RSPAMD_MAP_WATCH_PRIMARY_CONTROLLER, | RSPAMD_MAP_WATCH_PRIMARY_CONTROLLER, |
rspamd_mempool_t *pool; | rspamd_mempool_t *pool; | ||||
khash_t(rspamd_map_hash) *htb; | khash_t(rspamd_map_hash) *htb; | ||||
radix_compressed_t *trie; | radix_compressed_t *trie; | ||||
struct rspamd_map *map; | |||||
rspamd_cryptobox_fast_hash_state_t hst; | rspamd_cryptobox_fast_hash_state_t hst; | ||||
}; | }; | ||||
struct rspamd_hash_map_helper { | struct rspamd_hash_map_helper { | ||||
rspamd_mempool_t *pool; | rspamd_mempool_t *pool; | ||||
khash_t(rspamd_map_hash) *htb; | khash_t(rspamd_map_hash) *htb; | ||||
struct rspamd_map *map; | |||||
rspamd_cryptobox_fast_hash_state_t hst; | rspamd_cryptobox_fast_hash_state_t hst; | ||||
}; | }; | ||||
struct rspamd_cdb_map_helper { | struct rspamd_cdb_map_helper { | ||||
GQueue cdbs; | GQueue cdbs; | ||||
struct rspamd_map *map; | |||||
rspamd_cryptobox_fast_hash_state_t hst; | rspamd_cryptobox_fast_hash_state_t hst; | ||||
gsize total_size; | gsize total_size; | ||||
}; | }; | ||||
gconstpointer nk; | gconstpointer nk; | ||||
rspamd_ftok_t tok; | rspamd_ftok_t tok; | ||||
gint res; | gint res; | ||||
struct rspamd_map *map; | |||||
map = r->map; | |||||
vlen = strlen (value); | vlen = strlen (value); | ||||
val = rspamd_mempool_alloc0 (r->pool, sizeof (*val) + | val = rspamd_mempool_alloc0 (r->pool, sizeof (*val) + | ||||
vlen + 1); | vlen + 1); | ||||
tok.begin = nk; | tok.begin = nk; | ||||
k = kh_put (rspamd_map_hash, r->htb, tok, &res); | k = kh_put (rspamd_map_hash, r->htb, tok, &res); | ||||
} | } | ||||
else { | |||||
msg_warn_map ("duplicate radix entry found for map %s: %s (old value: %s, new: %s)", | |||||
map->name, key, kh_value (r->htb, k), val); | |||||
} | |||||
nk = kh_key (r->htb, k).begin; | nk = kh_key (r->htb, k).begin; | ||||
val->key = nk; | val->key = nk; | ||||
kh_value (r->htb, k) = val; | kh_value (r->htb, k) = val; | ||||
rspamd_radix_add_iplist (key, ",", r->trie, val, FALSE); | |||||
rspamd_radix_add_iplist (key, ",", r->trie, val, FALSE, | |||||
r->map->name); | |||||
rspamd_cryptobox_fast_hash_update (&r->hst, nk, tok.len); | rspamd_cryptobox_fast_hash_update (&r->hst, nk, tok.len); | ||||
} | } | ||||
gconstpointer nk; | gconstpointer nk; | ||||
rspamd_ftok_t tok; | rspamd_ftok_t tok; | ||||
gint res; | gint res; | ||||
struct rspamd_map *map; | |||||
map = r->map; | |||||
vlen = strlen (value); | vlen = strlen (value); | ||||
val = rspamd_mempool_alloc0 (r->pool, sizeof (*val) + | val = rspamd_mempool_alloc0 (r->pool, sizeof (*val) + | ||||
vlen + 1); | vlen + 1); | ||||
tok.begin = nk; | tok.begin = nk; | ||||
k = kh_put (rspamd_map_hash, r->htb, tok, &res); | k = kh_put (rspamd_map_hash, r->htb, tok, &res); | ||||
} | } | ||||
else { | |||||
msg_warn_map ("duplicate radix entry found for map %s: %s (old value: %s, new: %s)", | |||||
map->name, key, kh_value (r->htb, k), val); | |||||
} | |||||
nk = kh_key (r->htb, k).begin; | nk = kh_key (r->htb, k).begin; | ||||
val->key = nk; | val->key = nk; | ||||
kh_value (r->htb, k) = val; | kh_value (r->htb, k) = val; | ||||
rspamd_radix_add_iplist (key, ",", r->trie, val, TRUE); | |||||
rspamd_radix_add_iplist (key, ",", r->trie, val, TRUE, | |||||
r->map->name); | |||||
rspamd_cryptobox_fast_hash_update (&r->hst, nk, tok.len); | rspamd_cryptobox_fast_hash_update (&r->hst, nk, tok.len); | ||||
} | } | ||||
gsize vlen; | gsize vlen; | ||||
gint r; | gint r; | ||||
rspamd_ftok_t tok; | rspamd_ftok_t tok; | ||||
struct rspamd_map *map; | |||||
tok.begin = key; | tok.begin = key; | ||||
tok.len = strlen (key); | tok.len = strlen (key); | ||||
map = ht->map; | |||||
k = kh_get (rspamd_map_hash, ht->htb, tok); | k = kh_get (rspamd_map_hash, ht->htb, tok); | ||||
vlen = strlen (value); | vlen = strlen (value); | ||||
/* Same element, skip */ | /* Same element, skip */ | ||||
return; | return; | ||||
} | } | ||||
else { | |||||
msg_warn_map ("duplicate hash entry found for map %s: %s (old value: %s, new: %s)", | |||||
map->name, key, kh_value (ht->htb, k), val); | |||||
} | |||||
} | } | ||||
/* Null termination due to alloc0 */ | /* Null termination due to alloc0 */ | ||||
vlen = strlen (value); | vlen = strlen (value); | ||||
val = rspamd_mempool_alloc0 (re_map->pool, sizeof (*val) + | val = rspamd_mempool_alloc0 (re_map->pool, sizeof (*val) + | ||||
vlen + 1); | vlen + 1); | ||||
memcpy (val->value, value, vlen); | |||||
memcpy (val->value, value, vlen); /* Null terminated due to alloc0 previously */ | |||||
tok.begin = key; | tok.begin = key; | ||||
tok.len = strlen (key); | tok.len = strlen (key); | ||||
tok.begin = nk; | tok.begin = nk; | ||||
k = kh_put (rspamd_map_hash, re_map->htb, tok, &r); | k = kh_put (rspamd_map_hash, re_map->htb, tok, &r); | ||||
} | } | ||||
else { | |||||
msg_warn_map ("duplicate re found for map %s: %s (old value: %s, new: %s)", | |||||
map->name, key, kh_value (re_map->htb, k)->value, val); | |||||
} | |||||
nk = kh_key (re_map->htb, k).begin; | nk = kh_key (re_map->htb, k).begin; | ||||
val->key = nk; | val->key = nk; | ||||
htb = rspamd_mempool_alloc0 (pool, sizeof (*htb)); | htb = rspamd_mempool_alloc0 (pool, sizeof (*htb)); | ||||
htb->htb = kh_init (rspamd_map_hash); | htb->htb = kh_init (rspamd_map_hash); | ||||
htb->pool = pool; | htb->pool = pool; | ||||
htb->map = map; | |||||
rspamd_cryptobox_fast_hash_init (&htb->hst, map_hash_seed); | rspamd_cryptobox_fast_hash_init (&htb->hst, map_hash_seed); | ||||
return htb; | return htb; | ||||
{ | { | ||||
struct rspamd_radix_map_helper *r; | struct rspamd_radix_map_helper *r; | ||||
rspamd_mempool_t *pool; | rspamd_mempool_t *pool; | ||||
const gchar *name = "unnamed"; | |||||
if (map) { | if (map) { | ||||
pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), | pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), | ||||
map->tag, 0); | map->tag, 0); | ||||
name = map->name; | |||||
} | } | ||||
else { | else { | ||||
pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), | pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), | ||||
} | } | ||||
r = rspamd_mempool_alloc0 (pool, sizeof (*r)); | r = rspamd_mempool_alloc0 (pool, sizeof (*r)); | ||||
r->trie = radix_create_compressed_with_pool (pool); | |||||
r->trie = radix_create_compressed_with_pool (pool, name); | |||||
r->htb = kh_init (rspamd_map_hash); | r->htb = kh_init (rspamd_map_hash); | ||||
r->pool = pool; | r->pool = pool; | ||||
r->map = map; | |||||
rspamd_cryptobox_fast_hash_init (&r->hst, map_hash_seed); | rspamd_cryptobox_fast_hash_init (&r->hst, map_hash_seed); | ||||
return r; | return r; | ||||
n = g_malloc0 (sizeof (*n)); | n = g_malloc0 (sizeof (*n)); | ||||
n->cdbs = (GQueue)G_QUEUE_INIT; | n->cdbs = (GQueue)G_QUEUE_INIT; | ||||
n->map = map; | |||||
rspamd_cryptobox_fast_hash_init (&n->hst, map_hash_seed); | rspamd_cryptobox_fast_hash_init (&n->hst, map_hash_seed); | ||||
if (elt) { | if (elt) { | ||||
if (ucl_object_type (elt) == UCL_STRING) { | if (ucl_object_type (elt) == UCL_STRING) { | ||||
radix_add_generic_iplist (ucl_object_tostring (elt), | radix_add_generic_iplist (ucl_object_tostring (elt), | ||||
&conf->expected, FALSE); | |||||
&conf->expected, FALSE, NULL); | |||||
} | } | ||||
else if (ucl_object_type (elt) == UCL_ARRAY) { | else if (ucl_object_type (elt) == UCL_ARRAY) { | ||||
const ucl_object_t *cur; | const ucl_object_t *cur; | ||||
while ((cur = ucl_object_iterate (elt, &it, true)) != NULL) { | while ((cur = ucl_object_iterate (elt, &it, true)) != NULL) { | ||||
radix_add_generic_iplist (ucl_object_tostring (elt), | radix_add_generic_iplist (ucl_object_tostring (elt), | ||||
&conf->expected, FALSE); | |||||
&conf->expected, FALSE, NULL); | |||||
} | } | ||||
} | } | ||||
} | } |
struct radix_tree_compressed { | struct radix_tree_compressed { | ||||
rspamd_mempool_t *pool; | rspamd_mempool_t *pool; | ||||
struct btrie *tree; | struct btrie *tree; | ||||
const gchar *name; | |||||
size_t size; | size_t size; | ||||
guint duplicates; | guint duplicates; | ||||
gboolean own_pool; | gboolean own_pool; | ||||
g_assert (tree != NULL); | g_assert (tree != NULL); | ||||
g_assert (keybits >= masklen); | g_assert (keybits >= masklen); | ||||
msg_debug_radix ("want insert value %p with mask %z, key: %*xs", | |||||
(gpointer)value, keybits - masklen, (int)keylen, key); | |||||
msg_debug_radix ("%s: want insert value %p with mask %z, key: %*xs", | |||||
tree->name, (gpointer)value, keybits - masklen, (int)keylen, key); | |||||
old = radix_find_compressed (tree, key, keylen); | old = radix_find_compressed (tree, key, keylen); | ||||
tree->duplicates++; | tree->duplicates++; | ||||
if (tree->duplicates == max_duplicates) { | if (tree->duplicates == max_duplicates) { | ||||
msg_err_radix ("maximum duplicates limit reached: %d, " | |||||
"suppress further errors", max_duplicates); | |||||
msg_err_radix ("%s: maximum duplicates limit reached: %d, " | |||||
"suppress further errors", tree->name, max_duplicates); | |||||
} | } | ||||
else if (tree->duplicates < max_duplicates) { | else if (tree->duplicates < max_duplicates) { | ||||
memset (ip_str, 0, sizeof (ip_str)); | memset (ip_str, 0, sizeof (ip_str)); | ||||
if (keybits == 32) { | if (keybits == 32) { | ||||
msg_err_radix ("cannot insert %p, key: %s/%d, duplicate value", | |||||
msg_err_radix ("%s: cannot insert %p, key: %s/%d, duplicate value", | |||||
tree->name, | |||||
(gpointer) value, | (gpointer) value, | ||||
inet_ntop (AF_INET, key, ip_str, sizeof (ip_str) - 1), | inet_ntop (AF_INET, key, ip_str, sizeof (ip_str) - 1), | ||||
(gint) (keybits - masklen)); | (gint) (keybits - masklen)); | ||||
} else if (keybits == 128) { | } else if (keybits == 128) { | ||||
msg_err_radix ("cannot insert %p, key: [%s]/%d, duplicate value", | |||||
msg_err_radix ("%s: cannot insert %p, key: [%s]/%d, duplicate value", | |||||
tree->name, | |||||
(gpointer) value, | (gpointer) value, | ||||
inet_ntop (AF_INET6, key, ip_str, sizeof (ip_str) - 1), | inet_ntop (AF_INET6, key, ip_str, sizeof (ip_str) - 1), | ||||
(gint) (keybits - masklen)); | (gint) (keybits - masklen)); | ||||
} else { | } else { | ||||
msg_err_radix ("cannot insert %p with mask %z, key: %*xs, duplicate value", | |||||
(gpointer) value, keybits - masklen, (int) keylen, key); | |||||
msg_err_radix ("%s: cannot insert %p with mask %z, key: %*xs, duplicate value", | |||||
tree->name, | |||||
(gpointer) value, | |||||
keybits - masklen, | |||||
(int) keylen, key); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
radix_compressed_t * | radix_compressed_t * | ||||
radix_create_compressed (void) | |||||
radix_create_compressed (const gchar *tree_name) | |||||
{ | { | ||||
radix_compressed_t *tree; | radix_compressed_t *tree; | ||||
tree->duplicates = 0; | tree->duplicates = 0; | ||||
tree->tree = btrie_init (tree->pool); | tree->tree = btrie_init (tree->pool); | ||||
tree->own_pool = TRUE; | tree->own_pool = TRUE; | ||||
tree->name = tree_name; | |||||
return tree; | return tree; | ||||
} | } | ||||
radix_compressed_t * | radix_compressed_t * | ||||
radix_create_compressed_with_pool (rspamd_mempool_t *pool) | |||||
radix_create_compressed_with_pool (rspamd_mempool_t *pool, const gchar *tree_name) | |||||
{ | { | ||||
radix_compressed_t *tree; | radix_compressed_t *tree; | ||||
tree->duplicates = 0; | tree->duplicates = 0; | ||||
tree->tree = btrie_init (tree->pool); | tree->tree = btrie_init (tree->pool); | ||||
tree->own_pool = FALSE; | tree->own_pool = FALSE; | ||||
tree->name = tree_name; | |||||
return tree; | return tree; | ||||
} | } | ||||
gint | gint | ||||
rspamd_radix_add_iplist (const gchar *list, const gchar *separators, | rspamd_radix_add_iplist (const gchar *list, const gchar *separators, | ||||
radix_compressed_t *tree, gconstpointer value, gboolean resolve) | |||||
radix_compressed_t *tree, gconstpointer value, | |||||
gboolean resolve, const gchar *tree_name) | |||||
{ | { | ||||
gchar *token, *ipnet, *err_str, **strv, **cur, *brace; | gchar *token, *ipnet, *err_str, **strv, **cur, *brace; | ||||
union { | union { | ||||
k = strtoul (ipnet, &err_str, 10); | k = strtoul (ipnet, &err_str, 10); | ||||
if (errno != 0) { | if (errno != 0) { | ||||
msg_warn_radix ( | msg_warn_radix ( | ||||
"invalid netmask, error detected on symbol: %s, error: %s", | |||||
"%s: invalid netmask, error detected on symbol: %s, error: %s", | |||||
tree_name, | |||||
err_str, | err_str, | ||||
strerror (errno)); | strerror (errno)); | ||||
k = G_MAXINT; | k = G_MAXINT; | ||||
gboolean | gboolean | ||||
radix_add_generic_iplist (const gchar *ip_list, radix_compressed_t **tree, | radix_add_generic_iplist (const gchar *ip_list, radix_compressed_t **tree, | ||||
gboolean resolve) | |||||
gboolean resolve, const gchar *tree_name) | |||||
{ | { | ||||
static const char fill_ptr[] = "1"; | static const char fill_ptr[] = "1"; | ||||
if (*tree == NULL) { | if (*tree == NULL) { | ||||
*tree = radix_create_compressed (); | |||||
*tree = radix_create_compressed (tree_name); | |||||
} | } | ||||
return (rspamd_radix_add_iplist (ip_list, ",; ", *tree, | return (rspamd_radix_add_iplist (ip_list, ",; ", *tree, | ||||
fill_ptr, resolve) > 0); | |||||
fill_ptr, resolve, tree_name) > 0); | |||||
} | } | ||||
* Create new radix trie | * Create new radix trie | ||||
* @return | * @return | ||||
*/ | */ | ||||
radix_compressed_t *radix_create_compressed (void); | |||||
radix_compressed_t *radix_create_compressed (const gchar *tree_name); | |||||
radix_compressed_t *radix_create_compressed_with_pool (rspamd_mempool_t *pool); | |||||
radix_compressed_t *radix_create_compressed_with_pool (rspamd_mempool_t *pool, const gchar *tree_name); | |||||
/** | /** | ||||
* Insert list of ip addresses and masks to the radix tree | * Insert list of ip addresses and masks to the radix tree | ||||
* @return number of elements inserted | * @return number of elements inserted | ||||
*/ | */ | ||||
gint rspamd_radix_add_iplist (const gchar *list, const gchar *separators, | gint rspamd_radix_add_iplist (const gchar *list, const gchar *separators, | ||||
radix_compressed_t *tree, gconstpointer value, gboolean resolve); | |||||
radix_compressed_t *tree, gconstpointer value, | |||||
gboolean resolve, const gchar *tree_name); | |||||
/** | /** | ||||
* Generic version of @see rspamd_radix_add_iplist. This function creates tree | * Generic version of @see rspamd_radix_add_iplist. This function creates tree | ||||
* if `tree` is NULL. | * if `tree` is NULL. | ||||
*/ | */ | ||||
gboolean radix_add_generic_iplist (const gchar *ip_list, | |||||
radix_compressed_t **tree, gboolean resolve); | |||||
gboolean | |||||
radix_add_generic_iplist (const gchar *ip_list, | |||||
radix_compressed_t **tree, | |||||
gboolean resolve, | |||||
const gchar *tree_name); | |||||
/** | /** | ||||
* Returns number of elements in the tree | * Returns number of elements in the tree |
rspamd_config_get_module_opt (cfg, "dkim", "whitelist")) != NULL) { | rspamd_config_get_module_opt (cfg, "dkim", "whitelist")) != NULL) { | ||||
rspamd_config_radix_from_ucl (cfg, value, "DKIM whitelist", | rspamd_config_radix_from_ucl (cfg, value, "DKIM whitelist", | ||||
&dkim_module_ctx->whitelist_ip, NULL, NULL); | |||||
&dkim_module_ctx->whitelist_ip, NULL, NULL, "dkim whitelist"); | |||||
} | } | ||||
if ((value = | if ((value = |
rspamd_config_radix_from_ucl (cfg, value, "Fuzzy whitelist", | rspamd_config_radix_from_ucl (cfg, value, "Fuzzy whitelist", | ||||
&fuzzy_module_ctx->whitelist, | &fuzzy_module_ctx->whitelist, | ||||
NULL, | NULL, | ||||
NULL); | |||||
NULL, "fuzzy ip whitelist"); | |||||
} | } | ||||
else { | else { | ||||
fuzzy_module_ctx->whitelist = NULL; | fuzzy_module_ctx->whitelist = NULL; |
static void | static void | ||||
rspamd_radix_test_vec (void) | rspamd_radix_test_vec (void) | ||||
{ | { | ||||
radix_compressed_t *tree = radix_create_compressed (); | |||||
radix_compressed_t *tree = radix_create_compressed (NULL); | |||||
struct _tv *t = &test_vec[0]; | struct _tv *t = &test_vec[0]; | ||||
struct in_addr ina; | struct in_addr ina; | ||||
struct in6_addr in6a; | struct in6_addr in6a; | ||||
{ | { | ||||
struct btrie *btrie; | struct btrie *btrie; | ||||
rspamd_mempool_t *pool; | rspamd_mempool_t *pool; | ||||
radix_compressed_t *comp_tree = radix_create_compressed (); | |||||
radix_compressed_t *comp_tree = radix_create_compressed (NULL); | |||||
struct { | struct { | ||||
guint32 addr; | guint32 addr; | ||||
guint32 mask; | guint32 mask; |