X-Git-Url: http://git.madism.org/?a=blobdiff_plain;f=postlicyd%2Fiplist.c;h=867f88b7757e965418dfe6fba7aa5b0152373925;hb=ae0c2eb5d2ea501fd9e458fc138696c268a14569;hp=256c360d9c546923a44f6a30e7f2694d3d23af07;hpb=91da9fe6f37e6a82b226622e1a3e90ee85a9a138;p=apps%2Fpfixtools.git diff --git a/postlicyd/iplist.c b/postlicyd/iplist.c index 256c360..867f88b 100644 --- a/postlicyd/iplist.c +++ b/postlicyd/iplist.c @@ -62,7 +62,7 @@ enum { }; struct rbldb_t { - A(uint32_t) ips; + A(uint16_t) ips[1 << 16]; }; ARRAY(rbldb_t) @@ -123,6 +123,7 @@ rbldb_t *rbldb_create(const char *file, bool lock) rbldb_t *db; file_map_t map; const char *p, *end; + uint32_t ips = 0; if (!file_map_open(&map, file, false)) { return NULL; @@ -148,33 +149,37 @@ rbldb_t *rbldb_create(const char *file, bool lock) if (parse_ipv4(p, &p, &ip) < 0) { p = (char *)memchr(p, '\n', end - p) + 1; } else { - array_add(db->ips, ip); + array_add(db->ips[ip >> 16], ip & 0xffff); + ++ips; } } file_map_close(&map); /* Lookup may perform serveral I/O, so avoid swap. */ - array_adjust(db->ips); - if (lock && !array_lock(db->ips)) { - UNIXERR("mlock"); - } - - if (db->ips.len) { -# define QSORT_TYPE uint32_t -# define QSORT_BASE db->ips.data -# define QSORT_NELT db->ips.len + for (int i = 0 ; i < 1 << 16 ; ++i) { + array_adjust(db->ips[i]); + if (lock && !array_lock(db->ips[i])) { + UNIXERR("mlock"); + } + if (db->ips[i].len) { +# define QSORT_TYPE uint16_t +# define QSORT_BASE db->ips[i].data +# define QSORT_NELT db->ips[i].len # define QSORT_LT(a,b) *a < *b # include "qsort.c" + } } - info("rbl %s loaded, %d IPs", file, db->ips.len); + info("rbl %s loaded, %d IPs", file, ips); return db; } static void rbldb_wipe(rbldb_t *db) { - array_wipe(db->ips); + for (int i = 0 ; i < 1 << 16 ; ++i) { + array_wipe(db->ips[i]); + } } void rbldb_delete(rbldb_t **db) @@ -187,20 +192,26 @@ void rbldb_delete(rbldb_t **db) uint32_t rbldb_stats(const rbldb_t *rbl) { - return rbl->ips.len; + uint32_t ips = 0; + for (int i = 0 ; i < 1 << 16 ; ++i) { + ips += array_len(rbl->ips[i]); + } + return ips; } bool rbldb_ipv4_lookup(const rbldb_t *db, uint32_t ip) { - int l = 0, r = db->ips.len; + const uint16_t hip = ip >> 16; + const uint16_t lip = ip & 0xffff; + int l = 0, r = db->ips[hip].len; while (l < r) { int i = (r + l) / 2; - if (array_elt(db->ips, i) == ip) + if (array_elt(db->ips[hip], i) == lip) return true; - if (ip < array_elt(db->ips, i)) { + if (lip < array_elt(db->ips[hip], i)) { r = i; } else { l = i + 1; @@ -268,7 +279,7 @@ static bool rbl_filter_constructor(filter_t *filter) * 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: { + case ATK_FILE: case ATK_RBLDNS: { bool lock = false; int weight = 0; rbldb_t *rbl = NULL; @@ -288,7 +299,7 @@ static bool rbl_filter_constructor(filter_t *filter) lock = false; } else { PARSE_CHECK(false, "illegal locking state %.*s", - p - current, current); + (int)(p - current), current); } break; @@ -296,7 +307,7 @@ static bool rbl_filter_constructor(filter_t *filter) weight = strtol(current, &next, 10); PARSE_CHECK(next == p && weight >= 0 && weight <= 1024, "illegal weight value %.*s", - (p - current), current); + (int)(p - current), current); break; case 2: @@ -314,11 +325,11 @@ static bool rbl_filter_constructor(filter_t *filter) } } break; - /* host parameter. + /* dns parameter. * weight:hostname. * define a RBL to use through DNS resolution. */ - case ATK_HOST: { + case ATK_DNS: { int weight = 0; const char *current = param->value; const char *p = m_strchrnul(param->value, ':'); @@ -331,7 +342,7 @@ static bool rbl_filter_constructor(filter_t *filter) weight = strtol(current, &next, 10); PARSE_CHECK(next == p && weight >= 0 && weight <= 1024, "illegal weight value %.*s", - (p - current), current); + (int)(p - current), current); break; case 1: @@ -367,7 +378,7 @@ static bool rbl_filter_constructor(filter_t *filter) } }} - PARSE_CHECK(data->rbls.len, + PARSE_CHECK(data->rbls.len || data->host_offsets.len, "no file parameter in the filter %s", filter->name); filter->data = data; return true; @@ -380,7 +391,8 @@ static void rbl_filter_destructor(filter_t *filter) filter->data = data; } -static filter_result_t rbl_filter(const filter_t *filter, const query_t *query) +static filter_result_t rbl_filter(const filter_t *filter, const query_t *query, + filter_context_t *context) { uint32_t ip; int32_t sum = 0; @@ -439,7 +451,8 @@ static filter_result_t rbl_filter(const filter_t *filter, const query_t *query) static int rbl_init(void) { filter_type_t type = filter_register("iplist", rbl_filter_constructor, - rbl_filter_destructor, rbl_filter); + rbl_filter_destructor, rbl_filter, + NULL, NULL); /* Hooks. */ (void)filter_hook_register(type, "abort"); @@ -447,11 +460,13 @@ static int rbl_init(void) (void)filter_hook_register(type, "fail"); (void)filter_hook_register(type, "hard_match"); (void)filter_hook_register(type, "soft_match"); + (void)filter_hook_register(type, "async"); /* Parameters. */ (void)filter_param_register(type, "file"); - (void)filter_param_register(type, "host"); + (void)filter_param_register(type, "rbldns"); + (void)filter_param_register(type, "dns"); (void)filter_param_register(type, "hard_threshold"); (void)filter_param_register(type, "soft_threshold"); return 0;