On 06/14/2017 08:51 AM, Frederic Lecaille wrote:
On 06/13/2017 09:16 PM, Frederic Lecaille wrote:
Hello Patrick,
[snipped]
I hope the pach attached to this mail will definitively fix such peer
CLOSE_WAIT issues.
A better patch which fixes the comments and commit message.
Sorry again but when I created my patch yesterday evening from a clean
branch I did not use the correct flag I used in another branch during my
tests. In the bad patch PEER_SESS_ST_CONNECT was replaced by
PEER_SESS_SC_CONNECTCODE.
Here is a new patch.
>From bc5c6a75eedb1745866cca27c4aafb67bbfdc1cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <[email protected]>
Date: Tue, 13 Jun 2017 16:39:57 +0200
Subject: [PATCH] MINOR: peers: Peers CLOSE_WAIT issue.
A peer session which has just been created upon reconnect timeout expirations,
could be right after shutdown (at peer session level) because the remote
side peer could also righ after have connected. In such a case the underlying
TCP session was still running (connect()/accept()) and finally left in CLOSE_WAIT
state after the remote side stopped writting (shutdown(SHUT_WR)).
Now on, with this patch we never shutdown such peer sessions wich have just
been created. We leave them connect to the remote peer which is already
connected and must shutdown its own peer session.
Thanks to Patric Hemmer for reporting this issue and to Willy and Yelp blogs
which helped me in fixing this issue.
(See https://www.haproxy.com/blog/truly-seamless-reloads-with-haproxy-no-more-hacks/ and
https://engineeringblog.yelp.com/2015/04/true-zero-downtime-haproxy-reloads.htmll)
---
src/peers.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/peers.c b/src/peers.c
index 0c8861f..beeec96 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -1719,7 +1719,13 @@ static void peer_session_forceshutdown(struct appctx *appctx)
{
struct peer *ps;
- if (!appctx)
+ /* Note that the peer sessions which have just been created
+ * (->st0 == PEER_SESS_ST_CONNECT) must not
+ * be shutdown, if not, the TCP session will never be closed
+ * and stay in CLOSE_WAIT state after having been closed by
+ * the remote side.
+ */
+ if (!appctx || appctx->st0 == PEER_SESS_ST_CONNECT)
return;
if (appctx->applet != &peer_applet)
--
2.1.4