struct rbldb_t {
A(uint32_t) ips;
- bool locked;
};
ARRAY(rbldb_t)
--end;
}
if (end != map.end) {
- syslog(LOG_WARNING, "file %s miss a final \\n, ignoring last line",
- file);
+ warn("file %s miss a final \\n, ignoring last line",
+ file);
}
db = p_new(rbldb_t, 1);
/* Lookup may perform serveral I/O, so avoid swap.
*/
array_adjust(db->ips);
- db->locked = lock && array_lock(db->ips);
- if (lock && !db->locked) {
+ if (lock && !array_lock(db->ips)) {
UNIXERR("mlock");
}
# include "qsort.c"
}
- syslog(LOG_INFO, "rbl %s loaded, %d IPs", file, db->ips.len);
+ info("rbl %s loaded, %d IPs", file, db->ips.len);
return db;
}
static void rbldb_wipe(rbldb_t *db)
{
- if (db->locked) {
- array_unlock(db->ips);
- }
array_wipe(db->ips);
}
#define PARSE_CHECK(Expr, Str, ...) \
if (!(Expr)) { \
- syslog(LOG_ERR, Str, ##__VA_ARGS__); \
+ err(Str, ##__VA_ARGS__); \
rbl_filter_delete(&data); \
return false; \
}
- foreach (filter_params_t *param, filter->params) {
- /* file parameter is:
- * [no]lock:weight:filename
- * valid options are:
- * - lock: memlock the database in memory.
- * - nolock: don't memlock the database in memory [default].
- * - \d+: a number describing the weight to give to the match
- * the given list [mandatory]
- * the file pointed by filename MUST be a valid ip list issued from
- * the rsync (or equivalent) service of a (r)bl.
- */
- if (strcmp(param->name, "file") == 0) {
+ data->hard_threshold = 1;
+ data->soft_threshold = 1;
+ foreach (filter_param_t *param, filter->params) {
+ switch (param->type) {
+ /* file parameter is:
+ * [no]lock:weight:filename
+ * valid options are:
+ * - lock: memlock the database in memory.
+ * - nolock: don't memlock the database in memory [default].
+ * - \d+: a number describing the weight to give to the match
+ * the given list [mandatory]
+ * the file pointed by filename MUST be a valid ip list issued from
+ * the rsync (or equivalent) service of a (r)bl.
+ */
+ case ATK_FILE: {
bool lock = false;
int weight = 0;
rbldb_t *rbl = NULL;
const char *p = m_strchrnul(param->value, ':');
char *next = NULL;
for (int i = 0 ; i < 3 ; ++i) {
- PARSE_CHECK(i == 2 || *p,
- "file parameter must contains a locking state and a weight option");
+ PARSE_CHECK(i == 2 || *p,
+ "file parameter must contains a locking state "
+ "and a weight option");
switch (i) {
case 0:
if ((p - current) == 4 && strncmp(current, "lock", 4) == 0) {
lock = true;
- } else if ((p - current) == 6 && strncmp(current, "nolock", 6) == 0) {
+ } else if ((p - current) == 6
+ && strncmp(current, "nolock", 6) == 0) {
lock = false;
} else {
PARSE_CHECK(false, "illegal locking state %.*s",
array_add(data->weights, weight);
break;
}
- current = p + 1;
- p = m_strchrnul(current, ':');
+ if (i != 2) {
+ current = p + 1;
+ p = m_strchrnul(current, ':');
+ }
}
-
- /* hard_threshold parameter is an integer.
- * If the matching score of a ip get a score gretter than this threshold,
- * the hook "hard_match" is called.
- * hard_threshold = 0 means, that all matches are hard matches.
- * default is 0;
- */
- } else if (strcmp(param->name, "hard_threshold") == 0) {
- char *next;
- data->hard_threshold = strtol(param->value, &next, 10);
- PARSE_CHECK(*next, "invalid threshold value %s", param->value);
-
- /* soft_threshold parameter is an integer.
- * if the matching score of an ip get a score getter than this threshold
- * and smaller or equal than the hard_threshold, the hook "soft_match"
- * is called.
- * default is 0;
- */
- } else if (strcmp(param->name, "hard_threshold") == 0) {
- char *next;
- data->soft_threshold = strtol(param->value, &next, 10);
- PARSE_CHECK(*next, "invalid threshold value %s", param->value);
-
- } else {
- syslog(LOG_INFO, "ignored parameter %s in rbl filter %s",
- filter->name, param->name);
+ } break;
+
+ /* hard_threshold parameter is an integer.
+ * If the matching score is greater or equal than this threshold,
+ * the hook "hard_match" is called.
+ * hard_threshold = 1 means, that all matches are hard matches.
+ * default is 1;
+ */
+ FILTER_PARAM_PARSE_INT(HARD_THRESHOLD, data->hard_threshold);
+
+ /* soft_threshold parameter is an integer.
+ * if the matching score is greater or equal than this threshold
+ * and smaller or equal than the hard_threshold, the hook "soft_match"
+ * is called.
+ * default is 1;
+ */
+ FILTER_PARAM_PARSE_INT(SOFT_THRESHOLD, data->soft_threshold);
+
+ default: break;
}
}}
const rbl_filter_t *data = filter->data;
if (parse_ipv4(query->client_address, &end, &ip) != 0) {
- syslog(LOG_WARNING, "invalid client address: %s, expected ipv4",
- query->client_address);
+ warn("invalid client address: %s, expected ipv4",
+ query->client_address);
return HTK_ERROR;
}
- for (int i = 0 ; i < data->rbls.len ; ++i) {
+ for (uint32_t i = 0 ; i < data->rbls.len ; ++i) {
const rbldb_t *rbl = array_elt(data->rbls, i);
int weight = array_elt(data->weights, i);
if (rbldb_ipv4_lookup(rbl, ip)) {
sum += weight;
}
}
- if (sum > data->hard_threshold) {
+ if (sum >= data->hard_threshold) {
return HTK_HARD_MATCH;
- } else if (sum > data->soft_threshold) {
+ } else if (sum >= data->soft_threshold) {
return HTK_SOFT_MATCH;
} else {
return HTK_FAIL;
static int rbl_init(void)
{
- filter_type_t type = filter_register("rbl", rbl_filter_constructor,
+ filter_type_t type = filter_register("iplist", rbl_filter_constructor,
rbl_filter_destructor, rbl_filter);
+ /* Hooks.
+ */
+ (void)filter_hook_register(type, "abort");
(void)filter_hook_register(type, "error");
(void)filter_hook_register(type, "fail");
(void)filter_hook_register(type, "hard_match");
(void)filter_hook_register(type, "soft_match");
+
+ /* Parameters.
+ */
+ (void)filter_param_register(type, "file");
+ (void)filter_param_register(type, "hard_threshold");
+ (void)filter_param_register(type, "soft_threshold");
return 0;
}
module_init(rbl_init);