dovecot-2.0: lmtp: Error handling fixes.
dovecot at dovecot.org
dovecot at dovecot.org
Tue Nov 24 01:19:06 EET 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/6ab1e2f4ca55
changeset: 10396: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