]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: stream: Only save previous connection state for the server side
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 30 Mar 2022 15:13:02 +0000 (17:13 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 13 Apr 2022 13:10:14 +0000 (15:10 +0200)
The previous connection state on the client side was only used for debugging
purpose to report client close. But this may be handled when the client
stream-interface is switched from SI_ST_DIS to SI_ST_CLO.

So, there only remains the previous connection state on the server side that
is used by the stream, in process_stream(), to be able to set the correct
termination flags. Thus, instead of keeping this info in the
stream-interface for only one side, the info is now stored in the stream
itself.

include/haproxy/stream-t.h
include/haproxy/stream_interface-t.h
include/haproxy/stream_interface.h
src/cli.c
src/stream.c
src/stream_interface.c

index e179e541735ee1f4309c50592eb291c983cc22da..02b8789f16823a3da9d62dd4240d7afffd75043b 100644 (file)
@@ -143,6 +143,7 @@ struct stream {
 
        int conn_retries;               /* number of connect retries performed */
        unsigned int conn_exp;          /* wake up time for connect, queue, turn-around, ... */
+       enum si_state prev_conn_state;  /* SI_ST*, copy of previous state of the server conn-stream */
 
        struct list list;               /* position in the thread's streams list */
        struct mt_list by_srv;          /* position in server stream list */
index bb2fdbdc44e658a4c6084427185fdb4d4ceba1ec..08c30ad2209aebdb3f9cb1f373e2fc6032633735 100644 (file)
@@ -112,7 +112,6 @@ enum {
 struct stream_interface {
        /* struct members used by the "buffer" side */
        enum si_state state;     /* SI_ST* */
-       enum si_state prev_state;/* SI_ST*, copy of previous state */
        /* 16-bit hole here */
        unsigned int flags;     /* SI_FL_* */
        struct conn_stream *cs; /* points to the conn-streams that owns the endpoint (connection or applet) */
index 0b02c9e338f130db285f0c5e9dab2a5b81e1035e..1b7fd13fa3868abaca6fca1fe59490b6823a441e 100644 (file)
@@ -109,7 +109,7 @@ static inline int si_init(struct stream_interface *si)
        si->err_type       = SI_ET_NONE;
        si->flags         &= SI_FL_ISBACK;
        si->cs             = NULL;
-       si->state          = si->prev_state = SI_ST_INI;
+       si->state          = SI_ST_INI;
        si->ops            = &si_embedded_ops;
        si->wait_event.tasklet = tasklet_new();
        if (!si->wait_event.tasklet)
@@ -126,7 +126,7 @@ static inline int si_init(struct stream_interface *si)
  */
 static inline void si_set_state(struct stream_interface *si, int state)
 {
-       si->state = si->prev_state = state;
+       si->state = si_strm(si)->prev_conn_state = state;
 }
 
 /* returns a bit for a stream-int state, to match against SI_SB_* */
index f55999e034d0c9f723655d51f6180414474462f9..a428b691ddd65d8ddba124912fa47a683c44534c 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -2766,7 +2766,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
 
                sockaddr_free(&s->csb->dst);
 
-               cs_si(s->csb)->state = cs_si(s->csb)->prev_state = SI_ST_INI;
+               si_set_state(cs_si(s->csb), SI_ST_INI);
                cs_si(s->csb)->err_type = SI_ET_NONE;
                cs_si(s->csb)->flags &= SI_FL_ISBACK; /* we're in the context of process_stream */
                s->csb->flags &= CS_FL_ISBACK | CS_FL_DONT_WAKE; /* we're in the context of process_stream */
index 61e66601c4bd7885d6a484044fc938bc807a1c9f..7ab4f5c14e306b1985cc30e8c5a439a6fe1d5db3 100644 (file)
@@ -422,6 +422,7 @@ struct stream *stream_new(struct session *sess, struct conn_stream *cs, struct b
        s->pending_events = 0;
        s->conn_retries = 0;
        s->conn_exp = TICK_ETERNITY;
+       s->prev_conn_state = SI_ST_INI;
        t->process = process_stream;
        t->context = s;
        t->expire = TICK_ETERNITY;
@@ -958,7 +959,7 @@ static void sess_set_term_flags(struct stream *s)
                        s->flags |= SF_FINST_Q;
                else if (si_state_in(cs_si(s->csb)->state, SI_SB_REQ|SI_SB_TAR|SI_SB_ASS|SI_SB_CON|SI_SB_CER|SI_SB_RDY))
                        s->flags |= SF_FINST_C;
-               else if (cs_si(s->csb)->state == SI_ST_EST || cs_si(s->csb)->prev_state == SI_ST_EST)
+               else if (cs_si(s->csb)->state == SI_ST_EST || s->prev_conn_state == SI_ST_EST)
                        s->flags |= SF_FINST_D;
                else
                        s->flags |= SF_FINST_L;
@@ -1780,9 +1781,23 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
        DBG_TRACE_POINT(STRM_EV_STRM_PROC, s);
 
        /* nothing special to be done on client side */
-       if (unlikely(si_f->state == SI_ST_DIS))
+       if (unlikely(si_f->state == SI_ST_DIS)) {
                si_f->state = SI_ST_CLO;
 
+               /* This is needed only when debugging is enabled, to indicate
+                * client-side close.
+                */
+               if (unlikely((global.mode & MODE_DEBUG) &&
+                            (!(global.mode & MODE_QUIET) ||
+                             (global.mode & MODE_VERBOSE)))) {
+                       chunk_printf(&trash, "%08x:%s.clicls[%04x:%04x]\n",
+                                    s->uniq_id, s->be->id,
+                                    (unsigned short)conn_fd(cs_conn(si_f->cs)),
+                                    (unsigned short)conn_fd(cs_conn(si_b->cs)));
+                       DISGUISE(write(1, trash.area, trash.data));
+               }
+       }
+
        /* When a server-side connection is released, we have to count it and
         * check for pending connections on this server.
         */
@@ -1798,6 +1813,21 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                        if (may_dequeue_tasks(srv, s->be))
                                process_srv_queue(srv);
                }
+
+               /* This is needed only when debugging is enabled, to indicate
+                * server-side close.
+                */
+               if (unlikely((global.mode & MODE_DEBUG) &&
+                            (!(global.mode & MODE_QUIET) ||
+                             (global.mode & MODE_VERBOSE)))) {
+                       if (s->prev_conn_state == SI_ST_EST) {
+                               chunk_printf(&trash, "%08x:%s.srvcls[%04x:%04x]\n",
+                                            s->uniq_id, s->be->id,
+                                            (unsigned short)conn_fd(__cs_conn(si_f->cs)),
+                                            (unsigned short)conn_fd(cs_conn(si_b->cs)));
+                               DISGUISE(write(1, trash.area, trash.data));
+                       }
+               }
        }
 
        /*
@@ -2392,33 +2422,6 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
        s->csf->flags &= ~CS_FL_DONT_WAKE;
        s->csb->flags &= ~CS_FL_DONT_WAKE;
 
-       /* This is needed only when debugging is enabled, to indicate
-        * client-side or server-side close. Please note that in the unlikely
-        * event where both sides would close at once, the sequence is reported
-        * on the server side first.
-        */
-       if (unlikely((global.mode & MODE_DEBUG) &&
-                    (!(global.mode & MODE_QUIET) ||
-                     (global.mode & MODE_VERBOSE)))) {
-               if (si_b->state == SI_ST_CLO &&
-                   si_b->prev_state == SI_ST_EST) {
-                       chunk_printf(&trash, "%08x:%s.srvcls[%04x:%04x]\n",
-                                    s->uniq_id, s->be->id,
-                                    (unsigned short)conn_fd(cs_conn(si_f->cs)),
-                                    (unsigned short)conn_fd(cs_conn(si_b->cs)));
-                       DISGUISE(write(1, trash.area, trash.data));
-               }
-
-               if (si_f->state == SI_ST_CLO &&
-                   si_f->prev_state == SI_ST_EST) {
-                       chunk_printf(&trash, "%08x:%s.clicls[%04x:%04x]\n",
-                                    s->uniq_id, s->be->id,
-                                    (unsigned short)conn_fd(cs_conn(si_f->cs)),
-                                    (unsigned short)conn_fd(cs_conn(si_b->cs)));
-                       DISGUISE(write(1, trash.area, trash.data));
-               }
-       }
-
        if (likely((si_f->state != SI_ST_CLO) || !si_state_in(si_b->state, SI_SB_INI|SI_SB_CLO) ||
                   (req->analysers & AN_REQ_FLT_END) || (res->analysers & AN_RES_FLT_END))) {
                if ((sess->fe->options & PR_O_CONTSTATS) && (s->flags & SF_BE_ASSIGNED) && !(s->flags & SF_IGNORE))
index 1198215e0bc2a2f664ccd71cd10ff8c87f799c89..3f38fb785ccef135822bdfc22668edd9201814eb 100644 (file)
@@ -988,8 +988,7 @@ void si_update_both(struct stream_interface *si_f, struct stream_interface *si_b
        req->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_READ_ATTACHED|CF_WRITE_NULL|CF_WRITE_PARTIAL);
        res->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_READ_ATTACHED|CF_WRITE_NULL|CF_WRITE_PARTIAL);
 
-       si_f->prev_state = si_f->state;
-       si_b->prev_state = si_b->state;
+       si_strm(si_b)->prev_conn_state = si_b->state;
 
        /* let's recompute both sides states */
        if (si_state_in(si_f->state, SI_SB_RDY|SI_SB_EST))