]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
3 years agoCLEANUP: applet: use applet_put*() everywhere possible
Willy Tarreau [Wed, 18 May 2022 13:07:19 +0000 (15:07 +0200)] 
CLEANUP: applet: use applet_put*() everywhere possible

This applies the change so that the applet code stops using ci_putchk()
and friends everywhere possible, for the much saferapplet_put*() instead.
The change is mechanical but large. Two or three functions used to have no
appctx and a cs derived from the appctx instead, which was a reminiscence
of old times' stream_interface. These were simply changed to directly take
the appctx. No sensitive change was performed, and the old (more complex)
API is still usable when needed (e.g. the channel is already known).

The change touched roughly a hundred of locations, with no less than 124
lines removed.

It's worth noting that the stats applet, the oldest of the series, could
get a serious lifting, as it's still very channel-centric instead of
propagating the appctx along the chain. Given that this code doesn't
change often, there's no emergency to clean it up but it would look
better.

3 years agoMINOR: applet: add new wrappers to put chk/blk/str/chr to channel from appctx
Willy Tarreau [Wed, 18 May 2022 09:38:31 +0000 (11:38 +0200)] 
MINOR: applet: add new wrappers to put chk/blk/str/chr to channel from appctx

The vast majority of calls to ci_putchk() etc are performed from applets
which directly know an endpoint. Figuring the correct API (writing into
input channel etc) isn't trivial for newcomers, and knowing that they
must mark the flag indicating a buffer full condition isn't trivial
either.

Here we're adding wrappers to these functions but to be used directly
from the appctx. That's already what is being done in multiple steps in
the applet code, where the endp is derived from the appctx, then the cs
from the endp, then the stream from the cs, then the channel from the
stream, and so on. But this time the function doesn't require to know
much of the internals, applet_putchr() writes a char from the appctx,
and marks the buffer full if needed. Period. This will allow to remove
a significant amount of obscure ci_putchk() and cs_ic() calls from the
code, hence a significant number of possible mistakes.

3 years agoMEDIUM: stconn: merge the app_ops and the data_cb fields
Willy Tarreau [Wed, 18 May 2022 08:17:16 +0000 (10:17 +0200)] 
MEDIUM: stconn: merge the app_ops and the data_cb fields

For historical reasons (stream-interface and connections), we used to
require two independent fields for the application level callbacks and
the transport-level functions. Over time the distinction faded away so
much that the low-level functions became specific to the application
and conversely. For example, applets may only work with streams on top
since they rely on the channels, and the stream-level functions differ
between applets and connections. Right now the application level only
contains a wake() callback and the low-level ones contain the functions
that act at the lower level to perform the shutr/shutw and at the upper
level to notify about readability and writability. Let's just merge them
together into a single set and get rid of this confusing distinction.
Note that the check ops do not define any app-level function since these
are only called by streams.

3 years agoMINOR: conn_stream: test the various ops functions before calling them
Willy Tarreau [Tue, 24 May 2022 06:17:58 +0000 (08:17 +0200)] 
MINOR: conn_stream: test the various ops functions before calling them

We currently call all ->shutr, ->chk_snd etc from ->ops unconditionally,
while the ->wake() call from data_cb is checked. Better check ops as
well for consistency, this will help get them merged.

3 years agoMINOR: check: export wake_srv_chk()
Willy Tarreau [Wed, 18 May 2022 07:11:52 +0000 (09:11 +0200)] 
MINOR: check: export wake_srv_chk()

We'll need it to centralize the stream connectors definitions.

3 years agoCLEANUP: stconn: tree-wide rename stconn states CS_ST/SB_* to SC_ST/SB_*
Willy Tarreau [Tue, 17 May 2022 17:47:17 +0000 (19:47 +0200)] 
CLEANUP: stconn: tree-wide rename stconn states CS_ST/SB_* to SC_ST/SB_*

This also follows the natural naming. There are roughly 238 changes, all
totally trivial. conn_stream-t.h has become completely void of any
"conn_stream" related stuff now (except its name).

3 years agoCLEANUP: stconn: tree-wide rename stream connector flags CS_FL_* to SC_FL_*
Willy Tarreau [Tue, 17 May 2022 17:44:42 +0000 (19:44 +0200)] 
CLEANUP: stconn: tree-wide rename stream connector flags CS_FL_* to SC_FL_*

This follows the natural naming. There are roughly 100 changes, all
totally trivial.

3 years agoCLEANUP: stream: rename "csf" and "csb" to "scf" and "scb"
Willy Tarreau [Tue, 17 May 2022 17:40:40 +0000 (19:40 +0200)] 
CLEANUP: stream: rename "csf" and "csb" to "scf" and "scb"

These are the stream connectors, let's give them consistent names. The
patch is large (405 locations) but totally trivial.

3 years agoCLEANUP: stdesc: rename the stream connector ->cs field to ->sc
Willy Tarreau [Wed, 18 May 2022 05:43:52 +0000 (07:43 +0200)] 
CLEANUP: stdesc: rename the stream connector ->cs field to ->sc

This is a rename of this field. Most of the places were in muxes, but
were already factored with the previous series adding *_sc().

3 years agoCLEANUP: mux-pt: add and use pt_sc() to retrieve the stream connector
Willy Tarreau [Wed, 18 May 2022 05:36:10 +0000 (07:36 +0200)] 
CLEANUP: mux-pt: add and use pt_sc() to retrieve the stream connector

This is better and easier to adapt than pt->endp->cs.

3 years agoCLEANUP: mux-fcgi: add and use fcgi_strm_sc() to retrieve the stream connector
Willy Tarreau [Wed, 18 May 2022 05:34:16 +0000 (07:34 +0200)] 
CLEANUP: mux-fcgi: add and use fcgi_strm_sc() to retrieve the stream connector

This is better and easier to adapt than fstrm->endp->cs.

3 years agoCLEANUP: mux-h2: add and use h2s_sc() to retrieve the stream connector
Willy Tarreau [Wed, 18 May 2022 05:31:41 +0000 (07:31 +0200)] 
CLEANUP: mux-h2: add and use h2s_sc() to retrieve the stream connector

This is better and easier to adapt than h2s->endp->cs.

3 years agoCLEANUP: mux-h1: add and use h1s_sc() to retrieve the stream connector
Willy Tarreau [Wed, 18 May 2022 05:27:14 +0000 (07:27 +0200)] 
CLEANUP: mux-h1: add and use h1s_sc() to retrieve the stream connector

This is better and easier to adapt than h1s->endp->cs.

3 years agoCLEANUP: conn_stream: tree-wide rename to stconn (stream connector)
Willy Tarreau [Tue, 17 May 2022 17:07:51 +0000 (19:07 +0200)] 
CLEANUP: conn_stream: tree-wide rename to stconn (stream connector)

This renames the "struct conn_stream" to "struct stconn" and updates
the descriptions in all comments (and the rare help descriptions) to
"stream connector" or "connector". This touches a lot of files but
the change is minimal. The local variables were not even renamed, so
there's still a lot of "cs" everywhere.

3 years agoCLEANUP: conn_stream: rename cs_app_* to sc_app_*
Willy Tarreau [Tue, 17 May 2022 16:28:19 +0000 (18:28 +0200)] 
CLEANUP: conn_stream: rename cs_app_* to sc_app_*

Let's start to introduce the stream connector at the app_ops level.
This is entirely self-contained into conn_stream.c. The functions
were also updated to reflect the new name, and the comments were
updated.

3 years agoCLEANUP: conn_stream: rename the conn_stream's endp to sedesc
Willy Tarreau [Tue, 17 May 2022 16:20:02 +0000 (18:20 +0200)] 
CLEANUP: conn_stream: rename the conn_stream's endp to sedesc

Just like for the appctx, this is a pointer to a stream endpoint descriptor,
so let's make this explicit and not confuse it with the full endpoint. There
are very few changes thanks to the preliminary refactoring of the flags
manipulation.

3 years agoCLEANUP: applet: rename the sedesc pointer from "endp" to "sedesc"
Willy Tarreau [Tue, 17 May 2022 16:05:31 +0000 (18:05 +0200)] 
CLEANUP: applet: rename the sedesc pointer from "endp" to "sedesc"

Now at least it makes it obvious that it's the stream endpoint descriptor
and not an endpoint. There were few changes thanks to the previous refactor
of the flags.

3 years agoCLEANUP: conn_stream: rename cs_endpoint to sedesc (stream endpoint descriptor)
Willy Tarreau [Tue, 17 May 2022 15:53:22 +0000 (17:53 +0200)] 
CLEANUP: conn_stream: rename cs_endpoint to sedesc (stream endpoint descriptor)

After some discussion we found that the cs_endpoint was precisely the
descriptor for a stream endpoint, hence the naturally coming name,
stream endpoint constructor.

This patch renames only the type everywhere and the new/init/free functions
to remain consistent with it. Future patches will address field names and
argument names in various code areas.

3 years agoCLEANUP: conn_stream: rename the cs_endpoint's target to "se"
Willy Tarreau [Mon, 16 May 2022 15:29:42 +0000 (17:29 +0200)] 
CLEANUP: conn_stream: rename the cs_endpoint's target to "se"

That's the "stream endpoint" pointer. Let's change it now while it's
not much spread. The function __cs_endp_target() wasn't yet renamed
because that will change more globally soon.

3 years agoCLEANUP: conn_stream: rename the stream endpoint flags CS_EP_* to SE_FL_*
Willy Tarreau [Tue, 17 May 2022 15:04:55 +0000 (17:04 +0200)] 
CLEANUP: conn_stream: rename the stream endpoint flags CS_EP_* to  SE_FL_*

Let's now use the new flag names for the stream endpoint.

3 years agoCLEANUP: conn_stream: apply endp_flags.cocci tree-wide
Willy Tarreau [Tue, 17 May 2022 14:31:36 +0000 (16:31 +0200)] 
CLEANUP: conn_stream: apply endp_flags.cocci tree-wide

This changes all main uses of endp->flags to the se_fl_*() equivalent
by applying coccinelle script endp_flags.cocci. The se_fl_*() functions
themselves were manually excluded from the change, of course.

Note: 144 locations were touched, manually reviewed and found to be OK.

The script was applied with all includes:

  spatch --in-place --recursive-includes -I include --sp-file $script $files

3 years agoDEV: coccinelle: add endp_flags.cocci
Willy Tarreau [Tue, 17 May 2022 14:30:44 +0000 (16:30 +0200)] 
DEV: coccinelle: add endp_flags.cocci

This one turns the various forms of "endp->flags <op> value" to their
se_fl_<op>(cs) equivalent. That's basically the same as the previous
one except that it acts on the stream endpoint itself instead of the
conn_stream.

3 years agoCLEANUP: conn_stream: apply cs_endp_flags.cocci tree-wide
Willy Tarreau [Tue, 17 May 2022 14:10:17 +0000 (16:10 +0200)] 
CLEANUP: conn_stream: apply cs_endp_flags.cocci tree-wide

This changes all main uses of cs->endp->flags to the sc_ep_*() equivalent
by applying coccinelle script cs_endp_flags.cocci.

Note: 143 locations were touched, manually reviewed and found to be OK,
except a single one that was adjusted in cs_reset_endp() where the flags
are read and filtered to be used as-is and not as a boolean, hence was
replaced with sc_ep_get() & $FLAGS.

The script was applied with all includes:

  spatch --in-place --recursive-includes -I include --sp-file $script $files

3 years agoDEV: coccinelle: add cs_endp_flags.cocci
Willy Tarreau [Tue, 17 May 2022 14:08:36 +0000 (16:08 +0200)] 
DEV: coccinelle: add cs_endp_flags.cocci

This one turns the various forms of "cs->endp->flags <op> value" to
their sc_ep_<op>(cs) equivalent.

3 years agoMINOR: conn_stream: add new sets of functions to set/get endpoint flags
Willy Tarreau [Tue, 17 May 2022 13:39:33 +0000 (15:39 +0200)] 
MINOR: conn_stream: add new sets of functions to set/get endpoint flags

At plenty of places we need to manipulate the conn_stream's endpoint just
to set or clear a flag. This patch adds a handful of functions to perform
the common operations (clr/set/get etc) on these flags at both the endpoint
and at the conn_stream level.

The functions were named after the target names, i.e. se_fl_*() to act on
the stream endpoint flags, and sc_ep_* to manipulate the endpoint flags
from the stream connector (currently conn_stream).

For now they're not used.

3 years agoCLEANUP: conn_stream: rename the cs_endpoint's context to "conn"
Willy Tarreau [Mon, 16 May 2022 15:17:16 +0000 (17:17 +0200)] 
CLEANUP: conn_stream: rename the cs_endpoint's context to "conn"

This one is exclusively used by the connection, regardless its generic
name "ctx" is rather confusing. Let's make it a struct connection* and
call it "conn". This way there's no doubt about what it is and there's
no way it will be used by accident by being taken for something else.

3 years agoCLEANUP: conn_stream: remove unneeded exclusion of RX_WAIT_EP from RXBLK_ANY
Willy Tarreau [Tue, 24 May 2022 06:03:26 +0000 (08:03 +0200)] 
CLEANUP: conn_stream: remove unneeded exclusion of RX_WAIT_EP from RXBLK_ANY

This test in cs_update_rx() was introduced in 1.9 by commit b26a6f970
("MEDIUM: stream-int: make use of si_rx_chan_{rdy,blk} to control the
stream-int from the channel"), but by then already it was not needed
because the RX_WAIT_EP flag has never been part of RXBLK_ANY so there's
no point doing "flags & RXBLK_ANY & ~RX_WAIT_EP", that part is already
complicated enough like this.

3 years agoREGTESTS: Do not use REQUIRE_VERSION for HAProxy 2.5+ (2)
Tim Duesterhus [Mon, 23 May 2022 20:45:36 +0000 (22:45 +0200)] 
REGTESTS: Do not use REQUIRE_VERSION for HAProxy 2.5+ (2)

Introduced in:

18c13d3bd MEDIUM: http-ana: Add a proxy option to restrict chars in request header names

see also:

fbbbc33df REGTESTS: Do not use REQUIRE_VERSION for HAProxy 2.5+

3 years agoBUG/MEDIUM: sample: Fix adjusting size in word converter
Thayne McCombs [Thu, 26 May 2022 04:58:51 +0000 (22:58 -0600)] 
BUG/MEDIUM: sample: Fix adjusting size in word converter

Adjust the size of the sample buffer before we change the "area"
pointer. Otherwise, we end up not changing the size, because the area
pointer is already the same as "start" before we compute the difference
between the two.

This is similar to the change in b28430591d18f7fda5bac2e0ea590b3a34f04601
but for the word converter instead of field.

3 years agoBUG/MINOR: ssl/lua: use correctly cert_ext in CertCache.set()
William Lallemand [Thu, 26 May 2022 09:20:13 +0000 (11:20 +0200)] 
BUG/MINOR: ssl/lua: use correctly cert_ext in CertCache.set()

Fix a typo that lead to using the wrong pointer when loading a
certificate, which lead to always using the pem loader for every
parameeter.

Use the cert_ext->load() ptr instead of cert_exts->load() which was the
first element of the cert_exts[] array.

Enhance the error message with the field name.

Should fix issue #1716

3 years agoCLEANUP: init: address another coverity warning about a possible multiply overflow
Willy Tarreau [Thu, 26 May 2022 06:55:05 +0000 (08:55 +0200)] 
CLEANUP: init: address another coverity warning about a possible multiply overflow

Commit 2cb3be76b ("CLEANUP: init: address a coverity warning about
possible multiply overflow") was incomplete, two other locations were
present. This should address issue #1585.

3 years agoDOC: configuration: add a warning for @system-ca on bind
William Lallemand [Wed, 25 May 2022 22:18:46 +0000 (00:18 +0200)] 
DOC: configuration: add a warning for @system-ca on bind

Add a warning on @system-ca on the bind line so people don't use it this
way.

3 years agoRevert "BUG/MINOR: task: Don't defer tasks release when HAProxy is stopping"
Christopher Faulet [Wed, 25 May 2022 14:30:41 +0000 (16:30 +0200)] 
Revert "BUG/MINOR: task: Don't defer tasks release when HAProxy is stopping"

This reverts commit d9404b464faae3340ac1745b594929e4b7edd650.

In fact, there is a BUG_ON() in __task_free() function to be sure the task
is no longer in the wait-queue or the run-queue. Because the patch tries to
fix a "leak" on deinit, it is safer to revert it. there is no reason to
introduce potential bug for this kind of issues. And there is no reason to
impact the normal use-cases at runtime with additionnal conditions to only
remove a task on deinit.

3 years agoMINOR: h3: refactor SETTINGS parsing/error reporting
Amaury Denoyelle [Tue, 24 May 2022 16:16:49 +0000 (18:16 +0200)] 
MINOR: h3: refactor SETTINGS parsing/error reporting

Bring some improvment to h3_parse_settings_frm() function. The first one
is the parsing which now manipulates a buffer instead of a plain char*.
This is more to unify with other parsing functions rather than dealing
with data wrapping : it's unlikely to happen as SETTINGS is only
received as the first frame on the control STREAM.

Various errors are now properly reported as connection error :
* on incomplete frame payload
* on a duplicated settings in the same frame
* on reserved settings receive

3 years agoMINOR: h3: abort read on unknown uni stream
Amaury Denoyelle [Tue, 24 May 2022 15:22:07 +0000 (17:22 +0200)] 
MINOR: h3: abort read on unknown uni stream

As specified by HTTP/3 draft, an unknown unidirectional stream can be
aborted. To do this, use a new flag QC_SF_READ_ABORTED. When the MUX
detects this flag, QCS instance is automatically freed.

Previously, such streams were instead automatically drained. By aborting
them, we economize some useless memcpy instruction. On future data
reception, QCS instance is not found in the tree and considered as
already closed. The frame payload is thus deleted without copying it.

3 years agoCLEANUP: h3: remove h3 uni tasklet
Amaury Denoyelle [Tue, 24 May 2022 14:27:41 +0000 (16:27 +0200)] 
CLEANUP: h3: remove h3 uni tasklet

Remove all unnecessary bits of code for H3 unidirectional streams. Most
notable, an individual tasklet is not require anymore for each stream.
This is useless since the merge of RX/TX uni streams handling with
bidirectional streams code.

3 years agoMEDIUM: quic: refactor uni streams RX
Amaury Denoyelle [Tue, 24 May 2022 13:26:07 +0000 (15:26 +0200)] 
MEDIUM: quic: refactor uni streams RX

The whole QUIC stack is impacted by this change :
* at quic-conn level, a single function is now used to handle uni and
  bidirectional streams. It uses qcc_recv() function from MUX.
* at MUX level, qc_recv() io-handler function does not skip uni streams
* most changes are conducted at app layer. Most notably, all received
  data is handle by decode_qcs operation.

Now that decode_qcs is the single app read function, the H3 layer can be
simplified. Uni streams parsing was extracted from h3_attach_ruqs() to
h3_decode_qcs().

h3_decode_qcs() is able to deal with all HTTP/3 frame types. It first
check if the frame is valid for the H3 stream type. Most notably,
SETTINGS parsing was moved from h3_control_recv() into h3_decode_qcs().

This commit has some major benefits besides removing duplicated code.
Mainly, QUIC flow control is now enforced for uni streams as with bidi
streams. Also, an unknown frame received on control stream does not set
an error : it is now silently ignored as required by the specification.

Some cleaning in H3 code is already done with this patch :
h3_control_recv() and h3_attach_ruqs() are removed as they are now
unused. A final patch should clean up the unneeded remaining bit.

3 years agoMINOR: h3: define non-h3 generic parsing function
Amaury Denoyelle [Tue, 24 May 2022 13:25:19 +0000 (15:25 +0200)] 
MINOR: h3: define non-h3 generic parsing function

Define a new function h3_parse_uni_stream_no_h3(). It can be used to
handle the payload of streams which does not convey H3 frames. This is
mainly useful for QPACK encoder/decoder streams. It can also be used for
a stream of unknown type which should be drain without parsing it.

This patch is useful to extract code in a dedicated function. It will be
simple to reuse it in h3_decode_qcs() when uni-streams reception is
unify with bidirectional streams, without using dedicated stream tasklet.

3 years agoMINOR: h3: check if frame is valid for stream type
Amaury Denoyelle [Tue, 24 May 2022 13:24:32 +0000 (15:24 +0200)] 
MINOR: h3: check if frame is valid for stream type

Define a new function h3_is_frame_valid(). It returns if a frame is
valid or not depending on the stream which received it.

For the moment, it is used in h3_decode_qcs() which only deals with
bidirectional streams. Soon, uni streams will use the same function,
rendering the frame type check useful.

3 years agoMINOR: h3: refactor uni streams initialization
Amaury Denoyelle [Tue, 24 May 2022 13:14:53 +0000 (15:14 +0200)] 
MINOR: h3: refactor uni streams initialization

Define a new function h3_init_uni_stream(). This can be used to read the
stream type of an unidirectional stream. There is no functional change
with previous code.

This patch will be useful to unify reception for uni streams with
bidirectional ones.

3 years agoMINOR: h3: define stream type
Amaury Denoyelle [Tue, 24 May 2022 13:24:03 +0000 (15:24 +0200)] 
MINOR: h3: define stream type

Define a new enum h3s_t. This is used to differentiate between the
different stream types used in a HTTP/3 connection, including the QPACK
encoder/decoder streams.

For the moment, only bidirectional streams is positioned. This patch
will be useful to unify reception of uni streams with bidirectional
ones.

3 years agoMINOR: h3/qpack: use qcs as type in decode callbacks
Amaury Denoyelle [Mon, 23 May 2022 12:25:53 +0000 (14:25 +0200)] 
MINOR: h3/qpack: use qcs as type in decode callbacks

Replace h3_uqs type by qcs in stream callbacks. This change is done in
the context of unification between bidi and uni-streams. h3_uqs type
will be unneeded when this is achieved.

3 years agoBUG/MINOR: mux-quic: refactor uni streams TX/send H3 SETTINGS
Amaury Denoyelle [Mon, 23 May 2022 09:39:14 +0000 (11:39 +0200)] 
BUG/MINOR: mux-quic: refactor uni streams TX/send H3 SETTINGS

Remove the unneeded skip over unidirectional streams in qc_send(). This
unify sending for both uni and bidi streams.

In fact, the only local unidirectional streams in use for the moment is
the H3 Control stream responsible of SETTINGS emission. The frame was
already properly generated in qcs.tx.buf, but not send due to stream
skip in qc_send(). Now, there is no need to ignore uni streams so remove
this condition.

This fixes the emission of H3 settings which is now properly emitted.

Uni and bidi streams use the same set of funtcions for sending. One of
the most notable gain is that flow-control is now enforced for uni
streams.

3 years agoMINOR: mux-quic: emit STREAM_STATE_ERROR in qcc_recv
Amaury Denoyelle [Mon, 23 May 2022 14:12:49 +0000 (16:12 +0200)] 
MINOR: mux-quic: emit STREAM_STATE_ERROR in qcc_recv

Emit STREAM_STATE_ERROR connection error in two cases :
* if receiving data for send-only stream
* if receiving data on a locally initiated stream not open yet

For the moment the first case cannot be encoutered as uni streams
reception does not use qcc_recv(). However, this will be soon
implemented with the unification between bidi and uni streams.

3 years agoMINOR: h3: reject too big frames
Amaury Denoyelle [Tue, 24 May 2022 09:13:46 +0000 (11:13 +0200)] 
MINOR: h3: reject too big frames

The whole frame payload must have been received to demux a H3 frames,
except for H3 DATA which can be fragmented into multiple HTX blocks.

If the frame is bigger than the buffer and is not a DATA frame, a
connection error is reported with error H3_EXCESSIVE_LOAD.

This should be completed in the future with the H3 settings to limit the
size of uncompressed header section.

This code is more generic : it can handle every H3 frames. This is done
in order to be able to use h3_decode_qcs() to demux both uni and bidir
streams.

3 years agoMINOR: mux-quic: disable read on CONNECTION_CLOSE emission
Amaury Denoyelle [Tue, 24 May 2022 12:47:48 +0000 (14:47 +0200)] 
MINOR: mux-quic: disable read on CONNECTION_CLOSE emission

Similar to sending, read operations are disabled when a CONNECTION_CLOSE
frame has been emitted.

Most notably, this prevents unneeded loop demuxing when the H3 layer has
issue an error and cannot process the buffer payload anymore.

Note that read is not prevented for unidirectional streams for the
moment. This will supported soon with the unification of bidir and uni
streams treatment.

3 years agoMINOR: quic: support CONNECTION_CLOSE_APP emission
Amaury Denoyelle [Mon, 23 May 2022 14:12:15 +0000 (16:12 +0200)] 
MINOR: quic: support CONNECTION_CLOSE_APP emission

Complete quic-conn API for error reporting. A new parameter <app> is
defined in the function quic_set_connection_close(). This will transform
the frame into a CONNECTION_CLOSE_APP type.

This type of frame will be generated by the applicative layer, h3 or
hq-interop for the moment. A new function qcc_emit_cc_app() is exported
by the MUX layer for them.

3 years agoMINOR: h3: refactor h3_control_send()
Amaury Denoyelle [Tue, 24 May 2022 13:06:10 +0000 (15:06 +0200)] 
MINOR: h3: refactor h3_control_send()

The only change is that the H3_CF_SETTINGS_SENT flag if-condition is
replaced by a BUG_ON statement. This may help to catch multiple calls on
h3_control_send() instead of silently ignore them.

3 years agoBUG/MINOR: h3: prevent overflow when parsing SETTINGS
Amaury Denoyelle [Tue, 24 May 2022 14:30:11 +0000 (16:30 +0200)] 
BUG/MINOR: h3: prevent overflow when parsing SETTINGS

h3_parse_settings_frm() read one byte after the frame payload. Fix the
parsing code. In most cases, this has no impact as we are inside an
allocated buffer but it could cause a segfault depending on the buffer
alignment.

3 years agoCLEANUP: h3: rename uni stream type constants
Amaury Denoyelle [Mon, 23 May 2022 12:35:15 +0000 (14:35 +0200)] 
CLEANUP: h3: rename uni stream type constants

Cosmetic fix which reduce the name of unidirectional stream constants.
No impact on the code.

3 years agoCLEANUP: h3: rename struct h3 -> h3c
Amaury Denoyelle [Tue, 24 May 2022 12:55:43 +0000 (14:55 +0200)] 
CLEANUP: h3: rename struct h3 -> h3c

struct h3 represents the whole HTTP/3 connection. A new type h3s was
recently introduced to represent a single HTTP/3 stream. To facilitate
the analogy with other haproxy code, most notable in MUX, rename h3 type
to h3c.

3 years agoMINOR: mux-quic: adjust return value of decode_qcs
Amaury Denoyelle [Tue, 24 May 2022 09:07:28 +0000 (11:07 +0200)] 
MINOR: mux-quic: adjust return value of decode_qcs

Use 0 for success of decode_qcs operation else non-zero. This is to
follow the same model which is in use in most of the function in MUX/H3
code.

3 years agoMINOR: mux-quic: add traces in qc_recv()
Amaury Denoyelle [Mon, 23 May 2022 16:52:11 +0000 (18:52 +0200)] 
MINOR: mux-quic: add traces in qc_recv()

Just add traces in qc_recv() similarly to qc_send() function.

3 years agoMINOR: mux-quic: delay cs_endpoint allocation
Amaury Denoyelle [Tue, 24 May 2022 14:53:56 +0000 (16:53 +0200)] 
MINOR: mux-quic: delay cs_endpoint allocation

Do not allocate cs_endpoint for every QCS instances in qcs_new().
Instead, this is delayed to qc_attach_cs() function.

In effect, with H3 as app protocol, cs_endpoint will be allocated on
HEADERS parsing. Thus, no cs_endpoint is allocated for H3 unidirectional
streams which do not convey any HTTP data.

3 years agoMINOR: mux-quic: do not alloc quic_stream_desc for uni remote stream
Amaury Denoyelle [Tue, 24 May 2022 14:53:14 +0000 (16:53 +0200)] 
MINOR: mux-quic: do not alloc quic_stream_desc for uni remote stream

qc_stream_desc type is required for sending. Thus, it is not required
for an unidirectional remote stream where only receive will be
performed.

3 years agoMINOR: h3: mark ncbuf as const on h3_b_dup
Amaury Denoyelle [Tue, 24 May 2022 16:14:28 +0000 (18:14 +0200)] 
MINOR: h3: mark ncbuf as const on h3_b_dup

h3_b_dup() is used to obtains a ncbuf representation into a struct
buffer. ncbuf can thus be marked as a const parameter. This will allows
function which already manipulates a const ncbuf to use it.

3 years agoBUG/MINOR: task: Don't defer tasks release when HAProxy is stopping
Christopher Faulet [Wed, 25 May 2022 07:31:20 +0000 (09:31 +0200)] 
BUG/MINOR: task: Don't defer tasks release when HAProxy is stopping

A running or queued task is not released when task_destroy() is called,
except if it is the current task. Its process function is set to NULL and we
let the scheduler to release the task. However, when HAProxy is stopping, it
never happens and some tasks may leak. To fix the issue, we now also rely on
the global MODE_STOPPING flag. When this flag is set, the task is always
immediately released.

This patch should fix the issue #1714. It could be backported as far as 2.4
but it's not a real problem in practice because it only happens on
deinit. The leak exists on previous versions but not MODE_STOPPING flag.

3 years agoBUG/MEDIUM: peers: prevent unitialized multiple listeners on peers section
Emeric Brun [Wed, 25 May 2022 08:25:45 +0000 (10:25 +0200)] 
BUG/MEDIUM: peers: prevent unitialized multiple listeners on peers section

The previous fix:
BUG/MEDIUM: peers: fix segfault using multiple bind on peers

Prevents to declare multiple listeners on a peers sections but if
peers protocol is extended to support this we could raise the bug
again.

Indeed, after allocating a new listener and adding it to a list the
code mistakenly re-configure the first element of the list instead
of the new added one, and the last one remains finally uninitialized.
The previous fix assure there is no more than one listener in this
list but this could be changed in futur.

This patch patch assures we configure and initialize the newly added
listener instead of the first one in the list.

This patch could be backported until version 2.0 to complete
BUG/MEDIUM: peers: fix segfault using multiple bind on peers

3 years agoBUG/MEDIUM: peers: fix segfault using multiple bind on peers sections
Emeric Brun [Wed, 25 May 2022 08:12:07 +0000 (10:12 +0200)] 
BUG/MEDIUM: peers: fix segfault using multiple bind on peers sections

If multiple "bind" lines were present on the "peers" section, multiple
listeners were added to a list but the code mistakenly initialize
the first member and this first listener was re-configured instead of
the newly created one. The last one remains uninitialized causing a null
dereference a soon a connection is received.

In addition, the 'peers' sections and protocol are not currently designed to
handle multiple listeners.

This patch check if there is already a listener configured on the 'peers'
section when we want to create a new one. This is rising an error if
a listener is already present showing the file and line in the error
message.

To keep the file and line number of the previous listener available
for the error message, the 'bind_conf_uniq_alloc' function was modified
to keep the file/line data the struct 'bind_conf' was firstly
allocated (previously it was updated each time the 'bind_conf' was
reused).

This patch should be backported until version 2.0

3 years agoBUG/MEDIUM: resolvers: Don't defer resolutions release in deinit function
Christopher Faulet [Tue, 24 May 2022 16:10:42 +0000 (18:10 +0200)] 
BUG/MEDIUM: resolvers: Don't defer resolutions release in deinit function

resolvers_deinit() function is called on error, during post-parsing stage,
or on deinit, when HAProxy is stopped. It releases all entities: resolvers,
resolutions and SRV requests. There is no reason to defer the resolutions
release by moving them in the death_row list because this function is
terminal. And it is in fact a bug. Resolutions must not be released at the
end of the function because resolvers were already freed. However some
resolutions may still be attached to a reolver. Thus, when we try to remove
it from the resolver's tree, in resolv_reset_resolution(), this resolver was
already released.

So now, resolution are immediately released. It means there is no more
reason to track this function. calls to
enter_resolver_code()/leave_resolver_code() have been removed.

This patch should fix the issue #1680 and may be related to #1485. It must
be backported as far as 2.2.

3 years agoMEDIUM: h1: enlarge the scope of accepted version chars with accept-invalid-http...
Willy Tarreau [Tue, 24 May 2022 13:34:26 +0000 (15:34 +0200)] 
MEDIUM: h1: enlarge the scope of accepted version chars with accept-invalid-http-request

We used to support both RTSP and HTTP protocol version names with and
without accept-invalid-http-request, but since this is based on the
characters themselves, any protocol made of chars {0-9/.HPRST} was
possible and not others. Now that such non-standard protocols are
restricted to accept-invalid-http-request, there's no reason for not
allowing other letters. With this patch, characters {0-9./A-Z} are
permitted when the option is set.

3 years agoBUG/MEDIUM: http: Properly reject non-HTTP/1.x protocols
Tim Duesterhus [Mon, 9 Mar 2020 23:55:40 +0000 (00:55 +0100)] 
BUG/MEDIUM: http: Properly reject non-HTTP/1.x protocols

This patch hardens the verification of the HTTP/1.x version line
(i.e. the first line within an HTTP/1.x request) to verify that
the protocol name within the version actually reads "HTTP".

Previously protocols that superficially resembled the wire-format
of HTTP/1.x and having a 4-letter acronym as the protocol name, such
as RTSP would pass this check.

This patch fixes GitHub issue #540, it must be backported to all
supported versions. The legacy, non-HTX parser is affected as well,
a fix must be created for it as well.

Note that such protocols can still be used when option
accept-invalid-http-request is set.

3 years agoCLEANUP: init: address a coverity warning about possible multiply overflow
Willy Tarreau [Tue, 24 May 2022 05:43:57 +0000 (07:43 +0200)] 
CLEANUP: init: address a coverity warning about possible multiply overflow

In issue #1585 Coverity suspects a risk of multiply overflow when
calculating the SSL cache size, though in practice the cache is
limited to 2^32 anyway thus it cannot really happen. Nevertheless,
casting the operation should be sufficient to avoid marking it as a
false positive.

3 years agoRevert "MINOR: mux-quic: activate qmux traces on stdout via macro"
Amaury Denoyelle [Mon, 23 May 2022 07:25:19 +0000 (09:25 +0200)] 
Revert "MINOR: mux-quic: activate qmux traces on stdout via macro"

This reverts commit 251eadfce55b8e5d7a2ac2d87d17ba36147cb4ad.

This patch is similar to the previous revert for QUIC-MUX traces.

3 years agoRevert "MINOR: quic: activate QUIC traces at compilation"
Amaury Denoyelle [Mon, 23 May 2022 07:01:56 +0000 (09:01 +0200)] 
Revert "MINOR: quic: activate QUIC traces at compilation"

This reverts commit 118b2cbf8430a9513947c27a8403ff380e1dcaf2.

This patch was useful mainly for the docker image of QUIC interop to
have traces on stdout.

A better solution has been found by integrating this patch directly in
the qns repository which is used to build the docker image. Thus, this
hack is not require anymore in the main repository.

3 years agoBUG/MEDIUM: mux-quic: adjust buggy proxy closing support
Amaury Denoyelle [Mon, 23 May 2022 06:52:58 +0000 (08:52 +0200)] 
BUG/MEDIUM: mux-quic: adjust buggy proxy closing support

The wake handler detects if the frontend is closed. This can happen if
the proxy has been disabled individually or even on process soft-stop.
Before this patch, in this condition QCS instances were freed before
being detached from the cs_endpoint. This clearly violates the haproxy
connection architecture and cause a BUG_ON statement crash in cs_free().

To handle this properly, cs_endpoint is notified by setting RD_SH|WR_SH
on connection flags. The cs_endpoint will thus use the detach operation
which allows the QCS instance to be freed.

This code allows the soft-stop process to complete as soon as possible.
However, the client is not notified about the connection closing. It
should be done by emitting a H3 GOAWAY + CONNECTION_CLOSE. Sadly, this
is impossible at this stage because the listener sockets are closed so
the quic-conn cannot use it to emit new frames. At this stage the client
will most probably detect connection closing on its idle timeout
expiration.

Thus, to completely support proxy closing/soft-stop, important
architecture changes are required in QUIC socket management. This is
also linked with the reload feature.

3 years agoCLEANUP: tools: Crash if inet_ntop fails due to ENOSPC in sa2str
Tim Duesterhus [Mon, 23 May 2022 07:30:49 +0000 (09:30 +0200)] 
CLEANUP: tools: Crash if inet_ntop fails due to ENOSPC in sa2str

This is impossible, because we pass a destination buffer that is appropriately
sized to hold an IPv6 address.

This is related to GitHub issue #1599.

3 years agoBUG/MEDIUM: tools: Fix `inet_ntop` usage in sa2str
Tim Duesterhus [Sun, 22 May 2022 11:06:27 +0000 (13:06 +0200)] 
BUG/MEDIUM: tools: Fix `inet_ntop` usage in sa2str

The given size must be the size of the destination buffer, not the size of the
(binary) address representation.

This fixes GitHub issue #1599.

The bug was introduced in 92149f9a82a9b55c598f1cc815bc330c555f3561 which is in
2.4+. The fix must be backported there.

3 years agoCLEANUP: tools: Clean up non-QUIC error message handling in str2sa_range()
Tim Duesterhus [Sun, 22 May 2022 10:40:58 +0000 (12:40 +0200)] 
CLEANUP: tools: Clean up non-QUIC error message handling in str2sa_range()

If QUIC support is enabled both branches of the ternary conditional are
identical, upsetting Coverity. Move the full conditional into the non-QUIC
preprocessor branch to make the code more clear.

This resolves GitHub issue #1710.

3 years ago[RELEASE] Released version 2.6-dev11 v2.6-dev11
Willy Tarreau [Fri, 20 May 2022 21:31:51 +0000 (23:31 +0200)] 
[RELEASE] Released version 2.6-dev11

Released version 2.6-dev11 with the following main changes :
    - CI: determine actual LibreSSL version dynamically
    - BUG/MEDIUM: ncbuf: fix null buffer usage
    - MINOR: ncbuf: fix warnings for testing build
    - MEDIUM: http-ana: Add a proxy option to restrict chars in request header names
    - MEDIUM: ssl: Delay random generator initialization after config parsing
    - MINOR: ssl: Add 'ssl-propquery' global option
    - MINOR: ssl: Add 'ssl-provider' global option
    - CLEANUP: Add missing header to ssl_utils.c
    - CLEANUP: Add missing header to hlua_fcn.c
    - CLEANUP: Remove unused function hlua_get_top_error_string
    - BUILD: fix build warning on solaris based systems with __maybe_unused.
    - MINOR: tools: add get_exec_path implementation for solaris based systems.
    - BUG/MINOR: ssl: Fix crash when no private key is found in pem
    - CLEANUP: conn-stream: Remove cs_applet_shut declaration from header file
    - MINOR: applet: Prepare appctx to own the session on frontend side
    - MINOR: applet: Let the frontend appctx release the session
    - MINOR: applet: Change return value for .init callback function
    - MINOR: stream: Export stream_free()
    - MINOR: applet: Add appctx_init() helper fnuction
    - MINOR: applet: Add a function to finalize frontend appctx startup
    - MINOR: applet: Add function to release appctx on error during init stage
    - MEDIUM: dns: Refactor dns appctx creation
    - MEDIUM: spoe: Refactor SPOE appctx creation
    - MEDIUM: lua: Refactor cosocket appctx creation
    - MEDIUM: httpclient: Refactor http-client appctx creation
    - MINOR: sink: Add a ref to sink in the sink_forward_target structure
    - MEDIUM: sink: Refactor sink forwarder appctx creation
    - MINOR: peers: Add a ref to peers section in the peer structure
    - MEDIUM: peers: Refactor peer appctx creation
    - MINOR: applet: Add API to start applet on a thread subset
    - MEDIUM: applet: Add support for async appctx startup on a thread subset
    - MINOR: peers: Track number of applets run by thread
    - MEDIUM: peers: Balance applets across threads
    - MINOR: conn-stream/applet: Stop setting appctx as the endpoint context
    - CLEANUP: proxy: Remove dead code when parsing "http-restrict-req-hdr-names" option
    - REGTESTS: abortonclose: Fix some race conditions
    - MINOR: ssl: Add 'ssl-provider-path' global option
    - CLEANUP: http_ana: Make use of the return value of stream_generate_unique_id()
    - BUG/MINOR: spoe: Fix error handling in spoe_init_appctx()
    - CLEANUP: peers: Remove unreachable code in peer_session_create()
    - CLEANUP: httpclient: Remove useless test on ss_dst in httpclient_applet_init()
    - BUG/MEDIUM: quic: fix Rx buffering
    - OPTIM: quic: realign empty Rx buffer
    - BUG/MINOR: ncbuf: fix ncb_is_empty()
    - MINOR: ncbuf: refactor ncb_advance()
    - BUG/MINOR: mux-quic: update session's idle delay before stream creation
    - MINOR: h3: do not wait a complete frame for demuxing
    - MINOR: h3: flag demux as full on HTX full
    - MEDIUM: mux-quic: implement recv on io-cb
    - MINOR: mux-quic: remove qcc_decode_qcs() call in XPRT
    - MINOR: mux-quic: reorganize flow-control frames emission
    - MINOR: mux-quic: implement MAX_STREAM_DATA emission
    - MINOR: mux-quic: implement MAX_DATA emission
    - BUG/MINOR: mux-quic: support nul buffer with qc_free_ncbuf()
    - MINOR: mux-quic: free RX buf if empty
    - BUG/MEDIUM: config: Reset outline buffer size on realloc error in readcfgfile()
    - BUG/MINOR: check: Reinit the buffer wait list at the end of a check
    - MEDIUM: check: No longer shutdown the connection in .wake callback function
    - REORG: check: Rename and export I/O callback function
    - MEDIUM: check: Use the CS to handle subscriptions for read/write events
    - BUG/MINOR: quic: break for error on sendto
    - MINOR: quic: abort on unlisted errno on sendto()
    - MINOR: quic: detect EBADF on sendto()
    - BUG/MEDIUM: quic: fix initialization for local/remote TPs
    - CLEANUP: quic: adjust comment/coding style for TPs init
    - BUG/MINOR: cfgparse: abort earlier in case of allocation error
    - MINOR: quic: Dump initial derived secrets
    - MINOR: quic_tls: Add quic_tls_derive_retry_token_secret()
    - MINOR: quic_tls: Add quic_tls_decrypt2() implementation
    - MINOR: quic: Retry implementation
    - MINOR: cfgparse: Update for "cluster-secret" keyword for QUIC Retry
    - MINOR: quic: Move quic_lstnr_dgram_dispatch() out of xprt_quic.c
    - BUILD: stats: Missing headers inclusions from stats.h
    - MINOR: quic_stats: Add a new stats module for QUIC
    - MINOR: quic: Attach proxy QUIC stats counters to the QUIC connection
    - BUG/MINOR: quic: Fix potential memory leak during QUIC connection allocations
    - MINOR: quic: QUIC stats counters handling
    - MINOR: quic: Add tune.quic.retry-threshold keyword
    - MINOR: quic: Dynamic Retry implementation
    - MINOR: quic/mux-quic: define CONNECTION_CLOSE send API
    - MINOR: mux-quic: emit FLOW_CONTROL_ERROR
    - MINOR: mux-quic: emit STREAM_LIMIT_ERROR
    - MINOR: mux-quic: close connection on error if different data at offset
    - BUG/MINOR: peers: fix error reporting of "bind" lines
    - CLEANUP: config: improve address parser error report for unmatched protocols
    - CLEANUP: config: provide cleare hints about unsupported QUIC addresses
    - MINOR: protocol: replace ctrl_type with xprt_type and clarify it
    - MINOR: listener: provide a function to process all of a bind_conf's arguments
    - MINOR: config: use the new bind_parse_args_list() to parse a "bind" line
    - CLEANUP: listener: add a comment about what the BC_SSL_O_* flags are for
    - MINOR: listener: add a new "options" entry in bind_conf
    - CLEANUP: listener: replace all uses of bind_conf->is_ssl with BC_O_USE_SSL
    - CLEANUP: listener: replace bind_conf->generate_cers with BC_O_GENERATE_CERTS
    - CLEANUP: listener: replace bind_conf->quic_force_retry with BC_O_QUIC_FORCE_RETRY
    - CLEANUP: listener: store stream vs dgram at the bind_conf level
    - MINOR: listener: detect stream vs dgram conflict during parsing
    - MINOR: listener: set the QUIC xprt layer immediately after parsing the args
    - MINOR: listener/ssl: set the SSL xprt layer only once the whole config is known
    - MINOR: connection: add flag MX_FL_FRAMED to mark muxes relying on framed xprt
    - MINOR: config: detect and report mux and transport incompatibilities
    - MINOR: listener: automatically select a QUIC mux with a QUIC transport
    - MINOR: listener: automatically enable SSL if a QUIC transport is found
    - BUG/MINOR: quic: Fixe a typo in qc_idle_timer_task()
    - BUG/MINOR: quic: Missing <conn_opening> stats counter decrementation
    - BUILD/MINOR: cpuset fix build for FreeBSD 13.1
    - CI: determine actual OpenSSL version dynamically

3 years agoCI: determine actual OpenSSL version dynamically
Ilya Shipitsin [Fri, 20 May 2022 18:02:38 +0000 (23:02 +0500)] 
CI: determine actual OpenSSL version dynamically

this change introduce "OPENSSL_VERSION=latest" semantic, which scans
https://api.github.com/repos/openssl/openssl/tags and detects latest release.

3 years agoBUILD/MINOR: cpuset fix build for FreeBSD 13.1
David CARLIER [Wed, 18 May 2022 14:45:40 +0000 (15:45 +0100)] 
BUILD/MINOR: cpuset fix build for FreeBSD 13.1

the cpuset api changes done fir the future 14 release had been
backported to the 13.1 release so changing the cpuset api of choice
condition change accordingly.

3 years agoBUG/MINOR: quic: Missing <conn_opening> stats counter decrementation
Frédéric Lécaille [Fri, 20 May 2022 18:53:20 +0000 (20:53 +0200)] 
BUG/MINOR: quic: Missing <conn_opening> stats counter decrementation

When we receive a CONNECTION_CLOSE frame, we should decrement this counter
if the handshake state was not successful and if we have not received
a TLS alert from the TLS stack.

3 years agoBUG/MINOR: quic: Fixe a typo in qc_idle_timer_task()
Frédéric Lécaille [Fri, 20 May 2022 18:50:59 +0000 (20:50 +0200)] 
BUG/MINOR: quic: Fixe a typo in qc_idle_timer_task()

The & operator was confused with | operator :-(

3 years agoMINOR: listener: automatically enable SSL if a QUIC transport is found
Willy Tarreau [Fri, 20 May 2022 16:16:52 +0000 (18:16 +0200)] 
MINOR: listener: automatically enable SSL if a QUIC transport is found

When a bind line is configured without the "ssl" keyword, a warning is
emitted and a crash happens at runtime:

   bind quic4@:4449 crt rsa+dh2048.pem alpn h3 allow-0rtt

   [WARNING]  (17867) : config : Proxy 'decrypt': A certificate was specified but SSL was not enabled on bind 'quic4@:4449' at [quic-mini.cfg:24] (use 'ssl').

Let's automatically turn SSL on when QUIC is detected, as it doesn't
exist without SSL anyway. It solves the runtime issue, and also makes
sure it is not possible to accidentally configure a quic listener with
no certificate since the error is detected via the SSL checks.

A warning is emitted in this case, to encourage the user to fix the
configuration so that it remains reviewable.

3 years agoMINOR: listener: automatically select a QUIC mux with a QUIC transport
Willy Tarreau [Fri, 20 May 2022 16:07:06 +0000 (18:07 +0200)] 
MINOR: listener: automatically select a QUIC mux with a QUIC transport

When no mux protocol is configured on a bind line with "proto", and the
transport layer is QUIC, right now mux_h1 is being used, leading to a
crash.

Now when the transport layer of the bind line is already known as being
QUIC, let's automatically try to configure the QUIC mux, so that users
do not have to enter "proto quic" all the time while it's the only
supported option. this means that the following line now works:

    bind quic4@:4449 ssl crt rsa+dh2048.pem alpn h3 allow-0rtt

3 years agoMINOR: config: detect and report mux and transport incompatibilities
Willy Tarreau [Fri, 20 May 2022 15:53:32 +0000 (17:53 +0200)] 
MINOR: config: detect and report mux and transport incompatibilities

Till now, placing "proto h1" or "proto h2" on a "quic" bind or placing
"proto quic" on a TCP line would parse fine but would crash when traffic
arrived. The reason is that there's a strong binding between the QUIC
mux and QUIC transport and that they're not expected to be called with
other types at all.

Now that we have the mux's type and we know the type of the protocol used
on the bind conf, we can perform such checks. This now returns:

  [ALERT]    (16978) : config : frontend 'decrypt' : stream-based MUX protocol 'h2' is incompatible with framed transport of 'bind quic4@:4448' at [quic-mini.cfg:27].
  [ALERT]    (16978) : config : frontend 'decrypt' : frame-based MUX protocol 'quic' is incompatible with stream transport of 'bind :4448' at [quic-mini.cfg:29].

This config tightening is only tagged MINOR since while such a config,
despite not reporting error, cannot work at all so even if it breaks
experimental configs, they were just waiting for a single connection
to crash.

3 years agoMINOR: connection: add flag MX_FL_FRAMED to mark muxes relying on framed xprt
Willy Tarreau [Tue, 26 Apr 2022 09:54:08 +0000 (11:54 +0200)] 
MINOR: connection: add flag MX_FL_FRAMED to mark muxes relying on framed xprt

In order to be able to check compatibility between muxes and transport
layers, we'll need a new flag to tag muxes that work on framed transport
layers like QUIC. Only QUIC has this flag now.

3 years agoMINOR: listener/ssl: set the SSL xprt layer only once the whole config is known
Willy Tarreau [Fri, 20 May 2022 15:14:31 +0000 (17:14 +0200)] 
MINOR: listener/ssl: set the SSL xprt layer only once the whole config is known

We used to preset XPRT_SSL on bind_conf->xprt when parsing the "ssl"
keyword, which required to be careful about what QUIC could have set
before, and which makes it impossible to consider the whole line to
set all options.

Now that we have the BC_O_USE_SSL option on the bind_conf, it becomes
easier to set XPRT_SSL only once the bind_conf's args are parsed.

3 years agoMINOR: listener: set the QUIC xprt layer immediately after parsing the args
Willy Tarreau [Fri, 20 May 2022 15:10:00 +0000 (17:10 +0200)] 
MINOR: listener: set the QUIC xprt layer immediately after parsing the args

It used to be set when parsing the listeners' addresses but this comes
with some difficulties in that other places have to be careful not to
replace it (e.g. the "ssl" keyword parser).

Now we know what protocols a bind_conf line relies on, we can set it
after having parsed the whole line.

3 years agoMINOR: listener: detect stream vs dgram conflict during parsing
Willy Tarreau [Fri, 20 May 2022 14:20:52 +0000 (16:20 +0200)] 
MINOR: listener: detect stream vs dgram conflict during parsing

Now that we have a function to parse all bind keywords, and that we
know what types of sock-level and xprt-level protocols a bind_conf
is using, it's easier to centralize the check for stream vs dgram
conflict by putting it directly at the end of the args parser. This
way it also works for peers, provides better precision in the report,
and will also allow to validate transport layers. The check was even
extended to detect inconsistencies between xprt layer (which were not
covered before). It can even detect that there are two incompatible
"bind" lines in a single peers section.

3 years agoCLEANUP: listener: store stream vs dgram at the bind_conf level
Willy Tarreau [Fri, 20 May 2022 14:15:01 +0000 (16:15 +0200)] 
CLEANUP: listener: store stream vs dgram at the bind_conf level

Let's collect the set of xprt-level and sock-level dgram/stream protocols
seen on a bind line and store that in the bind_conf itself while they're
being parsed. This will make it much easier to detect incompatibilities
later than the current approch which consists in scanning all listeners
in post-parsing.

3 years agoCLEANUP: listener: replace bind_conf->quic_force_retry with BC_O_QUIC_FORCE_RETRY
Willy Tarreau [Fri, 20 May 2022 14:06:01 +0000 (16:06 +0200)] 
CLEANUP: listener: replace bind_conf->quic_force_retry with BC_O_QUIC_FORCE_RETRY

It was only set and used once, let's replace it now and take it out of
the ifdef.

3 years agoCLEANUP: listener: replace bind_conf->generate_cers with BC_O_GENERATE_CERTS
Willy Tarreau [Fri, 20 May 2022 14:03:18 +0000 (16:03 +0200)] 
CLEANUP: listener: replace bind_conf->generate_cers with BC_O_GENERATE_CERTS

The new flag will now replace this boolean variable.

3 years agoCLEANUP: listener: replace all uses of bind_conf->is_ssl with BC_O_USE_SSL
Willy Tarreau [Fri, 20 May 2022 13:56:32 +0000 (15:56 +0200)] 
CLEANUP: listener: replace all uses of bind_conf->is_ssl with BC_O_USE_SSL

The new flag will now replace this boolean variable that was only set and
tested.

3 years agoMINOR: listener: add a new "options" entry in bind_conf
Willy Tarreau [Fri, 20 May 2022 13:52:31 +0000 (15:52 +0200)] 
MINOR: listener: add a new "options" entry in bind_conf

There is no way to store useful info there, yet there's about one entry
per boolean. Let's add an "options" attribute which will collect various
options.

In practice, even the BC_O_SSL_* flags and a few info such as strict_sni
could move there.

3 years agoCLEANUP: listener: add a comment about what the BC_SSL_O_* flags are for
Willy Tarreau [Fri, 20 May 2022 13:51:14 +0000 (15:51 +0200)] 
CLEANUP: listener: add a comment about what the BC_SSL_O_* flags are for

They're for ->ssl_options but it wasn't obvious.

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.