]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: conn-stream: Don't erase endpoint flags on reset
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 28 Apr 2022 16:25:24 +0000 (18:25 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 29 Apr 2022 12:12:42 +0000 (14:12 +0200)
Only CS_EP_ERROR flag is now removed from the endpoint when a reset is
performed. When a new the endpoint is allocated, flags are preserved. It is
the caller responsibility to remove other flags, depending on its need.

Concretly, during a connection retry or a L7 retry, we must preserve
flags. In tcpcheck and the CLI, we reset flags.

This patch is 2.6-specific. No backport needed.

src/backend.c
src/check.c
src/cli.c
src/conn_stream.c
src/http_ana.c

index a887eb2ea9873926926486ae732801bc87a475aa..5a8bc0e30e6d090aea9839b65216a2234493ce13 100644 (file)
@@ -1577,6 +1577,7 @@ static int connect_server(struct stream *s)
                                        srv_conn = NULL;
                                        if (cs_reset_endp(s->csb) < 0)
                                                return SF_ERR_INTERNAL;
+                                       s->csb->endp->flags &= CS_EP_DETACHED;
                                }
                        }
                        else
index 2db82c4ab7c06ae0ac7a7297cf8a1a1e15506b2c..d65850da95e8a3139d0cb3cab548221e8736eb9c 100644 (file)
@@ -1164,7 +1164,12 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
                                TRACE_DEVEL("closing current connection", CHK_EV_TASK_WAKE|CHK_EV_HCHK_RUN, check);
                                check->state &= ~CHK_ST_CLOSE_CONN;
                                conn = NULL;
-                               cs_reset_endp(check->cs); /* error will be handled by tcpcheck_main() */
+                               if (!cs_reset_endp(check->cs)) {
+                                       /* error will be handled by tcpcheck_main().
+                                        * On success, remove all flags except CS_EP_DETACHED
+                                        */
+                                       check->cs->endp->flags &= CS_EP_DETACHED;
+                               }
                                tcpcheck_main(check);
                        }
                        if (check->result == CHK_RES_UNKNOWN) {
index 081d28ce3d7e2ad3f599e4e157f3bfe226c03717..b32b8b1a4b62d88fa3e615980bf36b6c73507ad3 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -2761,6 +2761,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
                                        s->srv_error(s, s->csb);
                                return 1;
                        }
+                       s->csb->endp->flags &= CS_EP_DETACHED;
                }
 
                sockaddr_free(&s->csb->dst);
index fda8ab44e882d604f824d355fc67de8ea91f67f7..5f1508dbcc28315d559176ca4d19a121b3c12f53 100644 (file)
@@ -392,7 +392,8 @@ static void cs_detach_endp(struct conn_stream **csp)
 
        if (cs->endp) {
                /* the cs is the only one one the endpoint */
-               cs_endpoint_init(cs->endp);
+               cs->endp->target = NULL;
+               cs->endp->ctx = NULL;
                cs->endp->flags |= CS_EP_DETACHED;
        }
 
@@ -442,12 +443,17 @@ void cs_destroy(struct conn_stream *cs)
 /* Resets the conn-stream endpoint. It happens when the app layer want to renew
  * its endpoint. For a connection retry for instance. If a mux or an applet is
  * attached, a new endpoint is created. Returns -1 on error and 0 on sucess.
+ *
+ * Only CS_EP_ERROR flag is removed on the endpoint. Orther flags are preserved.
+ * It is the caller responsibility to remove other flags if needed.
  */
 int cs_reset_endp(struct conn_stream *cs)
 {
        struct cs_endpoint *new_endp;
 
        BUG_ON(!cs->app);
+
+       cs->endp->flags &= ~CS_EP_ERROR;
        if (!__cs_endp_target(cs)) {
                /* endpoint not attached or attached to a mux with no
                 * target. Thus the endpoint will not be release but just
@@ -465,6 +471,7 @@ int cs_reset_endp(struct conn_stream *cs)
                cs->endp->flags |= CS_EP_ERROR;
                return -1;
        }
+       new_endp->flags = cs->endp->flags;
 
        /* The app is still attached, the cs will not be released */
        cs_detach_endp(&cs);
index 7a987a5cf603b662d43bca04177995cba1a03aad..a81c53d428f94de031c2a3e105a403123d372c16 100644 (file)
@@ -1246,7 +1246,6 @@ static __inline int do_l7_retry(struct stream *s, struct conn_stream *cs)
        req->flags &= ~(CF_WRITE_ERROR | CF_WRITE_TIMEOUT | CF_SHUTW | CF_SHUTW_NOW);
        res->flags &= ~(CF_READ_ERROR | CF_READ_TIMEOUT | CF_SHUTR | CF_EOI | CF_READ_NULL | CF_SHUTR_NOW);
        res->analysers &= AN_RES_FLT_END;
-       cs->endp->flags &= ~CS_EP_RXBLK_SHUT;
        s->conn_err_type = STRM_ET_NONE;
        s->flags &= ~(SF_CONN_EXP | SF_ERR_MASK | SF_FINST_MASK);
        s->conn_exp = TICK_ETERNITY;
@@ -1261,6 +1260,7 @@ static __inline int do_l7_retry(struct stream *s, struct conn_stream *cs)
                        s->flags |= SF_ERR_INTERNAL;
                return -1;
        }
+       cs->endp->flags &= ~CS_EP_RXBLK_SHUT;
 
        b_free(&req->buf);
        /* Swap the L7 buffer with the channel buffer */