Commit graph

27185 commits

Author SHA1 Message Date
Willy Tarreau
11bad01760 MINOR: proxy: remove the experimental status on dynamic backends
As initially planned, if no trouble was reported on dynamic backend
commands on the CLI, the experimental status could be dropped before the
release. The feedback was not very broad, but was conclusive in that the
operations work as expected and the current syntax can be preserved even
for future evolutions. So we can drop the experimental status.
2026-05-19 14:56:45 +02:00
Willy Tarreau
b59fe471a5 DOC: config: further clarify that resolvers "default" exists
It was explained in the general presentation of resolvers but not in
the "resolvers" keyword description itself, which might be where users
could be looking for that info, so let's quickly repeat that info there.
2026-05-19 14:48:27 +02:00
Willy Tarreau
29b9da7821 CLEANUP: jwe: fix theoretical overflow in AAD length calculation
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
The expression items[JWE_ELT_JOSE].length << 3 performs the shift on an
unsigned int (32-bit) before being cast to uint64_t instead of after.
This means that we don't cover for a possible overflow (which would
never happen as it would need a header length beyond 512MB). At least
fixing it will avoid code check reports.
2026-05-18 18:52:28 +02:00
Willy Tarreau
d4a4be6c34 BUG/MINOR: jwt: fix possible memory leak in convert_ecdsa_sig() error path
The allocated ec_R and ec_S were not released in case one of the two
would fail to be allocated/created, and would cause a memory leak. Let's
add the missing BN_free(). This may be backported to 2.4.
2026-05-18 18:50:30 +02:00
Willy Tarreau
bbc41785d9 CLEANUP: tcpcheck: mention that we're a bit far for a sync errno
The collection of errno in tcpcheck_eval_connect() and tcpcheck_main()
is quite far from the production location, and the risk of having a
zero errno is definitely not null. Tests show that this works, so
better not try to fix something not broken, but at least place a
comment there indicating that it's not necessarily super-reliable.
This would need to be revisited the day we finally store errno in
the connection.
2026-05-18 18:47:41 +02:00
Willy Tarreau
3b825d2745 BUG/MINOR: check: properly report errno in chk_report_conn_err()
When in 2.2, with commit c8dc20a825 ("BUG/MINOR: checks: refine which
errno values are really errors."), errno reporting was refined, an
extra check was added before calling retrieve_errno_from_socket(), and
by mistake the test on !errno got inverted so that we only call the
function to retrieve the error from the socket when errno is set!
The first test in the function detects it and returns without changing
anything, so this didn't have much effect, however when errno is not
set (certain call places purposely pass zero so that getsockopt() is
used), this wasn't called so the error wasn't reported. Apparently it
only happened when called from process_chk_conn() after an async
error was detected, so probably just cases where POLLERR is reported,
which remains infrequent.

Let's fix the direction of this flag. It can be backported if needed
but it's unlikely anyone really noticed.
2026-05-18 18:40:37 +02:00
Willy Tarreau
3da2b63274 BUG/MINOR: sock: store the connection error status
When an async connect() fails in sock_conn_check(), it returns an errno
that will not be retrieved later by a subsequent getsockopt(SO_ERROR).
The problem is that this errno is then definitely lost. This is visible
in the 4be_1srv_smtpchk_httpchk_layer47errors regtest that fails on
certain systems (e.g. glibc 2.31 on arm32 running Linux 6.1), where the
connect() error is systematically lost and the "Connection refused" is
never seen in the check status. It also matches a few random reports of
the past indicating that the connection error was sometimes not reported
in the stats page in front of a down server.

Ideally we should store errno in connections as soon as the error is
seen. However this would require significant changes that are not
acceptable yet for 3.4 nor stable releases. A more acceptable fix is to
make use of the extra CO_ER_* flags set by conn_set_errno() as soon as
the error is detected. This will recognize a sufficiently large number
of errors and the check status will report them (here we'll have
"ECONNREFUSED" in the check). Note that on systems where the error is
seen synchronously, we can have "ECONNREFUSED (Connection refused)",
but this is not a problem.

This fix adds the missing conn_set_errno() call to sock_conn_check(),
that is thus sufficient to catch this error. In addition, the two
affected regtests were updated to search for ECONNREFUSED here.

This might be backported to older releases if users request it, but it
is probably not necessary.
2026-05-18 18:16:25 +02:00
Willy Tarreau
fdb569c2ea REGTESTS: quic/issuers_chain_path: do not forget to enable QUIC compat mode
This test is compatible with QUIC_OPENSSL_COMPAT but the "limited-quic"
directive was not set, making it fail on older libs with no QUIC support
despite being declared as compatible.
2026-05-18 18:01:53 +02:00
Willy Tarreau
fd31df765f REGTESTS: do not run quic/tls13_ssl_crt-list_filters in quic openssl compat mode
This test uses the the backend, it fails in QUIC_OPENSSL_COMPAT so let's
disable it in this case, like other similar tests.
2026-05-18 18:01:53 +02:00
Willy Tarreau
b44d60eb42 CLEANUP: stick-table: uniformize the different action_inc_gpc*()
Some checks failed
Contrib / admin/halog/ (push) Has been cancelled
Contrib / dev/flags/ (push) Has been cancelled
Contrib / dev/haring/ (push) Has been cancelled
Contrib / dev/hpack/ (push) Has been cancelled
Contrib / dev/poll/ (push) Has been cancelled
VTest / Generate Build Matrix (push) Has been cancelled
Windows / Windows, gcc, all features (push) Has been cancelled
VTest / (push) Has been cancelled
While action_inc_gpc1() explicitly checks if s->stkctr or sess->stkctr
are set since 2.8 with commit 6c0117168 ("MEDIUM: stick-table: set the
track-sc limit at boottime via tune.stick-counters"), action_inc_gpc0()
and the generic action_inc_gpc() still stuck to the old approach of not
checking them, causing confusion when reviewing the code.

Upon closer inspection, the only case where the pointer may be NULL is
when global.tune.nb_stk_ctr is zero, which happens when the global
section contains "tune.stick-counters 0". However in this case, the
config parser "parse_inc_gpc()" will reject any reference to any stick
counter, so in theory there is no problem.

Regardless, the difference of treatment between sibling functions remains
confusing and the check is cheap, so let's generalize it, it will save a
future reader from the need to inspect stream_new() and session_new().
2026-05-17 23:10:27 +02:00
Willy Tarreau
015933794e BUG/MINOR: session/trace: use distinct flags for SESS_EV_END and _ERR
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
Session traces were brought in 3.1 by commit abb07af67 ("MINOR:
session/trace: enable very minimal session tracing") though there was
an issue, because SESS_EV_END and SESS_EV_ERR have the same value (it's
a copy-paste mistake).

This can be backported to 3.2.
2026-05-16 20:29:40 +02:00
Willy Tarreau
4519906c70 DOC: internal: add a few rules about internal core principles
The new file core-principles.txt quickly enumerates a number of rules
and invariants across the project. These can be used as quick reminders
as well as basic rules for reviews. It's still lacking a lot of info but
should be a good start.
2026-05-16 20:12:32 +02:00
Willy Tarreau
2f88b4bc4b CLEANUP: address a few typos and copy-paste errors in httpclient and dns
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
These are either typos or copy-paste mistakes (mostly mouse-induced
spaces instead of tabs for dns.c).
2026-05-15 18:25:13 +02:00
Willy Tarreau
9ebb00e673 CLEANUP: proxy: fix duplicate declaration of cli_find_frontend in proxy.h
The function cli_find_frontend was declared twice identically at lines 98-99
of include/haproxy/proxy.h. The second declaration should have been for
cli_find_backend, which is defined in src/proxy.c and used in several places
but was missing from the header's exported symbols.

This is a simple copy-paste mistake where line 99 duplicated line 98 verbatim
instead of declaring cli_find_backend.
2026-05-15 18:24:57 +02:00
Willy Tarreau
3460626148 BUG/MINOR: resolvers: fix missing task_idle destruction in resolvers_destroy()
When destroying a stream-based DNS nameserver, task_req and task_rsp
were destroyed but task_idle was missed, causing a task object leak.
This doesn't necessarily have to be backported since it's only upon
exit that it is visible.
2026-05-15 18:19:41 +02:00
Willy Tarreau
6cbcb4f9db BUG/MINOR: resolvers: fix leaked fields on cfg_parse_resolvers() error paths
cfg_parse_resolvers() has many error paths on allocation failure when
parsing "nameserver". These paths handle their own cleanup instead of
centralizing it. The result is that some errors paths leak some fields.
The most complex ones are the strdup() failures which require to check
for stream or dgram to figure what to free. These can be detected via
ASAN on a dummy strdup() allocation failure:

  Indirect leak of 131080 byte(s) in 1 object(s) allocated from:
      #0 0x7f0b7ed1f0ab in malloc (/usr/lib64/libasan.so.8+0x11f0ab)
      #1 0x000000c73e19 in dns_ring_new src/dns_ring.c:59
      #2 0x000000af1848 in dns_dgram_init src/dns.c:480
      #3 0x000000922005 in cfg_parse_resolvers src/resolvers.c:3792
      #4 0x00000089d33e in parse_cfg src/cfgparse.c:2202
      #5 0x0000009e0a39 in read_cfg src/haproxy.c:1142
      #6 0x000000447e8c in main src/haproxy.c:3474
      #7 0x7f0b7e02ad13 in __libc_start_call_main (/lib64/libc.so.6+0x2ad13)
      #8 0x7ffd35f1531c  ([stack]+0x2031c)

  Indirect leak of 304 byte(s) in 1 object(s) allocated from:
      #0 0x7f0b7ed1ea23 in calloc (/usr/lib64/libasan.so.8+0x11ea23)
      #1 0x000000af1681 in dns_dgram_init src/dns.c:468
      #2 0x000000922005 in cfg_parse_resolvers src/resolvers.c:3792
      #3 0x00000089d33e in parse_cfg src/cfgparse.c:2202
      #4 0x0000009e0a39 in read_cfg src/haproxy.c:1142
      #5 0x000000447e8c in main src/haproxy.c:3474
      #6 0x7f0b7e02ad13 in __libc_start_call_main (/lib64/libc.so.6+0x2ad13)
      #7 0x7ffd35f1531c  ([stack]+0x2031c)

  Indirect leak of 104 byte(s) in 1 object(s) allocated from:
      #0 0x7f0b7ed1ea23 in calloc (/usr/lib64/libasan.so.8+0x11ea23)
      #1 0x000000921f83 in cfg_parse_resolvers src/resolvers.c:3772
      #2 0x00000089d33e in parse_cfg src/cfgparse.c:2202
      #3 0x0000009e0a39 in read_cfg src/haproxy.c:1142
      #4 0x000000447e8c in main src/haproxy.c:3474
      #5 0x7f0b7e02ad13 in __libc_start_call_main (/lib64/libc.so.6+0x2ad13)
      #6 0x7ffd35f1531c  ([stack]+0x2031c)

  Indirect leak of 64 byte(s) in 1 object(s) allocated from:
      #0 0x7f0b7ed1f0ab in malloc (/usr/lib64/libasan.so.8+0x11f0ab)
      #1 0x000000c73e09 in dns_ring_new src/dns_ring.c:55
      #2 0x000000af1848 in dns_dgram_init src/dns.c:480
      #3 0x000000922005 in cfg_parse_resolvers src/resolvers.c:3792
      #4 0x00000089d33e in parse_cfg src/cfgparse.c:2202
      #5 0x0000009e0a39 in read_cfg src/haproxy.c:1142
      #6 0x000000447e8c in main src/haproxy.c:3474
      #7 0x7f0b7e02ad13 in __libc_start_call_main (/lib64/libc.so.6+0x2ad13)
      #8 0x7ffd35f1531c  ([stack]+0x2031c)

  Indirect leak of 15 byte(s) in 1 object(s) allocated from:
      #0 0x7f0b7ed18e20 in strdup (/usr/lib64/libasan.so.8+0x118e20)
      #1 0x00000092203b in cfg_parse_resolvers src/resolvers.c:3798
      #2 0x00000089d33e in parse_cfg src/cfgparse.c:2202
      #3 0x0000009e0a39 in read_cfg src/haproxy.c:1142
      #4 0x000000447e8c in main src/haproxy.c:3474
      #5 0x7f0b7e02ad13 in __libc_start_call_main (/lib64/libc.so.6+0x2ad13)
      #6 0x7ffd35f1531c  ([stack]+0x2031c)

This should be completely reworked so that the cleanup is performed in
a central place, as the risk to get it wrong remains high.

This patch does the minimal changes to clean this up. It does not need
to be backported since it only triggers on boot OOM.
2026-05-15 18:07:50 +02:00
Willy Tarreau
677fdfe126 BUG/MINOR: resolvers: fix leaked dgram and dns_ring struct in parse_resolve_conf()
Some strdup() failures in parse_resolve_conf() do not release everything
due to the way the function is built, resulting in leaks on error that are
caught by ASAN:

  Direct leak of 304 byte(s) in 1 object(s) allocated from:
      #0 0x7fe74231ea23 in calloc (/usr/lib64/libasan.so.8+0x11ea23)
      #1 0x000000af1681 in dns_dgram_init src/dns.c:468
      #2 0x00000091cbbf in parse_resolve_conf src/resolvers.c:3559
      #3 0x00000092179e in cfg_parse_resolvers src/resolvers.c:3815
      #4 0x00000089d33e in parse_cfg src/cfgparse.c:2202
      #5 0x0000009e0a39 in read_cfg src/haproxy.c:1142
      #6 0x000000447e8c in main src/haproxy.c:3474
      #7 0x7fe74162ad13 in __libc_start_call_main (/lib64/libc.so.6+0x2ad13)
      #8 0x7ffc0a43e31f  ([stack]+0x2031f)

  Indirect leak of 131080 byte(s) in 1 object(s) allocated from:
      #0 0x7fe74231f0ab in malloc (/usr/lib64/libasan.so.8+0x11f0ab)
      #1 0x000000c73e19 in dns_ring_new src/dns_ring.c:59
      #2 0x000000af1848 in dns_dgram_init src/dns.c:480
      #3 0x00000091cbbf in parse_resolve_conf src/resolvers.c:3559
      #4 0x00000092179e in cfg_parse_resolvers src/resolvers.c:3815
      #5 0x00000089d33e in parse_cfg src/cfgparse.c:2202
      #6 0x0000009e0a39 in read_cfg src/haproxy.c:1142
      #7 0x000000447e8c in main src/haproxy.c:3474
      #8 0x7fe74162ad13 in __libc_start_call_main (/lib64/libc.so.6+0x2ad13)
      #9 0x7ffc0a43e31f  ([stack]+0x2031f)

  Indirect leak of 64 byte(s) in 1 object(s) allocated from:
      #0 0x7fe74231f0ab in malloc (/usr/lib64/libasan.so.8+0x11f0ab)
      #1 0x000000c73e09 in dns_ring_new src/dns_ring.c:55
      #2 0x000000af1848 in dns_dgram_init src/dns.c:480
      #3 0x00000091cbbf in parse_resolve_conf src/resolvers.c:3559
      #4 0x00000092179e in cfg_parse_resolvers src/resolvers.c:3815
      #5 0x00000089d33e in parse_cfg src/cfgparse.c:2202
      #6 0x0000009e0a39 in read_cfg src/haproxy.c:1142
      #7 0x000000447e8c in main src/haproxy.c:3474
      #8 0x7fe74162ad13 in __libc_start_call_main (/lib64/libc.so.6+0x2ad13)
      #9 0x7ffc0a43e31f  ([stack]+0x2031f)

  SUMMARY: AddressSanitizer: 131448 byte(s) leaked in 3 allocation(s).

Let's free the dgram and the dns ring. This can be backported though it's
not important as it only happens on OOM condition during boot.
2026-05-15 18:00:04 +02:00
Willy Tarreau
b15e9b1b29 BUG/MINOR: resolvers: report the expression error in the do-resolve() action parser
When an expression is used for do-resolve(), an error may be reported.
Unfortunately it was scratched and replaced by the do-resolve() error,
leaving no chance to know exactly what was wrong. Let's report the
contents of the error when available. It will indicate identifiers that
are not found or invalid ranges or types being used.

This can be backported to all versions.
2026-05-15 17:53:00 +02:00
Willy Tarreau
0c8c9b1c2a CLEANUP: resolvers: properly initialize the sample in resolv_action_do_resolve()
The sample used to pass the IP address only had its data, px, sess and
strm fields initialized before being passed to vars_set_by_name(). It
turns out that this latter one doesn't seem to touch ctx, flags nor opt
but nothing guarantees it. Let's at least initialize the fields properly
to avoid passing random garbage.

No backport is needed.
2026-05-15 17:51:58 +02:00
Willy Tarreau
bed842390f BUG/MINOR: proxy: use proxy_drop() in parse_new_proxy() error path
In parse_new_proxy(), when proxy_defproxy_cpy() fails, the error path used
ha_free(&curproxy) to release the partially constructed proxy. However, the
proxy was allocated via alloc_new_proxy() which performs significant setup:
  - setup_new_proxy() inserts it into the proxy_by_name tree (proxy_store_name)
  - It appends to the global proxies list (LIST_APPEND)
  - proxy_take() increments its refcount

Additionally, proxy_defproxy_cpy() may have allocated further resources
(strdup'd strings, compression structures, email alert fields, etc).

Using ha_free() only freed the proxy struct itself, leaving:
  - The proxy still registered in the name tree (dangling pointer)
  - The proxy still linked in the global proxies list
  - All strdup'd strings and other allocations leaked

This is visible with ASAN when causing random allocation errors:

  [NOTICE]   (27033) : haproxy version is 3.4-dev12-b15468-11
  [NOTICE]   (27033) : path to executable is ./haproxy
  [ALERT]    (27033) : config : parsing [/dev/stdin:5015] : proxy 'bk3': failed to duplicate tcpcheck preset-vars
  [ALERT]    (27033) : config : Error(s) found in configuration file : /dev/stdin

  =================================================================
  ==27033==ERROR: LeakSanitizer: detected memory leaks

  Direct leak of 4 byte(s) in 1 object(s) allocated from:
      #0 0x7f113e518e20 in strdup (/usr/lib64/libasan.so.8+0x118e20)
      #1 0x000000955410 in setup_new_proxy src/proxy.c:3178
      #2 0x000000955816 in alloc_new_proxy src/proxy.c:3221
      #3 0x000000956c33 in parse_new_proxy src/proxy.c:3554
      #4 0x000000a24d03 in cfg_parse_listen src/cfgparse-listen.c:495
      #5 0x00000089d33e in parse_cfg src/cfgparse.c:2202
      #6 0x0000009e0bb9 in read_cfg src/haproxy.c:1142
      #7 0x000000447e8c in main src/haproxy.c:3474
      #8 0x7f113d82ad13 in __libc_start_call_main (/lib64/libc.so.6+0x2ad13)
      #9 0x7fff65b4e320  ([stack]+0x20320)

  SUMMARY: AddressSanitizer: 4 byte(s) leaked in 1 allocation(s).

The fix replaces ha_free(&curproxy) with proxy_drop(curproxy), which
properly calls deinit_proxy() to release all internal resources, removes
the proxy from trees and lists, decrements the refcount, and frees the
struct.

No backport is needed since proxy_drop() is only in 3.4.
2026-05-15 17:39:25 +02:00
Willy Tarreau
569f1e2f37 BUG/MINOR: dns: fix dangling dgram pointer on dns_dgram_init() failure path
In dns_dgram_init(), the newly created dgram is assigned to the name server
before the ring is attached. In case of errors, e.g. due to too many watchers,
the dgram is released but not removed from ns->dgram. Let's only assign the
pointer on success to avoid this, as it's not needed before. The problem
was introduced in 2.4 with commit c943799c86 ("MEDIUM: resolvers/dns: split
dns.c into dns.c and resolvers.c"), and was possibly there before. The fix
may be backported to all stable versions.
2026-05-15 17:39:25 +02:00
Willy Tarreau
493dc352ad BUG/MINOR: resolvers: fix dangling list pointer in resolvers_new() error paths
The resolver 'r' is appended to the global sec_resolvers list, but upon failure
later, pointers are released but the element remains in the list, corrupting it,
and possibly causing a crash during deinit() when releasing remaining ones.
Adding a LIST_DEL_INIT() on the error unrolling path is sufficient.

Note that the issue will only happen on failure to allocate memory via
strdup() so the risk is low. The bug was introduced in 2.6 by commit
e7f5776800 ("MINOR: resolvers: resolvers_new() create a resolvers with
default values"), so the fix may be backported to several releases, but
does not necessarily have to go that far.
2026-05-15 17:39:25 +02:00
Willy Tarreau
8aa99dfc74 BUG/MEDIUM: server/cli: unlock server lock on failure in cli_parse_set_server
In cli_parse_set_server()'s 'ssl' branch, the server lock is taken,
and not released in case srv_set_ssl() fails, resulting in a dead lock
and a panic the next time an attempt to touch this server is made. The
lock must be released on all error paths.

This was introduced in 3.3 by commit f8f94ffc9 ("BUG/MEDIUM: server:
Use sni as pool connection name for SSL server only") which was marked
for backporting to 3.0, so this must likely be backported that far.
2026-05-15 17:39:25 +02:00
Willy Tarreau
5b468a0820 BUG/MINOR: servers: use proper source of pool_conn_name in srv_settings_cpy()
The condition 'if (srv->pool_conn_name)' was checking the destination
instead of the source 'src->pool_conn_name', meaning the strdup() would
never fire (since newly calloc'd servers start with NULL pool_conn_name),
and the pool_conn_name setting from default-server was silently ignored.

Introduced in 3.2 with commit f0f1816f1 ("MINOR: check: implement
check-pool-conn-name srv keyword") when pool_conn_name support was added
to srv_settings_cpy(). The bug caused any 'pool-conn-name' setting in a
'default-server' line to be lost for all servers inheriting from it.

Note that it's not the first time this function induces such a bug due
to the poor choice of "srv" vs "src" that should be renamed to avoid
keyboard mistakes and visual confusion.

This needs to be backported to 3.2.
2026-05-15 17:39:25 +02:00
Willy Tarreau
6c663a9374 BUG/MINOR: server: better handling of OOM in srv_set_fqdn()
This function may face an OOM on strdup() in the middle of the hostname
or hostname_dn replacement, leaving NULLs in either or both of the server's
fields, which is definitely not good for other call places.

Let's perform a safe replacement instead: we first allocate the new
values, and only if they are successful, then we release the previous
ones and replace them.

It is not necessary to backport this unless the issue is reported (it
was found via code review).
2026-05-15 17:39:25 +02:00
Willy Tarreau
2a43a1306b CLEANUP: dns: fix misleading error messages in dns_stream_init()
All task allocation errors report "memory allocation error initializing
the ring" when the actual failure was task_new_anywhere() returning NULL.
This clearly is a copy-paste. Let's fix the error messages to help when
debugging. Since it's only about allocation failures during init, there
is probably no point in backporting this.
2026-05-15 17:39:25 +02:00
Willy Tarreau
b6bd6f5b9a CLEANUP: proxy: fix tiny mistakes in parse error messages
One is s/keyworld/keyword in the retry-on parser. The other one is a
wrong argument "len" being printed in case of parse error for
"declare capture" instead of the length itself.

These can be backported though they are not important.
2026-05-15 15:46:46 +02:00
Willy Tarreau
ace19fd638 BUG/MEDIUM: dns: fix memory leak of sockaddr in dns_session_init() error path
In dns_session_init(), sockaddr_alloc() allocates 'addr' from the sockaddr
pool, but on failure of appctx_finalize_startup() we jump to the error label
without calling sockaddr_free(&addr), leaking the allocation. Let's add the
missing sockaddr_free() on the error branch.

This must be backported to 2.6.
2026-05-15 15:40:29 +02:00
Willy Tarreau
bb5c18ab74 BUG/MEDIUM: resolvers: fix name compression pointer validation in resolv_read_name()
The original DNS code would only use the 8 lower bits of the compression
offset. This was fixed in 2.0 with commit 2fa66c3b9 ("BUG/MEDIUM: dns:
overflowed dns name start position causing invalid dns error") but it was
not sufficient because the anti-loop check continues to use only 8 of the
14 bits, thus a crafted response where the 8 lower bits pass the check and
the 6 higher should fail it would be accepted. The impacts remains limited
thanks to the bounds check and the recursion limits, but such invalid
responses could still cost a lot to process. Let's compute the 14-bit
offset once for all and use it everywhere.
2026-05-15 15:33:14 +02:00
Willy Tarreau
fefce297ab BUG/MEDIUM: dns: fix long loops in additional records parse on name failure
In resolv_validate_dns_response(), the additional records loop calls
resolv_read_name(). When it returns zero due to a bad response, the main
loop does a "continue" without making the "reader" pointer progress, so it
evaluates the exact same field again and again. Fortunately this is limited
by arcount which is 16 bits, but it means it can still iterate 65535 times
there, allocating and releasing an answer_record at each turn. Let's just
jump to the invalid_resp label that handles the cleaning. There was the
same pattern (without the allocation) with nscount a few lines above BTW.
These can possibly explain some situations where a high CPU usage observed
processing responses.

Seems like these were introduced in 2.2 with commit 37950c8d2
("BUG/MEDIUM: dns: improper parsing of aditional records")

This must be backported to stable versions.
2026-05-15 15:26:49 +02:00
Willy Tarreau
bcb4f9cd4a BUG/MINOR: config/dns: properly fail on duplicate nameserver name detection
In cfg_parse_resolvers(), two duplicate name checks set err_code but lacked
'goto out', allowing execution to fall through and create the duplicate entry.
This would result in new resolvers and nameservers to be created after the
error was displayed, and a leak of the previous one. It's mostly harmless
since we're exiting after such errors. This can be backported if desired.
2026-05-15 15:04:00 +02:00
Willy Tarreau
da4a4976d7 BUG/MINOR: backend: correct parameter value validation in get_server_ph_post()
In the inner while loop that validates each character of a POST parameter
value, the code checks *p via HTTP_IS_TOKEN() and HTTP_IS_LWS() instead
of *end, while the loop condition only advances "end", so only the first
character of each value is validated.

This means spaces or binary data embedded in parameter values after the
first character goes undetected. Fix by replacing both references to *p
with *end to properly scan through all characters as intended.

This bug was introduced in 1.5-dev20 by commit 98634f0c7 ("MEDIUM:
backend: Enhance hash-type directive with an algorithm options") so
the fix must be backported to all versions.
2026-05-15 15:03:16 +02:00
Willy Tarreau
4a499938d0 [RELEASE] Released version 3.4-dev12
Some checks failed
Contrib / admin/halog/ (push) Has been cancelled
Contrib / dev/flags/ (push) Has been cancelled
Contrib / dev/haring/ (push) Has been cancelled
Contrib / dev/hpack/ (push) Has been cancelled
Contrib / dev/poll/ (push) Has been cancelled
VTest / Generate Build Matrix (push) Has been cancelled
Windows / Windows, gcc, all features (push) Has been cancelled
VTest / (push) Has been cancelled
Released version 3.4-dev12 with the following main changes :
    - SCRIPTS: announce-release: add a link to the OpenTelemetry filter
    - BUG/MEDIUM: servers: Only requeue servers if they are up
    - MINOR: tinfo: store the number of committed extra streams in the tgroup
    - MINOR: connection: add a function to calculate elastic streams limit
    - MINOR: mux-h2: consider the elastic streams limit on frontend
    - MINOR: lb: make LB initialization even more declarative
    - BUG/MINOR: cfgparse-listen: do not emit extraneous line in rule order warnings
    - CLEANUP: tree-wide: fix typos in non user-visible comments in 15 files
    - CLEANUP: h1/htx: fix a few typos in warning, debug and trace messages
    - BUG/MINOR: mux-h1: only check h1s if not NULL
    - BUG/MINOR: http-fetch: fix smp_fetch_hdr_ip()'s handling of brackets for IPv6
    - BUG/MINOR: http-fetch: make http_first_req() check for HTTP first
    - BUG/MINOR: http-act: set-status() must check the response message, not the request
    - BUG/MINOR: tools: fix memory leak in env_expand() error path
    - BUG/MINOR: auth: free user groups on error paths in userlist_postinit()
    - BUG/MINOR: uri-auth: avoid leaks on initialization error
    - BUG/MINOR: cache: fix memory leak in parse_cache_rule error path
    - BUG/MINOR: cfgcond: make KQUEUE check for GTUNE_USE_KQUEUE not GTUNE_USE_EPOLL
    - BUG/MINOR: mqtt: connack parser returns MQTT_NEED_MORE_DATA on unknown property
    - BUG/MINOR: mqtt: connect parser uses wrong bit field for TOPIC_ALIAS_MAXIMUM
    - BUG/MINOR: mqtt: connack parser uses wrong bit for SUBSCRIPTION_IDENTIFIERS_AVAILABLE
    - BUG/MINOR: mqtt: fix PUBLISH flags validation that want all bits to be set
    - CLEANUP: http_htx: rename inner 'type' to 'ptype' to avoid variable shadowing
    - CLEANUP: mux-h2: fix minor output debugging format issues
    - CLEANUP: http-rules: fix a few '&' vs '&&' checks for clarity
    - CLEANUP: auth: remove undeclared auth_resolve_groups() from auth.h
    - CLEANUP: cache: remove redundant res_htx assignment in http_cache_io_handler()
    - CLEANUP: channel: remove bogus and unused definition of channel_empty()
    - CLEANUP: flt_http_comp: remove duplicate rate limit and CPU usage checks
    - CLEANUP: mqtt: remove duplicate MQTT_FN_BIT_USER_PROPERTY in CONNECT fields
    - BUG/MINOR: uri-auth: fix possible null-deref in latest fix for leaks
    - BUG/MEDIUM: tasks: Keep the TASK_RUNNING flag until queued
    - CLEANUP: mqtt: fix spelling of shared_subscription_available
    - CLEANUP: regex: pre-initialize error variable in regex_comp() to calm analysis
    - BUILD: compiler: fix redefinition of __nonstring
    - CLEANUP: defaults: adjust MAX_THREADS multiplier number in comment
    - CLEANUP: src/cpuset.c: fix missing return in functions returning int
    - REGTESTS: Use ${tmpdir} instead of hardcoded /tmp/
    - REGTESTS: Don't try to use real nameservers for testcases
    - CLEANUP: tree-wide: fix typos in non user-visible comments in 3 more files
    - MINOR: cli: improve forward compatibility for show fd
    - DOC: management: document the <tgid>/<fd> form of show fd
    - CLEANUP: tree-wide: fix more typos and outdated explanations in comments
    - BUG/MEDIUM: dict: hold read lock while incrementing refcount in dict_insert
    - BUG/MEDIUM: http-client: Only consume input buffer when hc one is empty
    - BUG/MINOR: xprt_qstrm: fix conflicting prototype
    - REORG: mux_quic: use newer qcm prefix for legacy qmux files
    - MINOR: mux_quic: use qcm prefix for mux callbacks
    - MINOR: mux_quic: use qcm prefix for mux functions
    - MINOR: mux_quic: use qcm prefix for traces functions/structs
    - MINOR: mux_quic: rename qstrm files to qmux
    - MINOR: mux_quic: remove qstrm naming in QUIC MUX
    - MINOR: connection: rename QMux related flags
    - MINOR: xprt_qmux: use qmux instead of qstrm naming
    - MINOR: trace: implement source alias
    - MEDIUM: mux_quic: rename qmux traces to qcm
    - MINOR: sample: add a generic reverse converter
    - MINOR: sample: add a reverse_dom converter
    - DOC: proxy-protocol: clarify UDP usage
    - BUILD: 51d.c: cleanup, fix preprocessor ifdefs
    - CLEANUP: tree-wide: fix typos in user-invisible files
    - CLEANUP: htx: Adjust numbering of HTX blocks' types in the description
2026-05-13 17:22:12 +02:00
Egor Shestakov
b08cf94ae2 CLEANUP: htx: Adjust numbering of HTX blocks' types in the description
Support of pseudo-headers was removed as unused, but mention of it
in the description remains and disrupt the numbering in comment, which
can be confusing.
2026-05-13 17:03:48 +02:00
Egor Shestakov
68f6522add CLEANUP: tree-wide: fix typos in user-invisible files
Fix typos and spelling mistakes in sources files and in the BRANCHES.
These mistakes are harmless, no backport needed.
2026-05-13 17:03:48 +02:00
Ilia Shipitsin
61aa17aec8 BUILD: 51d.c: cleanup, fix preprocessor ifdefs
The ifdef spans over function boundaries, making some combinations produce
code that does not build:

addons/51degrees/51d.c:638:1: error: Unmatched '}'. Configuration: ''. [syntaxError]
2026-05-13 17:00:20 +02:00
Kevin Ludwig
6e9b9196bd DOC: proxy-protocol: clarify UDP usage
the proxy protocol spec didn't specify UDP and therefore most
implementations treat it as a TCP connection and re-use the last send
information for a ip/port pair.

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

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

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

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

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

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

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

The documentation is updated and a reg-test is added to cover the basic
conversion as well as a simple composition with concat(.).
2026-05-13 16:45:25 +02:00
Amaury Denoyelle
c090e51502 MEDIUM: mux_quic: rename qmux traces to qcm
This patch is part of a renaming affecting mux_quic and related files.
Naming "qcm" will become the new marker for common mux_quic stuffs,
shared both on QUIC and QMux protocols. The final objective is to limit
"qmux" naming for stuffs related to the new experimental protocol of the
same name.

The current patch renames mux_quic traces token to "qcm". This is the
only change with external visible impacts in the whole renaming series.
However, to preserve compatibility, trace source alias is defined with
the older name "qmux". This relies on the previous patch which
introduced "alias" new trace_source member.
2026-05-13 16:23:58 +02:00
Amaury Denoyelle
8e1b46f8d7 MINOR: trace: implement source alias
Add a new "alias" member in trace_source structure. Its purpose is to be
an alternative to the member "name". This will be used in the next patch
to allow renaming of QUIC mux traces while preserving compatibility.

This new member is only used in trace_find_source() which is the helper
used to retrieve a trace source from its name.
2026-05-13 16:23:58 +02:00
Amaury Denoyelle
19a3c29d3c MINOR: xprt_qmux: use qmux instead of qstrm naming
This is a follow-up on the QUIC MUX renaming process.

The current patch performs renaming in xprt_qmux layer. Older "qstrm"
identifier is replaced by the new name "qmux". Every remaining functions
and structures in xprt_qmux are changed. Outside effects are only
present in QUIC MUX which directly uses some of these functions.
2026-05-13 16:23:58 +02:00
Amaury Denoyelle
1bb879cb3f MINOR: connection: rename QMux related flags
This is a follow-up on the QUIC MUX renaming process.

The current patch performs renaming of "qstrm" to "qmux" in connection
flags. These flags are only used in linked with the xprt_qmux layer.
This has an impact on every files which manipulates these flags, namely
backend, session and ssl_sock sources.

Also, internal xprt identifier is renamed from XPRT_QSTRM to XPRT_QMUX,
2026-05-13 16:23:58 +02:00
Amaury Denoyelle
96b72fd461 MINOR: mux_quic: remove qstrm naming in QUIC MUX
This is a follow-up on the QUIC MUX renaming process.

The current patch replaces "qstrm" naming with "qmux" in QUIC MUX source
file. Some members are impacted in qcc and qcs structures, as well as
some internal functions used for QMux receive/send. Internal mux_ops is
also rename to qmux_ops. This is not a breaking change as its externally
visible name was already set to "qmux" originally.
2026-05-13 16:22:43 +02:00
Amaury Denoyelle
57ab169747 MINOR: mux_quic: rename qstrm files to qmux
This is a follow-up on the QUIC MUX renaming process. Now most of "qmux"
generic usages as been replaced in favor of "qcm" naming. The next part
of the renaming is to replace "qstrm" naming with "qmux" for stuffs
related to the new QMux protocol specifically.

This is first applied on filenames. As with the previous renaming,
Makefile and include statements are updated as well to prevent
compilation issues.
2026-05-13 16:15:48 +02:00
Amaury Denoyelle
e68d4c9c36 MINOR: mux_quic: use qcm prefix for traces functions/structs
This is a follow-up on the QUIC MUX renaming process.

This patch renames several definitions in QUIC MUX traces source code.
This is only an internal change. Trace source name is kept to "qmux" for
now, but will be changed in a dedicated patch.
2026-05-13 16:15:48 +02:00
Amaury Denoyelle
1a9ab14efc MINOR: mux_quic: use qcm prefix for mux functions
This is a follow-up on the QUIC MUX renaming process.

A previous patch already renames MUX ops callbacks. The current patch
proceed to a similar operation for the rest of the MUX functions.
2026-05-13 16:15:47 +02:00
Amaury Denoyelle
545351f2c1 MINOR: mux_quic: use qcm prefix for mux callbacks
This is a follow-up on the QUIC MUX renaming process.

The current patch renames all MUX functions used as stream ops
callbacks. Also, internally defined mux_ops is also renamed from
"qmux_ops" to "quic_ops". There is no breaking change as mux_ops name
field remain set to "QUIC".
2026-05-13 16:13:46 +02:00
Amaury Denoyelle
af3560fa0a REORG: mux_quic: use newer qcm prefix for legacy qmux files
This patch is the first one of the renaming serie, affecting the QUIC
MUX module. The objective is to remove older "qmux" naming which was
used as a generic identifier. Now it should be restricted to the QMux
experimental protocol. A new "qcm" naming will replace the generic
usage.

The current patch renames the files themselves. Token "qmux" is replaced
by the new "qcm" identifier. Makefile and include statements are
adjusted as required.
2026-05-13 16:11:50 +02:00
Amaury Denoyelle
7e2f0fa178 BUG/MINOR: xprt_qstrm: fix conflicting prototype
This patch adds the missing include of xprt_qstrm header into its
companion source file. This helped to detect an incoherence in the
xprt_qstrm_xfer_rxbuf() prototype which is now fixed.

Header files is also updated with mandatory include statements and
forward declaration.

No backport needed.
2026-05-13 16:11:50 +02:00