]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: stream: Don't update counters when TCP to H2 upgrades are performed
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 21 Jan 2021 16:10:44 +0000 (17:10 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 22 Jan 2021 08:06:34 +0000 (09:06 +0100)
When a TCP to H2 upgrade is performed, the SF_IGNORE flag is set on the
stream before killing it. This happens when a TCP/SSL client connection is
routed to a HTTP backend and the h2 alpn detected. The SF_IGNORE flag was
added for this purpose, to skip some processing when the stream is aborted
before a mux upgrade. Some counters updates were skipped this way. But some
others are still updated.

Now, all counters update at the end of process_stream(), before releasing
the stream, are ignored if SF_IGNORE flag is set. Note this stream is
aborted because we switch from a mono-stream to a multi-stream
multiplexer. It works differently for TCP to H1 upgrades.

This patch should be backported as far as 2.0 after some observation period.

src/stream.c

index 718eaa5c0597ddfb9e0ee230bb6ec6a594805337..1a41ea53b019754551f8fdbebe4454455c7d10ad 100644 (file)
@@ -2399,39 +2399,41 @@ struct task *process_stream(struct task *t, void *context, unsigned short state)
                DISGUISE(write(1, trash.area, trash.data));
        }
 
-       s->logs.t_close = tv_ms_elapsed(&s->logs.tv_accept, &now);
-       if (!(s->flags & SF_IGNORE))
+       if (!(s->flags & SF_IGNORE)) {
+               s->logs.t_close = tv_ms_elapsed(&s->logs.tv_accept, &now);
+
                stream_process_counters(s);
 
-       if (s->txn && s->txn->status) {
-               int n;
+               if (s->txn && s->txn->status) {
+                       int n;
 
-               n = s->txn->status / 100;
-               if (n < 1 || n > 5)
-                       n = 0;
+                       n = s->txn->status / 100;
+                       if (n < 1 || n > 5)
+                               n = 0;
 
-               if (sess->fe->mode == PR_MODE_HTTP) {
-                       _HA_ATOMIC_ADD(&sess->fe->fe_counters.p.http.rsp[n], 1);
+                       if (sess->fe->mode == PR_MODE_HTTP) {
+                               _HA_ATOMIC_ADD(&sess->fe->fe_counters.p.http.rsp[n], 1);
+                       }
+                       if ((s->flags & SF_BE_ASSIGNED) &&
+                           (s->be->mode == PR_MODE_HTTP)) {
+                               _HA_ATOMIC_ADD(&s->be->be_counters.p.http.rsp[n], 1);
+                               _HA_ATOMIC_ADD(&s->be->be_counters.p.http.cum_req, 1);
+                       }
                }
-               if ((s->flags & SF_BE_ASSIGNED) &&
-                   (s->be->mode == PR_MODE_HTTP)) {
-                       _HA_ATOMIC_ADD(&s->be->be_counters.p.http.rsp[n], 1);
-                       _HA_ATOMIC_ADD(&s->be->be_counters.p.http.cum_req, 1);
+
+               /* let's do a final log if we need it */
+               if (!LIST_ISEMPTY(&sess->fe->logformat) && s->logs.logwait &&
+                   !(s->flags & SF_MONITOR) &&
+                   (!(sess->fe->options & PR_O_NULLNOLOG) || req->total)) {
+                       /* we may need to know the position in the queue */
+                       pendconn_free(s);
+                       s->do_log(s);
                }
-       }
 
-       /* let's do a final log if we need it */
-       if (!LIST_ISEMPTY(&sess->fe->logformat) && s->logs.logwait &&
-           !(s->flags & SF_MONITOR) &&
-           (!(sess->fe->options & PR_O_NULLNOLOG) || req->total)) {
-               /* we may need to know the position in the queue */
-               pendconn_free(s);
-               s->do_log(s);
+               /* update time stats for this stream */
+               stream_update_time_stats(s);
        }
 
-       /* update time stats for this stream */
-       stream_update_time_stats(s);
-
        /* the task MUST not be in the run queue anymore */
        stream_free(s);
        task_destroy(t);