dovecot-2.2: lmtp proxy: Forward proxy_timeout to backend and se...

dovecot at dovecot.org dovecot at dovecot.org
Tue Aug 28 14:46:26 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/6d2a439a10a6
changeset: 14960:6d2a439a10a6
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Aug 28 14:46:16 2012 +0300
description:
lmtp proxy: Forward proxy_timeout to backend and set mail_max_lock_timeout based on it.
This automatically avoids duplicate mail deliveries caused by long lock
waits.

diffstat:

 src/lib-lda/lmtp-client.c |   4 ++++
 src/lib-lda/lmtp-client.h |   6 +++++-
 src/lmtp/client.h         |   1 +
 src/lmtp/commands.c       |  25 ++++++++++++++++++++++---
 src/lmtp/lmtp-proxy.c     |   1 +
 5 files changed, 33 insertions(+), 4 deletions(-)

diffs (140 lines):

diff -r 57efcf0957ea -r 6d2a439a10a6 src/lib-lda/lmtp-client.c
--- a/src/lib-lda/lmtp-client.c	Sat Aug 25 12:05:34 2012 +0300
+++ b/src/lib-lda/lmtp-client.c	Tue Aug 28 14:46:16 2012 +0300
@@ -98,6 +98,7 @@
 	client->set.source_ip = set->source_ip;
 	client->set.source_port = set->source_port;
 	client->set.proxy_ttl_plus_1 = set->proxy_ttl_plus_1;
+	client->set.proxy_timeout_secs = set->proxy_timeout_secs;
 	client->finish_callback = finish_callback;
 	client->finish_context = context;
 	client->fd = -1;
@@ -435,6 +436,9 @@
 	if (client->set.proxy_ttl_plus_1 != 0 &&
 	    str_array_icase_find(client->xclient_args, "TTL"))
 		str_printfa(str, " TTL=%u", client->set.proxy_ttl_plus_1-1);
+	if (client->set.proxy_timeout_secs != 0 &&
+	    str_array_icase_find(client->xclient_args, "TIMEOUT"))
+		str_printfa(str, " TIMEOUT=%u", client->set.proxy_timeout_secs);
 
 	if (str_len(str) == empty_len)
 		return FALSE;
diff -r 57efcf0957ea -r 6d2a439a10a6 src/lib-lda/lmtp-client.h
--- a/src/lib-lda/lmtp-client.h	Sat Aug 25 12:05:34 2012 +0300
+++ b/src/lib-lda/lmtp-client.h	Tue Aug 28 14:46:16 2012 +0300
@@ -18,11 +18,15 @@
 	const char *dns_client_socket_path;
 
 	/* if remote server supports XCLIENT capability,
-	   send the these as ADDR/PORT */
+	   send the these as ADDR/PORT/TTL/TIMEOUT */
 	struct ip_addr source_ip;
 	unsigned int source_port;
 	/* send TTL as this -1, so the default 0 means "don't send it" */
 	unsigned int proxy_ttl_plus_1;
+	/* remote is notified that the connection is going to be closed after
+	   this many seconds, so it should try to keep lock waits and such
+	   lower than this. */
+	unsigned int proxy_timeout_secs;
 };
 
 /* reply contains the reply coming from remote server, or NULL
diff -r 57efcf0957ea -r 6d2a439a10a6 src/lmtp/client.h
--- a/src/lmtp/client.h	Sat Aug 25 12:05:34 2012 +0300
+++ b/src/lmtp/client.h	Tue Aug 28 14:46:16 2012 +0300
@@ -63,6 +63,7 @@
 	struct istream *dot_input;
 	struct lmtp_proxy *proxy;
 	unsigned int proxy_ttl;
+	unsigned int proxy_timeout_secs;
 
 	unsigned int disconnected:1;
 };
diff -r 57efcf0957ea -r 6d2a439a10a6 src/lmtp/commands.c
--- a/src/lmtp/commands.c	Sat Aug 25 12:05:34 2012 +0300
+++ b/src/lmtp/commands.c	Tue Aug 28 14:46:16 2012 +0300
@@ -12,6 +12,7 @@
 #include "istream-dot.h"
 #include "safe-mkstemp.h"
 #include "restrict-access.h"
+#include "settings-parser.h"
 #include "master-service.h"
 #include "rfc822-parser.h"
 #include "message-date.h"
@@ -69,7 +70,7 @@
 	client_state_reset(client);
 	client_send_line(client, "250-%s", client->my_domain);
 	if (client_is_trusted(client))
-		client_send_line(client, "250-XCLIENT ADDR PORT TTL");
+		client_send_line(client, "250-XCLIENT ADDR PORT TTL TIMEOUT");
 	client_send_line(client, "250-8BITMIME");
 	client_send_line(client, "250-ENHANCEDSTATUSCODES");
 	client_send_line(client, "250 PIPELINING");
@@ -573,14 +574,28 @@
 	struct mail_storage *storage;
 	const struct mail_storage_service_input *input;
 	struct mail_namespace *ns;
+	struct setting_parser_context *set_parser;
 	void **sets;
-	const char *error, *username;
+	const char *line, *error, *username;
 	enum mail_error mail_error;
 	int ret;
 
 	input = mail_storage_service_user_get_input(rcpt->service_user);
 	username = t_strdup(input->username);
 
+	set_parser = mail_storage_service_user_get_settings_parser(rcpt->service_user);
+	if (client->proxy_timeout_secs > 0) {
+		/* set lock timeout waits to be less than when proxy has
+		   advertised that it's going to timeout the connection.
+		   this avoids duplicate deliveries in case the delivery
+		   succeeds after the proxy has already disconnected from us. */
+		line = t_strdup_printf("mail_max_lock_timeout=%u",
+				       client->proxy_timeout_secs <= 1 ? 1 :
+				       client->proxy_timeout_secs-1);
+		if (settings_parse_line(set_parser, line) < 0)
+			i_unreached();
+	}
+
 	i_set_failure_prefix(t_strdup_printf("lmtp(%s, %s): ",
 					     my_pid, username));
 	if (mail_storage_service_next(storage_service, rcpt->service_user,
@@ -1000,7 +1015,7 @@
 {
 	const char *const *tmp;
 	struct ip_addr remote_ip;
-	unsigned int remote_port = 0, ttl = -1U;
+	unsigned int remote_port = 0, ttl = -1U, timeout_secs = 0;
 	bool args_ok = TRUE;
 
 	if (!client_is_trusted(client)) {
@@ -1019,6 +1034,9 @@
 		} else if (strncasecmp(*tmp, "TTL=", 4) == 0) {
 			if (str_to_uint(*tmp + 4, &ttl) < 0)
 				args_ok = FALSE;
+		} else if (strncasecmp(*tmp, "TIMEOUT=", 8) == 0) {
+			if (str_to_uint(*tmp + 8, &timeout_secs) < 0)
+				args_ok = FALSE;
 		}
 	}
 	if (!args_ok) {
@@ -1034,6 +1052,7 @@
 		client->remote_port = remote_port;
 	if (ttl != -1U)
 		client->proxy_ttl = ttl;
+	client->proxy_timeout_secs = timeout_secs;
 	client_send_line(client, "220 %s %s", client->my_domain,
 			 client->lmtp_set->login_greeting);
 	return 0;
diff -r 57efcf0957ea -r 6d2a439a10a6 src/lmtp/lmtp-proxy.c
--- a/src/lmtp/lmtp-proxy.c	Sat Aug 25 12:05:34 2012 +0300
+++ b/src/lmtp/lmtp-proxy.c	Tue Aug 28 14:46:16 2012 +0300
@@ -136,6 +136,7 @@
 	client_set.source_ip = proxy->set.source_ip;
 	client_set.source_port = proxy->set.source_port;
 	client_set.proxy_ttl_plus_1 = proxy->set.proxy_ttl+1;
+	client_set.proxy_timeout_secs = set->timeout_msecs/1000;
 
 	conn = p_new(proxy->pool, struct lmtp_proxy_connection, 1);
 	conn->proxy = proxy;


More information about the dovecot-cvs mailing list