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, ...);

Attachment: signature.asc
Description: Digital signature

Reply via email to