]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
11 days agoMINOR: ssl: check TLS1.3 ciphersuites again in clienthello with recent AWS-LC
William Lallemand [Mon, 30 Jun 2025 14:20:29 +0000 (16:20 +0200)] 
MINOR: ssl: check TLS1.3 ciphersuites again in clienthello with recent AWS-LC

Patch ed9b8fec49 ("BUG/MEDIUM: ssl: AWS-LC + TLSv1.3 won't do ECDSA in
RSA+ECDSA configuration") partly fixed a cipher selection problem with
AWS-LC. However this was not checking anymore if the ciphersuites was
available in haproxy which is still a problem.

The problem was fixed in AWS-LC 1.46.0 with this PR
https://github.com/aws/aws-lc/pull/2092.

This patch allows to filter again the TLS13 ciphersuites with recent
versions of AWS-LC. However, since there are no macros to check the
AWS-LC version, it is enabled at the next AWS-LC API version change
following the fix in AWS-LC v1.50.0.

This could be backported where ed9b8fec49 was backported.

11 days agoMINOR: counters: rename last_change counter to last_state_change
Aurelien DARRAGON [Mon, 30 Jun 2025 13:55:56 +0000 (15:55 +0200)] 
MINOR: counters: rename last_change counter to last_state_change

Since proxy and server struct already have an internal last_change
variable and we cannot merge it with the shared counter one, let's
rename the last_change counter to be more specific and prevent the
mixup between the two.

last_change counter is renamed to last_state_change, and unlike the
internal last_change, this one is a shared counter so it is expected
to be updated by other processes in our back.

However, when updating last_state_change counter, we use the value
of the server/proxy last_change as reference value.

11 days agoMEDIUM: proxy: add and use a separate last_change variable for internal use
Aurelien DARRAGON [Mon, 30 Jun 2025 13:45:44 +0000 (15:45 +0200)] 
MEDIUM: proxy: add and use a separate last_change variable for internal use

Same motivation as previous commit, proxy last_change is "abused" because
it is used for 2 different purposes, one for stats, and the other one
for process-local internal use.

Let's add a separate proxy-only last_change variable for internal use,
and leave the last_change shared (and thread-grouped) counter for
statistics.

11 days agoMEDIUM: server: add and use a separate last_change variable for internal use
Aurelien DARRAGON [Mon, 30 Jun 2025 08:57:29 +0000 (10:57 +0200)] 
MEDIUM: server: add and use a separate last_change variable for internal use

last_change server metric is used for 2 separate purposes. First it is
used to report last server state change date for stats and other related
metrics. But it is also used internally, including in sensitive paths,
such as lb related stuff to take decision or perform computations
(ie: in srv_dynamic_maxconn()).

Due to last_change counter now being split over thread groups since 16eb0fa
("MAJOR: counters: dispatch counters over thread groups"), reading the
aggregated value has a cost, and we cannot afford to consult last_change
value from srv_dynamic_maxconn() anymore. Moreover, since the value is
used to take decision for the current process we don't wan't the variable
to be updated by another process in our back.

To prevent performance regression and sharing issues, let's instead add a
separate srv->last_change value, which is not updated atomically (given how
rare the  updates are), and only serves for places where the use of the
aggregated last_change counter/stats (split over thread groups) is too
costly.

11 days agoBUG/MEDIUM: counters/server: fix server and proxy last_change mixup
Aurelien DARRAGON [Mon, 30 Jun 2025 09:20:13 +0000 (11:20 +0200)] 
BUG/MEDIUM: counters/server: fix server and proxy last_change mixup

16eb0fa ("MAJOR: counters: dispatch counters over thread groups")
introduced some bugs: as a result of improper copy paste during
COUNTERS_SHARED_LAST() macro introduction, some functions such as
srv_downtime() which used to make use of the server last_change variable
now use the proxy one, which doesn't make sense and will likely cause
unexpected logical errors/bugs.

Let's fix them all at once by properly pointing to the server last_change
variable when relevant.

No backport needed.

2 weeks agoMINOR: mailers: warn if mailers are configured but not actually used
Aurelien DARRAGON [Fri, 27 Jun 2025 14:28:48 +0000 (16:28 +0200)] 
MINOR: mailers: warn if mailers are configured but not actually used

Now that native mailers configuration is only usable with Lua mailers,
Willy noticed that we lack a way to warn the user if mailers were
previously configured on an older version but Lua mailers were not loaded,
which could trick the user into thinking mailers keep working when
transitionning to 3.2 while it is not.

In this patch we add the 'core.use_native_mailers_config()' Lua function
which should be called in Lua script body before making use of
'Proxy:get_mailers()' function to retrieve legacy mailers configuration
from haproxy main config. This way haproxy effectively knows that the
native mailers config is actually being used from Lua (which indicates
user correctly migrated from native mailers to Lua mailers), else if
mailers are configured but not used from Lua then haproxy warns the user
about the fact that they will be ignored unless they are used from Lua.
(e.g.: using the provided 'examples/lua/mailers.lua' to ease transition)

2 weeks agoMINOR: server: move send-proxy* incompatibility check in _srv_check_proxy_mode()
Aurelien DARRAGON [Fri, 27 Jun 2025 10:03:30 +0000 (12:03 +0200)] 
MINOR: server: move send-proxy* incompatibility check in _srv_check_proxy_mode()

This way the check is executed no matter the section where the server
is declared (ie: not only under the "ring" section)

2 weeks agoMEDIUM: server: move _srv_check_proxy_mode() checks from server init to finalize
Aurelien DARRAGON [Fri, 27 Jun 2025 10:15:24 +0000 (12:15 +0200)] 
MEDIUM: server: move _srv_check_proxy_mode() checks from server init to finalize

_srv_check_proxy_mode() is currently executed during server init (from
_srv_parse_init()), while it used to be fine for current checks, it
seems it occurs a bit too early to be usable for some checks that depend
on server keywords to be evaluated for instance.

As such, to make _srv_check_proxy_mode() more relevant and be extended
with additional checks in the future, let's call it later during server
finalization, once all server keywords were evaluated.

No change of behavior is expected

2 weeks agoMEDIUM: sink: change the sink mode type to PR_MODE_SYSLOG
Aurelien DARRAGON [Fri, 27 Jun 2025 10:05:16 +0000 (12:05 +0200)] 
MEDIUM: sink: change the sink mode type to PR_MODE_SYSLOG

No change of behavior expected, but some compat checks will now be aware
that the proxy type is not TCP but SYSLOG instead.

2 weeks agoBUG/MINOR: quic-be: Wrong retry_source_connection_id check
Frederic Lecaille [Fri, 27 Jun 2025 05:53:28 +0000 (07:53 +0200)] 
BUG/MINOR: quic-be: Wrong retry_source_connection_id check

This commit broke the QUIC backend connection to servers without address validation
or retry activated:

  MINOR: quic-be: address validation support implementation (RETRY)

Indeed the retry_source_connection_id transport parameter was already checked as
as if it was required, as if the peer (server) was always using the address validation.
Furthermore, relying on ->odcid.len to ensure a retry token was received is not
correct.

This patch ensures the retry_source_connection_id transport parameter is checked
only when a retry token was received (->retry_token != NULL). In this case
it also checks that this transport parameter is present when a retry token
has been received (tx_params->retry_source_connection_id.len != 0).

No need to backport.

2 weeks ago[RELEASE] Released version 3.3-dev2 v3.3-dev2
Willy Tarreau [Thu, 26 Jun 2025 16:26:45 +0000 (18:26 +0200)] 
[RELEASE] Released version 3.3-dev2

Released version 3.3-dev2 with the following main changes :
    - BUG/MINOR: config/server: reject QUIC addresses
    - MINOR: server: implement helper to identify QUIC servers
    - MINOR: server: mark QUIC support as experimental
    - MINOR: mux-quic-be: allow QUIC proto on backend side
    - MINOR: quic-be: Correct Version Information transp. param encoding
    - MINOR: quic-be: Version Information transport parameter check
    - MINOR: quic-be: Call ->prepare_srv() callback at parsing time
    - MINOR: quic-be: QUIC backend XPRT and transport parameters init during parsing
    - MINOR: quic-be: QUIC server xprt already set when preparing their CTXs
    - MINOR: quic-be: Add a function for the TLS context allocations
    - MINOR: quic-be: Correct the QUIC protocol lookup
    - MINOR: quic-be: ssl_sock contexts allocation and misc adaptations
    - MINOR: quic-be: SSL sessions initializations
    - MINOR: quic-be: Add a function to initialize the QUIC client transport parameters
    - MINOR: sock: Add protocol and socket types parameters to sock_create_server_socket()
    - MINOR: quic-be: ->connect() protocol callback adaptations
    - MINOR: quic-be: QUIC connection allocation adaptation (qc_new_conn())
    - MINOR: quic-be: xprt ->init() adapatations
    - MINOR: quic-be: add field for max_udp_payload_size into quic_conn
    - MINOR: quic-be: Do not redispatch the datagrams
    - MINOR: quic-be: Datagrams and packet parsing support
    - MINOR: quic-be: Handshake packet number space discarding
    - MINOR: h3-be: Correctly retrieve h3 counters
    - MINOR: quic-be: Store asap the DCID
    - MINOR: quic-be: Build post handshake frames
    - MINOR: quic-be: Add the conn object to the server SSL context
    - MINOR: quic-be: Initial packet number space discarding.
    - MINOR: quic-be: I/O handler switch adaptation
    - MINOR: quic-be: Store the remote transport parameters asap
    - MINOR: quic-be: Missing callbacks initializations (USE_QUIC_OPENSSL_COMPAT)
    - MINOR: quic-be: Make the secret derivation works for QUIC backends (USE_QUIC_OPENSSL_COMPAT)
    - MINOR: quic-be: SSL_get_peer_quic_transport_params() not defined by OpenSSL 3.5 QUIC API
    - MINOR: quic-be: get rid of ->li quic_conn member
    - MINOR: quic-be: Prevent the MUX to send/receive data
    - MINOR: quic: define proper proto on QUIC servers
    - MEDIUM: quic-be: initialize MUX on handshake completion
    - BUG/MINOR: hlua: Don't forget the return statement after a hlua_yieldk()
    - BUILD: hlua: Fix warnings about uninitialized variables
    - BUILD: listener: fix 'for' loop inline variable declaration
    - BUILD: hlua: Fix warnings about uninitialized variables (2)
    - BUG/MEDIUM: mux-quic: adjust wakeup behavior
    - MEDIUM: backend: delay MUX init with ALPN even if proto is forced
    - MINOR: quic: mark ctrl layer as ready on quic_connect_server()
    - MINOR: mux-quic: improve documentation for snd/rcv app-ops
    - MINOR: mux-quic: define flag for backend side
    - MINOR: mux-quic: set expect data only on frontend side
    - MINOR: mux-quic: instantiate first stream on backend side
    - MINOR: quic: wakeup backend MUX on handshake completed
    - MINOR: hq-interop: decode response into HTX for backend side support
    - MINOR: hq-interop: encode request from HTX for backend side support
    - CLEANUP: quic-be: Add comments about qc_new_conn() usage
    - BUG/MINOR: quic-be: CID double free upon qc_new_conn() failures
    - MINOR: quic-be: Avoid SSL context unreachable code without USE_QUIC_OPENSSL_COMPAT
    - BUG/MINOR: quic: prevent crash on startup with -dt
    - MINOR: server: reject QUIC servers without explicit SSL
    - BUG/MINOR: quic: work around NEW_TOKEN parsing error on backend side
    - BUG/MINOR: http-ana: Properly handle keep-query redirect option if no QS
    - BUG/MINOR: quic: don't restrict reception on backend privileged ports
    - MINOR: hq-interop: handle HTX response forward if not enough space
    - BUG/MINOR: quic: Fix OSSL_FUNC_SSL_QUIC_TLS_got_transport_params_fn callback (OpenSSL3.5)
    - BUG/MINOR: quic: fix ODCID initialization on frontend side
    - BUG/MEDIUM: cli: Don't consume data if outbuf is full or not available
    - MINOR: cli: handle EOS/ERROR first
    - BUG/MEDIUM: check: Set SOCKERR by default when a connection error is reported
    - BUG/MINOR: mux-quic: check sc_attach_mux return value
    - MINOR: h3: support basic HTX start-line conversion into HTTP/3 request
    - MINOR: h3: encode request headers
    - MINOR: h3: complete HTTP/3 request method encoding
    - MINOR: h3: complete HTTP/3 request scheme encoding
    - MINOR: h3: adjust path request encoding
    - MINOR: h3: adjust auth request encoding or fallback to host
    - MINOR: h3: prepare support for response parsing
    - MINOR: h3: convert HTTP/3 response into HTX for backend side support
    - MINOR: h3: complete response status transcoding
    - MINOR: h3: transcode H3 response headers into HTX blocks
    - MINOR: h3: use BUG_ON() on missing request start-line
    - MINOR: h3: reject invalid :status in response
    - DOC: config: prefer-last-server: add notes for non-deterministic algorithms
    - CLEANUP: connection: remove unused mux-ops dedicated to QUIC
    - BUG/MINOR: mux-quic/h3: properly handle too low peer fctl initial stream
    - MINOR: mux-quic: support max bidi streams value set by the peer
    - MINOR: mux-quic: abort conn if cannot create stream due to fctl
    - MEDIUM: mux-quic: implement attach for new streams on backend side
    - BUG/MAJOR: fwlc: Count an avoided server as unusable.
    - MINOR: fwlc: Factorize code.
    - BUG/MEDIUM: quic: do not release BE quic-conn prior to upper conn
    - MAJOR: cfgparse: turn the same proxy name warning to an error
    - MAJOR: cfgparse: make sure server names are unique within a backend
    - BUG/MINOR: tools: only reset argument start upon new argument
    - BUG/MINOR: stream: Avoid recursive evaluation for unique-id based on itself
    - BUG/MINOR: log: Be able to use %ID alias at anytime of the stream's evaluation
    - MINOR: hlua: emit a log instead of an alert for aborted actions due to unavailable yield
    - MAJOR: mailers: remove native mailers support
    - BUG/MEDIUM: ssl/clienthello: ECDSA with ssl-max-ver TLSv1.2 and no ECDSA ciphers
    - DOC: configuration: add details on prefer-client-ciphers
    - MINOR: ssl: Add "renegotiate" server option
    - DOC: remove the program section from the documentation
    - MAJOR: mworker: remove program section support
    - BUG/MINOR: quic: wrong QUIC_FT_CONNECTION_CLOSE(0x1c) frame encoding
    - MINOR: quic-be: add a "CC connection" backend TX buffer pool
    - MINOR: quic: Useless TX buffer size reduction in closing state
    - MINOR: quic-be: Allow sending 1200 bytes Initial datagrams
    - MINOR: quic-be: address validation support implementation (RETRY)
    - MEDIUM: proxy: deprecate the "transparent" and "option transparent" directives
    - REGTESTS: update http_reuse_be_transparent with "transparent" deprecated
    - REGTESTS: script: also add a line pointing to the log file
    - DOC: config: explain how to deal with "transparent" deprecation
    - MEDIUM: proxy: mark the "dispatch" directive as deprecated
    - DOC: config: crt-list clarify default cert + cert-bundle
    - MEDIUM: cpu-topo: switch to the "performance" cpu-policy by default
    - SCRIPTS: drop the HTML generation from announce-release
    - BUG/MINOR: tools: use my_unsetenv instead of unsetenv
    - CLEANUP: startup: move comment about nbthread where it's more appropriate
    - BUILD: qpack: fix a build issue on older compilers

2 weeks agoBUILD: qpack: fix a build issue on older compilers
Willy Tarreau [Thu, 26 Jun 2025 16:09:24 +0000 (18:09 +0200)] 
BUILD: qpack: fix a build issue on older compilers

Got this on gcc-4.8:

  src/qpack-enc.c: In function 'qpack_encode_method':
  src/qpack-enc.c:168:3: error: 'for' loop initial declarations are only allowed in C99 mode
     for (size_t i = 0; i < istlen(other); ++i)
     ^

This came from commit a0912cf914 ("MINOR: h3: complete HTTP/3 request
method encoding"), no backport is needed.

2 weeks agoCLEANUP: startup: move comment about nbthread where it's more appropriate
Valentine Krasnobaeva [Thu, 26 Jun 2025 14:50:19 +0000 (16:50 +0200)] 
CLEANUP: startup: move comment about nbthread where it's more appropriate

Move the comment about non_global_section_parsed just above the line, where
we reset it.

2 weeks agoBUG/MINOR: tools: use my_unsetenv instead of unsetenv
Valentine Krasnobaeva [Thu, 26 Jun 2025 14:49:12 +0000 (16:49 +0200)] 
BUG/MINOR: tools: use my_unsetenv instead of unsetenv

Let's use our own implementation of unsetenv() instead of the one, which is
provided in libc. Implementation from libc may vary in dependency of UNIX
distro. Implemenation from libc.so.1 ported on Illumos (see the link below) has
caused an eternal loop in the clean_env(), where we invoke unsetenv().

(https://github.com/illumos/illumos-gate/blob/master/usr/src/lib/libc/port/gen/getenv.c#L411C1-L456C1)

This is reported at GitHUB #3018 and the reporter has proposed the patch, which
we really appreciate! But looking at his fix and to the implementations of
unsetenv() in FreeBSD libc and in Linux glibc 2.31, it seems, that the algorithm
of clean_env() will perform better with our my_unsetenv() implementation.

This should be backported in versions 3.1 and 3.2.

2 weeks agoSCRIPTS: drop the HTML generation from announce-release
Willy Tarreau [Thu, 26 Jun 2025 16:01:02 +0000 (18:01 +0200)] 
SCRIPTS: drop the HTML generation from announce-release

It has not been used over the last 5 years or so and systematically
requires manual removal. Let's just stop producing it. Also take
this opportunity to add the missing link to /discussions.

2 weeks agoMEDIUM: cpu-topo: switch to the "performance" cpu-policy by default
Willy Tarreau [Thu, 26 Jun 2025 14:01:55 +0000 (16:01 +0200)] 
MEDIUM: cpu-topo: switch to the "performance" cpu-policy by default

As mentioned during the NUMA series development, the goal is to use
all available cores in the most efficient way by default, which
normally corresponds to "cpu-policy performance". The previous default
choice of "cpu-policy first-usable-node" was only meant to stay 100%
identical to before cpu-policy.

So let's switch the default cpu-policy to "performance" right now.
The doc was updated to reflect this.

2 weeks agoDOC: config: crt-list clarify default cert + cert-bundle
Maximilian Moehl [Thu, 26 Jun 2025 14:08:03 +0000 (16:08 +0200)] 
DOC: config: crt-list clarify default cert + cert-bundle

Clarify that HAProxy duplicates crt-list entries for multi-cert bundles
which can create unexpected side-effects as only the very first
certificate after duplication is considered as default implicitly.

2 weeks agoMEDIUM: proxy: mark the "dispatch" directive as deprecated
Willy Tarreau [Thu, 26 Jun 2025 13:29:47 +0000 (15:29 +0200)] 
MEDIUM: proxy: mark the "dispatch" directive as deprecated

As mentioned in [1], the "dispatch" directive from haproxy 1.0 has long
outlived its original purpose and still suffers from a number of technical
limitations (no checks, no SSL, no idle connes etc) and still hinders some
internal evolutions. It's now time to mark it as deprecated, and to remove
it in 3.5 [2]. It was already recommended against in the documentation but
remained popular in raw TCP environments for being shorter to write.

The directive will now cause a warning to be emitted, suggesting an
alternate method involving "server". The warning can be shut using
"expose-deprecated-directives". The rare configs from 1.0 where
"dispatch" is combined with sticky servers using cookies will just
need to set these servers's weights to zero to prevent them from
being selected by the load balancing algorithm. All of this is
explained in the doc with examples.

Two reg tests were using this method, one purposely for this directive,
which now has expose-deprecated-directives, and another one to test the
behavior of idle connections, which was updated to use "server" and
extended to test both "http-reuse never" and "http-reuse always".

[1] https://github.com/orgs/haproxy/discussions/2921
[2] https://github.com/haproxy/wiki/wiki/Breaking-changes

2 weeks agoDOC: config: explain how to deal with "transparent" deprecation
Willy Tarreau [Thu, 26 Jun 2025 12:50:44 +0000 (14:50 +0200)] 
DOC: config: explain how to deal with "transparent" deprecation

The explanations for the "option transparent" keyword were a bit scarce
regarding deprecation, so let's explain how to replace it with a server
line that does the same.

2 weeks agoREGTESTS: script: also add a line pointing to the log file
Willy Tarreau [Thu, 26 Jun 2025 12:33:09 +0000 (14:33 +0200)] 
REGTESTS: script: also add a line pointing to the log file

I never counted the number of hours I've been spending selecting then
copy-pasting the directory output and manually appending "/LOG" to read
a log file but it amounts in tens to hundreds. Let's just add a direct
pointer to the log file at the end of the log for a failed run.

2 weeks agoREGTESTS: update http_reuse_be_transparent with "transparent" deprecated
Willy Tarreau [Thu, 26 Jun 2025 12:28:36 +0000 (14:28 +0200)] 
REGTESTS: update http_reuse_be_transparent with "transparent" deprecated

With commit e93f3ea3f8 ("MEDIUM: proxy: deprecate the "transparent" and
"option transparent" directives") this one no longer works as the config
either has to be adjusted to use server 0.0.0.0 or to enable the deprecated
feature. The test used to validate a technical limitation ("transparent"
not supporting shared connections), indicated as being comparable to
"http-reuse never". Let's now duplicate the test for "http-reuse never"
and "http-reuse always" and validate both behaviors.

Take this opportunity to fix a few problems in this config:
  - use "nbthread 1": depending on the thread where the connection
    arrives, the connection may or may not be reused
  - add explicit URLs to the clients so that they can be recognized
    in the logs
  - add comments to make it clearer what to expect for each test

2 weeks agoMEDIUM: proxy: deprecate the "transparent" and "option transparent" directives
Willy Tarreau [Thu, 26 Jun 2025 09:55:47 +0000 (11:55 +0200)] 
MEDIUM: proxy: deprecate the "transparent" and "option transparent" directives

As discussed here [1], "transparent" (already deprecated) and
"option transparent" are horrible hacks which should really disappear
in favor of "server xxx 0.0.0.0" which doesn't rely on hackish code
path. This old feature is now deprecated in 3.3 and will disappear in
3.5, as indicated here [2]. A warning is emitted when used, explaining
how to proceed, and how to silence the warning using the global
"expose-deprecated-directives" if needed. The doc was updated to
reflect this new state.

[1] https://github.com/orgs/haproxy/discussions/2921
[2] https://github.com/haproxy/wiki/wiki/Breaking-changes

2 weeks agoMINOR: quic-be: address validation support implementation (RETRY)
Frederic Lecaille [Wed, 25 Jun 2025 16:11:24 +0000 (18:11 +0200)] 
MINOR: quic-be: address validation support implementation (RETRY)

- Add ->retry_token and ->retry_token_len new quic_conn struct members to store
  the retry tokens. These objects are allocated by quic_rx_packet_parse() and
  released by quic_conn_release().
- Add <pool_head_quic_retry_token> new pool for these tokens.
- Implement quic_retry_packet_check() to check the integrity tag of these tokens
  upon RETRY packets receipt. quic_tls_generate_retry_integrity_tag() is called
  by this new function. It has been modified to pass the address where the tag
  must be generated
- Add <resend> new parameter to quic_pktns_discard(). This function is called
  to discard the packet number spaces where the already TX packets and frames are
  attached to. <resend> allows the caller to prevent this function to release
  the in flight TX packets/frames. The frames are requeued to be resent.
- Modify quic_rx_pkt_parse() to handle the RETRY packets. What must be done upon
  such packets receipt is:
  - store the retry token,
  - store the new peer SCID as the DCID of the connection. Note that the peer will
    modify again its SCID. This is why this SCID is also stored as the ODCID
    which must be matched with the peer retry_source_connection_id transport parameter,
  - discard the Initial packet number space without flagging it as discarded and
    prevent retransmissions calling qc_set_timer(),
  - modify the TLS cryptographic cipher contexts (RX/TX),
  - wakeup the I/O handler to send new Initial packets asap.
- Modify quic_transport_param_decode() to handle the retry_source_connection_id
  transport parameter as a QUIC client. Then its caller is modified to
  check this transport parameter matches with the SCID sent by the peer with
  the RETRY packet.

2 weeks agoMINOR: quic-be: Allow sending 1200 bytes Initial datagrams
Frederic Lecaille [Wed, 25 Jun 2025 14:04:28 +0000 (16:04 +0200)] 
MINOR: quic-be: Allow sending 1200 bytes Initial datagrams

This easy to understand patch is not intrusive at all and cannot break the QUIC
listeners.

The QUIC client MUST always pad its datagrams with Initial packets. A "!l" (not
a listener) test OR'ed with the existing ones is added to satisfy the condition
to allow the build of such datagrams.

2 weeks agoMINOR: quic: Useless TX buffer size reduction in closing state
Frederic Lecaille [Wed, 25 Jun 2025 08:15:50 +0000 (10:15 +0200)] 
MINOR: quic: Useless TX buffer size reduction in closing state

There is no need to limit the size of the TX buffer to QUIC_MIN_CC_PKTSIZE bytes
when the connection is in closing state. There is already a test which limits the
number of bytes to be used from this TX buffer after this useless test removed.
It limits this number of bytes to the size of the TX buffer itself:

    if (end > (unsigned char *)b_wrap(buf))
    end = (unsigned char *)b_wrap(buf);

This is exactly what is needed when the connection is in closing state. Indeed,
the size of the TX buffers are limited to reduce the memory usage. The connection
only needs to send short datagrams with at most 2 packets with a CONNECTION_CLOSE*
frames. They are built only one time and backed up into small TX buffer allocated
from a dedicated pool.
The size of this TX buffer is QUIC_MAX_CC_BUFSIZE which depends on QUIC_MIN_CC_PKTSIZE:

 #define QUIC_MIN_CC_PKTSIZE  128
 #define QUIC_MAX_CC_BUFSIZE (2 * (QUIC_MIN_CC_PKTSIZE + QUIC_DGRAM_HEADLEN))

This size is smaller than an MTU.

This patch should be backported as far as 2.9 to ease further backports to come.

2 weeks agoMINOR: quic-be: add a "CC connection" backend TX buffer pool
Frederic Lecaille [Tue, 24 Jun 2025 08:55:22 +0000 (10:55 +0200)] 
MINOR: quic-be: add a "CC connection" backend TX buffer pool

A QUIC client must be able to close a connection sending Initial packets. But
QUIC client Initial packets must always be at least 1200 bytes long. To reduce
the memory use of TX buffers of a connection when in "closing" state, a pool
was dedicated for this purpose but with a too much reduced TX buffer size
(QUIC_MAX_CC_BUFSIZE).

This patch adds a "closing state connection" TX buffer pool with the same role
for QUIC backends.

2 weeks agoBUG/MINOR: quic: wrong QUIC_FT_CONNECTION_CLOSE(0x1c) frame encoding
Frederic Lecaille [Mon, 23 Jun 2025 14:52:09 +0000 (16:52 +0200)] 
BUG/MINOR: quic: wrong QUIC_FT_CONNECTION_CLOSE(0x1c) frame encoding

This is an old bug which was there since this commit:

     MINOR: quic: Avoid zeroing frame structures

It seems QUIC_FT_CONNECTION_CLOSE was confused with QUIC_FT_CONNECTION_CLOSE_APP
which does not include a "frame type" field. This field was not initialized
(so with a random value) which prevent the packet to be built because the
packet builder supposes the packet with such frames are very short.

Must be backported as far as 2.6.

2 weeks agoMAJOR: mworker: remove program section support
William Lallemand [Wed, 25 Jun 2025 14:11:34 +0000 (16:11 +0200)] 
MAJOR: mworker: remove program section support

This patch removes completely the support for the program section, the
parsing of the section as well as the internals in the mworker does not
support it anymore.

The program section was considered dysfonctional and not fully
compatible with the "mworker V3" model. Users that want to run an
external program must use their init system.

The documentation is cleaned up in another patch.

2 weeks agoDOC: remove the program section from the documentation
William Lallemand [Wed, 25 Jun 2025 13:42:57 +0000 (15:42 +0200)] 
DOC: remove the program section from the documentation

The program section is obsolete and can be remove from the
documentation.

2 weeks agoMINOR: ssl: Add "renegotiate" server option
Remi Tricot-Le Breton [Thu, 12 Jun 2025 13:08:28 +0000 (15:08 +0200)] 
MINOR: ssl: Add "renegotiate" server option

This "renegotiate" option can be set on SSL backends to allow secure
renegotiation. It is mostly useful with SSL libraries that disable
secure regotiation by default (such as AWS-LC).
The "no-renegotiate" one can be used the other way around, to disable
secure renegotation that could be allowed by default.
Those two options can be set via "ssl-default-server-options" as well.

2 weeks agoDOC: configuration: add details on prefer-client-ciphers
William Lallemand [Wed, 25 Jun 2025 12:41:45 +0000 (14:41 +0200)] 
DOC: configuration: add details on prefer-client-ciphers

prefer-client-ciphers does not work exactly the same way when used with
a dual algorithm stack (ECDSA + RSA). This patch details its behavior.

This patch must be backported in every maintained version.

Problem was discovered in #2988.

2 weeks agoBUG/MEDIUM: ssl/clienthello: ECDSA with ssl-max-ver TLSv1.2 and no ECDSA ciphers
William Lallemand [Thu, 12 Jun 2025 14:50:08 +0000 (16:50 +0200)] 
BUG/MEDIUM: ssl/clienthello: ECDSA with ssl-max-ver TLSv1.2 and no ECDSA ciphers

Patch 23093c72 ("BUG/MINOR: ssl: suboptimal certificate selection with TLSv1.3
and dual ECDSA/RSA") introduced a problem when prioritizing the ECDSA
with TLSv1.3.

Indeed, when a client with TLSv1.3 capabilities announce a list of
ECDSA sigalgs, a list of TLSv1.3 ciphersuites compatible with ECDSA,
but only RSA ciphers for TLSv1.2, and haproxy is configured to a
ssl-max-ver TLSv1.2, then haproxy would use the ECDSA keypair, but the
client wouldn't be able to process it because TLSv1.2 was negociated.

HAProxy would be configured like that:

  ssl-default-bind-options ssl-max-ver TLSv1.2

And a client could be used this way:

  openssl s_client -connect localhost:8443 -cipher ECDHE-ECDSA-AES128-GCM-SHA256 \
          -ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256

This patch fixes the issue by checking if TLSv1.3 was configured before
allowing ECDSA is an TLSv1.3 ciphersuite is in the list.

This could be backported where 23093c72 ("BUG/MINOR: ssl: suboptimal
certificate selection with TLSv1.3 and dual ECDSA/RSA") was backported.
However this is quite sensible and we should wait a bit before the
backport.

This should fix issue #2988

2 weeks agoMAJOR: mailers: remove native mailers support
Aurelien DARRAGON [Mon, 23 Jun 2025 20:32:08 +0000 (22:32 +0200)] 
MAJOR: mailers: remove native mailers support

As mentioned in 2.8 announce on the mailing list [1] and on the wiki [2]
native mailers were deprecated and planned for removal in 3.3. Now is
the time to drop the legacy code for native mailers which is based on a
tcpcheck "hack" and cannot be maintained. Lua mailers should be used as
a drop in replacement. Indeed, "mailers" and associated config directives
are preserved because mailers config is exposed to Lua, which helps smoothing
the transition from native mailers to Lua based ones.

As a reminder, to keep mailers configuration working as before without
making changes to the config file, simply add the line below to the global
section:

       lua-load examples/lua/mailers.lua

mailers.lua script (provided in the git repository, adjust path as needed)
may be customized by users familiar with Lua, by default it emulates the
behavior of the native (now removed) mailers.

[1]: https://www.mail-archive.com/haproxy@formilux.org/msg43600.html
[2]: https://github.com/haproxy/wiki/wiki/Breaking-changes

2 weeks agoMINOR: hlua: emit a log instead of an alert for aborted actions due to unavailable...
Aurelien DARRAGON [Mon, 23 Jun 2025 14:23:33 +0000 (16:23 +0200)] 
MINOR: hlua: emit a log instead of an alert for aborted actions due to unavailable yield

As reported by Chris Staite in GH #3002, trying to yield from a Lua
action during a client disconnect causes the script to be interrupted
(which is expected) and an alert to be emitted with the error:
"Lua function '%s': yield not allowed".

While this error is well suited for cases where the yield is not expected
at all (ie: when context doesn't allow it) and results from a yield misuse
in the Lua script, it isn't the case when the yield is exceptionnally not
available due to an abort or error in the request/response processing.
Because of that we raise an alert but the user cannot do anything about it
(the script is correct), so it is confusing and polluting the logs.

In this patch we introduce the ACT_OPT_FINAL_EARLY flag which is a
complementary flag to ACT_OPT_FIRST. This flag is set when the
ACT_OPT_FIRST is set earlier than normal (due to error/abort).
hlua_action() then checks for this flag to decide whether an error (alert)
or a simple log message should be emitted when the yield is not available.

It should solve GH #3002. Thanks to Chris Staite (@chrisstaite-menlo) for
having reported the issue and suggested a solution.

2 weeks agoBUG/MINOR: log: Be able to use %ID alias at anytime of the stream's evaluation
Christopher Faulet [Mon, 23 Jun 2025 05:50:01 +0000 (07:50 +0200)] 
BUG/MINOR: log: Be able to use %ID alias at anytime of the stream's evaluation

In a log-format string, using "%[unique-id]" or "%ID" should be equivalent.
However, for the first one, the unique ID is generated when the sample fetch
function is called. For the alias, it is not true. It that case, the
stream's unique ID is generated when the log message is emitted. Otherwise,
by default, the unique id is automatically generated at the end of the HTTP
request analysis.

So, if the alias "%ID" is use in a log-format string anywhere before the end
of the request analysis, the evaluation failed and the ID is considered as
empty. It is not consistent and in contradiction with the "%ID"
documentation.

To fix the issue, instead of evaluating the unique ID when the log message
is emitted, it is now performed on demand when "%ID" format is evaluated.

This patch should fix the issue #3016. It should be backported to all stable
versions. It relies on the following commit:

  * BUG/MINOR: stream: Avoid recursive evaluation for unique-id based on itself

2 weeks agoBUG/MINOR: stream: Avoid recursive evaluation for unique-id based on itself
Christopher Faulet [Mon, 23 Jun 2025 05:33:06 +0000 (07:33 +0200)] 
BUG/MINOR: stream: Avoid recursive evaluation for unique-id based on itself

There is nothing that prevent a "unique-id-format" to reference itself,
using '%ID' or '%[unique-id]'. If the sample fetch function is used, it
leads to an infinite loop, calling recursively the function responsible to
generate the unique ID.

One solution is to detect it during the configuration parsing to trigger an
error. With this patch, we just inhibit recursive calls by considering the
unique-id as empty during its evaluation. So "id-%[unique-id]" lf string
will be evaluated as "id-".

This patch must be backported to all stable versions.

2 weeks agoBUG/MINOR: tools: only reset argument start upon new argument
Willy Tarreau [Mon, 23 Jun 2025 16:33:31 +0000 (18:33 +0200)] 
BUG/MINOR: tools: only reset argument start upon new argument

In issue #2995, Thomas Kjaer reported that empty argument position
reporting had been broken yet again. This time it was broken by this
latest fix: 2b60e54fb1 ("BUG/MINOR: tools: improve parse_line()'s
robustness against empty args"). It turns out that this fix is not
the culprit and it's in fact correct. The culprit was the original
commit of this series, 7e4a2f39ef ("BUG/MINOR: tools: do not create
an empty arg from trailing spaces"), which used to reset arg_start
to outpos for every new char in addition to doing it for every arg.
This resulted in the end of the line to be seen as always being in
error, thus reporting an incorrect position that the caller would
correct in a generic way designating the beginning of the line. It
didn't reveal prior to the upper fix above because the misassigned
value was almost not used by then.

Assigning the value before entering the loop fixes this problem and
doens't break the series of previous oss-fuzz reproducers. Hopefully
it's the last one again.

This must be backported to 3.2. Thanks to @tkjaer for reporting the
issue along with a reproducer.

2 weeks agoMAJOR: cfgparse: make sure server names are unique within a backend
Willy Tarreau [Mon, 23 Jun 2025 13:42:32 +0000 (15:42 +0200)] 
MAJOR: cfgparse: make sure server names are unique within a backend

There was already a check for this but there used to be an exception
that allowed duplicate server names only in case where their IDs were
explicit and different. This has been emitting a warning since 3.1 and
planned for removal in 3.3, so let's do it now. The doc was updated,
though it never mentioned this unicity constraint, so that was added.

Only the check for the exception was removed, the rest of the code
that is currently made to deal with duplicate server names was not
cleaned yet (e.g. the tree doesn't need to support dups anymore, and
this could be done at insertion time). This may be a subject for future
cleanups.

2 weeks agoMAJOR: cfgparse: turn the same proxy name warning to an error
Willy Tarreau [Mon, 23 Jun 2025 13:26:44 +0000 (15:26 +0200)] 
MAJOR: cfgparse: turn the same proxy name warning to an error

As warned since 3.1, it's no longer permitted to have a frontend and
a backend under the same name. This causes too many designation issues,
and causes trouble with stick-tables as well. Now each proxy name is
unique.

This commit only changes the check to return an error. Some code parts
currently exist to find the best candidates, these will be able to be
simplified as future cleanup patches. The doc was updated.

3 weeks agoBUG/MEDIUM: quic: do not release BE quic-conn prior to upper conn
Amaury Denoyelle [Mon, 16 Jun 2025 08:42:34 +0000 (10:42 +0200)] 
BUG/MEDIUM: quic: do not release BE quic-conn prior to upper conn

For frontend side, quic_conn is only released if MUX wasn't allocated,
either due to handshake abort, in which case upper layer is never
allocated, or after transfer completion when full conn + MUX layers are
already released.

On the backend side, initialization is not performed in the same order.
Indeed, in this case, connection is first instantiated, the nthe
quic_conn is created to execute the handshake, while MUX is still only
allocated on handshake completion. As such, it is not possible anymore
to free immediately quic_conn on handshake failure. Else, this can cause
crash if the connection try to reaccess to its transport layer after
quic_conn release.

Such crash can easily be reproduced in case of connection error to the
QUIC server. Here is an example of an experienced backtrace.

Thread 1 "haproxy" received signal SIGSEGV, Segmentation fault.
  0x0000555555739733 in quic_close (conn=0x55555734c0d0, xprt_ctx=0x5555573a6e50) at src/xprt_quic.c:28
  28              qc->conn = NULL;
  [ ## gdb ## ] bt
  #0  0x0000555555739733 in quic_close (conn=0x55555734c0d0, xprt_ctx=0x5555573a6e50) at src/xprt_quic.c:28
  #1  0x00005555559c9708 in conn_xprt_close (conn=0x55555734c0d0) at include/haproxy/connection.h:162
  #2  0x00005555559c97d2 in conn_full_close (conn=0x55555734c0d0) at include/haproxy/connection.h:206
  #3  0x00005555559d01a9 in sc_detach_endp (scp=0x7fffffffd648) at src/stconn.c:451
  #4  0x00005555559d05b9 in sc_reset_endp (sc=0x55555734bf00) at src/stconn.c:533
  #5  0x000055555598281d in back_handle_st_cer (s=0x55555734adb0) at src/backend.c:2754
  #6  0x000055555588158a in process_stream (t=0x55555734be10, context=0x55555734adb0, state=516) at src/stream.c:1907
  #7  0x0000555555dc31d9 in run_tasks_from_lists (budgets=0x7fffffffdb30) at src/task.c:655
  #8  0x0000555555dc3dd3 in process_runnable_tasks () at src/task.c:889
  #9  0x0000555555a1daae in run_poll_loop () at src/haproxy.c:2865
  #10 0x0000555555a1e20c in run_thread_poll_loop (data=0x5555569d1c00 <ha_thread_info>) at src/haproxy.c:3081
  #11 0x0000555555a1f66b in main (argc=5, argv=0x7fffffffde18) at src/haproxy.c:3671

To fix this, change the condition prior to calling quic_conn release. If
<conn> member is not NULL, delay the release, similarly to the case when
MUX is allocated. This allows connection to be freed first, and detach
from quic_conn layer through close xprt operation.

No need to backport.

3 weeks agoMINOR: fwlc: Factorize code.
Olivier Houchard [Fri, 20 Jun 2025 13:53:27 +0000 (15:53 +0200)] 
MINOR: fwlc: Factorize code.

Always set unusable if we could not use a server, instead of doing it in
each branch

This should be backported to 3.2 after e28e647fef43e5865c87f328832fec7794a423e5
is backported.

3 weeks agoBUG/MAJOR: fwlc: Count an avoided server as unusable.
Olivier Houchard [Fri, 20 Jun 2025 13:06:04 +0000 (15:06 +0200)] 
BUG/MAJOR: fwlc: Count an avoided server as unusable.

When fwlc_get_next_server(), if a server to avoid has been provided, and
we have to ignore it, don't forget to increase the number of unusable
servers, otherwise we may end up ignoring it over and over, never
switching to another server, in an infinite loop until the process gets
killed.
This hopefully fixes Github issues #3004 and #3014.

This should be backported to 3.2.

3 weeks agoMEDIUM: mux-quic: implement attach for new streams on backend side
Amaury Denoyelle [Wed, 18 Jun 2025 07:59:50 +0000 (09:59 +0200)] 
MEDIUM: mux-quic: implement attach for new streams on backend side

Implement attach and avail_streams mux-ops callbacks, which are used on
backend side for connection reuse.

Attach operation is used to initiate new streams on the connection
outside of the first one. It simply relies on qcc_init_stream_local() to
instantiate a new QCS instance, which is immediately linked to its
stream data layer.

Outside of attach, it is also necessary to implement avail_streams so
that the stream layer will try to initiate connection reuse. This method
reports the number of bidirectional streams which can still be opened
for the QUIC connection. It depends directly to the flow-control value
advertised by the peer. Thus, this ensures that attach won't cause any
flow control violation.

3 weeks agoMINOR: mux-quic: abort conn if cannot create stream due to fctl
Amaury Denoyelle [Wed, 18 Jun 2025 14:24:41 +0000 (16:24 +0200)] 
MINOR: mux-quic: abort conn if cannot create stream due to fctl

Prior to initiate first stream on the backend side, ensure that peer
flow-control allows at least that a single bidirectional stream can be
created. If this is not the case, abort MUX init operation.

Before this patch, flow-control limit was not checked. Hence, if peer
does not allow any bidirectional stream, haproxy would violate it, which
whould then cause the peer to close the connection.

Note that with the current situation, haproxy won't be able to talk to
servers which uses a 0 for initial max bidi streams. A proper solution
could be to pause the request until a MAX_STREAMS is received, under
timeout supervision to ensure the connection is closed if no frame is
received.

3 weeks agoMINOR: mux-quic: support max bidi streams value set by the peer
Amaury Denoyelle [Wed, 18 Jun 2025 07:25:39 +0000 (09:25 +0200)] 
MINOR: mux-quic: support max bidi streams value set by the peer

Implement support for MAX_STREAMS frame. On frontend, this was mostly
useless as haproxy would never initiate new bidirectional streams.
However, this becomes necessary to control stream flow-control when
using QUIC as a client on the backend side.

Parsing of MAX_STREAMS is implemented via new qcc_recv_max_streams().
This allows to update <ms_uni>/<ms_bidi> QCC fields.

This patch is necessary to achieve QUIC backend connection reuse.

3 weeks agoBUG/MINOR: mux-quic/h3: properly handle too low peer fctl initial stream
Amaury Denoyelle [Wed, 18 Jun 2025 13:12:31 +0000 (15:12 +0200)] 
BUG/MINOR: mux-quic/h3: properly handle too low peer fctl initial stream

Previously, no check on peer flow-control was implemented prior to open
a local QUIC stream. This was a small problem for frontend
implementation, as in this case haproxy as a server never opens
bidirectional streams.

On frontend, the only stream opened by haproxy in this case is for
HTTP/3 control unidirectional data. If the peer uses an initial value
for max uni streams set to 0, it would violate its flow control, and the
peer will probably close the connection. Note however that RFC 9114
mandates that each peer defines minimal initial value so that at least
the control stream can be created.

This commit improves the situation of too low initial max uni streams
value. Now, on HTTP/3 layer initialization, haproxy preemptively checks
flow control limit on streams via a new function
qcc_fctl_avail_streams(). If credit is already expired due to a too
small initial value, haproxy preemptively closes the connection using
H3_ERR_GENERAL_PROTOCOL_ERROR. This behavior is better as haproxy is now
the initiator of the connection closure.

This should be backported up to 2.8.

3 weeks agoCLEANUP: connection: remove unused mux-ops dedicated to QUIC
Amaury Denoyelle [Tue, 17 Jun 2025 09:49:04 +0000 (11:49 +0200)] 
CLEANUP: connection: remove unused mux-ops dedicated to QUIC

Remove avail_streams_bidi/avail_streams_uni mux_ops. These callbacks
were designed to be specific to QUIC. However, they won't be necessary,
as stream layer only cares about bidirectional streams.

3 weeks agoDOC: config: prefer-last-server: add notes for non-deterministic algorithms
Valentine Krasnobaeva [Tue, 17 Jun 2025 13:33:12 +0000 (13:33 +0000)] 
DOC: config: prefer-last-server: add notes for non-deterministic algorithms

Add some notes which load-balancing algorithm can be considered as
deterministic or non-deterministic and add some examples for each type.
This was asked via mailing list to clarify the usage of
prefer-last-server option.

This can be backported to all stable versions.

3 weeks agoMINOR: h3: reject invalid :status in response
Amaury Denoyelle [Tue, 17 Jun 2025 09:33:53 +0000 (11:33 +0200)] 
MINOR: h3: reject invalid :status in response

Add checks to ensure that :status pseudo-header received in HTTP/3
response is valid. If either the header is not provided, or it isn't a 3
digit numbers, the response is considered as invalid and the streams is
rejected. Also, glitch counter is now incremented in any of these cases.

This should fix coverity report from github issue #3009.

3 weeks agoMINOR: h3: use BUG_ON() on missing request start-line
Amaury Denoyelle [Tue, 17 Jun 2025 08:25:30 +0000 (10:25 +0200)] 
MINOR: h3: use BUG_ON() on missing request start-line

Convert BUG_ON_HOT() statements to BUG_ON() if HTX start-line is either
missing or duplicated when transcoding into a HTTP/3 request. This
ensures that such abnormal conditions will be detected even on default
builds.

This is linked to coverity report #3008.

3 weeks agoMINOR: h3: transcode H3 response headers into HTX blocks
Amaury Denoyelle [Mon, 16 Jun 2025 14:32:57 +0000 (16:32 +0200)] 
MINOR: h3: transcode H3 response headers into HTX blocks

Finalize HTTP/3 response transcoding into HTX message. This patch
implements conversion of HTTP/3 headers provided by the server into HTX
blocks.

Special checks have been implemented to reject connection-specific
headers, causing the stream to be shut in error. Also, handling of
content-length requires that the body size is equal to the value
advertized in the header to prevent HTTP desync.

3 weeks agoMINOR: h3: complete response status transcoding
Amaury Denoyelle [Mon, 16 Jun 2025 14:32:36 +0000 (16:32 +0200)] 
MINOR: h3: complete response status transcoding

On the backend side, HTTP/3 request response from server is transcoded
into a HTX message. Previously, a fixed value was used for the status
code.

Improve this by extracting the value specified by the server and set it
into the HTX status line. This requires to detect :status pseudo-header
from the HTTP/3 response.

3 weeks agoMINOR: h3: convert HTTP/3 response into HTX for backend side support
Amaury Denoyelle [Tue, 10 Jun 2025 15:45:27 +0000 (17:45 +0200)] 
MINOR: h3: convert HTTP/3 response into HTX for backend side support

Implement basic support for HTTP/3 request response transcoding into
HTX. This is done via a new dedicated function h3_resp_headers_to_htx().
A valid HTX status-line is allocated and stored. Status code is
hardcoded to 200 for now.

Following patches will be added to remove hardcoded status value and
also handle response headers provided by the server.

3 weeks agoMINOR: h3: prepare support for response parsing
Amaury Denoyelle [Wed, 28 May 2025 15:07:07 +0000 (17:07 +0200)] 
MINOR: h3: prepare support for response parsing

Refactor HTTP/3 request headers transcoding to HTX done in
h3_headers_to_htx(). Some operations are extracted into dedicated
functions, to check pseudo-headers and headers conformity, and also trim
the value of headers before encoding it in HTX.

The objective will be to simplify implementation of HTTP/3 response
transcoding by reusing these functions.

Also, h3_headers_to_htx() has been renamed to h3_req_headers_to_htx(),
to highlight that it is reserved to frontend usage.

3 weeks agoMINOR: h3: adjust auth request encoding or fallback to host
Amaury Denoyelle [Fri, 30 May 2025 16:00:48 +0000 (18:00 +0200)] 
MINOR: h3: adjust auth request encoding or fallback to host

Implement proper encoding of HTTP/3 authority pseudo-header during
request transcoding on the backend side. A pseudo-header :authority is
encoded if a value can be extracted from HTX start-line. A special check
is also implemented to ensure that a host header is not encoded if
:authority already is.

A new function qpack_encode_auth() is defined to implement QPACK
encoding of :authority header using literal field line with name ref.

3 weeks agoMINOR: h3: adjust path request encoding
Amaury Denoyelle [Fri, 30 May 2025 14:25:15 +0000 (16:25 +0200)] 
MINOR: h3: adjust path request encoding

Previously, HTTP/3 backend request :path was hardcoded to value '/'.
Change this so that we can now encode any path as requested by the
client. Path is extracted from the HTX URI. Also, qpack_encode_path() is
extended to support literal field line with name ref.

3 weeks agoMINOR: h3: complete HTTP/3 request scheme encoding
Amaury Denoyelle [Fri, 30 May 2025 09:48:00 +0000 (11:48 +0200)] 
MINOR: h3: complete HTTP/3 request scheme encoding

Previously, scheme was always set to https when transcoding an HTX
start-line into a HTTP/3 request. Change this so this conversion is now
fully compliant.

If no scheme is specified by the client, which is what happens most of
the time with HTTP/1, https is set for the HTTP/3 request. Else, reuse
the scheme requested by the client.

If either https or http is set, qpack_encode_scheme will encode it using
entry from QPACK static table. Else, a full literal field line with name
ref is used instead as the scheme value is specified as-is.

3 weeks agoMINOR: h3: complete HTTP/3 request method encoding
Amaury Denoyelle [Fri, 30 May 2025 13:59:04 +0000 (15:59 +0200)] 
MINOR: h3: complete HTTP/3 request method encoding

On the backend side, HTX start-line is converted into a HTTP/3 request
message. Previously, GET method was hardcoded. Implement proper method
conversion, by extracting it from the HTX start-line.

qpack_encode_method() has also been extended, so that it is able to
encode any method, either using a static table entry, or with a literal
field line with name ref representation.

3 weeks agoMINOR: h3: encode request headers
Amaury Denoyelle [Mon, 16 Jun 2025 13:38:26 +0000 (15:38 +0200)] 
MINOR: h3: encode request headers

Implement encoding of HTTP/3 request headers during HTX->H3 conversion
on the backend side. This simply relies on h3_encode_header().

Special check is implemented to ensure that connection-specific headers
are ignored. An HTTP/3 endpoint must never generate them, or the peer
will consider the message as malformed.

3 weeks agoMINOR: h3: support basic HTX start-line conversion into HTTP/3 request
Amaury Denoyelle [Wed, 28 May 2025 09:24:43 +0000 (11:24 +0200)] 
MINOR: h3: support basic HTX start-line conversion into HTTP/3 request

This commit is the first one of a serie which aim is to implement
transcoding of a HTX request into HTTP/3, which is necessary for QUIC
backend support.

Transcoding is implementing via a new function h3_req_headers_send()
when a HTX start-line is parsed. For now, most of the request fields are
hardcoded, using a GET method. This will be adjusted in the next
following patches.

3 weeks agoBUG/MINOR: mux-quic: check sc_attach_mux return value
Amaury Denoyelle [Mon, 16 Jun 2025 08:46:05 +0000 (10:46 +0200)] 
BUG/MINOR: mux-quic: check sc_attach_mux return value

On backend side, QUIC MUX needs to initialize the first local stream
during MUX init operation. This is necessary so that the first transfer
can then be performed.

sc_attach_mux() is used to attach the created QCS instance to its stream
data layer. However, return value was not checked, which may cause
issues on allocation error. This patch fixes it by returning an error on
MUX init operation and freeing the QCS instance in case of
sc_attach_mux() error.

This fixes coverity report from github issue #3007.

No need to backport.

3 weeks agoBUG/MEDIUM: check: Set SOCKERR by default when a connection error is reported
Christopher Faulet [Mon, 16 Jun 2025 14:33:04 +0000 (16:33 +0200)] 
BUG/MEDIUM: check: Set SOCKERR by default when a connection error is reported

When a connection error is reported, we try to collect as much information
as possible on the connection status and the server status is adjusted
accordingly. However, the function does nothing if there is no connection
error and if the healthcheck is not expired yet. It is a problem when an
internal error occurred. It may happen at many places and it is hard to be
sure an error is reported on the connection. And in fact, it is already a
problem when the multiplexer allocation fails. In that case, the healthcheck
is not interrupted as it should be. Concretely, it could only happen when a
connection is established.

It is hard to predict the effects of this bug. It may be unimportant. But it
could probably lead to a crash. To avoid any issue, a SOCKERR status is now
set by default when a connection error is reported. There is no reason to
report a connection error for nothing. So a healthcheck failure must be
reported. There is no "internal error" status. So a socket error is
reported.

This patch must be backport to all stable versions.

3 weeks agoMINOR: cli: handle EOS/ERROR first
Christopher Faulet [Mon, 16 Jun 2025 14:29:07 +0000 (16:29 +0200)] 
MINOR: cli: handle EOS/ERROR first

It is not especially a bug fixed. But APPCTX_FL_EOS and APPCTX_FL_ERROR
flags must be handled first. These flags are set by the applet itself and
should mark the end of all processing. So there is not reason to get the
output buffer in first place.

This patch could be backported as far as 3.0.

3 weeks agoBUG/MEDIUM: cli: Don't consume data if outbuf is full or not available
Christopher Faulet [Mon, 16 Jun 2025 13:48:04 +0000 (15:48 +0200)] 
BUG/MEDIUM: cli: Don't consume data if outbuf is full or not available

The output buffer must be available to process a command, at least to be
able to emit error messages. When this buffer is full or cannot be
allocated, we must wait. In that case, we must take care to notify the SE
will not consume input data. It is important to avoid wakeup in loop,
especially when the client aborts.

When the output buffer is available again and no longer full, and the CLI
applet is waiting for a command line, it must notify it will consume input
data.

This patch must be backported as far as 3.0.

3 weeks agoBUG/MINOR: quic: fix ODCID initialization on frontend side
Amaury Denoyelle [Mon, 16 Jun 2025 08:02:47 +0000 (10:02 +0200)] 
BUG/MINOR: quic: fix ODCID initialization on frontend side

QUIC support on the backend side has been implemented recently. This has
lead to some adjustment on qc_new_conn() to handle both FE and BE sides,
with some of these changes performed by the following commit.

  29fb1aee57288a8b16ed91771ae65c2bfa400128
  MINOR: quic-be: QUIC connection allocation adaptation (qc_new_conn())

An issue was introduced during some code adjustement. Initialization of
ODCID was incorrectly performed, which caused haproxy to emit invalid
transport parameters. Most of the clients detected this and immediatly
closed the connection.

Fix this by adjusting qc_lstnr_params_init() invokation : replace
<qc.dcid>, which in fact points to the received SCID, by <qc.odcid>
whose purpose is dedicated to original DCID storage.

This fixes github issue #3006. This issue also caused the majority of
tests in the interop to fail.

No backport needed.

3 weeks agoBUG/MINOR: quic: Fix OSSL_FUNC_SSL_QUIC_TLS_got_transport_params_fn callback (OpenSSL3.5)
Frederic Lecaille [Thu, 12 Jun 2025 15:37:49 +0000 (17:37 +0200)] 
BUG/MINOR: quic: Fix OSSL_FUNC_SSL_QUIC_TLS_got_transport_params_fn callback (OpenSSL3.5)

This patch is OpenSSL3.5 QUIC API specific. It fixes
OSSL_FUNC_SSL_QUIC_TLS_got_transport_params_fn() callback (see man(3) SSL_set_quic_tls_cb).

The role of this callback is to store the transport parameters received by the peer.
At this time it is never used by QUIC listeners because there is another callback
which is used to store the transport parameters. This latter callback is not specific
to OpenSSL 3.5 QUIC API. As far as I know, the TLS stack call only one time
one of the callbacks which have been set to receive and store the transport parameters.

That said, OSSL_FUNC_SSL_QUIC_TLS_got_transport_params_fn() is called for QUIC
backends to store the server transport parameters.

qc_ssl_set_quic_transport_params() is useless is this callback. It is dedicated
to store the local tranport parameters (which are sent to the peer). Furthermore
<server> second parameter of quic_transport_params_store() must be 0 for a listener
(or QUIC server) whichs call it, denoting it does not receive the transport parameters
of a QUIC server. It must be 1 for a QUIC backend (a QUIC client which receives
the transport parameter of a QUIC server).

Must be backported to 3.2.

4 weeks agoMINOR: hq-interop: handle HTX response forward if not enough space
Amaury Denoyelle [Fri, 13 Jun 2025 15:41:13 +0000 (17:41 +0200)] 
MINOR: hq-interop: handle HTX response forward if not enough space

On backend side, HTTP/0.9 response body is copied into stream data HTX
buffer. Properly handle the case where the HTX out buffer space is too
small. Only copy a partial copy of the HTTP response. Transcoding will
be restarted when new room is available.

4 weeks agoBUG/MINOR: quic: don't restrict reception on backend privileged ports
Amaury Denoyelle [Fri, 13 Jun 2025 08:19:16 +0000 (10:19 +0200)] 
BUG/MINOR: quic: don't restrict reception on backend privileged ports

When QUIC is used on the frontend side, communication is restricted with
clients using privileged port. This is a simple protection against
DNS/NTP spoofing.

This feature should not be activated on the backend side, as in this
case it is quite frequent to exchange with server running on privileged
ports. As such, a new parameter is added to quic_recv() so that it is
only active on the frontend side.

Without this patch, it is impossible to communicate with QUIC servers
running on privileged ports, as incoming datagrams would be silently
dropped.

No need to backport.

4 weeks agoBUG/MINOR: http-ana: Properly handle keep-query redirect option if no QS
Christopher Faulet [Fri, 13 Jun 2025 09:19:50 +0000 (11:19 +0200)] 
BUG/MINOR: http-ana: Properly handle keep-query redirect option if no QS

The keep-query redirect option must do nothing is there is no query-string.
However, there is a bug. When there is no QS, an error is returned, leading
to return a 500-internal-error to the client.

To fix the bug, instead of returning 0 when there is no QS, we just skip the
QS processing.

This patch should fix the issue #3005. It must be backported as far as 3.1.

4 weeks agoBUG/MINOR: quic: work around NEW_TOKEN parsing error on backend side
Amaury Denoyelle [Thu, 12 Jun 2025 15:39:31 +0000 (17:39 +0200)] 
BUG/MINOR: quic: work around NEW_TOKEN parsing error on backend side

NEW_TOKEN frame is never emitted by a client, hence parsing was not
tested on frontend side.

On backend side, an issue can occur, as expected token length is static,
based on the token length used internally by haproxy. This is not
sufficient for most server implementation which uses larger token. This
causes a parsing error, which may cause skipping of following frames in
the same packet. This issue was detected using ngtcp2 as server.

As for now tokens are unused by haproxy, simply discard test on token
length during NEW_TOKEN frame parsing. The token itself is merely
skipped without being stored. This is sufficient for now to continue on
experimenting with QUIC backend implementation.

This does not need to be backported.

4 weeks agoMINOR: server: reject QUIC servers without explicit SSL
Amaury Denoyelle [Thu, 12 Jun 2025 14:16:43 +0000 (16:16 +0200)] 
MINOR: server: reject QUIC servers without explicit SSL

Report an error during server configuration if QUIC is used by SSL is
not activiated via 'ssl' keyword. This is done in _srv_parse_finalize(),
which is both used by static and dynamic servers.

Note that contrary to listeners, an error is reported instead of a
warning, and SSL is not automatically activated if missing. This is
mainly due to the complex server configuration : _srv_parse_finalize()
is ideal to affect every servers, including dynamic entries. However, it
is executed after server SSL context allocation performed via
<prepare_srv> XPRT operation. A proper fix would be to move SSL ctx
alloc in _srv_parse_finalize(), but this may have unknown impact. Thus,
for now a simpler solution has been chosen.

4 weeks agoBUG/MINOR: quic: prevent crash on startup with -dt
Amaury Denoyelle [Thu, 12 Jun 2025 13:15:56 +0000 (15:15 +0200)] 
BUG/MINOR: quic: prevent crash on startup with -dt

QUIC traces in ssl_quic_srv_new_ssl_ctx() are problematic as this
function is called early during startup. If activating traces via -dt
command-line argument, a crash occurs due to stderr sink not yet
available.

Thus, traces from ssl_quic_srv_new_ssl_ctx() are simply removed.

No backport needed.

4 weeks agoMINOR: quic-be: Avoid SSL context unreachable code without USE_QUIC_OPENSSL_COMPAT
Frederic Lecaille [Thu, 12 Jun 2025 09:17:18 +0000 (11:17 +0200)] 
MINOR: quic-be: Avoid SSL context unreachable code without USE_QUIC_OPENSSL_COMPAT

This commit added a "err" C label reachable only with USE_QUIC_OPENSSL_COMPAT:

   MINOR: quic-be: Missing callbacks initializations (USE_QUIC_OPENSSL_COMPAT)

leading coverity to warn this:

*** CID 1611481:         Control flow issues  (UNREACHABLE)
/src/quic_ssl.c: 802             in ssl_quic_srv_new_ssl_ctx()
796      goto err;
797     #endif
798
799      leave:
800      TRACE_LEAVE(QUIC_EV_CONN_NEW);
801      return ctx;
>>>     CID 1611481:         Control flow issues  (UNREACHABLE)
>>>     This code cannot be reached: "err:
SSL_CTX_free(ctx);".
802      err:
803      SSL_CTX_free(ctx);
804      ctx = NULL;
805      TRACE_DEVEL("leaving on error", QUIC_EV_CONN_NEW);
806      goto leave;
807     }

The less intrusive (without #ifdef) way to fix this it to add a "goto err"
statement from the code part which is reachable without USE_QUIC_OPENSSL_COMPAT.

Thank you to @chipitsine for having reported this issue in GH #3003.

4 weeks agoBUG/MINOR: quic-be: CID double free upon qc_new_conn() failures
Frederic Lecaille [Thu, 12 Jun 2025 08:59:35 +0000 (10:59 +0200)] 
BUG/MINOR: quic-be: CID double free upon qc_new_conn() failures

This issue may occur when qc_new_conn() fails after having allocated
and attached <conn_cid> to its tree. This is the case when compiling
haproxy against WolfSSL for an unknown reason at this time. In this
case the <conn_cid> is freed by pool_head_quic_connection_id(), then
freed again by quic_conn_release().

This bug arrived with this commit:

    MINOR: quic-be: QUIC connection allocation adaptation (qc_new_conn())

So, the aim of this patch is to free <conn_cid> only for QUIC backends
and if it is not attached to its tree. This is the case when <conn_id>
local variable passed with NULL value to qc_new_conn() is then intialized
to the same <conn_cid> value.

4 weeks agoCLEANUP: quic-be: Add comments about qc_new_conn() usage
Frederic Lecaille [Thu, 12 Jun 2025 08:50:52 +0000 (10:50 +0200)] 
CLEANUP: quic-be: Add comments about qc_new_conn() usage

This patch should have come with this last commit for the last qc_new_conn()
modifications for QUIC backends:

     MINOR: quic-be: get rid of ->li quic_conn member

qc_new_conn() must be passed NULL pointers for several variables as mentioned
by the comment. Some of these local variables are used to avoid too much
code modifications.

4 weeks agoMINOR: hq-interop: encode request from HTX for backend side support
Amaury Denoyelle [Wed, 11 Jun 2025 09:45:40 +0000 (11:45 +0200)] 
MINOR: hq-interop: encode request from HTX for backend side support

Implement transcoding of a HTX request into HTTP/0.9. This protocol is a
simplified version of HTTP. Request only supports GET method without any
header. As such, only a request line is written during snd_buf
operation.

4 weeks agoMINOR: hq-interop: decode response into HTX for backend side support
Amaury Denoyelle [Fri, 6 Jun 2025 14:23:22 +0000 (16:23 +0200)] 
MINOR: hq-interop: decode response into HTX for backend side support

Implement transcoding of a HTTP/0.9 response into a HTX message.

HTTP/0.9 is a really simple substract of HTTP spec. The response does
not have any status line and is contains only the payload body. Response
is finished when the underlying connection/stream is closed.

A status line is generated to be compliant with HTX. This is performed
on the first invokation of rcv_buf for the current stream. Status code
is set to 200. Payload body if present is then copied using
htx_add_data().

4 weeks agoMINOR: quic: wakeup backend MUX on handshake completed
Amaury Denoyelle [Wed, 28 May 2025 09:26:08 +0000 (11:26 +0200)] 
MINOR: quic: wakeup backend MUX on handshake completed

This commit is the second and final step to initiate QUIC MUX on the
backend side. On handshake completion, MUX is woken up just after its
creation. This step is necessary to notify the stream layer, via the QCS
instance pre-initialized on MUX init, so that the transfer can be
resumed.

This mode of operation is similar to TCP stack when TLS+ALPN are used,
which forces MUX initialization to be delayed after handshake
completion.

4 weeks agoMINOR: mux-quic: instantiate first stream on backend side
Amaury Denoyelle [Wed, 11 Jun 2025 13:38:59 +0000 (15:38 +0200)] 
MINOR: mux-quic: instantiate first stream on backend side

Adjust qmux_init() to handle frontend and backend sides differently.
Most notably, on backend side, the first bidirectional stream is created
preemptively. This step is necessary as MUX layer will be woken up just
after handshake completion.

4 weeks agoMINOR: mux-quic: set expect data only on frontend side
Amaury Denoyelle [Tue, 10 Jun 2025 14:37:11 +0000 (16:37 +0200)] 
MINOR: mux-quic: set expect data only on frontend side

Stream data layer is notified that data is expected when FIN is
received, which marks the end of the HTTP request. This prepares data
layer to be able to handle the expected HTTP response.

Thus, this step is only relevant on frontend side. On backend side, FIN
marks the end of the HTTP response. No further content is expected, thus
expect data should not be set in this case.

Note that se_expect_data() invokation via qcs_attach_sc() is not
protected. This is because this function will only be called during
request headers parsing which is performed on the frontend side.

4 weeks agoMINOR: mux-quic: define flag for backend side
Amaury Denoyelle [Wed, 11 Jun 2025 09:30:24 +0000 (11:30 +0200)] 
MINOR: mux-quic: define flag for backend side

Mux connection is flagged with new QC_CF_IS_BACK if used on the backend
side. For now the only change is during traces, to be able to
differentiate frontend and backend usage.

4 weeks agoMINOR: mux-quic: improve documentation for snd/rcv app-ops
Amaury Denoyelle [Tue, 10 Jun 2025 14:36:54 +0000 (16:36 +0200)] 
MINOR: mux-quic: improve documentation for snd/rcv app-ops

Complete document for rcv_buf/snd_buf operations. In particular, return
value is now explicitely defined. For H3 layer, associated functions
documentation is also extended.

4 weeks agoMINOR: quic: mark ctrl layer as ready on quic_connect_server()
Amaury Denoyelle [Thu, 5 Jun 2025 13:27:49 +0000 (15:27 +0200)] 
MINOR: quic: mark ctrl layer as ready on quic_connect_server()

Use conn_ctrl_init() on the connection when quic_connect_server()
succeeds. This is necessary so that the connection is considered as
completely initialized. Without this, connect operation will be call
again if connection is reused.

4 weeks agoMEDIUM: backend: delay MUX init with ALPN even if proto is forced
Amaury Denoyelle [Wed, 28 May 2025 15:05:44 +0000 (17:05 +0200)] 
MEDIUM: backend: delay MUX init with ALPN even if proto is forced

On backend side, multiplexer layer is initialized during
connect_server(). However, this step is not performed if ALPN is used,
as the negotiated protocol may be unknown. Multiplexer initialization is
delayed after TLS handshake completion.

There are still exceptions though that forces the MUX to be initialized
even if ALPN is used. One of them was if <mux_proto> server field was
already set at this stage, which is the case when an explicit proto is
selected on the server line configuration. Remove this condition so that
now MUX init is delayed with ALPN even if proto is forced.

The scope of this change should be minimal. In fact, the only impact
concerns server config with both proto and ALPN set, which is pretty
unlikely as it is contradictory.

The main objective of this patch is to prepare QUIC support on the
backend side. Indeed, QUIC proto will be forced on the server if a QUIC
address is used, similarly to bind configuration. However, we still want
to delay MUX initialization after QUIC handshake completion. This is
mandatory to know the selected application protocol, required during
QUIC MUX init.

4 weeks agoBUG/MEDIUM: mux-quic: adjust wakeup behavior
Amaury Denoyelle [Tue, 3 Jun 2025 15:18:30 +0000 (17:18 +0200)] 
BUG/MEDIUM: mux-quic: adjust wakeup behavior

Change wake callback behavior for QUIC MUX. This operation loops over
each QCS and notify their stream data layer on certain events via
internal helper qcc_wake_some_streams().

Previously, streams were notified only if an error occured on the
connection. Change this to notify streams data layer everytime wake
callback is used. This behavior is now identical to H2 MUX.

qcc_wake_some_streams() is also renamed to qcc_wake_streams(), as it
better reflect its true behavior.

This change should not have performance impact as wake mux ops should
not be called frequently. Note that qcc_wake_streams() can also be
called directly via qcc_io_process() to ensure a new error is correctly
propagated. As wake callback first uses qcc_io_process(), it will only
call qcc_wake_streams() if no error is present.

No known issue is associated with this commit. However, it could prevent
freezing transfer under certain condition. As such, it is considered as
a bug fix worthy of backporting.

This should be backported after a period of observation.

4 weeks agoBUILD: hlua: Fix warnings about uninitialized variables (2)
Christopher Faulet [Thu, 12 Jun 2025 08:49:51 +0000 (10:49 +0200)] 
BUILD: hlua: Fix warnings about uninitialized variables (2)

It was still failing on Ubuntu-24.04 with GCC+ASAN. So, instead of
understand the code path the compiler followed to report uninitialized
variables, let's init them now.

No backport needed.

4 weeks agoBUILD: listener: fix 'for' loop inline variable declaration
Aurelien DARRAGON [Wed, 11 Jun 2025 17:41:38 +0000 (19:41 +0200)] 
BUILD: listener: fix 'for' loop inline variable declaration

commit 16eb0fab3 ("MAJOR: counters: dispatch counters over thread groups")
introduced a build regression on some compilers:

  src/listener.c: In function 'listener_accept':
  src/listener.c:1095:3: error: 'for' loop initial declarations are only allowed in C99 mode
     for (int it = 0; it < global.nbtgroups; it++)
     ^
  src/listener.c:1095:3: note: use option -std=c99 or -std=gnu99 to compile your code
  src/listener.c:1101:4: error: 'for' loop initial declarations are only allowed in C99 mode
      for (int it = 0; it < global.nbtgroups; it++) {
      ^
  make: *** [src/listener.o] Error 1
  make: *** Waiting for unfinished jobs....

Let's fix that.
No backport needed

4 weeks agoBUILD: hlua: Fix warnings about uninitialized variables
Christopher Faulet [Thu, 12 Jun 2025 06:42:18 +0000 (08:42 +0200)] 
BUILD: hlua: Fix warnings about uninitialized variables

In hlua_applet_tcp_recv_try() and hlua_applet_tcp_getline_yield(), GCC 14.2
reports warnings about 'blk2' variable that may be used uninitialized. It is
a bit strange because the code is pretty similar than before. But to make it
happy and to avoid bugs if the API change in future, 'blk2' is now used only
when its length is greater than 0.

No need to backport.

4 weeks agoBUG/MINOR: hlua: Don't forget the return statement after a hlua_yieldk()
Christopher Faulet [Wed, 11 Jun 2025 19:39:19 +0000 (21:39 +0200)] 
BUG/MINOR: hlua: Don't forget the return statement after a hlua_yieldk()

In hlua_applet_tcp_getline_yield(), the function may yield if there is no
data available. However we must take care to add a return statement just
after the call to hlua_yieldk(). I don't know the details of the LUA API,
but at least, this return statement fix a build error about uninitialized
variables that may be used.

It is a 3.3-specific issue. No backport needed.

4 weeks agoMEDIUM: quic-be: initialize MUX on handshake completion
Frederic Lecaille [Thu, 11 Jan 2024 18:05:55 +0000 (19:05 +0100)] 
MEDIUM: quic-be: initialize MUX on handshake completion

On backend side, MUX is instantiated after QUIC handshake completion.
This step is performed via qc_ssl_provide_quic_data(). First, connection
flags for handshake completion are resetted. Then, MUX is instantiated
via conn_create_mux() function.

4 weeks agoMINOR: quic: define proper proto on QUIC servers
Amaury Denoyelle [Thu, 5 Jun 2025 13:18:44 +0000 (15:18 +0200)] 
MINOR: quic: define proper proto on QUIC servers

Force QUIC as <mux_proto> for server if a QUIC address is used. This is
similarly to what is already done for bind instances on the frontend
side. This step ensures that conn_create_mux() will select the proper
protocol.

4 weeks agoMINOR: quic-be: Prevent the MUX to send/receive data
Frederic Lecaille [Fri, 5 Jan 2024 14:45:17 +0000 (15:45 +0100)] 
MINOR: quic-be: Prevent the MUX to send/receive data

Such actions must be interrupted until the handshake completion.

4 weeks agoMINOR: quic-be: get rid of ->li quic_conn member
Frederic Lecaille [Fri, 6 Jun 2025 13:20:00 +0000 (15:20 +0200)] 
MINOR: quic-be: get rid of ->li quic_conn member

Replace ->li quic_conn pointer to struct listener member by  ->target which is
an object type enum and adapt the code.
Use __objt_(listener|server)() where the object type is known. Typically
this is were the code which is specific to one connection type (frontend/backend).
Remove <server> parameter passed to qc_new_conn(). It is redundant with the
<target> parameter.
GSO is not supported at this time for QUIC backend. qc_prep_pkts() is modified
to prevent it from building more than an MTU. This has as consequence to prevent
qc_send_ppkts() to use GSO.
ssl_clienthello.c code is run only by listeners. This is why __objt_listener()
is used in place of ->li.

4 weeks agoMINOR: quic-be: SSL_get_peer_quic_transport_params() not defined by OpenSSL 3.5 QUIC API
Frederic Lecaille [Mon, 2 Jun 2025 07:04:52 +0000 (09:04 +0200)] 
MINOR: quic-be: SSL_get_peer_quic_transport_params() not defined by OpenSSL 3.5 QUIC API

Disable the code around SSL_get_peer_quic_transport_params() as this was done
for USE_QUIC_OPENSSL_COMPAT because SSL_get_peer_quic_transport_params() is not
defined by OpenSSL 3.5 QUIC API.

4 weeks agoMINOR: quic-be: Make the secret derivation works for QUIC backends (USE_QUIC_OPENSSL_...
Frederic Lecaille [Wed, 28 May 2025 14:30:41 +0000 (16:30 +0200)] 
MINOR: quic-be: Make the secret derivation works for QUIC backends (USE_QUIC_OPENSSL_COMPAT)

quic_tls_compat_keylog_callback() is the callback used by the QUIC OpenSSL
compatibility module to derive the TLS secrets from other secrets provided
by keylog. The <write> local variable to this function is initialized to denote
the direction (write to send, read to receive) the secret is supposed to be used
for. That said, as the QUIC cryptographic algorithms are symmetrical, the
direction is inversed between the peer: a secret which is used to write/send/cipher
data from a peer point of view is also the secret which is used to
read/receive/decipher data. This was confirmed by the fact that without this
patch, the TLS stack first provides the peer with Handshake to send/cipher
data. The client could not use such secret to decipher the Handshake packets
received from the server. This patch simply reverse the direction stored by
<write> variable to make the secrets derivation works for the QUIC client.

4 weeks agoMINOR: quic-be: Missing callbacks initializations (USE_QUIC_OPENSSL_COMPAT)
Frederic Lecaille [Wed, 28 May 2025 13:58:44 +0000 (15:58 +0200)] 
MINOR: quic-be: Missing callbacks initializations (USE_QUIC_OPENSSL_COMPAT)

quic_tls_compat_init() function is called from OpenSSL QUIC compatibility module
(USE_QUIC_OPENSSL_COMPAT) to initialize the keylog callback and the callback
which stores the QUIC transport parameters as a TLS extensions into the stack.
These callbacks must also be initialized for QUIC backends.

4 weeks agoMINOR: quic-be: Store the remote transport parameters asap
Frederic Lecaille [Wed, 17 Jan 2024 14:30:04 +0000 (15:30 +0100)] 
MINOR: quic-be: Store the remote transport parameters asap

This is done from TLS secrets derivation callback at Application level (the last
encryption level) calling SSL_get_peer_quic_transport_params() to have an access
to the TLS transport paremeters extension embedded into the Server Hello TLS message.
Then, quic_transport_params_store() is called to store a decoded version of
these transport parameters.

4 weeks agoMINOR: quic-be: I/O handler switch adaptation
Frederic Lecaille [Tue, 16 Jan 2024 09:30:13 +0000 (10:30 +0100)] 
MINOR: quic-be: I/O handler switch adaptation

For connection to QUIC servers, this patch modifies the moment where the I/O
handler callback is switched to quic_conn_app_io_cb(). This is no more
done as for listener just after the handshake has completed but just after
it has been confirmed.

4 weeks agoMINOR: quic-be: Initial packet number space discarding.
Frederic Lecaille [Fri, 12 Jan 2024 16:03:02 +0000 (17:03 +0100)] 
MINOR: quic-be: Initial packet number space discarding.

Discard the Initial packet number space as soon as possible. This is done
during handshakes in quic_conn_io_cb() as soon as an Handshake packet could
be successfully sent.

4 weeks agoMINOR: quic-be: Add the conn object to the server SSL context
Frederic Lecaille [Tue, 27 May 2025 09:29:30 +0000 (11:29 +0200)] 
MINOR: quic-be: Add the conn object to the server SSL context

The initialization of <ssl_app_data_index> SSL user data index is required
to make all the SSL sessions to QUIC servers work as this is done for TCP
servers. The conn object notably retrieve for SSL callback which are
server specific (e.g. ssl_sess_new_srv_cb()).