From f983d00a1ce89d9505daf1ffde5db1bf58aab1fc Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 14 May 2019 10:40:21 +0200 Subject: [PATCH] BUG/MINOR: mux-h2: make the do_shut{r,w} functions more robust against retries These functions may fail to emit an RST or an empty DATA frame because the mux is full or busy. Then they subscribe the h2s and try again. However when doing so, they will already have marked the error state on the stream and will not pass anymore through the sequence resulting in the failed frame to be attempted to be sent again nor to the close to be done, instead they will return a success. It is important to only leave when the stream is already closed, but to go through the whole sequence otherwise. This patch should ideally be backported to 1.9 though it's possible that the lack of the WANT_SHUT* flags makes this difficult or dangerous. The severity is low enough to avoid this in case of trouble. --- src/mux_h2.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mux_h2.c b/src/mux_h2.c index 8c73cce45d..c4588eec52 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -3162,7 +3162,7 @@ static void h2_do_shutr(struct h2s *h2s) struct h2c *h2c = h2s->h2c; struct wait_event *sw = &h2s->wait_event; - if (h2s->st == H2_SS_HLOC || h2s->st == H2_SS_ERROR || h2s->st == H2_SS_CLOSED) + if (h2s->st == H2_SS_CLOSED) goto done; /* a connstream may require us to immediately kill the whole connection @@ -3215,10 +3215,11 @@ static void h2_do_shutw(struct h2s *h2s) struct h2c *h2c = h2s->h2c; struct wait_event *sw = &h2s->wait_event; - if (h2s->st == H2_SS_HLOC || h2s->st == H2_SS_ERROR || h2s->st == H2_SS_CLOSED) + if (h2s->st == H2_SS_CLOSED) goto done; - if (h2s->flags & H2_SF_HEADERS_SENT) { + if (h2s->st != H2_SS_HLOC && h2s->st != H2_SS_ERROR && + (h2s->flags & H2_SF_HEADERS_SENT)) { /* we can cleanly close using an empty data frame only after headers */ if (!(h2s->flags & (H2_SF_ES_SENT|H2_SF_RST_SENT)) && -- 2.39.5