]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
submission: Fix starting secondary backends created before the server-side transactio...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Sun, 14 Oct 2018 20:34:50 +0000 (22:34 +0200)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Tue, 12 Feb 2019 13:41:08 +0000 (15:41 +0200)
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
src/submission/submission-client.c
src/submission/submission-client.h

index 66c948723bd2406cc865a33606b260fe4aa1bdbf..c8f1beb4905b2ed270cf56827df45bfb5927a57c 100644 (file)
@@ -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);
 }
index 4777e760a3bc84919d62d78b014edde7e76026e7..e0cd34dcfbdf131f05e9bbf81794e742bd3ea4b4 100644 (file)
@@ -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);
 
index 722177a00198595e43cbd1eabd771ca7c49a4a8d..2cce3c6762310091d643f32f37d3251ec81aeee2 100644 (file)
@@ -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;