Commit graph

3476 commits

Author SHA1 Message Date
Pierre Cheynier
85c3f3c1fd MINOR: sample: converter for frontend existence check
Introduced a new sample converter using keyword "fe_exists" checking if
a frontend with a given name exists.
2026-04-24 15:22:09 +02:00
Willy Tarreau
81e3f013a9 DOC: config: fix typo introduce in max-threads-per-group documentation
Since commit 0af603f46f ("MEDIUM: threads: change the default
max-threads-per-group value to 16"), it was written "Tha minimum" instead
of "The minimum". No backport needed, this is only in latest -dev.
2026-04-23 11:55:45 +02:00
Christopher Faulet
deba2ffaeb DOC: config: Fix a typo for "external-check" directive
Fix duplicated "to the" in the "external-check" directive description.
2026-04-23 10:49:28 +02:00
Christopher Faulet
594753238c MINOR: stream: Move the HTTP txn in an union
The HTTP transaction is moved in an union. For now, it is the only possible
transaction that can be allocated. But that will change. Thanks to this
commit and the next one, it will be possible to deal with different kind of
transactions for a stream.

This patch looks quite huge, but it is more or less a renaming of all
accesses to "txn" field by "txn.http".
2026-04-22 15:19:12 +02:00
Christopher Faulet
80776da297 MEDIUM: cli: increase the payload pattern up to 64 bytes
The maximum size allowed for the payload pattern was increase up to 64 bytes
(65 bytes because of the trailing \0), to be able to use a sha256 of random
data for instance. It could be useful to prevent any data smuggling on the
payload.

Note that on the CLI, it could be possible to have only the buffer size as a
limit, because the command line is only consumed once all commands are
executed. The payload pattern is only a pointer in the buffer where the
command line was copied. However, for the master CLI, the data are streamed
to the worker, so we must keep a copy of he payload pattern. This is why we
must limit its size.
2026-04-22 15:19:12 +02:00
Christopher Faulet
9b1f0a3553 MEDIUM: cli: Add support for dynamically allocated payloads
It is now possible to deal with too big payload to fit in a buffer, without
changing the buffer size. By default, a payload up to 128 KB can be
dynamically allocated. "tune.cli.max-payload-size" global parameter can be
used to change this value, with some caution for huge values.

For CLI command handler functions, there is no change at all. A pointer on
the payload is still passed as parameter. Internally, an area is allocated
for the payload only if it is too big.

The payload pattern used to detect the end of the payload is part from the
allocated area.
2026-04-22 15:19:12 +02:00
William Lallemand
95c400d08e MINOR: acme: allow IP SAN in certificate request
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
Implement IP in both requestOrder and CSR so a certificate with SAN IPs
can be generated.
2026-04-20 18:10:47 +02:00
William Lallemand
0d14bb7473 MINOR: acme: implement draft-ietf-acme-profiles
The ACME Profiles extension (draft-ietf-acme-profiles) allows a client
to request a specific certificate profile by including a "profile" field
in the newOrder request. This lets the CA select the appropriate
certificate issuance policy (e.g. "classic", "shortlived") for a given
order.

A new "profile" keyword is added to the acme section. When set, its
value is included in the newOrder JSON payload sent to the CA.
2026-04-20 18:10:35 +02:00
Willy Tarreau
0af603f46f MEDIUM: threads: change the default max-threads-per-group value to 16
A lot of our subsystems start to be shared by thread groups now
(listeners, queues, stick-tables, stats, idle connections, LB algos).
This has allowed to recover the performance that used to be out of
reach on losely shared platforms (typically AMD EPYC systems), but in
parallel other large unified systems (Xeon and large Arm in general)
still suffer from the remaining contention when placing too many
threads in a group.

A first test running on a 64-core Neoverse-N1 processor with a single
backend with one server and no LB algo specifiied shows 1.58 Mrps with
64 threads per group, and 1.71 Mrps with 16 threads per group. The
difference is essentially spent updating stats counters everywhere.

Another test is the connection:close mode, delivering 85 kcps with
64 threads per group, and 172 kcps (202%) with 16 threads per group.
In this case it's mostly the more numerous listeners which improve
the situation as the change is mostly in the kernel:

max-threads-per-group 64:
  # perf top
  Samples: 244K of event 'cycles', 4000 Hz, Event count (approx.): 61065854708 los
  Overhead  Shared Object     Symbol
    10.41%  [kernel]          [k] queued_spin_lock_slowpath
    10.36%  [kernel]          [k] _raw_spin_unlock_irqrestore
     2.54%  [kernel]          [k] _raw_spin_lock
     2.24%  [kernel]          [k] handle_softirqs
     1.49%  haproxy           [.] process_stream
     1.22%  [kernel]          [k] _raw_spin_lock_bh

  # h1load
  time conns tot_conn  tot_req      tot_bytes    err  cps  rps  bps   ttfb
     1  1024    84560    83536        4761666      0 84k5 83k5 38M0 11.91m
     2  1024   168736   167713        9559698      0 84k0 84k0 38M3 11.98m
     3  1024   253865   252841       14412165      0 85k0 85k0 38M7 11.84m
     4  1024   339143   338119       19272783      0 85k1 85k1 38M8 11.80m
     5  1024   424204   423180       24121374      0 84k9 84k9 38M7 11.86m

max-threads-per-group 16:
  # perf top
  Samples: 1M of event 'cycles', 4000 Hz, Event count (approx.): 375998622679 lost
  Overhead  Shared Object     Symbol
    15.20%  [kernel]          [k] queued_spin_lock_slowpath
     4.31%  [kernel]          [k] _raw_spin_unlock_irqrestore
     3.33%  [kernel]          [k] handle_softirqs
     2.54%  [kernel]          [k] _raw_spin_lock
     1.46%  haproxy           [.] process_stream
     1.12%  [kernel]          [k] _raw_spin_lock_bh

  # h1load
      time conns tot_conn  tot_req      tot_bytes    err  cps  rps  bps   ttfb
         1  1020   172230   171211        9759255      0 172k 171k 78M0 5.817m
         2  1024   343482   342460       19520277      0 171k 171k 78M0 5.875m
         3  1021   515947   514926       29350953      0 172k 172k 78M5 5.841m
         4  1024   689972   688949       39270207      0 173k 173k 79M2 5.783m
         5  1024   863904   862881       49184274      0 173k 173k 79M2 5.795m

So let's change the default value to 16. It also happens to match what's
used by default on EPYC systems these days.

This change was marked MEDIUM as it will increase the number of listening
sockets on some systems, to match their counter parts from other vendors,
which is easier for capacity planning.
2026-04-16 10:48:43 +02:00
Willy Tarreau
42c5cd8e5c DOC: config: fix spelling of "max-threads-per-group" in the index
It was spelled "max-thread-per-group" (without 's'). No backport is
needed unless commit 7e22d9c484 ("MEDIUM: cpu-topo: Add a new
"max-threads-per-group" global keyword") and its possible successors
are backported.
2026-04-16 10:35:31 +02:00
Willy Tarreau
1cdb6bf3f8 [RELEASE] Released version 3.4-dev9
Some checks failed
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
VTest / Alpine+musl, gcc (push) Has been cancelled
Windows / Windows, gcc, all features (push) Has been cancelled
VTest / (push) Has been cancelled
Released version 3.4-dev9 with the following main changes :
    - DOC: config: fix ambiguous info in log-steps directive description
    - MINOR: filters: add filter name to flt_conf struct
    - MEDIUM: filters: add "filter-sequence" directive
    - REGTESTS: add a test for "filter-sequence" directive
    - Revert "CLEANUP: tcpcheck: Don't needlessly expose proxy_parse_tcpcheck()"
    - MINOR: tcpcheck: reintroduce proxy_parse_tcpcheck() symbol
    - BUG/MEDIUM: haterm: Move all init functions of haterm in haterm_init.c
    - BUG/MEDIUM: mux-h1: Disable 0-copy forwarding when draining the request
    - MINOR: servers: The right parameter for idle-pool.shared is "full"
    - DOC: config: Fix two typos in the server param "healthcheck" description
    - BUG/MINOR: http-act: fix a typo in the "pause" action error message
    - MINOR: tcpcheck: Reject unknown keyword during parsing of healthcheck section
    - BUG/MEDIUM: tcpcheck/server: Fix parsing of healthcheck param for dynamic servers
    - BUG/MINOR: counters: fix unexpected 127 char GUID truncation for shm-stats-file objects
    - BUG/MEDIUM: tcpcheck: Properly retrieve tcpcheck type to install the best mux
    - BUG/MEDIUM: payload: validate SNI name_len in req.ssl_sni
    - BUG/MEDIUM: jwe: fix NULL deref crash with empty CEK and non-dir alg
    - BUG/MEDIUM: jwt: fix heap overflow in ECDSA signature DER conversion
    - BUG/MEDIUM: jwe: fix memory leak in jwt_decrypt_secret with var argument
    - BUG: hlua: fix stack overflow in httpclient headers conversion
    - BUG/MINOR: hlua: fix stack overflow in httpclient headers conversion
    - BUG/MINOR: hlua: fix format-string vulnerability in Patref error path
    - BUG/MEDIUM: chunk: fix typo allocating small trash with bufsize_large
    - BUG/MEDIUM: chunk: fix infinite loop in get_larger_trash_chunk()
    - BUG/MINOR: peers: fix OOB heap write in dictionary cache update
    - CI: VTest build with git clone + cache
    - BUG/MEDIUM: connection: Wake the stconn on error when failing to create mux
    - CI: github: update to cache@v5
    - Revert "BUG: hlua: fix stack overflow in httpclient headers conversion"
    - CI: github: fix vtest path to allow correct caching
    - CI: github: add the architecture to the cache key for vtest2
    - MEDIUM: connections: Really enforce mux protocol requirements
    - MINOR: tools: Implement net_addr_type_is_quic()
    - MEDIUM: check: Revamp the way the protocol and xprt are determined
    - BUG/MAJOR: slz: always make sure to limit fixed output to less than worst case literals
    - MINOR: lua: add tune.lua.openlibs to restrict loaded Lua standard libraries
    - REGTESTS: lua: add tune.lua.openlibs to all Lua reg-tests
    - BUG/MINOR: resolvers: fix memory leak on AAAA additional records
    - BUG/MINOR: spoe: fix pointer arithmetic overflow in spoe_decode_buffer()
    - BUG/MINOR: http-act: validate decoded lengths in *-headers-bin
    - BUG/MINOR: haterm: Return the good start-line for 100-continue interim message
    - BUG/MEDIUM: samples: Fix handling of SMP_T_METH samples
    - BUG/MINOR: sample: fix info leak in regsub when exp_replace fails
    - BUG/MEDIUM: mux-fcgi: prevent record-length truncation with large bufsize
    - BUG/MINOR: hlua: fix use-after-free of HTTP reason string
    - BUG/MINOR: mux-quic: fix potential NULL deref on qcc_release()
    - BUG/MINOR: quic: increment pos pointer on QMux transport params parsing
    - MINOR: xprt_qstrm: implement Rx buffering
    - MINOR: xprt_qstrm/mux-quic: handle extra QMux frames after params
    - MINOR: xprt_qstrm: implement Tx buffering
    - MINOR: xprt_qstrm: handle connection errors
    - MEDIUM: mux-quic: implement QMux record parsing
    - MEDIUM: xprt_qstrm: implement QMux record parsing
    - MEDIUM: mux-quic/xprt_qstrm: implement QMux record emission
    - DOC: update draft link for QMux protocol
    - BUG/MINOR: do not crash on QMux reception of BLOCKED frames
    - Revert "BUG/MEDIUM: haterm: Move all init functions of haterm in haterm_init.c"
    - BUG/MEDIUM: haterm: Properly initialize the splicing support for haterm
    - BUG/MINOR: mux_quic: prevent QMux crash on qcc_io_send() error path
    - BUG/MINOR: xprt_qstrm: do not parse record length on read again
    - MEDIUM: otel: added OpenTelemetry filter skeleton
    - MEDIUM: otel: added configuration and utility layer
    - MEDIUM: otel: added configuration parser and event model
    - MEDIUM: otel: added post-parse configuration check
    - MEDIUM: otel: added memory pool and runtime scope layer
    - MEDIUM: otel: implemented filter callbacks and event dispatcher
    - MEDIUM: otel: wired OTel C wrapper library integration
    - MEDIUM: otel: implemented scope execution and span management
    - MEDIUM: otel: added context propagation via carrier interfaces
    - MEDIUM: otel: added HTTP header operations for context propagation
    - MEDIUM: otel: added HAProxy variable storage for context propagation
    - MINOR: otel: added prefix-based variable scanning
    - MEDIUM: otel: added CLI commands for runtime filter management
    - MEDIUM: otel: added group action for rule-based scope execution
    - MINOR: otel: added log-format support to the sample parser and runtime
    - MINOR: otel: test: added test and benchmark suite for the OTel filter
    - MINOR: otel: added span link support
    - MINOR: otel: added metrics instrument support
    - MINOR: otel: added log-record signal support
    - MINOR: otel: test: added full-event test config
    - DOC: otel: added documentation
    - DOC: otel: test: added test README-* files
    - DOC: otel: test: added speed test guide and benchmark results
    - DOC: otel: added cross-cutting design patterns document
    - MINOR: otel: added flt_otel_sample_eval and exposed flt_otel_sample_add_kv
    - MINOR: otel: changed log-record attr to use sample expressions
    - MINOR: otel: changed instrument attr to use sample expressions
    - DOC: otel: added README.md overview document
    - CLEANUP: ot: use the item API for the variables trees
    - BUG/MINOR: ot: removed dead code in flt_ot_parse_cfg_str()
    - BUG/MINOR: ot: fixed wrong NULL check in flt_ot_parse_cfg_group()
    - BUILD: ot: removed explicit include path when building opentracing filter
    - MINOR: ot: renamed the variable dbg_indent_level to flt_ot_dbg_indent_level
    - CI: Drop obsolete `packages: write` permission from `quic-interop-*.yml`
    - CI: Consistently add a top-level `permissions` definition to GHA workflows
    - CI: Wrap all `if:` conditions in `${{ }}`
    - CI: Fix regular expression escaping in matrix.py
    - CI: Update to actions/checkout@v6
    - CI: Simplify version extraction with `haproxy -vq`
    - CI: Merge `aws-lc.yml` and `aws-lc-fips.yml` into `aws-lc.yml`
    - CI: Merge `aws-lc-template.yml` into `aws-lc.yml`
    - CI: Consistently set up VTest with `./.github/actions/setup-vtest`
    - MINOR: mux_quic: remove duplicate QMux local transport params
    - CI: github: add bash to the musl job
    - BUG/MINOR: quic: do not use hardcoded values in QMux TP frame builder
    - BUG/MINOR: log: Fix error message when using unavailable fetch in logfmt
    - CLEANUP: log: Return `size_t` from `sess_build_logline_orig()`
    - CLEANUP: stream: Explain the two-step initialization in `stream_generate_unique_id()`
    - CLEANUP: stream: Reduce duplication in `stream_generate_unique_id()`
    - CLEANUP: http_fetch: Use local `unique_id` variable in `smp_fetch_uniqueid()`
    - CI: build WolfSSL job with asan enabled
    - MINOR: tools: memvprintf(): remove <out> check that always true
    - BUG/MEDIUM: cli: Properly handle too big payload on a command line
    - REGTESTS: Never reuse server connection in reg-tests/jwt/jwt_decrypt.vtc
    - MINOR: errors: remove excessive errmsg checks
    - BUG/MINOR: haterm: preserve the pipe size margin for splicing
    - MEDIUM: acme: implement dns-persist-01 challenge
    - MINOR: acme: extend resolver-based DNS pre-check to dns-persist-01
    - DOC: configuration: document dns-persist-01 challenge type and options
    - BUG/MINOR: acme: read the wildcard flag from the authorization response
    - BUG/MINOR: acme: don't pass NULL into format string
    - BUG/MINOR: haterm: don't apply the default pipe size margin twice
    - CLEANUP: Make `lf_expr` parameter of `sess_build_logline_orig()` const
    - MINOR: Add `generate_unique_id()` helper
    - MINOR: Allow inlining of `stream_generate_unique_id()`
    - CLEANUP: log: Stop touching `struct stream` internals for `%ID`
    - MINOR: check: Support generating a `unique_id` for checks
    - MINOR: http_fetch: Add support for checks to `unique-id` fetch
    - MINOR: acme: display the type of challenge in ACME_INITIAL_DELAY
    - MINOR: mjson: reintroduce mjson_next()
    - CI: Remove obsolete steps from musl.yml
    - CI: Use `sh` in `actions/setup-vtest/action.yml`
    - CI: Sync musl.yml with vtest.yml
    - CI: Integrate Musl build into vtest.yml
    - CI: Use `case()` function
    - CI: Generate vtest.yml matrix on `ubuntu-slim`
    - CI: Run contrib.yml on `ubuntu-slim`
    - CI: Use `matrix:` in contrib.yml
    - CI: Build `dev/haring/` as part of contrib.yml
    - MINOR: htx: Add helper function to get type and size from the block info field
    - BUG/MEDIUM: htx: Properly handle block modification during defragmentation
    - BUG/MEDIUM: htx: Don't count delta twice when block value is replaced
    - MINOR: ssl: add TLS 1.2 values in HAPROXY_KEYLOG_XX_LOG_FMT
    - EXAMPLES: ssl: keylog entries are greater than 1024
    - BUILD: Makefile: don't forget to also delete haterm on make clean
    - MINOR: stats: report the number of thread groups in "show info"
    - CLEANUP: sample: fix the comment regarding the range of the thread sample fetch
    - MINOR: sample: return the number of the current thread group
    - MINOR: sample: add new sample fetch functions reporting current CPU usage
    - BUG/MEDIUM: peers: trash of expired entries delayed after fullresync
    - DOC: remove the alpine/musl status job image
    - MINOR: mux-quic: improve documentation for qcs_attach_sc()
    - MINOR: mux-quic: reorganize code for app init/shutdown
    - MINOR: mux-quic: perform app init in case of early shutdown
    - MEDIUM: quic: implement fe.stream.max-total
    - MINOR: mux-quic: close connection when reaching max-total streams
    - REGTESTS: add QUIC test for max-total streams setting
    - MEDIUM: threads: start threads by groups
    - MINOR: acme: opportunistic DNS check for dns-persist-01 to skip challenge-ready steps
    - BUG/MINOR: acme: fix fallback state after failed initial DNS check
    - CLEANUP: acme: no need to reset ctx state and http_state before nextreq
    - BUG/MINOR: threads: properly set the number of tgroups when non using policy
2026-04-15 17:59:00 +02:00
William Lallemand
c295a5c861 MINOR: acme: opportunistic DNS check for dns-persist-01 to skip challenge-ready steps
For dns-persist-01, the "_validation-persist.<domain>" TXT record is set once
and never changes between renewals. Add an initial opportunistic DNS check
(ACME_INITIAL_RSLV_TRIGGER / ACME_INITIAL_RSLV_READY states) that runs before
the challenge-ready conditions are evaluated. If all domains already have the
TXT record, the challenge is submitted immediately without going through the
cli/delay/dns challenge-ready steps, making renewals faster once the record is
in place.

The new ACME_RDY_INITIAL_DNS flag is automatically set for
dns-persist-01 in cond_ready.
2026-04-15 15:57:57 +02:00
Amaury Denoyelle
e2dbcd20f2 MINOR: mux-quic: close connection when reaching max-total streams
This commit completes the previous one which implements a new setting to
limit the number of streams usable by a client on a QUIC connection.

When the connection becomes idle after reaching this limit, it is
immediately closed. This is implemented by extending checks in
qcc_is_dead(). This results in a CONNECTION_CLOSE emission, which is
useful to free resources as soon as possible.
2026-04-15 15:18:37 +02:00
Amaury Denoyelle
497cabd9e5 MEDIUM: quic: implement fe.stream.max-total
Implement a new setting to limit the total number of bidirectional
streams that the client may use on a single connection. By default, it
is set to 0 which means it is not limited at all.

If a positive value is configured, the client can only open a fixed
number of request streams per QUIC connection. Internally, this is
implemented in two steps :

* First, MAX_STREAMS_BIDI flow control advertizing will be reduced when
  approaching the limit before being completely turned off when reaching
  it. This guarantees that the client cannot exceed the limit without
  violating the flow control.

* Second, when attaching the latest stream with ID matching max-total
  setting, connection graceful shutdown is initiated. In HTTP/3, this
  results in a GOAWAY emission. This allows the remaining streams to be
  completed before the connection becomes completely idle.
2026-04-15 15:18:37 +02:00
Willy Tarreau
90e8ccd9c2 MINOR: sample: add new sample fetch functions reporting current CPU usage
Some checks are pending
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
VTest / Alpine+musl, gcc (push) Waiting to run
Windows / Windows, gcc, all features (push) Waiting to run
Some features can automatically turn on or off depending on CPU usage,
but it's not easy to measure it. Let's provide 3 new sample fetch functions
reporting the CPU usage as measured inside haproxy during the previous
polling loop, and reported in "idle" stats header / "show info", or used
by tune.glitches.kill.cpu-usage, or maxcompcpuusage:

  - cpu_usage_thr: CPU usage between 0 and 100 of the current thread, used
    by functions above
  - cpu_usage_grp: CPU usage between 0 and 100, averaged over all threads of
    the same group as the current one.
  - cpu_usage_proc: CPU usage between 0 and 100, averaged over all threads
    of the current process

Note that the value will fluctuate since it only covers a few tens to
hundreds of requests of the last polling loop, but it reports what is
being used to take decisions.

It could also be used to disable some non-essential debugging/processing
under too high loads for example.
2026-04-14 17:47:18 +02:00
Willy Tarreau
630ef96f92 MINOR: sample: return the number of the current thread group
Just like we have a sample fetch function that returns the number of the
current thread, let's have the same with the thread group number. This
can be useful for troubleshooting, given that certain things are currently
per thread-group (e.g. idle backend connections, certain LB algos etc).
2026-04-14 17:05:34 +02:00
Tim Duesterhus
ed0c51d2c0 MINOR: http_fetch: Add support for checks to unique-id fetch
Some checks are pending
Contrib / build (push) Waiting to run
alpine/musl / gcc (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
This allows to use the `unique-id` fetch within `tcp-check` or `http-check`
ruleset. The format is taken from the checked server's backend (which is
naturally inherited from the corresponding `defaults` section).

This is particularly useful with

    http-check send ... hdr request-id %[unique-id]

to ensure all requests sent by HAProxy have a unique ID header attached.

This resolves GitHub Issue #3307.

Reviewed-by: Volker Dusch <github@wallbash.com>
2026-04-13 20:02:21 +02:00
William Lallemand
a5e732ed1d DOC: configuration: document dns-persist-01 challenge type and options
Document the dns-persist-01 challenge type under the challenge keyword,
the challenge-ready dns option (existence-only TXT check for dns-persist-01),
and the default challenge-ready value when challenge is dns-persist-01.
2026-04-13 18:45:08 +02:00
Amaury Denoyelle
ec552b0cc2 DOC: update draft link for QMux protocol
QMux draft 01 support is mostly achieved thanks to the recent
implementation of the Record layer. This patch thus updates the link in
the documentation to the validated draft version.
2026-04-10 10:20:52 +02:00
William Lallemand
591a85e29e MINOR: lua: add tune.lua.openlibs to restrict loaded Lua standard libraries
HAProxy has always called luaL_openlibs() unconditionally, which opens
all standard Lua libraries including io, os, package and debug. This
makes it impossible to prevent Lua scripts from executing binaries
(os.execute, io.popen), loading native C modules (package/require), or
bypassing any Lua-level sandbox via the debug library.

Add a new global directive tune.lua.openlibs that accepts a comma-separated
list of library names to load:

  tune.lua.openlibs none                   # only base + coroutine
  tune.lua.openlibs string,math,table,utf8 # safe libs only
  tune.lua.openlibs all                    # default, same as before

The base and coroutine libraries are always loaded regardless: base provides
core Lua functions that HAProxy relies on, and coroutine is required because
HAProxy overrides coroutine.create() with its own safe implementation.

When all libraries are enabled (the default), the fast path still calls
luaL_openlibs() directly with no overhead. A parse error is returned if
the directive appears after lua-load or lua-load-per-thread (the Lua state
is already initialised at that point), or if 'none' is combined with other
library names. Note that fork() and new thread creation are already blocked
by default regardless of this setting (see "insecure-fork-wanted").
2026-04-09 14:31:10 +02:00
Christopher Faulet
063dfd9ff3 DOC: config: Fix two typos in the server param "healthcheck" description
There was 2 typos here. First, the 'k' was missing on the parameter name.
Then "sectino" was used in the description instead of "section". Let's fix
them.
2026-04-03 15:56:57 +02:00
Olivier Houchard
2147e8e368 MINOR: servers: The right parameter for idle-pool.shared is "full"
In documentation, and in an error message, provide the right new keyword for
"idle-pool.shared", it is "full", not "auto".
2026-04-03 15:45:26 +02:00
Aurelien DARRAGON
8d28c0e37b MEDIUM: filters: add "filter-sequence" directive
This is another pre-requisite work for upcoming decompression filter.

In this patch we implement the "filter-sequence" directive which can be
used in proxy section (frontend,backend,listen) and takes 2 parameters

The first one is the direction (request or response), the second one
is a comma separated list of filter names previously declared on the
proxy using the "filter" keyword.

The main goal of this directive is to be able to instruct haproxy in which
order the filters should be executed on request and response paths,
especially if the ordering between request and response handling must
differ, and without relying on the filter declaration ordering (within
the proxy) which is used by default by haproxy.

Another benefit of this feature is that it becomes possible to "ignore"
a previously declared filter on the proxy. Indeed, when filter-sequence
is defined for a given direction (request/response), then it will be used
over the implicit filter ordering, but if a filter which was previously
declared is not specified in the related filter-sequence, it will not be
executed on purpose. This can be used as a way to temporarily disable a
filter without completely removing its configuration.

Documentation was updated (check examples for more info)
2026-04-03 12:10:27 +02:00
Aurelien DARRAGON
882176a602 DOC: config: fix ambiguous info in log-steps directive description
log-steps takes <steps> as parameter. <steps> is made of individual
log origins separated by commas, as shown in the examples, but the
directive's description says it should be separated by spaces, which
is wrong.

Let's fix that

It should be backported up to 3.2
2026-04-03 12:10:14 +02:00
Willy Tarreau
f2e362ab22 [RELEASE] Released version 3.4-dev8
Some checks failed
Contrib / build (push) Has been cancelled
alpine/musl / gcc (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-dev8 with the following main changes :
    - MINOR: log: split do_log() in do_log() + do_log_ctx()
    - MINOR: log: provide a way to override logger->profile from process_send_log_ctx
    - MINOR: log: support optional 'profile <log_profile_name>' argument to do-log action
    - BUG/MINOR: sock: adjust accept() error messages for ENFILE and ENOMEM
    - BUG/MINOR: qpack: fix 62-bit overflow and 1-byte OOB reads in decoding
    - MEDIUM: sched: do not run a same task multiple times in series
    - MINOR: sched: do not requeue a tasklet into the current queue
    - MINOR: sched: do not punish self-waking tasklets anymore
    - MEDIUM: sched: do not punish self-waking tasklets if TASK_WOKEN_ANY
    - MEDIUM: sched: change scheduler budgets to lower TL_BULK
    - MINOR: mux-h2: assign a limited frames processing budget
    - BUILD: sched: fix leftover of debugging test in single-run changes
    - BUG/MEDIUM: acme: fix multiple resource leaks in acme_x509_req()
    - MINOR: http_htx: use enum for arbitrary values in conf_errors
    - MINOR: http_htx: rename fields in struct conf_errors
    - MINOR: http_htx: split check/init of http_errors
    - MINOR/OPTIM: http_htx: lookup once http_errors section on check/init
    - MEDIUM: proxy: remove http-errors limitation for dynamic backends
    - BUG/MINOR: acme: leak of ext_san upon insertion error
    - BUG/MINOR: acme: wrong error when checking for duplicate section
    - BUG/MINOR: acme/cli: wrong argument check in 'acme renew'
    - BUG/MINOR: http_htx: fix null deref in http-errors config check
    - MINOR: buffers: Move small buffers management from quic to dynbuf part
    - MINOR: dynbuf: Add helper functions to alloc large and small buffers
    - MINOR: quic: Use b_alloc_small() to allocate a small buffer
    - MINOR: config: Relax tests on the configured size of small buffers
    - MINOR: config: Report the warning when invalid large buffer size is set
    - MEDIUM: htx: Add htx_xfer function to replace htx_xfer_blks
    - MINOR: htx: Add helper functions to xfer a message to smaller or larger one
    - MINOR: http-ana: Use HTX API to move to a large buffer
    - MEDIUM: chunk: Add support for small chunks
    - MEDIUM: stream: Try to use a small buffer for HTTP request on queuing
    - MEDIUM: stream: Try to use small buffer when TCP stream is queued
    - MEDIUM: stconn: Use a small buffer if possible for L7 retries
    - MEDIUM: tree-wide: Rely on htx_xfer() instead of htx_xfer_blks()
    - Revert "BUG/MEDIUM: mux-h2: make sure to always report pending errors to the stream"
    - MEDIUM: mux-h2: Stop dealing with HTX flags transfer in h2_rcv_buf()
    - MEDIUM: tcpcheck: Use small buffer if possible for healthchecks
    - MINOR: proxy: Review options flags used to configure healthchecks
    - DOC: config: Fix alphabetical ordering of proxy options
    - DOC: config: Fix alphabetical ordering of external-check directives
    - MINOR: proxy: Add use-small-buffers option to set where to use small buffers
    - DOC: config: Add missing 'status-code' param for 'http-check expect' directive
    - DOC: config: Reorder params for 'tcp-check expect' directive
    - BUG/MINOR: acme: NULL check on my_strndup()
    - BUG/MINOR: acme: free() DER buffer on a2base64url error path
    - BUG/MINOR: acme: replace atol with len-bounded __strl2uic() for retry-after
    - BUG/MINOR: acme/cli: fix argument check and error in 'acme challenge_ready'
    - BUILD: tools: potential null pointer dereference in dl_collect_libs_cb
    - BUG/MINOR: ech: permission checks on the CLI
    - BUG/MINOR: acme: permission checks on the CLI
    - BUG/MEDIUM: check: Don't reuse the server xprt if we should not
    - MINOR: checks: Store the protocol to be used in struct check
    - MINOR: protocols: Add a new proto_is_quic() function
    - MEDIUM: connections: Enforce mux protocol requirements
    - MEDIUM: server: remove a useless memset() in srv_update_check_addr_port.
    - BUG/MINOR: config: Warn only if warnif_cond_conflicts report a conflict
    - BUG/MINOR: config: Properly test warnif_misplaced_* return values
    - BUG/MINOR: http-ana: Only consider client abort for abortonclose
    - BUG/MEDIUM: acme: skip doing challenge if it is already valid
    - MINOR: connections: Enhance tune.idle-pool.shared
    - BUG/MINOR: acme: fix task allocation leaked upon error
    - BUG/MEDIUM: htx: Fix htx_xfer() to consume more data than expected
    - CI: github: fix tag listing by implementing proper API pagination
    - CLEANUP: fix typos and spelling in comments and documentation
    - BUG/MINOR: quic: close conn on packet reception with incompatible frame
    - CLEANUP: stconn: Remove usless sc_new_from_haterm() declaration
    - BUG/MINOR: stconn: Always declare the SC created from healthchecks as a back SC
    - MINOR: stconn: flag the stream endpoint descriptor when the app has started
    - MINOR: mux-h2: report glitches on early RST_STREAM
    - BUG/MINOR: net_helper: fix length controls on ip.fp tcp options parsing
    - BUILD: net_helper: fix unterminated comment that broke the build
    - MINOR: resolvers: basic TXT record implementation
    - MINOR: acme: store the TXT record in auth->token
    - MEDIUM: acme: add dns-01 DNS propagation pre-check
    - MEDIUM: acme: new 'challenge-ready' option
    - DOC: configuration: document challenge-ready and dns-delay options for ACME
    - SCRIPTS: git-show-backports: list new commits and how to review them with -L
    - BUG/MEDIUM: ssl/cli: tls-keys commands warn when accessed without admin level
    - BUG/MEDIUM: ssl/ocsp: ocsp commands warn when accessed without admin level
    - BUG/MEDIUM: map/cli: map/acl commands warn when accessed without admin level
    - BUG/MEDIUM: ssl/cli: tls-keys commands are missing permission checks
    - BUG/MEDIUM: ssl/ocsp: ocsp commands are missing permission checks
    - BUG/MEDIUM: map/cli: CLI commands lack admin permission checks
    - DOC: configuration: mention QUIC server support
    - MEDIUM: Add set-headers-bin, add-headers-bin and del-headers-bin actions
    - BUG/MEDIUM: mux-h1: Don't set MSG_MORE on bodyless responses forwarded to client
    - BUG/MINOR: http_act: Properly handle decoding errors in *-headers-bin actions
    - MEDIUM: stats: Hide the version by default and add stats-showversion
    - MINOR: backends: Don't update last_sess if it did not change
    - MINOR: servers: Don't update last_sess if it did not change
    - MINOR: ssl/log: add keylog format variables and env vars
    - DOC: configuration: update tune.ssl.keylog URL to IETF draft
    - BUG/MINOR: http_act: Make set/add-headers-bin compatible with ACL conditions
    - MINOR: action: Add a sample expression field in arguments used by HTTP actions
    - MEDIUM: http_act: Rework *-headers-bin actions
    - BUG/MINOR: tcpcheck: Remove unexpected flag on tcpcheck rules for httchck option
    - MEDIUM: tcpcheck: Refactor how tcp-check rulesets are stored
    - MINOR: tcpcheck: Deal with disable-on-404 and send-state in the tcp-check itself
    - BUG/MINOR: tcpcheck: Don't enable http_needed when parsing HTTP samples
    - MINOR: tcpcheck: Use tcpcheck flags to know a healthcheck uses SSL connections
    - BUG/MINOR: tcpcheck: Use tcpcheck context for expressions parsing
    - CLEANUP: tcpcheck: Don't needlessly expose proxy_parse_tcpcheck()
    - MINOR: tcpcheck: Add a function to stringify the healthcheck type
    - MEDIUM: tcpcheck: Split parsing functions to prepare healthcheck sections parsing
    - MEDIUM: tcpcheck:  Add parsing support for healthcheck sections
    - MINOR: tcpcheck: Extract tcpheck ruleset post-config in a dedicated function
    - MEDIUM: tcpcheck/server: Add healthcheck server keyword
    - REGTESTS: tcpcheck: Add a script to check healthcheck section
    - MINOR: acme: add 'dns-timeout' keyword for dns-01 challenge
    - CLEANUP: net_helper: fix typo in comment
    - MINOR: acme: set the default dns-delay to 30s
    - MINOR: connection: add function to identify a QUIC connection
    - MINOR: quic: refactor frame parsing
    - MINOR: quic: refactor frame encoding
    - BUG/MINOR: quic: fix documentation for transport params decoding
    - MINOR: quic: split transport params decoding/check
    - MINOR: quic: remove useless quic_tp_dec_err type
    - MINOR: quic: define QMux transport parameters frame type
    - MINOR: quic: implement QMux transport params frame parser/builder
    - MINOR: mux-quic: move qcs stream member into tx inner struct
    - MINOR: mux-quic: prepare Tx support for QMux
    - MINOR: mux-quic: convert init/closure for QMux compatibility
    - MINOR: mux-quic: protect qcc_io_process for QMux
    - MINOR: mux-quic: prepare traces support for QMux
    - MINOR: quic: abstract stream type in qf_stream frame
    - MEDIUM: mux-quic: implement QMux receive
    - MINOR: mux-quic: handle flow-control frame on qstream read
    - MINOR: mux-quic: define Rx connection buffer for QMux
    - MINOR: mux_quic: implement qstrm rx buffer realign
    - MEDIUM: mux-quic: implement QMux send
    - MINOR: mux-quic: implement qstream send callback
    - MINOR: mux-quic: define Tx connection buffer for QMux
    - MINOR: xprt_qstrm: define new xprt module for QMux protocol
    - MINOR: xprt_qstrm: define callback for ALPN retrieval
    - MINOR: xprt_qstrm: implement reception of transport parameters
    - MINOR: xprt_qstrm: implement sending of transport parameters
    - MEDIUM: ssl: load xprt_qstrm after handshake completion
    - MINOR: mux-quic: use QMux transport parameters from qstrm xprt
    - MAJOR: mux-quic: activate QMux for frontend side
    - MAJOR: mux-quic: activate QMux on the backend side
    - MINOR: acme: split the CLI wait from the resolve wait
    - MEDIUM: acme: initialize the dns timer starting from the first DNS request
    - DEBUG: connection/flags: add QSTRM flags for the decoder
    - BUG/MINOR: mux_quic: fix uninit for QMux emission
    - MINOR: acme: remove remaining CLI wait in ACME_RSLV_TRIGGER
    - MEDIUM: acme: split the initial delay from the retry DNS delay
    - BUG/MINOR: cfgcond: properly set the error pointer on evaluation error
    - BUG/MINOR: cfgcond: always set the error string on openssl_version checks
    - BUG/MINOR: cfgcond: always set the error string on awslc_api checks
    - BUG/MINOR: cfgcond: fail cleanly on missing argument for "feature"
    - MINOR: ssl: add the ssl_fc_crtname sample fetch
    - MINOR: hasterm: Change hstream_add_data() to prepare zero-copy data forwarding
    - MEDIUM: haterm: Add support for 0-copy data forwading and option to disable it
    - MEDIUM: haterm: Prepare support for splicing by initializing a master pipe
    - MEDIUM: haterm: Add support for splicing and option to disable it
    - MINOR: haterm: Handle boolean request options as flags
    - MINOR: haterm: Add an request option to disable splicing
    - BUG/MINOR: ssl: fix memory leak in ssl_fc_crtname by using SSL_CTX ex_data index
2026-04-03 11:46:05 +02:00
William Lallemand
d89ae36adc MINOR: ssl: add the ssl_fc_crtname sample fetch
This new sample fetch returns the name of the certificate selected for
an incoming SSL/TLS connection, as it would appear in "show ssl cert".
It may be a filename with its relative or absolute path, or an alias,
depending on how the certificate was declared in the configuration.

The certificate name is stored as ex_data on the SSL_CTX at load time
in ckch_inst_new_load_store(), and freed via a dedicated free callback.
2026-04-03 10:41:00 +02:00
William Lallemand
6df3662077 MEDIUM: acme: split the initial delay from the retry DNS delay
Some checks are pending
Contrib / build (push) Waiting to run
alpine/musl / gcc (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
The previous ACME_RSLV_WAIT state served a dual role: it applied the
initial dns-delay before the first DNS probe and also handled the
delay between retries. There was no way to simply wait a fixed delay
before submitting the challenge without also triggering DNS pre-checks.

Replace ACME_RSLV_WAIT with two distinct states:
  - ACME_INITIAL_DELAY: an optional initial wait before proceeding,
    only applied when "challenge-ready" includes the new "delay" keyword
  - ACME_RSLV_RETRY_DELAY: the delay between resolution retries, always
    applied when DNS pre-checks are in progress

The new "delay" keyword in "challenge-ready" can be used standalone
(wait then submit the challenge directly) or combined with "dns" (wait
then start the DNS pre-checks). When "delay" is not set, the first DNS
probe fires immediately.

Update the documentation accordingly.
2026-04-02 18:29:26 +02:00
William Lallemand
253bf8cbae MEDIUM: acme: initialize the dns timer starting from the first DNS request
Previously the dns timeout timer was initialized in ACME_RSLV_WAIT,
before the initial dns-delay expires. This meant the countdown started
before any DNS request was actually sent, so the effective timeout was
shorter than expected by one dns-delay period.

Move the initialization to ACME_RSLV_TRIGGER so the timer starts only
when the first DNS resolution attempt is triggered. Update the
documentation to clarify this behaviour.
2026-04-02 15:54:02 +02:00
Amaury Denoyelle
2457701299 MAJOR: mux-quic: activate QMux on the backend side
Some checks failed
Contrib / build (push) Has been cancelled
alpine/musl / gcc (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
During connect_server(), xprt_qstrm is selected to performed transport
parameters exchange prior to the mux layer initialization.
2026-04-02 14:02:05 +02:00
Amaury Denoyelle
490b465fd1 MAJOR: mux-quic: activate QMux for frontend side
To be able to support QMux protocol, xprt_qstrm is activated by the
session for transport parameters exchange, prior to the mux layer
initialization.
2026-04-02 14:02:05 +02:00
William Lallemand
7c3fe4d0c0 MINOR: acme: set the default dns-delay to 30s
Set the default dns-delay to 30s so it can be more efficient with fast
DNS providers. The dns-timeout is set to 600s by default so this does
not have a big impact, it will only do more check and allow the
challenge to be started more quickly.
2026-04-02 13:47:13 +02:00
William Lallemand
7f6999b764 MINOR: acme: add 'dns-timeout' keyword for dns-01 challenge
Some checks are pending
Contrib / build (push) Waiting to run
alpine/musl / gcc (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 using the dns-01 challenge method with "challenge-ready dns", HAProxy
retries DNS resolution indefinitely at the interval set by "dns-delay". This
adds a "dns-timeout" keyword to set a maximum duration for the DNS check phase
(default: 600s). If the next resolution attempt would be scheduled beyond that
deadline, the renewal is aborted with an explicit error message.

A new "dnsstarttime" field is stored in the acme_ctx to record when DNS
resolution began, used to evaluate the timeout on each retry.
2026-04-01 18:56:13 +02:00
Christopher Faulet
6fbccae1ab MEDIUM: tcpcheck/server: Add healthcheck server keyword
Thanks to this patch, it is now possible to specify an healthcheck section
on the server line. In that case, the server will use the tcpcheck as
defined in the correspoding healthcheck section instead of the proxy's one.
2026-04-01 16:34:38 +02:00
Christopher Faulet
8c00df7448 MEDIUM: http_act: Rework *-headers-bin actions
These actions were added recently and it appeared the way binary headers
were retrieved could be simplified.

First, there is no reason to retrieve a base64 encoded string. It is
possible to rely on the binary string directly. "b64dec" converter can be
used to perform a base64 decoding if necessary.

Then, using a log-format string is quite overkill and probably
conterintuitive. Most of time, the headers will be retrieved from a
variable. So a sample expression is easier to use. Thanks to the previous
patch, it is quite easy to achieve.

This patch relies on the commit "MINOR: action: Add a sample expression
field in arguments used by HTTP actions". The documentation was updated
accordingly.
2026-04-01 16:34:37 +02:00
William Lallemand
6a862009be DOC: configuration: update tune.ssl.keylog URL to IETF draft
Replace the Mozilla NSS key log format link with the IETF draft:
https://tlswg.org/sslkeylogfile/draft-ietf-tls-keylogfile.html
2026-04-01 16:28:49 +02:00
William Lallemand
c8bfd06b57 MINOR: ssl/log: add keylog format variables and env vars
Add keylog_format_fc and keylog_format_bc global variables containing
the SSLKEYLOGFILE log-format strings for the frontend (client-facing)
and backend (server-facing) TLS connections respectively. These produce
output compatible with the SSLKEYLOGFILE format described at:
https://tlswg.org/sslkeylogfile/draft-ietf-tls-keylogfile.html

Both formats are also exported as environment variables at startup:
  HAPROXY_KEYLOG_FC_LOG_FMT
  HAPROXY_KEYLOG_BC_LOG_FMT

These variables contains \n so they might not be compatible with syslog
servers, using them with stderr or a sink might be required.

These can be referenced directly in "log-format" directives to produce
SSLKEYLOGFILE-compatible output, usable by network analyzers such as
Wireshark to decrypt captured TLS traffic.
2026-04-01 16:28:49 +02:00
Olivier Houchard
397530b1e9 MEDIUM: stats: Hide the version by default and add stats-showversion
Reverse the default, to hide the version from stats by default, and add
a new keyword, "stats show-version", to enable them, as we don't want to
disclose the version by default, especially on public websites.
2026-04-01 14:39:28 +02:00
Nenad Merdanovic
daf378d2b4 MEDIUM: Add set-headers-bin, add-headers-bin and del-headers-bin actions
These actions allow setting, adding and deleting multiple headers from
the same action, without having to know the header names during parsing.
This is useful when doing things with SPOE.
2026-03-31 19:56:28 +02:00
Amaury Denoyelle
b134065ea8 DOC: configuration: mention QUIC server support
Adds 'quic4@' / 'quic6@' as prefixes available for server addresses.
This is explicitely listed as experimental for now.

This must be backported up to 3.3.
2026-03-31 17:50:20 +02:00
William Lallemand
ad87ab1f2e DOC: configuration: document challenge-ready and dns-delay options for ACME
Some checks are pending
Contrib / build (push) Waiting to run
alpine/musl / gcc (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
Add documentation for two new directives in the acme section:

- challenge-ready: configures the conditions that must be satisfied
  before notifying the ACME server that a dns-01 challenge is ready.
  Accepted values are cli, dns and none. cli waits for an operator
  to signal readiness via the "acme challenge_ready" CLI command. dns
  performs a DNS pre-check against the "default" resolvers section,
  not the authoritative name servers. When both are combined, HAProxy
  waits for the CLI confirmation before triggering the DNS check.

- dns-delay: configures the delay before the first DNS resolution
  attempt and between retries when challenge-ready includes dns.
  Default is 300 seconds.
2026-03-30 18:24:28 +02:00
Ilia Shipitsin
b7d1c2f91d CLEANUP: fix typos and spelling in comments and documentation
Corrected multiple spelling mistakes across CLI scripts, documentation,
and source comments (e.g. "Specifiy" → "Specify", "explicitely" → "explicitly",
"transfert" → "transfer", "resetted" → "reset", etc.). These changes
improve readability and consistency without altering functionality.
2026-03-30 09:24:19 +02:00
Olivier Houchard
506cfcb5d4 MINOR: connections: Enhance tune.idle-pool.shared
There are two settings to control idle connection sharing across
threads.
tune.idle-pool.shared, that enables or disables it, and then
tune.takeover-other-tg-connections, which lets you or not get idle
connections from other thread groups.
Add a new keyword for tune.idle-pool.shared, "full", that lets you get
connections from other thread groups (equivalent to "full" keyword for
tune.takeover-other-tg-connections). The "on" keyword now will be
equivalent to the "restrict" one, which allowed getting connection from
other thread groups only when not doing it would result in a connection
failure (when reverse-http or when strict-macxonn are used).
tune.takeover-other-tg-connections will be deprecated.
2026-03-27 16:14:53 +01:00
Christopher Faulet
38a7d8599d DOC: config: Reorder params for 'tcp-check expect' directive
Order of parameters for the 'tcp-check expect' directive is changed to be
the same than 'http-check expect'.
2026-03-23 14:02:43 +01:00
Christopher Faulet
82afd36b6c DOC: config: Add missing 'status-code' param for 'http-check expect' directive
In the documentation of 'http-check expect' directive, the parameter
'status-code' was missing. Let's add it.

This patch could be backported to all stable versions.
2026-03-23 14:02:43 +01:00
Christopher Faulet
ada33006ef MINOR: proxy: Add use-small-buffers option to set where to use small buffers
Thanks to previous commits, it is possible to use small buffers at different
places: to store the request when a connection is queued or when L7 retries
are enabled, or for health-checks requests. However, there was no
configuration parameter to fine tune small buffer use.

It is now possible, thanks to the proxy option "use-small-buffers".
Documentation was updated accordingly.
2026-03-23 14:02:43 +01:00
Christopher Faulet
163eba5c8c DOC: config: Fix alphabetical ordering of external-check directives
external-check directives were not at the right place. Let's fix it.
2026-03-23 14:02:43 +01:00
Christopher Faulet
61d68f14b2 DOC: config: Fix alphabetical ordering of proxy options
external-check and idle-close-on-response options were not at the right
place. Let's fix it.
2026-03-23 14:02:43 +01:00
Christopher Faulet
5ead611cc2 MEDIUM: htx: Add htx_xfer function to replace htx_xfer_blks
htx_xfer() function should replace htx_xfer_blks(). It will be a bit easier to
maintain and to use. The behavior of htx_xfer() can be changed by calling it
with specific flags:

  * HTX_XFER_KEEP_SRC_BLKS: Blocks from the source message are just copied
  * HTX_XFER_PARTIAL_HDRS_COPY: It is allowed to partially xfer headers or trailers
  * HTX_XFER_HDRS_ONLY: only headers are xferred

By default (HTX_XFER_DEFAULT or 0), all blocks from the source message are moved
into to the destination mesage. So copied in the destination messageand removed
from the source message.

The caller must still define the maximum amount of data (including meta-data)
that can be xferred.

It is no longer necessary to specify a block type to stop the copy. Most of
time, with htx_xfer_blks(), this parameter was set to HTX_BLK_UNUSED. And
otherwise it was only specified to transfer headers.

It is important to not that the caller is responsible to verify the original
HTX message is well-formated. Especially, it must be sure headers part and
trailers part are complete (finished by EOH/EOT block).

For now, htx_xfer_blks() is not removed for compatiblity reason. But it is
deprecated.
2026-03-23 14:02:42 +01:00
Amaury Denoyelle
c6fc53aa99 MEDIUM: proxy: remove http-errors limitation for dynamic backends
Use proxy_check_http_errors() on defaults proxy instances. This will
emit alert messages for errorfiles directives referencing a non-existing
http-errors section, or a warning if an explicitely listed status code
is not present in the target section.

This is a small behavior changes, as previouly this was only performed
for regular proxies. Thus, errorfile/errorfiles directives in an unused
defaults were never checked.

This may prevent startup of haproxy with a configuration file previously
considered as valid. However, this change is considered as necessary to
be able to use http-errors with dynamic backends. Any invalid defaults
will be detected on startup, rather than having to discover it at
runtime via "add backend" invokation.

Thus, any restriction on http-errors usage is now lifted for the
creation of dynamic backends.
2026-03-23 11:14:07 +01:00
Willy Tarreau
5d0f5f8168 MINOR: mux-h2: assign a limited frames processing budget
This introduces 3 new settings: tune.h2.be.max-frames-at-once and
tune.h2.fe.max-frames-at-once, which limit the number of frames that
will be processed at once for backend and frontend side respectively,
and tune.h2.fe.max-rst-at-once which limits the number of RST_STREAM
frames processed at once on the frontend.

We can now yield when reading too many frames at once, which allows to
limit the latency caused by processing too many frames in large buffers.
However if we stop due to the RST budget being depleted, it's most likely
the sign of a protocol abuse, so we make the tasklet go to BULK since
the goal is to punish it.

By limiting the number of RST per loop to 1, the SSL response time drops
from 95ms to 1.6ms during an H2 RST flood attack, and the maximum SSL
connection rate drops from 35.5k to 28.0k instead of 11.8k. A moderate
SSL load that shows 1ms response time and 23kcps increases to 2ms with
15kcps versus 95ms and 800cps before. The average loop time goes down
from 270-280us to 160us, while still doubling the attack absorption
rate with the same CPU capacity.

This patch may usefully be backported to 3.3 and 3.2. Note that to be
effective, this relies on the following patches:

  MEDIUM: sched: do not run a same task multiple times in series
  MINOR: sched: do not requeue a tasklet into the current queue
  MINOR: sched: do not punish self-waking tasklets anymore
  MEDIUM: sched: do not punish self-waking tasklets if TASK_WOKEN_ANY
  MEDIUM: sched: change scheduler budgets to lower TL_BULK
2026-03-23 07:14:22 +01:00