]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: stconn: Add samples to retrieve about stream aborts
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 30 Apr 2024 13:20:24 +0000 (15:20 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 6 May 2024 20:00:00 +0000 (22:00 +0200)
It is now possible to retrieve some info about the abort received for a
server or a client stream, if any.

  * fs.aborted and bs.aborted can be used to know if an abort was received
    on frontend or backend side. A boolean is returned.

  * fs.rst_code and bs.rst_code return the code of the received RESET_STREAM
    frame for a H2 stream or the code of the received STOP_SENDING frame for
    a QUIC stream. In both cases, the error code attached to the frame is
    returned. The sample fetch fails if no such frame was received or if the
    stream is not an H2/QUIC stream.

doc/configuration.txt
src/stconn.c

index 220b551f031405c722312a1e71933d461747f4cc..ed9b67f347d2bd5f681c18bf29975543e6aab54e 100644 (file)
@@ -23604,9 +23604,13 @@ Summary of sample fetch methods in this section and their respective types:
   keyword                                             output type
 ----------------------------------------------------+-------------
 bs.id                                                 integer
+bs.aborted                                            boolean
+bs.rst_code                                           integer
 distcc_body(<token>[,<occ>])                          binary
 distcc_param(<token>[,<occ>])                         integer
 fs.id                                                 integer
+fs.aborted                                            boolean
+fs.rst_code                                           integer
 payload(<offset>,<length>)                            binary
 payload_lv(<offset1>,<length>[,<offset2>])            binary
 req.len                                               integer
@@ -23642,6 +23646,16 @@ bs.id : integer
   Returns the multiplexer's stream ID on the server side. It is the
   multiplexer's responsibility to return the appropriate information.
 
+bs.aborted: boolean
+  Returns true is an abort was received from the server for the current
+  stream. Otherwise false is returned.
+
+bs.rst_code: integer
+  Returns the reset code received from the server for the current stream. The
+  code of the H2 RST_STEAM frame or the QUIC STOP_SENDING frame received from
+  the server is returned. The sample fetch fails if no abort was received or if
+  the server stream is not an H2/QUIC stream.
+
 distcc_body(<token>[,<occ>]) : binary
   Parses a distcc message and returns the body associated to occurrence #<occ>
   of the token <token>. Occurrences start at 1, and when unspecified, any may
@@ -23673,6 +23687,16 @@ fs.id : integer
   multiplexer's responsibility to return the appropriate information. For
   instance, on a raw TCP, 0 is always returned because there is no stream.
 
+fs.aborted: boolean
+  Returns true is an abort was received from the client for the current
+  stream. Otherwise false is returned.
+
+fs.rst_code: integer
+  Returns the reset code received from the client for the current stream. The
+  code of the H2 RST_STEAM frame or the QUIC STOP_SENDING frame received from the
+  client is returned. The sample fetch fails if no abort was received or
+  if the client stream is not an H2/QUIC stream.
+
 payload(<offset>,<length>) : binary (deprecated)
   This is an alias for "req.payload" when used in the context of a request (e.g.
   "stick on", "stick match"), and for "res.payload" when used in the context of
index 53888efb4a8e5989f66528dfcb7003ad83909d9b..a00f8e1140eaff4bbfea11e502033a8ee30abf5c 100644 (file)
@@ -2401,6 +2401,57 @@ smp_fetch_sid(const struct arg *args, struct sample *smp, const char *kw, void *
        return 1;
 }
 
+/* return 1 if the frontend or backend mux stream has received an abort and 0 otherwise.
+ */
+static int
+smp_fetch_strm_aborted(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stconn *sc;
+       unsigned int aborted = 0;
+
+       if (!smp->strm)
+               return 0;
+
+       sc = (kw[0] == 'f' ? smp->strm->scf : smp->strm->scb);
+       if (sc->sedesc->abort_info.info)
+               aborted = 1;
+
+       smp->flags = SMP_F_VOL_TXN;
+       smp->data.type = SMP_T_BOOL;
+       smp->data.u.sint = aborted;
+
+       return 1;
+}
+
+/* return the H2/QUIC RESET code of the frontend or backend mux stream. Any value
+ * means an a RST_STREAM was received on H2 and a STOP_SENDING on QUIC. Otherwise the sample fetch fails.
+ */
+static int
+smp_fetch_strm_rst_code(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stconn *sc;
+       unsigned int source;
+       unsigned long long code = 0;
+
+       if (!smp->strm)
+               return 0;
+
+       sc = (kw[0] == 'f' ? smp->strm->scf : smp->strm->scb);
+       source = ((sc->sedesc->abort_info.info & SE_ABRT_SRC_MASK) >> SE_ABRT_SRC_SHIFT);
+       if (source != SE_ABRT_SRC_MUX_H2 && source != SE_ABRT_SRC_MUX_QUIC) {
+               if (!source)
+                       smp->flags |= SMP_F_MAY_CHANGE;
+               return 0;
+       }
+       code = sc->sedesc->abort_info.code;
+
+       smp->flags = SMP_F_VOL_TXN;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = code;
+
+       return 1;
+}
+
 /* Note: must not be declared <const> as its list will be overwritten.
  * Note: fetches that may return multiple types should be declared using the
  * appropriate pseudo-type. If not available it must be declared as the lowest
@@ -2408,7 +2459,11 @@ smp_fetch_sid(const struct arg *args, struct sample *smp, const char *kw, void *
  */
 static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
        { "bs.id", smp_fetch_sid, 0, NULL, SMP_T_SINT, SMP_USE_L6REQ },
+       { "bs.aborted", smp_fetch_strm_aborted, 0, NULL, SMP_T_SINT, SMP_USE_L5SRV },
+       { "bs.rst_code", smp_fetch_strm_rst_code, 0, NULL, SMP_T_SINT, SMP_USE_L5SRV },
        { "fs.id", smp_fetch_sid, 0, NULL, SMP_T_STR, SMP_USE_L6RES },
+       { "fs.aborted", smp_fetch_strm_aborted, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
+       { "fs.rst_code", smp_fetch_strm_rst_code, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
        { /* END */ },
 }};