changeset 22555:e05ab5f8a8bc

doveadm: Refactor server/client code to support versioning properly This way we can distinguish between old and new server side
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Thu, 24 Aug 2017 14:45:22 +0300
parents 8c27d8d766bd
children ba71422dc32f
files src/doveadm/client-connection.c src/doveadm/doveadm-util.h src/doveadm/server-connection.c
diffstat 3 files changed, 24 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/doveadm/client-connection.c	Tue Sep 12 13:43:30 2017 +0300
+++ b/src/doveadm/client-connection.c	Thu Aug 24 14:45:22 2017 +0300
@@ -392,6 +392,7 @@
 	const char *line;
 	bool ok = TRUE;
 	int ret;
+	unsigned int minor;
 
 	if (!conn->handshaked) {
 		if ((line = i_stream_read_next_line(conn->input)) == NULL) {
@@ -401,14 +402,19 @@
 			}
 			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) {
@@ -421,6 +427,7 @@
 		}
 		o_stream_nsend(conn->output, "+\n", 2);
 		conn->authenticated = TRUE;
+		doveadm_print_ostream = conn->output;
 	}
 
 	if (!conn->io_setup) {
@@ -558,7 +565,6 @@
 	client_connection_send_auth_handshake(conn, listen_fd);
 	client_connection_set_proctitle(conn, "");
 
-	doveadm_print_ostream = conn->output;
 	return conn;
 }
 
--- a/src/doveadm/doveadm-util.h	Tue Sep 12 13:43:30 2017 +0300
+++ b/src/doveadm/doveadm-util.h	Thu Aug 24 14:45:22 2017 +0300
@@ -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;
 
--- a/src/doveadm/server-connection.c	Tue Sep 12 13:43:30 2017 +0300
+++ b/src/doveadm/server-connection.c	Thu Aug 24 14:45:22 2017 +0300
@@ -39,6 +39,8 @@
 	struct doveadm_settings *set;
 
 	int fd;
+	unsigned int minor;
+
 	struct io *io;
 	struct istream *input;
 	struct ostream *output;
@@ -298,6 +300,16 @@
 
 	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;
@@ -472,7 +484,6 @@
 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;
 
@@ -501,7 +512,7 @@
 
 	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;