]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
3 years agoMINOR: config: use the new bind_parse_args_list() to parse a "bind" line
Willy Tarreau [Fri, 20 May 2022 13:44:17 +0000 (15:44 +0200)] 
MINOR: config: use the new bind_parse_args_list() to parse a "bind" line

This now makes sure that both the peers' "bind" line and the regular one
will use the exact same parser with the exact same behavior. Note that
the parser applies after the address and that it could be factored
further, since the peers one still does quite a bit of duplicated work.

3 years agoMINOR: listener: provide a function to process all of a bind_conf's arguments
Willy Tarreau [Fri, 20 May 2022 13:41:45 +0000 (15:41 +0200)] 
MINOR: listener: provide a function to process all of a bind_conf's arguments

The "bind" parsing code was duplicated for the peers section and as a
result it wasn't kept updated, resulting in slightly different error
behavior (e.g. errors were not freed, warnings were emitted as alerts)
Let's first unify it into a new dedicated function that properly reports
and frees the error.

3 years agoMINOR: protocol: replace ctrl_type with xprt_type and clarify it
Willy Tarreau [Fri, 20 May 2022 14:36:46 +0000 (16:36 +0200)] 
MINOR: protocol: replace ctrl_type with xprt_type and clarify it

There's been some great confusion between proto_type, ctrl_type and
sock_type. It turns out that ctrl_type was improperly chosen because
it's not the control layer that is of this or that type, but the
transport layer, and it turns out that the transport layer doesn't
(normally) denaturate the underlying control layer, except for QUIC
which turns dgrams to streams. The fact that the SOCK_{DGRAM|STREAM}
set of values was used added to the confusion.

Let's replace it with xprt_type which reuses the later introduced
PROTO_TYPE_* values, and update the comments to explain which one
works at what level.

3 years agoCLEANUP: config: provide cleare hints about unsupported QUIC addresses
Willy Tarreau [Fri, 20 May 2022 15:32:35 +0000 (17:32 +0200)] 
CLEANUP: config: provide cleare hints about unsupported QUIC addresses

We now detect that QUIC was likely requested, and if it's not compiled
it, we clearly mention it.

3 years agoCLEANUP: config: improve address parser error report for unmatched protocols
Willy Tarreau [Fri, 20 May 2022 15:28:30 +0000 (17:28 +0200)] 
CLEANUP: config: improve address parser error report for unmatched protocols

Just trying "quic4@:4433" with USE_QUIC not set rsults in such a cryptic
error:

   [ALERT]    (14610) : config : parsing [quic-mini.cfg:44] : 'bind' : unsupported protocol family 2 for address 'quic4@:4433'

Let's at least add the stream and datagram statuses to indicate what was
being looked for:

   [ALERT]    (15252) : config : parsing [quic-mini.cfg:44] : 'bind' : unsupported stream protocol for datagram family 2 address 'quic4@:4433'

Still not very pretty but gives a little bit more info.

3 years agoBUG/MINOR: peers: fix error reporting of "bind" lines
Willy Tarreau [Fri, 20 May 2022 13:19:48 +0000 (15:19 +0200)] 
BUG/MINOR: peers: fix error reporting of "bind" lines

In case the str2listener() parser reports a generic error with no message
when parsing the argument of a "bind" statement in a "peers" section, the
reported error indicates an invalid address on the empty arg. This has
existed since 2.0 with commit 355b2033e ("MINOR: cfgparse: SSL/TLS binding
in "peers" sections."), so this must be backported till 2.0.

3 years agoMINOR: mux-quic: close connection on error if different data at offset
Amaury Denoyelle [Fri, 20 May 2022 13:14:57 +0000 (15:14 +0200)] 
MINOR: mux-quic: close connection on error if different data at offset

As specified by the RFC reception of different STREAM data for the same
offset should be treated with a CONNECTION_CLOSE with error
PROTOCOL_VIOLATION.

Use ncbuf API to detect this case : if add operation fails with
NCB_RET_DATA_REJ with add mode NCB_ADD_COMPARE.

3 years agoMINOR: mux-quic: emit STREAM_LIMIT_ERROR
Amaury Denoyelle [Fri, 20 May 2022 14:45:32 +0000 (16:45 +0200)] 
MINOR: mux-quic: emit STREAM_LIMIT_ERROR

Send a CONNECTION_CLOSE on reception of a STREAM frame for a STREAM id
exceeding the maximum value enforced. Only implemented for bidirectional
streams for the moment.

3 years agoMINOR: mux-quic: emit FLOW_CONTROL_ERROR
Amaury Denoyelle [Fri, 20 May 2022 13:05:07 +0000 (15:05 +0200)] 
MINOR: mux-quic: emit FLOW_CONTROL_ERROR

Send a CONNECTION_CLOSE if the peer emits more data than authorized by
our flow-control. This is implemented for both stream and connection
level.

Fields have been added in qcc/qcs structures to differentiate received
offsets for limit enforcing with consumed offsets for sending of
MAX_DATA/MAX_STREAM_DATA frames.

3 years agoMINOR: quic/mux-quic: define CONNECTION_CLOSE send API
Amaury Denoyelle [Fri, 20 May 2022 13:04:38 +0000 (15:04 +0200)] 
MINOR: quic/mux-quic: define CONNECTION_CLOSE send API

Define an API to easily set a CONNECTION_CLOSE. This will mainly be
useful for the MUX when an error is detected which require to close the
whole connection.

On the MUX side, a new flag is added when a CONNECTION_CLOSE has been
prepared. This will disable add future send operations.

3 years agoMINOR: quic: Dynamic Retry implementation
Frédéric Lécaille [Fri, 20 May 2022 14:37:36 +0000 (16:37 +0200)] 
MINOR: quic: Dynamic Retry implementation

We rely on <conn_opening> stats counter and tune.quic.retry_threshold
setting to dynamically start sending Retry packets. We continue to send such packets
when "quic-force-retry" setting is set. The difference is when we receive tokens.
We check them regardless of this setting because the Retry could have been
dynamically started. We must also send Retry packets when we receive Initial
packets without token if the dynamic Retry threshold was reached but only for connection
which are not currently opening or in others words for Initial packets without
connection already instantiated. Indeed, we must not send Retry packets for all
Initial packets without token. For instance a client may have already sent an
Initial packet without receiving Retry packet because the Retry feature was not
started, then the Retry starts on exeeding the threshold value due to others
connections, then finally our client decide to send another Initial packet
(to ACK Initial CRYPTO data for instance). It does this without token. So, for
this already existing connection we must not send a Retry packet.

3 years agoMINOR: quic: Add tune.quic.retry-threshold keyword
Frédéric Lécaille [Fri, 20 May 2022 14:29:10 +0000 (16:29 +0200)] 
MINOR: quic: Add tune.quic.retry-threshold keyword

This QUIC specific keyword may be used to set the theshold, in number of
connection openings, beyond which QUIC Retry feature will be automatically
enabled. Its default value is 100.

3 years agoMINOR: quic: QUIC stats counters handling
Frédéric Lécaille [Fri, 20 May 2022 06:11:26 +0000 (08:11 +0200)] 
MINOR: quic: QUIC stats counters handling

First commit to handle the QUIC stats counters. There is nothing special to say
except perhaps for ->conn_openings which is a gauge to count the number of
connection openings. It is incremented after having instantiated a quic_conn
struct, then decremented when the handshake was successful (handshake completed
state) or failed or when the connection timed out without reaching the handshake
completed state.

3 years agoBUG/MINOR: quic: Fix potential memory leak during QUIC connection allocations
Frédéric Lécaille [Thu, 19 May 2022 12:35:20 +0000 (14:35 +0200)] 
BUG/MINOR: quic: Fix potential memory leak during QUIC connection allocations

Move the code which finalizes the QUIC connections initialisations after
having called qc_new_conn() into this function to benefit from its
error handling to release the memory allocated for QUIC connections
the initialization of which could not be finalized.

3 years agoMINOR: quic: Attach proxy QUIC stats counters to the QUIC connection
Frédéric Lécaille [Thu, 19 May 2022 09:58:53 +0000 (11:58 +0200)] 
MINOR: quic: Attach proxy QUIC stats counters to the QUIC connection

Make usage of EXTRA_COUNTERS_GET() do to so from qc_new_conn().

3 years agoMINOR: quic_stats: Add a new stats module for QUIC
Frédéric Lécaille [Wed, 18 May 2022 12:30:03 +0000 (14:30 +0200)] 
MINOR: quic_stats: Add a new stats module for QUIC

This is a very minimalist frontend only stats module with only one gauge for the
QUIC establishing connections count.

3 years agoBUILD: stats: Missing headers inclusions from stats.h
Frédéric Lécaille [Wed, 18 May 2022 09:49:34 +0000 (11:49 +0200)] 
BUILD: stats: Missing headers inclusions from stats.h

If we add a new stats module to C source files including only
stats.h we get these errors:

    include/haproxy/stats.h:39:31: error: array type has incomplete element type
    ‘struct name_desc’
       39 | extern const struct name_desc stat_fields[];

    include/haproxy/stats.h:55:50: warning: ‘struct listener’ declared inside
    parameter list will not be visible outside of this definition or declaration
       55 | int stats_fill_li_stats(struct proxy *px, struct listener *l, int flags,

name_desc struct is defined in tools-t.h and listener struct in listner-t.h.

3 years agoMINOR: quic: Move quic_lstnr_dgram_dispatch() out of xprt_quic.c
Frédéric Lécaille [Tue, 17 May 2022 15:23:16 +0000 (17:23 +0200)] 
MINOR: quic: Move quic_lstnr_dgram_dispatch() out of xprt_quic.c

Remove this function from xprt_quic.c which for now implements only
"by thread attached to a connection" code.

3 years agoMINOR: cfgparse: Update for "cluster-secret" keyword for QUIC Retry
Frédéric Lécaille [Mon, 16 May 2022 14:51:41 +0000 (16:51 +0200)] 
MINOR: cfgparse: Update for "cluster-secret" keyword for QUIC Retry

The QUIC Retry feature is disabled if no "cluster-secret" setting was set.

3 years agoMINOR: quic: Retry implementation
Frédéric Lécaille [Thu, 12 May 2022 12:47:59 +0000 (14:47 +0200)] 
MINOR: quic: Retry implementation

Here is the format of a token:
        - format (1 byte)
        - ODCID (from 9 up 21 bytes)
        - creation timestamp (4 bytes)
        - salt (16 bytes)

A format byte is required to distinguish the Retry token from others sent in
NEW_TOKEN frames.

The Retry token is ciphered after having derived a strong secret from the cluster secret
and generated the AEAD AAD, as well as a 16 bytes long salt. This salt is
added to the token. Obviously it is not ciphered. The format byte is not
ciphered too.

The AAD are built by quic_generate_retry_token_aad() which concatenates the version,
the client SCID and the IP address and port. We had to implement quic_saddr_cpy()
to copy the IP address and port to the AAD buffer. Only the Retry SCID is generated
on our side to build a Retry packet, the others fields come from the first packet
received by the client. It must reuse this Retry SCID in response to our Retry packet.
So, we have not to store it on our side. Everything is offloaded to the client (stateless).
quic_generate_retry_token() must be used to generate a Retry packet. It calls
quic_pkt_encrypt() to cipher the token.

quic_generate_retry_check() must be used to check the validity of a Retry token.
It is able to decipher a token which arrives into an Initial packet in response
to a Retry packet. It calls parse_retry_token() after having deciphered the token
to store the ODCID into a local quic_cid struct variable. Finally this ODCID may
be stored into the transport parameter thanks to qc_lstnr_params_init().
The Retry token lifetime is 10 seconds. This lifetime is also checked by
quic_generate_retry_check(). If quic_generate_retry_check() fails, the received
packet is dropped without anymore packet processing at this time.

3 years agoMINOR: quic_tls: Add quic_tls_decrypt2() implementation
Frédéric Lécaille [Mon, 16 May 2022 08:27:57 +0000 (10:27 +0200)] 
MINOR: quic_tls: Add quic_tls_decrypt2() implementation

This function does exactly the same thing as quic_tls_decrypt(), except that
it does reuse its input buffer as output buffer. This is needed
to decrypt the Retry token without modifying the packet buffer which
contains this token. Indeed, this would prevent us from decryption
the packet itself as the token belong to the AEAD AAD for the packet.

3 years agoMINOR: quic_tls: Add quic_tls_derive_retry_token_secret()
Frédéric Lécaille [Thu, 12 May 2022 12:44:51 +0000 (14:44 +0200)] 
MINOR: quic_tls: Add quic_tls_derive_retry_token_secret()

This function must be used to derive strong secrets from a non pseudo-random
secret (cluster-secret setting in our case) and an IV. First it call
quic_hkdf_extract_and_expand() to do that for a temporary strong secret (tmpkey)
then two calls to quic_hkdf_expand() reusing this strong temporary secret
to derive the final strong secret and IV.

3 years agoMINOR: quic: Dump initial derived secrets
Frédéric Lécaille [Fri, 13 May 2022 13:07:49 +0000 (15:07 +0200)] 
MINOR: quic: Dump initial derived secrets

It seems <qc> parameters was removed for an unknown reason preventing
these secrets to dumped by the traces.

3 years agoBUG/MINOR: cfgparse: abort earlier in case of allocation error
Willy Tarreau [Fri, 20 May 2022 07:13:38 +0000 (09:13 +0200)] 
BUG/MINOR: cfgparse: abort earlier in case of allocation error

In issue #1563, Coverity reported a very interesting issue about a
possible UAF in the config parser if the config file ends in with a
very large line followed by an empty one and the large one causes an
allocation failure.

The issue essentially is that we try to go on with the next line in case
of allocation error, while there's no point doing so. If we failed to
allocate memory to read one config line, the same may happen on the next
one, and blatantly dropping it while trying to parse what follows it. In
the best case, subsequent errors will be incorrect due to this prior error
(e.g. a large ACL definition with many patterns, followed by a reference of
this ACL).

Let's just immediately abort in such a condition where there's no recovery
possible.

This may be backported to all versions once the issue is confirmed to be
addressed.

Thanks to Ilya for the report.

3 years agoCLEANUP: quic: adjust comment/coding style for TPs init
Amaury Denoyelle [Thu, 19 May 2022 14:55:29 +0000 (16:55 +0200)] 
CLEANUP: quic: adjust comment/coding style for TPs init

Fix typo in comment and adjust code alignment for better readability.

3 years agoBUG/MEDIUM: quic: fix initialization for local/remote TPs
Amaury Denoyelle [Thu, 19 May 2022 14:45:37 +0000 (16:45 +0200)] 
BUG/MEDIUM: quic: fix initialization for local/remote TPs

The local and remote TPs were both processed through the same function
quic_transport_params_init(). This caused the remote TPs to be
overwritten with values configured for our local usage.

Change this by reserving quic_transport_params_init() only for our local
TPs. Remote TPs are simply initialized via
quic_dflt_transport_params_cpy().

This bug could result in a connection closed in error by the client due
to a violation of its TPs. For example, curl client closed the
connection after receiving too many CONNECTION_ID due to an invalid
active_connection_id value used.

3 years agoMINOR: quic: detect EBADF on sendto()
Amaury Denoyelle [Thu, 19 May 2022 09:53:56 +0000 (11:53 +0200)] 
MINOR: quic: detect EBADF on sendto()

EBADF can be encountered during process termination after fd listener
has been reset to -1.

3 years agoMINOR: quic: abort on unlisted errno on sendto()
Amaury Denoyelle [Wed, 18 May 2022 16:26:13 +0000 (18:26 +0200)] 
MINOR: quic: abort on unlisted errno on sendto()

If an unlisted errno is reported, abort the process. If a crash is
reported on this condition, we must determine if the error code is a
bug, should interrupt emission on the fd or if we can retry the syscall.

3 years agoBUG/MINOR: quic: break for error on sendto
Amaury Denoyelle [Wed, 18 May 2022 16:14:12 +0000 (18:14 +0200)] 
BUG/MINOR: quic: break for error on sendto

If sendto returns an error, we should not retry the call and break from
the sending loop. An exception is made for EINTR which allows to retry
immediately the syscall.

This bug caused an infinite loop reproduced when the process is in the
closing state by SIGUSR1 but there is still QUIC data emission left.

3 years agoMEDIUM: check: Use the CS to handle subscriptions for read/write events
Christopher Faulet [Wed, 18 May 2022 13:57:15 +0000 (15:57 +0200)] 
MEDIUM: check: Use the CS to handle subscriptions for read/write events

Instead of using the health-check to subscribe to read/write events, we now
rely on the conn-stream. Indeed, on the server side, the conn-stream's
endpoint is a multiplexer. Thus it seems appropriate to handle subscriptions
for read/write events the same way than for the streams. Of course, the I/O
callback function is not the same. We use srv_chk_io_cb() instead of
cs_conn_io_cb().

3 years agoREORG: check: Rename and export I/O callback function
Christopher Faulet [Wed, 18 May 2022 12:50:30 +0000 (14:50 +0200)] 
REORG: check: Rename and export I/O callback function

event_srv_chk_io() function is renamed srv_chk_io_cb() to be consistant with
the I/O callback function of connections. In addition, this function is
exported. It will be required to use the conn-stream's subscriptions.

3 years agoMEDIUM: check: No longer shutdown the connection in .wake callback function
Christopher Faulet [Wed, 18 May 2022 12:35:49 +0000 (14:35 +0200)] 
MEDIUM: check: No longer shutdown the connection in .wake callback function

The connection is already closed by the health-check itself. Thus there is
now reason to duplicate this part in the .wake callback function. It is
enough to wake the health-check and wait.

3 years agoBUG/MINOR: check: Reinit the buffer wait list at the end of a check
Christopher Faulet [Wed, 18 May 2022 12:24:43 +0000 (14:24 +0200)] 
BUG/MINOR: check: Reinit the buffer wait list at the end of a check

The buffer wait list is used to deal with buffer allocation failure. But at
the end of health-check, it must be reinitialized. There is no reason to
reason to get a buffer between two health-check runs. And in fact, the
associated flags, CHK_ST_IN_ALLOC and CHK_ST_OUT_ALLOC, are already cleared
at the end of a health-check.

This patch must be backported as far as 2.2. On the 2.2, MT_LIST_ADDED and
MT_LIST_DEL must be used instead of LIST_INLIST and LIST_DEL_INIT.

3 years agoBUG/MEDIUM: config: Reset outline buffer size on realloc error in readcfgfile()
Christopher Faulet [Wed, 18 May 2022 14:22:43 +0000 (16:22 +0200)] 
BUG/MEDIUM: config: Reset outline buffer size on realloc error in readcfgfile()

When the line parsing failed because outline buffer must be reallocated, if
my_realloc2() call fails, the buffer size must be reset. Indeed, in this case
the current line is skipped, a fatal error is reported and we jump to the next
line. At this stage the outline buffer is NULL. If the buffer size is not reset,
the next call to parse_line() crashes because we try to write in the buffer. We
fail to detect the outline buffer is too small to copy any character.

To fix the issue, outlinesize variable must be set to 0 when outline allocation
failed.

This patch should fix the issue #1563. It must be backported as far as 2.2.

3 years agoMINOR: mux-quic: free RX buf if empty
Amaury Denoyelle [Wed, 18 May 2022 14:19:47 +0000 (16:19 +0200)] 
MINOR: mux-quic: free RX buf if empty

Release the QCS RX buffer if emptied afer qcs_consume(). This improves
memory usage and avoids a QCS to keep an allocated buffer, particularly
when no data is received anymore. Buffer is automatically reallocated if
needed via qc_get_ncbuf().

3 years agoBUG/MINOR: mux-quic: support nul buffer with qc_free_ncbuf()
Amaury Denoyelle [Tue, 17 May 2022 16:53:21 +0000 (18:53 +0200)] 
BUG/MINOR: mux-quic: support nul buffer with qc_free_ncbuf()

qc_free_ncbuf() may now be used with a NCBUF_NULL buffer as parameter.
This is useful when using this function on a QCS with no allocated
buffer. This case was not reproduced for the moment, but it will soon
become more present as buffers will be released if emptied.

Also a call to offer_buffers() is added to conform with the dynamic
buffer management of haproxy.

3 years agoMINOR: mux-quic: implement MAX_DATA emission
Amaury Denoyelle [Mon, 16 May 2022 14:19:59 +0000 (16:19 +0200)] 
MINOR: mux-quic: implement MAX_DATA emission

This commit is similar to the previous one but deals with MAX_DATA for
connection-level data flow control. It uses the same function
qcc_consume_qcs() to update flow control level and generate a MAX_DATA
frame if needed.

3 years agoMINOR: mux-quic: implement MAX_STREAM_DATA emission
Amaury Denoyelle [Mon, 16 May 2022 12:38:25 +0000 (14:38 +0200)] 
MINOR: mux-quic: implement MAX_STREAM_DATA emission

Send MAX_STREAM_DATA frames when at least half of the allocated
flow-control has been demuxed, frame and cleared. This is necessary to
support QUIC STREAM with received data greater than a buffer.

Transcoders must use the new function qcc_consume_qcs() to empty the QCS
buffer. This will allow to monitor current flow-control level and
generate a MAX_STREAM_DATA frame if required. This frame will be emitted
via qc_io_cb().

3 years agoMINOR: mux-quic: reorganize flow-control frames emission
Amaury Denoyelle [Mon, 16 May 2022 12:29:59 +0000 (14:29 +0200)] 
MINOR: mux-quic: reorganize flow-control frames emission

Adjust the mechanism for MAX_STREAMS_BIDI emission. When a bidirectional
stream is removed, current flow-control level is checked. If needed, a
MAX_STREAMS_BIDI frame is generated and inserted in a new list in the
QCS instance. The new frames will be emitted at the start of qc_send().

This has no impact on the current MAX_STREAMS_BIDI behavior. However,
this mechanism is more flexible and will allow to implement quickly
MAX_STREAM_DATA/MAX_DATA emission.

3 years agoMINOR: mux-quic: remove qcc_decode_qcs() call in XPRT
Amaury Denoyelle [Wed, 18 May 2022 09:38:22 +0000 (11:38 +0200)] 
MINOR: mux-quic: remove qcc_decode_qcs() call in XPRT

Slightly change the interface for qcc_recv() between MUX and XPRT. The
MUX is now responsible to call qcc_decode_qcs(). This is cleaner as now
the XPRT does not have to deal with an extra QCS parameter and the MUX
will call qcc_decode_qcs() only if really needed.

This change is possible since there is no extra buffering for
out-of-order STREAM frames and the XPRT does not have to handle buffered
frames.

3 years agoMEDIUM: mux-quic: implement recv on io-cb
Amaury Denoyelle [Mon, 16 May 2022 11:54:59 +0000 (13:54 +0200)] 
MEDIUM: mux-quic: implement recv on io-cb

Previously, qc_io_cb() of mux-quic only dealt with TX. Add support for
RX in it. This is done through a new function qc_recv(qcc). It loops
over all QCS instances and call qcc_decode_qcs(qcs).

This has no impact from the quic-conn layer as qcc_decode_qcs(qcs) is
called directly. However, this allows to have a resume point when demux
is blocked on the upper layer HTX full buffer.

Note that for the moment, only RX for bidirectional streams is managed
in qc_io_cb(). Unidirectional streams use their own mechanism for both
TX/RX. It should be unified in the near future in a refactoring.

3 years agoMINOR: h3: flag demux as full on HTX full
Amaury Denoyelle [Mon, 16 May 2022 11:54:31 +0000 (13:54 +0200)] 
MINOR: h3: flag demux as full on HTX full

Flag QCS if HTX buffer is full on demux. This will block all future
operations on QCS demux and should limit unnecessary decode_qcs() calls.
The flag is cleared on rcv_buf operation called by conn-stream.

3 years agoMINOR: h3: do not wait a complete frame for demuxing
Amaury Denoyelle [Thu, 12 May 2022 14:56:16 +0000 (16:56 +0200)] 
MINOR: h3: do not wait a complete frame for demuxing

Previously, H3 demuxer refused to proceed the payload if the frame was
not entirely received and the QCS buffer is not full. This code was
duplicated from the H2 demuxer.

In H2, this is a justified optimization as only one frame at a time can
be demuxed. However, this is not the case in H3 with interleaved frames
in the lower layer QUIC STREAM frames.

This condition is now removed. H3 demuxer will proceed payload as soon
as possible. An exception is kept for HEADERS frame as the code is not
able to deal with partial HEADERS.

With this change, H3 demuxer should consume less memory. To ensure that
we never received a HEADER bigger than the RX buffer, we should use the
H3 SETTINGS_MAX_FIELD_SECTION_SIZE.

3 years agoBUG/MINOR: mux-quic: update session's idle delay before stream creation
Amaury Denoyelle [Tue, 17 May 2022 16:03:37 +0000 (18:03 +0200)] 
BUG/MINOR: mux-quic: update session's idle delay before stream creation

This commit is an adaptation from the following patch :
  commit d0de6776826ee18da74e6949752e2f44cba8fdf2
  Author: Willy Tarreau <w@1wt.eu>
  Date:   Fri Feb 4 09:05:37 2022 +0100
  BUG/MINOR: mux-h2: update the session's idle delay before creating the stream

This should fix the incorrect timeouts present in httplog format for
QUIC requests.

3 years agoMINOR: ncbuf: refactor ncb_advance()
Amaury Denoyelle [Tue, 17 May 2022 16:52:39 +0000 (18:52 +0200)] 
MINOR: ncbuf: refactor ncb_advance()

First adjusted some typos in comments inside the function. Second,
change the naming of some variable to reduce confusion.

A special case has been inserted when advance is done inside a GAP block
and this block is the last of the buffer. In this case, the whole buffer
will be emptied, equivalent to a ncb_init() operation.

3 years agoBUG/MINOR: ncbuf: fix ncb_is_empty()
Amaury Denoyelle [Tue, 17 May 2022 16:52:22 +0000 (18:52 +0200)] 
BUG/MINOR: ncbuf: fix ncb_is_empty()

ncb_is_empty() was plainly incorrect as it directly dereferences the
memory to read offset blocks instead of ncb_read_off(). The result is
undefined.

Also, BUG_ON() statement is wrong when the buffer starts with a data
block. In this case, ncb_head() is not the first gap offset but instead
just random data. The calculated sum in BUG_ON() statement has thus no
meaning and may cause an abort. Adjust this by reorganizing the whole
function. Only the first data block size is read. If and only if not
nul, the first gap size is then checked.

ncb_is_full() has been rewritten to share the same model as
ncb_is_empty().

3 years agoOPTIM: quic: realign empty Rx buffer
Amaury Denoyelle [Tue, 17 May 2022 13:01:25 +0000 (15:01 +0200)] 
OPTIM: quic: realign empty Rx buffer

quic_rx_pkts_del() function removes packets from QUIC RX buffer. In most
cases, the buffer will be emptied after it. In this case, it's useful to
realign it. This will avoid future data wrapping and use of an
unnecessary junk to fill a too small contiguous space.

3 years agoBUG/MEDIUM: quic: fix Rx buffering
Amaury Denoyelle [Mon, 16 May 2022 16:13:56 +0000 (18:13 +0200)] 
BUG/MEDIUM: quic: fix Rx buffering

The quic-conn manages a buffer to store received QUIC packets. When the
buffer wraps, the gap is filled until the end with junk and packets can
be inserted at the start of the buffer.

On the other end, deletion is implemented via quic_rx_pkts_del().
Packets are removed one by one if their refcount is nul. If junk is
found, the buffer is emptied until its wrap.

This seems to work in most cases but a bug was found in a particular
case : on insertion if buffer gap is not at the end of the buffer. In
this case, the gap was filled, which is useless as now the buffer is
full and the packet cannot be inserted. Worst, on deletion, when junk is
removed there is a risk to removed new packets. This can happens in the
following case :
1. buffer contig space is too small, junk is inserted in the middle of
   it
2. on quic_rx_pkts_del() invocation, a packet is removed, but not the
   next one because its refcount is still positive. When a new packet is
   received, it will be stored after the junk.
3. on next quic_rx_pkts_del(), when junk is removed, all contig data is
   cleared, with newer packets data too.

This will cause a transfer between a client and haproxy to be stalled.
This can be reproduced with big enough POST requests. I triggered it
with ngtcp2 and 10M of posted data.

Hopefully, the solution of this bug is simple. If contig space is not
big enough to store a packet, but the space is not at the end of the
buffer, no junk is inserted and the packet is dropped as we cannot
buffered it. This ensures that junk is only present at the end of the
buffer and when removed no packets data is purged with it.

3 years agoCLEANUP: httpclient: Remove useless test on ss_dst in httpclient_applet_init()
Christopher Faulet [Wed, 18 May 2022 07:29:32 +0000 (09:29 +0200)] 
CLEANUP: httpclient: Remove useless test on ss_dst in httpclient_applet_init()

In httpclient_applet_init() function, ss_dst variable is always defined
before the call to sockaddr_alloc(). There is no reason to test it.

This patch should fix the issue #1706.

3 years agoCLEANUP: peers: Remove unreachable code in peer_session_create()
Christopher Faulet [Wed, 18 May 2022 06:02:37 +0000 (08:02 +0200)] 
CLEANUP: peers: Remove unreachable code in peer_session_create()

An error label is now unreachable in peer_session_create().

This patch should fix the issue #1704.

3 years agoBUG/MINOR: spoe: Fix error handling in spoe_init_appctx()
Christopher Faulet [Wed, 18 May 2022 05:42:49 +0000 (07:42 +0200)] 
BUG/MINOR: spoe: Fix error handling in spoe_init_appctx()

labels used in goto statement was not called in the right order. Thus if
there is an error during the appctx startup, it is possible to leak a task.

This patch should fix the issue #1703. No backport needed.

3 years agoCLEANUP: http_ana: Make use of the return value of stream_generate_unique_id()
Tim Duesterhus [Tue, 17 May 2022 22:22:15 +0000 (00:22 +0200)] 
CLEANUP: http_ana: Make use of the return value of stream_generate_unique_id()

Even if `unique_id` and `s->unique_id` are identical it is a bit odd to
`isttest()` `unique_id` and then use `s->unique_id` in the call to `http_add_header()`.

This "issue" was introduced in a17e66289c08a5bfadc1bb5b5f2c618c9299fe1b,
because before that commit the function returned the length of the ID, as it
was not an ist.

3 years agoMINOR: ssl: Add 'ssl-provider-path' global option
Remi Tricot-Le Breton [Tue, 17 May 2022 13:18:37 +0000 (15:18 +0200)] 
MINOR: ssl: Add 'ssl-provider-path' global option

When loading providers with 'ssl-provider' global options, this
ssl-provider-path option can be used to set the search path that is to
be used by openssl. It behaves the same way as the OPENSSL_MODULES
environment variable.

3 years agoREGTESTS: abortonclose: Fix some race conditions
Christopher Faulet [Tue, 17 May 2022 13:08:22 +0000 (15:08 +0200)] 
REGTESTS: abortonclose: Fix some race conditions

Depending on the timing, the second client that should be reported as a
client abort during connection attempt ("CC--" termination state) is
sometime logged as a server close ("SC--" termination state) instead. It
happens because sometime the connection failure to the server s1 is detected
by haproxy before the client c2 aborts. There is no retries and the
connection timeout is set to 100ms. So, to work, the client abort must be
performed and detected by haproxy in less than 100ms.

To fix the issue, the c2 client is now routed to a backend with a connection
timeout set to 1 second and 10 retries. It should be large enough to detect
the client aborts (~10s)

In addition, there is another race condition when the script is
started. sometime, server s1 is not stopped when the first client sends its
request. So a barrier was added to be sure it is stopped before starting to
send requests. And we wait to be sure the server is detected as DOWN to
unblock the barrier. It is performed by a dedicated backend with an
healthcheck on the server s1.

This patch should solve issue #1664.

3 years agoCLEANUP: proxy: Remove dead code when parsing "http-restrict-req-hdr-names" option
Christopher Faulet [Tue, 17 May 2022 12:46:15 +0000 (14:46 +0200)] 
CLEANUP: proxy: Remove dead code when parsing "http-restrict-req-hdr-names" option

negation or default modifiers are not supported for this option. However,
this was already tested earlier in cfg_parse_listen() function. Thus, when
"http-restrict-req-hdr-names" option is parsed, the keyword modifier is
always equal to KWM_STD. It is useless to test it again at this place.

This patch should solve the issue #1702.

3 years agoMINOR: conn-stream/applet: Stop setting appctx as the endpoint context
Christopher Faulet [Mon, 16 May 2022 15:29:37 +0000 (17:29 +0200)] 
MINOR: conn-stream/applet: Stop setting appctx as the endpoint context

The appctx is already the endpoint target. It is confusing to also use it to
set the endpoint context. So, never set the endpoint ctx when an appctx is
created or attached to an existing conn-stream.

3 years agoMEDIUM: peers: Balance applets across threads
Maciej Zdeb [Mon, 16 May 2022 15:27:28 +0000 (17:27 +0200)] 
MEDIUM: peers: Balance applets across threads

When creating a new applet for peer outgoing connection, we check
the load on each thread. Threads with least applet count are
preferred.

With this solution we avoid a situation when many outgoing
connections run on the same thread causing significant load on
single CPU core.

3 years agoMINOR: peers: Track number of applets run by thread
Maciej Zdeb [Mon, 16 May 2022 15:26:20 +0000 (17:26 +0200)] 
MINOR: peers: Track number of applets run by thread

Maintain number of peers applets run on all threads. It will be used
in next patch for least loaded thread selection.

3 years agoMEDIUM: applet: Add support for async appctx startup on a thread subset
Christopher Faulet [Mon, 16 May 2022 15:15:31 +0000 (17:15 +0200)] 
MEDIUM: applet: Add support for async appctx startup on a thread subset

It is now possible to start an appctx on a thread subset. Some controls were
added here and there. It is forbidden to start a backend appctx on another
thread than the local one. If a frontend appctx is started on another thread
or a thread subset, the applet .init callback function must be defined. This
callback function is responsible to finalize the appctx startup. It can be
performed synchornously. In this case, the appctx is started on the local
thread. It is not really useful but it is valid. Or it can be performed
asynchronously. In this case, .init callback function is called when the
appctx is woken up for the first time. When this happens, the appctx
affinity is set to the current thread to be able to start the session and
the stream.

3 years agoMINOR: applet: Add API to start applet on a thread subset
Christopher Faulet [Mon, 16 May 2022 15:09:48 +0000 (17:09 +0200)] 
MINOR: applet: Add API to start applet on a thread subset

In the same way than for the tasks, the applets api was changed to be able
to start a new appctx on a thread subset. For now the feature is
disabled. Only appctx_new_here() is working. But it will be possible to
start an appctx on a specific thread or a subset via a mask.

3 years agoMEDIUM: peers: Refactor peer appctx creation
Christopher Faulet [Thu, 12 May 2022 13:36:11 +0000 (15:36 +0200)] 
MEDIUM: peers: Refactor peer appctx creation

A .init callback function is defined for the peer_applet applet. This
function finishes the appctx startup by calling appctx_finalize_startup()
and its handles the stream customization.

3 years agoMINOR: peers: Add a ref to peers section in the peer structure
Christopher Faulet [Thu, 12 May 2022 12:47:52 +0000 (14:47 +0200)] 
MINOR: peers: Add a ref to peers section in the peer structure

This change is required to handle asynchrone init of the appctx. It is now
possible to directly get the peers section associated to a peer.

3 years agoMEDIUM: sink: Refactor sink forwarder appctx creation
Christopher Faulet [Thu, 12 May 2022 13:34:48 +0000 (15:34 +0200)] 
MEDIUM: sink: Refactor sink forwarder appctx creation

A .init callback function is defined for the sink_forward_applet applet.
This function finishes the appctx startup by calling
appctx_finalize_startup() and its handles the stream customization.

3 years agoMINOR: sink: Add a ref to sink in the sink_forward_target structure
Christopher Faulet [Thu, 12 May 2022 12:50:09 +0000 (14:50 +0200)] 
MINOR: sink: Add a ref to sink in the sink_forward_target structure

This change is required to be able to refactor the init stage of appctx. It
is now possible to directly get the sink from a forward target.

3 years agoMEDIUM: httpclient: Refactor http-client appctx creation
Christopher Faulet [Thu, 12 May 2022 13:33:14 +0000 (15:33 +0200)] 
MEDIUM: httpclient: Refactor http-client appctx creation

A .init callback function is defined for the httpclient_applet applet. This
function finishes the appctx startup by calling appctx_finalize_startup()
and its handles the stream customization.

3 years agoMEDIUM: lua: Refactor cosocket appctx creation
Christopher Faulet [Thu, 12 May 2022 13:31:05 +0000 (15:31 +0200)] 
MEDIUM: lua: Refactor cosocket appctx creation

A .init callback function is defined for the update_applet applet. This
function finishes the appctx startup by calling appctx_finalize_startup()
and its handles the stream customization.

3 years agoMEDIUM: spoe: Refactor SPOE appctx creation
Christopher Faulet [Thu, 12 May 2022 13:28:51 +0000 (15:28 +0200)] 
MEDIUM: spoe: Refactor SPOE appctx creation

A .init callback function is defined for the spoe_applet applet. This
function finishes the spoe_appctx initialization. It also finishes the
appctx startup by calling appctx_finalize_startup() and its handles the
stream customization.

3 years agoMEDIUM: dns: Refactor dns appctx creation
Christopher Faulet [Thu, 12 May 2022 13:24:46 +0000 (15:24 +0200)] 
MEDIUM: dns: Refactor dns appctx creation

A .init callback function is defined for the dns_session_applet applet. This
function finishes the appctx startup by calling appctx_finalize_startup()
and its handles the stream customization.

3 years agoMINOR: applet: Add function to release appctx on error during init stage
Christopher Faulet [Thu, 12 May 2022 13:18:48 +0000 (15:18 +0200)] 
MINOR: applet: Add function to release appctx on error during init stage

appctx_free_on_early_error() must be used to release a freshly created
frontend appctx if an error occurred during the init stage. It takes care to
release the stream instead of the appctx if it exists. For a backend appctx,
it just calls appctx_free().

3 years agoMINOR: applet: Add a function to finalize frontend appctx startup
Christopher Faulet [Thu, 12 May 2022 13:15:53 +0000 (15:15 +0200)] 
MINOR: applet: Add a function to finalize frontend appctx startup

appctx_finalize_startup() may be used to finalize the frontend appctx
startup. It is responsible to create the appctx's session and the frontend
conn-stream. On error, it is the caller responsibility to release the
appctx. However, the session is released if it was created. On success, if
an error is encountered in the caller function, the stream must be released
instead of the appctx.

This function should ease the init stage when new appctx is created.

3 years agoMINOR: applet: Add appctx_init() helper fnuction
Christopher Faulet [Thu, 12 May 2022 12:59:28 +0000 (14:59 +0200)] 
MINOR: applet: Add appctx_init() helper fnuction

It is just a helper function that call the .init applet callback function,
if it exists. This will simplify a bit the init stage when a new applet is
started. For now, this callback function is only used when a new service is
started.

3 years agoMINOR: stream: Export stream_free()
Christopher Faulet [Thu, 12 May 2022 12:56:55 +0000 (14:56 +0200)] 
MINOR: stream: Export stream_free()

The stream_free() function is now public. It is mandatory to properly handle
errors when a new applet is started.

3 years agoMINOR: applet: Change return value for .init callback function
Christopher Faulet [Thu, 12 May 2022 09:52:27 +0000 (11:52 +0200)] 
MINOR: applet: Change return value for .init callback function

0 is now returned on success and -1 on error.

3 years agoMINOR: applet: Let the frontend appctx release the session
Christopher Faulet [Wed, 11 May 2022 10:22:10 +0000 (12:22 +0200)] 
MINOR: applet: Let the frontend appctx release the session

The session created for frontend applets is now totally owns by the
corresponding appctx. It means the appctx is now responsible to release
it. This removes the hack in stream_free() about frontend applets to be sure
to release the session.

3 years agoMINOR: applet: Prepare appctx to own the session on frontend side
Christopher Faulet [Mon, 9 May 2022 06:08:26 +0000 (08:08 +0200)] 
MINOR: applet: Prepare appctx to own the session on frontend side

Applets were moved at the same level than multiplexers. Thus, gradually,
applets code is changed to be less dependent from the stream. With this
commit, the frontend appctx are ready to own the session. It means a
frontend appctx will be responsible to release the session.

3 years agoCLEANUP: conn-stream: Remove cs_applet_shut declaration from header file
Christopher Faulet [Wed, 11 May 2022 09:52:53 +0000 (11:52 +0200)] 
CLEANUP: conn-stream: Remove cs_applet_shut declaration from header file

This function was renamed and moved in applet code. cs_applet_shut() does
not exist anymore. Its declaration must be removed.

3 years agoBUG/MINOR: ssl: Fix crash when no private key is found in pem
Remi Tricot-Le Breton [Mon, 9 May 2022 09:07:13 +0000 (11:07 +0200)] 
BUG/MINOR: ssl: Fix crash when no private key is found in pem

If no private key can be found in a bind line's certificate and
ssl-load-extra-files is set to none we end up trying to call
X509_check_private_key with a NULL key, which crashes.

This fix should be backported to all stable branches.

3 years agoMINOR: tools: add get_exec_path implementation for solaris based systems.
David Carlier [Sat, 14 May 2022 16:15:49 +0000 (17:15 +0100)] 
MINOR: tools: add get_exec_path implementation for solaris based systems.

We can use getexecname() which fetches AT_SUN_EXECNAME from the auxiliary
vectors.

3 years agoBUILD: fix build warning on solaris based systems with __maybe_unused.
David Carlier [Sat, 14 May 2022 16:10:50 +0000 (17:10 +0100)] 
BUILD: fix build warning on solaris based systems with __maybe_unused.

__maybe_unused is already defined there.

3 years agoCLEANUP: Remove unused function hlua_get_top_error_string
Tim Duesterhus [Sat, 14 May 2022 20:15:28 +0000 (22:15 +0200)] 
CLEANUP: Remove unused function hlua_get_top_error_string

This function has no prototype defined in a header and is not used in hlua.c
either, thus it can be safely removed. Found with -Wmissing-prototypes.

3 years agoCLEANUP: Add missing header to hlua_fcn.c
Tim Duesterhus [Sat, 14 May 2022 20:17:25 +0000 (22:17 +0200)] 
CLEANUP: Add missing header to hlua_fcn.c

Found with -Wmissing-prototypes:

    src/hlua_fcn.c:53:5: fatal error: no previous prototype for function 'hlua_checkboolean' [-Wmissing-prototypes]
    int hlua_checkboolean(lua_State *L, int index)
        ^
    src/hlua_fcn.c:53:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    int hlua_checkboolean(lua_State *L, int index)
    ^
    static
    1 error generated.

3 years agoCLEANUP: Add missing header to ssl_utils.c
Tim Duesterhus [Sat, 14 May 2022 20:15:26 +0000 (22:15 +0200)] 
CLEANUP: Add missing header to ssl_utils.c

Found with -Wmissing-prototypes:

    src/ssl_utils.c:22:5: fatal error: no previous prototype for function 'cert_get_pkey_algo' [-Wmissing-prototypes]
    int cert_get_pkey_algo(X509 *crt, struct buffer *out)
        ^
    src/ssl_utils.c:22:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    int cert_get_pkey_algo(X509 *crt, struct buffer *out)
    ^
    static
    1 error generated.

3 years agoMINOR: ssl: Add 'ssl-provider' global option
Remi Tricot-Le Breton [Mon, 16 May 2022 14:24:33 +0000 (16:24 +0200)] 
MINOR: ssl: Add 'ssl-provider' global option

When HAProxy is linked to an OpenSSLv3 library, this option can be used
to load a provider during init. You can specify multiple ssl-provider
options, which will be loaded in the order they appear. This does not
prevent OpenSSL from parsing its own configuration file in which some
other providers might be specified.
A linked list of the providers loaded from the configuration file is
kept so that all those providers can be unloaded during cleanup. The
providers loaded directly by OpenSSL will be freed by OpenSSL.

3 years agoMINOR: ssl: Add 'ssl-propquery' global option
Remi Tricot-Le Breton [Mon, 16 May 2022 14:24:32 +0000 (16:24 +0200)] 
MINOR: ssl: Add 'ssl-propquery' global option

This option can be used to define a default property query used when
fetching algorithms in OpenSSL providers. It follows the format
described in https://www.openssl.org/docs/man3.0/man7/property.html.
It is only available when haproxy is built with SSL support and linked
to OpenSSLv3 libraries.

3 years agoMEDIUM: ssl: Delay random generator initialization after config parsing
Remi Tricot-Le Breton [Mon, 16 May 2022 14:24:31 +0000 (16:24 +0200)] 
MEDIUM: ssl: Delay random generator initialization after config parsing

The random generator initialization needs to be performed before the
chroot but it is not needed before. If we want to add provider
configuration option to the configuration file, they need to be
processed before any call to a crypto-related OpenSSL function.
We can then delay the initialization until after the configuration file
is parsed and processed.

3 years agoMEDIUM: http-ana: Add a proxy option to restrict chars in request header names
Christopher Faulet [Mon, 16 May 2022 09:43:10 +0000 (11:43 +0200)] 
MEDIUM: http-ana: Add a proxy option to restrict chars in request header names

The "http-restrict-req-hdr-names" option can now be set to restrict allowed
characters in the request header names to the "[a-zA-Z0-9-]" charset.

Idea of this option is to not send header names with non-alphanumeric or
hyphen character. It is especially important for FastCGI application because
all those characters are converted to underscore. For instance,
"X-Forwarded-For" and "X_Forwarded_For" are both converted to
"HTTP_X_FORWARDED_FOR". So, header names can be mixed up by FastCGI
applications. And some HAProxy rules may be bypassed by mangling header
names. In addition, some non-HTTP compliant servers may incorrectly handle
requests when header names contain characters ouside the "[a-zA-Z0-9-]"
charset.

When this option is set, the policy must be specify:

  * preserve: It disables the filtering. It is the default mode for HTTP
              proxies with no FastCGI application configured.

  * delete: It removes request headers with a name containing a character
            outside the "[a-zA-Z0-9-]" charset. It is the default mode for
            HTTP backends with a configured FastCGI application.

  * reject: It rejects the request with a 403-Forbidden response if it
            contains a header name with a character outside the
            "[a-zA-Z0-9-]" charset.

The option is evaluated per-proxy and after http-request rules evaluation.

This patch may be backported to avoid any secuirty issue with FastCGI
application (so as far as 2.2).

3 years agoMINOR: ncbuf: fix warnings for testing build
Amaury Denoyelle [Mon, 16 May 2022 09:09:05 +0000 (11:09 +0200)] 
MINOR: ncbuf: fix warnings for testing build

Using -Wall reveals several warning when building ncbuf testing API. One
of them was about the signedness mismatch. The other one was with an
incorrect print format.

3 years agoBUG/MEDIUM: ncbuf: fix null buffer usage
Amaury Denoyelle [Mon, 16 May 2022 09:09:29 +0000 (11:09 +0200)] 
BUG/MEDIUM: ncbuf: fix null buffer usage

ncbuf public API functions were not ready to deal with a NCBUF_NULL as
parameter. Strenghten these functions by handling it properly.

Most of the functions will consider the buffer as empty and silently
returns. The only exception is ncb_init(buf) which cannot be called
with a NCBUF_NULL. This seems legitimate to consider this as a bug and
not silently failed in this case.

3 years agoCI: determine actual LibreSSL version dynamically
Ilya Shipitsin [Fri, 13 May 2022 16:59:38 +0000 (21:59 +0500)] 
CI: determine actual LibreSSL version dynamically

this change introduce "LIBRESSL_VERSION=latest" semantic, which scans
http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/ and detects latest release.

LIBRESSL_VERSION=2.9.2 is removed from the matrix.

3 years ago[RELEASE] Released version 2.6-dev10 v2.6-dev10
Willy Tarreau [Sat, 14 May 2022 14:05:50 +0000 (16:05 +0200)] 
[RELEASE] Released version 2.6-dev10

Released version 2.6-dev10 with the following main changes :
    - MINOR: ssl: ignore dotfiles when loading a dir w/ ca-file
    - MEDIUM: ssl: ignore dotfiles when loading a dir w/ crt
    - BUG/MINOR: ssl: Fix typos in crl-file related CLI commands
    - MINOR: compiler: add a new macro to set an attribute on an enum when possible
    - BUILD: stats: conditionally mark obsolete stats states as deprecated
    - BUILD: ssl: work around bogus warning in gcc 12's -Wformat-truncation
    - BUILD: debug: work around gcc-12 excessive -Warray-bounds warnings
    - BUILD: listener: shut report of possible null-deref in listener_accept()
    - BUG/MEDIUM: ssl: fix the gcc-12 broken fix :-(
    - DOC: install: update gcc version requirements
    - BUILD: makefile: add -Wfatal-errors to the default flags
    - BUG/MINOR: server: Make SRV_STATE_LINE_MAXLEN value from 512 to 2kB (2000 bytes).
    - BUG/MAJOR: dns: multi-thread concurrency issue on UDP socket
    - BUG/MINOR: mux-h2: mark the stream as open before processing it not after
    - MINOR: mux-h2: report a trace event when failing to create a new stream
    - DOC: configuration: add the httpclient keywords to the global keywords index
    - MINOR: quic: Add a debug counter for sendto() errors
    - BUG/MINOR: quic: Dropped peer transport parameters
    - BUG/MINOR: quic: Wrong unit for ack delay for incoming ACK frames
    - MINOR: quic: Congestion controller event trace fix (loss)
    - MINOR: quic: Add correct ack delay values to ACK frames
    - MINOR: config: Add "cluster-secret" new global keyword
    - MINOR: quic-tls: Add quic_hkdf_extract_and_expand() for HKDF
    - MINOR: quic: new_quic_cid() code moving
    - MINOR: quic: Initialize stateless reset tokens with HKDF secrets
    - MINOR: qc_new_conn() rework for stateless reset
    - MINOR: quic: Stateless reset token copy to transport parameters
    - MINOR: quic: Send stateless reset tokens
    - MINOR: quic: Short packets always embed a trailing AEAD TAG
    - CLEANUP: quic: wrong use of eb*entry() macro
    - CLEANUP: quic: Useless use of pointer for quic_hkdf_extract()
    - CLEANUP: quic_tls: QUIC_TLS_IV_LEN defined two times
    - MINOR: ncbuf: define non-contiguous buffer
    - MINOR: ncbuf: complete API and define block interal abstraction
    - MINOR: ncbuf: optimize storage for the last gap
    - MINOR: ncbuf: implement insertion
    - MINOR: ncbuf: define various insertion modes
    - MINOR: ncbuf: implement advance
    - MINOR: ncbuf: write unit tests
    - BUG/MEDIUM: lua: fix argument handling in data removal functions
    - DOC/MINOR: fix typos in the lua-api document
    - BUG/MEDIUM: wdt: don't trigger the watchdog when p is unitialized
    - MINOR: mux-h1: Add global option accpet payload for any HTTP/1.0 requests
    - CLEANUP: mux-h1: Fix comments and error messages for global options
    - MINOR: conn_stream: make cs_set_error() work on the endpoint instead
    - CLEANUP: mux-h1: always take the endp from the h1s not the cs
    - CLEANUP: mux-h2: always take the endp from the h2s not the cs
    - CLEANUP: mux-pt: always take the endp from the context not the cs
    - CLEANUP: mux-fcgi: always take the endp from the fstrm not the cs
    - CLEANUP: mux-quic: always take the endp from the qcs not the cs
    - CLEANUP: applet: use the appctx's endp instead of cs->endp
    - MINOR: conn_stream: add a pointer back to the cs from the endpoint
    - MINOR: mux-h1: remove the now unneeded h1s->cs
    - MINOR: mux-h2: make sure any h2s always has an endpoint
    - MINOR: mux-h2: remove the now unneeded conn_stream from the h2s
    - MINOR: mux-fcgi: make sure any stream always has an endpoint
    - MINOR: mux-fcgi: remove the now unneeded conn_stream from the fcgi_strm
    - MINOR: mux-quic: remove the now unneeded conn_stream from the qcs
    - MINOR: mux-pt: remove the now unneeded conn_stream from the context
    - CLEANUP: muxes: make mux->attach/detach take a conn_stream endpoint
    - MINOR: applet: replace cs_applet_shut() with appctx_shut()
    - MINOR: applet: add appctx_strm() and appctx_cs() to access common fields
    - CLEANUP: applet: remove the unneeded appctx->owner
    - CLEANUP: conn_stream: merge cs_new_from_{mux,applet} into cs_new_from_endp()
    - MINOR: ext-check: indicate the transport and protocol of a server
    - BUG/MEDIUM: mux-quic: fix a thinko in the latest cs/endpoint cleanup
    - MINOR: tools: improve error message accuracy in str2sa_range
    - MINOR: config: make sure never to mix dgram and stream protocols on a bind line
    - BUG/MINOR: ncbuf: fix coverity warning on uninit sz_data
    - MINOR: xprt_quic: adjust flow-control according to bufsize
    - MEDIUM: mux-quic/h3/hq-interop: use ncbuf for bidir streams
    - MEDIUM: mux-quic/h3/qpack: use ncbuf for uni streams
    - CLEANUP: mux-quic: remove unused fields for Rx
    - CLEANUP: quic: remove unused quic_rx_strm_frm

3 years agoCLEANUP: quic: remove unused quic_rx_strm_frm
Amaury Denoyelle [Fri, 13 May 2022 13:42:19 +0000 (15:42 +0200)] 
CLEANUP: quic: remove unused quic_rx_strm_frm

quic_rx_strm_frm type was used to buffered STREAM frames received out of
order. Now the MUX is able to deal directly with these frames and
buffered it inside its ncbuf.

3 years agoCLEANUP: mux-quic: remove unused fields for Rx
Amaury Denoyelle [Fri, 13 May 2022 13:41:35 +0000 (15:41 +0200)] 
CLEANUP: mux-quic: remove unused fields for Rx

Rx has been simplified since the conversion of buffer to a ncbuf. The
old buffer can now be removed. The frms tree is also removed. It was
used previously to stored out-of-order received STREAM frames. Now the
MUX is able to buffer them directly into the ncbuf.

3 years agoMEDIUM: mux-quic/h3/qpack: use ncbuf for uni streams
Amaury Denoyelle [Fri, 13 May 2022 13:41:04 +0000 (15:41 +0200)] 
MEDIUM: mux-quic/h3/qpack: use ncbuf for uni streams

This commit is the equivalent for uni-streams of previous commit
  MEDIUM: mux-quic/h3/hq-interop: use ncbuf for bidir streams

All unidirectional streams data is now handle in MUX Rx ncbuf. The
obsolete buffer is not unused and will be cleared in the following
patches.

3 years agoMEDIUM: mux-quic/h3/hq-interop: use ncbuf for bidir streams
Amaury Denoyelle [Fri, 13 May 2022 12:49:05 +0000 (14:49 +0200)] 
MEDIUM: mux-quic/h3/hq-interop: use ncbuf for bidir streams

Add a ncbuf for data reception on qcs. Thanks to this, the MUX is able
to buffered all received frame directly into the buffer. Flow control
parameters will be used to ensure there is never an overflow.

This change will simplify Rx path with the future deletion of acked
frames tree previously used for frames out of order.

3 years agoMINOR: xprt_quic: adjust flow-control according to bufsize
Amaury Denoyelle [Fri, 13 May 2022 09:27:06 +0000 (11:27 +0200)] 
MINOR: xprt_quic: adjust flow-control according to bufsize

Redefine the initial local flow-control to enforce by us. Use bufsize as
the maximum offset allowed to be received.

This change is part of an adjustement on the Rx path. Mux buffer will be
converted to a ncbuf. Flow-control parameters must ensure that we never
receive a frame larger than the buffer. With this, all received frames
will be stored in the MUX buffer.

3 years agoBUG/MINOR: ncbuf: fix coverity warning on uninit sz_data
Amaury Denoyelle [Fri, 13 May 2022 13:33:50 +0000 (15:33 +0200)] 
BUG/MINOR: ncbuf: fix coverity warning on uninit sz_data

Coverity reports that data block generated by ncb_blk_first() has
sz_data field uninitialized. This has no real impact as it has no sense
for data block. Set to 0 to hide the warning.

This should fix github issue #1695.

3 years agoMINOR: config: make sure never to mix dgram and stream protocols on a bind line
Willy Tarreau [Tue, 26 Apr 2022 12:40:30 +0000 (14:40 +0200)] 
MINOR: config: make sure never to mix dgram and stream protocols on a bind line

It is absolutely not possible to use the same "bind" line to listen to
both quic and tcp for example, because no single transport layer would
fit both modes and we'll need the type to choose one then to choose a
mux. Let's make sure this does not happen. This may be relaxed in the
future if we manage to instantiate transport layers on the fly, but the
SSL vs quic part might be tricky to handle.

3 years agoMINOR: tools: improve error message accuracy in str2sa_range
Willy Tarreau [Mon, 9 May 2022 14:18:26 +0000 (16:18 +0200)] 
MINOR: tools: improve error message accuracy in str2sa_range

The error message when mixing stream and dgram protocols in an
address speaks about sockets while it ought to speak about addresses,
let's fix this as in some contexts it can be a bit confusing.

3 years agoBUG/MEDIUM: mux-quic: fix a thinko in the latest cs/endpoint cleanup
Willy Tarreau [Fri, 13 May 2022 14:31:23 +0000 (16:31 +0200)] 
BUG/MEDIUM: mux-quic: fix a thinko in the latest cs/endpoint cleanup

Fred & Amaury found that I messed up with qc_detach() in commit 4201ab791
("CLEANUP: muxes: make mux->attach/detach take a conn_stream endpoint"),
causing a segv in this case with endp->cs == NULL being passed to
__cs_mux(). It obviously ought to have been endp->target like in other
muxes.

No backport needed.

3 years agoMINOR: ext-check: indicate the transport and protocol of a server
Willy Tarreau [Fri, 13 May 2022 13:58:35 +0000 (15:58 +0200)] 
MINOR: ext-check: indicate the transport and protocol of a server

Valerio Pachera explained [1] that external checks would benefit from
having a variable indicating if SSL is being used or not on the server
being checked, and the discussion derived to also indicating the protocol
in use.

This patch adds two environment variables for external checks:
  - HAPROXY_SERVER_SSL: equals "0" when SSL is not used, "1" when it is
  - HAPROXY_SERVER_PROTO: contains one of the following words to describe
    the protocol used with this server:
      - "cli": the haproxy CLI. Normally not seen
      - "syslog": this is a syslog TCP server
      - "peers": this is a peers TCP server
      - "h1": this is an HTTP/1.x server
      - "h2": this is an HTTP/2 server
      - "tcp": this is any other TCP server

The patch is very simple, and may be backported to recent versions if
needed. This closes github issue #1692.

[1] https://www.mail-archive.com/haproxy@formilux.org/msg42233.html