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;