From: Stephan Bosch Date: Mon, 31 Aug 2020 12:10:18 +0000 (+0200) Subject: lib-smtp: smtp-server-recipient - Don't create event until transaction becomes available. X-Git-Tag: 2.3.13~235 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e0529aa3256cfddbd93db5c229db733ef0d50bd6;p=thirdparty%2Fdovecot%2Fcore.git lib-smtp: smtp-server-recipient - Don't create event until transaction becomes available. This way, the recipient event parent can be the transaction event once (and if) that becomes available. --- diff --git a/src/lib-smtp/smtp-server-cmd-rcpt.c b/src/lib-smtp/smtp-server-cmd-rcpt.c index 1a4a0014dd..9352d2c5f8 100644 --- a/src/lib-smtp/smtp-server-cmd-rcpt.c +++ b/src/lib-smtp/smtp-server-cmd-rcpt.c @@ -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); diff --git a/src/lib-smtp/smtp-server-private.h b/src/lib-smtp/smtp-server-private.h index cf68883679..a635aab1b1 100644 --- a/src/lib-smtp/smtp-server-private.h +++ b/src/lib-smtp/smtp-server-private.h @@ -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); diff --git a/src/lib-smtp/smtp-server-recipient.c b/src/lib-smtp/smtp-server-recipient.c index 8fe76a0438..3076530136 100644 --- a/src/lib-smtp/smtp-server-recipient.c +++ b/src/lib-smtp/smtp-server-recipient.c @@ -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 =