Mercurial > dnsbl
diff src/dnsbl.cpp @ 255:d6d5c50b9278 stable-6-0-30
Allow dnswl_list and dnsbl_list to be empty, to override lists specified in the ancestor contexts. Add daily recipient limits as a multiple of the hourly limits.
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Mon, 09 Apr 2012 18:02:05 -0700 |
parents | 836b7f2357f9 |
children | d11b529ce9c5 |
line wrap: on
line diff
--- a/src/dnsbl.cpp Sun Apr 08 16:17:53 2012 -0700 +++ b/src/dnsbl.cpp Mon Apr 09 18:02:05 2012 -0700 @@ -114,7 +114,8 @@ time_t last_error_time = 0; int resolver_sock_count = 0; // protected with fd_pool_mutex int resolver_pool_size = 0; // protected with fd_pool_mutex -rcpt_rates rcpt_counts; // protected with rate_mutex +rcpt_rates rcpt_hourly_counts; // protected with rate_mutex +rcpt_rates rcpt_daily_counts; // protected with rate_mutex struct ns_map { @@ -163,20 +164,29 @@ //////////////////////////////////////////////// // helper to manipulate recipient counts // -int incr_rcpt_count(const char *user); -int incr_rcpt_count(const char *user) { +void incr_rcpt_count(const char *user, int &hourly, int &daily); +void incr_rcpt_count(const char *user, int &hourly, int &daily) { pthread_mutex_lock(&rate_mutex); - rcpt_rates::iterator i = rcpt_counts.find(user); - int c = 1; - if (i == rcpt_counts.end()) { + rcpt_rates::iterator i = rcpt_hourly_counts.find(user); + hourly = 1; + if (i == rcpt_hourly_counts.end()) { user = strdup(user); - rcpt_counts[user] = c; + rcpt_hourly_counts[user] = hourly; } else { - c = ++((*i).second); + hourly = ++((*i).second); + } + + rcpt_rates::iterator j = rcpt_daily_counts.find(user); + daily = 1; + if (j == rcpt_daily_counts.end()) { + user = strdup(user); + rcpt_daily_counts[user] = daily; + } + else { + daily = ++((*j).second); } pthread_mutex_unlock(&rate_mutex); - return c; } //////////////////////////////////////////////// @@ -1171,14 +1181,16 @@ return SMFIS_REJECT; } if (priv.authenticated) { - int c = incr_rcpt_count(priv.authenticated); - int l = dc.default_context->find_rate(priv.authenticated); + int hourly, daily; + incr_rcpt_count(priv.authenticated, hourly, daily); + int h_limit = dc.default_context->find_rate(priv.authenticated); + int d_limit = dc.default_context->get_daily_multiple() * h_limit; if (debug_syslog > 1) { char msg[maxlen]; - snprintf(msg, sizeof(msg), "authenticated id %s (%d recipients, %d limit)", priv.authenticated, c, l); + snprintf(msg, sizeof(msg), "authenticated id %s (%d %d recipients, %d %d limits)", priv.authenticated, hourly, daily, h_limit, d_limit); my_syslog(&priv, msg); } - if (c > l) { + if ((hourly > h_limit) || (daily > d_limit)){ smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", (char*)"recipient rate limit exceeded"); return SMFIS_REJECT; } @@ -1525,20 +1537,32 @@ // extern "C" {void* config_loader(void *arg);} void* config_loader(void *arg) { - int loop = 0; + int loop1 = 0; + int loop2 = 0; while (loader_run) { sleep(180); // look for modifications every 3 minutes if (!loader_run) break; - loop++; - if (loop == 20) { + loop1++; + loop2++; + if (loop1 == 20) { // three minutes thru each loop, 20 loops per hour - // clear the recipient counts + // clear the recipient hourly counts pthread_mutex_lock(&rate_mutex); - for (rcpt_rates::iterator i=rcpt_counts.begin(); i!=rcpt_counts.end(); i++) { + for (rcpt_rates::iterator i=rcpt_hourly_counts.begin(); i!=rcpt_hourly_counts.end(); i++) { (*i).second = 0; } pthread_mutex_unlock(&rate_mutex); - loop = 0; + loop1 = 0; + } + if (loop2 == 480) { + // three minutes thru each loop, 480 loops per day + // clear the recipient daily counts + pthread_mutex_lock(&rate_mutex); + for (rcpt_rates::iterator i=rcpt_daily_counts.begin(); i!=rcpt_daily_counts.end(); i++) { + (*i).second = 0; + } + pthread_mutex_unlock(&rate_mutex); + loop2 = 0; } CONFIG &dc = *config; time_t then = dc.load_time;