From 0a408b1e4b47ee4cd10ab21e26bb247b03da6cd6 Mon Sep 17 00:00:00 2001 From: Stephan Bosch Date: Thu, 30 Aug 2018 00:18:40 +0200 Subject: [PATCH] submission: Split the QUIT command into a generic part and a part related to relaying to an MTA. --- src/submission/cmd-quit.c | 97 +++++++++++++++++++++------- src/submission/submission-commands.h | 1 + 2 files changed, 74 insertions(+), 24 deletions(-) diff --git a/src/submission/cmd-quit.c b/src/submission/cmd-quit.c index d77100eb07..0018614efb 100644 --- a/src/submission/cmd-quit.c +++ b/src/submission/cmd-quit.c @@ -10,32 +10,46 @@ * QUIT command */ -struct cmd_quit_context { +struct relay_cmd_quit_context { struct client *client; struct smtp_server_cmd_ctx *cmd; struct smtp_client_command *cmd_proxied; }; -static void cmd_quit_finish(struct cmd_quit_context *quit_cmd) +static void +relay_cmd_quit_destroy(struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, + struct relay_cmd_quit_context *quit_cmd) +{ + if (quit_cmd->cmd_proxied != NULL) + smtp_client_command_abort(&quit_cmd->cmd_proxied); +} + +static void +relay_cmd_quit_replied(struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, + struct relay_cmd_quit_context *quit_cmd) +{ + if (quit_cmd->cmd_proxied != NULL) + smtp_client_command_abort(&quit_cmd->cmd_proxied); +} + +static void relay_cmd_quit_finish(struct relay_cmd_quit_context *quit_cmd) { - struct client *client = quit_cmd->client; struct smtp_server_cmd_ctx *cmd = quit_cmd->cmd; - timeout_remove(&client->to_quit); if (quit_cmd->cmd_proxied != NULL) smtp_client_command_abort(&quit_cmd->cmd_proxied); smtp_server_reply_quit(cmd); } -static void cmd_quit_proxy_cb( - const struct smtp_reply *proxy_reply ATTR_UNUSED, - struct cmd_quit_context *quit_cmd) +static void +relay_cmd_quit_proxy_cb(const struct smtp_reply *proxy_reply ATTR_UNUSED, + struct relay_cmd_quit_context *quit_cmd) { quit_cmd->cmd_proxied = NULL; - cmd_quit_finish(quit_cmd); + relay_cmd_quit_finish(quit_cmd); } -static void cmd_quit_proxy(struct cmd_quit_context *quit_cmd) +static void relay_cmd_quit_proxy(struct relay_cmd_quit_context *quit_cmd) { struct client *client = quit_cmd->client; struct smtp_server_cmd_ctx *cmd = quit_cmd->cmd; @@ -59,27 +73,64 @@ static void cmd_quit_proxy(struct cmd_quit_context *quit_cmd) command). */ quit_cmd->cmd_proxied = smtp_client_command_new(client->proxy_conn, 0, - cmd_quit_proxy_cb, quit_cmd); + relay_cmd_quit_proxy_cb, quit_cmd); smtp_client_command_write(quit_cmd->cmd_proxied, "QUIT"); smtp_client_command_submit(quit_cmd->cmd_proxied); } static void -cmd_quit_next(struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, - struct cmd_quit_context *quit_cmd) +relay_cmd_quit_next(struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, + struct relay_cmd_quit_context *quit_cmd) +{ + /* QUIT command is next to reply */ + relay_cmd_quit_proxy(quit_cmd); +} + +int cmd_quit_relay(struct client *client, struct smtp_server_cmd_ctx *cmd) +{ + struct relay_cmd_quit_context *quit_cmd; + + quit_cmd = p_new(cmd->pool, struct relay_cmd_quit_context, 1); + quit_cmd->client = client; + quit_cmd->cmd = cmd; + + smtp_server_command_add_hook(cmd->cmd, SMTP_SERVER_COMMAND_HOOK_NEXT, + relay_cmd_quit_next, quit_cmd); + smtp_server_command_add_hook(cmd->cmd, SMTP_SERVER_COMMAND_HOOK_REPLIED, + relay_cmd_quit_replied, quit_cmd); + smtp_server_command_add_hook(cmd->cmd, SMTP_SERVER_COMMAND_HOOK_DESTROY, + relay_cmd_quit_destroy, quit_cmd); + + if (smtp_client_connection_get_state(client->proxy_conn) + >= SMTP_CLIENT_CONNECTION_STATE_READY) + relay_cmd_quit_proxy(quit_cmd); + return 0; +} + +struct cmd_quit_context { + struct client *client; + + struct smtp_server_cmd_ctx *cmd; +}; + +static void cmd_quit_finish(struct cmd_quit_context *quit_cmd) { struct client *client = quit_cmd->client; + struct smtp_server_cmd_ctx *cmd = quit_cmd->cmd; - /* QUIT command is next to reply */ + timeout_remove(&client->to_quit); + smtp_server_reply_quit(cmd); +} - cmd_quit_proxy(quit_cmd); +static void +cmd_quit_next(struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, + struct cmd_quit_context *quit_cmd) +{ + struct client *client = quit_cmd->client; - if (quit_cmd->cmd_proxied != NULL) { - /* give relay server brief interval to reply */ - client->to_quit = timeout_add( - SUBMISSION_MAX_WAIT_QUIT_REPLY_MSECS, - cmd_quit_finish, quit_cmd); - } + /* give backend a brief interval to generate a quit reply */ + client->to_quit = timeout_add(SUBMISSION_MAX_WAIT_QUIT_REPLY_MSECS, + cmd_quit_finish, quit_cmd); } int cmd_quit(void *conn_ctx, struct smtp_server_cmd_ctx *cmd) @@ -94,8 +145,6 @@ int cmd_quit(void *conn_ctx, struct smtp_server_cmd_ctx *cmd) smtp_server_command_add_hook(cmd->cmd, SMTP_SERVER_COMMAND_HOOK_NEXT, cmd_quit_next, quit_cmd); - if (smtp_client_connection_get_state(client->proxy_conn) - >= SMTP_CLIENT_CONNECTION_STATE_READY) - cmd_quit_proxy(quit_cmd); - return 0; + return cmd_quit_relay(client, cmd); } + diff --git a/src/submission/submission-commands.h b/src/submission/submission-commands.h index c5b0cc1584..cd8190662a 100644 --- a/src/submission/submission-commands.h +++ b/src/submission/submission-commands.h @@ -17,6 +17,7 @@ int cmd_data_relay(struct client *client, struct smtp_server_cmd_ctx *cmd, int cmd_vrfy_relay(struct client *client, struct smtp_server_cmd_ctx *cmd, const char *param); int cmd_noop_relay(struct client *client, struct smtp_server_cmd_ctx *cmd); +int cmd_quit_relay(struct client *client, struct smtp_server_cmd_ctx *cmd); void submission_helo_reply_submit(struct smtp_server_cmd_ctx *cmd, struct smtp_server_cmd_helo *data); -- 2.47.3