]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
2 months agoBUILD: incompatible pointer type suspected with -DDEBUG_UNIT 20250415-gcc-15-unittest
William Lallemand [Tue, 15 Apr 2025 13:49:44 +0000 (15:49 +0200)] 
BUILD: incompatible pointer type suspected with -DDEBUG_UNIT

src/jws.c: In function '__jws_init':
src/jws.c:594:38: error: passing argument 2 of 'hap_register_unittest' from incompatible pointer type [-Wincompatible-pointer-types]
  594 |         hap_register_unittest("jwk", jwk_debug);
      |                                      ^~~~~~~~~
      |                                      |
      |                                      int (*)(int,  char **)
In file included from include/haproxy/api.h:36,
                 from include/import/ebtree.h:251,
                 from include/import/ebmbtree.h:25,
                 from include/haproxy/jwt-t.h:25,
                 from src/jws.c:5:
include/haproxy/init.h:37:52: note: expected 'int (*)(void)' but argument is of type 'int (*)(int,  char **)'
   37 | void hap_register_unittest(const char *name, int (*fct)());
      |                                              ~~~~~~^~~~~~

GCC 15 is warning because the function pointer does have its
arguments in the register function.

Should fix issue #2929.

2 months agoCLEANUP: acme: stored value is overwritten before it can be used
William Lallemand [Tue, 15 Apr 2025 09:44:45 +0000 (11:44 +0200)] 
CLEANUP: acme: stored value is overwritten before it can be used

   >>>     CID 1609049:  Code maintainability issues  (UNUSED_VALUE)
   >>>     Assigning value "NULL" to "new_ckchs" here, but that stored value is overwritten before it can be used.
   592             struct ckch_store *old_ckchs, *new_ckchs = NULL;

Coverity reported an issue where a variable is initialized to NULL then
directry overwritten with another value. This doesn't arm but this patch
removes the useless initialization.

Must fix issue #2932.

2 months agoBUG/MINOR: acme: fix possible NULL deref
William Lallemand [Tue, 15 Apr 2025 09:36:26 +0000 (11:36 +0200)] 
BUG/MINOR: acme: fix possible NULL deref

Task was dereferenced when setting ctx but was checked after.
This patch move the setting of ctx after the check.

Should fix issue #2931

2 months agoMINOR: debug: detect call instructions and show the branch target in backtraces
Willy Tarreau [Mon, 14 Apr 2025 18:06:48 +0000 (20:06 +0200)] 
MINOR: debug: detect call instructions and show the branch target in backtraces

In backtraces, sometimes it's difficult to know what was called by a
given point, because some functions can be fairly long making one
doubt about the correct pointer of unresolved ones, others might
just use a tail branch instead of a call + return, etc. On common
architectures (x86 and aarch64), it's not difficult to detect and
decode a relative call, so let's do it on both of these platforms
and show the branch location after a '>'. Example:

x86_64:
   call trace(19):
   |       0x6bd644 <64 8b 38 e8 ac f7 ff ff]: debug_handler+0x84/0x95 > ha_thread_dump_one
   | 0x7feb3e5383a0 <00 00 00 00 0f 1f 40 00]: libpthread:+0x123a0
   | 0x7feb3e53748b <c0 b8 03 00 00 00 0f 05]: libpthread:__close+0x3b/0x8b
   |       0x7619e4 <44 89 ff e8 fc 97 d4 ff]: _fd_delete_orphan+0x1d4/0x1d6 > main-0x2130
   |       0x743862 <8b 7f 68 e8 8e e1 01 00]: sock_conn_ctrl_close+0x12/0x54 > fd_delete
   |       0x5ac822 <c0 74 05 4c 89 e7 ff d0]: main+0xff512
   |       0x5bc85c <48 89 ef e8 04 fc fe ff]: main+0x10f54c > main+0xff150
   |       0x5be410 <4c 89 e7 e8 c0 e1 ff ff]: main+0x111100 > main+0x10f2c0
   |       0x6ae6a4 <28 00 00 00 00 ff 51 58]: cli_io_handler+0x31524
   |       0x6aeab4 <7c 24 08 e8 fc fa ff ff]: sc_destroy+0x14/0x2a4 > cli_io_handler+0x31430
   |       0x6c685d <48 89 ef e8 43 82 fe ff]: process_chk_conn+0x51d/0x1927 > sc_destroy

aarch64:
   call trace(15):
   | 0xaaaaad0c1540 <60 6a 60 b8 c3 fd ff 97]: debug_handler+0x9c/0xbc > ha_thread_dump_one
   | 0xffffa8c177ac <c2 e0 3b d5 1f 20 03 d5]: linux-vdso:__kernel_rt_sigreturn
   | 0xaaaaad0b0964 <c0 03 5f d6 d2 ff ff 97]: cli_io_handler+0x28e44 > sedesc_new
   | 0xaaaaad0b22a4 <00 00 80 d2 94 f9 ff 97]: sc_new_from_strm+0x1c/0x54 > cli_io_handler+0x28dd0
   | 0xaaaaad0167e8 <21 00 80 52 a9 6e 02 94]: stream_new+0x258/0x67c > sc_new_from_strm
   | 0xaaaaad0b21f8 <e1 03 13 aa e7 90 fd 97]: sc_new_from_endp+0x38/0xc8 > stream_new
   | 0xaaaaacfda628 <21 18 40 f9 e7 5e 03 94]: main+0xcaca8 > sc_new_from_endp
   | 0xaaaaacfdb95c <42 c0 00 d1 02 f3 ff 97]: main+0xcbfdc > main+0xc8be0
   | 0xaaaaacfdd3f0 <e0 03 13 aa f5 f7 ff 97]: h1_io_cb+0xd0/0xb90 > main+0xcba40

2 months agoMINOR: debug: in call traces, dump the 8 bytes before the return address, not after
Willy Tarreau [Mon, 14 Apr 2025 17:28:22 +0000 (19:28 +0200)] 
MINOR: debug: in call traces, dump the 8 bytes before the return address, not after

In call traces, we're interested in seeing the code that was executed, not
the code that was not yet. The return address is where the CPU will return
to, so we want to see the bytes that precede this location. In the example
below on x86 we can clearly see a number of direct "call" instructions
(0xe8 + 4 bytes). There are also indirect calls (0xffd0) that cannot be
exploited but it gives insights about where the code branched, which will
not always be the function above it if that one used tail branching for
example. Here's an example dump output:

         call ------------,
                          v
       0x6bd634 <64 8b 38 e8 ac f7 ff ff]: debug_handler+0x84/0x95
 0x7fa4ea2593a0 <00 00 00 00 0f 1f 40 00]: libpthread:+0x123a0
       0x752132 <00 00 00 00 00 90 41 55]: htx_remove_blk+0x2/0x354
       0x5b1a2c <4c 89 ef e8 04 07 1a 00]: main+0x10471c
       0x5b5f05 <48 89 df e8 8b b8 ff ff]: main+0x108bf5
       0x60b6f4 <89 ee 4c 89 e7 41 ff d0]: tcpcheck_eval_send+0x3b4/0x14b2
       0x610ded <00 00 00 e8 53 a5 ff ff]: tcpcheck_main+0x7dd/0xd36
       0x6c5ab4 <48 89 df e8 5c ab f4 ff]: wake_srv_chk+0xc4/0x3d7
       0x6c5ddc <48 89 f7 e8 14 fc ff ff]: srv_chk_io_cb+0xc/0x13

2 months agoMINOR: tools: let dump_addr_and_bytes() support dumping before the offset
Willy Tarreau [Mon, 14 Apr 2025 17:25:27 +0000 (19:25 +0200)] 
MINOR: tools: let dump_addr_and_bytes() support dumping before the offset

For code dumps, dumping from the return address is pointless, what is
interesting is to dump before the return address to read the machine
code that was executed before branching. Let's just make the function
support negative sizes to indicate that we're dumping this number of
bytes to the address instead of this number from the address. In this
case, in order to distinguish them, we're using a '<' instead of '[' to
start the series of bytes, indicating where the bytes expand and where
they stop. For example we can now see this:

       0x6bd634 <64 8b 38 e8 ac f7 ff ff]: debug_handler+0x84/0x95
 0x7fa4ea2593a0 <00 00 00 00 0f 1f 40 00]: libpthread:+0x123a0
       0x752132 <00 00 00 00 00 90 41 55]: htx_remove_blk+0x2/0x354
       0x5b1a2c <4c 89 ef e8 04 07 1a 00]: main+0x10471c
       0x5b5f05 <48 89 df e8 8b b8 ff ff]: main+0x108bf5
       0x60b6f4 <89 ee 4c 89 e7 41 ff d0]: tcpcheck_eval_send+0x3b4/0x14b2
       0x610ded <00 00 00 e8 53 a5 ff ff]: tcpcheck_main+0x7dd/0xd36
       0x6c5ab4 <48 89 df e8 5c ab f4 ff]: wake_srv_chk+0xc4/0x3d7
       0x6c5ddc <48 89 f7 e8 14 fc ff ff]: srv_chk_io_cb+0xc/0x13

2 months agoDEBUG: counters: add the ability to enable/disable updating the COUNT_IF counters
Willy Tarreau [Mon, 14 Apr 2025 16:31:25 +0000 (18:31 +0200)] 
DEBUG: counters: add the ability to enable/disable updating the COUNT_IF counters

These counters can have a noticeable cost on large machines, though not
dramatic. There's no single good choice to keep them enabled or disabled.
This commit adds multiple choices:
  - DEBUG_COUNTERS set to 2 will automatically enable them by default, while
    1 will disable them by default
  - the global "debug.counters on/off" will allow to change the setting at
    boot, regardless of DEBUG_COUNTERS as long as it was at least 1.
  - the CLI "debug counters on/off" will also allow to change the value at
    run time, allowing to observe a phenomenon while it's happening, or to
    disable counters if it's suspected that their cost is too high

Finally, the "debug counters" command will append "(stopped)" at the end
of the CNT lines when these counters are stopped.

Not that the whole mechanism would easily support being extended to all
counter types by specifying the types to apply to, but it doesn't seem
useful at all and would require the user to also type "cnt" on debug
lines. This may easily be changed in the future if it's found relevant.

2 months agoDEBUG: counters: make COUNT_IF() only appear at DEBUG_COUNTERS>=1
Willy Tarreau [Mon, 14 Apr 2025 15:46:18 +0000 (17:46 +0200)] 
DEBUG: counters: make COUNT_IF() only appear at DEBUG_COUNTERS>=1

COUNT_IF() is convenient but can be heavy since some of them were found
to trigger often (roughly 1 counter per request on avg). This might even
have an impact on large setups due to the cost of a shared cache line
bouncing between multiple cores. For now there's no way to disable it,
so let's only enable it when DEBUG_COUNTERS is 1 or above. A future
change will make it configurable.

2 months agoDEBUG: rename DEBUG_GLITCHES to DEBUG_COUNTERS and enable it by default
Willy Tarreau [Mon, 14 Apr 2025 15:32:10 +0000 (17:32 +0200)] 
DEBUG: rename DEBUG_GLITCHES to DEBUG_COUNTERS and enable it by default

Till now the per-line glitches counters were only enabled with the
confusingly named DEBUG_GLITCHES (which would not turn glitches off
when disabled). Let's instead change it to DEBUG_COUNTERS and make sure
it's enabled by default (though it can still be disabled with
-DDEBUG_GLITCHES=0 just like for DEBUG_STRICT). It will later be
expanded to cover more counters.

2 months agoDEBUG: init: report invalid characters in debug description strings
Willy Tarreau [Mon, 14 Apr 2025 17:00:01 +0000 (19:00 +0200)] 
DEBUG: init: report invalid characters in debug description strings

It's easy to leave some trailing \n or even other characters that can
mangle the debug output. Let's verify at boot time that the debug sections
are clean by checking for chars 0x20 to 0x7e inclusive. This is very simple
to do and it managed to find another one in a multi-line message:

  [WARNING]  (23696) : Invalid character 0x0a at position 96 in description string at src/cli.c:2516 _send_status()

This way new offending code will be spotted before being committed.

2 months agoDOC: config: add the missing "force-cfg-parser-pause" to the global kw index
Willy Tarreau [Mon, 14 Apr 2025 16:29:02 +0000 (18:29 +0200)] 
DOC: config: add the missing "force-cfg-parser-pause" to the global kw index

It was documented but missing from the index, let's add it. This can be
backported to 3.1.

2 months agoDOC: config: add the missing "profiling.memory" to the global kw index
Willy Tarreau [Mon, 14 Apr 2025 16:28:09 +0000 (18:28 +0200)] 
DOC: config: add the missing "profiling.memory" to the global kw index

It was in the description but not in the index. This can be backported to
all versions where it applies.

2 months agoBUG/MINOR: debug: remove the trailing \n from BUG_ON() statements
Willy Tarreau [Mon, 14 Apr 2025 16:45:35 +0000 (18:45 +0200)] 
BUG/MINOR: debug: remove the trailing \n from BUG_ON() statements

These ones were added by mistake during the change of the cfgparse
mechanism in 3.1, but they're corrupting the output of "debug counters"
by leaving stray ']' on their own lines. We could possibly check them
all once at boot but it doens't seem worth it.

This should be backported to 3.1.

2 months agoDOC: acme: explain how to configure and run ACME
William Lallemand [Mon, 14 Apr 2025 14:12:26 +0000 (16:12 +0200)] 
DOC: acme: explain how to configure and run ACME

Add configuration about the acme section in the configuration manual, as
well as the acme command in the management guide.

2 months agoMINOR: acme: default to 2048bits for RSA
William Lallemand [Mon, 14 Apr 2025 13:28:54 +0000 (15:28 +0200)] 
MINOR: acme: default to 2048bits for RSA

Change the default RSA value to 2048 bits.

2 months agoBUG/MINOR: thread: protect thread_cpus_enabled_at_boot with USE_THREAD
Valentine Krasnobaeva [Sat, 12 Apr 2025 09:16:08 +0000 (11:16 +0200)] 
BUG/MINOR: thread: protect thread_cpus_enabled_at_boot with USE_THREAD

Following error is triggered at linker invokation, when we try to compile with
USE_THREAD=0 and -O0.

  make -j 8 TARGET=linux-glibc USE_LUA=1 USE_PCRE2=1 USE_LINUX_CAP=1 \
   USE_MEMORY_PROFILING=1 OPT_CFLAGS=-O0  USE_THREAD=0

  /usr/bin/ld: src/thread.o: warning: relocation against `thread_cpus_enabled_at_boot' in read-only section `.text'
  /usr/bin/ld: src/thread.o: in function `thread_detect_count':
  /home/vk/projects/haproxy/src/thread.c:1619: undefined reference to `thread_cpus_enabled_at_boot'
  /usr/bin/ld: /home/vk/projects/haproxy/src/thread.c:1619: undefined reference to `thread_cpus_enabled_at_boot'
  /usr/bin/ld: /home/vk/projects/haproxy/src/thread.c:1620: undefined reference to `thread_cpus_enabled_at_boot'
  /usr/bin/ld: warning: creating DT_TEXTREL in a PIE
  collect2: error: ld returned 1 exit status
  make: *** [Makefile:1044: haproxy] Error 1

thread_cpus_enabled_at_boot is only available when we compiled with
USE_THREAD=1, which is the default for the most targets now.

In some cases, we need to recompile in mono-thread mode, thus
thread_cpus_enabled_at_boot should be protected with USE_THREAD in
thread_detect_count().

thread_detect_count() is always called during the process initialization
never mind of multi thread support. It sets some defaults in global.nbthread
and global.nbtgroups.

This patch is related to GitHub issue #2916.
No need to be backported as it was added in 3.2-dev9 version.

2 months agoBUG/MINOR: acme: key not restored upon error in acme_res_certificate()
William Lallemand [Mon, 14 Apr 2025 08:44:24 +0000 (10:44 +0200)] 
BUG/MINOR: acme: key not restored upon error in acme_res_certificate()

When receiving the final certificate, it need to be loaded by
ssl_sock_load_pem_into_ckch(). However this function will remove any
existing private key in the struct ckch_store.

In order to fix the issue, the ptr to the key is swapped with a NULL
ptr, and restored once the new certificate is commited.

However there is a discrepancy when there is an error in
ssl_sock_load_pem_into_ckch() fails and the pointer is lost.

This patch fixes the issue by restoring the pointer in the error path.

This must fix issue #2933.

2 months agoBUG/MINOR: cpu-topo: check the correct variable for NULL after malloc()
Willy Tarreau [Sat, 12 Apr 2025 16:22:34 +0000 (18:22 +0200)] 
BUG/MINOR: cpu-topo: check the correct variable for NULL after malloc()

We were testing ha_cpu_topo instead of ha_cpu_clusters after an allocation,
making the check ineffective.

No backport is needed.

2 months agoBUILD: acme: enable the ACME feature when JWS is present
William Lallemand [Fri, 11 Apr 2025 23:10:14 +0000 (01:10 +0200)] 
BUILD: acme: enable the ACME feature when JWS is present

The ACME feature depends on the JWS, which currently does not work with
every SSL libraries. This patch only enables ACME when JWS is enabled.

2 months agoMINOR: acme: schedule retries with a timer
William Lallemand [Fri, 11 Apr 2025 22:47:33 +0000 (00:47 +0200)] 
MINOR: acme: schedule retries with a timer

Schedule the retries with a 3s exponential timer. This is a temporary
mesure as the client should follow the Retry-After field for
rate-limiting for every request (https://datatracker.ietf.org/doc/html/rfc8555#section-6.6)

2 months agoMEDIUM: acme: replace the previous ckch instance with new ones
William Lallemand [Fri, 11 Apr 2025 21:54:52 +0000 (23:54 +0200)] 
MEDIUM: acme: replace the previous ckch instance with new ones

This step is the latest to have a usable ACME certificate in haproxy.

It looks for the previous certificate, locks the "BIG CERTIFICATE LOCK",
copy every instance, deploys new ones, remove the previous one.
This is done in one step in a function which does not yield, so it could
be problematic if you have thousands of instances to handle.

It still lacks the rate limit which is mandatory to be used in
production, and more cleanup and deinit.

2 months agoMINOR: acme: copy the original ckch_store
William Lallemand [Fri, 11 Apr 2025 21:52:07 +0000 (23:52 +0200)] 
MINOR: acme: copy the original ckch_store

Copy the original ckch_store instead of creating a new one. This allows
to inherit the ckch_conf from the previous structure when doing a
ckchs_dup(). The ckch_conf contains the SAN for ACME.

Free the previous PKEY since it a new one is generated.

2 months agoMINOR: ssl/ckch: handle ckch_conf in ckchs_dup() and ckch_conf_clean()
William Lallemand [Fri, 11 Apr 2025 21:46:22 +0000 (23:46 +0200)] 
MINOR: ssl/ckch: handle ckch_conf in ckchs_dup() and ckch_conf_clean()

Handle new members of the ckch_conf in ckchs_dup() and
ckch_conf_clean().

This could be automated at some point since we have the description of
all types in ckch_conf_kws.

2 months agoBUG/MINOR: acme: ckch_conf_acme_init() when no filename
William Lallemand [Fri, 11 Apr 2025 21:44:13 +0000 (23:44 +0200)] 
BUG/MINOR: acme: ckch_conf_acme_init() when no filename

Does not try to strdup the configuration filename if there is none.

No backport needed.

2 months agoMINOR: acme: implement retrieval of the certificate
William Lallemand [Fri, 11 Apr 2025 20:19:24 +0000 (22:19 +0200)] 
MINOR: acme: implement retrieval of the certificate

Once the Order status is "valid", the certificate URL is accessible,
this patch implements the retrieval of the certificate which is stocked
in ctx->store.

2 months agoMINOR: acme: verify the order status once finalized
William Lallemand [Fri, 11 Apr 2025 18:56:57 +0000 (20:56 +0200)] 
MINOR: acme: verify the order status once finalized

This implements a call to the order status to check if the certificate
is ready.

2 months agoMINOR: acme: finalize by sending the CSR
William Lallemand [Fri, 11 Apr 2025 18:35:56 +0000 (20:35 +0200)] 
MINOR: acme: finalize by sending the CSR

This patch does the finalize step of the ACME task.
This encodes the CSR into base64 format and send it to the finalize URL.

https://www.rfc-editor.org/rfc/rfc8555#section-7.4

2 months agoMINOR: acme: generate the CSR in a X509_REQ
William Lallemand [Fri, 11 Apr 2025 16:33:47 +0000 (18:33 +0200)] 
MINOR: acme: generate the CSR in a X509_REQ

Generate the X509_REQ using the generated private key and the SAN from
the configuration. This is only done once before the task is started.

It could probably be done at the beginning of the task with the private
key generation once we have a scheduler instead of a CLI command.

2 months agoMINOR: acme: implement a check on the challenge status
William Lallemand [Fri, 11 Apr 2025 15:29:26 +0000 (17:29 +0200)] 
MINOR: acme: implement a check on the challenge status

This patch implements a check on the challenge URL, once haproxy asked
for the challenge to be verified, it must verify the status of the
challenge resolution and if there weren't any error.

2 months agoMINOR: acme: send the request for challenge ready
William Lallemand [Fri, 11 Apr 2025 14:44:50 +0000 (16:44 +0200)] 
MINOR: acme: send the request for challenge ready

This patch sends the "{}" message to specify that a challenge is ready.
It iterates on every challenge URL in the authorization list from the
acme_ctx.

This allows the ACME server to procede to the challenge validation.
https://www.rfc-editor.org/rfc/rfc8555#section-7.5.1

2 months agoMINOR: acme: get the challenges object from the Auth URL
William Lallemand [Thu, 10 Apr 2025 20:18:06 +0000 (22:18 +0200)] 
MINOR: acme: get the challenges object from the Auth URL

This patch implements the retrieval of the challenges objects on the
authorizations URLs. The challenges object contains a token and a
challenge url that need to be called once the challenge is setup.

Each authorization URLs contain multiple challenge objects, usually one
per challenge type (HTTP-01, DNS-01, ALPN-01... We only need to keep the
one that is relevent to our configuration.

2 months agoMINOR: acme: allow empty payload in acme_jws_payload()
William Lallemand [Thu, 10 Apr 2025 16:43:42 +0000 (18:43 +0200)] 
MINOR: acme: allow empty payload in acme_jws_payload()

Some ACME requests are required to have a JWS with an empty payload,
let's be more flexible and allow this function to have an empty buffer.

2 months agoMINOR: acme: newOrder request retrieve authorizations URLs
William Lallemand [Wed, 9 Apr 2025 21:16:28 +0000 (23:16 +0200)] 
MINOR: acme: newOrder request retrieve authorizations URLs

This patch implements the newOrder action in the ACME task, in order to
ask for a new certificate, a list of SAN is sent as a JWS payload.
the ACME server replies a list of Authorization URLs. One Authorization
is created per SAN on a Order.

The authorization URLs are stored in a linked list of 'struct acme_auth'
in acme_ctx, so we can get the challenge URLs from them later.

The location header is also store as it is the URL of the order object.

https://datatracker.ietf.org/doc/html/rfc8555#section-7.4

2 months agoMINOR: acme: generate new account
William Lallemand [Wed, 9 Apr 2025 19:32:05 +0000 (21:32 +0200)] 
MINOR: acme: generate new account

The new account action in the ACME task use the same function as the
chkaccount, but onlyReturnExisting is not sent in this case!

2 months agoMINOR: acme: check if the account exist
William Lallemand [Wed, 9 Apr 2025 18:31:52 +0000 (20:31 +0200)] 
MINOR: acme: check if the account exist

This patch implements the retrival of the KID (account identifier) using
the pkey.

A request is sent to the newAccount URL using the onlyReturnExisting
option, which allow to get the kid of an existing account.

acme_jws_payload() implement a way to generate a JWS payload using the
nonce, pkey and provided URI.

2 months agoMINOR: acme: handle the nonce
William Lallemand [Wed, 9 Apr 2025 15:45:39 +0000 (17:45 +0200)] 
MINOR: acme: handle the nonce

ACME requests are supposed to be sent with a Nonce, the first Nonce
should be retrieved using the newNonce URI provided by the directory.

This nonce is stored and must be replaced by the new one received in the
each response.

2 months agoMINOR: acme: get the ACME directory
William Lallemand [Wed, 9 Apr 2025 14:43:24 +0000 (16:43 +0200)] 
MINOR: acme: get the ACME directory

The first request of the ACME protocol is getting the list of URLs for
the next steps.

This patch implements the first request and the parsing of the response.

The response is a JSON object so mjson is used to parse it.

2 months agoMINOR: acme: the acme section is experimental
William Lallemand [Wed, 9 Apr 2025 14:35:11 +0000 (16:35 +0200)] 
MINOR: acme: the acme section is experimental

Allow the usage of the acme section only when
expose-experimental-directives is set.

2 months agoMINOR: acme/cli: add the 'acme renew' command
William Lallemand [Thu, 20 Feb 2025 10:31:32 +0000 (11:31 +0100)] 
MINOR: acme/cli: add the 'acme renew' command

The "acme renew" command launch the ACME task for a given certificate.

The CLI parser generates a new private key using the parameters from the
acme section..

2 months agoMINOR: acme: add private key configuration
William Lallemand [Wed, 2 Apr 2025 16:52:24 +0000 (18:52 +0200)] 
MINOR: acme: add private key configuration

This commit allows to configure the generated private keys, you can
configure the keytype (RSA/ECDSA), the number of bits or the curves.

Example:

    acme LE
        uri https://acme-staging-v02.api.letsencrypt.org/directory
        account account.key
        contact foobar@example.com
        challenge HTTP-01
        keytype ECDSA
        curves P-384

2 months agoMINOR: acme: add configuration for the crt-store
William Lallemand [Wed, 2 Apr 2025 09:03:45 +0000 (11:03 +0200)] 
MINOR: acme: add configuration for the crt-store

Add new acme keywords for the ckch_conf parsing, which will be used on a
crt-store, a crt line in a frontend, or even a crt-list.

The cfg_postparser_acme() is called in order to check if a section referenced
elsewhere really exists in the config file.

2 months agoMINOR: acme: add the acme section in the configuration parser
William Lallemand [Wed, 2 Apr 2025 08:54:19 +0000 (10:54 +0200)] 
MINOR: acme: add the acme section in the configuration parser

Add a configuration parser for the new acme section, the section is
configured this way:

    acme letsencrypt
        uri https://acme-staging-v02.api.letsencrypt.org/directory
        account account.key
        contact foobar@example.com
        challenge HTTP-01

When unspecified, the challenge defaults to HTTP-01, and the account key
to "<section_name>.account.key".

Section are stored in a linked list containing acme_cfg structures, the
configuration parsing is mostly resolved in the postsection parser
cfg_postsection_acme() which is called after the parsing of an acme section.

2 months agoMEDIUM: ssl/ckch: add filename and linenum argument to crt-store parsing
William Lallemand [Wed, 2 Apr 2025 09:40:42 +0000 (11:40 +0200)] 
MEDIUM: ssl/ckch: add filename and linenum argument to crt-store parsing

Add filename and linenum arguments to the crt-store / ckch_conf parsing.

It allows to use them in the parsing function so we could emits error.

2 months agoMINOR: master/cli: support bidirectional communications with workers
Willy Tarreau [Tue, 1 Apr 2025 05:50:19 +0000 (07:50 +0200)] 
MINOR: master/cli: support bidirectional communications with workers

Some rare commands in the worker require to keep their input open and
terminate when it's closed ("show events -w", "wait"). Others maintain
a per-session context ("set anon on"). But in its default operation
mode, the master CLI passes commands one at a time to the worker, and
closes the CLI's input channel so that the command can immediately
close upon response. This effectively prevents these two specific cases
from being used.

Here the approach that we take is to introduce a bidirectional mode to
connect to the worker, where everything sent to the master is immediately
forwarded to the worker (including the raw command), allowing to queue
multiple commands at once in the same session, and to continue to watch
the input to detect when the client closes. It must be a client's choice
however, since doing so means that the client cannot batch many commands
at once to the master process, but must wait for these commands to complete
before sending new ones. For this reason we use the prefix "@@<pid>" for
this. It works exactly like "@" except that it maintains the channel
open during the whole execution. Similarly to "@<pid>" with no command,
"@@<pid>" will simply open an interactive CLI session to the worker, that
will be ended by "quit" or by closing the connection. This can be convenient
for the user, and possibly for clients willing to dedicate a connection to
the worker.

2 months agoDOC: management: add a paragraph about the limitations of the '@' prefix
Willy Tarreau [Tue, 8 Apr 2025 09:36:59 +0000 (11:36 +0200)] 
DOC: management: add a paragraph about the limitations of the '@' prefix

The '@' prefix permits to execute a single command at once in a worker.
It is very handy but comes with some limitations affecting rare commands,
which is better to be documented (one command per session, input closed)
since it can seldom have user-visible effects.

2 months agoDOC: management: slightly clarify the prefix role of the '@' command
Willy Tarreau [Tue, 8 Apr 2025 09:26:33 +0000 (11:26 +0200)] 
DOC: management: slightly clarify the prefix role of the '@' command

While the examples were clear, the text did not fully imply what was
reflected there. Better have the text explicitly mention that the
'@' command may be used as a prefix or wrapper in front of a command
as well as a standalone command.

2 months agoCI: enable weekly QuicTLS build
Ilya Shipitsin [Fri, 4 Apr 2025 21:24:30 +0000 (23:24 +0200)] 
CI: enable weekly QuicTLS build

QuicTLS started own fork not dependant on OpenSSL, lets add
that to weekly builds

ML: https://www.mail-archive.com/haproxy@formilux.org/msg45574.html
GH: https://github.com/quictls/quictls/issues/244

2 months ago[RELEASE] Released version 3.2-dev10 v3.2-dev10
Willy Tarreau [Fri, 11 Apr 2025 08:04:00 +0000 (10:04 +0200)] 
[RELEASE] Released version 3.2-dev10

Released version 3.2-dev10 with the following main changes :
    - REORG: ssl: move curves2nid and nid2nist to ssl_utils
    - BUG/MEDIUM: stream: Fix a possible freeze during a forced shut on a stream
    - MEDIUM: stream: Save SC and channel flags earlier in process_steam()
    - BUG/MINOR: peers: fix expire learned from a peer not converted from ms to ticks
    - BUG/MEDIUM: peers: prevent learning expiration too far in futur from unsync node
    - CI: spell check: allow manual trigger
    - CI: codespell: add "pres" to spellcheck whitelist
    - CLEANUP: assorted typo fixes in the code, commits and doc
    - CLEANUP: atomics: remove support for gcc < 4.7
    - CLEANUP: atomics: also replace __sync_synchronize() with __atomic_thread_fence()
    - TESTS: Fix build for filltab25.c
    - MEDIUM: ssl: replace "crt" lines by "ssl-f-use" lines
    - DOC: configuration: replace "crt" by "ssl-f-use" in listeners
    - MINOR: backend: mark srv as nonnull in alloc_dst_address()
    - BUG/MINOR: server: ensure check-reuse-pool is copied from default-server
    - MINOR: server: activate automatically check reuse for rhttp@ protocol
    - MINOR: check/backend: support conn reuse with SNI
    - MINOR: check: implement check-pool-conn-name srv keyword
    - MINOR: task: add thread safe notification_new and notification_wake variants
    - BUG/MINOR: hlua_fcn: fix potential UAF with Queue:pop_wait()
    - MINOR: hlua_fcn: register queue class using hlua_register_metatable()
    - MINOR: hlua: add core.wait()
    - MINOR: hlua: core.wait() takes optional delay paramater
    - MINOR: hlua: split hlua_applet_tcp_recv_yield() in two functions
    - MINOR: hlua: add AppletTCP:try_receive()
    - MINOR: hlua_fcn: add Queue:alarm()
    - MEDIUM: task: make notification_* API thread safe by default
    - CLEANUP: log: adjust _lf_cbor_encode_byte() comment
    - MEDIUM: ssl/crt-list: warn on negative wildcard filters
    - MEDIUM: ssl/crt-list: warn on negative filters only
    - BUILD: atomics: fix build issue on non-x86/non-arm systems
    - BUG/MINOR: log: fix CBOR encoding with LOG_VARTEXT_START() + lf_encode_chunk()
    - BUG/MEDIUM: sample: fix risk of overflow when replacing multiple regex back-refs
    - DOC: configuration: rework the crt-list section
    - MINOR: ring: support arbitrary delimiters through ring_dispatch_messages()
    - MINOR: ring/cli: support delimiting events with a trailing \0 on "show events"
    - DEV: h2: fix h2-tracer.lua nil value index
    - BUG/MINOR: backend: do not use the source port when hashing clientip
    - BUG/MINOR: hlua: fix invalid errmsg use in hlua_init()
    - MINOR: proxy: add setup_new_proxy() function
    - MINOR: checks: mark CHECKS-FE dummy frontend as internal
    - MINOR: flt_spoe: mark spoe agent frontend as internal
    - MEDIUM: tree-wide: avoid manually initializing proxies
    - MINOR: proxy: add deinit_proxy() helper func
    - MINOR: checks: deinit checks_fe upon deinit
    - MINOR: flt_spoe: deinit spoe agent proxy upon agent release

2 months agoMINOR: flt_spoe: deinit spoe agent proxy upon agent release
Aurelien DARRAGON [Thu, 10 Apr 2025 14:57:58 +0000 (16:57 +0200)] 
MINOR: flt_spoe: deinit spoe agent proxy upon agent release

Even though spoe agent proxy is statically allocated, it uses the proxy
API and is initialized like a regular proxy, thus specific cleanup is
required upon release. This is not tagged as a bug because as of now this
would only cause some minor memory leak upon deinit.

We check the presence of proxy->id to know if it was initialized since
we cannot rely on a pointer for that.

2 months agoMINOR: checks: deinit checks_fe upon deinit
Aurelien DARRAGON [Thu, 10 Apr 2025 14:24:57 +0000 (16:24 +0200)] 
MINOR: checks: deinit checks_fe upon deinit

This is just to make valgrind and friends happy, leverage deinit_proxy()
for checks_fe proxy upon deinit to ensure proper cleanup.

We check the presence of proxy->id to know if it was initialized because
we cannot rely on a pointer for that.

2 months agoMINOR: proxy: add deinit_proxy() helper func
Aurelien DARRAGON [Thu, 10 Apr 2025 08:37:33 +0000 (10:37 +0200)] 
MINOR: proxy: add deinit_proxy() helper func

Same as free_proxy(), but does not free the base proxy pointer (ie: the
proxy itself may not be allocated)

Goal is to be able to cleanup statically allocated dummy proxies.

2 months agoMEDIUM: tree-wide: avoid manually initializing proxies
Aurelien DARRAGON [Wed, 9 Apr 2025 19:57:39 +0000 (21:57 +0200)] 
MEDIUM: tree-wide: avoid manually initializing proxies

In this patch we try to use the proxy API init functions as much as
possible to avoid code redundancy and prevent proxy initialization
errors. As such, we prefer using alloc_new_proxy() and setup_new_proxy()
instead of manually allocating the proxy pointer and performing the
base init ourselves.

2 months agoMINOR: flt_spoe: mark spoe agent frontend as internal
Aurelien DARRAGON [Thu, 10 Apr 2025 15:07:54 +0000 (17:07 +0200)] 
MINOR: flt_spoe: mark spoe agent frontend as internal

spoe agent frontend is used by the agent internally, but it is not meant
to be directly exposed like user-facing proxies defined in the config.

As such, better mark it as internal using PR_CAP_INT capability to prevent
any mis-use.

2 months agoMINOR: checks: mark CHECKS-FE dummy frontend as internal
Aurelien DARRAGON [Wed, 9 Apr 2025 19:40:44 +0000 (21:40 +0200)] 
MINOR: checks: mark CHECKS-FE dummy frontend as internal

CHECKS-FE frontend is a dummy frontend used to create checks sessions
as such, it is internal and should not be exposed to the user.
Better mark it as internal using PR_CAP_INT capability to prevent
proxy API from ever exposing it.

2 months agoMINOR: proxy: add setup_new_proxy() function
Aurelien DARRAGON [Wed, 9 Apr 2025 19:05:35 +0000 (21:05 +0200)] 
MINOR: proxy: add setup_new_proxy() function

Split alloc_new_proxy() in two functions: the preparing part is now
handled by setup_new_proxy() which can be called individually, while
alloc_new_proxy() takes care of allocating a new proxy struct and then
calling setup_new_proxy() with the freshly allocated proxy.

2 months agoBUG/MINOR: hlua: fix invalid errmsg use in hlua_init()
Aurelien DARRAGON [Thu, 10 Apr 2025 15:35:53 +0000 (17:35 +0200)] 
BUG/MINOR: hlua: fix invalid errmsg use in hlua_init()

errmsg is used with memprintf and friends, thus it must be NULL
initialized before being passed to memprintf, else invalid read will
occur.

However in hlua_init() the errmsg value isn't initialized, let's fix that

This is really minor because it would only cause issue on error paths,
yet it may be backported to all stable versions, just in case.

2 months agoBUG/MINOR: backend: do not use the source port when hashing clientip
Willy Tarreau [Wed, 9 Apr 2025 08:57:54 +0000 (10:57 +0200)] 
BUG/MINOR: backend: do not use the source port when hashing clientip

The server's "usesrc" keyword supports among other options "client"
and "clientip". The former means we bind to the client's IP and port
to connect to the server, while the latter means we bind to its IP
only. It's done in two steps, first alloc_bind_address() retrieves
the IP address and port, and second, tcp_connect_server() decides
to either bind to the IP only or IP+port.

The problem comes with idle connection pools, which hash all the
parameters: the hash is calculated before (and ideally withouy) calling
tcp_connect_server(), and it considers the whole struct sockaddr_storage
for the hash, except that both client and clientip entirely fill it with
the client's address. This means that both client and clientip make use
of the source port in the hash calculation, making idle connections
almost not reusable when using "usesrc clientip" while they should for
clients coming from the same source. A work-around is to force the
source port to zero using "tcp-request session set-src-port int(0)" but
it's ugly.

Let's fix this by properly zeroing the port for AF_INET/AF_INET6 addresses.

This can be backported to 2.4. Thanks to Sebastien Gross for providing a
reproducer for this problem.

2 months agoDEV: h2: fix h2-tracer.lua nil value index
Aurelien DARRAGON [Tue, 8 Apr 2025 15:36:49 +0000 (17:36 +0200)] 
DEV: h2: fix h2-tracer.lua nil value index

Nick Ramirez reported the following error while testing the h2-tracer.lua
script:

  Lua filter 'h2-tracer' : [state-id 0] runtime error: /etc/haproxy/h2-tracer.lua:227: attempt to index a nil value (field '?') from /etc/haproxy/h2-tracer.lua:227: in function line 109.

It is caused by h2ff indexing with an out of bound value. Indeed, h2ff
is indexed with the frame type, which can potentially be > 9 (not common
nor observed during Willy's tests), while h2ff only defines indexes from
0 to 9.

The fix was provided by Willy, it consists in skipping h2ff indexing if
frame type is > 9. It was confirmed that doing so fixes the error.

2 months agoMINOR: ring/cli: support delimiting events with a trailing \0 on "show events"
Willy Tarreau [Mon, 31 Mar 2025 16:26:26 +0000 (18:26 +0200)] 
MINOR: ring/cli: support delimiting events with a trailing \0 on "show events"

At the moment it is not supported to produce multi-line events on the
"show events" output, simply because the LF character is used as the
default end-of-event mark. However it could be convenient to produce
well-formatted multi-line events, e.g. in JSON or other formats. UNIX
utilities have already faced similar needs in the past and added
"-print0" to "find" and "-0" to "xargs" to mention that the delimiter
is the NUL character. This makes perfect sense since it's never present
in contents, so let's do exactly the same here.

Thus from now on, "show events <ring> -0" will delimit messages using
a \0 instead of a \n, permitting a better and safer encapsulation.

2 months agoMINOR: ring: support arbitrary delimiters through ring_dispatch_messages()
Willy Tarreau [Mon, 31 Mar 2025 16:17:35 +0000 (18:17 +0200)] 
MINOR: ring: support arbitrary delimiters through ring_dispatch_messages()

In order to support delimiting output events with other characters than
just the LF, let's pass the delimiter through the API. The default remains
the LF, used by applet_append_line(), and ignored by the log forwarder.

2 months agoDOC: configuration: rework the crt-list section
William Lallemand [Mon, 7 Apr 2025 17:11:11 +0000 (19:11 +0200)] 
DOC: configuration: rework the crt-list section

The crt-list section was unclear, this patch reworks it, giving more
details on the matching algorithms and how the things are loaded.

3 months agoBUG/MEDIUM: sample: fix risk of overflow when replacing multiple regex back-refs
Willy Tarreau [Mon, 7 Apr 2025 13:30:43 +0000 (15:30 +0200)] 
BUG/MEDIUM: sample: fix risk of overflow when replacing multiple regex back-refs

Aleandro Prudenzano of Doyensec and Edoardo Geraci of Codean Labs
reported a bug in sample_conv_regsub(), which can cause replacements
of multiple back-references to overflow the temporary trash buffer.

The problem happens when doing "regsub(match,replacement,g)": we're
replacing every occurrence of "match" with "replacement" in the input
sample, which requires a length check. For this, a max is applied, so
that a replacement may not use more than the remaining length in the
buffer. However, the length check is made on the replaced pattern and
not on the temporary buffer used to carry the new string. This results
in the remaining size to be usable for each input match, which can go
beyond the temporary buffer size if more than one occurrence has to be
replaced with something that's larger than the remaining room.

The fix proposed by Aleandro and Edoardo is the correct one (check on
"trash" not "output"), and is the one implemented in this patch.

While it is very unlikely that a config will replace multiple short
patterns each with a larger one in a request, this possibility cannot
be entirely ruled out (e.g. mask a known, short IP address using
"XXX.XXX.XXX.XXX").  However when this happens, the replacement pattern
will be static, and not be user-controlled, which is why this patch is
marked as medium.

The bug was introduced in 2.2 with commit 07e1e3c93e ("MINOR: sample:
regsub now supports backreferences"), so it must be backported to all
versions.

Special thanks go to Aleandro and Edoardo for reporting this bug with
a simple reproducer and a fix.

3 months agoBUG/MINOR: log: fix CBOR encoding with LOG_VARTEXT_START() + lf_encode_chunk()
Aurelien DARRAGON [Mon, 7 Apr 2025 10:00:03 +0000 (12:00 +0200)] 
BUG/MINOR: log: fix CBOR encoding with LOG_VARTEXT_START() + lf_encode_chunk()

There have been some reports that using %HV logformat alias with CBOR
encoder would produce invalid CBOR payload according to some CBOR
implementations such as "cbor.me". Indeed, with the below log-format:

  log-format "%{+cbor}o %(protocol)HV"

And the resulting CBOR payload:

  BF6870726F746F636F6C7F48485454502F312E31FFFF

cbor.me would complain with: "bytes/text mismatch (ASCII-8BIT != UTF-8) in
streaming string") error message.

It is due to the version string being first announced as text, while CBOR
encoder actually encodes it as byte string later when lf_encode_chunk()
is used.

In fact it affects all patterns combining LOG_VARTEXT_START() with
lf_encode_chunk() which means  %HM, %HU, %HQ, %HPO and %HP are also
affected. To fix the issue, in _lf_encode_bytes() (which is
lf_encode_chunk() helper), we now check if we are inside a VARTEXT (we
can tell it if ctx->in_text is true), in which case we consider that we
already announced the current data as regular text so we keep the same
type to encode the bytes from the chunk to prevent inconsistencies.

It should be backported in 3.0

3 months agoBUILD: atomics: fix build issue on non-x86/non-arm systems
Willy Tarreau [Mon, 7 Apr 2025 07:36:16 +0000 (09:36 +0200)] 
BUILD: atomics: fix build issue on non-x86/non-arm systems

Commit f435a2e518 ("CLEANUP: atomics: also replace __sync_synchronize()
with __atomic_thread_fence()") replaced the builtins used for barriers,
but the different API required an argument while the macros didn't specify
any, resulting in double parenthesis that were causing obscure build errors
such as "called object type 'void' is not a function or function pointer".
Let's just specify the args for the macro. No backport is needed.

3 months agoMEDIUM: ssl/crt-list: warn on negative filters only
William Lallemand [Fri, 4 Apr 2025 16:00:46 +0000 (18:00 +0200)] 
MEDIUM: ssl/crt-list: warn on negative filters only

negative SNI filters on crt-list lines only have a meaning when they
match a positive wildcard filter. This patch adds a warning which
is emitted when trying to use negative filters without any wildcard on
the same line.

This was discovered in ticket #2900.

3 months agoMEDIUM: ssl/crt-list: warn on negative wildcard filters
William Lallemand [Fri, 4 Apr 2025 15:13:51 +0000 (17:13 +0200)] 
MEDIUM: ssl/crt-list: warn on negative wildcard filters

negative wildcard filters were always a noop, and are not useful for
anything unless you want to use !* alone to remove every name from a
certificate.

This is confusing and the documentation never stated it correctly. This
patch adds a warning during the bind initialization if it founds one,
only !* does not emit a warning.

This patch was done during the debugging of issue #2900.

3 months agoCLEANUP: log: adjust _lf_cbor_encode_byte() comment
Aurelien DARRAGON [Tue, 1 Apr 2025 17:32:58 +0000 (19:32 +0200)] 
CLEANUP: log: adjust _lf_cbor_encode_byte() comment

_lf_cbor_encode_byte() comment was not updated in c33b857df ("MINOR: log:
support true cbor binary encoding") to reflect the new behavior.

Indeed, binary form is now supported. Updating the comment that says
otherwise.

3 months agoMEDIUM: task: make notification_* API thread safe by default
Aurelien DARRAGON [Tue, 1 Apr 2025 14:07:39 +0000 (16:07 +0200)] 
MEDIUM: task: make notification_* API thread safe by default

Some notification_* functions were not thread safe by default as they
assumed only one producer would emit events for registered tasks.

While this suited well with the Lua sockets use-case, this proved to
be a limitation with some other event sources (ie: lua Queue class)

instead of having to deal with both the non thread safe and thread
safe variants (_mt suffix), which is error prone, let's make the
entire API thread safe regarding the event list.

Pruning functions still require that only one thread executes them,
with Lua this is always the case because there is one cleanup list
per context.

3 months agoMINOR: hlua_fcn: add Queue:alarm()
Aurelien DARRAGON [Tue, 1 Apr 2025 08:37:08 +0000 (10:37 +0200)] 
MINOR: hlua_fcn: add Queue:alarm()

Queue:alarm() sets a wakeup alarm on the task when new data becomes
available on Queue. It must be re-armed for each event.

Lua documentation was updated

3 months agoMINOR: hlua: add AppletTCP:try_receive()
Aurelien DARRAGON [Mon, 31 Mar 2025 11:55:35 +0000 (13:55 +0200)] 
MINOR: hlua: add AppletTCP:try_receive()

This is the non-blocking variant for AppletTCP:receive(). It doesn't
take any argument, instead it tries to read as much data as available
at once. If no data is available, empty string is returned.

Lua documentation was updated.

3 months agoMINOR: hlua: split hlua_applet_tcp_recv_yield() in two functions
Aurelien DARRAGON [Fri, 21 Mar 2025 09:33:11 +0000 (10:33 +0100)] 
MINOR: hlua: split hlua_applet_tcp_recv_yield() in two functions

Split hlua_applet_tcp_recv_yield() in order to create
hlua_applet_tcp_recv_try() helper function which does a single receive
attempt.

3 months agoMINOR: hlua: core.wait() takes optional delay paramater
Aurelien DARRAGON [Tue, 1 Apr 2025 13:22:29 +0000 (15:22 +0200)] 
MINOR: hlua: core.wait() takes optional delay paramater

core.wait() now accepts optional delay parameter in ms. Passed this delay
the task is woken up if no event woke the task before.

Lua documentation was updated.

3 months agoMINOR: hlua: add core.wait()
Aurelien DARRAGON [Fri, 21 Mar 2025 08:37:38 +0000 (09:37 +0100)] 
MINOR: hlua: add core.wait()

Similar to core.yield(), except that the task is not woken up
automatically, instead it waits for events to trigger the task
wakeup.

Lua documentation was updated.

3 months agoMINOR: hlua_fcn: register queue class using hlua_register_metatable()
Aurelien DARRAGON [Fri, 21 Mar 2025 22:00:59 +0000 (23:00 +0100)] 
MINOR: hlua_fcn: register queue class using hlua_register_metatable()

Most lua classes are registered by leveraging the
hlua_register_metatable() helper. Let's use that for the Queue class as
well for consitency.

3 months agoBUG/MINOR: hlua_fcn: fix potential UAF with Queue:pop_wait()
Aurelien DARRAGON [Tue, 1 Apr 2025 09:01:45 +0000 (11:01 +0200)] 
BUG/MINOR: hlua_fcn: fix potential UAF with Queue:pop_wait()

If Queue:pop_wait() excecuted from a stream context and pop_wait() is
aborted due to a Lua or ressource error, then the waiting object pointing
to the task will still be registered, so if the task eventually dissapears,
Queue:push() may try to wake invalid task pointer..

To prevent this bug from happening, we now rely on notification_* API to
deliver waiting signals. This way signals are properly garbage collected
when a lua context is destroyed.

It should be backported in 2.8 with 86fb22c55 ("MINOR: hlua_fcn: add Queue
class").
This patch depends on ("MINOR: task: add thread safe notification_new and
notification_wake variants")

3 months agoMINOR: task: add thread safe notification_new and notification_wake variants
Aurelien DARRAGON [Tue, 1 Apr 2025 08:07:50 +0000 (10:07 +0200)] 
MINOR: task: add thread safe notification_new and notification_wake variants

notification_new and notification_wake were historically meant to be
called by a single thread doing both the init and the wakeup for other
tasks waiting on the signals.

In this patch, we extend the API so that notification_new and
notification_wake have thread-safe variants that can safely be used with
multiple threads registering on the same list of events and multiple
threads pushing updates on the list.

3 months agoMINOR: check: implement check-pool-conn-name srv keyword
Amaury Denoyelle [Thu, 3 Apr 2025 13:58:49 +0000 (15:58 +0200)] 
MINOR: check: implement check-pool-conn-name srv keyword

This commit is a direct follow-up of the previous one. It defines a new
server keyword check-pool-conn-name. It is used as the default value for
the name parameter of idle connection hash generation.

Its behavior is similar to server keyword pool-conn-name, but reserved
for checks reuse. If check-pool-conn-name is set, it is used in priority
to match a connection for reuse. If unset, a fallback is performed on
check-sni.

3 months agoMINOR: check/backend: support conn reuse with SNI
Amaury Denoyelle [Wed, 2 Apr 2025 15:48:23 +0000 (17:48 +0200)] 
MINOR: check/backend: support conn reuse with SNI

Support for connection reuse during server checks was implemented
recently. This is activated with the server keyword check-reuse-pool.

Similarly to stream processing via connect_backend(), a connection hash
is calculated when trying to perform reuse for checks. This is necessary
to retrieve for a connection which shares the check connect parameters.
However, idle connections can additionnally be tagged using a
pool-conn-name or SNI under connect_backend(). Check reuse does not test
these values, which prevent to retrieve a matching connection.

Improve this by using "check-sni" value as idle connection hash input
for check reuse. be_calculate_conn_hash() API has been adjusted so that
name value can be passed as input, both when using streams or checks.

Even with the current patch, there is still some scenarii which could
not be covered for checks connection reuse. most notably, when using
dynamic pool-conn-name/SNI value. It is however at least sufficient to
cover simpler cases.

3 months agoMINOR: server: activate automatically check reuse for rhttp@ protocol
Amaury Denoyelle [Wed, 2 Apr 2025 16:30:46 +0000 (18:30 +0200)] 
MINOR: server: activate automatically check reuse for rhttp@ protocol

Without check-reuse-pool, it is impossible to perform check on server
using @rhttp protocol. This is due to the inherent nature of the
protocol which does not implement an active connect method.

Thus, ensure that check-reuse-pool is always set when a reverse HTTP
server is declared. This reduces server configuration and should prevent
any omission. Note that it is still require to add "check" server
keyword so activate server checks.

3 months agoBUG/MINOR: server: ensure check-reuse-pool is copied from default-server
Amaury Denoyelle [Wed, 2 Apr 2025 16:31:49 +0000 (18:31 +0200)] 
BUG/MINOR: server: ensure check-reuse-pool is copied from default-server

Duplicate server check.reuse_pool boolean value in srv_settings_cpy().
This is necessary to ensure that check-reuse-pool value can be set via
default-server or server-template.

This does not need to be backported.

3 months agoMINOR: backend: mark srv as nonnull in alloc_dst_address()
Amaury Denoyelle [Thu, 3 Apr 2025 13:17:53 +0000 (15:17 +0200)] 
MINOR: backend: mark srv as nonnull in alloc_dst_address()

Server instance can be NULL on connect_server(), either when dispatch or
transparent proxy are active. However, in alloc_dst_address() access to
<srv> is safe thanks to SF_ASSIGNED stream flag. Add an ASSUME_NONNULL()
to reflect this state.

This should fix coverity report from github issue #2922.

3 months agoDOC: configuration: replace "crt" by "ssl-f-use" in listeners
William Lallemand [Thu, 3 Apr 2025 14:03:18 +0000 (16:03 +0200)] 
DOC: configuration: replace "crt" by "ssl-f-use" in listeners

Replace the "crt" keyword from the frontend section with a "ssl-f-use"
keyword, "crt" could be ambigous in case we don't want to put a
certificate filename.

3 months agoMEDIUM: ssl: replace "crt" lines by "ssl-f-use" lines
William Lallemand [Thu, 3 Apr 2025 14:12:49 +0000 (16:12 +0200)] 
MEDIUM: ssl: replace "crt" lines by "ssl-f-use" lines

The new "crt" lines in frontend and listen sections are confusing:

- a filename is mandatory but we could need a syntax without the
  filename in the future, if the filename is generated for example
- there is no clue about the fact that its only used on the frontend
  side when reading the line

A new "ssl-f-use" line replaces the "crt" line, but a "crt" keyword
can be used on this line. "f" indicates that this is the frontend
configuration, a "ssl-b-use" keyword could be used in the future.

The "crt" lines only appeared in 3.2-dev so this won't change anything
for people using configurations from previous major versions.

3 months agoTESTS: Fix build for filltab25.c
Olivier Houchard [Thu, 3 Apr 2025 14:20:11 +0000 (16:20 +0200)] 
TESTS: Fix build for filltab25.c

Give a return type to main(), so that filltab25.c compiles with
modern compilers.

3 months agoCLEANUP: atomics: also replace __sync_synchronize() with __atomic_thread_fence()
Willy Tarreau [Thu, 3 Apr 2025 09:59:31 +0000 (11:59 +0200)] 
CLEANUP: atomics: also replace __sync_synchronize() with __atomic_thread_fence()

The drop of older compilers also allows us to focus on clearer
barriers, so let's use them.

3 months agoCLEANUP: atomics: remove support for gcc < 4.7
Willy Tarreau [Thu, 3 Apr 2025 09:53:44 +0000 (11:53 +0200)] 
CLEANUP: atomics: remove support for gcc < 4.7

The old __sync_* API is no longer necessary since we do not support
gcc before 4.7 anymore. Let's just get rid of this code, the file is
still ugly enough without it.

3 months agoCLEANUP: assorted typo fixes in the code, commits and doc
Ilia Shipitsin [Wed, 2 Apr 2025 18:44:22 +0000 (20:44 +0200)] 
CLEANUP: assorted typo fixes in the code, commits and doc

3 months agoCI: codespell: add "pres" to spellcheck whitelist
Ilia Shipitsin [Wed, 2 Apr 2025 18:44:21 +0000 (20:44 +0200)] 
CI: codespell: add "pres" to spellcheck whitelist

spellcheck was triggered by the following:

  * pres  : same as "res" but using the parent stream, if any. "pres"
            variables are only accessible during response processing of the
            parent stream.

3 months agoCI: spell check: allow manual trigger
Ilia Shipitsin [Wed, 2 Apr 2025 18:44:20 +0000 (20:44 +0200)] 
CI: spell check: allow manual trigger

3 months agoBUG/MEDIUM: peers: prevent learning expiration too far in futur from unsync node
Emeric Brun [Thu, 3 Apr 2025 08:32:30 +0000 (10:32 +0200)] 
BUG/MEDIUM: peers: prevent learning expiration too far in futur from unsync node

This patch sets the expire of the entry to the max value in
configuration if the value showed in the peer update message
is too far in futur.

This should be backported an all supported branches.

3 months agoBUG/MINOR: peers: fix expire learned from a peer not converted from ms to ticks
Emeric Brun [Thu, 3 Apr 2025 08:29:16 +0000 (10:29 +0200)] 
BUG/MINOR: peers: fix expire learned from a peer not converted from ms to ticks

This is has now impact currently since MS_TO_TICKS macro does nothing
but it will prevent further bugs.

3 months agoMEDIUM: stream: Save SC and channel flags earlier in process_steam()
Christopher Faulet [Mon, 17 Mar 2025 15:07:21 +0000 (16:07 +0100)] 
MEDIUM: stream: Save SC and channel flags earlier in process_steam()

At the begining of process_stream(), the flags of the stream connectors and
channels are saved to be able to handle changes performed in sub-functions
(for instance in analyzers). But, some operations were performed before
saving these flags: Synchronous receives and forced shutdowns. While it
seems to safe for now, it is a bit annoying because some events could be
missed.

So, to avoid bugs in the future, the channels and stream connectors flags
are now really saved before any other processing.

3 months agoBUG/MEDIUM: stream: Fix a possible freeze during a forced shut on a stream
Christopher Faulet [Mon, 17 Mar 2025 13:49:45 +0000 (14:49 +0100)] 
BUG/MEDIUM: stream: Fix a possible freeze during a forced shut on a stream

When a forced shutdown is performed on a stream, it is possible to freeze it
infinitly because it is performed in an unexpected way from process_stream()
point of view, especially when the stream is waiting for a server
connection. The events sequence is a bit complex but at the end the stream
remains blocked in turn-around state and no event are trriggered to unblock
it.

By trying to fix the issue, we considered it was safer to rethink the
feature. The idea is to quickly shutdown a stream to release resources. For
instance to be able to delete a server. So, instead of scheduling a
shutdown, it is more efficient to trigger an error and detach the stream
from the server, if neecessary. The same code than the one used to deal with
connection errors in back_handle_st_cer() is used.

This patch must be slowly backported as far as 2.6.

3 months agoREORG: ssl: move curves2nid and nid2nist to ssl_utils
William Lallemand [Wed, 2 Apr 2025 17:34:09 +0000 (19:34 +0200)] 
REORG: ssl: move curves2nid and nid2nist to ssl_utils

curves2nid and nid2nist are generic functions that could be used outside
the JWS scope, this patch put them at the right place so they can be
reused.

3 months ago[RELEASE] Released version 3.2-dev9 v3.2-dev9
Willy Tarreau [Wed, 2 Apr 2025 16:12:34 +0000 (18:12 +0200)] 
[RELEASE] Released version 3.2-dev9

Released version 3.2-dev9 with the following main changes :
    - MINOR: quic: move global tune options into quic_tune
    - CLEANUP: quic: reorganize TP flow-control initialization
    - MINOR: quic: ignore uni-stream for initial max data TP
    - MINOR: mux-quic: define config for max-data
    - MINOR: quic: define max-stream-data configuration as a ratio
    - MEDIUM: lb-chash: add directive hash-preserve-affinity
    - MEDIUM: pools: be a bit smarter when merging comparable size pools
    - REGTESTS: disable the test balance/balance-hash-maxqueue
    - BUG/MINOR: log: fix gcc warn about truncating NUL terminator while init char arrays
    - CI: fedora rawhide: allow "on: workflow_dispatch" in forks
    - CI: fedora rawhide: install "awk" as a dependency
    - CI: spellcheck: allow "on: workflow_dispatch" in forks
    - CI: coverity scan: allow "on: workflow_dispatch" in forks
    - CI: cross compile: allow "on: workflow_dispatch" in forks
    - CI: Illumos: allow "on: workflow_dispatch" in forks
    - CI: NetBSD: allow "on: workflow_dispatch" in forks
    - CI: QUIC Interop on AWS-LC: allow "on: workflow_dispatch" in forks
    - CI: QUIC Interop on LibreSSL: allow "on: workflow_dispatch" in forks
    - MINOR: compiler: add __nonstring macro
    - MINOR: thread: dump the CPU topology in thread_map_to_groups()
    - MINOR: cpu-set: compare two cpu sets with ha_cpuset_isequal()
    - MINOR: cpu-set: add a new function to print cpu-sets in human-friendly mode
    - MINOR: cpu-topo: add a dump of thread-to-CPU mapping to -dc
    - MINOR: cpu-topo: pass an extra argument to ha_cpu_policy
    - MINOR: cpu-topo: add new cpu-policies "group-by-2-clusters" and above
    - BUG/MINOR: config: silence .notice/.warning/.alert in discovery mode
    - EXAMPLES: add "games.cfg" and an example game in Lua
    - MINOR: jws: emit the JWK thumbprint
    - TESTS: jws: change the jwk format
    - MINOR: ssl/ckch: add substring parser for ckch_conf
    - MINOR: mt_list: Implement mt_list_try_lock_prev().
    - MINOR: lbprm: Add method to deinit server and proxy
    - MINOR: threads: Add HA_RWLOCK_TRYRDTOWR()
    - MAJOR: leastconn; Revamp the way servers are ordered.
    - BUG/MINOR: ssl/ckch: leak in error path
    - BUILD: ssl/ckch: potential null pointer dereference
    - MINOR: log: support "raw" logformat node typecast
    - CLEANUP: assorted typo fixes in the code and comments
    - DOC: config: fix two missing "content" in "tcp-request" examples
    - MINOR: cpu-topo: cpu_dump_topology() SMT info check little optimisation
    - BUILD: compiler: undefine the CONCAT() macro if already defined
    - BUG/MEDIUM: leastconn: Don't try to reposition if the server is down
    - BUG/MINOR: rhttp: fix incorrect dst/dst_port values
    - BUG/MINOR: backend: do not overwrite srv dst address on reuse
    - BUG/MEDIUM: backend: fix reuse with set-dst/set-dst-port
    - MINOR: sample: define bc_reused fetch
    - REGTESTS: extend conn reuse test with transparent proxy
    - MINOR: backend: fix comment when killing idle conns
    - MINOR: backend: adjust conn_backend_get() API
    - MINOR: backend: extract conn hash calculation from connect_server()
    - MINOR: backend: extract conn reuse from connect_server()
    - MINOR: backend: remove stream usage on connection reuse
    - MINOR: check define check-reuse-pool server keyword
    - MEDIUM: check: implement check-reuse-pool
    - BUILD: backend: silence a build warning when not using ssl
    - BUILD: quic_sock: address a strict-aliasing build warning with gcc 5 and 6
    - BUILD: ssl_ckch: use my_strndup() instead of strndup()
    - DOC: update INSTALL to reflect the minimum compiler version

3 months agoDOC: update INSTALL to reflect the minimum compiler version
Willy Tarreau [Wed, 2 Apr 2025 16:05:36 +0000 (18:05 +0200)] 
DOC: update INSTALL to reflect the minimum compiler version

The mt_list update in 3.1 mandated the support for c11-like atomics that
arrived with gcc-4.7. As such, older versions are no longer supported.
For special cases in single-threaded environments, mt_lists could be
replaced with regular lists but it doesn't seem worth the hassle. It
was verified that gcc 4.7 to 14 and clang 3.0 and 19 do build fine.
That leaves us with 10 years of coverage of compiler versions, which
remains reasonable assuming that users of old ultra-stable systems are
unlikely to upgrade haproxy without touching the rest of the system.

This should be backported to 3.1.

3 months agoBUILD: ssl_ckch: use my_strndup() instead of strndup()
Willy Tarreau [Wed, 2 Apr 2025 15:18:23 +0000 (17:18 +0200)] 
BUILD: ssl_ckch: use my_strndup() instead of strndup()

Not all systems have strndup(), that's why we have our "my_strndup()",
so let's make use of it here. This fixes the build on Solaris 10.
No backport is needed, this was just merged with commit fdcb97614c
("MINOR: ssl/ckch: add substring parser for ckch_conf").

3 months agoBUILD: quic_sock: address a strict-aliasing build warning with gcc 5 and 6
Willy Tarreau [Wed, 2 Apr 2025 14:07:31 +0000 (16:07 +0200)] 
BUILD: quic_sock: address a strict-aliasing build warning with gcc 5 and 6

The UDP GSO code emits a build warning with older toolchains (gcc 5 and 6):

  src/quic_sock.c: In function 'cmsg_set_gso':
  src/quic_sock.c:683:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
    *((uint16_t *)CMSG_DATA(c)) = gso_size;
    ^

Let's just use the write_u16() function that's made for this purpose.
It was verified that for all versions from 5 to 13, gcc produces the
exact same code with the fix (and without the warning). It arrived in
3.1 with commit 448d3d388a ("MINOR: quic: add GSO parameter on quic_sock
send API") so this can be backported there.

3 months agoBUILD: backend: silence a build warning when not using ssl
Willy Tarreau [Wed, 2 Apr 2025 13:25:08 +0000 (15:25 +0200)] 
BUILD: backend: silence a build warning when not using ssl

Since recent commit ee94a6cfc1 ("MINOR: backend: extract conn reuse
from connect_server()") a build warning "set but not used" on the
"reuse" variable is emitted, because indeed the variable is now only
checked when SSL is in use. Let's just mark it as such.

3 months agoMEDIUM: check: implement check-reuse-pool
Amaury Denoyelle [Fri, 28 Mar 2025 16:25:57 +0000 (17:25 +0100)] 
MEDIUM: check: implement check-reuse-pool

Implement the possibility to reuse idle connections when performing
server checks. This is done thanks to the recently introduced functions
be_calculate_conn_hash() and be_reuse_connection().

One side effect of this change is that be_calculate_conn_hash() can now
be called with a NULL stream instance. As such, part of the functions
are adjusted accordingly.

Note that to simplify configuration, connection reuse is not performed
if any specific check connection parameters are defined on the server
line or via the tcp-check connect rule. This is performed via newly
defined tcpcheck_use_nondefault_connect().