comparison src/dnsbl.cpp @ 76:81f1e400e8ab

start coding on new config syntax
author carl
date Sat, 16 Jul 2005 13:47:19 -0700
parents 1142e46be550
children 8487650c98ee
comparison
equal deleted inserted replaced
75:1142e46be550 76:81f1e400e8ab
10 -r port The port used to talk to our internal dns resolver processes 10 -r port The port used to talk to our internal dns resolver processes
11 -p port The port through which the MTA will connect to this milter. 11 -p port The port through which the MTA will connect to this milter.
12 -t sec The timeout value. 12 -t sec The timeout value.
13 -c Check the config, and print a copy to stdout. Don't start the 13 -c Check the config, and print a copy to stdout. Don't start the
14 milter or do anything with the socket. 14 milter or do anything with the socket.
15 -s Stress test by loading and deleting the current config in a loop.
15 -d Add debug syslog entries 16 -d Add debug syslog entries
17 -e f|t Print the results of looking up from address f and to address
18 t in the current config
16 19
17 20
18 TODO: 21 TODO:
19 1) Add config for max_recipients for each mail domain. Recipients in 22
20 excess of that limit will be rejected, and the entire data will be 23 1) Add option for using smtp connections to verify addresses from backup
21 rejected if it is sent.
22
23 2) Add config for poison addresses. If any recipient is poison, all
24 recipients are rejected even if they would be whitelisted, and the
25 data is rejected if sent.
26
27 3) Add option to only allow one recipient if the return path is empty.
28
29 4) Check if the envelope from domain name primary MX points 127.0.0.0/8
30
31 5) Add option for using smtp connections to verify addresses from backup
32 mx machines. This allows the backup mx to learn the valid addresses 24 mx machines. This allows the backup mx to learn the valid addresses
33 on the primary machine. 25 on the primary machine.
34 26
35 */ 27 */
36 28
91 83
92 bool debug_syslog = false; 84 bool debug_syslog = false;
93 bool syslog_opened = false; 85 bool syslog_opened = false;
94 bool use_syslog = true; // false to printf 86 bool use_syslog = true; // false to printf
95 bool loader_run = true; // used to stop the config loader thread 87 bool loader_run = true; // used to stop the config loader thread
96 CONFIG * config = NULL; // protected by the config_mutex 88 CONFIG *config = NULL; // protected by the config_mutex
97 int generation = 0; // protected by the config_mutex 89 int generation = 0; // protected by the config_mutex
90 const int maxlen = 1000; // used for snprintf buffers
98 91
99 pthread_mutex_t config_mutex; 92 pthread_mutex_t config_mutex;
100 pthread_mutex_t syslog_mutex; 93 pthread_mutex_t syslog_mutex;
101 pthread_mutex_t resolve_mutex; 94 pthread_mutex_t resolve_mutex;
102 pthread_mutex_t fd_pool_mutex; 95 pthread_mutex_t fd_pool_mutex;
161 void discard(context_map &cm) { 154 void discard(context_map &cm) {
162 for (context_map::iterator i=cm.begin(); i!=cm.end(); i++) { 155 for (context_map::iterator i=cm.begin(); i!=cm.end(); i++) {
163 char *x = (*i).first; 156 char *x = (*i).first;
164 free(x); 157 free(x);
165 } 158 }
159 cm.clear();
166 } 160 }
167 161
168 162
169 //////////////////////////////////////////////// 163 ////////////////////////////////////////////////
170 // helper to register a string in a context_map 164 // helper to register a string in a context_map
233 pthread_mutex_lock(&config_mutex); 227 pthread_mutex_lock(&config_mutex);
234 pc = config; 228 pc = config;
235 pc->reference_count++; 229 pc->reference_count++;
236 pthread_mutex_unlock(&config_mutex); 230 pthread_mutex_unlock(&config_mutex);
237 get_fd(); 231 get_fd();
238 ip = 0; 232 ip = 0;
239 mailaddr = NULL; 233 mailaddr = NULL;
240 queueid = NULL; 234 queueid = NULL;
241 authenticated = false; 235 authenticated = false;
242 have_whites = false; 236 have_whites = false;
243 only_whites = true; 237 only_whites = true;
244 memory = new recorder(this, pc->get_html_tags(), pc->get_content_tlds()); 238 memory = NULL;
245 scanner = new url_scanner(memory); 239 scanner = NULL;
240 content_suffix = NULL;
241 content_message = NULL;
242 content_host_ignore = NULL;
246 } 243 }
247 244
248 mlfiPriv::~mlfiPriv() { 245 mlfiPriv::~mlfiPriv() {
249 return_fd(); 246 return_fd();
250 pthread_mutex_lock(&config_mutex); 247 pthread_mutex_lock(&config_mutex);
252 pthread_mutex_unlock(&config_mutex); 249 pthread_mutex_unlock(&config_mutex);
253 reset(true); 250 reset(true);
254 } 251 }
255 252
256 void mlfiPriv::reset(bool final) { 253 void mlfiPriv::reset(bool final) {
254 if (debug_syslog) my_syslog(this, "mlfiPriv::reset");
257 if (mailaddr) free(mailaddr); 255 if (mailaddr) free(mailaddr);
258 if (queueid) free(queueid); 256 if (queueid) free(queueid);
259 discard(env_to); 257 discard(env_to);
260 delete memory; 258 if (memory) delete memory;
261 delete scanner; 259 if (scanner) delete scanner;
262 if (!final) { 260 if (!final) {
263 mailaddr = NULL; 261 mailaddr = NULL;
264 queueid = NULL; 262 queueid = NULL;
265 authenticated = false; 263 authenticated = false;
266 have_whites = false; 264 have_whites = false;
267 only_whites = true; 265 only_whites = true;
268 memory = new recorder(this, pc->get_html_tags(), pc->get_content_tlds()); 266 memory = NULL;
269 scanner = new url_scanner(memory); 267 scanner = NULL;
270 } 268 content_suffix = NULL;
269 content_message = NULL;
270 content_host_ignore = NULL;
271 }
272 if (debug_syslog) my_syslog("mlfiPriv::reset exit");
271 } 273 }
272 274
273 void mlfiPriv::get_fd() { 275 void mlfiPriv::get_fd() {
274 err = true; 276 err = true;
275 fd = NULL_SOCKET; 277 fd = NULL_SOCKET;
366 } 368 }
367 return rs; 369 return rs;
368 } 370 }
369 371
370 void mlfiPriv::need_content_filter(char *rcpt, CONTEXT &con) { 372 void mlfiPriv::need_content_filter(char *rcpt, CONTEXT &con) {
373 if (debug_syslog) my_syslog(this, "need_content_filter");
371 register_string(env_to, rcpt, &con); 374 register_string(env_to, rcpt, &con);
375 if (!memory) {
376 // first recipient that needs content filtering sets all
377 // the content filtering parameters
378 memory = new recorder(this, con.get_html_tags(), con.get_content_tlds());
379 scanner = new url_scanner(memory);
380 content_suffix = con.get_content_suffix();
381 content_message = con.get_content_message();
382 content_host_ignore = &con.get_content_host_ignore();
383 }
384 if (debug_syslog) my_syslog(this, "need_content_filter exit");
372 } 385 }
373 386
374 #define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx)) 387 #define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx))
375 388
376 389
377 //////////////////////////////////////////////// 390 ////////////////////////////////////////////////
378 // syslog a message 391 // syslog a message
379 // 392 //
380 void my_syslog(mlfiPriv *priv, char *text) { 393 void my_syslog(mlfiPriv *priv, char *text) {
381 char buf[1000]; 394 char buf[maxlen];
382 if (priv) { 395 if (priv) {
383 snprintf(buf, sizeof(buf), "%s: %s", priv->queueid, text); 396 snprintf(buf, sizeof(buf), "%s: %s", priv->queueid, text);
384 text = buf; 397 text = buf;
385 } 398 }
386 if (use_syslog) { 399 if (use_syslog) {
388 if (!syslog_opened) { 401 if (!syslog_opened) {
389 openlog("dnsbl", LOG_PID, LOG_MAIL); 402 openlog("dnsbl", LOG_PID, LOG_MAIL);
390 syslog_opened = true; 403 syslog_opened = true;
391 } 404 }
392 syslog(LOG_NOTICE, "%s", text); 405 syslog(LOG_NOTICE, "%s", text);
406 closelog();
407 syslog_opened = false;
393 pthread_mutex_unlock(&syslog_mutex); 408 pthread_mutex_unlock(&syslog_mutex);
394 } 409 }
395 else { 410 else {
396 printf("%s \n", text); 411 printf("%s \n", text);
397 } 412 }
642 // 657 //
643 bool check_hosts(mlfiPriv &priv, bool random, int limit, char *&host, int ip); 658 bool check_hosts(mlfiPriv &priv, bool random, int limit, char *&host, int ip);
644 bool check_hosts(mlfiPriv &priv, bool random, int limit, char *&host, int ip) { 659 bool check_hosts(mlfiPriv &priv, bool random, int limit, char *&host, int ip) {
645 CONFIG &dc = *priv.pc; 660 CONFIG &dc = *priv.pc;
646 string_set &hosts = priv.memory->get_hosts(); 661 string_set &hosts = priv.memory->get_hosts();
647 string_set &ignore = dc.get_content_host_ignore(); 662 string_set &ignore = *priv.content_host_ignore;
648 char *suffix = dc.get_content_suffix(); 663 char *suffix = priv.content_suffix;
649 664
650 int count = 0; 665 int count = 0;
651 int cnt = hosts.size(); // number of hosts we could look at 666 int cnt = hosts.size(); // number of hosts we could look at
652 int_set ips; 667 int_set ips;
653 ns_map nameservers; 668 ns_map nameservers;
660 675
661 // try to only look at limit/cnt fraction of the available cnt host names in random mode 676 // try to only look at limit/cnt fraction of the available cnt host names in random mode
662 if ((cnt > limit) && (limit > 0) && random) { 677 if ((cnt > limit) && (limit > 0) && random) {
663 int r = rand() % cnt; 678 int r = rand() % cnt;
664 if (r >= limit) { 679 if (r >= limit) {
665 char buf[1000]; 680 char buf[maxlen];
666 snprintf(buf, sizeof(buf), "host %s skipped", host); 681 snprintf(buf, sizeof(buf), "host %s skipped", host);
667 my_syslog(&priv, buf); 682 my_syslog(&priv, buf);
668 continue; 683 continue;
669 } 684 }
670 } 685 }
671 count++; 686 count++;
672 ip = dns_interface(priv, host, true, &nameservers); 687 ip = dns_interface(priv, host, true, &nameservers);
673 if (debug_syslog) { 688 if (debug_syslog) {
674 char buf[1000]; 689 char buf[maxlen];
675 if (ip) { 690 if (ip) {
676 char adr[sizeof "255.255.255.255"]; 691 char adr[sizeof "255.255.255.255"];
677 adr[0] = '\0'; 692 adr[0] = '\0';
678 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr)); 693 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr));
679 snprintf(buf, sizeof(buf), "host %s found at %s", host, adr); 694 snprintf(buf, sizeof(buf), "host %s found at %s", host, adr);
702 } 717 }
703 host = (*i).first; // a transient reference that needs to be replaced before we return it 718 host = (*i).first; // a transient reference that needs to be replaced before we return it
704 ip = (*i).second; 719 ip = (*i).second;
705 if (!ip) ip = dns_interface(priv, host, false, NULL); 720 if (!ip) ip = dns_interface(priv, host, false, NULL);
706 if (debug_syslog) { 721 if (debug_syslog) {
707 char buf[200]; 722 char buf[maxlen];
708 if (ip) { 723 if (ip) {
709 char adr[sizeof "255.255.255.255"]; 724 char adr[sizeof "255.255.255.255"];
710 adr[0] = '\0'; 725 adr[0] = '\0';
711 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr)); 726 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr));
712 snprintf(buf, sizeof(buf), "ns %s found at %s", host, adr); 727 snprintf(buf, sizeof(buf), "ns %s found at %s", host, adr);
722 ips.insert(ip); 737 ips.insert(ip);
723 if (check_single(priv, ip, suffix)) { 738 if (check_single(priv, ip, suffix)) {
724 string_map::iterator j = nameservers.ns_host.find(host); 739 string_map::iterator j = nameservers.ns_host.find(host);
725 if (j != nameservers.ns_host.end()) { 740 if (j != nameservers.ns_host.end()) {
726 char *refer = (*j).second; 741 char *refer = (*j).second;
727 char buf[1000]; 742 char buf[maxlen];
728 snprintf(buf, sizeof(buf), "%s with nameserver %s", refer, host); 743 snprintf(buf, sizeof(buf), "%s with nameserver %s", refer, host);
729 host = register_string(hosts, buf); // put a copy into hosts, and return that reference 744 host = register_string(hosts, buf); // put a copy into hosts, and return that reference
730 } 745 }
731 else { 746 else {
732 host = register_string(hosts, host); // put a copy into hosts, and return that reference 747 host = register_string(hosts, host); // put a copy into hosts, and return that reference
760 //////////////////////////////////////////////// 775 ////////////////////////////////////////////////
761 // start of sendmail milter interfaces 776 // start of sendmail milter interfaces
762 // 777 //
763 sfsistat mlfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr) 778 sfsistat mlfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr)
764 { 779 {
780 if (debug_syslog) my_syslog("mlfi_connect");
765 // allocate some private memory 781 // allocate some private memory
766 mlfiPriv *priv = new mlfiPriv; 782 mlfiPriv *priv = new mlfiPriv;
767 if (hostaddr->sa_family == AF_INET) { 783 if (hostaddr->sa_family == AF_INET) {
768 priv->ip = ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr; 784 priv->ip = ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr;
769 } 785 }
776 } 792 }
777 793
778 sfsistat mlfi_envfrom(SMFICTX *ctx, char **from) 794 sfsistat mlfi_envfrom(SMFICTX *ctx, char **from)
779 { 795 {
780 mlfiPriv &priv = *MLFIPRIV; 796 mlfiPriv &priv = *MLFIPRIV;
797 if (debug_syslog) my_syslog(&priv, "mlfi_envfrom");
781 priv.mailaddr = to_lower_string(from[0]); 798 priv.mailaddr = to_lower_string(from[0]);
782 priv.authenticated = (smfi_getsymval(ctx, "{auth_authen}") != NULL); 799 priv.authenticated = (smfi_getsymval(ctx, "{auth_authen}") != NULL);
783 return SMFIS_CONTINUE; 800 return SMFIS_CONTINUE;
784 } 801 }
785 802
786 sfsistat mlfi_envrcpt(SMFICTX *ctx, char **rcpt) 803 sfsistat mlfi_envrcpt(SMFICTX *ctx, char **rcpt)
787 { 804 {
788 DNSBLP rejectlist = NULL; // list that caused the reject 805 DNSBLP rejectlist = NULL; // list that caused the reject
789 mlfiPriv &priv = *MLFIPRIV; 806 mlfiPriv &priv = *MLFIPRIV;
807 if (debug_syslog) my_syslog(&priv, "mlfi_envrcpt");
790 CONFIG &dc = *priv.pc; 808 CONFIG &dc = *priv.pc;
791 if (!priv.queueid) priv.queueid = strdup(smfi_getsymval(ctx, "i")); 809 if (!priv.queueid) priv.queueid = strdup(smfi_getsymval(ctx, "i"));
792 char *rcptaddr = rcpt[0]; 810 char *rcptaddr = rcpt[0];
793 char *loto = to_lower_string(rcptaddr); 811 char *loto = to_lower_string(rcptaddr);
794 CONTEXT con = *(dc.find_context(loto)->find_context(priv.mailaddr)); 812 if (debug_syslog) my_syslog(&priv, "finding context");
813 CONTEXT &con = *(dc.find_context(loto)->find_context(priv.mailaddr));
814 if (debug_syslog) {
815 char buf[maxlen];
816 char msg[maxlen];
817 snprintf(msg, sizeof(msg), "from <%s> to <%s> using context %s", priv.mailaddr, loto, con.get_full_name(buf,maxlen));
818 my_syslog(&priv, msg);
819 }
820 if (debug_syslog) my_syslog(&priv, "finding from value");
795 char *fromvalue = con.find_from(priv.mailaddr); 821 char *fromvalue = con.find_from(priv.mailaddr);
796 free(loto); 822 free(loto);
797 status st; 823 status st;
798 if (fromvalue == token_black) { 824 if (fromvalue == token_black) {
799 st = black; 825 st = black;
801 else if (fromvalue == token_white) { 827 else if (fromvalue == token_white) {
802 st = white; 828 st = white;
803 } 829 }
804 else { 830 else {
805 // check the dns based lists 831 // check the dns based lists
832 if (debug_syslog) my_syslog(&priv, "checking dns lists");
806 st = (check_dnsbl(priv, con.get_dnsbl_list(), rejectlist)) ? black : oksofar; 833 st = (check_dnsbl(priv, con.get_dnsbl_list(), rejectlist)) ? black : oksofar;
807 } 834 }
808 if (st == reject) { 835 if (st == reject) {
809 // reject the recipient based on some dnsbl 836 // reject the recipient based on some dnsbl
810 char adr[sizeof "255.255.255.255"]; 837 char adr[sizeof "255.255.255.255"];
811 adr[0] = '\0'; 838 adr[0] = '\0';
812 inet_ntop(AF_INET, (const u_char *)&priv.ip, adr, sizeof(adr)); 839 inet_ntop(AF_INET, (const u_char *)&priv.ip, adr, sizeof(adr));
813 char buf[2000]; 840 char buf[maxlen];
814 snprintf(buf, sizeof(buf), rejectlist->message, adr, adr); 841 snprintf(buf, sizeof(buf), rejectlist->message, adr, adr);
815 smfi_setreply(ctx, "550", "5.7.1", buf); 842 smfi_setreply(ctx, "550", "5.7.1", buf);
816 return SMFIS_REJECT; 843 return SMFIS_REJECT;
817 } 844 }
818 else if (st == black) { 845 else if (st == black) {
820 smfi_setreply(ctx, "550", "5.7.1", "no such user"); 847 smfi_setreply(ctx, "550", "5.7.1", "no such user");
821 return SMFIS_REJECT; 848 return SMFIS_REJECT;
822 } 849 }
823 else { 850 else {
824 // accept the recipient 851 // accept the recipient
852 if (debug_syslog) my_syslog(&priv, "checking content filtering");
825 if (!con.get_content_filtering()) st = white; 853 if (!con.get_content_filtering()) st = white;
826 if (st == oksofar) { 854 if (st == oksofar) {
827 // but remember the non-whites 855 // but remember the non-whites
828 priv.need_content_filter(rcptaddr, con); 856 priv.need_content_filter(rcptaddr, con);
829 priv.only_whites = false; 857 priv.only_whites = false;
836 } 864 }
837 865
838 sfsistat mlfi_body(SMFICTX *ctx, u_char *data, size_t len) 866 sfsistat mlfi_body(SMFICTX *ctx, u_char *data, size_t len)
839 { 867 {
840 mlfiPriv &priv = *MLFIPRIV; 868 mlfiPriv &priv = *MLFIPRIV;
869 if (debug_syslog) my_syslog(&priv, "mlfi_body");
841 if (priv.authenticated) return SMFIS_CONTINUE; 870 if (priv.authenticated) return SMFIS_CONTINUE;
842 if (priv.only_whites) return SMFIS_CONTINUE; 871 if (priv.only_whites) return SMFIS_CONTINUE;
843 priv.scanner->scan(data, len); 872 priv.scanner->scan(data, len);
844 return SMFIS_CONTINUE; 873 return SMFIS_CONTINUE;
845 } 874 }
846 875
847 sfsistat mlfi_eom(SMFICTX *ctx) 876 sfsistat mlfi_eom(SMFICTX *ctx)
848 { 877 {
878 if (debug_syslog) my_syslog("mlfi_eom");
849 sfsistat rc; 879 sfsistat rc;
850 mlfiPriv &priv = *MLFIPRIV; 880 mlfiPriv &priv = *MLFIPRIV;
881 if (debug_syslog) my_syslog(&priv, "mlfi_eom");
851 CONFIG &dc = *priv.pc; 882 CONFIG &dc = *priv.pc;
852 char *host = NULL; 883 char *host = NULL;
853 int ip; 884 int ip;
854 status st; 885 status st;
855 // process end of message 886 // process end of message
856 if (priv.authenticated || priv.only_whites) rc = SMFIS_CONTINUE; 887 if (priv.authenticated || priv.only_whites) rc = SMFIS_CONTINUE;
857 else { 888 else {
889 // assert env_to not empty
890 char buf[maxlen];
858 char *msg = NULL; 891 char *msg = NULL;
859 string_set alive; 892 string_set alive;
860 bool random = false; 893 bool random = false;
861 int limit = 0; 894 int limit = 0;
862 for (context_map::iterator i=priv.env_to.begin(); i!=priv.env_to.end(); i++) { 895 for (context_map::iterator i=priv.env_to.begin(); i!=priv.env_to.end(); i++) {
870 alive.insert(rcpt); 903 alive.insert(rcpt);
871 random |= con.get_host_random(); 904 random |= con.get_host_random();
872 limit = max(limit, con.get_host_limit()); 905 limit = max(limit, con.get_host_limit());
873 } 906 }
874 } 907 }
875 bool rejecting = alive.empty(); 908 bool rejecting = alive.empty(); // if alive is empty, we must have set msg above in acceptable_content()
876 if (!rejecting) { 909 if (!rejecting) {
877 rejecting = check_hosts(priv, random, limit, host, ip); 910 if (check_hosts(priv, random, limit, host, ip)) {
878 if (rejecting) {
879 static char buf[2000];
880 char adr[sizeof "255.255.255.255"]; 911 char adr[sizeof "255.255.255.255"];
881 adr[0] = '\0'; 912 adr[0] = '\0';
882 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr)); 913 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr));
883 snprintf(buf, sizeof(buf), dc.get_content_message(), host, adr); 914 snprintf(buf, sizeof(buf), priv.content_message, host, adr);
884 msg = buf; 915 msg = buf;
916 rejecting = true;
885 } 917 }
886 } 918 }
887 if (!rejecting) { 919 if (!rejecting) {
888 rc = SMFIS_CONTINUE; 920 rc = SMFIS_CONTINUE;
889 } 921 }
890 else if (!priv.have_whites && alive.empty()) { 922 else if (!priv.have_whites) {
891 // can reject the entire message 923 // can reject the entire message
892 smfi_setreply(ctx, "550", "5.7.1", msg); 924 smfi_setreply(ctx, "550", "5.7.1", msg);
893 rc = SMFIS_REJECT; 925 rc = SMFIS_REJECT;
894 } 926 }
895 else { 927 else {
907 } 939 }
908 940
909 sfsistat mlfi_abort(SMFICTX *ctx) 941 sfsistat mlfi_abort(SMFICTX *ctx)
910 { 942 {
911 mlfiPriv &priv = *MLFIPRIV; 943 mlfiPriv &priv = *MLFIPRIV;
944 if (debug_syslog) my_syslog(&priv, "mlfi_abort");
912 priv.reset(); 945 priv.reset();
913 return SMFIS_CONTINUE; 946 return SMFIS_CONTINUE;
914 } 947 }
915 948
916 sfsistat mlfi_close(SMFICTX *ctx) 949 sfsistat mlfi_close(SMFICTX *ctx)
917 { 950 {
918 mlfiPriv *priv = MLFIPRIV; 951 mlfiPriv *priv = MLFIPRIV;
952 if (debug_syslog) my_syslog(priv, "mlfi_close");
919 if (!priv) return SMFIS_CONTINUE; 953 if (!priv) return SMFIS_CONTINUE;
920 delete priv; 954 delete priv;
921 smfi_setpriv(ctx, NULL); 955 smfi_setpriv(ctx, NULL);
922 return SMFIS_CONTINUE; 956 return SMFIS_CONTINUE;
923 } 957 }
947 CONFIG* new_conf() { 981 CONFIG* new_conf() {
948 CONFIG *newc = new CONFIG; 982 CONFIG *newc = new CONFIG;
949 pthread_mutex_lock(&config_mutex); 983 pthread_mutex_lock(&config_mutex);
950 newc->generation = generation++; 984 newc->generation = generation++;
951 pthread_mutex_unlock(&config_mutex); 985 pthread_mutex_unlock(&config_mutex);
952 char buf[200]; 986 char buf[maxlen];
953 snprintf(buf, sizeof(buf), "loading configuration generation %d", newc->generation); 987 snprintf(buf, sizeof(buf), "loading configuration generation %d", newc->generation);
954 my_syslog(buf); 988 my_syslog(buf);
955 if (load_conf(*newc, "dnsbl.conf")) { 989 if (load_conf(*newc, "dnsbl.conf")) {
956 newc->load_time = time(NULL); 990 newc->load_time = time(NULL);
957 return newc; 991 return newc;
994 } 1028 }
995 // now look for old configs with zero ref counts 1029 // now look for old configs with zero ref counts
996 for (configp_set::iterator i=old_configs.begin(); i!=old_configs.end(); ) { 1030 for (configp_set::iterator i=old_configs.begin(); i!=old_configs.end(); ) {
997 CONFIG *old = *i; 1031 CONFIG *old = *i;
998 if (!old->reference_count) { 1032 if (!old->reference_count) {
999 char buf[200]; 1033 char buf[maxlen];
1000 snprintf(buf, sizeof(buf), "freeing memory for old configuration generation %d", old->generation); 1034 snprintf(buf, sizeof(buf), "freeing memory for old configuration generation %d", old->generation);
1001 my_syslog(buf); 1035 my_syslog(buf);
1002 delete old; // destructor does all the work 1036 delete old; // destructor does all the work
1003 old_configs.erase(i++); 1037 old_configs.erase(i++);
1004 } 1038 }
1130 exit(EX_USAGE); 1164 exit(EX_USAGE);
1131 } 1165 }
1132 } 1166 }
1133 1167
1134 if (check) { 1168 if (check) {
1135 use_syslog = false; 1169 use_syslog = false;
1170 debug_syslog = true;
1136 CONFIG *conf = new_conf(); 1171 CONFIG *conf = new_conf();
1137 if (conf) { 1172 if (conf) {
1138 conf->dump(); 1173 conf->dump();
1139 delete conf; 1174 delete conf;
1140 return 0; 1175 return 0;
1165 char *to = strdup(x+1); 1200 char *to = strdup(x+1);
1166 use_syslog = false; 1201 use_syslog = false;
1167 CONFIG *conf = new_conf(); 1202 CONFIG *conf = new_conf();
1168 if (conf) { 1203 if (conf) {
1169 CONTEXTP con = conf->find_context(to); 1204 CONTEXTP con = conf->find_context(to);
1170 const int maxlen = 1000;
1171 char buf[maxlen]; 1205 char buf[maxlen];
1172 fprintf(stdout, "envelope to <%s> finds context %s\n", to, con->get_full_name(buf,maxlen)); 1206 fprintf(stdout, "envelope to <%s> finds context %s\n", to, con->get_full_name(buf,maxlen));
1173 CONTEXTP fc = con->find_context(from); 1207 CONTEXTP fc = con->find_context(from);
1174 fprintf(stdout, "envelope from <%s> finds context %s\n", from, fc->get_full_name(buf,maxlen)); 1208 fprintf(stdout, "envelope from <%s> finds context %s\n", from, fc->get_full_name(buf,maxlen));
1175 char *st = fc->find_from(from); 1209 char *st = fc->find_from(from);