Commit graph

3527 commits

Author SHA1 Message Date
Olivier Houchard
aaee6c463c MINOR: tasks: Remove wq_lock and the per-thread group wait queues
Now that they are no longer used, remove wq_lock and the per-thread
group wait queues.
2026-06-12 11:49:09 +02:00
William Lallemand
92206fb02f DOC: acme: add mentions of lua features
Some checks are pending
Contrib / admin/halog/ (push) Waiting to run
Contrib / dev/flags/ (push) Waiting to run
Contrib / dev/haring/ (push) Waiting to run
Contrib / dev/hpack/ (push) Waiting to run
Contrib / dev/poll/ (push) Waiting to run
FreeBSD / clang (push) Waiting to run
VTest / Generate Build Matrix (push) Waiting to run
VTest / (push) Blocked by required conditions
Windows / Windows, gcc, all features (push) Waiting to run
Mention ACME.challenge_ready() and event_hdl which are useful in lua to
implement dns-01.
2026-06-11 23:51:45 +02:00
William Lallemand
4bb21dae2f MINOR: acme: publish ACME_DEPLOY event via event_hdl
Add EVENT_HDL_SUB_ACME_DEPLOY to the ACME family. It is published in
the dns-01 challenge path after the TXT record information has been
prepared, carrying the certificate store name, domain, account
thumbprint, dns_record value, and optionally the provider and vars
strings.

Lua subscribers using core.event_sub() receive the event data as an
AcmeEvent object, which is the same class used for ACME_NEWCERT and
carries the fields relevant to the event type.
2026-06-11 19:14:52 +02:00
William Lallemand
81d7624e01 MINOR: acme: publish ACME_NEWCERT event via event_hdl
Add a new EVENT_HDL_SUB_ACME_NEWCERT event type in the ACME family.
It is published after a new certificate has been successfully fetched
and installed. The event carries the certificate store name, allowing
subscribers to act on newly available certificates.

Lua subscribers using core.event_sub() receive the event data as an
AcmeEvent object with a crtname field containing the certificate store
name.
2026-06-11 19:14:52 +02:00
William Lallemand
784f972a6f MINOR: acme/lua: implement ACME.challenge_ready() Lua function
Add a new ACME global Lua table with a challenge_ready(crt, dns) method
that wraps acme_challenge_ready(). It marks the ACME challenge for domain
<dns> in certificate <crt> as ready and returns the number of remaining
challenges, or 0 when all challenges are ready and validation has been
triggered. A Lua error is raised if the certificate or domain is not found.

The ACME table is registered for each lua_State via the new
REGISTER_HLUA_STATE_INIT() mechanism.
2026-06-11 15:01:38 +02:00
William Lallemand
d0fde90e16 MINOR: lua: add REGISTER_HLUA_STATE_INIT() to register state init callbacks
Add a registration mechanism so that modules outside of hlua.c can hook
into each lua_State creation. Modules call hap_register_hlua_state_init()
(or the REGISTER_HLUA_STATE_INIT() macro) with a callback of the form:

  int my_init(lua_State *L, char **errmsg);

The callback returns an ERR_* code. ERR_ALERT and ERR_WARN trigger
ha_alert()/ha_warning() respectively; any other non-zero errmsg is
emitted via ha_notice(). ERR_FATAL or ERR_ABORT cause exit(1).
Registered entries are freed in hlua_deinit().
2026-06-11 14:13:04 +02:00
Willy Tarreau
7835e1fcbe [RELEASE] Released version 3.5-dev0
Some checks failed
Contrib / admin/halog/ (push) Has been cancelled
Contrib / dev/flags/ (push) Has been cancelled
Contrib / dev/haring/ (push) Has been cancelled
Contrib / dev/hpack/ (push) Has been cancelled
Contrib / dev/poll/ (push) Has been cancelled
FreeBSD / clang (push) Has been cancelled
VTest / Generate Build Matrix (push) Has been cancelled
Windows / Windows, gcc, all features (push) Has been cancelled
VTest / (push) Has been cancelled
Released version 3.5-dev0 with the following main changes :
    - MINOR: version: mention that it's development again
2026-06-03 15:26:45 +02:00
Willy Tarreau
64a335366d [RELEASE] Released version 3.4.0
Released version 3.4.0 with the following main changes :
    - BUG/MINOR: tcpcheck: Check LDAP response to not read more data than available
    - BUG/MINOR: ssl-gencert: validate SNI characters to prevent SAN certificate injection
    - BUG/MINOR: mux-h1: H2 preface rejection doesn't update stick-table glitches
    - BUG/MEDIUM: cpu-topo: Enforce thread-hard-limit on policy
    - BUG/MEDIUM: qmux: do not crash on too large record
    - BUG/MEDIUM: qmux: do not crash on receiving an invalid first frame
    - BUG/MINOR: qmux: reject too large initial record
    - Revert "BUG/MEDIUM: dns: fix long loops in additional records parse on name failure"
    - BUG/MINOR: qpack: Fix index calculation in debug functions
    - BUG/MINOR: qpack: fix potential null-pointer dereference in qpack_dht_insert()
    - CLEANUP: qpack: fix copy-paste typo in value Huffman debug string
    - BUG/MINOR: qpack: fix sign bit mask in qpack_decode_fs_pfx()
    - CLEANUP: qpack: fix copy-paste typo in value Huffman debug string for WLN
    - BUG/MINOR: qpack: fix huff_dec() error handling in qpack_decode_fs()
    - CLEANUP: qpack: move encoded macros to qpack-t.h to avoid duplication
    - BUG/MEDIUM: quic: handle ECONNREFUSED on RX side
    - BUG/MINOR: quic: Fix memory leak in quic_deallocate_dghdlrs()
    - BUG/MEDIUM: lua: defer Lua VM initialisation to the first Lua config keyword
    - REGTESTS: lua: fix tune.lua.openlibs in Lua reg-tests
    - BUG/MINOR: mux-h2: Count padding for connection flow control on error path
    - BUILD: addons: convert 51d addon to EXTRA_MAKE
    - BUILD: addons: convert deviceatlas addon to EXTRA_MAKE
    - BUILD: addons: convert WURFL addon to EXTRA_MAKE
    - MINOR: mux_quic/flags: add missing flags
    - BUG/MINOR: mux_quic: open an idle QCS on reset on BE side
    - BUG/MINOR: mux_quic: fix BE conn removal on app shutdown
    - BUG/MINOR: mux_quic: prevent BE reuse with an errored conn
    - BUG/MINOR: quic: fix ack range node pool_free call passing wrong pointer type
    - MEDIUM: quic: optimize HKDF operations by reusing per-thread contexts
    - BUG/MEDIUM: quic: reset cwnd in slow_start on persistent congestion (cubic)
    - BUG/MEDIUM: quic: reset consecutive_losses on exit from recovery period (cubic)
    - BUG/MINOR: quic: update drs->lost before calling on_ack_recv
    - Revert "MEDIUM: quic: optimize HKDF operations by reusing per-thread contexts"
    - BUG/MEDIUM: lua: register hlua_init() as a pre-check to fix crash without Lua config
    - REGTESTS: quic: disable quic/ocsp_auto_update for now
    - BUG/MINOR: threads: set at least grp_max when mtpg is too small
    - BUG/MEDIUM: threads: ignore max-threads-per-group when thread-groups is set
    - CLEANUP: thread: indicate when max-threads-per-group is ignored
    - MINOR: cpu-topo: notify when cpu-policy is ignored due to other settings
    - MINOR: thread: report when thread-groups or nbthread results in less threads
    - BUILD: makefile: include EXTRA_MAKE in the .build_opts construction
    - BUG/MINOR: quic: Fix another buffer overflow with sockaddr_in46
    - MINOR: quic: Copy sin6_flowinfo and sin6_scope_id too
    - BUILD: Makefile: put EXTRA_MAKE help at the right place
    - BUG/MINOR: cache: fix cache tree iteration
    - BUG/MEDIUM: resolvers: Wait a bit before calling the xprt prepare_srv
    - CLEANUP: addons/51degrees: initialize variables
    - MINOR: addons/51degrees: handle memory allocation failures
    - CLEANUP: ncbmbuf: improve handling of memory allocation errors in unit tests
    - CLEANUP: admin/halog: improve handling of memory allocation errors
    - DOC: internals: clarify ambiguous wording in core-principles
    - DOC: internals: add a threat model definition
    - DOC: add security.txt describing how to report security issues
    - DOC: security: also add a note to exclude dev/ and admin/
    - BUG/MEDIUM: qmux: Close connection on invalid frame
    - CLEANUP: fix comment typo
    - BUG/MEDIUM: h3: fix MAX_PUSH_ID handling
    - BUG/MINOR: cache: Fix copy of value when parsing maxage
    - BUG/MEDIUM: mux-h1: Dup connection/upgrade value to parse it when making headers
    - BUG/MEDIUM: htx: Fix headers rollback on partial copy in htx_xfer()
    - MINOR: deinit: release the in-memory copy of shared libs
    - MINOR: debug: add -dA to dump an archive of all dependencies
    - BUG/MEDIUM: ssl: Make sure the alpn length is small enough
    - BUG/MINOR: applet: Commit changes into input buffer after sending HTX data
    - BUG/MINOR: mux-spop: Fix possible off-by-one OOB read in spop_get_varint()
    - BUG/MEDIUM: leastconn: Unlock the write lock on allocation failure
    - BUG/MINOR: tasks: Increase the right niced_task counter
    - BUILD: makefile: search for Lua 5.5 as well
    - DEV: dev/gdb: improve ebtree pointer handling
    - DEV: dev/gdb: add simple task dump
    - DEV: dev/gdb: add simple thread dump
    - DEV: dev/gdb: add fdtab dump
    - DOC: config: add a few more explanation in http-reusee regarding sni-auto
    - REGTESTS: add basic QMux tests
    - BUG/MINOR: http-act: Properly handle final evaluation in pause action
    - BUILD: makefile/lua: use the system's default library before all other variants
    - BUG/MINOR: startup: unbreak chroot with CAP_SYS_CHROOT
    - BUG/MINOR: haterm: do not try to bind QUIC when not supported
    - BUG/MINOR: haterm: also apply the tcp-bind-opts to clear TCP "bind" lines
    - CLEANUP: haterm: do not try to bind to SSL when not built in
    - MINOR: haterm: enable ktls on the SSL bind line when supported
    - CI: github: replace cirrus by a vmactions/freebsd-vm job
    - BUILD: makefile: fix build error with GNU make 4.2.1 and /bin/dash
    - BUG/MEDIUM: channel: Fix condition to know if a channel may send
    - BUG/MEDIUM: vars: Properly eval set-var-fmt action for emtpy log-format string
    - CI: github: run illumos job weekly on Mondays at 03:00 instead of monthly
    - BUG/MEDIUM: stream: Don't use small buffer on queuing with a request data filter
    - BUG/MINOR: jwe: don't write randoms past MAX_DECRYPTED_CEK_LEN in RSA_PKCS1_PADDING
    - BUG/MEDIUM: chunk: do not rely on small trash by default for expressions
    - CLEANUP: map: always test pat->ref in sample_conv_map_key()
    - DEV: patchbot: prepare for new version 3.5-dev
    - MINOR: version: mention that it's 3.4 LTS now.
2026-06-03 15:01:51 +02:00
Willy Tarreau
7ac4bcfbd4 DOC: config: add a few more explanation in http-reusee regarding sni-auto
The default sni-auto that aims at not upsetting certain servers doing
excessive checks of SNI vs host has some drawbacks (lower reuse ratio)
that are particularly hard to diagnose, so let's explain how connections
are reused/purged when dealing with many hosts, and how to cheat as well.

Let's also mention the expression used by "sni-auto" since it was only
mentioned in the code.
2026-06-02 09:14:11 +02:00
Willy Tarreau
030a2bfeeb MINOR: debug: add -dA to dump an archive of all dependencies
This adds "-dA[file]" on the command line, which dumps an archive of all
dependencies detected at runtime into the designated file in tar format.
This is equivalent to "set-dumpable libs", but instead of keeping the libs
in memory, it dumps them into a file. This may be used after a core dump,
in order to provide all necessary libraries to developers to permit them
to exploit the core. This may not be available on all operating systems.
2026-06-01 15:01:32 +02:00
Willy Tarreau
41a20c1738 DOC: security: also add a note to exclude dev/ and admin/
These ones are not intended for production so they're out of scope.
This also fixes a paragraph formatting issue left after a fix.
2026-06-01 00:46:21 +02:00
Willy Tarreau
03b828b648 DOC: add security.txt describing how to report security issues
Move the security contact out of intro.txt into a dedicated, easily
searchable doc/security.txt that points reporters at the threat model
first, and reference it from intro.txt's contacts section and the
documentation index.
2026-05-31 22:44:15 +02:00
Willy Tarreau
8badf5d2fa DOC: internals: add a threat model definition
Add doc/internals/threat-model.txt describing what does and does not
qualify as a security vulnerability in HAProxy so that reporters and
developers have a common understanding of the threat model, and make it
clear that anything non-critical should be handled in the open and
not hidden behind embargoes.

The document lists assets to protect, what constitutes an attack, what
are the mitigations in place, and the severity ordering of various
risks. This may in the long term also help developers make better
choices of default settings and option names, and may also justify
changing default settings over time when modern operating systems
bring new possibilities.

A section also lists some invariants and defaults in an attempt to
limit the risk of reporting theoretical issues that are technically
impossible to happen in the field.

This is an initial version meant to be refined as cases arise. It
was incrementally designed and cross-checked with the help of three
independent LLMs (Qwen, Gemini and Claude) until each correctly
classified a set of sample reports against it. In the current state
they do not raise any residual ambiguities anymore.
2026-05-31 20:28:08 +02:00
Willy Tarreau
551e01e3e7 DOC: internals: clarify ambiguous wording in core-principles
After testing against a few LLMs, it appeared that several entries in
the core principles document were ambiguous or imprecise and could be
misread (size_t, pools, trash, dwcas, comparison, ncbuf). No more
complaint after this rewording so this will be sufficient for now.
2026-05-31 16:38:03 +02:00
William Lallemand
1c59c39171 BUG/MEDIUM: lua: defer Lua VM initialisation to the first Lua config keyword
HAProxy used to call hlua_init() unconditionally from step_init_1(),
before any configuration file was parsed.  As a consequence, Lua states
0 and 1 were always created with hlua_openlibs_flags set to its default
value (HLUA_OPENLIBS_ALL), regardless of any tune.lua.openlibs directive
that appeared later in the global section.  With multiple threads, states
2..N were created correctly in hlua_post_init() after the config had been
parsed, while states 0 and 1 retained the full standard-library set.
This produced the observable bug reported in GitHub issue #3396: a script
loaded with lua-load-per-thread could see require() as a function on
thread 1 but nil on thread 2 when tune.lua.openlibs was used to restrict
the available libraries.

The initialisation is now lazy.  hlua_init() is idempotent: it returns
immediately if the states already exist (hlua_states[0] != NULL).  It is
called explicitly from the three config keyword handlers that need the
Lua states to be live before they can do their work (lua-load,
lua-load-per-thread, lua-prepend-path) and from tune.lua.openlibs, after
the hlua_openlibs_flags variable has been updated, so that the states are
always created with the correct library set.

hlua_post_init() calls hlua_init() unconditionally as a safety net,
covering the case where no Lua directive appeared in the configuration at
all (no global section, or only pure-tuning directives such as timeouts
and memory limits), and ensuring correct behaviour with multiple
consecutive global sections.

As a result of this change, tune.lua.openlibs must now appear before
lua-load, lua-load-per-thread, and lua-prepend-path in the configuration;
if any of those keywords is encountered first, the Lua states will already
be initialised and tune.lua.openlibs with a non-default value will return
a parse error.

No backport needed.
2026-05-28 11:36:02 +02:00
Willy Tarreau
88da61e218 [RELEASE] Released version 3.4-dev14
Some checks are pending
Contrib / admin/halog/ (push) Waiting to run
Contrib / dev/flags/ (push) Waiting to run
Contrib / dev/haring/ (push) Waiting to run
Contrib / dev/hpack/ (push) Waiting to run
Contrib / dev/poll/ (push) Waiting to run
VTest / Generate Build Matrix (push) Waiting to run
VTest / (push) Blocked by required conditions
Windows / Windows, gcc, all features (push) Waiting to run
Released version 3.4-dev14 with the following main changes :
    - MINOR: config: shm-stats-file is no longer experimental
    - BUILD: proxy: unstatify the proxies_del_lock to avoid a warning without threads
    - BUG/MEDIUM: net_helper: fix a remaining possibly infinite loop in converters
    - MINOR: ssl_sock: remove unneeded check on QMux flags
    - MINOR: connection: define xprt_add_l6hs()
    - MINOR: xprt_qmux: define default value for get_alpn
    - MINOR: connection: define mask CO_FL_WAIT_XPRT_L6
    - MINOR: session: support QMux in clear on FE side
    - MINOR: backend: support QMux in clear for BE side
    - BUG/MINOR: ocsp: Manage date too far away in the future
    - MINOR: mux_quic: handle STOP_SENDING in QMux
    - MINOR: mux_quic: handle MAX_STREAMS for uni stream in QMux
    - MINOR: mux_quic: do not crash on unhandled QMux frame reception
    - BUG/MEDIUM: applet: Properly handle receives of size 0
    - BUG/MEDIUM: resolvers: Fix test on dn label size in resolv_dn_label_to_str()
    - BUG/MEDIUM: ssl-gencert: Unlock LRU cache if failing to generate certificate
    - BUG/MINOR: quic: fix ODCID lookup from derived value
    - BUG/MEDIUM: dict: hold lock while decrementing refcount in dict_entry_unref
    - BUG/MINOR: tcpchecks: Limit parsing of agent-check reply to the buffer
    - BUG/MEDIUM: hlua: Fix integer underflow when receiving line from lua cosocket
    - BUG/MEDIUM: cli: Fix parsing of pattern finishing a command payload
    - BUG/MEDIUM: acme: NUL terminate response buffer before PEM parsing
    - BUILD: intops: mask the fail value in array_size_or_fail()
    - BUG/MEDIUM: log-forward: make sure the month is unsigned
    - BUG/MEDIUM: regex: allocate a large enough pcre2 match for all matches
    - BUG/MEDIUM: tcpcheck/spoe: bound the SPOP error code to valid values
    - BUG/MEDIUM: cache: fix a refcount leak for missed secondary entries
    - BUG/MINOR: log: free logformat expr on compile failure in cfg_parse_log_profile
    - BUG/MINOR: resolvers: fix room for trailing zero in resolv_dn_label_to_str()
    - BUG/MINOR: resolvers: fix risk of appending garbage past the domain name
    - BUG/MINOR: mux-h2: validate HEADERS frame length before reading stream dep
    - BUG/MINOR: log: look for the end of priority before the end of the buffer
    - BUG/MINOR: dict: fix refcount race on insert collision
    - BUG/MINOR: init: use more than ha_random64() for the cluster secret
    - BUG/MINOR: sample: limit the be2hex converter's chunk size
    - CLEANUP: resolvers: use read_n32() instead of open-coded big-endian read
    - CLEANUP: resolvers: remove pool_free(NULL) in SRV additional record matching
    - CLEANUP: resolvers: fix comment typos and wrong filenames in file headers
    - BUG/MINOR: haterm: fix the random suffix multiplication
    - MINOR: haterm: enable h3 for TCP bindings
    - MINOR: haterm: do not emit a warning when not using SSL
    - BUG/MEDIUM: h1: drop headers whose names contain invalid chars
    - BUG/MEDIUM: h1: limit status codes to 3 digits by default
    - BUG/MEDIUM: cache: always verify the primary hash in get_secondary_entry()
    - BUG/MINOR: cache: also recognize directives in the form "token="
    - BUG/MINOR: resolvers: relax size checks in authority record parsing
    - BUG/MINOR: sample: request an extra output byte for the url_dec converter
    - BUG/MINOR: http-fetch: check against the whole token in get_http_auth()
    - BUG/MEDIUM: acme: protect against risk of null-deref on connection failure
    - BUG/MINOR: http-ext: always check remaining data when reading rfc7239 nodeport
    - BUG/MINOR: base64: return empty string for empty input in base64dec()
    - BUG/MINOR: payload: fix the handshake length bounds check smp_client_hello_parse()
    - BUG/MINOR: ssl-hello: make use of the null-terminated servername
    - BUG/MINOR: resolvers: switch to a better PRNG for query IDs
    - BUG/MINOR: addons/51d: NUL-terminate headers before passing them to Trie API
    - BUG/MEDIUM: tools: insert an XXH64 layer on the PRNG output
    - MINOR: tools: provide a function to generate a hashed random pair
    - MEDIUM: init: fall back to ha_random64_pair_hashed() for the cluster secret
    - MEDIUM: tools: use the hashed random pair for UUID generation
    - MEDIUM: h1: use ha_random64_pair_hashed() for the WebSocket key
    - MEDIUM: quic: use ha_random64_pair_hashed() to generate the QUIC retry tokens
    - MEDIUM: tools: switch the main PRNG to a thread-local xoshiro256**
    - BUG/MEDIUM: h3: reject client push stream
    - BUG/MINOR: h3: reject server push stream
    - BUG/MINOR: h3: reject client CANCEL_PUSH frame
    - BUG/MINOR: h3: adjust error on PUSH_PROMISE frame reception
    - BUG/MINOR: h3: reject server MAX_PUSH_ID frame
    - BUG/MEDIUM: auth: fix unconfigured password NULL deref
    - BUG/MINOR: h3: add missing break on rcv_buf()
    - BUG/MINOR: hlua: prevent Lua from passing CR/LF/NUL in HTTP headers
    - BUG/MINOR: qmux: do not crash on frame parsing issue
    - BUG/MINOR: quic: reject packet too short for HP decryption
    - BUG/MINOR: jwe: enforce GCM tag length to 128 bits
    - BUG/MEDIUM: jwe: substitute random CEK on RSA1_5 decryption failure per RFC 7516 #11.5
    - BUG/MEDIUM: mux-fcgi: reject stream ID 0 for application records
    - MINOR: http: Add function to remove all occurrences of a value in a header
    - MINOR: h1: Add  a H1M flag to specify a non-empty 'Upgrade:' header was parsed
    - BUG/MEDIUM: h1-htx: Sanitize parsing to properly handle upgrade requests
    - BUG/MINOR: mux-fcgi: Use relative offset to compute contig data in demux buf
    - BUG/MINOR: mux-spop: Use relative offset to compute contig data in demux buf
    - CLEANUP: mux-fcgi/mux-spop: Remove copy/pasted comment about slow realign
2026-05-26 21:56:40 +02:00
Willy Tarreau
8bdcc55163 BUG/MEDIUM: h1: limit status codes to 3 digits by default
By default, HTTP/1 status codes are not limited in the parser. However,
the value is stored in a 16-bit field, meaning that it may be truncated
if too large. Let's just restrict to 3-digits by default, and permit to
relax the check when accept-unsafe-violations is set, provided that the
value still fits in 16 bits.

This could be backported to latest LTS release.
2026-05-26 13:13:24 +02:00
Willy Tarreau
b9aaf3c18a BUG/MEDIUM: h1: drop headers whose names contain invalid chars
Originally with "option accept-invalid-http-request", we couldn't really
edit the request on the fly to remove offending headers. But since we
have HTX and the headers are indexed one at a time, it has become
trivial. A non-negligible number of violations are conditioned by the
now renamed "option accept-unsafe-violations-in-http-request", and a
controversial one could definitely be reporting and passing invalid
header names containing control chars or spaces. The option was placed
so as not to block requests/responses containing them, but there's no
point in passing them to the other side. Most of the time it will be
totally harmless since the other side will reject them. But in case
haproxy is placed in front of a non-compliant server, it would fail
to protect it.

This patch implements a name check for all headers when a parsing
error was detected. It's cheap enough (especially since only done
after an error), and will skip the header if its name is invalid.
This may also remove some possibilities of confusion in logs, or
when encoding headers names for example.

This should be backported at least till the latest LTS.
2026-05-26 13:13:18 +02:00
Willy Tarreau
050e06dd66 MINOR: config: shm-stats-file is no longer experimental
As confirmed by Aurlien, there isn't any point in keeping this feature
in experimental status, it's now stable.
2026-05-21 08:50:20 +02:00
Willy Tarreau
bcf768f157 [RELEASE] Released version 3.4-dev13
Some checks are pending
Contrib / admin/halog/ (push) Waiting to run
Contrib / dev/flags/ (push) Waiting to run
Contrib / dev/haring/ (push) Waiting to run
Contrib / dev/hpack/ (push) Waiting to run
Contrib / dev/poll/ (push) Waiting to run
VTest / Generate Build Matrix (push) Waiting to run
VTest / (push) Blocked by required conditions
Windows / Windows, gcc, all features (push) Waiting to run
Released version 3.4-dev13 with the following main changes :
    - BUG/MINOR: backend: correct parameter value validation in get_server_ph_post()
    - BUG/MINOR: config/dns: properly fail on duplicate nameserver name detection
    - BUG/MEDIUM: dns: fix long loops in additional records parse on name failure
    - BUG/MEDIUM: resolvers: fix name compression pointer validation in resolv_read_name()
    - BUG/MEDIUM: dns: fix memory leak of sockaddr in dns_session_init() error path
    - CLEANUP: proxy: fix tiny mistakes in parse error messages
    - CLEANUP: dns: fix misleading error messages in dns_stream_init()
    - BUG/MINOR: server: better handling of OOM in srv_set_fqdn()
    - BUG/MINOR: servers: use proper source of pool_conn_name in srv_settings_cpy()
    - BUG/MEDIUM: server/cli: unlock server lock on failure in cli_parse_set_server
    - BUG/MINOR: resolvers: fix dangling list pointer in resolvers_new() error paths
    - BUG/MINOR: dns: fix dangling dgram pointer on dns_dgram_init() failure path
    - BUG/MINOR: proxy: use proxy_drop() in parse_new_proxy() error path
    - CLEANUP: resolvers: properly initialize the sample in resolv_action_do_resolve()
    - BUG/MINOR: resolvers: report the expression error in the do-resolve() action parser
    - BUG/MINOR: resolvers: fix leaked dgram and dns_ring struct in parse_resolve_conf()
    - BUG/MINOR: resolvers: fix leaked fields on cfg_parse_resolvers() error paths
    - BUG/MINOR: resolvers: fix missing task_idle destruction in resolvers_destroy()
    - CLEANUP: proxy: fix duplicate declaration of cli_find_frontend in proxy.h
    - CLEANUP: address a few typos and copy-paste errors in httpclient and dns
    - DOC: internal: add a few rules about internal core principles
    - BUG/MINOR: session/trace: use distinct flags for SESS_EV_END and _ERR
    - CLEANUP: stick-table: uniformize the different action_inc_gpc*()
    - REGTESTS: do not run quic/tls13_ssl_crt-list_filters in quic openssl compat mode
    - REGTESTS: quic/issuers_chain_path: do not forget to enable QUIC compat mode
    - BUG/MINOR: sock: store the connection error status
    - BUG/MINOR: check: properly report errno in chk_report_conn_err()
    - CLEANUP: tcpcheck: mention that we're a bit far for a sync errno
    - BUG/MINOR: jwt: fix possible memory leak in convert_ecdsa_sig() error path
    - CLEANUP: jwe: fix theoretical overflow in AAD length calculation
    - DOC: config: further clarify that resolvers "default" exists
    - MINOR: proxy: remove the experimental status on dynamic backends
    - BUG/MEDIUM: limits: properly account for global.maxpipes in compute_ideal_maxconn()
    - BUG/MINOR: jws: fix OpenSSL 3.0 version check from > to >=
    - BUG/MINOR: jws: Add missing return value check (EVP_PKEY_get_bn_param)
    - BUG/MINOR: server: Properly handle init-state value during haproxy startup
    - BUG/MINOR: httpclient-cli: Destroy http-client context if failing to start it
    - BUG/MEDIUM: h1: Skip all h2c values from Upgrade headers during parsing
    - BUG/MINOR: h1: Don't mask websocket protocol if multiple protocols used
    - MINOR: haterm: Don't init haterm master pipe if not used
    - CLEANUP: haterm: Remove "(too old kernel)" from warning message during init
    - BUG/MINOR: httpclient-cli: fix uninit variable in error label
    - MINOR: mux: Rename the "token" from mux_proto_list to mux_proto
    - MEDIUM: connections: Use both mux_proto and alpn to pick a mux
    - MINOR: connection: define conn_select_mux_fe()
    - MINOR: connection: define conn_select_mux_be()
    - MINOR: connection/mux_quic: add MUX <init_xprt> field for QMux handshake
    - MINOR: proxy/server: reject TCP ALPN h3 without experimental
    - MEDIUM: ssl: allow h3/QMux negotiation without explicit proto
    - BUG/MINOR: server: accept server IDs above 2^31 and clarify error message
    - BUG/MINOR: backend: fix balance hash calculation when using hash-type none
    - MINOR: server: support hash-key id32 for a cleaner distribution
    - MINOR: backend: support hash-key guid for a stabler distribution
    - MINOR: startup: support unprivileged chroot if possible
    - MEDIUM: startup: add automatic chroot feature
    - MINOR: h2: explain committed_extra_streams dec on h2_init() error
    - OPTIM: h2: do not update committed streams if elasticity disabled
    - MINOR: mux_quic: implement basic committed_extra_streams accounting
    - MINOR: quic: use stream elasticity value for initial advertisement
    - MINOR: mux_quic: define ms_bidi_rel QCC member
    - MAJOR: mux_quic: support stream elasticity during connection lifetime
    - BUG/MEDIUM: servers: Store the connection hash with the parameter cache
    - BUG/MINOR: prevent conn leak in case of xprt_qmux init failure
    - BUILD: traces: set a few __maybe_unused on vars used only for traces
    - BUILD: traces: add USE_TRACE allowing to disable traces
    - MINOR: startup: do not execute chroot() when "/"
    - MEDIUM: startup: warn when chroot is not set for root
    - BUG/MEDIUM: servers: Don't forget to set srv_hash when needed
    - DOC: fix typo on QUIC stream.max-concurrent reference
    - BUG/MINOR: mux_quic: do not exceed stream.max-concurrent on backend side
    - BUG/MINOR: htx: Fix value of HTX_XFER_HDRS_ONLY flag
    - MEDIUM: htx: Improve htx_xfer API to not count HTX meta-data
    - BUG/MEDIUM: applet: Fix transfer of HTX data to the applet
    - BUG/MEDIUM: htx: Alloc a chunk of right size in htx_replace_blk_value()
    - MEDIUM: stick-tables: Avoid freeing elements while holding a lock
    - MINOR: intops: add a multiply overflow detection for ulong and size_t
    - CLEANUP: tree-wide: use array_size_or_fail() in array size for allocations
    - DOC: update supported gcc and openssl versions in INSTALL
2026-05-20 17:46:36 +02:00
Amaury Denoyelle
47a61eb86d BUG/MINOR: mux_quic: do not exceed stream.max-concurrent on backend side
Some checks are pending
Contrib / admin/halog/ (push) Waiting to run
Contrib / dev/flags/ (push) Waiting to run
Contrib / dev/haring/ (push) Waiting to run
Contrib / dev/hpack/ (push) Waiting to run
Contrib / dev/poll/ (push) Waiting to run
VTest / Generate Build Matrix (push) Waiting to run
VTest / (push) Blocked by required conditions
Windows / Windows, gcc, all features (push) Waiting to run
Fix usage of stream.max-concurrent QUIC setting on the backend side.
Contrary to frontend connections, this limit must be enforced by QUIC
MUX directly. This is necessary as the peer may allow a larger number of
concurrent streams via its flow control.

First, QUIC TP initial max bidi streams value is now set to 0. This is
fine as only the HTTP/3 client is expected to open bidirectional
streams.

The most important changes is performed in qcm_avail_streams(). The
value first depends on the peer flow control. Now, it is further reduced
if necessary to not exceed the configured BE stream.max-concurrent.

Note that this new behavior may further increases current limitation on
QUIC BE reuse when a QCS instance is kept while its upper stream layer
is detached. In this case there is a risk that the connection is not
reinserted in the correct server pool, as an idle or avail one.

This is a breaking change as BE stream.max-concurrent keyword setting
meaning is changed in effect. However, this does not necessitate extra
warnings as the previous usage was in effect useless. Furthermore, QUIC
on the backend side is still considered as experimental.

This can be backported up to 3.3.
2026-05-20 14:42:03 +02:00
Amaury Denoyelle
b7c607e207 DOC: fix typo on QUIC stream.max-concurrent reference
Add a missing "fe" prefix for the QUIC keyword reference in
tune.streams-elasticity documentation.
2026-05-20 13:40:53 +02:00
Willy Tarreau
b9acb4415f MEDIUM: startup: warn when chroot is not set for root
We're still regularly seeing insecure configs where chroot is missing.
Now that we have "chroot auto", there's no excuse for not knowing where
to chroot, so let's detect that we're starting as root, detect that the
process is allowed to chroot (i.e. no capability issue, or some hardened
containers), and if no chroot is set, let's emit a warning explaining how
to silence it, i.e. either "chroot auto" or "chroot /".

Most likely we'll start using "chroot auto" by default in 3.5 if no
usability issue is reported.
2026-05-20 11:51:45 +02:00
Amaury Denoyelle
e139dd90e3 MAJOR: mux_quic: support stream elasticity during connection lifetime
Some checks are pending
Contrib / admin/halog/ (push) Waiting to run
Contrib / dev/flags/ (push) Waiting to run
Contrib / dev/haring/ (push) Waiting to run
Contrib / dev/hpack/ (push) Waiting to run
Contrib / dev/poll/ (push) Waiting to run
VTest / Generate Build Matrix (push) Waiting to run
VTest / (push) Blocked by required conditions
Windows / Windows, gcc, all features (push) Waiting to run
qcc_release_remote_stream() is called each time a remote stream is
closed. Flow control accounting is updated and when necessary, a
MAX_STREAMS_BIDI frame is prepared to allow the peer to initiate new
streams.

This patch extends stream elasticity features with the QUIC bidirection
stream flow control mechanism. The announced value can now be possibly
reduced depending on conn_calc_max_streams().

The first step is to decrement closed streams from the global committed
extra streams total. This must be performed conn_calc_max_streams() to
ensure the calculation will be valid.

Then, there is two cases depending on conn_calc_max_streams() result. If
the value is less than the peer still remaining stream window, nothing
more is performed. If the opposite case, flow control must be increased
and a MAX_STREAMS_BIDI frame is prepared, with the value adjusted to not
exceed the stream elasticity limit. Global extra streams total is then
finally incremented.

This calcul also ensures that when all streams are closed, global extra
streams accounting operations are decremented by 1, as a connection
always has access to one stream which is excluded from the global total.

Note that if stream elasticity is not active, flow control increases
principle is unchanged and remains statically performed.

This patch is labelled as major as it complexifies bidirectional stream
flow control mechanisme. This is a sensitive operation as there is a
risk of connection freeze if flow control updates are inadvertently
skipped.
2026-05-20 09:52:50 +02:00
Amaury Denoyelle
d21ec4c707 MINOR: quic: use stream elasticity value for initial advertisement
When stream elasticity is active, the maximum number of concurrent bidi
streams advertised via transport parameters is now reduced depending on
the connection load. This is implemented via conn_calc_max_streams()
which returns the value to use.

This is not applied on listeners with enabled 0-RTT. Indeed, for such
connections, clients are expected to reuse the previously seen transport
parameters. The server on the other hand must not decrease several
values on the newly advertised params, in particular for the maximum
number of concurrent bidi streams. The simplest way to prevent 0-RTT
failure is to not mix stream elasticity with it.

Note that the 0-RTT limitation is only applied for the initial value :
during the connection lifetime, stream elasticity can still be used by
the MUX to dynamically reduce the stream window. This will be
implemented in a future patch.
2026-05-20 09:52:50 +02:00
Maxime Henrion
641fe4f119 MEDIUM: startup: add automatic chroot feature
It is now possible to use "chroot auto" in the configuration. This lets
haproxy create an anonymous (cleaned up after the process terminates)
and read-only directory for chroot. This directory is created in /tmp;
we might want to support creating it in a different directory in the
future, either by respecting $TMPDIR or by allowing an optional
directory after the "auto" keyword.
2026-05-20 08:34:24 +02:00
Willy Tarreau
7004bb3b8c MINOR: backend: support hash-key guid for a stabler distribution
Some checks are pending
Contrib / admin/halog/ (push) Waiting to run
Contrib / dev/flags/ (push) Waiting to run
Contrib / dev/haring/ (push) Waiting to run
Contrib / dev/hpack/ (push) Waiting to run
Contrib / dev/poll/ (push) Waiting to run
VTest / Generate Build Matrix (push) Waiting to run
VTest / (push) Blocked by required conditions
Windows / Windows, gcc, all features (push) Waiting to run
When server fleets are constantly updated, using a stable distribution
across a bunch of load balancers can be convenient. The addr and port
already provide a bit of this but for situations were addresses might
differ between sites or change dynamically this does not work. The guid
is perfect for this because by definition it's supposed to designate a
single server and be unique. So when two servers anywhere have the same,
the tool that provisionned them promises that they are the same server.

So here we introduce "hash-key guid" which performs a 32-bit hash on
the GUID value. When no guid is provided, a fallback is performed on
ID, as is done for other keys.
2026-05-19 19:11:25 +02:00
Willy Tarreau
a59e6e5efd MINOR: server: support hash-key id32 for a cleaner distribution
The "id" hash-key scales the ID by a factor of 16 that tries to leave
room between the nodes on the 32-bit space to permit smooth weight
variations (e.g. during slowstart). However this does not deal well
with overlaps between server IDs. For example, assigning IDs that are
only multiples of 256 million to 16 servers yields traffic only on
one since in practice they all have the same 28 lower bits.

The new "id32" hash key bridges this gap by using the full 32-bit ID
of the server as the key. On the other hand, the user must be careful
not to switch the hash function to "none" when using incremental IDs
because in this case they might be very poorly distributed. But this
can be convenient for automated provisionning systems which assign
IDs themselves, as the full 32 bits are used now.
2026-05-19 19:11:25 +02:00
Willy Tarreau
cb5d98c495 BUG/MINOR: backend: fix balance hash calculation when using hash-type none
The "hash-type xxx none" is broken for keys that are not in type string
because the sample fetch call casts them to SMP_T_BIN, that tends to
preserve the original format (integers, IP addresses etc), but the
gen_hash() function in case of BE_LB_HFCN_NONE expects to read a string
representing a number, that it parses to retrieve the value, and just
fails on many binary types. For example, the following just always
returns key 0:

    balance hash rand()
    hash type consistent none

An ugly workaround is to make sure the expression returns a string, for
example this:

    balance hash rand(),concat()
    hash type consistent none

In order to fix most cases here, we force the conversion to type string
when using BE_LB_HFCN_NONE, but a better approach would require a larger
rework and split gen_hash() or change it to accept an integer as well,
so that the caller could cast to SMP_T_INT for BE_LB_HFCN_NONE and pass
the resulting number already parsed with the least information loss. In
this case even IPv4 addresses would be preserved.

The current approach at least addresses the initially envisioned use
cases, and the limitations have been added to the doc. This can be
backported to 3.0 though it's not really important.
2026-05-19 19:11:25 +02:00
Willy Tarreau
f2bf3483ba BUG/MINOR: server: accept server IDs above 2^31 and clarify error message
Due to the check of the stored value instead of the parsed one, it was not
permitted to use server IDs above 2^31 while they are perfectly possible.
Let's refine the parsing and also update the error message to indicate the
range. The doc was also refined to reflect the relation with hash-key.

This may be backported though it wouldn't have any effect on working
configs.
2026-05-19 19:11:25 +02:00
Christopher Faulet
18c5cd6674 BUG/MINOR: server: Properly handle init-state value during haproxy startup
Unlike stated in the configuration manual, the server 'init-state' parameter
was not evaluated during haproxy startup/reload. After a review, it appeared
there were also issues if combined with the 'track' parameter. In addtition,
this parameter was only evaluated when health-checks were enabled for the
server, leading to unexpected behavior if the serve settings are dynamically
changed via the CLI.

To fix those issues, behavior of the 'init-state' parameter was slightly
adapted. It is always evaluated, even when there is no running health-checks
for the server. An error is reported if the 'track' parameter is also
defined. Both cannot work together.

In addition, the "none" state was introduced to be able to restore the
default behavior. It will be especially useful when the parameter is
inherited from a 'default-server' directive.

This patch should fix the issue #3298. It must be backported as far as 3.2.
2026-05-19 17:50:50 +02:00
Willy Tarreau
b59fe471a5 DOC: config: further clarify that resolvers "default" exists
It was explained in the general presentation of resolvers but not in
the "resolvers" keyword description itself, which might be where users
could be looking for that info, so let's quickly repeat that info there.
2026-05-19 14:48:27 +02:00
Willy Tarreau
4519906c70 DOC: internal: add a few rules about internal core principles
The new file core-principles.txt quickly enumerates a number of rules
and invariants across the project. These can be used as quick reminders
as well as basic rules for reviews. It's still lacking a lot of info but
should be a good start.
2026-05-16 20:12:32 +02:00
Willy Tarreau
4a499938d0 [RELEASE] Released version 3.4-dev12
Some checks failed
Contrib / admin/halog/ (push) Has been cancelled
Contrib / dev/flags/ (push) Has been cancelled
Contrib / dev/haring/ (push) Has been cancelled
Contrib / dev/hpack/ (push) Has been cancelled
Contrib / dev/poll/ (push) Has been cancelled
VTest / Generate Build Matrix (push) Has been cancelled
Windows / Windows, gcc, all features (push) Has been cancelled
VTest / (push) Has been cancelled
Released version 3.4-dev12 with the following main changes :
    - SCRIPTS: announce-release: add a link to the OpenTelemetry filter
    - BUG/MEDIUM: servers: Only requeue servers if they are up
    - MINOR: tinfo: store the number of committed extra streams in the tgroup
    - MINOR: connection: add a function to calculate elastic streams limit
    - MINOR: mux-h2: consider the elastic streams limit on frontend
    - MINOR: lb: make LB initialization even more declarative
    - BUG/MINOR: cfgparse-listen: do not emit extraneous line in rule order warnings
    - CLEANUP: tree-wide: fix typos in non user-visible comments in 15 files
    - CLEANUP: h1/htx: fix a few typos in warning, debug and trace messages
    - BUG/MINOR: mux-h1: only check h1s if not NULL
    - BUG/MINOR: http-fetch: fix smp_fetch_hdr_ip()'s handling of brackets for IPv6
    - BUG/MINOR: http-fetch: make http_first_req() check for HTTP first
    - BUG/MINOR: http-act: set-status() must check the response message, not the request
    - BUG/MINOR: tools: fix memory leak in env_expand() error path
    - BUG/MINOR: auth: free user groups on error paths in userlist_postinit()
    - BUG/MINOR: uri-auth: avoid leaks on initialization error
    - BUG/MINOR: cache: fix memory leak in parse_cache_rule error path
    - BUG/MINOR: cfgcond: make KQUEUE check for GTUNE_USE_KQUEUE not GTUNE_USE_EPOLL
    - BUG/MINOR: mqtt: connack parser returns MQTT_NEED_MORE_DATA on unknown property
    - BUG/MINOR: mqtt: connect parser uses wrong bit field for TOPIC_ALIAS_MAXIMUM
    - BUG/MINOR: mqtt: connack parser uses wrong bit for SUBSCRIPTION_IDENTIFIERS_AVAILABLE
    - BUG/MINOR: mqtt: fix PUBLISH flags validation that want all bits to be set
    - CLEANUP: http_htx: rename inner 'type' to 'ptype' to avoid variable shadowing
    - CLEANUP: mux-h2: fix minor output debugging format issues
    - CLEANUP: http-rules: fix a few '&' vs '&&' checks for clarity
    - CLEANUP: auth: remove undeclared auth_resolve_groups() from auth.h
    - CLEANUP: cache: remove redundant res_htx assignment in http_cache_io_handler()
    - CLEANUP: channel: remove bogus and unused definition of channel_empty()
    - CLEANUP: flt_http_comp: remove duplicate rate limit and CPU usage checks
    - CLEANUP: mqtt: remove duplicate MQTT_FN_BIT_USER_PROPERTY in CONNECT fields
    - BUG/MINOR: uri-auth: fix possible null-deref in latest fix for leaks
    - BUG/MEDIUM: tasks: Keep the TASK_RUNNING flag until queued
    - CLEANUP: mqtt: fix spelling of shared_subscription_available
    - CLEANUP: regex: pre-initialize error variable in regex_comp() to calm analysis
    - BUILD: compiler: fix redefinition of __nonstring
    - CLEANUP: defaults: adjust MAX_THREADS multiplier number in comment
    - CLEANUP: src/cpuset.c: fix missing return in functions returning int
    - REGTESTS: Use ${tmpdir} instead of hardcoded /tmp/
    - REGTESTS: Don't try to use real nameservers for testcases
    - CLEANUP: tree-wide: fix typos in non user-visible comments in 3 more files
    - MINOR: cli: improve forward compatibility for show fd
    - DOC: management: document the <tgid>/<fd> form of show fd
    - CLEANUP: tree-wide: fix more typos and outdated explanations in comments
    - BUG/MEDIUM: dict: hold read lock while incrementing refcount in dict_insert
    - BUG/MEDIUM: http-client: Only consume input buffer when hc one is empty
    - BUG/MINOR: xprt_qstrm: fix conflicting prototype
    - REORG: mux_quic: use newer qcm prefix for legacy qmux files
    - MINOR: mux_quic: use qcm prefix for mux callbacks
    - MINOR: mux_quic: use qcm prefix for mux functions
    - MINOR: mux_quic: use qcm prefix for traces functions/structs
    - MINOR: mux_quic: rename qstrm files to qmux
    - MINOR: mux_quic: remove qstrm naming in QUIC MUX
    - MINOR: connection: rename QMux related flags
    - MINOR: xprt_qmux: use qmux instead of qstrm naming
    - MINOR: trace: implement source alias
    - MEDIUM: mux_quic: rename qmux traces to qcm
    - MINOR: sample: add a generic reverse converter
    - MINOR: sample: add a reverse_dom converter
    - DOC: proxy-protocol: clarify UDP usage
    - BUILD: 51d.c: cleanup, fix preprocessor ifdefs
    - CLEANUP: tree-wide: fix typos in user-invisible files
    - CLEANUP: htx: Adjust numbering of HTX blocks' types in the description
2026-05-13 17:22:12 +02:00
Kevin Ludwig
6e9b9196bd DOC: proxy-protocol: clarify UDP usage
the proxy protocol spec didn't specify UDP and therefore most
implementations treat it as a TCP connection and re-use the last send
information for a ip/port pair.

This change makes it more clear.
2026-05-13 16:53:58 +02:00
Manu Nicolas
f4edcdf4de MINOR: sample: add a reverse_dom converter
In domain-based routing and policy rules, suffix matching on hostnames is
often easier to express as a prefix match on reversed labels. A dedicated
converter makes this convenient with existing fetches and matchers.

This also has a performance benefit for large maps. Prefix string matches use
the prefix-tree index (PAT_MATCH_BEG with pat_idx_tree_pfx), while end matches
use the string-list index (PAT_MATCH_END with pat_idx_list_str), so
reversed-label lookups can avoid linear suffix scans.

This patch adds "reverse_dom", a string converter that reverses domain labels,
ignores one optional trailing dot on input, and rejects empty labels. It
intentionally leaves trailing-dot handling to the caller so configurations can
choose between exact matches, subdomain-only matches, or an explicit dotted
form built with "concat(.)" for prefix lookups.

Examples:
  example.com      -> com.example
  mail.example.com -> com.example.mail

The documentation is updated and a reg-test covers the converter itself, the
explicit dotted form for "map_beg()", and the subdomain-only "-m beg" case.
2026-05-13 16:49:53 +02:00
Manu Nicolas
f3fc68e3a2 MINOR: sample: add a generic reverse converter
Some use cases benefit from reversing a string before passing it to other
converters or lookups. While reverse_dom addresses domain-specific label
reversal, a generic byte-wise string reversal remains useful on its own and can
also be combined with other converters such as concat().

A common lookup use case is turning a suffix match on the original string into
a prefix match on the reversed string. Prefix string matches use the
prefix-tree index (PAT_MATCH_BEG with pat_idx_tree_pfx), while end matches use
the string-list index (PAT_MATCH_END with pat_idx_list_str), so reversing
before map_beg can avoid linear suffix scans for large maps.

This patch adds a new string converter named "reverse". It reverses the input
string byte by byte and returns the resulting string unchanged otherwise. It
does not apply any domain-specific semantics or character-encoding semantics.

The documentation is updated and a reg-test is added to cover the basic
conversion as well as a simple composition with concat(.).
2026-05-13 16:45:25 +02:00
Maxime Henrion
a9f38c19b4 DOC: management: document the <tgid>/<fd> form of show fd
Add the syntax description, including the wildcard forms and the
note that <tgid> is currently parsed but ignored pending future
support for per-thread-group fd tables.
2026-05-13 10:33:20 +02:00
Willy Tarreau
dd36c84a7b MINOR: connection: add a function to calculate elastic streams limit
This adds a new tune.streams-elasticity parameter. This parameter
indicates, as a percentage, the average number of streams per connection
at full load. It is used to calculate limits of the number of streams to
advertise on new connections. 0 means that no such limit is set.

When a limit is set, the new function conn_calc_max_streams() determines
the optimal number of streams to allow on a connection. It will assign at
least the ratio of streams left to connections left, and at least a fair
share of what's left times the number of desired streams. It will always
ensure that each connection gets at least 1 stream, and everything beyond
this will be evenly distributed. For now the function is not used.
2026-05-10 14:36:08 +02:00
Willy Tarreau
5d26fe6082 [RELEASE] Released version 3.4-dev11
Released version 3.4-dev11 with the following main changes :
    - BUG/MEDIUM: acme: fix segfault on newOrder with empty authorizations
    - BUG/MINOR: acme: skip auth/challenge steps when newOrder returns a certificate
    - BUG/MINOR: sink: do not free existing sinks on allocation error
    - CLEANUP: net_helper: fix incorrect const pointers in writev_n16()
    - BUG/MINOR: vars: make parse_store() return error on var_set() failure
    - BUG/MINOR: vars: don't store the variable twice with set-var-fmt
    - BUG/MINOR: vars: only print first invalid char in fill_desc()
    - BUG/MINOR: hpack: validate idx > 0 in hpack_valid_idx()
    - MINOR: add an MPSC ring buffer implementation
    - OPTIM: quic: rework the QUIC RX code
    - MINOR: quic: store the DCID as an offset
    - OPTIM: quic: reduce the size of struct quic_dgram
    - BUG/MINOR: quic: handle cases where we don't have an address
    - BUG/MEDIUM: cli: fix master CLI connection slot leak on client disconnect
    - MEDIUM: mux-quic: extend shut to app proto layer
    - MINOR: h3/hq_interop: implement stream reset on shut abort/kill-conn
    - BUG/MINOR: acl: fix a possible arg corruption in smp_fetch_acl_parse()
    - BUG/MINOR: map: do not leak a map descriptor on load error
    - CLEANUP: map/cli: fix some map-related help messages
    - BUG/MINOR: pattern: release the reference on failure to load from file
    - CLEANUP: acl: remove duplicate test in parse_acl_expr() and unused variable
    - CI: github: add DEBUG_STRICT=2 to ASAN jobs
    - BUG/MINOR: quic: fix buffer overflow with sockaddr_in46
    - BUG/MEDIUM: acme: fix stalled renewal when opportunistic DNS check fails
    - BUG/MINOR: quic: fix trace crash on datagram receive
    - MINOR: quic: fix trace spacing when datagram is displayed
    - CLEANUP: mux-h2: remove the outdated condition to release h2c on timeout
    - BUILD: add an EXTRA_MAKE option to build addons easily
    - BUILD: otel: removed USE_OTEL, addon is now built via EXTRA_MAKE
    - CLEANUP: otel: move opentelemetry outside haproxy sources
    - BUG/MEDIUM: mux-h2: fix the body_len to check when parsing request trailers
    - BUG/MAJOR: mux-h2: preset MSGF_BODY_CL on H2_SF_DATA_CLEN in h2c_dec_hdrs()
    - DOC: otel: update the filter's status and URL in the docs
    - DOC: acme: document missing acme-vars and provider-name keywords
    - BUG/MINOR: dns: always validate the source address in responses
    - BUG/MINOR: tcpcheck: Properly report error for http health-checks
    - CLEANUP: resolvers: Remove duplicated line when resolvers proxy is initialized
    - BUG/MINOR: resolvers: Free new requester on error when linking a resolution
    - BUG/MINOR: resolvers: Fix lookup for a hostname in the state-file tree
    - BUG/MINOR: resolvers: Free opts on parse error in resolv_parse_do_resolve()
    - BUG/MAJOR: net_helper: also fix tcp_options_list for OOB write loop
    - BUG/MEDIUM: ssl/sample: check output buffer size in aes_cbc_enc converter
    - BUG/MAJOR: http-ana: fix private session retrieval on NTLM
    - REGTESTS: add a regtest to validate various NTLM transitions
    - BUG/MEDIUM: mworker/cli: fix user and operator permission via @@<pid> in master CLI
    - BUG/MINOR: mworker/cli: check ci_insert() return value in pcli_parse_request()
    - REGTESTS: http-messaging: always send RFC8441 client settings to use ext connect
    - BUG/MINOR: h2: add decoding for :protocol in traces
    - BUG/MINOR: mux-h2: condition the processing of 8441 extension to global setting
    - MINOR: mux-h2: add a new message flag to indicate ext connect support
    - BUG/MINOR: h2: only accept :protocol with extended CONNECT
    - BUG/MINOR: acme: contact mail should be optional, don't pass ToS bool
    - CLEANUP: http-fetch: Remove duplcated return statement in smp_fetch_stver()
    - CLEANUP: http-fetch: Adjust smp_fetch_url32_src() comment
    - CLEANUP: http-fetch: Fix indentation of sample_fetch_keywords
    - BUG/MINOR: http_fetch: Check return values of unchecked buffer operations
    - BUG/MINOR: http-fetch: Fix http_auth_bearer() when custom header is used
    - BUG/MEDIUM: h1_htx: Remove reverved block on error during contig chunks parsing
    - CLEANUP: haterm: Remove duplicated bloc to know if haterm must drain
    - BUG/MINOR: haterm: Immediately report error when draining the request
    - CLEANUP: haterm: Remove useless IS_HTX_SC() test
    - BUG/MINOR: haterm: Fix a possible integer overflow on the request body length
    - BUG/MEDIUM: haterm: Subscribe for receives until request was fully drained
    - BUG/MINOR: haterm: Don't set HTX_FL_EOM flag on 100-Continue responses
    - BUG/MEDIUM: haterm: Properly handle end of request and end of response
    - BUG/MEDIUM: haterm: Properly handle client timeout
    - BUG/MINOR: haterm: Fix condition to use direct data forwarding
    - BUG/MINOR: haterm: Report a 400-bad-request error on receive error
    - DEBUG: haterm: Add hstream flags in the trace messages
    - MINOR: haterm: Remove now useless req_body field from hstream
    - MINOR: mux_quic: reset stream after app shutdown for HTTP/0.9
    - MINOR: mux_quic: do not perform unnecessary timeout handling on BE side
    - BUG/MEDIUM: mux_quic: adjust qcc_is_dead() to account detached streams
    - MINOR: mux_quic: simplify MUX_CTL_GET_NBSTRM
    - MINOR: ssl: Export 'current_crtstore_name'
    - MINOR: ssl: Factorize code from "new/set ssl cert" CLI command
    - MINOR: ssl: Factorize ckch instance rebuild process
    - MEDIUM: ssl: Refactorize "commit ssl cert"
    - BUG/MINOR: ssl: Use the sequence number with kTLS and TLS 1.2
    - BUG/MINOR: mux_quic: fix max stream ID reuse estimation
    - MINOR: mux_quic: release BE conns if reuse definitely blocked
    - BUG/MINOR: mux_quic: refresh timeout only if I/O performed
    - MEDIUM: mux-h1: Return an error on h2 upgrade attempts if not allowed
    - BUG/MEDIUM: mux-h2: Properly consume padding for DATA frames
    - MEDIUM: tools: read_line_to_trash() handle empty files without \n
    - MINOR: jws: support HMAC in jws_b64_protected(), make nonce optional
    - MINOR: jws: introduce jws_b64_hmac_signature() function for HMAC signing
    - MINOR: acme: implement EAB - external account binding
    - MINOR: acme: allow specifying custom MAC alg for EAB
    - REGTESTS: Fix h1_to_h2_upgrade.vtc to force h2 on first bind line
    - MINOR: cli: allow specifying a tgid with show fd
    - Revert "BUG/MEDIUM: cli: fix master CLI connection slot leak on client disconnect"
    - BUILD: use Makefile.mk instead of Makefile.inc in EXTRA_MAKE
    - Revert "BUG/MINOR: mux-h2: condition the processing of 8441 extension to global setting"
    - BUG/MEDIUM: mux-h2: fix the detection of the ext connect support
    - MINOR: jwe: Add option to enable/disable algorithms or encryption algorithms for jwt_decrypt
    - MINOR: jwe: Disable 'RSA1_5' algorithm by default in jwt_decrypt converters
    - BUG/MEDIUM: jwe: Fix jwt.decrypt_alg_list to work correctly
    - BUG/MEDIUM: stick-table: properly check permissions on CLI's set/clear cmd
    - DOC: acme: EAB is now supported
2026-05-08 05:22:55 +02:00
William Lallemand
815845f17e DOC: acme: EAB is now supported
Remove the line mentioning than External Account Binding is not
supported. Since it was implemented in 3.4.
2026-05-07 18:50:54 +02:00
Remi Tricot-Le Breton
495eb7b0e0 MINOR: jwe: Disable 'RSA1_5' algorithm by default in jwt_decrypt converters
In RFC8725, section 3.2, they suggest to "Avoid all RSA-PKCS1 v1.5
encryption algorithms" so this algorithm gets disabled by default.
Tokens having this "alg" won't be decrypted unless it is explicitly
reenabled thanks to 'jwt.decrypt_alg_list' global option.

Thanks to Omkhar Arasaratnam for raising our awareness about this!
2026-05-07 18:00:29 +02:00
Remi Tricot-Le Breton
f82a242c8f MINOR: jwe: Add option to enable/disable algorithms or encryption algorithms for jwt_decrypt
Some users of the jwt_decrypt_XXX converters might want to reject JWT
tokens with a specific algorithm or encryption algorithm ("alg" or "enc"
field respectively) in order to avoid weak algorithms for instance.
This could be done from the configuration but would be tedious.

This patch adds the new 'jwt.decrypt_alg_list' and
'jwt.decrypt_enc_list' global options that can be used to define a
subset of accepted algorithms
2026-05-07 18:00:27 +02:00
Mia Kanashi
5f91cf1b7d MINOR: acme: allow specifying custom MAC alg for EAB
This implements configuration for custom mac alg in EAB.
I don't think there are any reasons to allow that TBH,
but it is something that exists in the spec.

Depends on the EAB impl.
No backport needed
2026-05-07 15:19:15 +02:00
Mia Kanashi
187b1250dd MINOR: acme: implement EAB - external account binding
Patch introduces ACME EAB support.

Configuring EAB requires two parts: Key ID and MAC Key.
Key ID is an ASCII string that specifies the name of the record CA
should look up. MAC Key is a base64url encoded key that is used
for the sake of JWS signing, using HS256 or other algorithms.
They are the credentials so must be stored securely.

A thing about EAB is that it is required only during account creation
so it is unexpectedly complex to think about.
Some CAs provide EAB credential pair that is reused between
multiple account order requests, for example ZeroSSL, but others like
Google Trusted Services require an unique EAB credential for each new
account creation request.

There are a lot of ways config could be implemented, I decided to make
so that Key ID and MAC Key are stored in separate files on disk,
that decision was made because of the security concerns.
File based approach in particular works well with systemd credentials,
works well with systems that have config world readable, or immutable,
and is compatible with existing setups that specify credentials in a
file.

EAB is configured through options like this in an acme section:

eab-mac-alg HS512
eab-mac-key pebble.eab.mac-key
eab-key-id pebble.eab.key-id

I decided to not error out on empty files, but issue a log msg instead,
so that credentials can be removed without changing the haproxy config.

Used read_line_to_trash function from tools.c for reading files,
that is something that could be replaced by a dedicated function too.

No backport needed
2026-05-07 15:19:15 +02:00
William Lallemand
4153aae932 DOC: acme: document missing acme-vars and provider-name keywords
Both keywords are used with dns-01 and dns-persist-01 challenges to pass
information to an external DNS provisioning tool (e.g. the dataplaneAPI)
via the "dpapi" sink. provider-name sets the DNS provider identifier and
acme-vars passes arbitrary tool-specific variables.

Thanks to @oliwer for reporting the issue.

Must be backported to 3.2, however previous version don't have
"dns-persist-01".
2026-05-04 14:44:53 +02:00
Willy Tarreau
8ffb4b5a09 DOC: otel: update the filter's status and URL in the docs
The docs (readme and configuration.txt) still used to mention that OTEL
was under development. Now that it's released, let's indicate that it's
ready with the download URL.
2026-05-04 14:38:35 +02:00
Willy Tarreau
c6d45fec86 [RELEASE] Released version 3.4-dev10
Released version 3.4-dev10 with the following main changes :
    - DOC: config: fix spelling of "max-threads-per-group" in the index
    - MEDIUM: threads: change the default max-threads-per-group value to 16
    - BUG/MEDIUM: mux-h2: ignore conn->owner when deciding if a connection is dead
    - BUG/MINOR: task: fix uninitialised read in run_tasks_from_lists()
    - MINOR: compression: prefix compression oriented functions with "comp_"
    - BUG/MINOR: mux_quic: limit avail_streams() to 2^62
    - MINOR: h3: simplify GOAWAY local emission
    - MEDIUM: h3: prevent new streams on GOAWAY reception
    - MINOR: mux-quic: release BE idle conn after GOAWAY reception
    - MINOR: otel: added debug thread ID support for the OTel C wrapper library
    - MINOR: otel: test: added option parsing to the speed test script
    - MINOR: otel: test: replaced argument variables with positional parameters in run scripts
    - CLEANUP: otel: removed insecure-fork-wanted requirement
    - MINOR: otel: test: unified run scripts into a single symlinked script
    - BUILD: haterm: don't pass size_t to %lu in error messages
    - CI: github: merge Test and Test-musl in VTest.yml
    - CI: Build halog as part of contrib.yml
    - BUG/MINOR: xprt_qstrm: read record length in 64bits
    - BUG/MINOR: mux_quic: convert QCC rx.rlen to 64bits
    - CI: github: revert quictls version on cross-zoo.yml
    - BUG/MINOR: xprt_qstrm: reduce max record length check
    - CI: github: use quictls-3.1.7 for cross-zoo.yml
    - BUILD: ssl/sample: potential null pointer dereference in sample_conv_aes
    - CI: github: add an i686 job in cross-zoo.yml
    - CI: github: run cross-zoo.yml weekly
    - CI: github: add cross-zoo.yml in README.md
    - BUG/MEDIUM: checks: Don't forget to set the "alt_proto" field
    - CI: github: do not install pcre-devel on Fedora Rawhide build
    - CI: github: fix sysctl in fedora-rawhide
    - CI: github: switch to USE_PCRE2 in Fedora Rawhide build
    - MINOR: acme: implement draft-ietf-acme-profiles
    - MINOR: acme: allow IP SAN in certificate request
    - BUG/MINOR: log: consider format expression dependencies to decide when to log
    - MINOR: sample: make RQ/RS stats available everywhere
    - BUG/MINOR: sample: adjust dependencies for channel output bytes counters
    - MEDIUM: muxes: always set conn->owner to the session that owns the connection
    - MEDIUM: session: always reset the conn->owner on backend when installing mux
    - CLEANUP: mux-h1: avoid using conn->owner in uncertain areas
    - CLEANUP: mux-h1: remove the unneeded test on conn->owner in h1s_finish_detach()
    - BUG/MAJOR: sched: protect task->expire on 32-bit platforms
    - CI: github: add an i686 job to the push job
    - BUILD: config: also set DEF_MAX_THREADS_PER_GROUP when not using threads
    - reg-tests/ssl/ssl_dh.vtc: fix syntax error
    - ci: modernize actions/upload-artifact@v4
    - BUG/MINOR: reg-tests: make shell syntax errors fatal
    - MINOR: cli: Handle the paylod pattern as a pointer in the cmdline buffer
    - MEDIUM: cli: Make a buffer for the command payload
    - MEDIUM: cli: Add support for dynamically allocated payloads
    - MEDIUM: cli: increase the payload pattern up to 64 bytes
    - MINOR: stream: Move the HTTP txn in an union
    - MINOR: stream: Add flags to identify the stream tansaction when allocated
    - MINOR: stream: Use a pcli transaction to replace pcli_* members
    - CLEANUP: applet: Remove useless shadow pointer from appctx
    - REGTESTS: ssl: mark ssl_dh.vtc as broken
    - BUG/MINOR: mux-h2: count a protocol error when failing to parse a trailer
    - BUG/MINOR: mux-h2: count a proto error when rejecting a stream on parsing error
    - BUG/MEDIUM: tasks: Make sure we don't schedule a task already running
    - BUG/MAJOR: net_helper: ip.fp infinite loop on malformed tcp options
    - BUG/MINOR: h2: make tune.h2.log-errors actually work
    - BUG/MINOR: h2: Don't look at the exclusive bit for PRIORITY frame
    - BUG/MINOR: H2: Don't forget to free shared_rx_bufs on failure
    - BUG/MINOR: log: also wait for the response when logging response headers
    - BUG/MINOR: mux-h1: Fix condition to send null-chunk for bodyless message
    - BUG/MINOR: mux-h1: Fix test to skip trailers from chunked messages
    - BUG/MINOR: http-act: fix a typo in a "del-heeaders-bin" error message
    - CLEANUP: tcpcheck: Fix some typos in comments
    - MINOR: tcpcheck: Rely on free_tcpcheck_ruleset() to deinit tcpchecks
    - BUG/MINOR: tcpcheck: Don't release ruleset when parsing 'spop-check' ruleset
    - BUG/MINOR: tcpcheck: Fix a leak on deinit by releasing ruleset's conf.file
    - CLEANUP: haterm: Fix typos in comments
    - CLEANUP: config: Fix warning about invalid small buffer size
    - CLEANUP: htx: Fix typos in comments
    - CLEANUP: chunk: Fix a typo in a comment
    - CLEANUP: http-client: Fix typos in comments
    - BUG/MEDIUM: tcpcheck: Release temporary small chunk when retrying on http-check
    - CLEANUP: proxy: Fix typos in comments
    - DOC: config: Fix a typo for "external-check" directive
    - CLEANUP: cli: Fix typos in comments
    - BUG/MINOR: stream: Add SF_TXN_HTTP/SF_TXN_PCLI flags in strm_show_flags()
    - REGTESTS: Never reuse server connection in jwt/jws_verify.vtc
    - REGTESTS: Never reuse server connection in server/cli_delete_dynamic_server.vtc
    - BUG/MINOR: compression: properly disable request when setting response
    - BUG/MINOR: servers: fix last_sess date calculation
    - DOC: config: fix typo introduce in max-threads-per-group documentation
    - BUG/MINOR: stream: add the newly added SF_TXN_* flags to strm_show_flags()
    - BUG/MINOR: debug: properly mark the entire libs archive read-only
    - Revert "BUG/MINOR: stream: add the newly added SF_TXN_* flags to strm_show_flags()"
    - BUG/MINOR: server: fix a possible leak of an error message in dynamic servers
    - BUG/MAJOR: mux-h2: detect incomplete transfers on HEADERS frames as well
    - BUG/MEDIUM: mux-h1: Force close mode for bodyless message announcing a C-L
    - BUG/MINOR: mux_quic: prevent crash on qc_frm_free() with QMux
    - BUG/MINOR: xprt_qstrm: ensure all local TPs are allocated
    - BUG/MINOR: xprt_qstrm: prevent crash if conn release on MUX wake
    - BUG/MINOR: mux_quic: do not release conn on qcc_recv() for QMux
    - MINOR: xprt_qstrm: remove unused subs
    - MINOR: connection: document conn_create_mux()
    - MINOR: xprt_qstrm: implement close callback
    - MINOR: mux_quic: refactor QMux send frames function
    - MINOR: mux_quic: use dynamic Tx streams buffers for QMux
    - MINOR: mux_quic: use dynamic conn buffers for QMux
    - MINOR: mux_quic/xprt_qstrm: simplify Rx buffer transfer
    - MINOR: mux_quic: receive MAX_STREAMS_BIDI frames in QMux
    - MINOR: mux_quic: handle conn errors on QMux without crash
    - MINOR: mux_quic: handle incomplete QMux record read
    - BUG/MINOR: tcpcheck: Allow connection reuse without prior traffic
    - MINOR: sample: converter for frontend existence check
    - BUG/MEDIUM: stats: fix crash on 'dump stats-file'
    - BUG/MINOR: ssl: fix memory leaks on realloc failure in ssl_ckch.c
    - BUG/MINOR: ssl: fix memory leaks on realloc failure in ssl_sock.c
    - BUG/MINOR: ssl: fix memory leak on realloc failure in acme.ips
    - DOC: config: Fix log-format example with last rule expressions
    - DOC: config: Fix typo in tune.bufsize.large description
    - MEDIUM: ot: emitted deprecation warning at filter init
    - BUILD: ot: emitted deprecation warning at build time
    - BUG/MINOR: ssl: fix double-free on failed realloc in ssl_sock.c
    - BUG/MINOR: tree-wide: fix a few user-visible spelling mistakes from dev7
    - CLEANUP: tree-wide: address various spelling mistakes in comments from -dev7
    - BUG/MINOR: tools: my_memspn/my_memcspn wrong cast causing incorrect byte reading
    - BUG/MINOR: tools: fix memory leak in indent_msg() on out of memory
    - BUG/MINOR: tools: free previously allocated strings on strdup failure in backup_env()
    - BUG/MINOR: sample: fix memory leak in check_when_cond() when ACL is not found
    - BUG/MINOR: sample: fix memory leak in smp_resolve_args error paths
    - BUG/MINOR: sample: fix NULL strm dereference in sample_conv_when
    - BUG/MINOR: peers: fix logical "and" when checking for local in PEER_APP_ST_STARTING
    - BUG/MINOR: peers: fix wrong flag reported twice for dump_flags
    - CLEANUP: peers: fix a few user-visible spelling mistakes
    - CLEANUP: tools: drop upper case check after tolower()
    - CLEANUP: mux-h2: remove duplicate forward declaration of h2s_rxbuf_{head,tail}()
    - CLEANUP: tree-wide: fix around 20 mistakes in comments in h2,tools,peers
    - MINOR: mux_quic: return conn error code in debug string
    - MINOR: mux_quic: display QCS sd on traces
    - MINOR: mux_quic/h3: report termination events at connection level
    - MINOR: mux_quic/h3: report termination events at stream layer
    - BUG/MEDIUM: mux_h1: fix stack buffer overflow in h1_append_chunk_size()
    - BUG/MINOR: http_ana: use scf to report term_evts in http_wait_for_request()
    - MINOR: lb: infrastructure for declarative initialization
    - MEDIUM: lb: use the LB ops tables
    - MINOR: lb: cleanups
    - MINOR: mux_quic: remove superfluous b_size() before b_alloc()
    - BUG/MINOR: mux_quic: free frames emitted with QMux
    - BUILD: 51d: fix bool definition on dummy lib v4
    - CLEANUP: Reapply ist.cocci (4)
    - CLEANUP: Reapply strcmp.cocci (3)
    - CLEANUP: Reapply ha_free.cocci (2)
    - BUG/MAJOR: http-htx: Store new host in a chunk for scheme-based normalization
    - BUG/MEDIUM: http-htx: Don't use data from HTX message to update authority
    - BUG/MEDIUM: http-htx: Loop on full host value during scheme based normalization
    - MEDIUM: http-htx: Make authority update optional when replacing a header value
    - MEDIUM: http-htx: Make authority update optional when adding a header
    - BUG/MAJOR: http: forbid comma character in authority value
    - BUG/MEDIUM: h1: Enforce the authority validation during H1 request parsing
    - BUG/MAJOR: mux-h1: Deal with true 64-bits integer to emit chunks size
    - BUG/MEDIUM: tasks: Do not loop in task_schedule() if a task is running
    - BUG/MINOR: fix various typos and spelling mistakes in user-visible messages
    - CLEANUP: tree-wide: fix comment typos all over the tree (~68)
    - BUG/MINOR: payload: validate minimum keyshare_len in smp_fetch_ssl_keyshare_groups
    - BUG/MINOR: payload: prevent integer overflow in distcc token parsing
    - BUG/MINOR: net_helper: fix out-of-bounds read in tcp_fullhdr_find_opt
    - BUG/MINOR: net_helper: fix out-of-bounds read in sample_conv_tcp_options_list
    - BUG/MINOR: net_helper: fix incomplete decoding in sample_conv_eth_vlan
    - BUG/MEDIUM: mux-fcgi: Properly handle full buffer for FCGI_PARAM record
    - BUG/MINOR: http-htx: Don't normalize emtpy path for OPTIONS requests
2026-04-29 15:51:32 +02:00
Willy Tarreau
61e843a0b4 BUG/MINOR: tree-wide: fix a few user-visible spelling mistakes from dev7
These spelling mistakes in documentation, traces or error messages
were introduced after -dev7. Some might possibly deserve being
backported.
2026-04-27 10:49:51 +02:00
Christopher Faulet
1124968dc1 DOC: config: Fix typo in tune.bufsize.large description
"butes" was used instead of "bytes".

Should fix the issue #3322.
2026-04-27 07:35:08 +02:00