changeset 19992:8bb067f6d2d3

lmtp: Use separate session ID suffixes for each RCPT TO delivery. Otherwise each delivery will use the same session ID when talking to stats process, which results in errors like: Error: stats: FIFO input error: CONNECT: Duplicate session ID ME3ZHCi+A1dUDQAAvAUe3g for user foobar service lmtp Warning: stats: Couldn't find session ID: ME3ZHCi+A1dUDQAAvAUe3g (There was a DISCONNECT for the session ID between these two log lines.)
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Tue, 05 Apr 2016 20:14:15 +0300
parents 64c72629595f
children 9e844498398e
files src/lmtp/client.h src/lmtp/commands.c
diffstat 2 files changed, 15 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lmtp/client.h	Tue Apr 05 20:10:53 2016 +0300
+++ b/src/lmtp/client.h	Tue Apr 05 20:14:15 2016 +0300
@@ -8,6 +8,7 @@
 
 struct mail_recipient {
 	struct client *client;
+	const char *session_id;
 
 	const char *address;
 	const char *detail; /* +detail part is also in address */
--- a/src/lmtp/commands.c	Tue Apr 05 20:10:53 2016 +0300
+++ b/src/lmtp/commands.c	Tue Apr 05 20:14:15 2016 +0300
@@ -655,6 +655,17 @@
 			return 0;
 	}
 
+	/* Use a unique session_id for each mail delivery. This is especially
+	   important for stats process to not see duplicate sessions. */
+	if (array_count(&client->state.rcpt_to) == 0)
+		rcpt->session_id = client->state.session_id;
+	else {
+		rcpt->session_id =
+			p_strdup_printf(client->state_pool, "%s:%u",
+					client->state.session_id,
+					array_count(&client->state.rcpt_to)+1);
+	}
+
 	memset(&input, 0, sizeof(input));
 	input.module = input.service = "lmtp";
 	input.username = username;
@@ -662,7 +673,7 @@
 	input.remote_ip = client->remote_ip;
 	input.local_port = client->local_port;
 	input.remote_port = client->remote_port;
-	input.session_id = client->state.session_id;
+	input.session_id = rcpt->session_id;
 
 	ret = mail_storage_service_lookup(storage_service, &input,
 					  &rcpt->service_user, &error);
@@ -829,7 +840,7 @@
 	dctx.pool = session->pool;
 	dctx.set = lda_set;
 	dctx.timeout_secs = LDA_SUBMISSION_TIMEOUT_SECS;
-	dctx.session_id = client->state.session_id;
+	dctx.session_id = rcpt->session_id;
 	dctx.src_mail = src_mail;
 	dctx.src_envelope_sender = client->state.mail_from;
 	dctx.dest_user = client->state.dest_user;
@@ -870,7 +881,7 @@
 			client->state.first_saved_mail = dctx.dest_mail;
 		}
 		client_send_line(client, "250 2.0.0 <%s> %s Saved",
-				 rcpt->address, client->state.session_id);
+				 rcpt->address, rcpt->session_id);
 		ret = 0;
 	} else if (dctx.tempfail_error != NULL) {
 		client_send_line(client, "451 4.2.0 <%s> %s",