From: Stephan Bosch Date: Wed, 29 Aug 2018 22:26:03 +0000 (+0200) Subject: submission: Move relay part of QUIT command to submission-backend-relay.c. X-Git-Tag: 2.3.9~1328 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b7cceeef8326fd69b6233ac323ffe10afbe4421c;p=thirdparty%2Fdovecot%2Fcore.git submission: Move relay part of QUIT command to submission-backend-relay.c. --- diff --git a/src/submission/Makefile.am b/src/submission/Makefile.am index 3121552b8d..0b92fad66d 100644 --- a/src/submission/Makefile.am +++ b/src/submission/Makefile.am @@ -33,11 +33,7 @@ submission_DEPENDENCIES = \ $(LIBDOVECOT_STORAGE_DEPS) \ $(LIBDOVECOT_DEPS) -cmds = \ - cmd-quit.c - submission_SOURCES = \ - $(cmds) \ main.c \ submission-backend-relay.c \ submission-client.c \ diff --git a/src/submission/cmd-quit.c b/src/submission/cmd-quit.c deleted file mode 100644 index 9d06c5d43d..0000000000 --- a/src/submission/cmd-quit.c +++ /dev/null @@ -1,108 +0,0 @@ -/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */ - -#include "submission-common.h" -#include "smtp-client.h" -#include "smtp-client-connection.h" - -#include "submission-commands.h" - -/* - * QUIT command - */ - -struct relay_cmd_quit_context { - struct client *client; - struct smtp_server_cmd_ctx *cmd; - struct smtp_client_command *cmd_proxied; -}; - -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 smtp_server_cmd_ctx *cmd = quit_cmd->cmd; - - if (quit_cmd->cmd_proxied != NULL) - smtp_client_command_abort(&quit_cmd->cmd_proxied); - smtp_server_reply_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; - relay_cmd_quit_finish(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; - - if (quit_cmd->cmd_proxied != NULL) - return; - - if (smtp_client_connection_get_state(client->proxy_conn) - < SMTP_CLIENT_CONNECTION_STATE_READY) { - /* Don't bother proxying QUIT command when proxy is not - fully initialized. */ - smtp_server_reply_quit(cmd); - return; - } - - /* RFC 5321, Section 4.1.1.10: - - The sender MUST NOT intentionally close the transmission channel - until it sends a QUIT command, and it SHOULD wait until it receives - the reply (even if there was an error response to a previous - command). */ - quit_cmd->cmd_proxied = - smtp_client_command_new(client->proxy_conn, 0, - 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 -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; -} diff --git a/src/submission/submission-backend-relay.c b/src/submission/submission-backend-relay.c index 88b7e9a0f2..d1410666f5 100644 --- a/src/submission/submission-backend-relay.c +++ b/src/submission/submission-backend-relay.c @@ -576,3 +576,104 @@ int cmd_noop_relay(struct client *client, struct smtp_server_cmd_ctx *cmd) (client->proxy_conn, 0, cmd_noop_proxy_cb, noop_cmd); return 0; } + +/* + * QUIT command + */ + +struct relay_cmd_quit_context { + struct client *client; + struct smtp_server_cmd_ctx *cmd; + struct smtp_client_command *cmd_proxied; +}; + +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 smtp_server_cmd_ctx *cmd = quit_cmd->cmd; + + if (quit_cmd->cmd_proxied != NULL) + smtp_client_command_abort(&quit_cmd->cmd_proxied); + smtp_server_reply_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; + relay_cmd_quit_finish(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; + + if (quit_cmd->cmd_proxied != NULL) + return; + + if (smtp_client_connection_get_state(client->proxy_conn) + < SMTP_CLIENT_CONNECTION_STATE_READY) { + /* Don't bother proxying QUIT command when proxy is not + fully initialized. */ + smtp_server_reply_quit(cmd); + return; + } + + /* RFC 5321, Section 4.1.1.10: + + The sender MUST NOT intentionally close the transmission channel + until it sends a QUIT command, and it SHOULD wait until it receives + the reply (even if there was an error response to a previous + command). */ + quit_cmd->cmd_proxied = + smtp_client_command_new(client->proxy_conn, 0, + 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 +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; +} diff --git a/src/submission/submission-backend-relay.h b/src/submission/submission-backend-relay.h index 9f2cc258a3..14dc38fe6b 100644 --- a/src/submission/submission-backend-relay.h +++ b/src/submission/submission-backend-relay.h @@ -14,5 +14,6 @@ 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); #endif diff --git a/src/submission/submission-commands.h b/src/submission/submission-commands.h index 4d3e990415..79afe1cce6 100644 --- a/src/submission/submission-commands.h +++ b/src/submission/submission-commands.h @@ -4,8 +4,6 @@ bool client_command_handle_proxy_reply(struct client *client, const struct smtp_reply *reply, struct smtp_reply *reply_r); -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); int cmd_helo(void *conn_ctx, struct smtp_server_cmd_ctx *cmd,