Hi, attached is a patch which adds the following configuration options to postfix:
smtpd_policy_service_error_sleep_time=1s smtpd_policy_service_max_keepalive=0 The first one will make the sleep(1) in attr_clnt_request configurable. (line with comment /* XXX make configurable */) In anvil_clnt.c and tls_mgr.c, where attr_clnt is also used, the current default 1 is used. For check_policy_service (smtpd_check.c) the configuration parameter is used. The second one will cause postfix to disconnect after the specified amount of requests made over a policyd connection. If set to 0 it will be disabled (default and current behaviour). Also statically set to 0 in anvil_clnt.c and tls_mgr.c and configurable for check_policy_service (smtpd_check.c). I wrote this patch because I implemented a prefork policyd with perl/Net::Server. So my policyd needs one process per connection. For a test scenario I need to use multiple check_policy_service checks. The number of connections will grow with smtpd processes * number of checks. For this reason I configured my policyd to close the connection after each request. The documentations says that postfix will reconnect, but it doesn't mention that it'll sleep(1) before reconnecting. So it did not perform very well. The max_keepalive options allows me to set this parameter to the same value in postfix and the policyd. Then both will drop the connection after a specified number of requests per connection. The best solution would be if postfix itself could do some multiplexing and use a single policyd connection for multiple smtpd like proxymap does for eg. database tables. Is such a feature planed? Do you think it would be hard to implement such a feature? Markus
diff -uNr postfix-2.11.1.orig/src/global/anvil_clnt.c postfix-2.11.1/src/global/anvil_clnt.c --- postfix-2.11.1.orig/src/global/anvil_clnt.c 2014-06-26 16:54:03.000000000 +0200 +++ postfix-2.11.1/src/global/anvil_clnt.c 2014-06-27 07:53:21.000000000 +0200 @@ -163,9 +163,9 @@ */ #ifndef VAR_ANVIL_SERVICE anvil_clnt = attr_clnt_create("local:" ANVIL_CLASS "/" ANVIL_SERVICE, - var_ipc_timeout, 0, 0); + var_ipc_timeout, 0, 0, 1, 0); #else - anvil_clnt = attr_clnt_create(var_anvil_service, var_ipc_timeout, 0, 0); + anvil_clnt = attr_clnt_create(var_anvil_service, var_ipc_timeout, 0, 0, 1, 0); #endif return ((ANVIL_CLNT *) anvil_clnt); } diff -uNr postfix-2.11.1.orig/src/global/mail_params.h postfix-2.11.1/src/global/mail_params.h --- postfix-2.11.1.orig/src/global/mail_params.h 2014-06-26 16:54:03.000000000 +0200 +++ postfix-2.11.1/src/global/mail_params.h 2014-06-27 07:53:49.000000000 +0200 @@ -2879,6 +2879,14 @@ #define DEF_SMTPD_POLICY_TMOUT "100s" extern int var_smtpd_policy_tmout; +#define VAR_SMTPD_POLICY_MAX_KEEPALIVE "smtpd_policy_service_max_keepalive" +#define DEF_SMTPD_POLICY_MAX_KEEPALIVE 0 +extern int var_smtpd_policy_max_keepalive; + +#define VAR_SMTPD_POLICY_ERR_SLEEP "smtpd_policy_service_error_sleep_time" +#define DEF_SMTPD_POLICY_ERR_SLEEP "1s" +extern int var_smtpd_policy_err_sleep; + #define VAR_SMTPD_POLICY_IDLE "smtpd_policy_service_max_idle" #define DEF_SMTPD_POLICY_IDLE "300s" extern int var_smtpd_policy_idle; diff -uNr postfix-2.11.1.orig/src/smtpd/smtpd.c postfix-2.11.1/src/smtpd/smtpd.c --- postfix-2.11.1.orig/src/smtpd/smtpd.c 2014-06-26 16:54:03.000000000 +0200 +++ postfix-2.11.1/src/smtpd/smtpd.c 2014-06-27 07:55:10.000000000 +0200 @@ -1220,6 +1220,8 @@ char *var_smtpd_proxy_opts; char *var_input_transp; int var_smtpd_policy_tmout; +int var_smtpd_policy_err_sleep; +int var_smtpd_policy_max_keepalive; int var_smtpd_policy_idle; int var_smtpd_policy_ttl; char *var_xclient_hosts; @@ -5314,6 +5316,7 @@ #ifdef USE_TLS VAR_SMTPD_TLS_CCERT_VD, DEF_SMTPD_TLS_CCERT_VD, &var_smtpd_tls_ccert_vd, 0, 0, #endif + VAR_SMTPD_POLICY_MAX_KEEPALIVE, DEF_SMTPD_POLICY_MAX_KEEPALIVE, &var_smtpd_policy_max_keepalive, 0, 0, 0, }; static const CONFIG_TIME_TABLE time_table[] = { @@ -5322,6 +5325,7 @@ VAR_SMTPD_PROXY_TMOUT, DEF_SMTPD_PROXY_TMOUT, &var_smtpd_proxy_tmout, 1, 0, VAR_VERIFY_POLL_DELAY, DEF_VERIFY_POLL_DELAY, &var_verify_poll_delay, 1, 0, VAR_SMTPD_POLICY_TMOUT, DEF_SMTPD_POLICY_TMOUT, &var_smtpd_policy_tmout, 1, 0, + VAR_SMTPD_POLICY_ERR_SLEEP, DEF_SMTPD_POLICY_ERR_SLEEP, &var_smtpd_policy_err_sleep, 0, 0, VAR_SMTPD_POLICY_IDLE, DEF_SMTPD_POLICY_IDLE, &var_smtpd_policy_idle, 1, 0, VAR_SMTPD_POLICY_TTL, DEF_SMTPD_POLICY_TTL, &var_smtpd_policy_ttl, 1, 0, #ifdef USE_TLS diff -uNr postfix-2.11.1.orig/src/smtpd/smtpd_check.c postfix-2.11.1/src/smtpd/smtpd_check.c --- postfix-2.11.1.orig/src/smtpd/smtpd_check.c 2014-06-26 16:54:03.000000000 +0200 +++ postfix-2.11.1/src/smtpd/smtpd_check.c 2014-06-27 07:55:46.000000000 +0200 @@ -463,7 +463,9 @@ (char *) attr_clnt_create(name, var_smtpd_policy_tmout, var_smtpd_policy_idle, - var_smtpd_policy_ttl)); + var_smtpd_policy_ttl, + var_smtpd_policy_err_sleep, + var_smtpd_policy_max_keepalive)); } /* smtpd_check_parse - pre-parse restrictions */ @@ -5217,6 +5219,8 @@ int var_verify_poll_count; int var_verify_poll_delay; int var_smtpd_policy_tmout; +int var_smtpd_policy_err_sleep; +int var_smtpd_policy_max_keepalive; int var_smtpd_policy_idle; int var_smtpd_policy_ttl; int var_smtpd_rej_unl_from; diff -uNr postfix-2.11.1.orig/src/tls/tls_mgr.c postfix-2.11.1/src/tls/tls_mgr.c --- postfix-2.11.1.orig/src/tls/tls_mgr.c 2014-06-26 16:54:03.000000000 +0200 +++ postfix-2.11.1/src/tls/tls_mgr.c 2014-06-27 07:56:15.000000000 +0200 @@ -163,7 +163,7 @@ service = concatenate("local:" TLS_MGR_CLASS "/", var_tls_mgr_service, (char *) 0); tls_mgr = attr_clnt_create(service, var_ipc_timeout, - var_ipc_idle_limit, var_ipc_ttl_limit); + var_ipc_idle_limit, var_ipc_ttl_limit, 1, 0); myfree(service); attr_clnt_control(tls_mgr, diff -uNr postfix-2.11.1.orig/src/util/attr_clnt.c postfix-2.11.1/src/util/attr_clnt.c --- postfix-2.11.1.orig/src/util/attr_clnt.c 2014-06-26 16:54:03.000000000 +0200 +++ postfix-2.11.1/src/util/attr_clnt.c 2014-06-27 08:02:19.000000000 +0200 @@ -95,6 +95,9 @@ AUTO_CLNT *auto_clnt; ATTR_CLNT_PRINT_FN print; ATTR_CLNT_SCAN_FN scan; + int err_sleep; + int max_keepalive; + int reuse_cnt; }; /* attr_clnt_free - destroy attribute client */ @@ -108,7 +111,7 @@ /* attr_clnt_create - create attribute client */ ATTR_CLNT *attr_clnt_create(const char *service, int timeout, - int max_idle, int max_ttl) + int max_idle, int max_ttl, int err_sleep, int max_keepalive) { ATTR_CLNT *client; @@ -116,6 +119,9 @@ client->auto_clnt = auto_clnt_create(service, timeout, max_idle, max_ttl); client->scan = attr_vscan_plain; client->print = attr_vprint_plain; + client->err_sleep = err_sleep; + client->max_keepalive = max_keepalive; + client->reuse_cnt = 0; return (client); } @@ -188,8 +194,15 @@ ret = client->scan(stream, recv_flags, ap); va_end(ap); /* Finalize argument lists before returning. */ - if (ret > 0) + if (ret > 0) { + if( client->max_keepalive ) { + client->reuse_cnt++; + if( client->reuse_cnt >= client->max_keepalive ) + // better name would be auto_clnt_reset? + auto_clnt_recover(client->auto_clnt); + } break; + } } } if (++count >= 2 @@ -202,7 +215,9 @@ ret = -1; break; } - sleep(1); /* XXX make configurable */ + if( client->err_sleep ) { + sleep(client->err_sleep); + } auto_clnt_recover(client->auto_clnt); } /* Finalize argument lists before returning. */ diff -uNr postfix-2.11.1.orig/src/util/attr_clnt.h postfix-2.11.1/src/util/attr_clnt.h --- postfix-2.11.1.orig/src/util/attr_clnt.h 2014-06-26 16:54:03.000000000 +0200 +++ postfix-2.11.1/src/util/attr_clnt.h 2014-06-27 08:02:33.000000000 +0200 @@ -28,7 +28,7 @@ typedef int (*ATTR_CLNT_PRINT_FN) (VSTREAM *, int, va_list); typedef int (*ATTR_CLNT_SCAN_FN) (VSTREAM *, int, va_list); -extern ATTR_CLNT *attr_clnt_create(const char *, int, int, int); +extern ATTR_CLNT *attr_clnt_create(const char *, int, int, int, int, int); extern int attr_clnt_request(ATTR_CLNT *, int,...); extern void attr_clnt_free(ATTR_CLNT *); extern void attr_clnt_control(ATTR_CLNT *, int, ...);
signature.asc
Description: Digital signature