3412 Commits

Author SHA1 Message Date
Christopher Faulet
97a63835af DOC: config: Use the right alias for %B
In custom log format part, %[req.bytes_in] was erroneously documented as the
alias of %B. The good alias is %[res.bytes_in]. It is now fixed.

This patch must be backported to 3.3.
2026-03-05 15:34:47 +01:00
Christopher Faulet
b2ba3c6662 MEDIUM: http-fetch: Rework how HTTP message version is retrieved
Thanks to previous patches, we can now rely on the version stored in the
http_msg structure to get the request or the response version.

"req.ver" and "res.ver" sample fetch functions returns the string
representation of the version, without the prefix, so "<major>.<minor>", but
only if the version is valid. For the response, "res.ver" may be added from
a health-check context, in that case, the HTX message is used.

"capture.req.ver" and "capture.res.ver" does the same but the "HTTP/" prefix
is added to the result. And "capture.res.ver" cannot be called from a
health-check.

To ease the version formatting and avoid code duplication, an helper
function was added. So these samples are now relying on "get_msg_version()".
2026-03-05 15:34:46 +01:00
Amaury Denoyelle
98c8c5e16e MINOR: cli: implement wait on be-removable
Implement be-removable argument to CLI wait. This is implemented via
be_check_for_deletion() invokation, also used by "del backend" handler.

The objective is to test whether a backend instance can be removed. If
this is not the case, the command may returns immediately if the target
proxy is incompatible with dynamic removal or if a user action is
required. Else, the command will wait until the temporary restriction is
lifted.
2026-03-02 14:08:30 +01:00
Amaury Denoyelle
5ddfbd4b03 MINOR: server: mark backend removal as forbidden if QUIC was used
Currenly, quic_conn on the backend side may access their parent proxy
instance during their lifetime. In particular, this is the case for
counters update, with <prx_counters> field directly referencing a proxy
memory zone.

As such, this prevents safe backend removal. One solution would be to
check if the upper connection instance is still alive, as a proxy cannot
be removed if connection are still active. However, this would
completely prevent proxy counters update via
quic_conn_prx_cntrs_update(), as this is performed on quic_conn release.

Another solution would be to use refcount, or a dedicated counter on the
which account for QUIC connections on a backend instance. However,
refcount is currently only used by short-term references, and it could
also have a negative impact on performance.

Thus, the simplest solution for now is to disable a backend removal if a
QUIC server is/was used in it. This is considered acceptable for now as
QUIC on the backend side is experimental.
2026-03-02 14:08:30 +01:00
Amaury Denoyelle
053887cc98 MINOR: proxy: prevent backend deletion if server still exists in it
Ensure a backend instance cannot be removed if there is still server in
it. This is checked via be_check_for_deletion() to ensure "del backend"
cannot be executed. The only solution is to use "del server" to remove
on the servers instances.

This check only covers servers not yet targetted via "del server". For
deleted servers not yet purged (due to their refcount), the proxy
refcount is incremented but this does not block "del backend"
invokation.
2026-03-02 14:08:30 +01:00
Amaury Denoyelle
7f725f0754 MINOR: proxy: prevent deletion of backend referenced by config elements
Define a new proxy flag PR_FL_NON_PURGEABLE. This is used to mark every
proxy instance explicitely referenced in the config. Such instances
cannot be deleted at runtime.

Static use_backend/default_backend rules are handled in
proxy_finalize(). Also, sample expression proxy references are protected
via smp_resolve_args().

Note that this last case also incidentally protects any proxies
referenced via a CLI "set var" expression. This should not be the case
as in this case variable value is instantly resolved so the proxy
reference is not needed anymore. This also affects dynamic servers.
2026-03-02 14:08:30 +01:00
Amaury Denoyelle
7bf3020952 MINOR: proxy: prevent backend removal when unsupported
Prevent removal of a backend which relies on features not compatible
with dynamic backends. This is the case if either dispatch or
transparent option is used, or if a stick-table is declared.

These limitations are similar to the "add backend" ones.
2026-03-02 14:08:30 +01:00
Amaury Denoyelle
08623228a1 MINOR: proxy: define a basic "del backend" CLI
Add "del backend" handler which is restricted to admin level. Along with
it, a new function be_check_for_deletion() is used to test if the
backend is removable.
2026-02-27 10:28:24 +01:00
Willy Tarreau
e67e36c9eb MINOR: mux-h2: add a new setting, "tune.h2.log-errors" to tweak error logging
The H2 mux currently logs whenever some decoding fails. Most of the errors
happen at the connection level, but some are even at the stream level,
meaning that multiple logs can be emitted for a given connection, which
can quickly use some resource for little value. This new setting allows
to tweak this and decide to only log errors that affect the connection,
or even none at all.

This should be backported at least as far as 3.2.
2026-02-25 22:43:40 +01:00
Frederic Lecaille
92581043fb MINOR: haterm: add long options for QUIC and TCP "bind" settings
Add the --quic-bind-opts and --tcp-bind-opts long options to append
settings to all QUIC and TCP bind lines. This requires modifying the argv
parser to first process these new options, ensuring they are available
during the second argv pass to be added to each relevant "bind" line.
2026-02-20 12:00:34 +01:00
Frederic Lecaille
8927426f78 MINOR: haterm: provide -b and -c options (RSA key size, ECDSA curves)
Add -b and -c options to the haterm argv parser. Use -b to specify the RSA
private key size (in bits) and -c to define the ECDSA certificate curves.
These self-signed certificates are required for haterm SSL bindings.
2026-02-20 10:43:54 +01:00
Willy Tarreau
028940725a [RELEASE] Released version 3.4-dev5
Released version 3.4-dev5 with the following main changes :
    - DOC: internals: addd mworker V3 internals
    - BUG/MINOR: threads: Initialize maxthrpertgroup earlier.
    - BUG/MEDIUM: threads: Differ checking the max threads per group number
    - BUG/MINOR: startup: fix allocation error message of progname string
    - BUG/MINOR: startup: handle a possible strdup() failure
    - MINOR: cfgparse: validate defaults proxies separately
    - MINOR: cfgparse: move proxy post-init in a dedicated function
    - MINOR: proxy: refactor proxy inheritance of a defaults section
    - MINOR: proxy: refactor mode parsing
    - MINOR: backend: add function to check support for dynamic servers
    - MINOR: proxy: define "add backend" handler
    - MINOR: proxy: parse mode on dynamic backend creation
    - MINOR: proxy: parse guid on dynamic backend creation
    - MINOR: proxy: check default proxy compatibility on "add backend"
    - MEDIUM: proxy: implement dynamic backend creation
    - MINOR: proxy: assign dynamic proxy ID
    - REGTESTS: add dynamic backend creation test
    - BUG/MINOR: proxy: fix clang build error on "add backend" handler
    - BUG/MINOR: proxy: fix null dereference in "add backend" handler
    - MINOR: net_helper: extend the ip.fp output with an option presence mask
    - BUG/MINOR: proxy: fix default ALPN bind settings
    - CLEANUP: lb-chash: free lb_nodes from chash's deinit(), not global
    - BUG/MEDIUM: lb-chash: always properly initialize lb_nodes with dynamic servers
    - CLEANUP: haproxy: fix bad line wrapping in run_poll_loop()
    - MINOR: activity: support setting/clearing lock/memory watching for task profiling
    - MEDIUM: activity: apply and use new finegrained task profiling settings
    - MINOR: activity: allow to switch per-task lock/memory profiling at runtime
    - MINOR: startup: Add the SSL lib verify directory in haproxy -vv
    - BUG/MINOR: ssl: SSL_CERT_DIR environment variable doesn't affect haproxy
    - CLEANUP: initcall: adjust comments to INITCALL{0,1} macros
    - DOC: proxy-proto: underline the packed attribute for struct pp2_tlv_ssl
    - MINOR: queues: Check minconn first in srv_dynamic_maxconn()
    - MINOR: servers: Call process_srv_queue() without lock when possible
    - BUG/MINOR: quic: ensure handshake speed up is only run once per conn
    - BUG/MAJOR: quic: reject invalid token
    - BUG/MAJOR: quic: fix parsing frame type
    - MINOR: ssl: Missing '\n' in error message
    - MINOR: jwt: Convert an RSA JWK into an EVP_PKEY
    - MINOR: jwt: Add new jwt_decrypt_jwk converter
    - REGTESTS: jwt: Add new "jwt_decrypt_jwk" tests
    - MINOR: startup: Add HAVE_WORKING_TCP_MD5SIG in haproxy -vv
    - MINOR: startup: sort the feature list in haproxy -vv
    - MINOR: startup: show the list of detected features at runtime with haproxy -vv
    - SCRIPTS: build-vtest: allow to set a TMPDIR and a DESTDIR
    - MINOR: filters: rework RESUME_FILTER_* macros as inline functions
    - MINOR: filters: rework filter iteration for channel related callback functions
    - MEDIUM: filters: use per-channel filter list when relevant
    - DEV: gdb: add a utility to find the post-mortem address from a core
    - BUG/MINOR: deviceatlas: add missing return on error in config parsers
    - BUG/MINOR: deviceatlas: add NULL checks on strdup() results in config parsers
    - BUG/MEDIUM: deviceatlas: fix resource leaks on init error paths
    - BUG/MINOR: deviceatlas: fix off-by-one in da_haproxy_conv()
    - BUG/MINOR: deviceatlas: fix cookie vlen using wrong length after extraction
    - BUG/MINOR: deviceatlas: fix double-checked locking race in checkinst
    - BUG/MINOR: deviceatlas: fix resource leak on hot-reload compile failure
    - BUG/MINOR: deviceatlas: fix deinit to only finalize when initialized
    - BUG/MINOR: deviceatlas: set cache_size on hot-reloaded atlas instance
    - MINOR: deviceatlas: check getproptype return and remove pprop indirection
    - MINOR: deviceatlas: increase DA_MAX_HEADERS and header buffer sizes
    - MINOR: deviceatlas: define header_evidence_entry in dummy library header
    - MINOR: deviceatlas: precompute maxhdrlen to skip oversized headers early
    - CLEANUP: deviceatlas: add unlikely hints and minor code tidying
    - DEV: gdb: use unsigned longs to display pools memory usage
    - BUG/MINOR: ssl: lack crtlist_dup_ssl_conf() declaration
    - BUG/MINOR: ssl: double-free on error path w/ ssl-f-use parser
    - BUG/MINOR: ssl: fix leak in ssl-f-use parser upon error
    - BUG/MINOR: ssl: clarify ssl-f-use errors in post-section parsing
    - BUG/MINOR: ssl: error with ssl-f-use when no "crt"
    - MEDIUM: backend: make "balance random" consider tg local req rate when loads are equal
    - BUG/MAJOR: Revert "MEDIUM: mux-quic: add BUG_ON if sending on locally closed QCS"
    - BUG/MEDIUM: h3: reject frontend CONNECT as currently not implemented
    - MINOR: mux-quic: add BUG_ON_STRESS() when draining data on closed stream
    - REGTESTS: fix quoting in feature cmd which prevents test execution
    - BUG/MEDIUM: mux-h2/quic: Stop sending via fast-forward if stream is closed
    - BUG/MEDIUM: mux-h1: Stop sending vi fast-forward for unexpected states
    - BUG/MEDIUM: applet: Fix test on shut flags for legacy applets (v2)
    - DEV: term-events: Fix hanshake events decoding
    - BUG/MINOR: flt-trace: Properly compute length of the first DATA block
    - MINOR: flt-trace: Add an option to limit the amount of data forwarded
    - CLEANUP: compression: Remove unused static buffers
    - BUG/MEDIUM: shctx: Use the next block when data exactly filled a block
    - BUG/MINOR: http-ana: Stop to wait for body on client error/abort
    - MINOR: stconn: Add missing SC_FL_NO_FASTFWD flag in sc_show_flags
    - REORG: stconn: Move functions related to channel buffers to sc_strm.h
    - BUG/MEDIUM: jwe: fix timing side-channel and dead code in JWE decryption
    - MINOR: tree-wide: Use the buffer size instead of global setting when possible
    - MINOR: buffers: Swap buffers of same size only
    - BUG/MINOR: config: Check buffer pool creation for failures
    - MEDIUM: cache: Don't rely on a chunk to store messages payload
    - MEDIUM: stream: Limit number of synchronous send per stream wakeup
    - MEDIUM: compression: Be sure to never compress more than a chunk at once
    - MEDIUM: mux-h1/mux-h2/mux-fcgi/h3: Disable 0-copy for buffers of different size
    - MEDIUM: applet: Disable 0-copy for buffers of different size
    - MINOR: h1-htx: Disable 0-copy for buffers of different size
    - MEDIUM: stream: Offer buffers of default size only
    - BUG/MEDIUM: htx: Fix function used to change part of a block value when defrag
    - MEDIUM: htx: Refactor transfer of htx blocks to merge DATA blocks if possible
    - MEDIUM: htx: Refactor htx defragmentation to merge data blocks
    - MEDIUM: htx: Improve detection of fragmented/unordered HTX messages
    - MINOR: http-ana: Do a defrag on unaligned HTX message when waiting for payload
    - MINOR: http-fetch: Use pointer to HTX DATA block when retrieving HTX body
    - MEDIUM: dynbuf: Add a pool for large buffers with a configurable size
    - MEDIUM: chunk: Add support for large chunks
    - MEDIUM: stconn: Properly handle large buffers during a receive
    - MEDIUM: sample: Get chunks with a size dependent on input data when necessary
    - MEDIUM: http-fetch: Be able to use large chunks when necessary
    - MINPR: htx: Get large chunk if necessary to perform a defrag
    - MEDIUM: http-ana: Use a large buffer if necessary when waiting for body
    - MINOR: dynbuf: Add helpers to know if a buffer is a default or a large buffer
    - MINOR: config: reject configs using HTTP with large bufsize >= 256 MB
    - CI: do not use ghcr.io for Quic Interop workflows
    - BUG/MEDIUM: ssl: SSL backend sessions used after free
    - CI: vtest: move the vtest2 URL to vinyl-cache.org
    - CI: github: disable windows.yml by default on unofficials repo
    - MEDIUM: Add connect/queue/tarpit timeouts to set-timeout
    - CLEANUP: mux-h1: Remove unneeded null check
    - DOC: remove openssl no-deprecated CI image
    - BUG/MINOR: acme: fix X509_NAME leak when X509_set_issuer_name() fails
    - BUG/MINOR: backend: check delay MUX before conn_prepare()
    - OPTIM: backend: reduce contention when checking MUX init with ALPN
    - DOC: configuration: add the ACME wiki page link
    - MINOR: ssl/ckch: Move EVP_PKEY and cert code generation from acme
    - MINOR: ssl/ckch: certificates generation from "load" "crt-store" directive
    - MINOR: trace: add definitions for haterm streams
    - MINOR: init: allow a fileless init mode
    - MEDIUM: init: allow the redefinition of argv[] parsing function
    - MINOR: stconn: stream instantiation from proxy callback
    - MINOR: haterm: add haterm HTTP server
    - MINOR: haterm: new "haterm" utility
    - MINOR: haterm: increase thread-local pool size
    - BUG/MEDIUM: stats-file: fix shm-stats-file recover when all process slots are full
    - BUG/MINOR: stats-file: manipulate shm-stats-file heartbeat using unsigned int
    - BUG/MEDIUM: stats-file: detect and fix inconsistent shared clock when resuming from shm-stats-file
    - CI: github: only enable OS X on development branches
2026-02-19 16:26:52 +01:00
Frederic Lecaille
b007b7aa04 MINOR: haterm: new "haterm" utility
haterm_init.c is added to implement haproxy_init_args() which overloads
the one defined by haproxy.c. This way, haterm program uses its own argv[]
parsing function. It generates its own configuration in memory that is
parsed during boot and executed by the common code.
2026-02-19 15:45:01 +01:00
Frederic Lecaille
c9d47804d1 MINOR: haterm: add haterm HTTP server
Contrary to haproxy, httpterm does not support all the HTTP protocols.
Furthermore, it has become easier to handle inbound/outbound
connections / streams since the rework done at conn_stream level.

This patch implements httpterm HTTP server services into haproxy. To do
so, it proceeds the same way as for the TCP checks which use only one
stream connector, but on frontend side.

The makefile is modified to handle haterm.c in additions to all the C
files for haproxy to build new haterm program into haproxy, the haterm
server also instantiates a haterm stream (hstream struct) attached to a
stream connector for each incoming connection without backend stream
connector. This is the role of sc_new_from_endp() called by the muxes to
instantiate streams/hstreams.

As for stream_new(), hstream_new() instantiates a task named
process_hstream() (see haterm.c) which has the same role as
process_stream() but for haterm streams.

haterm into haproxy takes advantage of the HTTP muxes and HTX API to
support all the HTTP protocols supported by haproxy.
2026-02-19 15:10:37 +01:00
Frederic Lecaille
5d3bca4b17 MINOR: ssl/ckch: certificates generation from "load" "crt-store" directive
Add "generate-dummy" on/off type keyword to "load" directive to
automatically generate dummy certificates as this is done for ACME from
ckch_conf_load_pem_or_generate() function which is called if a "crt"
keyword is also provide for this directive.

Also implement "keytype" to specify the key type used for these
certificates.  Only "RSA" or "ECDSA" is accepted. This patch also
implements "bits" keyword for the "load" directive to specify the
private key size used for RSA. For ECDSA, a new "curves" keyword is also
provided by this patch to specify the curves to be used for the EDCSA
private keys generation.

ckch_conf_load_pem_or_generate() is modified to use these parameters
provided by "keytype", "bits" and "curves" to generate the private key
with ssl_gen_EVP_PKEY() before generating the X509 certificate calling
ssl_gen_x509().
2026-02-19 14:46:49 +01:00
William Lallemand
b0240bcfaf DOC: configuration: add the ACME wiki page link
Add the ACME page link to the HAProxy github wiki.
2026-02-19 13:53:50 +01:00
Nenad Merdanovic
5a079d1811 MEDIUM: Add connect/queue/tarpit timeouts to set-timeout
Add the ability to set connect, queue and tarpit timeouts from the
set-timeout action. This is especially useful when using set-dst to
dynamically connect to servers.

This patch also adds the relevant fe_/be_/cur_ sample fetches for these
timeouts.
2026-02-19 08:20:37 +01:00
Christopher Faulet
5737fc9518 MEDIUM: http-ana: Use a large buffer if necessary when waiting for body
Thanks to previous patches, it is now possible to allocate a large buffer to
store the message payload in the context of the "wait-for-body" action. To
do so, "use-large-buffer" option must be set.

It means now it is no longer necessary to increase the regular buffer size
to be able to get message payloads of some requests or responses.
2026-02-18 13:26:21 +01:00
Christopher Faulet
ce912271db MEDIUM: chunk: Add support for large chunks
Because there is now a memory pool for large buffers, we must also add the
support for large chunks. So, if large buffers are configured, a dedicated
memory pool is created to allocate large chunks. alloc_large_trash_chunk()
must be used to allocate a large chunk. alloc_trash_chunk_sz() can be used to
allocate a chunk with the best size. However free_trash_chunk() remains the
only way to release a chunk, regular or large.

In addition, large trash buffers are also created, using the same mechanism
than for regular trash buffers. So three thread-local trash buffers are
created. get_large_trash_chunk() must be used to get a large trash buffer.
And get_trash_chunk_sz() may be used to get a trash buffer with the best
size.
2026-02-18 13:26:21 +01:00
Christopher Faulet
d89ec33a34 MEDIUM: dynbuf: Add a pool for large buffers with a configurable size
Add the support for large bufers. A dedicated memory pool is added. The size
of these buffers must be explicitly configured by setting
"tune.bufsize.large" directive. If it is not set, the pool is not
created. In addition, if the size for large buffers is the same than for
regular buffer, the feature is automatically disable.

For now, large buffers remain unused.
2026-02-18 13:26:21 +01:00
Christopher Faulet
829002d459 MINOR: flt-trace: Add an option to limit the amount of data forwarded
"max-fwd <max>" option can now be used to limit the maximum amount of data
forwarded at a time by the filter. It could be handy to make tests.
2026-02-18 09:44:15 +01:00
Remi Tricot-Le Breton
aad212954f MINOR: jwt: Add new jwt_decrypt_jwk converter
This converter takes a private key in the JWK format (RFC7517) that can
be provided as a string of via a variable.
The only keys managed for now are of type 'RSA' or 'oct'.
2026-02-12 16:31:27 +01:00
Willy Tarreau
c622ed23c8 DOC: proxy-proto: underline the packed attribute for struct pp2_tlv_ssl
Oto Valek rightfully reported in issue #3262 that the proxy-protocol
doc makes no mention of the packed attribute on struct pp2_tlv_ssl,
which is mandatory since fields are not type-aligned in it. Let's
add it in the definition and make an explicit mention about it to
save implementers from wasting their time trying to debug this.

It can be backported.
2026-02-11 14:46:55 +01:00
Willy Tarreau
c724693b95 MINOR: activity: allow to switch per-task lock/memory profiling at runtime
Given that we already have "set profiling task", it's easy to permit to
enable/disable the lock and/or memory profiling at run time. However, the
change will only be applied next time the task profiling will be switched
from off/auto to on.

The patch is very minor and is best viewed with git show -b because it
indents a whole block that moves in a "if" clause.

This can be backported to 3.3 along with the two previous patches.
2026-02-10 17:53:01 +01:00
Willy Tarreau
a7b2353cb3 MINOR: activity: support setting/clearing lock/memory watching for task profiling
Damien Claisse reported in issue #3257 a performance regression between
3.2 and 3.3 when task profiling is enabled, more precisely in relation
with the following patches were merged:

  98cc815e3e ("MINOR: activity: collect time spent with a lock held for each task")
  503084643f ("MINOR: activity: collect time spent waiting on a lock for each task")
  9d8c2a888b ("MINOR: activity: collect CPU time spent on memory allocations for each task")

The issue mostly comes from the first patches. What happens is that the
local time is taken when entering and leaving each lock, which costs a
lot on a contended system. The problem here is the lack of finegrained
settings for lock and malloc profiling.

This patch introduces a better approach. The task profiler goes back to
its default behavior in on/auto modes, but the configuration now accepts
new extra options "lock", "no-lock", "memory", "no-memory" to precisely
indicate other timers to watch for each task when profiling turns on.

This is achieved by setting two new flags HA_PROF_TASKS_LOCK and
HA_PROF_TASKS_MEM in the global "profiling" variable.

This patch only parses the new values and assigns them to the global
variable from the config file for now. The doc was updated.
2026-02-10 17:47:02 +01:00
Willy Tarreau
ecffaa6d5a MINOR: net_helper: extend the ip.fp output with an option presence mask
Emeric suggested that it's sometimes convenient to instantly know if a
client has advertised support for window scaling or timestamps for
example. While the info is present in the TCP options output, it's hard
to extract since it respects the options order.

So here we're extending the 56-bit fingerprint with 8 extra bits that
indicate the presence of options 2..8, and any option above 9 for the
last bit. In practice this is sufficient since higher options are not
commonly used. Also TCP option 5 is normally not sent on the SYN (SACK,
only SACK_perm is sent), and echo options 6 & 7 are no longer used
(replaced with timestamps). These fields might be repurposed in the
future if some more meaningful options are to be mapped (e.g. MPTCP,
TFO cookie, auth).
2026-02-09 09:18:04 +01:00
Amaury Denoyelle
07195a1af4 MINOR: proxy: check default proxy compatibility on "add backend"
This commits completes "add backend" handler with some checks performed
on the specified default proxy instance. These are additional checks
outside of the already existing inheritance rules, specific to dynamic
backends.

For now, a default proxy is considered not compatible if it is not in
mode TCP/HTTP. Also, a default proxy is rejected if it references HTTP
errors. This limitation may be lifted in the future, when HTTP errors
are partiallay reworked.
2026-02-06 17:28:26 +01:00
Amaury Denoyelle
a603811aac MINOR: proxy: parse guid on dynamic backend creation
Defines an extra optional GUID argument for "add backend" command. This
can be useful as it is not possible to define it via a default proxy
instance.
2026-02-06 17:28:04 +01:00
Amaury Denoyelle
e152913327 MINOR: proxy: parse mode on dynamic backend creation
Add an optional "mode" argument to "add backend" CLI command. This
argument allows to specify if the backend is in TCP or HTTP mode.

By default, it is mandatory, unless the inherited default proxy already
explicitely specifies the mode. To differentiate if TCP mode is implicit
or explicit, a new proxy flag PR_FL_DEF_EXPLICIT_MODE is defined. It is
set for every defaults instances which explicitely defined their mode.
2026-02-06 17:27:50 +01:00
Amaury Denoyelle
7ac5088c50 MINOR: proxy: define "add backend" handler
Define a basic CLI handler for "add backend".

For now, this handler only performs a parsing of the name argument and
return an error if a duplicate already exists. It runs under thread
isolation, to guarantee thread safety during the proxy creation.

This feature is considered in development. CLI command requires to set
experimental-mode.
2026-02-06 17:26:55 +01:00
William Lallemand
9e023ae930 DOC: internals: addd mworker V3 internals
Document the mworker V3 implementation introduced in HAProxy 3.1.
Explains the rationale behind moving configuration parsing out of the
master process to improve robustness.

Could be backported to 3.1.
2026-02-04 16:39:44 +01:00
Willy Tarreau
68e9fb73fd [RELEASE] Released version 3.4-dev4
Released version 3.4-dev4 with the following main changes :
    - BUG/MEDIUM: hlua: fix invalid lua_pcall() usage in hlua_traceback()
    - BUG/MINOR: hlua: consume error object if ignored after a failing lua_pcall()
    - BUG/MINOR: promex: Detach promex from the server on error dump its metrics dump
    - BUG/MEDIUM: mux-h1: Skip UNUSED htx block when formating the start line
    - BUG/MINOR: proto_tcp: Properly report support for HAVE_TCP_MD5SIG feature
    - BUG/MINOR: config: check capture pool creations for failures
    - BUG/MINOR: stick-tables: abort startup on stk_ctr pool creation failure
    - MEDIUM: pools: better check for size rounding overflow on registration
    - DOC: reg-tests: update VTest upstream link in the starting guide
    - BUG/MINOR: ssl: Properly manage alloc failures in SSL passphrase callback
    - BUG/MINOR: ssl: Encrypted keys could not be loaded when given alongside certificate
    - MINOR: ssl: display libssl errors on private key loading
    - BUG/MAJOR: applet: Don't call I/O handler if the applet was shut
    - MINOR: ssl: allow to disable certificate compression
    - BUG/MINOR: ssl: fix error message of tune.ssl.certificate-compression
    - DOC: config: mention some possible TLS versions restrictions for kTLS
    - OPTIM: server: move queueslength in server struct
    - OPTIM: proxy: separate queues fields from served
    - OPTIM: server: get rid of the last use of _ha_barrier_full()
    - DOC: config: mention that idle connection sharing is per thread-group
    - MEDIUM: h1: strictly verify quoting in chunk extensions
    - BUG/MINOR: config/ssl: fix spelling of "expose-experimental-directives"
    - BUG/MEDIUM: ssl: fix msg callbacks on QUIC connections
    - MEDIUM: ssl: remove connection from msg callback args
    - MEDIUM: ssl: porting to X509_STORE_get1_objects() for OpenSSL 4.0
    - REGTESTS: ssl: make reg-tests compatible with OpenSSL 4.0
    - DOC: internals: cleanup few typos in master-worker documentation
    - BUG/MEDIUM: applet: Fix test on shut flags for legacy applets
    - MINOR: quic: Fix build with USE_QUIC_OPENSSL_COMPAT
    - MEDIUM: tcpcheck: add post-80 option for mysql-check to support MySQL 8.x
    - BUG/MEDIUM: threads: Atomically set TH_FL_SLEEPING and clr FL_NOTIFIED
    - BUG/MINOR: cpu-topo: count cores not cpus to distinguish core types
    - DOC: config: mention the limitation on server id range for consistent hash
    - MEDIUM: backend: make "balance random" consider req rate when loads are equal
    - BUG/MINOR: config: Fix setting of alt_proto
2026-02-04 14:59:47 +01:00
Willy Tarreau
b6bdb2553b MEDIUM: backend: make "balance random" consider req rate when loads are equal
As reported by Damien Claisse and Cdric Paillet, the "random" LB
algorithm can become particularly unfair with large numbers of servers
having few connections. It's indeed fairly common to see many servers
with zero connection in a thousand-server large farm, and in this case
the P2C algo consisting in checking the servers' loads doesn't help at
all and is basically similar to random(1). In this case, we only rely
on the distribution of server IDs in the random space to pick the best
server, but it's possible to observe huge discrepancies.

An attempt to model the problem clearly shows that with 1600 servers
with weight 10, for 1 million requests, the lowest loaded ones will
take 300 req while the most loaded ones will get 780, with most of
the values between 520 and 700.

In addition, only the first 28 lower bits of server IDs are used for
the key calculation, which means that node keys are more determinist.
Setting random keys in the lowest 28 bits only better packs values
with min around 530 and max around 710, with values mostly between
550 and 680.

This can only be compensated by increasing weights and draws without
being a perfect fix either. At 4 draws, the min is around 560 and the
max around 670, with most values bteween 590 and 650.

This patch takes another approach to this problem: when servers are on
tie regarding their loads, instead of arbitrarily taking the second one,
we now compare their current request rates, which is updated all the
time and smoothed over one second, and we pick the server with the
lowest request rate. Now with 2 draws, the curve is mostly flat, with
the min at 580 and the max at 628, and almost all values between 611
and 625. And 4 draws exclusively gives values from 614 to 624.

Other points will need to be addressed separately (bits of server ID,
maybe refine the hash algorithm), but these ones would affect how
caches are selected, and cannot be changed without an extra option.
For random however we can perform a change without impacting anyone.

This should be backported, probably only to 3.3 since it's where the
"random" algo became the default.
2026-02-04 14:54:16 +01:00
Willy Tarreau
3edf600859 DOC: config: mention the limitation on server id range for consistent hash
When using "hash-type consistent", we default to using the server's ID
as the insertion key. However, that key is scaled to avoid collisions
when inserting multiple slots for a server (16 per weight unit), and
that scaling loses the 4 topmost bits of the ID, so the only effective
range of IDs is 1..268435456, and anything above will provide the same
hashing keys again.

Let's mention this in the documentation, and also remind that it can
affect "balance random". This can be backported to all versions.
2026-02-04 14:54:16 +01:00
Hyeonggeun Oh
2527d9dcd1 MEDIUM: tcpcheck: add post-80 option for mysql-check to support MySQL 8.x
This patch adds a new 'post-80' option that sets the
CLIENT_PLUGIN_AUTH (0x00080000) capability flag
and explicitly specifies mysql_native_password as
the authentication plugin in the handshake response.

This patch also addes documentation content for post-80 option
support in MySQL 8.x version. Which handles new default auth
plugin caching_sha2_password.

MySQL 8.0 changed the default authentication plugin from
mysql_native_password to caching_sha2_password.
The current mysql-check implementation only supports pre-41
and post-41 client auth protocols, which lack the CLIENT_PLUGIN_AUTH
capability flag. When HAProxy sends a post-41 authentication
packet to a MySQL 8.x server, the server responds with error 1251:
"Client does not support authentication protocol requested by server".

The new client capabilities for post-80 are:
- CLIENT_PROTOCOL_41 (0x00000200)
- CLIENT_SECURE_CONNECTION (0x00008000)
- CLIENT_PLUGIN_AUTH (0x00080000)

Usage example:
backend mysql_servers
	option mysql-check user haproxy post-80
	server db1 192.168.1.10:3306 check

The health check user must be created with mysql_native_password:
CREATE USER 'haproxy'@'%' IDENTIFIED WITH mysql_native_password BY '';

This addresses https://github.com/haproxy/haproxy/issues/2934.
2026-02-03 07:36:53 +01:00
Egor Shestakov
02e6375017 DOC: internals: cleanup few typos in master-worker documentation
s/mecanism/mechanism
s/got ride/got rid
s/traditionnal/traditional

One typo is confusion between master and worker that results to a
semantic mistake in the sentence:

"...the master will emit an "exit-on-failure" error and will kill every
workers with a SIGTERM and exits with the same error code than the
failed [-master-]{+worker+}..."

Should be backported as far as 3.1.
2026-01-29 18:44:40 +01:00
Willy Tarreau
bb36836d76 DOC: config: mention that idle connection sharing is per thread-group
There's already a tunable "tune.idle-pool.shared" allowing to enable or
disable idle connection sharing between threads. However the doc does not
mention that these connections are only shared between threads of the same
thread group, since 2.7 with commit 15c5500b6e ("MEDIUM: conn: make
conn_backend_get always scan the same group"). Let's clarify this and
also give a hint about "max-threads-per-group" which can be helpful for
machines with unified caches.
2026-01-28 17:18:50 +01:00
Willy Tarreau
cb3fd012cd DOC: config: mention some possible TLS versions restrictions for kTLS
It took me one hour of trial and fail to figure that kTLS and splicing
were not used only for reasons of TLS version, and that switching to
TLS v1.2 solved the issue. Thus, let's mention it in the doc so that
others find it more easily in the future.

This should be backported to 3.3.
2026-01-28 10:45:21 +01:00
William Lallemand
6995fe60c3 MINOR: ssl: allow to disable certificate compression
This option allows to disable the certificate compression (RFC 8879)
using OpenSSL >= 3.2.0.

This feature is known to permit some denial of services by causing extra
memory allocations of approximately 22MiB and extra CPU work per
connection with OpenSSL versions affected by CVE-2025-66199.
( https://openssl-library.org/news/vulnerabilities/index.html#CVE-2025-66199 )

Setting this to "off" permits to mitigate the problem.

Must be backported to every stable branches.
2026-01-27 16:10:41 +01:00
Egor Shestakov
f4cd1e74ba DOC: reg-tests: update VTest upstream link in the starting guide
The starting guide to regression testing had an outdated VTest link.

Could be backported as far as 2.6.
2026-01-26 13:56:13 +01:00
Willy Tarreau
2eda6e1cbe [RELEASE] Released version 3.4-dev3
Released version 3.4-dev3 with the following main changes :
    - BUILD: ssl: strchr definition changed in C23
    - BUILD: tools: memchr definition changed in C23
    - BUG/MINOR: cfgparse: wrong section name upon error
    - MINOR: cfgparse: Refactor "userlist" parser to print it in -dKall operation
    - BUILD: sockpair: fix build issue on macOS related to variable-length arrays
    - BUG/MINOR: cli/stick-tables: argument to "show table" is optional
    - REGTESTS: ssl: Fix reg-tests curve check
    - CI: github: remove ERR=1 temporarly from the ECH job
    - BUG/MINOR: ech/quic: enable ech configuration also for quic listeners
    - MEDIUM: config: warn if some userlist hashes are too slow
    - MINOR: cfgparse: remove duplicate "force-persist" in common kw list
    - MINOR: sample: also support retrieving fc.timer.handshake without a stream
    - MINOR: tcp-sample: permit retrieving tcp_info from the connection/session stage
    - CLEANUP: connection: Remove outdated note about CO_FL `0x00002000` being unused
    - MINOR: receiver: Dynamically alloc the "members" field of shard_info
    - MINOR: stats: Increase the tgid from 8bits to 16bits
    - BUG/MINOR: stats-file: Use a 16bits variable when loading tgid
    - BUG/MINOR: hlua_fcn: fix broken yield for Patref:add_bulk()
    - BUG/MINOR: hlua_fcn: ensure Patref:add_bulk() is given a table object before using it
    - BUG/MINOR: net_helper: fix IPv6 header length processing
    - MEDIUM: counters: Dynamically allocate per-thread group counters
    - MEDIUM: counters: Remove some extra tests
    - BUG/MEDIUM: threads: Fix binding thread on bind.
    - BUG/MEDIUM: quic: fix ACK ECN frame parsing
    - MEDIUM: counters: mostly revert da813ae4d7cb77137ed
    - BUG/MINOR: http_act: fix deinit performed on uninitialized lf_expr in release_http_map()
    - MINOR: queues: Turn non_empty_tgids into a long array.
    - MINOR: threads: Eliminate all_tgroups_mask.
    - BUG/MEDIUM: queues: Fix arithmetic when feeling non_empty_tgids
    - MEDIUM: thread: Turn the group mask in thread set into a group counter
    - BUG/MINOR: proxy: free persist_rules
    - MEDIUM: stream: refactor switching-rules processing
    - REGTESTS: add test on backend switching rules selection
    - MEDIUM: proxy: do not select a backend if disabled
    - MEDIUM: proxy: implement publish/unpublish backend CLI
    - MINOR: stats: report BE unpublished status
    - MINOR: cfgparse: adapt warnif_cond_conflicts() error output
    - MEDIUM: proxy: force traffic on unpublished/disabled backends
    - MINOR: ssl: Factorize AES GCM data processing
    - MINOR: ssl: Add new aes_cbc_enc/_dec converters
    - REGTESTS: ssl: Add tests for new aes cbc converters
    - MINOR: jwe: Add new jwt_decrypt_secret converter
    - MINOR: jwe: Add new jwt_decrypt_cert converter
    - REGTESTS: jwe: Add jwt_decrypt_secret and jwt_decrypt_cert tests
    - DOC: jwe: Add doc for jwt_decrypt converters
    - MINOR: jwe: Some algorithms not supported by AWS-LC
    - REGTESTS: jwe: Fix tests of algorithms not supported by AWS-LC
    - BUG/MINOR: cfgparse: fix "default" prefix parsing
    - REORG/MINOR: cfgparse: eliminate code duplication by lshift_args()
    - MEDIUM: systemd: implement directory loading
    - CI: github: switch monthly Fedora Rawhide build to OpenSSL
    - SCRIPTS: build-ssl: use QUICTLS_VERSION instead of QUICTLS=yes
    - CI: github: define the right quictls version in each jobs
    - CI: github: fix vtest.yml with "not quictls"
    - MINOR: cli: use srv_drop() when server was created using new_server()
    - BUG/MINOR: server: ensure server is detached from proxy list before being freed
    - BUG/MEDIUM: promex: server iteration may rely on stale server
    - SCRIPTS: build-ssl: clone the quictls branch directly
    - SCRIPTS: build-ssl: fix quictls build for 1.1.1 versions
    - BUG/MEDIUM: log: parsing log-forward options may result in segfault
    - DOC: proxy-protocol: Add SSL client certificate TLV
    - DOC: fix typos in the documentation files
    - DOC: fix mismatched quotes typos around words in the documentation files
    - REORG: cfgparse: move peers parsing to cfgparse-peers.c
    - MINOR: tools: add chunk_escape_string() helper function
    - MINOR: vars: store variable names for runtime access
    - MINOR: vars: implement dump_all_vars() sample fetch
    - DOC: vars: document dump_all_vars() sample fetch
    - BUG/MEDIUM: ssl: fix error path on generate-certificates
    - BUG/MEDIUM: ssl: fix generate-certificates option when SNI greater than 64bytes
    - BUG/MEDIUM: mux-quic: prevent BUG_ON() on aborted uni stream close
    - REGTESTS: ssl: fix generate-certificates w/ LibreSSL
    - SCRIPTS: build: enable symbols in AWS-LC builds
    - BUG/MINOR: proxy: fix deinit crash on defaults with duplicate name
    - BUG/MEDIUM: debug: only dump Lua state when panicking
    - MINOR: proxy: remove proxy_preset_defaults()
    - MINOR: proxy: refactor defaults proxies API
    - MINOR: proxy: simplify defaults proxies list storage
    - MEDIUM: cfgparse: do not store unnamed defaults in name tree
    - MEDIUM: proxy: implement persistent named defaults
2026-01-22 19:02:54 +01:00
Amaury Denoyelle
b52c60d366 MEDIUM: proxy: implement persistent named defaults
This patch changes the handling of named defaults sections. Prior to
this patch, every unreferenced defaults proxies were removed on post
parsing. Now by default, these sections are kept after postparsing and
only purged on deinit. The objective is to allow reusing them as base
configuration for dynamic backends.

To implement this, refcount of every still addressable named sections is
incremented by one after parsing. This ensures that they won't be
removed even if referencing proxies are removed at runtime. This is done
via the new function proxy_ref_all_defaults().

To ensure defaults instances are still properly removed on deinit, the
inverse operation is performed : refcount is decremented by one on every
defaults sections via proxy_unref_all_defaults().

The original behavior can still be used by using the new global keyword
tune.defaults.purge. This is useful for users using configuration with
large number of defaults and not interested in dynamic backends
creation.
2026-01-22 18:06:42 +01:00
Hyeonggeun Oh
2d8d2b4247 DOC: vars: document dump_all_vars() sample fetch
Add documentation for the dump_all_vars() sample fetch function in the
configuration manual. This function was introduced in the previous commit
to dump all variables in a given scope with optional prefix filtering.

The documentation includes:
- Function signature and return type
- Description of output format
- Explanation of scope and prefix arguments
- Usage examples for common scenarios

This completes the implementation of GitHub issue #1623.
2026-01-21 10:44:19 +01:00
Egor Shestakov
44c491ae6b DOC: fix mismatched quotes typos around words in the documentation files
s/"no'/"no"
s/'private"/"private"
s/"flt'/"flt"

There isn't definite convention but people usually prefer to highlight
something important with quotation marks. For example, it's convenient
to find keywords from a text when they are quoted, mismatches make this
harder.

No backport needed.
2026-01-20 08:15:41 +01:00
Egor Shestakov
0c3b212aab DOC: fix typos in the documentation files
This fixes several obvious typos in the documentation:

s/elvoved/evolved
s/performend/performed
s/importnat/important
s/sharedd/shared
s/eveyone/everyone

No backport needed.
2026-01-20 08:15:28 +01:00
Simon Ser
6f5def3cbd DOC: proxy-protocol: Add SSL client certificate TLV
Add the PP2_SUBTYPE_SSL_CLIENT_CERT code point reservation in the
proxy protocol specification. This is useful in cases where the
backend needs to perform mTLS authentication, but the rules for
certificate validation are backend-specific (e.g. database of
allowed certificate hashes).

This is left optional to leave it up to the frontend configuration
to dictate whether to forward raw certificate data.

Support for this new TLV has been added in tlstunnel:
https://codeberg.org/emersion/tlstunnel/pulls/33
2026-01-20 08:11:19 +01:00
Remi Tricot-Le Breton
aba18bac71 MINOR: jwe: Some algorithms not supported by AWS-LC
AWS-LC does not have EVP_aes_128_wrap or EVP_aes_192_wrap so the A128KW
and A192KW algorithms will not be supported for JWE token decryption.
2026-01-15 10:56:28 +01:00
Remi Tricot-Le Breton
39da1845fc DOC: jwe: Add doc for jwt_decrypt converters
Add doc for jwt_decrypt_secret and jwt_decrypt_cert converters.
2026-01-15 10:56:28 +01:00
Remi Tricot-Le Breton
c431034037 MINOR: ssl: Add new aes_cbc_enc/_dec converters
Those converters allow to encrypt or decrypt data with AES in Cipher
Block Chaining mode. They work the same way as the already existing
aes_gcm_enc/_dec ones apart from the AEAD tag notion which is not
supported in CBC mode.
2026-01-15 10:56:27 +01:00
Amaury Denoyelle
6870551a57 MEDIUM: proxy: force traffic on unpublished/disabled backends
A recent patch has introduced a new state for proxies : unpublished
backends. Such backends won't be eligilible for traffic, thus
use_backend/default_backend rules which target them won't match and
content switching rules processing will continue.

This patch defines a new frontend keywords 'force-be-switch'. This
keyword allows to ignore unpublished or disabled state. Thus,
use_backend/default_backend will match even if the target backend is
unpublished or disabled. This is useful to be able to test a backend
instance before exposing it outside.

This new keyword is converted into a persist rule of new type
PERSIST_TYPE_BE_SWITCH, stored in persist_rules list proxy member. This
is the only persist rule applicable to frontend side. Prior to this
commit, pure frontend proxies persist_rules list were always empty.

This new features requires adjustment in process_switching_rules(). Now,
when a use_backend/default_backend rule matches with an non eligible
backend, frontend persist_rules are inspected to detect if a
force-be-switch is present so that the backend may be selected.
2026-01-15 09:08:19 +01:00