From: Timo Sirainen Date: Mon, 24 Oct 2016 18:58:03 +0000 (+0300) Subject: director: If SYNCs are received during handshake, send them later. X-Git-Tag: 2.2.26~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=827bb6585dd19964eccba2a78a1ba3d8971bdfd0;p=thirdparty%2Fdovecot%2Fcore.git director: If SYNCs are received during handshake, send them later. This fixes delays during handshake: Error: Ring SYNC appears to have got lost, resending --- diff --git a/src/director/director-connection.c b/src/director/director-connection.c index 0bab7c4731..973d1d051b 100644 --- a/src/director/director-connection.c +++ b/src/director/director-connection.c @@ -316,6 +316,25 @@ static bool director_has_outgoing_connections(struct director *dir) return FALSE; } +static void director_send_delayed_syncs(struct director *dir) +{ + struct director_host *const *hostp; + + i_assert(dir->right != NULL); + + dir_debug("director(%s): Sending delayed SYNCs", dir->right->name); + array_foreach(&dir->dir_hosts, hostp) { + if ((*hostp)->delayed_sync_seq == 0) + continue; + + director_sync_send(dir, *hostp, (*hostp)->delayed_sync_seq, + (*hostp)->delayed_sync_minor_version, + (*hostp)->delayed_sync_timestamp, + (*hostp)->delayed_sync_hosts_hash); + (*hostp)->delayed_sync_seq = 0; + } +} + static bool director_connection_assign_right(struct director_connection *conn) { struct director *dir = conn->dir; @@ -343,6 +362,7 @@ static bool director_connection_assign_right(struct director_connection *conn) i_free(conn->name); conn->name = i_strdup_printf("%s/right", conn->host->name); director_connection_assigned(conn); + director_send_delayed_syncs(dir); return TRUE; } @@ -1422,6 +1442,13 @@ director_connection_sync_host(struct director_connection *conn, /* forward it to the connection on right */ director_sync_send(dir, host, seq, minor_version, timestamp, hosts_hash); + } else { + dir_debug("director(%s): We have no right connection - " + "delay replying to SYNC until finished", conn->name); + host->delayed_sync_seq = seq; + host->delayed_sync_minor_version = minor_version; + host->delayed_sync_timestamp = timestamp; + host->delayed_sync_hosts_hash = hosts_hash; } } return TRUE; diff --git a/src/director/director-host.h b/src/director/director-host.h index 08c1020da3..68979c259e 100644 --- a/src/director/director-host.h +++ b/src/director/director-host.h @@ -30,6 +30,14 @@ struct director_host { /* Last time host was detected to be down */ time_t last_network_failure; time_t last_protocol_failure; + + /* When we finish getting a right connection, send a SYNC with these + parameters (if delayed_sync_seq != 0) */ + uint32_t delayed_sync_seq; + unsigned int delayed_sync_minor_version; + unsigned int delayed_sync_timestamp; + unsigned int delayed_sync_hosts_hash; + /* we are this director */ unsigned int self:1; unsigned int removed:1;