Mercurial > dnsbl
comparison 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 |
comparison
equal
deleted
inserted
replaced
254:720cdc2c303f | 255:d6d5c50b9278 |
---|---|
112 int resolver_socket = NULL_SOCKET; // socket used to listen for resolver requests | 112 int resolver_socket = NULL_SOCKET; // socket used to listen for resolver requests |
113 const char *dccifd_port = NULL; // unix domain socket to talk to the dcc interface daemon | 113 const char *dccifd_port = NULL; // unix domain socket to talk to the dcc interface daemon |
114 time_t last_error_time = 0; | 114 time_t last_error_time = 0; |
115 int resolver_sock_count = 0; // protected with fd_pool_mutex | 115 int resolver_sock_count = 0; // protected with fd_pool_mutex |
116 int resolver_pool_size = 0; // protected with fd_pool_mutex | 116 int resolver_pool_size = 0; // protected with fd_pool_mutex |
117 rcpt_rates rcpt_counts; // protected with rate_mutex | 117 rcpt_rates rcpt_hourly_counts; // protected with rate_mutex |
118 rcpt_rates rcpt_daily_counts; // protected with rate_mutex | |
118 | 119 |
119 | 120 |
120 struct ns_map { | 121 struct ns_map { |
121 // all the strings are owned by the keys/values in the ns_host string map | 122 // all the strings are owned by the keys/values in the ns_host string map |
122 string_map ns_host; // nameserver name -> host name that uses this name server | 123 string_map ns_host; // nameserver name -> host name that uses this name server |
161 | 162 |
162 | 163 |
163 //////////////////////////////////////////////// | 164 //////////////////////////////////////////////// |
164 // helper to manipulate recipient counts | 165 // helper to manipulate recipient counts |
165 // | 166 // |
166 int incr_rcpt_count(const char *user); | 167 void incr_rcpt_count(const char *user, int &hourly, int &daily); |
167 int incr_rcpt_count(const char *user) { | 168 void incr_rcpt_count(const char *user, int &hourly, int &daily) { |
168 pthread_mutex_lock(&rate_mutex); | 169 pthread_mutex_lock(&rate_mutex); |
169 rcpt_rates::iterator i = rcpt_counts.find(user); | 170 rcpt_rates::iterator i = rcpt_hourly_counts.find(user); |
170 int c = 1; | 171 hourly = 1; |
171 if (i == rcpt_counts.end()) { | 172 if (i == rcpt_hourly_counts.end()) { |
172 user = strdup(user); | 173 user = strdup(user); |
173 rcpt_counts[user] = c; | 174 rcpt_hourly_counts[user] = hourly; |
174 } | 175 } |
175 else { | 176 else { |
176 c = ++((*i).second); | 177 hourly = ++((*i).second); |
178 } | |
179 | |
180 rcpt_rates::iterator j = rcpt_daily_counts.find(user); | |
181 daily = 1; | |
182 if (j == rcpt_daily_counts.end()) { | |
183 user = strdup(user); | |
184 rcpt_daily_counts[user] = daily; | |
185 } | |
186 else { | |
187 daily = ++((*j).second); | |
177 } | 188 } |
178 pthread_mutex_unlock(&rate_mutex); | 189 pthread_mutex_unlock(&rate_mutex); |
179 return c; | |
180 } | 190 } |
181 | 191 |
182 //////////////////////////////////////////////// | 192 //////////////////////////////////////////////// |
183 // helper to discard the strings held by a context_map | 193 // helper to discard the strings held by a context_map |
184 // | 194 // |
1169 if (replyvalue == token_black) { | 1179 if (replyvalue == token_black) { |
1170 smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", (char*)"recipient can not reply due to blacklisting"); | 1180 smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", (char*)"recipient can not reply due to blacklisting"); |
1171 return SMFIS_REJECT; | 1181 return SMFIS_REJECT; |
1172 } | 1182 } |
1173 if (priv.authenticated) { | 1183 if (priv.authenticated) { |
1174 int c = incr_rcpt_count(priv.authenticated); | 1184 int hourly, daily; |
1175 int l = dc.default_context->find_rate(priv.authenticated); | 1185 incr_rcpt_count(priv.authenticated, hourly, daily); |
1186 int h_limit = dc.default_context->find_rate(priv.authenticated); | |
1187 int d_limit = dc.default_context->get_daily_multiple() * h_limit; | |
1176 if (debug_syslog > 1) { | 1188 if (debug_syslog > 1) { |
1177 char msg[maxlen]; | 1189 char msg[maxlen]; |
1178 snprintf(msg, sizeof(msg), "authenticated id %s (%d recipients, %d limit)", priv.authenticated, c, l); | 1190 snprintf(msg, sizeof(msg), "authenticated id %s (%d %d recipients, %d %d limits)", priv.authenticated, hourly, daily, h_limit, d_limit); |
1179 my_syslog(&priv, msg); | 1191 my_syslog(&priv, msg); |
1180 } | 1192 } |
1181 if (c > l) { | 1193 if ((hourly > h_limit) || (daily > d_limit)){ |
1182 smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", (char*)"recipient rate limit exceeded"); | 1194 smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", (char*)"recipient rate limit exceeded"); |
1183 return SMFIS_REJECT; | 1195 return SMFIS_REJECT; |
1184 } | 1196 } |
1185 st = white; | 1197 st = white; |
1186 } | 1198 } |
1523 // and reload when needed. | 1535 // and reload when needed. |
1524 // we also clear the SMTP AUTH recipient counts hourly | 1536 // we also clear the SMTP AUTH recipient counts hourly |
1525 // | 1537 // |
1526 extern "C" {void* config_loader(void *arg);} | 1538 extern "C" {void* config_loader(void *arg);} |
1527 void* config_loader(void *arg) { | 1539 void* config_loader(void *arg) { |
1528 int loop = 0; | 1540 int loop1 = 0; |
1541 int loop2 = 0; | |
1529 while (loader_run) { | 1542 while (loader_run) { |
1530 sleep(180); // look for modifications every 3 minutes | 1543 sleep(180); // look for modifications every 3 minutes |
1531 if (!loader_run) break; | 1544 if (!loader_run) break; |
1532 loop++; | 1545 loop1++; |
1533 if (loop == 20) { | 1546 loop2++; |
1547 if (loop1 == 20) { | |
1534 // three minutes thru each loop, 20 loops per hour | 1548 // three minutes thru each loop, 20 loops per hour |
1535 // clear the recipient counts | 1549 // clear the recipient hourly counts |
1536 pthread_mutex_lock(&rate_mutex); | 1550 pthread_mutex_lock(&rate_mutex); |
1537 for (rcpt_rates::iterator i=rcpt_counts.begin(); i!=rcpt_counts.end(); i++) { | 1551 for (rcpt_rates::iterator i=rcpt_hourly_counts.begin(); i!=rcpt_hourly_counts.end(); i++) { |
1538 (*i).second = 0; | 1552 (*i).second = 0; |
1539 } | 1553 } |
1540 pthread_mutex_unlock(&rate_mutex); | 1554 pthread_mutex_unlock(&rate_mutex); |
1541 loop = 0; | 1555 loop1 = 0; |
1556 } | |
1557 if (loop2 == 480) { | |
1558 // three minutes thru each loop, 480 loops per day | |
1559 // clear the recipient daily counts | |
1560 pthread_mutex_lock(&rate_mutex); | |
1561 for (rcpt_rates::iterator i=rcpt_daily_counts.begin(); i!=rcpt_daily_counts.end(); i++) { | |
1562 (*i).second = 0; | |
1563 } | |
1564 pthread_mutex_unlock(&rate_mutex); | |
1565 loop2 = 0; | |
1542 } | 1566 } |
1543 CONFIG &dc = *config; | 1567 CONFIG &dc = *config; |
1544 time_t then = dc.load_time; | 1568 time_t then = dc.load_time; |
1545 struct stat st; | 1569 struct stat st; |
1546 bool reload = false; | 1570 bool reload = false; |