These are called when the SMTP transaction is started and freed respectively.
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;
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;
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);
uoff_t data_size;
bool started:1;
+ bool trans_started:1;
};
void submission_backend_init(struct submission_backend *backend,
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,
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;
submission_recipient_destroy(rcptp);
array_clear(&client->rcpt_to);
- submission_backends_trans_free(client);
+ submission_backends_trans_free(client, trans);
client_state_reset(client);
}
.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,
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);
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);
}
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);
}