dovecot-2.0-sslstream: lmtp proxy: More error handling fixes.

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


details:   http://hg.dovecot.org/dovecot-2.0-sslstream/rev/96152031f5d9
changeset: 10401:96152031f5d9
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Nov 24 15:11:13 2009 -0500
description:
lmtp proxy: More error handling fixes.

diffstat:

3 files changed, 34 insertions(+), 19 deletions(-)
src/lmtp/commands.c   |   10 ++++++++--
src/lmtp/lmtp-proxy.c |   39 +++++++++++++++++++++++----------------
src/lmtp/lmtp-proxy.h |    4 +++-

diffs (140 lines):

diff -r 8f6995923fbd -r 96152031f5d9 src/lmtp/commands.c
--- a/src/lmtp/commands.c	Tue Nov 24 14:32:10 2009 -0500
+++ b/src/lmtp/commands.c	Tue Nov 24 15:11:13 2009 -0500
@@ -637,12 +637,18 @@ static void client_input_data_finish(str
 		client_input_handle(client);
 }
 
-static void client_proxy_finish(void *context)
+static void client_proxy_finish(bool timeout, void *context)
 {
 	struct client *client = context;
 
 	lmtp_proxy_deinit(&client->proxy);
-	client_input_data_finish(client);
+	if (timeout) {
+		client_destroy(client,
+			t_strdup_printf("421 4.4.2 %s", client->my_domain),
+			"Disconnected for inactivity");
+	} else {
+		client_input_data_finish(client);
+	}
 }
 
 static const char *client_get_received_line(struct client *client)
diff -r 8f6995923fbd -r 96152031f5d9 src/lmtp/lmtp-proxy.c
--- a/src/lmtp/lmtp-proxy.c	Tue Nov 24 14:32:10 2009 -0500
+++ b/src/lmtp/lmtp-proxy.c	Tue Nov 24 15:11:13 2009 -0500
@@ -39,16 +39,17 @@ struct lmtp_proxy {
 
 	struct timeout *to, *to_data_idle;
 	struct io *io;
-	struct istream *data_input;
+	struct istream *data_input, *orig_data_input;
 	struct ostream *client_output;
 	struct tee_istream *tee_data_input;
 
 	unsigned int max_timeout_msecs;
 
-	void (*finish_callback)(void *);
+	lmtp_proxy_finish_callback_t *finish_callback;
 	void *finish_context;
 
 	unsigned int finished:1;
+	unsigned int input_timeout:1;
 };
 
 static void lmtp_conn_finish(void *context);
@@ -168,12 +169,13 @@ static void lmtp_proxy_finish(struct lmt
 	i_assert(!proxy->finished);
 
 	proxy->finished = TRUE;
-	proxy->finish_callback(proxy->finish_context);
+	proxy->finish_callback(proxy->input_timeout, proxy->finish_context);
 }
 
 static void lmtp_proxy_try_finish(struct lmtp_proxy *proxy)
 {
-	if (lmtp_proxy_send_data_replies(proxy) && proxy->data_input->eof)
+	if (lmtp_proxy_send_data_replies(proxy) &&
+	    (proxy->data_input->eof || proxy->data_input->stream_errno != 0))
 		lmtp_proxy_finish(proxy);
 }
 
@@ -200,18 +202,21 @@ static void lmtp_proxy_fail_all(struct l
 				lmtp_client_state_to_string(conns[i]->client));
 		lmtp_client_fail(conns[i]->client, line);
 
-		if (!array_is_created(&proxy->connections)) {
-			pool_unref(&proxy->pool);
-			return;
-		}
-	}
-	i_unreached();
+		if (!array_is_created(&proxy->connections))
+			break;
+	}
+	pool_unref(&proxy->pool);
+	/* either the whole proxy is destroyed now, or we still have some
+	   DATA input to read. */
 }
 
 static void lmtp_proxy_data_input_timeout(struct lmtp_proxy *proxy)
 {
 	struct lmtp_proxy_connection *const *conns;
 	unsigned int i, count;
+
+	proxy->input_timeout = TRUE;
+	i_stream_close(proxy->orig_data_input);
 
 	pool_ref(proxy->pool);
 	conns = array_get(&proxy->connections, &count);
@@ -223,6 +228,7 @@ static void lmtp_proxy_data_input_timeou
 			return;
 		}
 	}
+	/* last client failure should have caused the proxy to be destroyed */
 	i_unreached();
 }
 
@@ -389,13 +395,14 @@ static void lmtp_proxy_data_input(struct
 
 void lmtp_proxy_start(struct lmtp_proxy *proxy, struct istream *data_input,
 		      const char *header,
-		      void (*finish_callback)(void *), void *context)
-{
-	struct lmtp_proxy_connection *const *conns;
-	unsigned int i, count;
-
-	proxy->finish_callback = finish_callback;
+		      lmtp_proxy_finish_callback_t *callback, void *context)
+{
+	struct lmtp_proxy_connection *const *conns;
+	unsigned int i, count;
+
+	proxy->finish_callback = callback;
 	proxy->finish_context = context;
+	proxy->orig_data_input = data_input;
 	proxy->tee_data_input = tee_i_stream_create(data_input);
 	proxy->data_input = tee_i_stream_create_child(proxy->tee_data_input);
 	proxy->to_data_idle = timeout_add(LMTP_PROXY_DATA_INPUT_TIMEOUT_MSECS,
diff -r 8f6995923fbd -r 96152031f5d9 src/lmtp/lmtp-proxy.h
--- a/src/lmtp/lmtp-proxy.h	Tue Nov 24 14:32:10 2009 -0500
+++ b/src/lmtp/lmtp-proxy.h	Tue Nov 24 15:11:13 2009 -0500
@@ -10,6 +10,8 @@ struct lmtp_proxy_settings {
 	unsigned int timeout_msecs;
 	enum lmtp_client_protocol protocol;
 };
+
+typedef void lmtp_proxy_finish_callback_t(bool timeout, void *context);
 
 struct lmtp_proxy *
 lmtp_proxy_init(const char *my_hostname, struct ostream *client_output);
@@ -24,6 +26,6 @@ int lmtp_proxy_add_rcpt(struct lmtp_prox
 /* Start proxying */
 void lmtp_proxy_start(struct lmtp_proxy *proxy, struct istream *data_input,
 		      const char *header,
-		      void (*finish_callback)(void *), void *context);
+		      lmtp_proxy_finish_callback_t *callback, void *context);
 
 #endif


More information about the dovecot-cvs mailing list