]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: smtp-server-recipient - Don't create event until transaction becomes available.
authorStephan Bosch <stephan.bosch@open-xchange.com>
Mon, 31 Aug 2020 12:10:18 +0000 (14:10 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Thu, 10 Sep 2020 12:43:56 +0000 (12:43 +0000)
This way, the recipient event parent can be the transaction event once (and if)
that becomes available.

src/lib-smtp/smtp-server-cmd-rcpt.c
src/lib-smtp/smtp-server-private.h
src/lib-smtp/smtp-server-recipient.c

index 1a4a0014dd4c759c0564d9346bd4dda10007f42b..9352d2c5f8bb48a0467e45551a65f3c4e4fba01d 100644 (file)
@@ -14,6 +14,8 @@
 
 struct smtp_server_cmd_rcpt {
        struct smtp_server_recipient *rcpt;
+
+       bool initialized:1;
 };
 
 static void
@@ -64,6 +66,7 @@ cmd_rcpt_completed(struct smtp_server_cmd_ctx *cmd,
        i_assert(smtp_server_command_is_replied(command));
        i_assert(conn->state.state == SMTP_SERVER_STATE_RCPT_TO ||
                 !smtp_server_command_replied_success(command));
+       i_assert(data->initialized);
 
        if (!smtp_server_command_replied_success(command)) {
                /* Failure */
@@ -83,9 +86,15 @@ cmd_rcpt_recheck(struct smtp_server_cmd_ctx *cmd,
                 struct smtp_server_cmd_rcpt *data ATTR_UNUSED)
 {
        struct smtp_server_connection *conn = cmd->conn;
+       struct smtp_server_recipient *rcpt = data->rcpt;
 
        i_assert(conn->state.pending_mail_cmds == 0);
 
+       if (!data->initialized) {
+               smtp_server_recipient_initialize(rcpt);
+               data->initialized = TRUE;
+       }
+
        /* All preceeding commands have finished and now the transaction state
           is clear. This provides the opportunity to re-check the transaction
           state and abort the pending proxied mail command if it is bound to
@@ -206,6 +215,11 @@ void smtp_server_cmd_rcpt(struct smtp_server_cmd_ctx *cmd,
        smtp_server_command_add_hook(command, SMTP_SERVER_COMMAND_HOOK_DESTROY,
                                     cmd_rcpt_destroy, rcpt_data);
 
+       if (conn->state.trans != NULL) {
+               smtp_server_recipient_initialize(rcpt);
+               rcpt_data->initialized = TRUE;
+       }
+
        conn->state.pending_rcpt_cmds++;
 
        smtp_server_command_ref(command);
index cf6888367964299984f4813dd2387e423f538ef4..a635aab1b1fe90ddc5077ed365c6b3614d1dea26 100644 (file)
@@ -369,6 +369,8 @@ void smtp_server_recipient_ref(struct smtp_server_recipient *rcpt);
 bool smtp_server_recipient_unref(struct smtp_server_recipient **_rcpt);
 void smtp_server_recipient_destroy(struct smtp_server_recipient **_rcpt);
 
+void smtp_server_recipient_initialize(struct smtp_server_recipient *rcpt);
+
 bool smtp_server_recipient_approved(struct smtp_server_recipient **_rcpt);
 void smtp_server_recipient_denied(struct smtp_server_recipient *rcpt,
                                  const struct smtp_server_reply *reply);
index 8fe76a043847a6b535df88b3653ef470dd0b6332..30765301360b89c145c7f58bb45d65fc65b0c416 100644 (file)
@@ -20,6 +20,19 @@ smtp_server_recipient_update_event(struct smtp_server_recipient_private *prcpt)
                event, t_strdup_printf("rcpt %s: ", str_sanitize(path, 128)));
 }
 
+static void
+smtp_server_recipient_create_event(struct smtp_server_recipient_private *prcpt)
+{
+       struct smtp_server_recipient *rcpt = &prcpt->rcpt;
+       struct smtp_server_connection *conn = rcpt->conn;
+
+       if (rcpt->event != NULL)
+               return;
+
+       rcpt->event = event_create(conn->event);
+       smtp_server_recipient_update_event(prcpt);
+}
+
 struct smtp_server_recipient *
 smtp_server_recipient_create(struct smtp_server_cmd_ctx *cmd,
                             const struct smtp_address *rcpt_to,
@@ -37,9 +50,6 @@ smtp_server_recipient_create(struct smtp_server_cmd_ctx *cmd,
        prcpt->rcpt.path = smtp_address_clone(pool, rcpt_to);
        smtp_params_rcpt_copy(pool, &prcpt->rcpt.params, params);
 
-       prcpt->rcpt.event = event_create(cmd->conn->event);
-       smtp_server_recipient_update_event(prcpt);
-
        return &prcpt->rcpt;
 }
 
@@ -77,6 +87,8 @@ bool smtp_server_recipient_unref(struct smtp_server_recipient **_rcpt)
                i_unreached();
 
        if (!rcpt->finished) {
+               smtp_server_recipient_create_event(prcpt);
+
                struct event_passthrough *e =
                        event_create_passthrough(rcpt->event)->
                        set_name("smtp_server_transaction_rcpt_finished");
@@ -97,6 +109,14 @@ void smtp_server_recipient_destroy(struct smtp_server_recipient **_rcpt)
        smtp_server_recipient_unref(_rcpt);
 }
 
+void smtp_server_recipient_initialize(struct smtp_server_recipient *rcpt)
+{
+       struct smtp_server_recipient_private *prcpt =
+               (struct smtp_server_recipient_private *)rcpt;
+
+       smtp_server_recipient_create_event(prcpt);
+}
+
 const struct smtp_address *
 smtp_server_recipient_get_original(struct smtp_server_recipient *rcpt)
 {
@@ -111,6 +131,7 @@ bool smtp_server_recipient_approved(struct smtp_server_recipient **_rcpt)
        struct smtp_server_transaction *trans = rcpt->conn->state.trans;
 
        i_assert(trans != NULL);
+       i_assert(rcpt->event != NULL);
 
        e_debug(rcpt->event, "Approved");
 
@@ -125,6 +146,8 @@ void smtp_server_recipient_denied(struct smtp_server_recipient *rcpt,
                                  const struct smtp_server_reply *reply)
 {
        i_assert(!rcpt->finished);
+       i_assert(rcpt->event != NULL);
+
        rcpt->finished = TRUE;
 
        struct event_passthrough *e =