diff --git a/doc/configuration.txt b/doc/configuration.txt index 220b551f0..ed9b67f34 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -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([,]) binary distcc_param([,]) integer fs.id integer +fs.aborted boolean +fs.rst_code integer payload(,) binary payload_lv(,[,]) 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([,]) : binary Parses a distcc message and returns the body associated to occurrence # of the 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(,) : 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 diff --git a/src/stconn.c b/src/stconn.c index 53888efb4..a00f8e114 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -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 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 */ }, }};