dovecot-2.0: dsync: Fixed potential assert crashes with remote d...

dovecot at dovecot.org dovecot at dovecot.org
Mon Jul 19 17:42:25 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/e6f376a1c755
changeset: 11858:e6f376a1c755
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Jul 19 15:42:22 2010 +0100
description:
dsync: Fixed potential assert crashes with remote dsyncing.

diffstat:

 src/dsync/dsync-proxy-client.c |  82 +++++++++++++++++++---------------------
 1 files changed, 39 insertions(+), 43 deletions(-)

diffs (truncated from 306 to 300 lines):

diff -r 204eaf35e144 -r e6f376a1c755 src/dsync/dsync-proxy-client.c
--- a/src/dsync/dsync-proxy-client.c	Mon Jul 19 15:09:53 2010 +0100
+++ b/src/dsync/dsync-proxy-client.c	Mon Jul 19 15:42:22 2010 +0100
@@ -66,6 +66,7 @@
 	struct dsync_msg_static_data msg_get_data;
 	ARRAY_DEFINE(request_array, struct proxy_client_request);
 	struct aqueue *request_queue;
+	string_t *pending_commands;
 
 	unsigned int handshake_received:1;
 	unsigned int finishing:1;
@@ -363,6 +364,7 @@
 	fd_set_nonblock(fd_in, TRUE);
 	fd_set_nonblock(fd_out, TRUE);
 
+	worker->pending_commands = str_new(default_pool, 1024);
 	worker->msg_get_pool = pool_alloconly_create("dsync proxy msg", 128);
 	i_array_init(&worker->request_array, 64);
 	worker->request_queue = aqueue_init(&worker->request_array.arr);
@@ -391,6 +393,7 @@
 	aqueue_deinit(&worker->request_queue);
 	array_free(&worker->request_array);
 	pool_unref(&worker->msg_get_pool);
+	str_free(&worker->pending_commands);
 	i_free(worker);
 }
 
@@ -417,6 +420,7 @@
 {
 	struct proxy_client_dsync_worker *worker =
 		(struct proxy_client_dsync_worker *)_worker;
+	int ret = 1;
 
 	if (o_stream_flush(worker->output) < 0)
 		return -1;
@@ -424,8 +428,13 @@
 	o_stream_uncork(worker->output);
 	if (o_stream_get_buffer_used_size(worker->output) > 0)
 		return 0;
+
+	if (o_stream_send(worker->output, str_data(worker->pending_commands),
+			  str_len(worker->pending_commands)) < 0)
+		ret = -1;
+	str_truncate(worker->pending_commands, 0);
 	o_stream_cork(worker->output);
-	return 1;
+	return ret;
 }
 
 static struct dsync_worker_mailbox_iter *
@@ -439,7 +448,7 @@
 	iter->iter.worker = _worker;
 	iter->pool = pool_alloconly_create("proxy mailbox iter", 1024);
 	o_stream_send_str(worker->output, "BOX-LIST\n");
-	proxy_client_worker_output_flush(_worker);
+	(void)proxy_client_worker_output_flush(_worker);
 	return &iter->iter;
 }
 
@@ -502,7 +511,7 @@
 	iter->iter.worker = _worker;
 	iter->pool = pool_alloconly_create("proxy subscription iter", 1024);
 	o_stream_send_str(worker->output, "SUBS-LIST\n");
-	proxy_client_worker_output_flush(_worker);
+	(void)proxy_client_worker_output_flush(_worker);
 	return &iter->iter;
 }
 
@@ -650,7 +659,7 @@
 	o_stream_send(worker->output, str_data(str), str_len(str));
 	p_clear(iter->pool);
 
-	proxy_client_worker_output_flush(_worker);
+	(void)proxy_client_worker_output_flush(_worker);
 	return &iter->iter;
 }
 
@@ -719,21 +728,28 @@
 }
 
 static void
+proxy_client_worker_cmd(struct proxy_client_dsync_worker *worker, string_t *str)
+{
+	if (worker->save_input == NULL)
+		o_stream_send(worker->output, str_data(str), str_len(str));
+	else
+		str_append_str(worker->pending_commands, str);
+}
+
+static void
 proxy_client_worker_create_mailbox(struct dsync_worker *_worker,
 				   const struct dsync_mailbox *dsync_box)
 {
 	struct proxy_client_dsync_worker *worker =
 		(struct proxy_client_dsync_worker *)_worker;
 
-	i_assert(worker->save_input == NULL);
-
 	T_BEGIN {
 		string_t *str = t_str_new(128);
 
 		str_append(str, "BOX-CREATE\t");
 		dsync_proxy_mailbox_export(str, dsync_box);
 		str_append_c(str, '\n');
-		o_stream_send(worker->output, str_data(str), str_len(str));
+		proxy_client_worker_cmd(worker, str);
 	} T_END;
 }
 
@@ -744,15 +760,13 @@
 	struct proxy_client_dsync_worker *worker =
 		(struct proxy_client_dsync_worker *)_worker;
 
-	i_assert(worker->save_input == NULL);
-
 	T_BEGIN {
 		string_t *str = t_str_new(128);
 
 		str_append(str, "BOX-DELETE\t");
 		dsync_proxy_mailbox_guid_export(str, &dsync_box->mailbox_guid);
 		str_printfa(str, "\t%s\n", dec2str(dsync_box->last_change));
-		o_stream_send(worker->output, str_data(str), str_len(str));
+		proxy_client_worker_cmd(worker, str);
 	} T_END;
 }
 
@@ -763,15 +777,13 @@
 	struct proxy_client_dsync_worker *worker =
 		(struct proxy_client_dsync_worker *)_worker;
 
-	i_assert(worker->save_input == NULL);
-
 	T_BEGIN {
 		string_t *str = t_str_new(128);
 
 		str_append(str, "DIR-DELETE\t");
 		str_tabescape_write(str, dsync_box->name);
 		str_printfa(str, "\t%s\n", dec2str(dsync_box->last_change));
-		o_stream_send(worker->output, str_data(str), str_len(str));
+		proxy_client_worker_cmd(worker, str);
 	} T_END;
 }
 
@@ -784,8 +796,6 @@
 		(struct proxy_client_dsync_worker *)_worker;
 	char sep[2];
 
-	i_assert(worker->save_input == NULL);
-
 	T_BEGIN {
 		string_t *str = t_str_new(128);
 
@@ -797,7 +807,7 @@
 		sep[0] = dsync_box->name_sep; sep[1] = '\0';
 		str_tabescape_write(str, sep);
 		str_append_c(str, '\n');
-		o_stream_send(worker->output, str_data(str), str_len(str));
+		proxy_client_worker_cmd(worker, str);
 	} T_END;
 }
 
@@ -808,15 +818,13 @@
 	struct proxy_client_dsync_worker *worker =
 		(struct proxy_client_dsync_worker *)_worker;
 
-	i_assert(worker->save_input == NULL);
-
 	T_BEGIN {
 		string_t *str = t_str_new(128);
 
 		str_append(str, "BOX-UPDATE\t");
 		dsync_proxy_mailbox_export(str, dsync_box);
 		str_append_c(str, '\n');
-		o_stream_send(worker->output, str_data(str), str_len(str));
+		proxy_client_worker_cmd(worker, str);
 	} T_END;
 }
 
@@ -828,8 +836,6 @@
 	struct proxy_client_dsync_worker *worker =
 		(struct proxy_client_dsync_worker *)_worker;
 
-	i_assert(worker->save_input == NULL);
-
 	if (dsync_guid_equals(&worker->selected_box_guid, mailbox))
 		return;
 	worker->selected_box_guid = *mailbox;
@@ -842,7 +848,7 @@
 		if (cache_fields != NULL)
 			dsync_proxy_strings_export(str, cache_fields);
 		str_append_c(str, '\n');
-		o_stream_send(worker->output, str_data(str), str_len(str));
+		proxy_client_worker_cmd(worker, str);
 	} T_END;
 }
 
@@ -853,8 +859,6 @@
 	struct proxy_client_dsync_worker *worker =
 		(struct proxy_client_dsync_worker *)_worker;
 
-	i_assert(worker->save_input == NULL);
-
 	T_BEGIN {
 		string_t *str = t_str_new(128);
 
@@ -862,7 +866,7 @@
 			    (unsigned long long)msg->modseq);
 		imap_write_flags(str, msg->flags, msg->keywords);
 		str_append_c(str, '\n');
-		o_stream_send(worker->output, str_data(str), str_len(str));
+		proxy_client_worker_cmd(worker, str);
 	} T_END;
 }
 
@@ -873,12 +877,10 @@
 	struct proxy_client_dsync_worker *worker =
 		(struct proxy_client_dsync_worker *)_worker;
 
-	i_assert(worker->save_input == NULL);
-
 	T_BEGIN {
-		o_stream_send_str(worker->output,
-			t_strdup_printf("MSG-UID-CHANGE\t%u\t%u\n",
-					old_uid, new_uid));
+		string_t *str = t_str_new(64);
+		str_printfa(str, "MSG-UID-CHANGE\t%u\t%u\n", old_uid, new_uid);
+		proxy_client_worker_cmd(worker, str);
 	} T_END;
 }
 
@@ -888,11 +890,10 @@
 	struct proxy_client_dsync_worker *worker =
 		(struct proxy_client_dsync_worker *)_worker;
 
-	i_assert(worker->save_input == NULL);
-
 	T_BEGIN {
-		o_stream_send_str(worker->output,
-			t_strdup_printf("MSG-EXPUNGE\t%u\n", uid));
+		string_t *str = t_str_new(64);
+		str_printfa(str, "MSG-EXPUNGE\t%u\n", uid);
+		proxy_client_worker_cmd(worker, str);
 	} T_END;
 }
 
@@ -908,8 +909,6 @@
 		(struct proxy_client_dsync_worker *)_worker;
 	struct proxy_client_request request;
 
-	i_assert(worker->save_input == NULL);
-
 	T_BEGIN {
 		string_t *str = t_str_new(128);
 
@@ -918,7 +917,7 @@
 		str_printfa(str, "\t%u\t", src_uid);
 		dsync_proxy_msg_export(str, dest_msg);
 		str_append_c(str, '\n');
-		o_stream_send(worker->output, str_data(str), str_len(str));
+		proxy_client_worker_cmd(worker, str);
 	} T_END;
 
 	memset(&request, 0, sizeof(request));
@@ -976,6 +975,7 @@
 	callback = worker->save_callback;
 	worker->save_callback = NULL;
 	i_stream_unref(&worker->save_input);
+	(void)proxy_client_worker_output_flush(&worker->worker);
 
 	callback(worker->save_context);
 }
@@ -990,8 +990,6 @@
 	struct proxy_client_dsync_worker *worker =
 		(struct proxy_client_dsync_worker *)_worker;
 
-	i_assert(worker->save_input == NULL);
-
 	T_BEGIN {
 		string_t *str = t_str_new(128);
 
@@ -1000,7 +998,7 @@
 		str_append_c(str, '\t');
 		dsync_proxy_msg_export(str, msg);
 		str_append_c(str, '\n');
-		o_stream_send(worker->output, str_data(str), str_len(str));
+		proxy_client_worker_cmd(worker, str);
 	} T_END;
 
 	i_assert(worker->save_io == NULL);
@@ -1034,15 +1032,13 @@
 		(struct proxy_client_dsync_worker *)_worker;
 	struct proxy_client_request request;
 
-	i_assert(worker->save_input == NULL);
-
 	T_BEGIN {
 		string_t *str = t_str_new(128);
 
 		str_append(str, "MSG-GET\t");
 		dsync_proxy_mailbox_guid_export(str, mailbox);


More information about the dovecot-cvs mailing list