]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-master, global: Replace master_service_anvil_send() with explicit connect/disconn...
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Sun, 12 Dec 2021 22:56:12 +0000 (00:56 +0200)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 8 Feb 2022 09:48:24 +0000 (10:48 +0100)
src/imap-hibernate/imap-client.c
src/imap/imap-client.c
src/lib-master/master-service.c
src/lib-master/master-service.h
src/lib-storage/mail-user.c
src/lib-storage/mail-user.h
src/lmtp/lmtp-local.c
src/pop3/pop3-client.c
src/submission/submission-client.c

index 4713de455a0e31f2f4837df7eb058108baca838c..8ae59240dfcdb0f6ae96a6ed3c3b5f09100abd0c 100644 (file)
@@ -565,14 +565,6 @@ static void imap_client_io_deactivate_user(struct imap_client *client ATTR_UNUSE
        i_set_failure_prefix("imap-hibernate: ");
 }
 
-static const char *imap_client_get_anvil_userip_ident(struct imap_client_state *state)
-{
-       if (state->remote_ip.family == 0)
-               return NULL;
-       return t_strconcat(net_ip2addr(&state->remote_ip), "/",
-                          str_tabescape(state->username), NULL);
-}
-
 struct imap_client *
 imap_client_create(int fd, const struct imap_client_state *state)
 {
@@ -583,7 +575,7 @@ imap_client_create(int fd, const struct imap_client_state *state)
        struct imap_client *client;
        pool_t pool = pool_alloconly_create("imap client", 256);
        void *statebuf;
-       const char *ident, *error;
+       const char *error;
 
        i_assert(state->username != NULL);
        i_assert(state->mail_log_prefix != NULL);
@@ -638,12 +630,13 @@ imap_client_create(int fd, const struct imap_client_state *state)
                client->log_prefix = p_strdup(pool, str_c(str));
        } T_END;
 
-       ident = imap_client_get_anvil_userip_ident(&client->state);
-       if (ident != NULL) {
-               if (master_service_anvil_send(master_service, t_strconcat(
-                       "CONNECT\t", my_pid, "\timap/", ident, "\n", NULL)))
-                       client->state.anvil_sent = TRUE;
-       }
+       struct master_service_anvil_session anvil_session = {
+               .username = client->state.username,
+               .service_name = "imap",
+               .ip = client->state.remote_ip,
+       };
+       if (master_service_anvil_connect(master_service, &anvil_session))
+               client->state.anvil_sent = TRUE;
 
        p_array_init(&client->notifys, pool, 2);
        DLLIST_PREPEND(&imap_clients, client);
@@ -685,10 +678,12 @@ void imap_client_destroy(struct imap_client **_client, const char *reason)
        }
 
        if (client->state.anvil_sent) {
-               master_service_anvil_send(master_service, t_strconcat(
-                       "DISCONNECT\t", my_pid, "\timap/",
-                       imap_client_get_anvil_userip_ident(&client->state),
-                       "\n", NULL));
+               struct master_service_anvil_session anvil_session = {
+                       .username = client->state.username,
+                       .service_name = "imap",
+                       .ip = client->state.remote_ip,
+               };
+               master_service_anvil_disconnect(master_service, &anvil_session);
        }
 
        if (client->master_conn != NULL)
index 5592b51db1db993a61b857fd0668d95af6fb6b26..d842d6c7653d62cead70bc204aee06083c2abb57 100644 (file)
@@ -118,7 +118,6 @@ struct client *client_create(int fd_in, int fd_out,
 {
        const struct mail_storage_settings *mail_set;
        struct client *client;
-       const char *ident;
        pool_t pool;
 
        /* always use nonblocking I/O */
@@ -203,12 +202,10 @@ struct client *client_create(int fd_in, int fd_out,
                client_add_capability(client, "SPECIAL-USE");
        }
 
-       ident = mail_user_get_anvil_userip_ident(client->user);
-       if (ident != NULL) {
-               if (master_service_anvil_send(master_service, t_strconcat(
-                       "CONNECT\t", my_pid, "\timap/", ident, "\n", NULL)))
-                       client->anvil_sent = TRUE;
-       }
+       struct master_service_anvil_session anvil_session;
+       mail_user_get_anvil_session(client->user, &anvil_session);
+       if (master_service_anvil_connect(master_service, &anvil_session))
+               client->anvil_sent = TRUE;
 
        imap_client_count++;
        DLLIST_PREPEND(&imap_clients, client);
@@ -493,10 +490,9 @@ static void client_default_destroy(struct client *client, const char *reason)
        if (client->mailbox != NULL)
                imap_client_close_mailbox(client);
        if (client->anvil_sent) {
-               master_service_anvil_send(master_service, t_strconcat(
-                       "DISCONNECT\t", my_pid, "\timap/",
-                       mail_user_get_anvil_userip_ident(client->user),
-                       "\n", NULL));
+               struct master_service_anvil_session anvil_session;
+               mail_user_get_anvil_session(client->user, &anvil_session);
+               master_service_anvil_disconnect(master_service, &anvil_session);
        }
 
        if (client->free_parser != NULL)
index fcad69109389d0a0a62b0984218742aad7464430..f47f7d8a09d22ef9e921d978da22fa2d9880f445 100644 (file)
@@ -8,6 +8,7 @@
 #include "hostpid.h"
 #include "path-util.h"
 #include "array.h"
+#include "str.h"
 #include "strescape.h"
 #include "env-util.h"
 #include "home-expand.h"
@@ -920,7 +921,8 @@ bool master_service_is_master_stopped(struct master_service *service)
                (service->flags & MASTER_SERVICE_FLAG_STANDALONE) == 0;
 }
 
-bool master_service_anvil_send(struct master_service *service, const char *cmd)
+static bool
+master_service_anvil_send(struct master_service *service, const char *cmd)
 {
        ssize_t ret;
 
@@ -945,6 +947,40 @@ bool master_service_anvil_send(struct master_service *service, const char *cmd)
        }
 }
 
+static void
+master_service_anvil_session_to_cmd(string_t *cmd,
+       const struct master_service_anvil_session *session)
+{
+       str_printfa(cmd, "%s\t", my_pid);
+       str_append_tabescaped(cmd, session->service_name);
+       if (session->ip.family != 0) {
+               str_append_c(cmd, '/');
+               str_append(cmd, net_ip2addr(&session->ip));
+       }
+       str_append_c(cmd, '/');
+       str_append_tabescaped(cmd, session->username);
+}
+
+bool master_service_anvil_connect(struct master_service *service,
+       const struct master_service_anvil_session *session)
+{
+       string_t *cmd = t_str_new(128);
+       str_append(cmd, "CONNECT\t");
+       master_service_anvil_session_to_cmd(cmd, session);
+       str_append_c(cmd, '\n');
+       return master_service_anvil_send(service, str_c(cmd));
+}
+
+void master_service_anvil_disconnect(struct master_service *service,
+       const struct master_service_anvil_session *session)
+{
+       string_t *cmd = t_str_new(128);
+       str_append(cmd, "DISCONNECT\t");
+       master_service_anvil_session_to_cmd(cmd, session);
+       str_append_c(cmd, '\n');
+       (void)master_service_anvil_send(service, str_c(cmd));
+}
+
 void master_service_client_connection_created(struct master_service *service)
 {
        i_assert(service->master_status.available_count > 0);
index efb90d4b7f244b99cedcbadd4e1c82c68cd196ec..4c065bb91f455a7095c2afc374cb8243d4366828 100644 (file)
@@ -92,6 +92,12 @@ struct master_service_connection {
        bool accepted:1;
 };
 
+struct master_service_anvil_session {
+       const char *username;
+       const char *service_name;
+       struct ip_addr ip;
+};
+
 typedef void
 master_service_connection_callback_t(struct master_service_connection *conn);
 
@@ -225,9 +231,13 @@ bool master_service_is_killed(struct master_service *service);
    standalone. */
 bool master_service_is_master_stopped(struct master_service *service);
 
-/* Send command to anvil process, if we have fd to it. Returns TRUE if it was
-   successfully sent. */
-bool master_service_anvil_send(struct master_service *service, const char *cmd);
+/* Send CONNECT command to anvil process, if it's still connected.
+   Returns TRUE if it was successfully sent. */
+bool master_service_anvil_connect(struct master_service *service,
+       const struct master_service_anvil_session *session);
+/* Send DISCONNECT command to anvil process, if it's still connected. */
+void master_service_anvil_disconnect(struct master_service *service,
+       const struct master_service_anvil_session *session);
 /* Call to accept the client connection. Otherwise the connection is closed. */
 void master_service_client_connection_accept(struct master_service_connection *conn);
 /* Used to create "extra client connections" outside the common accept()
index 9cf60424a5c34b1da619af474fed98b6296d05e3..85cd3551878bac9487f33482b205b66e0e748d64 100644 (file)
@@ -640,12 +640,14 @@ int mail_user_lock_file_create(struct mail_user *user, const char *lock_fname,
        return mail_storage_lock_create(path, &lock_set, mail_set, lock_r, error_r);
 }
 
-const char *mail_user_get_anvil_userip_ident(struct mail_user *user)
+void mail_user_get_anvil_session(struct mail_user *user,
+                                struct master_service_anvil_session *session_r)
 {
-       if (user->conn.remote_ip == NULL)
-               return NULL;
-       return t_strconcat(net_ip2addr(user->conn.remote_ip), "/",
-                          str_tabescape(user->username), NULL);
+       i_zero(session_r);
+       session_r->username = user->username;
+       session_r->service_name = master_service_get_name(master_service);
+       if (user->conn.remote_ip != NULL)
+               session_r->ip = *user->conn.remote_ip;
 }
 
 static void
index ef833d1bd101af47c5a91ce7f89104dbc0fe6574..f442d9396ab1bf88ec01b703182d50b6c1a018e0 100644 (file)
@@ -10,6 +10,7 @@ struct module;
 struct stats;
 struct fs_settings;
 struct ssl_iostream_settings;
+struct master_service_anvil_session;
 struct mail_user;
 struct dict_op_settings;
 
@@ -200,8 +201,9 @@ void mail_user_drop_useless_namespaces(struct mail_user *user);
 const char *mail_user_home_expand(struct mail_user *user, const char *path);
 /* Returns 0 if ok, -1 if home directory isn't set. */
 int mail_user_try_home_expand(struct mail_user *user, const char **path);
-/* Returns unique user+ip identifier for anvil. */
-const char *mail_user_get_anvil_userip_ident(struct mail_user *user);
+/* Fill out anvil session struct for the user session. */
+void mail_user_get_anvil_session(struct mail_user *user,
+                                struct master_service_anvil_session *session_r);
 
 /* Basically the same as mail_storage_find_class(), except automatically load
    storage plugins when needed. */
index 202fbb2c4f771d376defdc609f09ee7807963fb6..7c685553da3327d81aca337b8b9a0ed465a8a417 100644 (file)
@@ -97,9 +97,11 @@ lmtp_local_rcpt_anvil_disconnect(struct lmtp_local_recipient *llrcpt)
        llrcpt->anvil_connect_sent = FALSE;
 
        input = mail_storage_service_user_get_input(llrcpt->service_user);
-       master_service_anvil_send(master_service, t_strconcat(
-               "DISCONNECT\t", my_pid, "\t", master_service_get_name(master_service),
-               "/", input->username, "\n", NULL));
+       struct master_service_anvil_session anvil_session = {
+               .username = input->username,
+               .service_name = master_service_get_name(master_service),
+       };
+       master_service_anvil_disconnect(master_service, &anvil_session);
 }
 
 static void
@@ -274,9 +276,11 @@ lmtp_local_rcpt_anvil_cb(const char *reply, void *context)
                        "Too many concurrent deliveries for user");
        } else if (lmtp_local_rcpt_anvil_finish(llrcpt)) {
                input = mail_storage_service_user_get_input(llrcpt->service_user);
-               if (master_service_anvil_send(master_service, t_strconcat(
-                       "CONNECT\t", my_pid, "\t", master_service_get_name(master_service),
-                       "/", input->username, "\n", NULL)))
+               struct master_service_anvil_session anvil_session = {
+                       .username = input->username,
+                       .service_name = master_service_get_name(master_service),
+               };
+               if (master_service_anvil_connect(master_service, &anvil_session))
                        llrcpt->anvil_connect_sent = TRUE;
        }
 }
index e0c8c589a395efc3fc077bb6662baf436d7f0649..09d927175f4c87b00458103388043a8a373fba78 100644 (file)
@@ -448,7 +448,7 @@ void client_create_finish(struct client *client)
 int client_init_mailbox(struct client *client, const char **error_r)
 {
         enum mailbox_flags flags;
-       const char *ident, *errmsg;
+       const char *errmsg;
 
        /* refresh proctitle before a potentially long-running init_mailbox() */
        pop3_refresh_proctitle();
@@ -473,12 +473,10 @@ int client_init_mailbox(struct client *client, const char **error_r)
        if (!client->set->pop3_no_flag_updates && client->messages_count > 0)
                client->seen_bitmask = i_malloc(MSGS_BITMASK_SIZE(client));
 
-       ident = mail_user_get_anvil_userip_ident(client->user);
-       if (ident != NULL) {
-               if (master_service_anvil_send(master_service, t_strconcat(
-                       "CONNECT\t", my_pid, "\tpop3/", ident, "\n", NULL)))
-                       client->anvil_sent = TRUE;
-       }
+       struct master_service_anvil_session anvil_session;
+       mail_user_get_anvil_session(client->user, &anvil_session);
+       if (master_service_anvil_connect(master_service, &anvil_session))
+               client->anvil_sent = TRUE;
        return 0;
 }
 
@@ -604,10 +602,9 @@ static void client_default_destroy(struct client *client, const char *reason)
        if (client->mailbox != NULL)
                mailbox_free(&client->mailbox);
        if (client->anvil_sent) {
-               master_service_anvil_send(master_service, t_strconcat(
-                       "DISCONNECT\t", my_pid, "\tpop3/",
-                       mail_user_get_anvil_userip_ident(client->user),
-                       "\n", NULL));
+               struct master_service_anvil_session anvil_session;
+               mail_user_get_anvil_session(client->user, &anvil_session);
+               master_service_anvil_disconnect(master_service, &anvil_session);
        }
 
        if (client->session_dotlock != NULL)
index a0f0a0efa393cf9feaf7fbff500a795a15d95df4..a2d1914413130312a9851ade3c3ff3c6bb364e70 100644 (file)
@@ -186,7 +186,6 @@ client_create(int fd_in, int fd_out, struct mail_user *user,
                set->parsed_workarounds;
        const struct mail_storage_settings *mail_set;
        struct smtp_server_settings smtp_set;
-       const char *ident;
        struct client *client;
        pool_t pool;
 
@@ -249,14 +248,10 @@ client_create(int fd_in, int fd_out, struct mail_user *user,
        submission_client_count++;
        DLLIST_PREPEND(&submission_clients, client);
 
-       ident = mail_user_get_anvil_userip_ident(client->user);
-       if (ident != NULL) {
-               if (master_service_anvil_send(
-                       master_service, t_strconcat(
-                               "CONNECT\t", my_pid, "\tsubmission/", ident,
-                               "\n", NULL)))
-                       client->anvil_sent = TRUE;
-       }
+       struct master_service_anvil_session anvil_session;
+       mail_user_get_anvil_session(client->user, &anvil_session);
+       if (master_service_anvil_connect(master_service, &anvil_session))
+               client->anvil_sent = TRUE;
 
        if (hook_client_created != NULL)
                hook_client_created(&client);
@@ -316,11 +311,9 @@ client_default_destroy(struct client *client)
        DLLIST_REMOVE(&submission_clients, client);
 
        if (client->anvil_sent) {
-               master_service_anvil_send(
-                       master_service, t_strconcat(
-                               "DISCONNECT\t", my_pid, "\tsubmission/",
-                               mail_user_get_anvil_userip_ident(client->user),
-                               "\n", NULL));
+               struct master_service_anvil_session anvil_session;
+               mail_user_get_anvil_session(client->user, &anvil_session);
+               master_service_anvil_disconnect(master_service, &anvil_session);
        }
 
        if (client->urlauth_ctx != NULL)