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