]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm: Refactor server/client code to support versioning properly
authorAki Tuomi <aki.tuomi@dovecot.fi>
Thu, 24 Aug 2017 11:45:22 +0000 (14:45 +0300)
committerTimo Sirainen <tss@dovecot.fi>
Thu, 5 Oct 2017 10:58:28 +0000 (13:58 +0300)
This way we can distinguish between old and new server side

src/doveadm/client-connection.c
src/doveadm/doveadm-util.h
src/doveadm/server-connection.c

index 0692bed268968553c19846d7fde1077ad44d4aa9..187695a78ee4d6bdb80b167bcc05f3a33e7bc73b 100644 (file)
@@ -388,6 +388,7 @@ static void client_connection_input(struct client_connection *conn)
        const char *line;
        bool ok = TRUE;
        int ret;
+       unsigned int minor;
 
        if (!conn->handshaked) {
                if ((line = i_stream_read_next_line(conn->input)) == NULL) {
@@ -397,14 +398,19 @@ static void client_connection_input(struct client_connection *conn)
                        }
                        return;
                }
-
-               if (!version_string_verify(line, "doveadm-server",
-                               DOVEADM_SERVER_PROTOCOL_VERSION_MAJOR)) {
+               if (!version_string_verify_full(line, "doveadm-server",
+                               DOVEADM_SERVER_PROTOCOL_VERSION_MAJOR, &minor)) {
                        i_error("doveadm client not compatible with this server "
                                "(mixed old and new binaries?)");
                        client_connection_destroy(&conn);
                        return;
                }
+               if (minor > 0) {
+                       /* send version reply */
+                       o_stream_nsend_str(conn->output,
+                                          DOVEADM_CLIENT_PROTOCOL_VERSION_LINE"\n");
+                       conn->use_multiplex = TRUE;
+               }
                conn->handshaked = TRUE;
        }
        if (!conn->authenticated) {
@@ -417,6 +423,7 @@ static void client_connection_input(struct client_connection *conn)
                }
                o_stream_nsend(conn->output, "+\n", 2);
                conn->authenticated = TRUE;
+               doveadm_print_ostream = conn->output;
        }
 
        if (!conn->io_setup) {
@@ -554,7 +561,6 @@ client_connection_create(int fd, int listen_fd, bool ssl)
        client_connection_send_auth_handshake(conn, listen_fd);
        client_connection_set_proctitle(conn, "");
 
-       doveadm_print_ostream = conn->output;
        return conn;
 }
 
index 54fdf60d7ca62a6a51da928d2dfb078212e37c9f..62a5630f0bc29c5323bf9bde9ab376f62b6c15cb 100644 (file)
@@ -6,6 +6,7 @@
 #define DOVEADM_SERVER_PROTOCOL_VERSION_MAJOR 1
 #define DOVEADM_SERVER_PROTOCOL_VERSION_MINOR 0
 #define DOVEADM_SERVER_PROTOCOL_VERSION_LINE "VERSION\tdoveadm-server\t1\t0"
+#define DOVEADM_CLIENT_PROTOCOL_VERSION_LINE "VERSION\tdoveadm-client\t1\t0"
 
 extern bool doveadm_verbose, doveadm_debug, doveadm_server;
 
index a0a6de74080c251ac06474729d1a2a98594245fc..ab76e8dcbc57f780a0bc14ac616e761fda23e90c 100644 (file)
@@ -39,6 +39,8 @@ struct server_connection {
        struct doveadm_settings *set;
 
        int fd;
+       unsigned int minor;
+
        struct io *io;
        struct istream *input;
        struct ostream *output;
@@ -309,6 +311,16 @@ static void server_connection_input(struct server_connection *conn)
 
        if (!conn->handshaked || !conn->authenticated) {
                while((line = i_stream_read_next_line(conn->input)) != NULL) {
+                       if (strncmp(line, "VERSION\t", 8) == 0) {
+                               if (!version_string_verify_full(line, "doveadm-client",
+                                                               DOVEADM_SERVER_PROTOCOL_VERSION_MAJOR,
+                                                               &conn->minor)) {
+                                       i_error("doveadm server not compatible with this client"
+                                               "(mixed old and new binaries?)");
+                                       server_connection_destroy(&conn);
+                               }
+                               continue;
+                       }
                        if (strcmp(line, "+") == 0) {
                                server_connection_authenticated(conn);
                                break;
@@ -481,7 +493,6 @@ static int server_connection_init_ssl(struct server_connection *conn)
 int server_connection_create(struct doveadm_server *server,
                             struct server_connection **conn_r)
 {
-#define DOVEADM_SERVER_HANDSHAKE "VERSION\tdoveadm-server\t1\t0\n"
        struct server_connection *conn;
        pool_t pool;
 
@@ -492,8 +503,8 @@ int server_connection_create(struct doveadm_server *server,
        conn->fd = doveadm_connect_with_default_port(server->name,
                                                     doveadm_settings->doveadm_port);
        net_set_nonblock(conn->fd, TRUE);
-       conn->io = io_add(conn->fd, IO_READ, server_connection_input, conn);
        conn->input = i_stream_create_fd(conn->fd, MAX_INBUF_SIZE);
+       conn->io = io_add_istream(conn->input, server_connection_input, conn);
        conn->output = o_stream_create_fd(conn->fd, (size_t)-1);
        o_stream_set_flush_callback(conn->output, server_connection_output, conn);
 
@@ -510,7 +521,7 @@ int server_connection_create(struct doveadm_server *server,
 
        o_stream_set_no_error_handling(conn->output, TRUE);
        conn->state = SERVER_REPLY_STATE_DONE;
-       o_stream_nsend_str(conn->output, DOVEADM_SERVER_HANDSHAKE);
+       o_stream_nsend_str(conn->output, DOVEADM_SERVER_PROTOCOL_VERSION_LINE"\n");
 
        *conn_r = conn;
        return 0;