From 910239887e1c9e4ed816ece0a84448b4a8793b46 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= Date: Wed, 14 Oct 2020 11:50:26 +0200 Subject: [PATCH] BUG/MINOR: peers: Possible unexpected peer seesion reset after collisions. During a peers session collision (two peer sessions opened on both side) we must mark the peer the session of which will be shutdown as alive, if not ->reconnect timer will be set with a wrong value if the synchro task expires after the peer has been reconnected. This possibly leads to unexpected deconnections during handshakes. Furthermore, this patch cancels any heartbeat tranmimission when a reconnection is prepared. (cherry picked from commit 6e1a9c57c938360e95f445e800f0d22782bb6c22) Signed-off-by: Christopher Faulet --- src/peers.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/peers.c b/src/peers.c index 295798e..fb7f80f 100644 --- a/src/peers.c +++ b/src/peers.c @@ -796,8 +796,6 @@ void __peer_session_deinit(struct peer *peer) /* reset teaching and learning flags to 0 */ peer->flags &= PEER_TEACH_RESET; peer->flags &= PEER_LEARN_RESET; - /* set this peer as dead from heartbeat point of view */ - peer->flags &= ~PEER_F_ALIVE; task_wakeup(peers->sync_task, TASK_WOKEN_MSG); } @@ -817,6 +815,7 @@ static void peer_session_release(struct appctx *appctx) HA_SPIN_LOCK(PEER_LOCK, &peer->lock); if (peer->appctx == appctx) __peer_session_deinit(peer); + peer->flags &= ~PEER_F_ALIVE; HA_SPIN_UNLOCK(PEER_LOCK, &peer->lock); } } @@ -2125,6 +2124,7 @@ static inline void init_accepted_peer(struct peer *peer, struct peers *peers) { struct shared_table *st; + peer->heartbeat = tick_add(now_ms, MS_TO_TICKS(PEER_HEARTBEAT_TIMEOUT)); /* Register status code */ peer->statuscode = PEER_SESS_SC_SUCCESSCODE; @@ -2170,6 +2170,7 @@ static inline void init_connected_peer(struct peer *peer, struct peers *peers) { struct shared_table *st; + peer->heartbeat = tick_add(now_ms, MS_TO_TICKS(PEER_HEARTBEAT_TIMEOUT)); /* Init cursors */ for (st = peer->tables; st ; st = st->next) { st->last_get = st->last_acked = 0; @@ -2275,6 +2276,7 @@ switchstate: */ curpeer->reconnect = tick_add(now_ms, MS_TO_TICKS(50 + ha_random() % 2000)); peer_session_forceshutdown(curpeer); + curpeer->heartbeat = TICK_ETERNITY; } if (maj_ver != (unsigned int)-1 && min_ver != (unsigned int)-1) { if (min_ver == PEER_DWNGRD_MINOR_VER) { @@ -2285,6 +2287,7 @@ switchstate: } } curpeer->appctx = appctx; + curpeer->flags |= PEER_F_ALIVE; appctx->ctx.peers.ptr = curpeer; appctx->st0 = PEER_SESS_ST_SENDSUCCESS; _HA_ATOMIC_ADD(&active_peers, 1); @@ -2546,7 +2549,7 @@ static struct appctx *peer_session_create(struct peers *peers, struct peer *peer struct stream *s; peer->reconnect = tick_add(now_ms, MS_TO_TICKS(PEER_RECONNECT_TIMEOUT)); - peer->heartbeat = tick_add(now_ms, MS_TO_TICKS(PEER_HEARTBEAT_TIMEOUT)); + peer->heartbeat = TICK_ETERNITY; peer->statuscode = PEER_SESS_SC_CONNECTCODE; s = NULL; @@ -2727,6 +2730,7 @@ static struct task *process_peer_sync(struct task * task, void *context, unsigne } else { ps->reconnect = tick_add(now_ms, MS_TO_TICKS(50 + ha_random() % 2000)); + ps->heartbeat = TICK_ETERNITY; peer_session_forceshutdown(ps); ps->no_hbt++; } -- 1.7.10.4