From: Stephan Bosch Date: Sat, 15 Sep 2018 16:15:36 +0000 (+0200) Subject: submission: backends: Add trans_start() and trans_free() vfuncs. X-Git-Tag: 2.3.9~1288 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=694365517b13f4a45d091670481f48584b797235;p=thirdparty%2Fdovecot%2Fcore.git submission: backends: Add trans_start() and trans_free() vfuncs. These are called when the SMTP transaction is started and freed respectively. --- diff --git a/src/submission/submission-backend.c b/src/submission/submission-backend.c index c92e15724f..66dfc81ca0 100644 --- a/src/submission/submission-backend.c +++ b/src/submission/submission-backend.c @@ -89,7 +89,44 @@ uoff_t submission_backend_get_max_mail_size(struct submission_backend *backend) return UOFF_T_MAX; } -void submission_backends_trans_free(struct client *client) +void submission_backend_trans_start(struct submission_backend *backend, + struct smtp_server_transaction *trans) +{ + submission_backend_start(backend); + + if (backend->trans_started) + return; + backend->trans_started = TRUE; + + if (backend->v.trans_start != NULL) + backend->v.trans_start(backend, trans); +} + +static void +submission_backend_trans_free(struct submission_backend *backend, + struct smtp_server_transaction *trans) +{ + i_stream_unref(&backend->data_input); + if (backend->v.trans_free != NULL) + backend->v.trans_free(backend, trans); +} + +void submission_backends_trans_start(struct client *client, + struct smtp_server_transaction *trans) +{ + struct submission_backend *const *bkp; + + i_assert(client->state.backend != NULL); + submission_backend_trans_start(client->state.backend, trans); + + array_foreach(&client->rcpt_backends, bkp) { + struct submission_backend *backend = *bkp; + submission_backend_trans_start(backend, trans); + } +} + +void submission_backends_trans_free(struct client *client, + struct smtp_server_transaction *trans) { struct submission_backend *const *bkp; @@ -98,8 +135,7 @@ void submission_backends_trans_free(struct client *client) array_foreach(&client->rcpt_backends, bkp) { struct submission_backend *backend = *bkp; - - i_stream_unref(&backend->data_input); + submission_backend_trans_free(backend, trans); } array_clear(&client->rcpt_backends); client->state.backend = NULL; diff --git a/src/submission/submission-backend.h b/src/submission/submission-backend.h index 54c7aa7ce7..92f58fa87c 100644 --- a/src/submission/submission-backend.h +++ b/src/submission/submission-backend.h @@ -13,6 +13,11 @@ struct submission_backend_vfuncs { uoff_t (*get_max_mail_size)(struct submission_backend *backend); + void (*trans_start)(struct submission_backend *backend, + struct smtp_server_transaction *trans); + void (*trans_free)(struct submission_backend *backend, + struct smtp_server_transaction *trans); + int (*cmd_helo)(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd, struct smtp_server_cmd_helo *data); @@ -51,6 +56,7 @@ struct submission_backend { uoff_t data_size; bool started:1; + bool trans_started:1; }; void submission_backend_init(struct submission_backend *backend, @@ -67,7 +73,12 @@ void submission_backends_client_input_post(struct client *client); uoff_t submission_backend_get_max_mail_size(struct submission_backend *backend); -void submission_backends_trans_free(struct client *client); +void submission_backend_trans_start(struct submission_backend *backend, + struct smtp_server_transaction *trans); +void submission_backends_trans_start(struct client *client, + struct smtp_server_transaction *trans); +void submission_backends_trans_free(struct client *client, + struct smtp_server_transaction *trans); void submission_backend_helo_reply_submit(struct submission_backend *backend, struct smtp_server_cmd_ctx *cmd, diff --git a/src/submission/submission-client.c b/src/submission/submission-client.c index bb0a353d13..1d80074e31 100644 --- a/src/submission/submission-client.c +++ b/src/submission/submission-client.c @@ -309,9 +309,18 @@ void client_destroy(struct client *client, const char *prefix, submission_refresh_proctitle(); } +static void +client_connection_trans_start(void *context, + struct smtp_server_transaction *trans) +{ + struct client *client = context; + + submission_backends_trans_start(client, trans); +} + static void client_connection_trans_free(void *context, - struct smtp_server_transaction *trans ATTR_UNUSED) + struct smtp_server_transaction *trans) { struct client *client = context; struct submission_recipient **rcptp; @@ -320,7 +329,7 @@ client_connection_trans_free(void *context, submission_recipient_destroy(rcptp); array_clear(&client->rcpt_to); - submission_backends_trans_free(client); + submission_backends_trans_free(client, trans); client_state_reset(client); } @@ -485,6 +494,7 @@ static const struct smtp_server_callbacks smtp_callbacks = { .conn_cmd_input_pre = client_input_pre, .conn_cmd_input_post = client_input_post, + .conn_trans_start = client_connection_trans_start, .conn_trans_free = client_connection_trans_free, .conn_state_changed = client_connection_state_changed, diff --git a/src/submission/submission-commands.c b/src/submission/submission-commands.c index c6ef4ec33a..865c5251ed 100644 --- a/src/submission/submission-commands.c +++ b/src/submission/submission-commands.c @@ -136,6 +136,7 @@ int cmd_rcpt(void *conn_ctx, struct smtp_server_cmd_ctx *cmd, struct smtp_server_cmd_rcpt *data) { struct client *client = conn_ctx; + struct smtp_server_transaction *trans; struct submission_recipient *rcpt; rcpt = submission_recipient_create(client, data->path); @@ -146,6 +147,10 @@ int cmd_rcpt(void *conn_ctx, struct smtp_server_cmd_ctx *cmd, data->trans_context = rcpt; data->hook_finished = submission_rcpt_finished; + trans = smtp_server_connection_get_transaction(cmd->conn); + if (trans != NULL) + submission_backend_trans_start(rcpt->backend, trans); + return submission_backend_cmd_rcpt(rcpt->backend, cmd, data); } @@ -161,6 +166,8 @@ int cmd_rset(void *conn_ctx, struct smtp_server_cmd_ctx *cmd) if (backend == NULL) backend = client->backend_default; + /* all backends will also be notified through trans_free(), but that + doesn't allow changing the RSET command response. */ return submission_backend_cmd_rset(backend, cmd); }