changeset 10400:96152031f5d9 HEAD

lmtp proxy: More error handling fixes.
author Timo Sirainen <tss@iki.fi>
date Tue, 24 Nov 2009 15:11:13 -0500
parents 8f6995923fbd
children 99e069c98709
files src/lmtp/commands.c src/lmtp/lmtp-proxy.c src/lmtp/lmtp-proxy.h
diffstat 3 files changed, 29 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- 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 @@
 		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)
--- 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 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 @@
 	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,12 +202,12 @@
 				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;
-		}
+		if (!array_is_created(&proxy->connections))
+			break;
 	}
-	i_unreached();
+	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)
@@ -213,6 +215,9 @@
 	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);
 	for (i = 0; i < count; i++) {
@@ -223,6 +228,7 @@
 			return;
 		}
 	}
+	/* last client failure should have caused the proxy to be destroyed */
 	i_unreached();
 }
 
@@ -389,13 +395,14 @@
 
 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)
 {
 	struct lmtp_proxy_connection *const *conns;
 	unsigned int i, count;
 
-	proxy->finish_callback = finish_callback;
+	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,
--- 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
@@ -11,6 +11,8 @@
 	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);
 void lmtp_proxy_deinit(struct lmtp_proxy **proxy);
@@ -24,6 +26,6 @@
 /* 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