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