]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
16 months agoBUG/MINOR: server: fix first server template not being indexed
Willy Tarreau [Tue, 12 Mar 2024 07:16:16 +0000 (08:16 +0100)] 
BUG/MINOR: server: fix first server template not being indexed

3.0-dev1 introduced a small regression with commit b4db3be86e ("BUG/MINOR:
server: fix server_find_by_name() usage during parsing"). By changing the
way servers are indexed and moving it into the server template loop, the
first one is no longer indexed because the loop starts at low+1 since it
focuses on duplication. Let's index the first one explicitly now.

This should not be backported, unless the commit above is backported.

16 months agoBUG/MINOR: ssl: do not set the aead_tag flags in sample_conv_aes_gcm()
Dragan Dosen [Mon, 11 Mar 2024 17:17:26 +0000 (18:17 +0100)] 
BUG/MINOR: ssl: do not set the aead_tag flags in sample_conv_aes_gcm()

This was not useful and was using uninitialized value. Introduced with
the commit 08ac28237 ("MINOR: Add aes_gcm_enc converter").

Must be backported wherever the commit 08ac28237 was backported.

16 months agoBUG/MINOR: ssl: fix possible ctx memory leak in sample_conv_aes_gcm()
Dragan Dosen [Mon, 11 Mar 2024 17:10:01 +0000 (18:10 +0100)] 
BUG/MINOR: ssl: fix possible ctx memory leak in sample_conv_aes_gcm()

The issue was introduced with the commit c31499d74 ("MINOR: ssl: Add
aes_gcm_dec converter").

This must be backported to all stable branches where the above converter
is present, but it may need to be adjusted for older branches because of
code refactoring.

16 months agoMINOR: tools: use public interface for FreeBSD get_exec_path()
Brooks Davis [Wed, 28 Feb 2024 18:12:40 +0000 (18:12 +0000)] 
MINOR: tools: use public interface for FreeBSD get_exec_path()

Where possible (FreeBSD 13+), use the public, documented interface to
the ELF auxiliary argument vector: elf_aux_info().

__elf_aux_vector is a private interface exported so that the runtime
linker can set its value during process startup and not intended for
public consumption.  In FreeBSD 15 it has been removed from libc and
moved to libsys.

16 months agoDOC: configuration: clarify ciphersuites usage (V2)
William Lallemand [Mon, 11 Mar 2024 14:48:14 +0000 (15:48 +0100)] 
DOC: configuration: clarify ciphersuites usage (V2)

The previous attempt removed the TLSv1.3 version for the
"ciphersuites" keywords. However it looks like the TLSv1.2 support for
SSL_CTX_set_ciphersuites() is a bug, and can have inconsistent behavior.

This patch revert the previous attempt and add explaining about this
problem and clear examples on how to configure TLSv1.2 ciphers + TLSv1.3
ciphersuites.

Revert "DOC: configuration: clarify ciphersuites usage"
This reverts commit e2a44d6c94b08d1bdf6294706c3b64267a13c86f.

This must be backported to all stable branches.

Fixes issue #2459.

16 months agoMINOR: quic: remove qc_treat_rx_crypto_frms()
Amaury Denoyelle [Fri, 8 Mar 2024 16:47:03 +0000 (17:47 +0100)] 
MINOR: quic: remove qc_treat_rx_crypto_frms()

This commit removes qc_treat_rx_crypto_frms(). This function was used in
a single place inside qc_ssl_provide_all_quic_data(). Besides, its
naming was confusing as conceptually it is directly linked to quic_ssl
module instead of quic_rx.

Thus, body of qc_treat_rx_crypto_frms() is inlined directly inside
qc_ssl_provide_all_quic_data(). Also, qc_ssl_provide_quic_data() is now
only used inside quic_ssl to its scope is set to static. Overall, API
for CRYPTO frame handling is now cleaner.

16 months agoMINOR: quic: simplify rescheduling for handshake
Amaury Denoyelle [Fri, 8 Mar 2024 16:40:16 +0000 (17:40 +0100)] 
MINOR: quic: simplify rescheduling for handshake

On CRYPTO frames reception, tasklet is rescheduled with TASK_HEAVY to
limit CPU consumption. This commit slighly simplifies this by regrouping
TASK_HEAVY setting and tasklet_wakeup() instructions in a single
location in qc_handle_crypto_frm(). All other unnecessary
tasklet_wakeup() are removed.

16 months agoMEDIUM: mux-h2: allow to set the glitches threshold to kill a connection
Willy Tarreau [Mon, 11 Mar 2024 06:33:44 +0000 (07:33 +0100)] 
MEDIUM: mux-h2: allow to set the glitches threshold to kill a connection

Till now it was still needed to write rules to eliminate bad behaving
H2 clients, while most of the time it would be desirable to just be able
to set a threshold on the level of anomalies on a connection.

This is what this patch does. By setting a glitches threshold for frontend
and backend, it allows to automatically turn a connection to the error
state when the threshold is reached so that the connection dies by itself
without having to write possibly complex rules.

One subtlety is that we still have the error state being exclusive to the
parser's state so this requires the h2c_report_glitches() function to return
a status indicating if the threshold was reached or not so that processing
can instantly stop and bypass the state update, otherwise the state could
be turned back to a valid one (e.g. after parsing CONTINUATION); we should
really contemplate the possibility to use H2_CF_ERROR for this. Fortunately
there were very few places where a glitch was reported outside of an error
path so the changes are quite minor.

Now by setting the front value to 1000, a client flooding with short
CONTINUATION frames is instantly stopped.

16 months agoMINOR: mux-h2: always use h2c_report_glitch()
Willy Tarreau [Mon, 11 Mar 2024 06:35:19 +0000 (07:35 +0100)] 
MINOR: mux-h2: always use h2c_report_glitch()

The function aims at centralizing counter measures but due to the fact
that it only increments the counter by one unit, sometimes it was not
used and the value was calculated directly. Let's pass the increment in
argument so that it can be used everywhere.

16 months ago[RELEASE] Released version 3.0-dev5 v3.0-dev5
Willy Tarreau [Sat, 9 Mar 2024 15:50:15 +0000 (16:50 +0100)] 
[RELEASE] Released version 3.0-dev5

Released version 3.0-dev5 with the following main changes :
    - BUG/MEDIUM: applet: Fix HTX .rcv_buf callback function to release outbuf buffer
    - BUG/MAJOR: ssl/ocsp: crash with ocsp when old process exit or using ocsp CLI
    - BUG/MEDIUM: server: fix dynamic servers initial settings
    - BUG/MINOR: ssl/cli: duplicate cleaning code in cli_parse_del_crtlist
    - LICENSE: event_hdl: fix GPL license version
    - LICENSE: http_ext: fix GPL license version
    - BUG/MEDIUM: mux-h1: Fix again 0-copy forwarding of chunks with an unknown size
    - BUG/MINOR: mux-h1: Properly report when mux is blocked during a nego
    - MINOR: mux-h1: Move checks performed before a shutdown in a dedicated function
    - MINOR: mux-h1: Move all stuff to detach a stream in an internal function
    - MAJOR: mux-h1: Drain requests on client side before shut a stream down
    - MEDIUM: htx/http-ana: No longer close connection on early HAProxy response
    - MINOR: quic: filter show quic by address
    - MINOR: quic: specify show quic output fields
    - MINOR: quic: add MUX output for show quic
    - CLEANUP: mux-h2: Fix h2s_make_data() comment about the return value
    - DOC: configuration: clarify ciphersuites usage
    - BUG/MINOR: config/quic: Alert about PROXY protocol use on a QUIC listener
    - BUG/MINOR: hlua: Fix log level to the right value when set via TXN:set_loglevel
    - MINOR: hlua: Be able to disable logging from lua
    - BUG/MINOR: tools: seed the statistical PRNG slightly better
    - BUG/MINOR: hlua: fix unsafe lua_tostring() usage with empty stack
    - BUG/MINOR: hlua: don't use lua_tostring() from unprotected contexts
    - BUG/MINOR: hlua: fix possible crash in hlua_filter_new() under load
    - BUG/MINOR: hlua: improper lock usage in hlua_filter_callback()
    - BUG/MINOR: hlua: improper lock usage in hlua_filter_new()
    - BUG/MEDIUM: hlua: improper lock usage with SET_SAFE_LJMP()
    - BUG/MAJOR: hlua: improper lock usage with hlua_ctx_resume()
    - BUG/MINOR: hlua: don't call ha_alert() in hlua_event_subscribe()
    - MINOR: hlua: use SEND_ERR to report errors in hlua_event_runner()
    - CLEANUP: hlua: txn class functions may LJMP
    - BUG/MINOR: sink: fix a race condition in the TCP log forwarding code
    - BUILD: thread: move lock label definitions to thread-t.h
    - BUILD: tree-wide: fix a few missing includes in a few files
    - BUILD: buf: make b_ncat() take a const for the source
    - CLEANUP: assorted typo fixes in the code and comments
    - CLEANUP: fix typo in naming for variable "unused"
    - CI: run more smoke tests on config syntax to check memory related issues
    - CI: enable monthly build only test on netbsd-9.3
    - CI: skip scheduled builds on forks
    - BUG/MINOR: ssl/cli: typo in new ssl crl-file CLI description
    - BUG/MEDIUM: quic: fix connection freeze on post handshake
    - BUG/MINOR: mux-quic: fix crash on aborting uni remote stream
    - CLEANUP: log: fix obsolete comment for add_sample_to_logformat_list()
    - CLEANUP: tree-wide: use proper ERR_* return values for PRE_CHECK fcts
    - BUG/MINOR: cfgparse: report proper location for log-format-sd errors
    - MINOR: vars: export var_set and var_unset functions
    - MINOR: Add aes_gcm_enc converter
    - BUG/MEDIUM: quic: fix handshake freeze under high traffic
    - MINOR: quic: always use ncbuf for rx CRYPTO
    - BUILD: ssl: define EVP_CTRL_AEAD_GET_TAG for older versions
    - DOC: design: write first notes about ring-v2
    - OPTIM: sink: try to merge "dropped" messages faster
    - OPTIM: sink: drop the sink lock used to count drops
    - DEV: haring: make haring not depend on the struct ring itself
    - DEV: haring: split the code between ring and buffer
    - DEV: haring: automatically use the advertised ring header size
    - BUILD: solaris: fix compilation errors

16 months agoBUILD: solaris: fix compilation errors
matthias sweertvaegher [Fri, 23 Feb 2024 16:05:01 +0000 (17:05 +0100)] 
BUILD: solaris: fix compilation errors

Compilation on solaris fails because of usage of names reserved on that
platform, i.e. 'queue' and 's_addr'.

This patch redefines 'queue' as '_queue' and renames 's_addr' to
'srv_addr' which fixes compilation for now.

Future plan: rename 'queue' in code base so define can be removed again.

Backporting: 2.9, 2.8

16 months agoDEV: haring: automatically use the advertised ring header size
Willy Tarreau [Mon, 4 Mar 2024 18:15:59 +0000 (19:15 +0100)] 
DEV: haring: automatically use the advertised ring header size

Instead of emitting a warning, since we don't need the ring struct
anymore, we can just read what we need, parse the buffer and use the
advertised offset. Thus for now -f is simply ignored.

16 months agoDEV: haring: split the code between ring and buffer
Willy Tarreau [Mon, 4 Mar 2024 18:12:33 +0000 (19:12 +0100)] 
DEV: haring: split the code between ring and buffer

By splitting the initialization and the parsing of the ring, we'll ease
the support for multiple ring sizes and get rid of the annoyances of the
optional lock.

16 months agoDEV: haring: make haring not depend on the struct ring itself
Willy Tarreau [Mon, 4 Mar 2024 18:04:09 +0000 (19:04 +0100)] 
DEV: haring: make haring not depend on the struct ring itself

haring needs to be self-sufficient about the ring format so that it continues
to build when the ring API changes. Let's import the struct ring definition
and call it "ring_v1".

16 months agoOPTIM: sink: drop the sink lock used to count drops
Willy Tarreau [Fri, 1 Mar 2024 18:22:04 +0000 (19:22 +0100)] 
OPTIM: sink: drop the sink lock used to count drops

The sink lock was made to prevent event producers from passing while
there were other threads trying to print a "dropped" message, in order
to guarantee the absence of reordering. It has a serious impact however,
which is that all threads need to take the read lock when producing a
regular trace even when there's no reader.

This patch takes a different approach. The drop counter is shifted left
by one so that the lowest bit is used to indicate that one thread is
already taking care of trying to dump the counter. Threads only read
this value normally, and will only try to change it if it's non-null,
in which case they'll first check if they are the first ones trying to
dump it, otherwise will simply count another drop and leave. This has
a large benefit. First, it will avoid the locking that causes stalls
as soon as a slow reader is present. Second, it avoids any write on the
fast path as long as there's no drop. And it remains very lightweight
since we just need to add +2 or subtract 2*dropped in operations, while
offering the guarantee that the sink_write() has succeeded before
unlocking the counter.

While a reader was previously limiting the traffic to 11k RPS under
4C/8T, now we reach 36k RPS vs 14k with no reader, so readers will no
longer slow the traffic down and will instead even speed it up due to
avoiding the contention down the chain in the ring. The locking cost
dropped from ~75% to ~60% now (it's in ring_write now).

16 months agoOPTIM: sink: try to merge "dropped" messages faster
Willy Tarreau [Fri, 1 Mar 2024 16:59:59 +0000 (17:59 +0100)] 
OPTIM: sink: try to merge "dropped" messages faster

When a reader doesn't read fast enough and causes drops, subsequent
threads try to produce a "dropped" message. But it takes time to
produce and emit this message, in part due to the use of chunk_printf()
that relies on vfprintf() which has to parse the printf format, and
during this time other threads may continue to increment the counter.
This is the reason why this is currently performed in a loop. When
reading what is received, it's common to see a large count followed
by one or two single-digit counts, indicating that we could possibly
have improved that by writing faster.

Let's improve the situation a little bit. First we're now using a
static message prefixed with enough space to write the digits, and a
call to ultoa_r() fills these digits from right to left so that we
don't have to process a format string nor perform a copy of the message.

Second, we now re-check the counter immediately after having prepared
the message so that we still get an opportunity for updating it. In
order to avoid too long loops, this is limited to 10 iterations.

Tests show that the number of single-digit "dropped" counters on output
now dropped roughly by 15-30%. Also, it was observed that with 8 threads,
there's almost never more than one retry.

16 months agoDOC: design: write first notes about ring-v2
Willy Tarreau [Wed, 21 Feb 2024 06:54:37 +0000 (07:54 +0100)] 
DOC: design: write first notes about ring-v2

This explains the observed limitations of the current ring applied to
traces and proposes a multi-step, more scalable, improvement.

16 months agoBUILD: ssl: define EVP_CTRL_AEAD_GET_TAG for older versions
Willy Tarreau [Fri, 8 Mar 2024 17:21:14 +0000 (18:21 +0100)] 
BUILD: ssl: define EVP_CTRL_AEAD_GET_TAG for older versions

Amaury reported that previous commit 08ac282375 ("MINOR: Add aes_gcm_enc
converter") broke the CI on OpenSSL 1.0.2 due to the define above not
existing there. Let's just map it to its older name when not existing.
For reference, these were renamed when switching to 1.1.0:

    https://marc.info/?l=openssl-cvs&m=142244190907706&w=2

No backport is needed.

16 months agoMINOR: quic: always use ncbuf for rx CRYPTO
Amaury Denoyelle [Fri, 8 Mar 2024 15:47:36 +0000 (16:47 +0100)] 
MINOR: quic: always use ncbuf for rx CRYPTO

The previous patch fix the handling of in-order CRYPTO frames which
requires the usage of a new buffer for these data as their handling is
delayed to run under TASK_HEAVY.

In fact, as now all CRYPTO frames handling must be delayed, their
handling can be unify. This is the purpose of this commit, which removes
the just introduced new buffer. Now, all CRYPTO frames are buffered
inside the ncbuf. Unused elements such as crypto_frms member for
encryption level are also removed.

This commit is not a bugcfix but is a direct follow-up to the last one.
As such, it can probably be backported with it to 2.9 to reduce code
differences between these versions.

16 months agoBUG/MEDIUM: quic: fix handshake freeze under high traffic
Amaury Denoyelle [Fri, 8 Mar 2024 14:19:22 +0000 (15:19 +0100)] 
BUG/MEDIUM: quic: fix handshake freeze under high traffic

QUIC relies on SSL_do_hanshake() to be able to validate handshake. As
this function is computation heavy, it is since 2.9 called only under
TASK_HEAVY. This has been implemented by the following patch :
  94d20be1388023bff36d795f501571adfefe8c75
  MEDIUM: quic: Heavy task mode during handshake

Instead of handling CRYPTO frames immediately during reception, this
patch delays the process to run under TASK_HEAVY tasklet. A frame copy
is stored in qel.rx.crypto_frms list. However, this frame still
reference the receive buffer. If the receive buffer is cleared before
the tasklet is rescheduled, it will point to garbage data, resulting in
haproxy decryption error. This happens if a fair amount of data is
received constantly to preempt the quic_conn tasklet execution.

This bug can be reproduced with a fair amount of clients. It is
exhibited by 'show quic full' which can report connections blocked on
handshake. Using the following commands result in h2load non able to
complete the last connections.

$ h2load --alpn-list h3 -t 8 -c 800 -m 10 -w 10 -n 8000 "https://127.0.0.1:20443/?s=10k"

Also, haproxy QUIC listener socket mode was active to trigger the issue.
This forces several connections to share the same reception buffer,
rendering the bug even more plausible to occur. It should be possible to
reproduce it with connection socket if increasing the clients amount.

To fix this bug, define a new buffer under quic_cstream. It is used
exclusively to copy CRYPTO data for in-order frame if ncbuf is empty.
This ensures data remains accessible even if receive buffer is cleared.

Note that this fix is only a temporary step. Indeed, a ncbuf is also
already used for out-of-order data. It should be possible to unify its
usage for both in and out-of-order data, rendering this new buffer
instance unnecessary. In this case, several unneeded elements will
become obsolete such as qel.rx.crypto_frms list. This will be done in a
future refactoring patch.

This must be backported up to 2.9.

16 months agoMINOR: Add aes_gcm_enc converter
Nenad Merdanovic [Tue, 5 Mar 2024 12:03:51 +0000 (13:03 +0100)] 
MINOR: Add aes_gcm_enc converter

The converter can be used to encrypt the raw byte input using the
AES-GCM algorithm, using provided nonce and key.

Co-authored-by: Dragan Dosen (ddosen@haproxy.com)
16 months agoMINOR: vars: export var_set and var_unset functions
Nenad Merdanovic [Tue, 5 Mar 2024 11:54:34 +0000 (12:54 +0100)] 
MINOR: vars: export var_set and var_unset functions

Co-authored-by: Dragan Dosen <ddosen@haproxy.com>
16 months agoBUG/MINOR: cfgparse: report proper location for log-format-sd errors
Aurelien DARRAGON [Wed, 28 Feb 2024 18:29:27 +0000 (19:29 +0100)] 
BUG/MINOR: cfgparse: report proper location for log-format-sd errors

When a parsing error occurs inside a log-format-sd expression, we report
the location of the log-format directive (which may not be set) instead
of reporting the proper log-format-sd directive location where the parsing
error occured.

 1|listen test
 2|  log-format "%B"      # no error
 3|  log-format-sd "%bad" # error

 | [ALERT]    (322261) : config : Parsing [empty.conf:2]: failed to parse log-format-sd : no such format variable 'bad'. If you wanted to emit the '%' character verbatim, you need to use '%%'.

The fix consists in using the config hints dedicated to log-format-sd
directive instead of the log-format one.

The bug was introduced in 8a4e4420 ("MEDIUM: log-format: Use standard
HAProxy log system to report errors").

This should be backported to every stable versions.

16 months agoCLEANUP: tree-wide: use proper ERR_* return values for PRE_CHECK fcts
Aurelien DARRAGON [Tue, 27 Feb 2024 15:12:40 +0000 (16:12 +0100)] 
CLEANUP: tree-wide: use proper ERR_* return values for PRE_CHECK fcts

httpclient_precheck(), ssl_ocsp_update_precheck(), and
resolvers_create_default() functions are registered through
REGISTER_PRE_CHECK() macro to be called by haproxy during init from the
pre_check_list list. When calling functions registered in pre_check_list,
haproxy expects ERR_* return values. However those 3 functions currently
use raw return values, so we better use explicit ERR_* macros to prevent
breakage in the future if ERR_* values mapping were to change.

16 months agoCLEANUP: log: fix obsolete comment for add_sample_to_logformat_list()
Aurelien DARRAGON [Thu, 22 Feb 2024 15:13:13 +0000 (16:13 +0100)] 
CLEANUP: log: fix obsolete comment for add_sample_to_logformat_list()

Since 833cc794 ("MEDIUM: sample: handle comma-delimited converter list")
logformat expressions now support having a comma-delimited converter list
right after the fetch. Let's remove a leftover comment from the initial
implementation that says otherwise.

16 months agoBUG/MINOR: mux-quic: fix crash on aborting uni remote stream
Amaury Denoyelle [Tue, 5 Mar 2024 14:14:08 +0000 (15:14 +0100)] 
BUG/MINOR: mux-quic: fix crash on aborting uni remote stream

A remote unidirectional stream can be aborted prematurely if application
layers cannot identify its type. In this case, a STOP_SENDING frame is
emitted.

Since QUIC MUX refactoring, a crash would occur in this scenario due to
2 specific characteristics of remote uni streams :
* qcs.tx.fctl was not initialized completely. This cause a crash due to
  BUG_ON() statement inside qcs_destroy().
* qcs.stream is never allocated. This caused qcs_prep_bytes() to crash
  inside qcc_io_send().

This bug is considered minor as it happens only on very specific QUIC
clients. It was detected when using s2n-quic over interop.

This does not need to be backported.

16 months agoBUG/MEDIUM: quic: fix connection freeze on post handshake
Amaury Denoyelle [Mon, 4 Mar 2024 17:41:39 +0000 (18:41 +0100)] 
BUG/MEDIUM: quic: fix connection freeze on post handshake

After handshake completion, QUIC server is responsible to emit
HANDSHAKE_DONE frame. Some clients wait for it to begin STREAM
transfers.

Previously, there was no explicit tasklet_wakeup() after handshake
completion, which is necessary to emit post-handshake frames. In most
cases, this was undetected as most client continue emission which will
reschedule the tasklet. However, as there is no tasklet_wakeup(), this
is not a consistent behavior. If this bug occurs, it causes a connection
freeze, preventing the client to emit any request. The connection is
finally closed on idle timeout.

To fix this, add an explicit tasklet_wakeup() after handshake
completion. It sounds simple enough but in fact it's difficult to find
the correct location efor tasklet_wakeup() invocation, as post-handshake
is directly linked to connection accept, with different orderings.
Notably, if 0-RTT is used, connection can be accepted prior handshake
completion. Another major point is that along HANDSHAKE_DONE frame, a
series of NEW_CONNECTION_ID frames are emitted. However, these new CIDs
allocation must occur after connection is migrated to its new thread as
these CIDs are tied to it. A BUG_ON() is present to check this in
qc_set_tid_affinity().

With all this in mind, 2 locations were selected for the necessary
tasklet_wakeup() :
* on qc_xprt_start() : this is useful for standard case without 0-RTT.
  This ensures that this is done only after connection thread migration.
* on qc_ssl_provide_all_quic_data() : this is done on handshake
  completion with 0-RTT used. In this case only, connection is already
  accepted and migrated, so tasklet_wakeup() is safe.

Note that as a side-change, quic_accept_push_qc() API has evolved to
better reflect differences between standard and 0-RTT usages. It is now
forbidden to call it multiple times on a single quic_conn instance. A
BUG_ON() has been added.

This issue is labelled as medium even though it seems pretty rare. It
was only reproducible using QUIC interop runner, with haproxy compiled
with LibreSSL with quic-go as client. However, affected code parts are
pretty sensible, which justify the chosen severity.

This should fix github issue #2418.

It should be backported up to 2.6, after a brief period of observation.
Note that the extra comment added in qc_set_tid_affinity() can be
removed in 2.6 as thread migration is not implemented for this version.
Other parts should apply without conflict.

16 months agoBUG/MINOR: ssl/cli: typo in new ssl crl-file CLI description
William Lallemand [Tue, 5 Mar 2024 13:49:17 +0000 (14:49 +0100)] 
BUG/MINOR: ssl/cli: typo in new ssl crl-file CLI description

The `new ssl crl-file` option description on the CLI lacks the dash.

Must be backported as far as 2.6.

16 months agoCI: skip scheduled builds on forks
Ilya Shipitsin [Wed, 21 Feb 2024 16:05:39 +0000 (17:05 +0100)] 
CI: skip scheduled builds on forks

tracking bleeding edge changes with some rare platforms or modern
compilers on scheduled basis is not what usually forks do. let's
skip by default in forks, if some fork is interested, it might be
enabled locally

16 months agoCI: enable monthly build only test on netbsd-9.3
Ilya Shipitsin [Mon, 19 Feb 2024 21:14:59 +0000 (22:14 +0100)] 
CI: enable monthly build only test on netbsd-9.3

it is interesting to try https://github.com/vmactions/netbsd-vm actions

16 months agoCI: run more smoke tests on config syntax to check memory related issues
Ilya Shipitsin [Sat, 17 Feb 2024 19:42:28 +0000 (20:42 +0100)] 
CI: run more smoke tests on config syntax to check memory related issues

config syntax check seems add a value on testing code path not
covered by VTest, also checks are very fast

16 months agoCLEANUP: fix typo in naming for variable "unused"
Ilya Shipitsin [Thu, 22 Feb 2024 09:12:27 +0000 (10:12 +0100)] 
CLEANUP: fix typo in naming for variable "unused"

In resolvers.c:rslv_promex_next_ts() and in
stick-tables.c:stk_promex_next_ts(), an unused argument was mistakenly
called "unsued" instead of "unused". Let's fix this in a separate patch
so that it can be omitted from backports if this causes build problems.

16 months agoCLEANUP: assorted typo fixes in the code and comments
Ilya Shipitsin [Thu, 22 Feb 2024 09:12:27 +0000 (10:12 +0100)] 
CLEANUP: assorted typo fixes in the code and comments

This is 39th iteration of typo fixes
The naming issue on the argument called "unsued" instead of "unused"
in two functions from resolvers and stick-tables was put into a second
patch so that it can be omitted if it were to cause backport issues.

16 months agoBUILD: buf: make b_ncat() take a const for the source
Willy Tarreau [Tue, 27 Feb 2024 18:06:41 +0000 (19:06 +0100)] 
BUILD: buf: make b_ncat() take a const for the source

In 2.7 with commit 35df34223b ("MINOR: buffers: split b_force_xfer() into
b_cpy() and b_force_xfer()"), b_ncat() was extracted from b_force_xfer()
but kept its source variable instead of constant, making it unusable for
calls from a const source. Let's just fix it.

16 months agoBUILD: tree-wide: fix a few missing includes in a few files
Willy Tarreau [Wed, 14 Feb 2024 07:41:11 +0000 (08:41 +0100)] 
BUILD: tree-wide: fix a few missing includes in a few files

Some include files, mostly types definitions, are missing a few includes
to define the types they're using, causing include ordering dependencies
between files, which are most often not seen due to the alphabetical
order of includes. Let's just fix them.

These were spotted by building pre-compiled headers for all these files
to .h.gch.

16 months agoBUILD: thread: move lock label definitions to thread-t.h
Willy Tarreau [Wed, 14 Feb 2024 07:39:57 +0000 (08:39 +0100)] 
BUILD: thread: move lock label definitions to thread-t.h

The 'lock_label' enum is defined in thread.h but it's used in a few
type files, so let's move it to thread-t.h to allow explicit includes.

16 months agoBUG/MINOR: sink: fix a race condition in the TCP log forwarding code
Willy Tarreau [Tue, 27 Feb 2024 16:32:44 +0000 (17:32 +0100)] 
BUG/MINOR: sink: fix a race condition in the TCP log forwarding code

That's exactly the same as commit 53bfab080c ("BUG/MINOR: sink: fix a race
condition between the writer and the reader") that went into 2.7 and was
backported as far as 2.4, except that since the code was duplicated, the
second instance was not noticed, leaving the race present. The race has
a limited impact, if a forwarder reaches the end of the logs and a new
message arrives before it leaves, the forwarder will only wake up after
yet another new message will be sent. In practice it remains unnoticeable
because for the race to trigger, one needs to have a steady flow of logs,
which means the wakeup will happen anyway.

This should be backported, but no need to insist on it if it resists.

16 months agoCLEANUP: hlua: txn class functions may LJMP
Aurelien DARRAGON [Fri, 1 Mar 2024 20:09:40 +0000 (21:09 +0100)] 
CLEANUP: hlua: txn class functions may LJMP

Clarify that some txn related class functions may LJMP by adding the
__LJMP tag to their prototype.

16 months agoMINOR: hlua: use SEND_ERR to report errors in hlua_event_runner()
Aurelien DARRAGON [Mon, 4 Mar 2024 10:19:46 +0000 (11:19 +0100)] 
MINOR: hlua: use SEND_ERR to report errors in hlua_event_runner()

Instead of reporting lua errors using ha_alert(), let's use SEND_ERR()
helper which will also try to generate a log message according to lua
log settings.

16 months agoBUG/MINOR: hlua: don't call ha_alert() in hlua_event_subscribe()
Aurelien DARRAGON [Mon, 4 Mar 2024 15:31:23 +0000 (16:31 +0100)] 
BUG/MINOR: hlua: don't call ha_alert() in hlua_event_subscribe()

hlua_event_subscribe() is meant to be called from a protected lua env
during init and/or runtime. As such, only hlua_event_sub() makes uses
of it: when an error happens hlua_event_sub() will already raise a Lua
exception. Thus it's not relevant to use ha_alert() there as it could
generate log pollution (error is relevant from Lua script point of view,
not from haproxy one).

This could be backported in 2.8.

16 months agoBUG/MAJOR: hlua: improper lock usage with hlua_ctx_resume()
Aurelien DARRAGON [Fri, 1 Mar 2024 20:17:51 +0000 (21:17 +0100)] 
BUG/MAJOR: hlua: improper lock usage with hlua_ctx_resume()

hlua_ctx_resume() itself can safely be used as-is in a multithreading
context because it takes care of taking the lua lock.

However, when hlua_ctx_resume() returns, the lock is released and it is
thus the caller's responsibility to ensure it owns the lock prior to
performing additional manipulations on the Lua stack. Unfortunately, since
early haproxy lua implementation, we used to do it wrong:

The most common hlua_ctx_resume() pattern we can find in the code (because
it was duplicated over and over over time) is the following:

  |ret = hlua_ctx_resume()
  |switch (ret) {
  |        case HLUA_E_OK:
  |        break;
  |        case HLUA_E_ERRMSG:
  |        break;
  |        [...]
  |}

Problem is: for some of the switch cases, we still perform lua stack
manipulations. This is the case for the HLUA_E_ERRMSG for instance where
we often use lua_tostring() to retrieve last lua error message on the top
of the stack, or sometimes for the HLUA_E_OK case, when we need to perform
some lua cleanup logic once the resume ended. But all of this is done
WITHOUT the lua lock, so this means that the main lua stack could be
accessed simultaneously by concurrent threads when a script was loaded
using 'lua-load'.

While it is not critical for switch-cases dedicated to error handling,
(those are not supposed to happen very often), it can be very problematic
for stack manipulations occuring in the HLUA_E_OK case under heavy load
for instance. In this case, main lua stack corruptions will eventually
happen. This is especially true inside hlua_filter_new(), where this bug
was known to cause lua stack corruptions under load, leading to lua errors
and even crashing the process as reported by @bgrooot in GH #2467.

The fix is relatively simple, once hlua_ctx_resume() returns: we should
consider that ANY lua stack access should be lua-lock protected. If the
related lua calls may raise lua errors, then (RE)SET_SAFE_LJMP
combination should be used as usual (it allows to lock the lua stack and
catch lua exceptions at the same time), else hlua_{lock,unlock} may be
used if no exceptions are expected.

This patch should fix GH #2467.

It should be backported to all stable versions.

[ada: some ctx adj will be required for older versions as event_hdl
 doesn't exist prior to 2.8 and filters were implemented in 2.5, thus
 some chunks won't apply]

16 months agoBUG/MEDIUM: hlua: improper lock usage with SET_SAFE_LJMP()
Aurelien DARRAGON [Mon, 4 Mar 2024 10:17:58 +0000 (11:17 +0100)] 
BUG/MEDIUM: hlua: improper lock usage with SET_SAFE_LJMP()

When we want to perform some unsafe lua stack manipulations from an
unprotected lua environment, we use SET_SAFE_LJMP() RESET_SAFE_LJMP()
combination to lock lua stack and catch potential lua exceptions that
may occur between the two.

Hence, we regularly find this pattern (duplicated over and over):

  |if (!SET_SAFE_LJMP(hlua)) {
  |        const char *error;
  |
  |        if (lua_type(hlua->T, -1) == LUA_TSTRING)
  |                error = hlua_tostring_safe(hlua->T, -1);
  |         else
  |                error = "critical error";
  |        SEND_ERR(NULL, "*: %s.\n", error);
  |}

This is wrong because when SET_SAFE_LJMP() returns false (meaning that an
exception was caught), then the lua lock was released already, thus the
caller is not expected to perform lua stack manipulations (because the
main lua stack may be shared between multiple threads). In the pattern
above we only want to retrieve the lua exception message which may be
found at the top of the stack, to do so we now explicitly take the lua
lock before accessing the lua stack. Note that hlua_lock() doesn't catch
lua exceptions so only safe lua functions are expected to be used there
(lua functions that may NOT raise exceptions).

It should be backported to every stable versions.

[ada: some ctx adj will be required for older versions as event_hdl
 doesn't exist prior to 2.8 and filters were implemented in 2.5, thus
 some chunks won't apply, but other fixes should stay relevant]

16 months agoBUG/MINOR: hlua: improper lock usage in hlua_filter_new()
Aurelien DARRAGON [Mon, 4 Mar 2024 10:25:47 +0000 (11:25 +0100)] 
BUG/MINOR: hlua: improper lock usage in hlua_filter_new()

In hlua_filter_new(), after each hlua resume, we systematically try to
empty the stack by calling lua_settop(). However we're doing this without
locking the lua context, so it is unsafe in multithreading context if the
script is loaded using 'lua-load'. To fix the issue, we protect the call
with hlua_{lock,unlock}() helpers.

This should be backported up to 2.6.

16 months agoBUG/MINOR: hlua: improper lock usage in hlua_filter_callback()
Aurelien DARRAGON [Mon, 4 Mar 2024 10:06:24 +0000 (11:06 +0100)] 
BUG/MINOR: hlua: improper lock usage in hlua_filter_callback()

In hlua_filter_callback(), some lua stack work is performed under
SET_SAFE_LJMP() guard which also takes care of locking the hlua context
when needed. However, a lua_gettop() call is performed out of the guard,
thus it is unsafe in multithreading context if the script is loaded using
'lua-load' because in this case the main lua stack is shared between
threads and each access to a lua stack must be performed under the lock,
thus we move lua_gettop() call under the lock.

It should be backported up to 2.6.

16 months agoBUG/MINOR: hlua: fix possible crash in hlua_filter_new() under load
Aurelien DARRAGON [Mon, 4 Mar 2024 08:39:58 +0000 (09:39 +0100)] 
BUG/MINOR: hlua: fix possible crash in hlua_filter_new() under load

hlua_filter_new() handles memory allocation errors by jumping to the
"end:" cleanup label in case of errors. Such errors may happen when the
system is heavily loaded for instance.

In hlua_filter_new(), we try to allocate two hlua contexts in a row before
checking if one of them failed (in which case we jump to the cleanup part
of the function), and only then we initialize them both.

If a memory allocation failure happens for only one out of the two
flt_ctx->hlua[] contexts pair, we still jump to the cleanup part.
It means that the hlua context that was successfully allocated and wasn't
initialized yet will be passed to hlua_ctx_destroy(), resulting in invalid
reads in the cleanup function, which may ultimately cause the process to
crash.

To fix the issue: we make sure flt_ctx hlua contexts are initialized right
after they are allocated, that is before any error handling condition that
may force the cleanup.

This bug was discovered when trying to reproduce GH #2467 with haproxy
started with "-dMfail" argument.

It should be backported up to 2.6.

16 months agoBUG/MINOR: hlua: don't use lua_tostring() from unprotected contexts
Aurelien DARRAGON [Fri, 1 Mar 2024 14:55:17 +0000 (15:55 +0100)] 
BUG/MINOR: hlua: don't use lua_tostring() from unprotected contexts

As per lua documentation, lua_tostring() may raise a memory error.
However, we're often using it to fetch the error message at the top of
the stack (ie: after a failing lua call) from unprotected environments.
In practise, lua_tostring() has rare chances of failing, but still, if
it happens to be the case, it could crash the process and we better not
risk it.

So here, we add hlua_tostring_safe() function, which works exactly as
lua_tostring(), but the function cannot LJMP as it will catch
lua_tostring() exceptions to return NULL instead.

Everywhere lua_tostring() was used to retrieve error string from such
unprotected contexts, we now rely on hlua_tostring_safe().

This should be backported to all stable versions.

[ada: ctx adj will be required, for versions prior to 2.8 event_hdl
 API didn't exist so some chunks won't apply, and prior to 2.5 filters
 API didn't exist either, so again, some chunks should be ignored]

16 months agoBUG/MINOR: hlua: fix unsafe lua_tostring() usage with empty stack
Aurelien DARRAGON [Fri, 1 Mar 2024 18:54:16 +0000 (19:54 +0100)] 
BUG/MINOR: hlua: fix unsafe lua_tostring() usage with empty stack

Lua documentation says that lua_tostring() returns a pointer that remains
valid as long as the object is not removed from the stack.

However there are some places were we use the returned string AFTER the
corresponding object is removed from the stack. In practise this doesn't
seem to cause visible bugs (probably because the pointer remains valid
waiting for a GC cycle), but let's fix that to comply with the
documentation and avoid undefined behavior.

It should be backported in all stable versions.

16 months agoBUG/MINOR: tools: seed the statistical PRNG slightly better
Willy Tarreau [Fri, 1 Mar 2024 15:17:47 +0000 (16:17 +0100)] 
BUG/MINOR: tools: seed the statistical PRNG slightly better

Thomas Baroux reported a very interesting issue. "balance random" would
systematically assign the same server first upon restart. That comes from
its use of statistical_prng() which is only seeded with the thread number,
and since at low loads threads are assigned to incoming connections in
round robin order, practically speaking, the same thread always gets the
same request and will produce the same random number.

We already have a much better RNG that's also way more expensive, but we
can use it at boot time to seed the PRNG instead of using the thread ID
only.

This needs to be backported to 2.4.

16 months agoMINOR: hlua: Be able to disable logging from lua
Christopher Faulet [Thu, 29 Feb 2024 14:41:17 +0000 (15:41 +0100)] 
MINOR: hlua: Be able to disable logging from lua

Add core.silent (-1) value to be able to disable logging via
TXN:set_loglevel() call. Otherwise, there is no way to do so and it may be
handy. This special value cannot be used with TXN:log() function.

This patch may be backported if necessary.

16 months agoBUG/MINOR: hlua: Fix log level to the right value when set via TXN:set_loglevel
Christopher Faulet [Thu, 29 Feb 2024 14:37:43 +0000 (15:37 +0100)] 
BUG/MINOR: hlua: Fix log level to the right value when set via TXN:set_loglevel

When the log level is changed in lua, by calling TXN:set_loglevel function,
it must be incremented by one because it is decremented in strm_log()
function.

This patch must be backport to all stable versions.

16 months agoBUG/MINOR: config/quic: Alert about PROXY protocol use on a QUIC listener
Christopher Faulet [Thu, 29 Feb 2024 13:27:45 +0000 (14:27 +0100)] 
BUG/MINOR: config/quic: Alert about PROXY protocol use on a QUIC listener

PROXY procotol is not supported on QUIC for now. Thus return an error during
configuration parsing if 'accept-proxy' option is used for a QUIC listener.

This patch should fix the issue #2186. It should be backport as far as 2.6.

16 months agoDOC: configuration: clarify ciphersuites usage
William Lallemand [Thu, 29 Feb 2024 17:04:12 +0000 (18:04 +0100)] 
DOC: configuration: clarify ciphersuites usage

Ciphersuites can be used with any TLS/SSL protocol version and are not
specific to TLSv1.3. However you can only specify the TLSv1.3 ciphers in
ciphersuite format.

Should fix issue #2459.

Backport to every stable branches.

16 months agoCLEANUP: mux-h2: Fix h2s_make_data() comment about the return value
Christopher Faulet [Thu, 29 Feb 2024 12:52:35 +0000 (13:52 +0100)] 
CLEANUP: mux-h2: Fix h2s_make_data() comment about the return value

2 return values are specified in the h2s_make_data() function comment. Both
are more or less equivalent but the later is probably more accurate. So,
keep the right one and remove the other one.

This patch should fix the issue #2175.

16 months agoMINOR: quic: add MUX output for show quic
Amaury Denoyelle [Fri, 23 Feb 2024 16:32:14 +0000 (17:32 +0100)] 
MINOR: quic: add MUX output for show quic

Extend "show quic" to be able to dump MUX related information. This is
done via the new function qcc_show_quic(). This replaces the old streams
dumping list which was incomplete.

These info are displayed on full output or by specifying "mux" field.

16 months agoMINOR: quic: specify show quic output fields
Amaury Denoyelle [Mon, 26 Feb 2024 08:57:05 +0000 (09:57 +0100)] 
MINOR: quic: specify show quic output fields

Add the possibility to customize show quic full output with only a
specific set of printed fields. This is specified as a comma-separated
list. Here are the currently supported values :
* tp: transport parameters
* sock: connection addresses and socket FD
* pktns: packet number space with ack ranges and in flight bytes
* cc: congestion controler and loss information

Note that streams output is not filtered by this mechanism. It's because
it will be replaced soon by an output generated from the MUX which will
use its owned field name.

16 months agoMINOR: quic: filter show quic by address
Amaury Denoyelle [Mon, 26 Feb 2024 09:56:30 +0000 (10:56 +0100)] 
MINOR: quic: filter show quic by address

Add the possibilty to restrict show quic output to only a single
connection. This is done by specifying a quic_conn address pointer.

Default format selection has evolved with it. Indeed, it seems more
fitting to use full format by default when filtering on a connection.
However, it's still possible to revert to the original oneline format
with it by specifying it explicitely.

16 months agoMEDIUM: htx/http-ana: No longer close connection on early HAProxy response
Christopher Faulet [Mon, 26 Feb 2024 07:36:58 +0000 (08:36 +0100)] 
MEDIUM: htx/http-ana: No longer close connection on early HAProxy response

When a response was returned by HAProxy, a dedicated HTX flag was
set. Thanks to this flag, it was possible to add a "connection: close"
header to the response if the request was not fully received and to close
the connection. In the same way, when a redirect rule was applied,
keep-alive was forcefully disabled for unfinished requests.

All these mechanisms are now useless because the H1 mux is able to drain the
response. So HTX_FL_PROXY_RESP flag is removed and no special processing is
performed on HAProxy response when the request is unfinished.

16 months agoMAJOR: mux-h1: Drain requests on client side before shut a stream down
Christopher Faulet [Mon, 26 Feb 2024 06:50:23 +0000 (07:50 +0100)] 
MAJOR: mux-h1: Drain requests on client side before shut a stream down

unlike for H2 and H3, there is no mechanism in H1 to notify the client it
must stop to upload data when a response is replied before the end of the
request without closing the connection. There is no RST_STREAM frame
equivalent.

Thus, there is only two ways to deal with this situation: closing the
connection or draining the request. Until now, HAProxy didn't support
draining H1 messages. Closing the connection in this case has however a
major drawback. It leads to send a TCP reset, dropping this way all in-fly
data. There is no warranty the client has fully received the response.

Draining H1 messages was never implemented because in old versions it was a
bit tricky to implement. However, it is now far simplier to support this
feature because it is possible to have a H1 stream without any applicative
stream. It is the purpose of this patch. Now, when a shutdown is requested
and the stream is detached from the connection, if the request is unfinished
while the response was fully sent, the request in drained.

To do so, in this case the shutdown and the detach are delayed. From the
upper layer point of view, there is no changes. The endpoint is shut down
and detached as usual. But on H1 mux point of view, the H1 stream is still
alive and is being able to drain data. However the stream-endpoint
descriptor is orphan. Once the request is fully received (and drained), the
connection is shut down if it cannot be reused for a new transaction and the
H1 stream is destroyed.

16 months agoMINOR: mux-h1: Move all stuff to detach a stream in an internal function
Christopher Faulet [Mon, 26 Feb 2024 06:44:52 +0000 (07:44 +0100)] 
MINOR: mux-h1: Move all stuff to detach a stream in an internal function

All code from h1_detach() function was moved in a internal function,
h1s_finish_detach(). It will be used to defer the detach and be able to
drain the requests payload.

16 months agoMINOR: mux-h1: Move checks performed before a shutdown in a dedicated function
Christopher Faulet [Mon, 26 Feb 2024 06:35:50 +0000 (07:35 +0100)] 
MINOR: mux-h1: Move checks performed before a shutdown in a dedicated function

Checks performed in h1_shutw() to determine if the connection must be
shutdown now or not was move in a dedicated function. This will be used to
be able to drain the requests payload.

16 months agoBUG/MINOR: mux-h1: Properly report when mux is blocked during a nego
Christopher Faulet [Wed, 28 Feb 2024 13:46:56 +0000 (14:46 +0100)] 
BUG/MINOR: mux-h1: Properly report when mux is blocked during a nego

During a zero-copy forwarding negociation, if the H1 mux is blocked for any
reason, the IOBUF_FL_FF_BLOCKED flag must be set on its iobuf to notfiy the
producer it must wait. However, there were two places where it was not
performed: when the output buffer allocation failed and when the chunk
formatting failed.

This patch fixes the issue. It must be backported to 2.9.

16 months agoBUG/MEDIUM: mux-h1: Fix again 0-copy forwarding of chunks with an unknown size
Christopher Faulet [Wed, 28 Feb 2024 07:01:06 +0000 (08:01 +0100)] 
BUG/MEDIUM: mux-h1: Fix again 0-copy forwarding of chunks with an unknown size

There is still an issue with zero-copy forwarding of chunks with an unknown
size. It is possible for a producer to fill the sapce reserved for the CRLF
at the end of the chunk. The root cause is that this space is not accounted
in the iobuf offset. So, from the producer point of view, the space may be
used. We can also argue the current design for iobuf is not well suited for
this case. Instead of using a pointer on the consumer's buffer, it could be
easier to use a custom buffer built on top of the consumer one, via a call
to b_make(), with the size, head and data field reflecting the avaialble
space the producer can use.

By the way, because of this bug, it is possible to trigger a BUG_ON() when
we try to write the CRLF at the end of the chunk because the buffer is
full. It is unexpected. Only the stats applet may hit this bug.

To fix the issue, instead of writting this CRLF when the current chunk is
consumed, it is written before consuming the next one. This way, all space
reserved to create the chunk formatting is always placed before forwarding
data.

No backport needed.

16 months agoLICENSE: http_ext: fix GPL license version
Aurelien DARRAGON [Wed, 28 Feb 2024 10:25:31 +0000 (11:25 +0100)] 
LICENSE: http_ext: fix GPL license version

This is a followup of the previous commit: GH user @songliumeng initially
reported an issue with the GPL license version for event_hdl source file
which was fixed by the previous commit. It turns out the same mistake was
made in http_ext source file: due to a mixup between LGPL and GPL, GPL
version '2.1' was referenced instead of '2'.

Again, clarify that this is indeed GPL by making use of the banner
provided in doc/gpl.txt

This should be backported in 2.8 with b2bb925 ("MINOR: proxy/http_ext:
introduce proxy forwarded option")

16 months agoLICENSE: event_hdl: fix GPL license version
Aurelien DARRAGON [Wed, 28 Feb 2024 10:22:49 +0000 (11:22 +0100)] 
LICENSE: event_hdl: fix GPL license version

As spotted by user @songliumeng in GH #2463, there was a mixup between
LGPL and GPL in event_hdl source file: GPL version '2.1' was referenced
instead of '2'. Clarify that this is indeed GPL by making use of the
banner provided in doc/gpl.txt.

This should be backported in 2.8 with 68e692d ("MINOR: event_hdl: add
event handler base api")

16 months agoBUG/MINOR: ssl/cli: duplicate cleaning code in cli_parse_del_crtlist
William Lallemand [Tue, 27 Feb 2024 16:22:15 +0000 (17:22 +0100)] 
BUG/MINOR: ssl/cli: duplicate cleaning code in cli_parse_del_crtlist

Since 23cab33 ("BUG/MINOR: ssl: Clear the ckch instance when deleting a
crt-list line"), LIST_DELETE is done twice, one time in
cli_parse_del_crtlist() and another time in ckch_inst_free().

It could trigger a crash with -DDEBUG_LIST.

This isn't a major problem since the ptr is not freed in the meantime so
it will only trigger with the debug.

This patch removes the LIST_DELETE as well as the loop done on link_ref
which is also don in ckch_inst_free()

Could be backported as far as 2.4. 2.4 version does not have a link_ref
loop.

16 months agoBUG/MEDIUM: server: fix dynamic servers initial settings
Amaury Denoyelle [Tue, 27 Feb 2024 14:33:59 +0000 (15:33 +0100)] 
BUG/MEDIUM: server: fix dynamic servers initial settings

Contrary to static servers, dynamic servers does not initialize their
settings from a default server instance. As such, _srv_parse_init() was
responsible to set a set of minimal values to have a correct behavior.

However, some settings were not properly initialized. This caused
dynamic servers to not behave as static ones without explicit
parameters.

Currently, the main issue detected is connection reuse which was
completely impossible. This is due to incorrect pool_purge_delay and
max_reuse settings incompatible with srv_add_to_idle_list().

To fix the connection reuse, but also more generally to ensure dynamic
servers are aligned with other server instances, define a new function
srv_settings_init(). This is used to set initial values for both default
servers and dynamic servers. For static servers, srv_settings_cpy() is
kept instead, using their default server as reference.

This patch could have unexpected effects on dynamic servers behavior as
it restored proper initial settings. Previously, they were set to 0 via
calloc() invocation from new_server().

This should be backported up to 2.6, after a brief period of
observation.

16 months agoBUG/MAJOR: ssl/ocsp: crash with ocsp when old process exit or using ocsp CLI
William Lallemand [Mon, 26 Feb 2024 16:53:02 +0000 (17:53 +0100)] 
BUG/MAJOR: ssl/ocsp: crash with ocsp when old process exit or using ocsp CLI

This patch reverts 2 fixes that were made in an attempt to fix the
ocsp-update feature used with the 'commit ssl cert' command.

The patches crash the worker when doing a soft-stop when the 'set ssl
ocsp-response' command was used, or during runtime if the ocsp-update
was used.

This was reported in issue #2462 and #2442.

The last patch reverted is the associated reg-test.

Revert "BUG/MEDIUM: ssl: Fix crash when calling "update ssl ocsp-response" when an update is ongoing"
This reverts commit 5e66bf26ecbf6439fafc8ef8857abe22e0874f4d.

Revert "BUG/MEDIUM: ocsp: Separate refcount per instance and per store"
This reverts commit 04b77f84d1b52185fc64735d7d81137479d68b00.

Revert "REGTESTS: ssl: Add OCSP related tests"
This reverts commit acd1b85d3442fc58164bd0fb96e72f3d4b501d15.

16 months agoBUG/MEDIUM: applet: Fix HTX .rcv_buf callback function to release outbuf buffer
Christopher Faulet [Mon, 26 Feb 2024 15:34:43 +0000 (16:34 +0100)] 
BUG/MEDIUM: applet: Fix HTX .rcv_buf callback function to release outbuf buffer

In appctx_htx_rcv_buf(), HTX blocks found in the appctx output buffer are
copied into the channel buffer. At the end, the state of the underlying
buffer must be updated. If everything was copied, the buffer is reset. This
way, it will be released later, at the end of the applet process function.

However, here there was a typo. We do it on the input buffer instead of the
output buffer. As side effect, an empty HTX message remained stuck in the
appctx outbut buffer, blocking the applet and leading to blocked session
with no expiration date.

No backport needed.

16 months ago[RELEASE] Released version 3.0-dev4 v3.0-dev4
Willy Tarreau [Fri, 23 Feb 2024 19:01:45 +0000 (20:01 +0100)] 
[RELEASE] Released version 3.0-dev4

Released version 3.0-dev4 with the following main changes :
    - BUG/MEDIUM: ssl: Fix crash when calling "update ssl ocsp-response" when an update is ongoing
    - BUG/MEDIUM: quic: Wrong K CUBIC calculation.
    - MINOR: quic: Update K CUBIC calculation (RFC 9438)
    - MINOR: quic: Dynamic packet reordering threshold
    - MINOR: quic: Add a counter for reordered packets
    - BUG/MAJOR: mux-h1: Fix zero-copy forwarding when sending chunks of unknown size
    - MINOR: stats: Use a dedicated function to check if output is almost full
    - BUG/MEDIUM: applet: Add a flag to state an applet is using zero-copy forwarding
    - BUG/MEDIUM: stconn/applet: Block 0-copy forwarding if producer needs more room
    - MINOR: applet: Remove uselelss test on SE_FL_SHR/SHW flags
    - MEDIUM: applet: Add notion of shutdown for write for applets
    - MINOR: cli: No longer check SC for shutdown to interrupt wait command
    - BUG/MEDIUM: stconn: Allow expiration update when READ/WRITE event is pending
    - BUG/MEDIUM: stconn: Don't check pending shutdown to wake an applet up
    - CLEANUP: stconn: Move SE flags set by app layer at the end of the bitfield
    - MINOR: stconn: Rename SE_FL_MAY_FASTFWD and reorder bitfield
    - MINOR: stconn: Add SE flag to announce zero-copy forwarding on consumer side
    - MINOR: muxes: Announce support for zero-copy forwarding on consumer side
    - BUG/MAJOR: stconn: Check support for zero-copy forwarding on both sides
    - MINOR: muxes/applet: Simplify checks on options to disable zero-copy forwarding
    - BUG/MINOR: quic: reject unknown frame type
    - MINOR: quic: handle all frame types on reception
    - BUG/MINOR: quic: reject HANDSHAKE_DONE as server
    - BUG/MINOR: qpack: reject invalid increment count decoding
    - BUG/MINOR: qpack: reject invalid dynamic table capacity
    - DOC/MINOR: userlists: mention solutions to high cpu with hashes
    - DOC: quic: Missing tuning setting in "Global parameters"
    - BUG/MEDIUM: applet: Immediately free appctx on early error
    - BUG/MEDIUM: hlua: Be able to garbage collect uninitialized lua sockets
    - BUG/MEDIUM: hlua: Don't loop if a lua socket does not consume received data
    - BUG/MEDIUM: quic: fix transient send error with listener socket
    - MINOR: log: custom name for logformat node
    - MINOR: sample: add type_to_smp() helper function
    - MINOR: log: explicit typecasting for logformat nodes
    - MINOR: log: simplify last_isspace in sess_build_logline()
    - MINOR: log: simplify quotes handling in sess_build_logline()
    - MINOR: log: print metadata prefixes separately in sess_build_logline()
    - MINOR: log: automate string array construction in sess_build_logline()
    - DOC: quic: fix recommandation for bind on multiple address
    - MINOR: quic: warn on bind on multiple addresses if no IP_PKTINFO support
    - OPTIM: quic: improve slightly qc_snd_buf() internal
    - MINOR: quic: move IP_PKTINFO on send on a dedicated function
    - MINOR: quic: remove sendto() usage variant
    - MINOR: quic: only use sendmsg() syscall variant
    - BUILD: applet: fix build on some 32-bit archs
    - BUG/MINOR: quic: initialize msg_flags before sendmsg
    - BUG/MEDIUM: mux-h1: Don't emit 0-CRLF chunk in h1_done_ff() when iobuf is empty
    - CLEANUP: proxy/log: remove unused proxy flag
    - CLEANUP: log: fix process_send_log() indentation
    - CLEANUP: log: use free_logformat_list() in parse_logformat_string()
    - MINOR: log: add free_logformat_node() helper function
    - BUG/MINOR: log: fix potential lf->name memory leak
    - BUG/MINOR: ist: allocate nul byte on istdup
    - BUG/MINOR: stats: drop srv refcount on early release
    - BUG/MAJOR: promex: fix crash on deleted server
    - BUG/MAJOR: server: fix stream crash due to deleted server
    - BUG/MEDIUM: mux-quic: do not crash on qcs_destroy for connection error
    - MINOR: cli: Remove useless loop on commands to find unescaped semi-colon
    - BUG/MEDIUM: cli: Warn if pipelined commands are delimited by a \n
    - BUG/MAJOR: cli: Restore non-interactive mode behavior with pipelined commands
    - BUG/MINOR: quic: fix output of show quic
    - MINOR: ssl: Call callback function after loading SSL CRL data
    - BUG/MINOR: ist: only store NUL byte on succeeded alloc

16 months agoBUG/MINOR: ist: only store NUL byte on succeeded alloc
Willy Tarreau [Fri, 23 Feb 2024 18:51:54 +0000 (19:51 +0100)] 
BUG/MINOR: ist: only store NUL byte on succeeded alloc

The trailing NUL added at the end of istdup() by recent commit de0216758
("BUG/MINOR: ist: allocate nul byte on istdup") was placed outside of
the pointer validity test, rightfully showing null deref warnings. This
fix should be backported along with the fix above, to the same versions.

16 months agoMINOR: ssl: Call callback function after loading SSL CRL data
Miroslav Zagorac [Fri, 23 Feb 2024 02:24:29 +0000 (03:24 +0100)] 
MINOR: ssl: Call callback function after loading SSL CRL data

Due to the possibility of calling a control process after adding CRLs, the
ssl_commit_crlfile_cb variable was added.  It is actually a pointer to the
callback function, which is called if defined after initial loading of CRL
data from disk and after committing CRL data via CLI command
'commit ssl crl-file ..'.

If the callback function returns an error, then the CLI commit operation
is terminated.

Also, one case was added to the CLI context used by "commit cafile" and
"commit crlfile": CACRL_ST_CRLCB in which the callback function is called.

Signed-off-by: William Lallemand <wlallemand@haproxy.com>
16 months agoBUG/MINOR: quic: fix output of show quic
Amaury Denoyelle [Fri, 23 Feb 2024 16:28:49 +0000 (17:28 +0100)] 
BUG/MINOR: quic: fix output of show quic

Output of 'show quic' is messed up since the introduction of reordered
packets counter in the following commit. The new counter is mixed up
with the first stream line. This is due to the wrong placement of the
newline delimiter.

  167e38e0e0296e899aa894d2f3db5ba2a0c68cb5
  MINOR: quic: Add a counter for reordered packets

This should be backported up to 2.6.

16 months agoBUG/MAJOR: cli: Restore non-interactive mode behavior with pipelined commands
Christopher Faulet [Tue, 20 Feb 2024 17:39:50 +0000 (18:39 +0100)] 
BUG/MAJOR: cli: Restore non-interactive mode behavior with pipelined commands

The issue was decribed in commit "BUG/MEDIUM: cli: Warn if pipelined commands
are delimited by a \n". In non-interactive mode, it was possible to use a
newline character as delimiter for pipelined commands. As a consequence, it was
possible to stop commands processing on the middle.

With the above commit, a warning is emitted to notify users. With this one,
we restore the expected behavior, as documented in the management guide.
Only the first line of commands is parsed. This commit will not be
backported to avoid breaking changes on stable versions.

This commit has of course some visible effects. All script using a newline
character as delimiter to pipeline commands in non-interactive mode will
stop working. Only the first command will be evaluated, all others will be
ignored. Pipelined commands MUST now be separated by a semi-colon.

But there is a more subtle and probably more annoying change. It is no
longer possible to pipeline commands with a payload ! A command with a
payload will always be the last one evaluated because it must be finished by
a newline (eventually preceeded by a custom pattern).

It is really annoying to introduce such breaking change. But, on the long
term, it is mandatory. The 2.8 will be the last LST version supporting the
old behavior (with some warning however). This will let 4 years to users to
adapt their scripts.

No backport needed.

16 months agoBUG/MEDIUM: cli: Warn if pipelined commands are delimited by a \n
Christopher Faulet [Tue, 20 Feb 2024 17:30:16 +0000 (18:30 +0100)] 
BUG/MEDIUM: cli: Warn if pipelined commands are delimited by a \n

This was broken since commit 0011c25144 ("BUG/MINOR: cli: avoid O(bufsize)
parsing cost on pipelined commands"). It is not really a bug fix but it is
labelled as is to make it more visible.

Before, a full line was first retrieved from the request buffer before
extracting the first command to eval it. Now, only one command is retrieved.
But we rely on the request buffer state to interrupt processing in
non-interactive mode. After a command processing, if output of the request
buffer is empty, we leave. Before the above commit, this was not a problem.
But since then, it is obviously a bad statement. First because some input
data may still be there. It is not true today, but it might change. Then,
there is no warranty to receive all commands in same time. For small list of
commands, it will be most of time the case, but it is a dangerous
assumption. For long list of commands, it is almost always false.

To be an issue, commands must be chunked exactly between two commands. But
in this case, remaining commands are skipped. A good way to reproduce the
issue is to wait a bit between two commands, for instance:

    (printf "show info;"; sleep 2; printf "show stat\n") | socat ...

In fact, to properly fix the issue, we should exit on the first command
finished by a newline. Indeed, as stated in the documentation, in
non-interactive mode, a single line is processed. To pipeline commands,
commands must be separated by a semi-colon. Unfortunately, the above commit
introduced another change. It is possible to pipeline commands delimited by
a newline. It was pushed 2 years ago and backported to all stable versions.
Several scripts may rely on this behavior.

So, on stable version, the bug will not be fixed. However a warning will be
emitted to notify users their scripts don't respect the documentation and
they must adapt it. Mainly because the cli behavior on this point will be
changed in 3.0 to stick to the doc. This warning will only be emitted once
over the whole worker process life. Idea is to not flood the logs with the
same warning for every offending commands.

This commit should probably be backported to all stable versions. But with
some cautions because the CLI was often modified.

16 months agoMINOR: cli: Remove useless loop on commands to find unescaped semi-colon
Christopher Faulet [Tue, 20 Feb 2024 15:37:11 +0000 (16:37 +0100)] 
MINOR: cli: Remove useless loop on commands to find unescaped semi-colon

This loop was added to detect pipelined commands when only co_getline() was
used to get commands. Now, co_getdelim() is used and the semi-colon is also
considered as a command delimiter.

As side effet, the last semi-colon, if any, is no longer replaced by a
newline. Thus, we must take care to adapt the test to detect partial
commands.

16 months agoBUG/MEDIUM: mux-quic: do not crash on qcs_destroy for connection error
Amaury Denoyelle [Fri, 23 Feb 2024 10:41:33 +0000 (11:41 +0100)] 
BUG/MEDIUM: mux-quic: do not crash on qcs_destroy for connection error

On qcs_destroy(), a BUG_ON() statement check that QCS does not have
anymore prepared data. This is to ensure connection flow control is
always coherent and prevent transfer freeze.

However, this BUG_ON() may cause a spurrious crash in case QCC is
considered on error. Indeed, in this case, all transfers are interrupted
and qmux_strm_detach() will proceed to immediate QCS free before
releasing the connection. In this situation, connection flow control is
irrelevant so the BUG_ON() should be ignored.

This crash occurs since the MUX refactoring via the following patch.
Previously, a similar BUG_ON() was used but it was incorrectly
implemented rendering it immune even to targetted cause.

  3fe3251593e32c7ee07be94a193aea3a8eefb076
  MEDIUM: mux-quic: simplify sending API

This should fix github issue #2456.

This does not need to be backported.

16 months agoBUG/MAJOR: server: fix stream crash due to deleted server
Amaury Denoyelle [Wed, 21 Feb 2024 14:54:11 +0000 (15:54 +0100)] 
BUG/MAJOR: server: fix stream crash due to deleted server

Before a dynamic server can be deleted, a set of preconditions must be
validated to ensure it is not referenced naymore by a stream or a
connection. This is implemented in srv_check_for_deletion().

The various criteria specified were incomplete. This allows a server
instance to be deleted while still be referenced by a stream and a
connection.

This bug was reproduced by using ASAN compilation. A script was used to
add and delete a server every second, while using h2load to generate
traffic with download of 1k objects. Here is the ASAN error.

==140916==ERROR: AddressSanitizer: heap-use-after-free on address 0x520000020080 at pc 0x63cb25679537 bp 0x701529ff5070 sp 0x701529ff5060
READ of size 1 at 0x520000020080 thread T7
    #0 0x63cb25679536 in objt_server include/haproxy/obj_type.h:99
    #1 0x63cb2568f465 in process_stream src/stream.c:1823
    #2 0x63cb25a4a4a2 in run_tasks_from_lists src/task.c:632
    #3 0x63cb25a4bf62 in process_runnable_tasks src/task.c:876
    #4 0x63cb2596a220 in run_poll_loop src/haproxy.c:3050
    #5 0x63cb2596b192 in run_thread_poll_loop src/haproxy.c:3252
    #6 0x701539aa9559  (/usr/lib/libc.so.6+0x8b559) (BuildId: c0caa0b7709d3369ee575fcd7d7d0b0fc48733af)
    #7 0x701539b26a3b  (/usr/lib/libc.so.6+0x108a3b) (BuildId: c0caa0b7709d3369ee575fcd7d7d0b0fc48733af)

To fix this, add <curr_used_conns> to the counters checked in
srv_check_for_deletion().

Outside of this bug, one case which remains sensible is for SF_DIRECT
streams which referenced a server instance early in process_stream()
before connect_server(). This occurs with use-server directive,
force-persist rule or cookie persistence. However, after code
reexamination, the code is considered reliable as process_stream() is
not rescheduled before connect_server() invocation. These observations
have been saved in sess_change_server() documentation to ensure it
remains valid in the future.

This must be backported up to 2.6.

16 months agoBUG/MAJOR: promex: fix crash on deleted server
Amaury Denoyelle [Thu, 22 Feb 2024 13:16:37 +0000 (14:16 +0100)] 
BUG/MAJOR: promex: fix crash on deleted server

Promex applet is used to dump many metrics. Some of them are related to
a server instance. The applet can be interrupted in the middle of a
dump, for example waiting for output buffer space. In this case, its
context is save to resume dump on the correct instance.

A crash can occur if dump is interrupted during servers loop. If the
server instance is deleted during two scheduling of the promex applet,
its context will still referenced the deleted server on resume.

To fix this, use server refcount to prevent its deletion during parsing.

No backport is needed, despite all stable releases being affected. This
is because promex applet context has been recently rewritten to use
generic pointers. As such, a specific commit will be applied for earlier
releases.

16 months agoBUG/MINOR: stats: drop srv refcount on early release
Amaury Denoyelle [Thu, 22 Feb 2024 13:13:45 +0000 (14:13 +0100)] 
BUG/MINOR: stats: drop srv refcount on early release

Server refcount is used to protect from server deletion while dumping a
server instance, for stats dump on both CLI and HTTP applet. However,
dump can be aborted prematurely before reaching the end. In this case,
server refcount is never decremented.

This bug can cause an inconsistency on servers refcount, preventing them
to be deleted even after "del server" success.

To fix this, implement release handler for both stats CLI and HTTP
applet. Drop server reference if dump was interrupted during servers
loop.

This should be backported up to 2.6.

16 months agoBUG/MINOR: ist: allocate nul byte on istdup
Amaury Denoyelle [Wed, 21 Feb 2024 15:10:43 +0000 (16:10 +0100)] 
BUG/MINOR: ist: allocate nul byte on istdup

istdup() is documented as having the same behavior as strdup(). However,
it may cause confusion as it allocates a block of input length, without
an extra byte for \0 delimiter. This behavior is incoherent as in case
of an empty string however a single \0 is allocated.

This API inconsistency could cause a bug anywhere an IST is used as a
C-string after istdup() invocation. Currently, the only found issue is
with 'wait' CLI command using 'srv-unused'. This causes a buffer
overflow due to ist0() invocation after istdup() for be_name and
sv_name.

Backport should be done to all stable releases. Even if no bug has been
found outside of wait CLI implementation, it ensures the code is more
consistent on every releases.

16 months agoBUG/MINOR: log: fix potential lf->name memory leak
Aurelien DARRAGON [Thu, 22 Feb 2024 14:14:21 +0000 (15:14 +0100)] 
BUG/MINOR: log: fix potential lf->name memory leak

Recent commit 2ed6068 ("MINOR: log: custom name for logformat node")
introduced a potential memory leak because when custom name is provided,
lf->name value is allocated using strdup(), thus is expected to be freed
alongside the node when the node is released.

However lf->name was only freed in some common places within log.c
cleanups and helpers func, but in reality there are still cases where
lf nodes are manually freed without making use of freeing helpers.

So this is what this patch does, it makes sure all lf freeing places now
leverage the free_logformat_node() helper function that takes care of
freeing all known allocated elements within the node, including custom
name.

This commit depends on:
 - "MINOR: log: add free_logformat_node() helper function"

No backport needed unless 2ed6068 gets backported.

16 months agoMINOR: log: add free_logformat_node() helper function
Aurelien DARRAGON [Thu, 22 Feb 2024 14:03:29 +0000 (15:03 +0100)] 
MINOR: log: add free_logformat_node() helper function

Function may be used to free a single logformat node.

16 months agoCLEANUP: log: use free_logformat_list() in parse_logformat_string()
Aurelien DARRAGON [Thu, 22 Feb 2024 14:08:33 +0000 (15:08 +0100)] 
CLEANUP: log: use free_logformat_list() in parse_logformat_string()

This is a follow up for 24a5e42db6 ("CLEANUP: log: deinitialization of
the log buffer in one function") as there was another opportunity to
make use of the new cleanup function.

16 months agoCLEANUP: log: fix process_send_log() indentation
Aurelien DARRAGON [Thu, 22 Feb 2024 09:53:39 +0000 (10:53 +0100)] 
CLEANUP: log: fix process_send_log() indentation

Fix bad indentation for process_send_log() prototype (tab was used instead
of spaces)

16 months agoCLEANUP: proxy/log: remove unused proxy flag
Aurelien DARRAGON [Wed, 21 Feb 2024 14:09:08 +0000 (15:09 +0100)] 
CLEANUP: proxy/log: remove unused proxy flag

Since 3d6350e10 ("MINOR: log: Remove log-error-via-logformat option"),
PR_O_ERR_LOGFMT flag is not used anymore, but it was left in the proxy-t.h
header file. Simply removing it and adding a comment to indicate that the
corresponding bit is now unused.

16 months agoBUG/MEDIUM: mux-h1: Don't emit 0-CRLF chunk in h1_done_ff() when iobuf is empty
Christopher Faulet [Wed, 21 Feb 2024 08:30:46 +0000 (09:30 +0100)] 
BUG/MEDIUM: mux-h1: Don't emit 0-CRLF chunk in h1_done_ff() when iobuf is empty

A chunk message transferred via zero-copy forwarding in H1 may be
corrupted. This only happens when the chunk size is not known during the
nego stage and when there is nothing to forward when h1_donn_ff() is
called. In this case, we always emit a chunk. Because there is nothing to
forward, a 0-CRLF is emitted in the middle of the message.

The issue occurred with the HTTP stats applet only.

A simple fix is to check the size of data in the iobuf before emitting a new
chunk in h1_done_ff(). However, we still try to send outgoing data because
when this happens, it is most of time because the H1 output buffer is almost
full.

This patch should fix the issue #2453. No backport needed.

16 months agoBUG/MINOR: quic: initialize msg_flags before sendmsg
Amaury Denoyelle [Wed, 21 Feb 2024 09:05:14 +0000 (10:05 +0100)] 
BUG/MINOR: quic: initialize msg_flags before sendmsg

Previously, msghdr struct used for sendmsg was memset to 0. This was
updated for performance reason with each members individually defined.
This is done by the following commit :

  commit 107d6d75465419a09d90c790edb617091a04468a
  OPTIM: quic: improve slightly qc_snd_buf() internal

msg_flags is the only member unset, as sendmsg manual page reports that
it is unused. However, this caused a coverity report. In the end, it is
better to explicitely set it to 0 to avoid any future interrogations,
compiler warning or even portability issues.

This should fix coverity report from github issue #2455.

No need to backport unless above patch is.

16 months agoBUILD: applet: fix build on some 32-bit archs
Willy Tarreau [Wed, 21 Feb 2024 03:16:16 +0000 (04:16 +0100)] 
BUILD: applet: fix build on some 32-bit archs

The to_forward field was added to debugging output of applets with commit
62a81cb6a ("MINOR: applet: Add callback function to deal with zero-copy
forwarding"), though it's a size_t printed as %lu, which causes complaints
on 32-bit archs. Let's just cast as %lu.

No backport is needed.

16 months agoMINOR: quic: only use sendmsg() syscall variant
Amaury Denoyelle [Tue, 20 Feb 2024 09:44:48 +0000 (10:44 +0100)] 
MINOR: quic: only use sendmsg() syscall variant

This patch is the direct followup of the previous one :
  MINOR: quic: remove sendto() usage variant

This finalizes qc_snd_buf() simplification by removing send() syscall
usage for quic-conn owned socket. Syscall invocation is merged in a
single code location to the sendmsg() variant.

The only difference for owned socket is that destination address for
sendmsg() is set to NULL. This usage is documented in man 2 sendmsg as
valid for connected sockets. This allows maximum performance by avoiding
unnecessary lookups on kernel socket address tables.

As the previous patch, no functional change should happen here. However,
it will be simpler to extend qc_snd_buf() for GSO usage.

16 months agoMINOR: quic: remove sendto() usage variant
Amaury Denoyelle [Mon, 19 Feb 2024 14:29:48 +0000 (15:29 +0100)] 
MINOR: quic: remove sendto() usage variant

qc_snd_buf() is a wrapper around emission syscalls. Given QUIC
configuration, a different variant is used. When using connection
socket, send() is the only used. For listener sockets, sendmsg() and
sendto() are possible. The first one is used only if local address has
been retrieved prior. This allows to fix it on sending to guarantee the
source address selection. Finally, sendto() is used for systems which do
not support local address retrieval.

All of these variants render the code too complex. As such, this patch
simplifies this by removing sendto() alternative. Now, sendmsg() is
always used for listener sockets. Source address is then specified only
if supported by the system.

This patch should not exhibit functional behavior changes. It will be
useful when implementing GSO as the code is now simpler.

16 months agoMINOR: quic: move IP_PKTINFO on send on a dedicated function
Amaury Denoyelle [Mon, 19 Feb 2024 14:21:13 +0000 (15:21 +0100)] 
MINOR: quic: move IP_PKTINFO on send on a dedicated function

When using listener socket, source address for emission is explicitely
set using ancillary data for sendmsg(). This is useful to guarantee the
correct address is used when binding on a non-explicit address.

This code was implemented directly under qc_snd_buf(). However, it is
quite complex due to portability issue. For IPv4, two parallel
implementations coexist, defined under IP_PKTINFO or IP_RECVDSTADDR. For
IPv6, another option is defined under IPV6_RECVPKTINFO. Each variant
uses its distinct name which increase the code complexity.

Extract ancillary data filling in a dedicated function named
cmsg_set_saddr(). This reduces greatly the body of qc_snd_buf(). Such
functions can be replicated when other ancillary data type will be
implemented. This will notably be useful for GSO implementation.

16 months agoOPTIM: quic: improve slightly qc_snd_buf() internal
Amaury Denoyelle [Tue, 20 Feb 2024 10:23:17 +0000 (11:23 +0100)] 
OPTIM: quic: improve slightly qc_snd_buf() internal

qc_snd_buf() is a wrapper for sendmsg() syscall (or its derivatives)
used for all QUIC emissions. This patch aims at removing several
non-optimal code sections :

* fd_send_ready() for connected sockets is only checked on the function
  preambule instead of inside the emission loop

* zero-ing msghdr structure for unconnected sockets is removed. This is
  unnecessary as all fields are properly initialized then.

* extra memcpy/memset invocations when using IP_PKTINFO/IPV6_RECVPKTINFO
  are removed by setting directly the address value into cmsg buffer

16 months agoMINOR: quic: warn on bind on multiple addresses if no IP_PKTINFO support
Amaury Denoyelle [Fri, 16 Feb 2024 14:40:06 +0000 (15:40 +0100)] 
MINOR: quic: warn on bind on multiple addresses if no IP_PKTINFO support

Binding on multiple addresses for QUIC is safe only if IP_PKTINFO or
equivalent is available. Else, the behavior may be undefined as the
system is responsible to choose the network interface and source address
on response.

This commit adds a warning on boot if no or partial support for
IP_PKTINFO or equivalent is detected and configuration contains UDP
binding on multiple addresses.

This should be backported up to 2.6. Special backport recommdations :
* change ha_warning() to ha_diag_warning() to ensure no spurrious
  warnings will be triggered on stable releases
* IP_PKTINFO usage was introduced on 2.7. For 2.6, multiple addresses
  QUIC binding is always unreliable. As such, preprocessor condition
  must simply be removed so that the warning is always active regarding
  of the system. Warning message should also be truncated to suppress
  IP_PKTINFO reference.

16 months agoDOC: quic: fix recommandation for bind on multiple address
Amaury Denoyelle [Thu, 15 Feb 2024 17:43:44 +0000 (18:43 +0100)] 
DOC: quic: fix recommandation for bind on multiple address

Documentation falsely mentions that binding on multiple addresses is
forbidden for QUIC listeners. This is not the case. Moreover, this
behavior is reliable when using destination address retrieval on receive
via IP_PKTINFO, which allows to determine the proper source address for
response.

This should be backported up to 2.7. On 2.6 specific source address
definition on sendmsg via IP_PKTINFO is not implemented. As such, bind
on multiple addresses should remain forbidden for this release.

16 months agoMINOR: log: automate string array construction in sess_build_logline()
Aurelien DARRAGON [Wed, 31 Jan 2024 13:37:07 +0000 (14:37 +0100)] 
MINOR: log: automate string array construction in sess_build_logline()

make it so string array construction is performed by dedicated macro
helpers instead of manual char insertion between string members.

The goal is to easily be able to support multiple forms of array
construction depending on the data encoding format (raw, json..).

Only %hrl and %hsl logformats are concerned.

16 months agoMINOR: log: print metadata prefixes separately in sess_build_logline()
Aurelien DARRAGON [Tue, 30 Jan 2024 17:01:15 +0000 (18:01 +0100)] 
MINOR: log: print metadata prefixes separately in sess_build_logline()

Some log variables may be prefixed with specific chars that represent
extra informations that are relevant with it but are are not directly
part of the "raw" value.

ie: '+' char is prepended before some values when "option logasap" is
used to indicate that the value has not yet reached its final value.

However, as those "metadata" are printed using the general purpose
LOGCHAR() printing helper, it's not easy to tell if they are part of the
base value or not.

In this patch we add the LOGMETACHAR() helper that is a wrapper for
LOGCHAR(). The goal is to prepare for adding some logic to prevent such
additional infos from being generated when not relevant or needed.

16 months agoMINOR: log: simplify quotes handling in sess_build_logline()
Aurelien DARRAGON [Wed, 10 Jan 2024 18:14:25 +0000 (19:14 +0100)] 
MINOR: log: simplify quotes handling in sess_build_logline()

quotes building for some log formats is directly performed under each
switch case statement so it would become painful to add other conditions
to prevent the quotes from being generated when it's not supported by the
the data encoding format for instance (ie: JSON).

Let's centralize and simplify quotes handling by adding LOGQUOTE_START()
and LOGQUOTE_END() helper macros. If a quotation is started and not
explicitly ended, it will be automatically ended at the end of the current
logformat node:

LOGQUOTE_START() sets 'quote' variable to 1, this way LOGQUOTE_END() only
prints the ending quote when needed. LOGQUOTE_END() is systematically
called after each node switch-case (after each value). LOGQUOTE_START()
does nothing if LOG_OPT_QUOTE isn't set, so does LOGQUOTE_END().

Some rare cases such as %hsl (list of captured headers) required special
handling: in this case multiple quoted texts are generated for the same
field value so explicit LOGQUOTE_START() + LOGQUOTE_END() combination was
needed.

16 months agoMINOR: log: simplify last_isspace in sess_build_logline()
Aurelien DARRAGON [Wed, 10 Jan 2024 16:41:47 +0000 (17:41 +0100)] 
MINOR: log: simplify last_isspace in sess_build_logline()

last_isspace variable is explicitly set to 0 in all cases except
LOG_FMT_SEPARATOR case. So we can actually simplify the code by setting
last_isspace to 0 by default and skipping the assignment for the
LOG_FMT_SEPARATOR case.

16 months agoMINOR: log: explicit typecasting for logformat nodes
Aurelien DARRAGON [Tue, 20 Feb 2024 09:29:49 +0000 (10:29 +0100)] 
MINOR: log: explicit typecasting for logformat nodes

Add the ability to manually specify desired output type after a custom
field name for logformat nodes. Forcing the type can be useful to ensure
value is stored with the proper type representation. (i.e.: forcing
numerical to string to work around the limited resolution of JS number
types)

By default, type is set to SMP_T_SAME, which means the original type will
be preserved.

Currently supported types are: bool, str, sint

16 months agoMINOR: sample: add type_to_smp() helper function
Aurelien DARRAGON [Wed, 10 Jan 2024 13:00:15 +0000 (14:00 +0100)] 
MINOR: sample: add type_to_smp() helper function

type_to_smp(type) does the reverse operation of smp_to_type[smp]: it takes
a type name as input string and tries to return the corresponding SMP_T_*
smp type or SMP_TYPES if not found.