dovecot-2.0-sslstream: lmtp: Error handling fixes.

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 13 02:56:41 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0-sslstream/rev/6ab1e2f4ca55
changeset: 10397:6ab1e2f4ca55
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Nov 23 18:19:01 2009 -0500
description:
lmtp: Error handling fixes.

diffstat:

3 files changed, 29 insertions(+), 20 deletions(-)
src/lib-lda/lmtp-client.c |   14 ++++++++++++--
src/lib-lda/lmtp-client.h |    2 ++
src/lmtp/lmtp-proxy.c     |   33 +++++++++++++++------------------

diffs (126 lines):

diff -r aba3cb15f082 -r 6ab1e2f4ca55 src/lib-lda/lmtp-client.c
--- a/src/lib-lda/lmtp-client.c	Mon Nov 23 17:39:18 2009 -0500
+++ b/src/lib-lda/lmtp-client.c	Mon Nov 23 18:19:01 2009 -0500
@@ -502,9 +502,14 @@ void lmtp_client_add_rcpt(struct lmtp_cl
 	rcpt->data_callback = data_callback;
 	rcpt->context = context;
 
-	if (client->global_fail_string != NULL)
+	if (client->global_fail_string != NULL) {
+		client->rcpt_next_receive_idx++;
+		i_assert(client->rcpt_next_receive_idx ==
+			 array_count(&client->recipients));
+
+		rcpt->failed = TRUE;
 		rcpt_to_callback(FALSE, client->global_fail_string, context);
-	else if (client->input_state == LMTP_INPUT_STATE_RCPT_TO)
+	} else if (client->input_state == LMTP_INPUT_STATE_RCPT_TO)
 		lmtp_client_send_rcpts(client);
 }
 
@@ -516,6 +521,11 @@ void lmtp_client_send(struct lmtp_client
 	lmtp_client_send_data_cmd(client);
 }
 
+bool lmtp_client_is_data_input_finished(struct lmtp_client *client)
+{
+	return client->data_input != NULL;
+}
+
 void lmtp_client_send_more(struct lmtp_client *client)
 {
 	if (client->input_state == LMTP_INPUT_STATE_DATA)
diff -r aba3cb15f082 -r 6ab1e2f4ca55 src/lib-lda/lmtp-client.h
--- a/src/lib-lda/lmtp-client.h	Mon Nov 23 17:39:18 2009 -0500
+++ b/src/lib-lda/lmtp-client.h	Mon Nov 23 18:19:01 2009 -0500
@@ -33,6 +33,8 @@ void lmtp_client_add_rcpt(struct lmtp_cl
 			  lmtp_callback_t *data_callback, void *context);
 /* Start sending input stream as DATA. */
 void lmtp_client_send(struct lmtp_client *client, struct istream *data_input);
+/* Returns TRUE if data_input is no longer needed. */
+bool lmtp_client_is_data_input_finished(struct lmtp_client *client);
 /* Call this function whenever input stream can potentially be read forward.
    This is useful with non-blocking istreams and tee-istreams. */
 void lmtp_client_send_more(struct lmtp_client *client);
diff -r aba3cb15f082 -r 6ab1e2f4ca55 src/lmtp/lmtp-proxy.c
--- a/src/lmtp/lmtp-proxy.c	Mon Nov 23 17:39:18 2009 -0500
+++ b/src/lmtp/lmtp-proxy.c	Mon Nov 23 18:19:01 2009 -0500
@@ -55,8 +55,6 @@ struct lmtp_proxy {
 	unsigned int finished:1;
 };
 
-static void lmtp_proxy_conn_deinit(struct lmtp_proxy_connection *conn,
-				   const char *reason);
 static void lmtp_proxy_data_input(struct lmtp_proxy *proxy);
 
 struct lmtp_proxy *
@@ -84,7 +82,7 @@ static void lmtp_proxy_connections_deini
 
 	conns = array_get(&proxy->connections, &count);
 	for (i = 0; i < count; i++)
-		lmtp_proxy_conn_deinit(conns[i], "451 4.3.0 Aborting");
+		lmtp_client_fail(conns[i]->client, "451 4.3.0 Aborting");
 }
 
 void lmtp_proxy_deinit(struct lmtp_proxy **_proxy)
@@ -146,22 +144,12 @@ lmtp_proxy_get_connection(struct lmtp_pr
 	return conn;
 }
 
-static void lmtp_proxy_conn_deinit(struct lmtp_proxy_connection *conn,
-				   const char *reason)
-{
-	struct lmtp_proxy_recipient *rcpt;
-
-	/* set failure replies to all recipients in this connection */
-	array_foreach_modifiable(&conn->proxy->rcpt_to, rcpt) {
-		if (rcpt->conn == conn && !rcpt->rcpt_to_failed)
-			rcpt->reply = reason;
-	}
-
+static void lmtp_proxy_conn_close(struct lmtp_proxy_connection *conn)
+{
 	if (conn->client != NULL)
 		lmtp_client_deinit(&conn->client);
 	if (conn->data_input != NULL)
 		i_stream_unref(&conn->data_input);
-	conn->failed = TRUE;
 }
 
 static bool lmtp_proxy_send_replies(struct lmtp_proxy *proxy)
@@ -256,6 +244,10 @@ lmtp_proxy_conn_rcpt_to(bool success, co
 	}
 	i_assert(i != count);
 
+	if (!success && conn->rcpt_next_reply_low_idx == count &&
+	    lmtp_client_is_data_input_finished(conn->client))
+		lmtp_proxy_conn_close(conn);
+
 	/* send replies only if we've already sent DATA. */
 	if (conn->proxy->data_input != NULL)
 		lmtp_proxy_try_finish(conn->proxy);
@@ -281,6 +273,11 @@ lmtp_proxy_conn_data(bool success ATTR_U
 		}
 	}
 	i_assert(i != count);
+
+	if (conn->data_next_reply_low_idx == count &&
+	    lmtp_client_is_data_input_finished(conn->client))
+		lmtp_proxy_conn_close(conn);
+
 	lmtp_proxy_try_finish(conn->proxy);
 }
 
@@ -334,9 +331,9 @@ static bool lmtp_proxy_disconnect_hangin
 	for (i = 0; i < count; i++) {
 		(void)i_stream_get_data(conns[i]->data_input, &size);
 		if (size == max_size) {
-			lmtp_proxy_conn_deinit(conns[i],
-					       ERRSTR_TEMP_REMOTE_FAILURE
-					       " (DATA output timeout)");
+			lmtp_client_fail(conns[i]->client,
+					 ERRSTR_TEMP_REMOTE_FAILURE
+					 " (DATA output timeout)");
 		}
 	}
 	return TRUE;


More information about the dovecot-cvs mailing list