From: Timo Sirainen Date: Mon, 8 Apr 2024 21:12:05 +0000 (+0300) Subject: login-common, imap: Allow imap process to handle multiplex ostream X-Git-Tag: 2.4.0~1579 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=58ca11e7fb71dcf04211c080c9015f6df0c0e016;p=thirdparty%2Fdovecot%2Fcore.git login-common, imap: Allow imap process to handle multiplex ostream --- diff --git a/src/imap/imap-client.c b/src/imap/imap-client.c index 2d4b9a6999..5427fa21f8 100644 --- a/src/imap/imap-client.c +++ b/src/imap/imap-client.c @@ -11,6 +11,7 @@ #include "istream.h" #include "istream-concat.h" #include "ostream.h" +#include "ostream-multiplex.h" #include "time-util.h" #include "var-expand.h" #include "settings.h" @@ -118,6 +119,13 @@ struct client *client_create(int fd_in, int fd_out, client->input = i_stream_create_fd(fd_in, set->imap_max_line_length); client->output = o_stream_create_fd(fd_out, SIZE_MAX); + if ((flags & CLIENT_CREATE_FLAG_MULTIPLEX_OUTPUT) != 0) { + client->multiplex_output = + o_stream_create_multiplex(client->output, SIZE_MAX, + OSTREAM_MULTIPLEX_FORMAT_STREAM_CONTINUE); + o_stream_unref(&client->output); + client->output = client->multiplex_output; + } o_stream_set_no_error_handling(client->output, TRUE); i_stream_set_name(client->input, ""); o_stream_set_name(client->output, ""); diff --git a/src/imap/imap-client.h b/src/imap/imap-client.h index 548e38fd4a..9017deb97b 100644 --- a/src/imap/imap-client.h +++ b/src/imap/imap-client.h @@ -20,6 +20,7 @@ struct imap_urlauth_context; enum client_create_flags { CLIENT_CREATE_FLAG_UNHIBERNATED = BIT(0), + CLIENT_CREATE_FLAG_MULTIPLEX_OUTPUT = BIT(1), }; struct mailbox_keywords { @@ -168,6 +169,7 @@ struct client { struct io *io; struct istream *input, *pre_rawlog_input, *post_rawlog_input; struct ostream *output, *pre_rawlog_output, *post_rawlog_output; + struct ostream *multiplex_output; struct timeout *to_idle, *to_idle_output, *to_delayed_input; guid_128_t anvil_conn_guid; diff --git a/src/imap/main.c b/src/imap/main.c index f9d05472b4..91a13ebce3 100644 --- a/src/imap/main.c +++ b/src/imap/main.c @@ -362,6 +362,7 @@ login_request_finished(const struct login_server_request *request, struct client *client; struct imap_login_request imap_request; enum login_request_flags flags = request->auth_req.flags; + enum client_create_flags create_flags = 0; const char *error; i_zero(&input); @@ -375,13 +376,15 @@ login_request_finished(const struct login_server_request *request, input.session_id = request->session_id; if ((flags & LOGIN_REQUEST_FLAG_END_CLIENT_SECURED_TLS) != 0) input.end_client_tls_secured = TRUE; + if ((flags & LOGIN_REQUEST_FLAG_MULTIPLEX_OUTPUT) != 0) + create_flags |= CLIENT_CREATE_FLAG_MULTIPLEX_OUTPUT; client_parse_imap_login_request(request->data, request->auth_req.data_size, &imap_request); if (client_create_from_input(&input, request->fd, request->fd, - 0, &client, &error) < 0) { + create_flags, &client, &error) < 0) { int fd = request->fd; struct ostream *output = o_stream_create_fd_autoclose(&fd, IO_BLOCK_SIZE); diff --git a/src/lib-login/login-interface.h b/src/lib-login/login-interface.h index 682231aeb9..eae04ba0a9 100644 --- a/src/lib-login/login-interface.h +++ b/src/lib-login/login-interface.h @@ -24,6 +24,8 @@ enum login_request_flags { LOGIN_REQUEST_FLAG_END_CLIENT_SECURED_TLS = BIT(2), /* This login is implicit; no command reply is expected */ LOGIN_REQUEST_FLAG_IMPLICIT = BIT(3), + /* The output stream is ostream-multiplex */ + LOGIN_REQUEST_FLAG_MULTIPLEX_OUTPUT = BIT(4), }; /* Login request. File descriptor may be sent along with the request. */ diff --git a/src/login-common/client-common.c b/src/login-common/client-common.c index 3ef60a7f1b..c052b33834 100644 --- a/src/login-common/client-common.c +++ b/src/login-common/client-common.c @@ -879,7 +879,7 @@ int client_get_plaintext_fd(struct client *client, int *fd_r, bool *close_fd_r) { int fds[2]; - if (client->ssl_iostream == NULL && client->multiplex_output == NULL) { + if (client->ssl_iostream == NULL) { /* Plaintext connection - We can send the fd directly to the post-login process without any proxying. */ *fd_r = client->fd; diff --git a/src/login-common/sasl-server.c b/src/login-common/sasl-server.c index ade2338c3b..4dd3bb7c93 100644 --- a/src/login-common/sasl-server.c +++ b/src/login-common/sasl-server.c @@ -178,6 +178,8 @@ static int master_send_request(struct anvil_request *anvil_request) req.local_port = client->local_port; req.remote_port = client->remote_port; req.client_pid = getpid(); + if (client->multiplex_output != NULL) + req.flags |= LOGIN_REQUEST_FLAG_MULTIPLEX_OUTPUT; if (client->ssl_iostream != NULL && ssl_iostream_get_compression(client->ssl_iostream) != NULL) req.flags |= LOGIN_REQUEST_FLAG_TLS_COMPRESSION;