From: Stephan Bosch Date: Sun, 14 Oct 2018 20:34:50 +0000 (+0200) Subject: submission: Fix starting secondary backends created before the server-side transactio... X-Git-Tag: 2.3.9~1201 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=624907b56495fc94d9687738730d33a6e0092760;p=thirdparty%2Fdovecot%2Fcore.git 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. --- 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;