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 <cfaulet@haproxy.com>
(cherry picked from commit 910239887e1c9e4ed816ece0a84448b4a8793b46)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/peers.c b/src/peers.c
index ea88a7e..ed0c11f 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -797,8 +797,6 @@
 	/* 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);
 }
 
@@ -818,6 +816,7 @@
 		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);
 	}
 }
@@ -2126,6 +2125,7 @@
 {
 	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;
 
@@ -2171,6 +2171,7 @@
 {
 	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;
@@ -2276,6 +2277,7 @@
 					 */
 					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) {
@@ -2286,6 +2288,7 @@
 					}
 				}
 				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);
@@ -2549,7 +2552,7 @@
 	struct conn_stream *cs;
 
 	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;
 
@@ -2752,6 +2755,7 @@
 								}
 								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++;
 								}