diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-11-21 23:13:13 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-11-21 23:13:13 +0200 |
commit | 7f4dfb88f23a14f0b9603e648d4a1a459a6f26a3 (patch) | |
tree | 2beb9dee6a3a93130bd7f783a62afa20ed14e853 | |
parent | d20b648b02aa1f8caf9975a116c54e05d67d1c39 (diff) | |
download | mailfromd-7f4dfb88f23a14f0b9603e648d4a1a459a6f26a3.tar.gz mailfromd-7f4dfb88f23a14f0b9603e648d4a1a459a6f26a3.tar.bz2 |
Use callout resolver to handle timed-out callouts.mtax-cleanup
* mfd/savclt.c: New file.
* mfd/Makefile.am (mailfromd_SOURCES): Add savclt.c
* mfd/callout.c (transcript): Get ID as 1st arg.
Remove static qualifier. All callers updated.
* mfd/engine.c (method_strict)
(method_standard): If callout returned mf_temp_failure,
try to pass the task to the callout server, if one is
defined.
* mfd/mailfromd.h (transcript)
(schedule_callout): New protos.
(callout_server_sa, callout_server_sa_len): New externs.
* mfd/main.c (force_remove): Initialize to 0 (see srvman.c)
(server_config_stmt): New statements single-process and
reuseaddr.
(add_legacy_milter_port, server_section_parser): Pass
flags to mfd_server_new.
(mf_cfg_param): New statement `callout-url'.
* mfd/savsrv.c (MF_SOURCE_NAME): Fixed.
(verify, callout_session_server): Set proctitle.
(callout_session_server): Fix memory leak.
* mfd/srvman.c (struct mfd_server): New member `flags'.
(mfd_server_new): Take flags as 4th argument.
(server_run): Use flags to set single-user and reuseaddr
modes.
* mfd/srvman.h (SRV_SINGLE_PROCESS)
(SRV_KEEP_EXISTING): New defines.
(mfd_server_new): Change signature.
(srvman_url_to_sockaddr): New proto.
-rw-r--r-- | mfd/Makefile.am | 1 | ||||
-rw-r--r-- | mfd/callout.c | 10 | ||||
-rw-r--r-- | mfd/engine.c | 6 | ||||
-rw-r--r-- | mfd/mailfromd.h | 15 | ||||
-rw-r--r-- | mfd/main.c | 55 | ||||
-rw-r--r-- | mfd/savclt.c | 275 | ||||
-rw-r--r-- | mfd/savsrv.c | 14 | ||||
-rw-r--r-- | mfd/srvman.c | 11 | ||||
-rw-r--r-- | mfd/srvman.h | 7 |
9 files changed, 364 insertions, 30 deletions
diff --git a/mfd/Makefile.am b/mfd/Makefile.am index 962c22a0..c68afcff 100644 --- a/mfd/Makefile.am +++ b/mfd/Makefile.am | |||
@@ -74,2 +74,3 @@ mailfromd_SOURCES = \ | |||
74 | prog.h\ | 74 | prog.h\ |
75 | savclt.c\ | ||
75 | savsrv.c\ | 76 | savsrv.c\ |
diff --git a/mfd/callout.c b/mfd/callout.c index c028838e..acecb26f 100644 --- a/mfd/callout.c +++ b/mfd/callout.c | |||
@@ -131,4 +131,4 @@ smtp_io_free(struct smtp_io_data *iop) | |||
131 | 131 | ||
132 | static void | 132 | void |
133 | transcript(struct smtp_io_data *io, char *prefix, const char *msg) | 133 | transcript(const char *id, char *prefix, const char *msg) |
134 | { | 134 | { |
@@ -143,3 +143,3 @@ transcript(struct smtp_io_data *io, char *prefix, const char *msg) | |||
143 | logmsg(LOG_INFO, "%s: %s %*.*s", | 143 | logmsg(LOG_INFO, "%s: %s %*.*s", |
144 | io->id, | 144 | id, |
145 | prefix, len, len, msg); | 145 | prefix, len, len, msg); |
@@ -218,3 +218,3 @@ smtp_send(struct smtp_io_data *iop, const char *command) | |||
218 | iop->reply = NULL; /* Clear reply for logging purposes */ | 218 | iop->reply = NULL; /* Clear reply for logging purposes */ |
219 | transcript(iop, "SEND:", command); | 219 | transcript(iop->id, "SEND:", command); |
220 | do { | 220 | do { |
@@ -345,3 +345,3 @@ smtp_recv(struct smtp_io_data *iop, enum smtp_timeout to) | |||
345 | return -1; | 345 | return -1; |
346 | transcript(iop, "RECV:", iop->reply); | 346 | transcript(iop->id, "RECV:", iop->reply); |
347 | code = strtoul(iop->reply, &p, 0); | 347 | code = strtoul(iop->reply, &p, 0); |
diff --git a/mfd/engine.c b/mfd/engine.c index e1f2de06..c9741c1b 100644 --- a/mfd/engine.c +++ b/mfd/engine.c | |||
@@ -273,2 +273,3 @@ mfl_smtp_io_callback(void *data, const char *key, const char *value) | |||
273 | 273 | ||
274 | |||
274 | /* Method "strict". Verifies whether EMAIL is understood either by | 275 | /* Method "strict". Verifies whether EMAIL is understood either by |
@@ -301,2 +302,4 @@ method_strict(eval_environ_t env, char *email, char *client_addr, | |||
301 | cache_insert2(email, client_addr, rc); | 302 | cache_insert2(email, client_addr, rc); |
303 | else if (rc == mf_temp_failure) | ||
304 | schedule_callout(email, ehlo, mailfrom, client_addr); | ||
302 | } else { | 305 | } else { |
@@ -332,2 +335,3 @@ method_standard(eval_environ_t env, char *email, char *ehlo, char *mailfrom) | |||
332 | env); | 335 | env); |
336 | smtp_io_setup_callout(io, email, ehlo, mailfrom); | ||
333 | rc = callout_standard(io); | 337 | rc = callout_standard(io); |
@@ -336,2 +340,4 @@ method_standard(eval_environ_t env, char *email, char *ehlo, char *mailfrom) | |||
336 | cache_insert(email, rc); | 340 | cache_insert(email, rc); |
341 | else if (rc == mf_temp_failure) | ||
342 | schedule_callout(email, ehlo, mailfrom, NULL); | ||
337 | } else { | 343 | } else { |
diff --git a/mfd/mailfromd.h b/mfd/mailfromd.h index 5df54636..74cf1079 100644 --- a/mfd/mailfromd.h +++ b/mfd/mailfromd.h | |||
@@ -988,6 +988,2 @@ int xeval(eval_environ_t env, enum smtp_state tag); | |||
988 | mf_status listens_on (const char *client_addr, int port, time_t timeout); | 988 | mf_status listens_on (const char *client_addr, int port, time_t timeout); |
989 | mf_status check_on_host(eval_environ_t env, char *email, char *client_addr, | ||
990 | char *ehlo, char *mailfrom); | ||
991 | mf_status check_mx_records(eval_environ_t env, char *email, char *client_addr, | ||
992 | char *ehlo, char *mailfrom, int *pcount); | ||
993 | mf_status method_strict(eval_environ_t env, char *email, char *client_addr, | 989 | mf_status method_strict(eval_environ_t env, char *email, char *client_addr, |
@@ -1149,3 +1145,5 @@ mf_status callout_strict(struct smtp_io_data *, const char *); | |||
1149 | mf_status callout_standard(struct smtp_io_data *); | 1145 | mf_status callout_standard(struct smtp_io_data *); |
1150 | 1146 | ||
1147 | void transcript(const char *id, char *prefix, const char *msg); | ||
1148 | |||
1151 | /* savsrv.c */ | 1149 | /* savsrv.c */ |
@@ -1155 +1153,8 @@ int callout_session_server(const char *id, int fd, | |||
1155 | 1153 | ||
1154 | /* savclt.c */ | ||
1155 | void schedule_callout(const char *email, const char *ehlo, | ||
1156 | const char *mailfrom, | ||
1157 | const char *client_addr); | ||
1158 | extern struct sockaddr *callout_server_sa; | ||
1159 | extern socklen_t callout_server_sa_len; | ||
1160 | |||
@@ -72,5 +72,5 @@ unsigned optimization_level = 1; /* Optimization level */ | |||
72 | int log_to_stderr; /* Use stderr for logging */ | 72 | int log_to_stderr; /* Use stderr for logging */ |
73 | int force_remove = 1; /* Remove local communication socket if it already | ||
74 | exists */ | ||
75 | int foreground; /* Stay in foreground */ | 73 | int foreground; /* Stay in foreground */ |
74 | int force_remove; /* Remove local communication socket if it already | ||
75 | exists */ | ||
76 | int single_process_option; /* Run in single process mode. */ | 76 | int single_process_option; /* Run in single process mode. */ |
@@ -624,3 +624,4 @@ add_legacy_milter_port(const char *str, mu_debug_t dbg) | |||
624 | mfd_server_t srv = mfd_server_new(id, url, | 624 | mfd_server_t srv = mfd_server_new(id, url, |
625 | milter_session_server); | 625 | milter_session_server, |
626 | 0); | ||
626 | if (srv) | 627 | if (srv) |
@@ -1383,3 +1384,2 @@ parse_opt(int key, char *arg, struct argp_state *state) | |||
1383 | case 'r': | 1384 | case 'r': |
1384 | /*FIXME*/ | ||
1385 | force_remove = 1; | 1385 | force_remove = 1; |
@@ -2101,2 +2101,4 @@ struct server_config_stmt { | |||
2101 | mfd_server_func_t server; | 2101 | mfd_server_func_t server; |
2102 | int single_process; | ||
2103 | int reuseaddr; | ||
2102 | }; | 2104 | }; |
@@ -2128,2 +2130,8 @@ struct mu_cfg_param server_section_param[] = { | |||
2128 | N_("Maximum number of instances allowed for this server.") }, | 2130 | N_("Maximum number of instances allowed for this server.") }, |
2131 | { "single-process", mu_cfg_bool, | ||
2132 | &server_config_stmt.single_process, 0, NULL, | ||
2133 | N_("Single-process mode.") }, | ||
2134 | { "reuseaddr", mu_cfg_bool, | ||
2135 | &server_config_stmt.reuseaddr, 0, NULL, | ||
2136 | N_("Reuse existing socket (default).") }, | ||
2129 | { "acl", mu_cfg_section, | 2137 | { "acl", mu_cfg_section, |
@@ -2143,2 +2151,3 @@ server_section_parser(enum mu_cfg_section_stage stage, | |||
2143 | memset(&server_config_stmt, 0, sizeof(server_config_stmt)); | 2151 | memset(&server_config_stmt, 0, sizeof(server_config_stmt)); |
2152 | server_config_stmt.reuseaddr = 1; | ||
2144 | if (mu_cfg_assert_value_type (node->label, MU_CFG_STRING, | 2153 | if (mu_cfg_assert_value_type (node->label, MU_CFG_STRING, |
@@ -2162,6 +2171,13 @@ server_section_parser(enum mu_cfg_section_stage stage, | |||
2162 | if (server_config_stmt.url && server_config_stmt.server) { | 2171 | if (server_config_stmt.url && server_config_stmt.server) { |
2163 | mfd_server_t srv = | 2172 | int flags = 0; |
2164 | mfd_server_new(server_config_stmt.id, | 2173 | mfd_server_t srv; |
2165 | server_config_stmt.url, | 2174 | |
2166 | server_config_stmt.server); | 2175 | if (server_config_stmt.single_process) |
2176 | flags |= SRV_SINGLE_PROCESS; | ||
2177 | if (!server_config_stmt.reuseaddr) | ||
2178 | flags |= SRV_KEEP_EXISTING; | ||
2179 | srv = mfd_server_new(server_config_stmt.id, | ||
2180 | server_config_stmt.url, | ||
2181 | server_config_stmt.server, | ||
2182 | flags); | ||
2167 | if (srv) { | 2183 | if (srv) { |
@@ -2204,2 +2220,18 @@ cb_milter_listen(mu_debug_t err, void *data, mu_config_value_t *arg) | |||
2204 | 2220 | ||
2221 | static int | ||
2222 | cb_callout_url(mu_debug_t err, void *data, mu_config_value_t *arg) | ||
2223 | { | ||
2224 | mu_url_t url; | ||
2225 | if (mu_cfg_assert_value_type(arg, MU_CFG_STRING, err)) | ||
2226 | return 1; | ||
2227 | url = parse_milter_url(err, arg->v.string); | ||
2228 | if (url) { | ||
2229 | callout_server_sa = srvman_url_to_sockaddr(url, | ||
2230 | &callout_server_sa_len); | ||
2231 | mu_url_destroy(&url); | ||
2232 | } | ||
2233 | return 0; | ||
2234 | } | ||
2235 | |||
2236 | |||
2205 | struct mu_cfg_param mf_cfg_param[] = { | 2237 | struct mu_cfg_param mf_cfg_param[] = { |
@@ -2294,2 +2326,9 @@ struct mu_cfg_param mf_cfg_param[] = { | |||
2294 | { "database", mu_cfg_section, NULL }, | 2326 | { "database", mu_cfg_section, NULL }, |
2327 | |||
2328 | { "callout-url", mu_cfg_callback, | ||
2329 | NULL, 0, | ||
2330 | cb_callout_url, | ||
2331 | N_("URL of the callout server"), | ||
2332 | N_("url") }, | ||
2333 | |||
2295 | 2334 | ||
diff --git a/mfd/savclt.c b/mfd/savclt.c new file mode 100644 index 00000000..447f6857 --- /dev/null +++ b/mfd/savclt.c | |||
@@ -0,0 +1,275 @@ | |||
1 | /* This file is part of Mailfromd. | ||
2 | Copyright (C) 2005, 2006, 2007, 2008, 2009 Sergey Poznyakoff | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 3, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
16 | |||
17 | #define MF_SOURCE_NAME MF_SOURCE_SAVCLT | ||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | #include <sys/types.h> | ||
22 | #include <sys/stat.h> | ||
23 | #include <unistd.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <stdio.h> | ||
26 | #include <sys/socket.h> | ||
27 | #include <netinet/in.h> | ||
28 | #include <arpa/inet.h> | ||
29 | #include <netdb.h> | ||
30 | |||
31 | #include "mailfromd.h" | ||
32 | |||
33 | struct sockaddr *callout_server_sa; | ||
34 | socklen_t callout_server_sa_len; | ||
35 | time_t savclt_timeout = 3; | ||
36 | |||
37 | /* Ideally, I'd want to use smtp_io functions here. But they are | ||
< |