]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
submission: Split the QUIT command into a generic part and a part related to relaying...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Wed, 29 Aug 2018 22:18:40 +0000 (00:18 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Tue, 9 Oct 2018 06:41:17 +0000 (06:41 +0000)
src/submission/cmd-quit.c
src/submission/submission-commands.h

index d77100eb07910715a0dbb2946e33cea4062273b9..0018614efbc7b369264cac7f1bed15f163e72750 100644 (file)
  * 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);
 }
+
index c5b0cc15847760d074dacb382e4e95339dddb339..cd8190662ae22290b6fd3f257ec4f7dfda1e17ce 100644 (file)
@@ -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);