* 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;
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)
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);
}
+