From 624907b56495fc94d9687738730d33a6e0092760 Mon Sep 17 00:00:00 2001 From: Stephan Bosch Date: Sun, 14 Oct 2018 22:34:50 +0200 Subject: [PATCH] submission: Fix starting secondary backends created before the server-side transaction is fully created. Record an array of those backends and start them once the transaction is created. Before, this was implemented using the array of approved recipients (which each point to their backend). However, this does not work, since there can be no approved recipients when there is no server-side transaction yet. --- src/submission/submission-backend.c | 22 +++++++++++++++++++++- src/submission/submission-client.c | 2 ++ src/submission/submission-client.h | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/submission/submission-backend.c b/src/submission/submission-backend.c index 66c948723b..c8f1beb490 100644 --- a/src/submission/submission-backend.c +++ b/src/submission/submission-backend.c @@ -120,10 +120,12 @@ void submission_backends_trans_start(struct client *client, i_assert(client->state.backend != NULL); submission_backend_trans_start(client->state.backend, trans); - array_foreach(&client->rcpt_backends, bkp) { + array_foreach(&client->pending_backends, bkp) { struct submission_backend *backend = *bkp; + submission_backend_trans_start(backend, trans); } + array_clear(&client->pending_backends); } void submission_backends_trans_free(struct client *client, @@ -138,6 +140,7 @@ void submission_backends_trans_free(struct client *client, struct submission_backend *backend = *bkp; submission_backend_trans_free(backend, trans); } + array_clear(&client->pending_backends); array_clear(&client->rcpt_backends); client->state.backend = NULL; } @@ -176,6 +179,21 @@ int submission_backend_cmd_mail(struct submission_backend *backend, return backend->v.cmd_mail(backend, cmd, data); } +static void +submission_backend_add_pending(struct submission_backend *backend) +{ + struct client *client = backend->client; + + struct submission_backend *const *bkp; + + array_foreach(&client->pending_backends, bkp) { + if (backend == *bkp) + return; + } + + array_append(&client->pending_backends, &backend, 1); +} + int submission_backend_cmd_rcpt(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd, struct submission_recipient *srcpt) @@ -190,6 +208,8 @@ int submission_backend_cmd_rcpt(struct submission_backend *backend, trans = smtp_server_connection_get_transaction(cmd->conn); if (trans != NULL) submission_backend_trans_start(srcpt->backend, trans); + else + submission_backend_add_pending(srcpt->backend); return backend->v.cmd_rcpt(backend, cmd, srcpt); } diff --git a/src/submission/submission-client.c b/src/submission/submission-client.c index 4777e760a3..e0cd34dcfb 100644 --- a/src/submission/submission-client.c +++ b/src/submission/submission-client.c @@ -205,6 +205,7 @@ struct client *client_create(int fd_in, int fd_out, client->set = set; client->session_id = p_strdup(pool, session_id); + i_array_init(&client->pending_backends, 4); i_array_init(&client->rcpt_to, 8); i_array_init(&client->rcpt_backends, 8); @@ -299,6 +300,7 @@ client_default_destroy(struct client *client, const char *prefix, client_disconnect(client, prefix, reason); submission_backends_destroy_all(client); + array_free(&client->pending_backends); array_free(&client->rcpt_to); array_free(&client->rcpt_backends); diff --git a/src/submission/submission-client.h b/src/submission/submission-client.h index 722177a001..2cce3c6762 100644 --- a/src/submission/submission-client.h +++ b/src/submission/submission-client.h @@ -65,6 +65,7 @@ struct client { struct smtp_server_connection *conn; enum smtp_server_state last_state; struct client_state state; + ARRAY(struct submission_backend *) pending_backends; ARRAY(struct submission_recipient *) rcpt_to; ARRAY(struct submission_backend *) rcpt_backends; -- 2.47.3