]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
2 years agoMEDIUM: hlua: introduce tune.lua.burst-timeout
Aurelien DARRAGON [Thu, 6 Apr 2023 20:51:56 +0000 (22:51 +0200)] 
MEDIUM: hlua: introduce tune.lua.burst-timeout

The "burst" execution timeout applies to any Lua handler.
If the handler fails to finish or yield before timeout is reached,
handler will be aborted to prevent thread contention, to prevent
traffic from not being served for too long, and ultimately to prevent
the process from crashing because of the watchdog kicking in.

Default value is 1000ms.
Combined with forced-yield default value of 10000 lua instructions, it
should be high enough to prevent any existing script breakage, while
still being able to catch slow lua converters or sample fetches
doing thread contention and risking the process stability.

Setting value to 0 completely bypasses this check. (not recommended but
could be required to restore original behavior if this feature breaks
existing setups somehow...)

No backport needed, although it could be used to prevent watchdog crashes
due to poorly coded (slow/cpu consuming) lua sample fetches/converters.

2 years agoMEDIUM: hlua: reliable timeout detection
Aurelien DARRAGON [Fri, 25 Nov 2022 08:10:07 +0000 (09:10 +0100)] 
MEDIUM: hlua: reliable timeout detection

For non yieldable lua handlers (converters, fetches or yield
incompatible lua functions), current timeout detection relies on now_ms
thread local variable.

But within non-yieldable contexts, now_ms won't be updated if not by us
(because we're momentarily stuck in lua context so we won't
re-enter the polling loop, which is responsible for clock updates).

To circumvent this, clock_update_date(0, 1) was manually performed right
before now_ms is being read for the timeout checks.

But this fails to work consistently, because if no other concurrent
threads periodically run clock_update_global_date(), which do happen if
we're the only active thread (nbthread=1 or low traffic), our
clock_update_date() call won't reliably update our local now_ms variable

Moreover, clock_update_date() is not the right tool for this anyway, as
it was initially meant to be used from the polling context.
Using it could have negative impact on other threads relying on now_ms
to be stable. (because clock_update_date() performs global clock update
from time to time)

-> Introducing hlua multipurpose timer, which is internally based on
now_cpu_time_fast() that provides per-thread consistent clock readings.

Thanks to this new hlua timer API, hlua timeout logic is less error-prone
and more robust.

This allows the timeout detection to work as expected for both yieldable
and non-yieldable lua handlers.

This patch depends on commit "MINOR: clock: add now_cpu_time_fast() function"

While this could theorically be backported to all stable versions,
it is advisable to avoid backports unless we're confident enough
since it could cause slight behavior changes (timing related) in
existing setups.

2 years agoMINOR: clock: add now_cpu_time_fast() function
Aurelien DARRAGON [Tue, 4 Apr 2023 15:21:40 +0000 (17:21 +0200)] 
MINOR: clock: add now_cpu_time_fast() function

Same as now_cpu_time(), but for fast queries (less accurate)
Relies on now_cpu_time() and now_mono_time_fast() is used
as a cache expiration hint to prevent now_cpu_time() from being
called too often since it is known to be quite expensive.

Depends on commit "MINOR: clock: add now_mono_time_fast() function"

2 years agoMINOR: clock: add now_mono_time_fast() function
Aurelien DARRAGON [Fri, 25 Nov 2022 07:56:46 +0000 (08:56 +0100)] 
MINOR: clock: add now_mono_time_fast() function

Same as now_mono_time(), but for fast queries (less accurate)
Relies on coarse clock source (also known as fast clock source on
some systems).

Fallback to now_mono_time() if coarse source is not supported on the system.

2 years agoBUG/MINOR: cfgparse: make sure to include openssl-compat
Willy Tarreau [Wed, 19 Apr 2023 08:41:55 +0000 (10:41 +0200)] 
BUG/MINOR: cfgparse: make sure to include openssl-compat

Commit 5003ac7fe ("MEDIUM: config: set useful ALPN defaults for HTTPS
and QUIC") revealed a build dependency bug: if QUIC is not enabled,
cfgparse doesn't have any dependency on the SSL stack, so the various
ifdefs that try to check special conditions such as rejecting an H2
config with too small a bufsize, are silently ignored. This was
detected because the default ALPN string was not set and caused the
alpn regtest to fail without QUIC support. Adding openssl-compat to
the list of includes seems to be sufficient to have what we need.

It's unclear when this dependency was broken, it seems that even 2.2
didn't have an explicit dependency on anything SSL-related, though it
could have been inherited through other files (as happens with QUIC
here). It would be safe to backport it to all stable branches. The
impact is very low anyway.

2 years agoBUG/MEDIUM: quic: prevent crash on Retry sending
Amaury Denoyelle [Wed, 19 Apr 2023 08:04:41 +0000 (10:04 +0200)] 
BUG/MEDIUM: quic: prevent crash on Retry sending

The following commit introduced a regression :
  commit 1a5cc19cecfa84bfd0fdd7b9d5d20899cce40662
  MINOR: quic: adjust Rx packet type parsing

Since this commit, qv variable was left to NULL as version is stored
directly in quic_rx_packet instance. In most cases, this only causes
traces to skip version printing. However, qv is dereferenced when
sending a Retry which causes a segfault.

To fix this, simply remove qv variable and use pkt->version instead,
both for traces and send_retry() invocation.

This bug was detected thanks to QUIC interop runner. It can easily be
reproduced by using quic-force-retry on the bind line.

This must be backported up to 2.7.

2 years agoMEDIUM: config: set useful ALPN defaults for HTTPS and QUIC
Willy Tarreau [Wed, 19 Apr 2023 07:12:33 +0000 (09:12 +0200)] 
MEDIUM: config: set useful ALPN defaults for HTTPS and QUIC

This commit makes sure that if three is no "alpn", "npn" nor "no-alpn"
setting on a "bind" line which corresponds to an HTTPS or QUIC frontend,
we automatically turn on "h2,http/1.1" as an ALPN default for an HTTP
listener, and "h3" for a QUIC listener. This simplifies the configuration
for end users since they won't have to explicitly configure the ALPN
string to enable H2, considering that at the time of writing, HTTP/1.1
represents less than 7% of the traffic on large infrastructures. The
doc and regtests were updated. For more info, refer to the following
thread:

  https://www.mail-archive.com/haproxy@formilux.org/msg43410.html

2 years agoMINOR: ssl_crtlist: dump "no-alpn" on "show crtlist" when "no-alpn" was set
Willy Tarreau [Wed, 19 Apr 2023 07:07:47 +0000 (09:07 +0200)] 
MINOR: ssl_crtlist: dump "no-alpn" on "show crtlist" when "no-alpn" was set

Instead of dumping "alpn " better show "no-alpn" as configured.

2 years agoMINOR: ssl: do not set ALPN callback with the empty string
Willy Tarreau [Wed, 19 Apr 2023 07:05:49 +0000 (09:05 +0200)] 
MINOR: ssl: do not set ALPN callback with the empty string

While it does not have any effect, it's better not to try to setup an
ALPN callback nor to try to lookup algorithms when the configured ALPN
string is empty as a result of "no-alpn" being used.

2 years agoDOC: add missing documentation for "no-alpn" on bind lines
Willy Tarreau [Wed, 19 Apr 2023 07:10:47 +0000 (09:10 +0200)] 
DOC: add missing documentation for "no-alpn" on bind lines

This is the doc for the no-alpn keyword that was mistakenly left out of
commit 158c18e85 ("MINOR: config: add "no-alpn" support for bind lines").

2 years agoREGTESTS: add a new "ssl_alpn" test to test ALPN negotiation
Willy Tarreau [Wed, 19 Apr 2023 06:34:01 +0000 (08:34 +0200)] 
REGTESTS: add a new "ssl_alpn" test to test ALPN negotiation

This teg-test verifies that different ALPN values on the "server" line
will negotiate the expected protocol depending on the ALPN "bind" line.

2 years agoMINOR: config: add "no-alpn" support for bind lines
Willy Tarreau [Wed, 19 Apr 2023 06:28:40 +0000 (08:28 +0200)] 
MINOR: config: add "no-alpn" support for bind lines

It's possible to replace a previously set ALPN but not to disable ALPN
if it was previously set. The new "no-alpn" setting allows to disable
a previously set ALPN setting by preparing an empty one that will be
replaced and freed when the config is validated.

2 years agoBUG/MEDIUM: stconn: Propagate error on the SC on sending path
Christopher Faulet [Tue, 18 Apr 2023 16:38:32 +0000 (18:38 +0200)] 
BUG/MEDIUM: stconn: Propagate error on the SC on sending path

On sending path, a pending error can be promoted to a terminal error at the
endpoint level (SE_FL_ERR_PENDING to SE_FL_ERROR). When this happens, we
must propagate the error on the SC to be able to handle it at the stream
level and eventually forward it to the other side.

Because of this bug, it is possible to freeze sessions, for instance on the
CLI.

It is a 2.8-specific issue. No backport needed.

2 years agoCLEANUP: cli: Remove useless debug message in cli_io_handler()
Christopher Faulet [Tue, 18 Apr 2023 16:36:43 +0000 (18:36 +0200)] 
CLEANUP: cli: Remove useless debug message in cli_io_handler()

When compiled in debug mode, HAProxy prints a debug message at the end of
the cli I/O handle. It is pretty annoying and useless because, we can active
applet traces. Thus, just remove it.

2 years agoCLEANUP: backend: Remove useless debug message in assign_server()
Christopher Faulet [Tue, 18 Apr 2023 16:25:09 +0000 (18:25 +0200)] 
CLEANUP: backend: Remove useless debug message in assign_server()

When compiled in debug mode, HAProxy prints a debug message at the beginning
of assign_server(). It is pretty annoying and useless because, in debug
mode, we can active stream traces. Thus, just remove it.

2 years agoBUG/MINOR: http-ana: Update analyzers on both sides when switching in TUNNEL mode
Christopher Faulet [Tue, 18 Apr 2023 09:01:51 +0000 (11:01 +0200)] 
BUG/MINOR: http-ana: Update analyzers on both sides when switching in TUNNEL mode

The commit 9704797fa ("BUG/MEDIUM: http-ana: Properly switch the request in
tunnel mode on upgrade") fixes the switch in TUNNEL mode, but only
partially. Because both channels are switch in TUNNEL mode in same time on
one side, the channel's analyzers on the opposite side are not updated
accordingly. This prevents the tunnel timeout to be applied.

So instead of updating both sides in same time, we only force the analysis
on the other side by setting CF_WAKE_ONCE flag when a channel is switched in
TUNNEL mode. In addition, we must take care to forward all data if there is
no DATAa TCP filters registered.

This patch is related to the issue #2125. It is 2.8-specific. No backport
needed.

2 years agoMINOR: listener: remove unneeded local accept flag
Amaury Denoyelle [Wed, 5 Apr 2023 16:14:51 +0000 (18:14 +0200)] 
MINOR: listener: remove unneeded local accept flag

Remove the receiver RX_F_LOCAL_ACCEPT flag. This was used by QUIC
protocol before thread rebinding was supported by the quic_conn layer.

This should be backported up to 2.7 after the previous patch has also
been taken.

2 years agoMAJOR: quic: support thread balancing on accept
Amaury Denoyelle [Wed, 5 Apr 2023 16:17:51 +0000 (18:17 +0200)] 
MAJOR: quic: support thread balancing on accept

Before this patch, QUIC protocol used a custom add_listener callback.
This was because a quic_conn instance was allocated before accept. Its
thread affinity was fixed and could not be changed after. The thread was
derived itself from the CID selected by the client which prevent an even
repartition of QUIC connections on multiple threads.

A series of patches was introduced with a lot of changes. The most
important ones :
* removal of affinity between an encoded CID and a thread
* possibility to rebind a quic_conn on a new thread

Thanks to this, it's possible to suppress the custom add_listener
callback. Accept is conducted for QUIC protocol as with the others. A
less loaded thread is selected on listener_accept() and the connection
stack is bind on it. This operation implies that quic_conn instance is
moved to the new thread using the set_affinity QUIC protocol callback.

To reactivate quic_conn instance after thread rebind,
qc_finalize_affinity_rebind() is called after accept on the new thread
by qc_xprt_start() through accept_queue_process() / session_accept_fd().

This should be backported up to 2.7 after a period of observation.

2 years agoMINOR: quic: properly finalize thread rebinding
Amaury Denoyelle [Tue, 11 Apr 2023 12:42:31 +0000 (14:42 +0200)] 
MINOR: quic: properly finalize thread rebinding

When a quic_conn instance is rebinded on a new thread its tasks and
tasklet are destroyed and new ones created. Its socket is also migrated
to a new thread which stop reception on it.

To properly reactivate a quic_conn after rebind, wake up its tasks and
tasklet if they were active before thread rebind. Also reactivate
reading on the socket FD. These operations are implemented on a new
function qc_finalize_affinity_rebind().

This should be backported up to 2.7 after a period of observation.

2 years agoBUG/MINOR: quic: transform qc_set_timer() as a reentrant function
Amaury Denoyelle [Tue, 11 Apr 2023 12:43:42 +0000 (14:43 +0200)] 
BUG/MINOR: quic: transform qc_set_timer() as a reentrant function

qc_set_timer() function is used to rearm the timer for loss detection
and probing. Previously, timer was always rearm when congestion window
was free due to a wrong interpretation of the RFC which mandates the
client to rearm the timer before handshake completion to avoid a
deadlock related to anti-amplification.

Fix this by removing this code from quic_pto_pktns(). This allows
qc_set_timer() to be reentrant and only activate the timer if needed.

The impact of this bug seems limited. It can probably caused the timer
task to be processed too frequently which could caused too frequent
probing.

This change will allow to reuse easily qc_set_timer() after quic_conn
thread migration. As such, the new timer task will be scheduled only if
needed.

This should be backported up to 2.6.

2 years agoMEDIUM: quic: implement thread affinity rebinding
Amaury Denoyelle [Wed, 5 Apr 2023 15:52:05 +0000 (17:52 +0200)] 
MEDIUM: quic: implement thread affinity rebinding

Implement a new function qc_set_tid_affinity(). This function is
responsible to rebind a quic_conn instance to a new thread.

This operation consists mostly of releasing existing tasks and tasklet
and allocating new instances on the new thread. If the quic_conn uses
its owned socket, it is also migrated to the new thread. The migration
is finally completed with updated the CID TID to the new thread. After
this step, the connection is thus accessible to the new thread and
cannot be access anymore on the old one without risking race condition.

To ensure rebinding is either done completely or not at all, tasks and
tasklet are pre-allocated before all operations. If this fails, an error
is returned and rebiding is not done.

To destroy the older tasklet, its context is set to NULL before wake up.
In I/O callbacks, a new function qc_process() is used to check context
and free the tasklet if NULL.

The thread rebinding can cause a race condition if the older thread
quic_dghdlrs::dgrams list contains datagram for the connection after
rebinding is done. To prevent this, quic_rx_pkt_retrieve_conn() always
check if the packet CID is still associated to the current thread or
not. In the latter case, no connection is returned and the new thread is
returned to allow to redispatch the datagram to the new thread in a
thread-safe way.

This should be backported up to 2.7 after a period of observation.

2 years agoMINOR: quic: delay post handshake frames after accept
Amaury Denoyelle [Tue, 11 Apr 2023 14:46:03 +0000 (16:46 +0200)] 
MINOR: quic: delay post handshake frames after accept

When QUIC handshake is completed on our side, some frames are prepared
to be sent :
* HANDSHAKE_DONE
* several NEW_CONNECTION_ID with CIDs allocated

This step was previously executed in quic_conn_io_cb() directly after
CRYPTO frames parsing. This patch delays it to be completed after
accept. Special care have been taken to ensure it is still functional
with 0-RTT activated.

For the moment, this patch should have no impact. However, when
quic_conn thread migration on accept will be implemented, it will be
easier to remap only one CID to the new thread. New CIDs will be
allocated after migration on the new thread.

This should be backported up to 2.7 after a period of observation.

2 years agoMINOR: protocol: define new callback set_affinity
Amaury Denoyelle [Wed, 5 Apr 2023 16:16:28 +0000 (18:16 +0200)] 
MINOR: protocol: define new callback set_affinity

Define a new protocol callback set_affinity. This function is used
during listener_accept() to notify about a rebind on a new thread just
before pushing the connection on the selected thread queue. If the
callback fails, accept is done locally.

This change will be useful for protocols with state allocated before
accept is done. For the moment, only QUIC protocol is concerned. This
will allow to rebind the quic_conn to a new thread depending on its
load.

This should be backported up to 2.7 after a period of observation.

2 years agoMINOR: quic: do not proceed to accept for closing conn
Amaury Denoyelle [Mon, 17 Apr 2023 07:31:16 +0000 (09:31 +0200)] 
MINOR: quic: do not proceed to accept for closing conn

Each quic_conn is inserted in an accept queue to allocate the upper
layers. This is done through a listener tasklet in
quic_sock_accept_conn().

This patch interrupts the accept process for a quic_conn in
closing/draining state. Indeed, this connection will soon be closed so
it's unnecessary to allocate a complete stack for it.

This patch will become necessary when thread migration is implemented.
Indeed, it won't be allowed to proceed to thread migration for a closing
quic_conn.

This should be backported up to 2.7 after a period of observation.

2 years agoMEDIUM: quic: handle conn bootstrap/handshake on a random thread
Amaury Denoyelle [Thu, 13 Apr 2023 15:42:34 +0000 (17:42 +0200)] 
MEDIUM: quic: handle conn bootstrap/handshake on a random thread

TID encoding in CID was removed by a recent change. It is now possible
to access to the <tid> member stored in quic_connection_id instance.

For unknown CID, a quick solution was to redispatch to the thread
corresponding to the first CID byte. This ensures that an identical CID
will always be handled by the same thread to avoid creating multiple
same connection. However, this forces an uneven load repartition which
can be critical for QUIC handshake operation.

To improve this, remove the above constraint. An unknown CID is now
handled by its receiving thread. However, this means that if multiple
packets are received with the same unknown CID, several threads will try
to allocate the same connection.

To prevent this race condition, CID insertion in global tree is now
conducted first before creating the connection. This is a thread-safe
operation which can only be executed by a single thread. The thread
which have inserted the CID will then proceed to quic_conn allocation.
Other threads won't be able to insert the same CID : this will stop the
treatment of the current packet which is redispatch to the now owning
thread.

This should be backported up to 2.7 after a period of observation.

2 years agoMINOR: quic: remove TID encoding in CID
Amaury Denoyelle [Thu, 13 Apr 2023 15:34:56 +0000 (17:34 +0200)] 
MINOR: quic: remove TID encoding in CID

CIDs were moved from a per-thread list to a global list instance. The
TID-encoded is thus non needed anymore.

This should be backported up to 2.7 after a period of observation.

2 years agoMEDIUM: quic: use a global CID trees list
Amaury Denoyelle [Tue, 18 Apr 2023 09:10:54 +0000 (11:10 +0200)] 
MEDIUM: quic: use a global CID trees list

Previously, quic_connection_id were stored in a per-thread tree list.
Datagram were first dispatched to the correct thread using the encoded
TID before a tree lookup was done.

Remove these trees and replace it with a global trees list of 256
entries. A CID is using the list index corresponding to its first byte.
On datagram dispatch, CID is lookup on its tree and TID is retrieved
using new member quic_connection_id.tid. As such, a read-write lock
protects each list instances. With 256 entries, it is expected that
contention should be reduced.

A new structure quic_cid_tree served as a tree container associated with
its read-write lock. An API is implemented to ensure lock safety for
insert/lookup/delete operation.

This patch is a step forward to be able to break the affinity between a
CID and a TID encoded thread. This is required to be able to migrate a
quic_conn after accept to select thread based on their load.

This should be backported up to 2.7 after a period of observation.

2 years agoMINOR: quic: remove TID ref from quic_conn
Amaury Denoyelle [Thu, 13 Apr 2023 09:48:38 +0000 (11:48 +0200)] 
MINOR: quic: remove TID ref from quic_conn

Remove <tid> member in quic_conn. This is moved to quic_connection_id
instance.

For the moment, this change has no impact. Indeed, qc.tid reference
could easily be replaced by tid as all of this work was already done on
the connection thread. However, it is planified to support quic_conn
thread migration in the future, so removal of qc.tid will simplify this.

This should be backported up to 2.7.

2 years agoMINOR: quic: adjust quic CID derive API
Amaury Denoyelle [Thu, 13 Apr 2023 13:26:18 +0000 (15:26 +0200)] 
MINOR: quic: adjust quic CID derive API

ODCID are never stored in the CID tree. Instead, we store our generated
CID which is directly derived from the CID using a hash function. This
operation is done via quic_derive_cid().

Previously, generated CID was returned as a 64-bits integer. However,
this is cumbersome to convert as an array of bytes which is the most
common CID representation. Adjust this by modifying return type to a
quic_cid struct.

This should be backported up to 2.7.

2 years agoMINOR: quic: adjust Rx packet type parsing
Amaury Denoyelle [Mon, 17 Apr 2023 13:03:51 +0000 (15:03 +0200)] 
MINOR: quic: adjust Rx packet type parsing

qc_parse_hd_form() is the function used to parse the first byte of a
packet and return its type and version. Its API has been simplified with
the following changes :
* extra out paremeters are removed (long_header and version). All infos
  are now stored directly in quic_rx_packet instance
* a new dummy version is declared in quic_versions array with a 0 number
  code. This can be used to match Version negotiation packets.
* a new default packet type is defined QUIC_PACKET_TYPE_UNKNOWN to be
  used as an initial value.

Also, the function has been exported to an include file. This will be
useful to be able to reuse on quic-sock to parse the first packet of a
datagram.

This should be backported up to 2.7.

2 years agoMINOR: quic: remove uneeded tasklet_wakeup after accept
Amaury Denoyelle [Tue, 11 Apr 2023 13:08:09 +0000 (15:08 +0200)] 
MINOR: quic: remove uneeded tasklet_wakeup after accept

No need to explicitely wakeup quic-conn tasklet after accept is done.

This should be backported up to 2.7.

2 years agoCLEANUP: quic: rename quic_connection_id vars
Amaury Denoyelle [Wed, 12 Apr 2023 08:04:49 +0000 (10:04 +0200)] 
CLEANUP: quic: rename quic_connection_id vars

Two different structs exists for QUIC connection ID :
* quic_connection_id which represents a full CID with its sequence
  number
* quic_cid which is just a buffer with a length. It is contained in the
  above structure.

To better differentiate them, rename all quic_connection_id variable
instances to "conn_id" by contrast to "cid" which is used for quic_cid.

This should be backported up to 2.7.

2 years agoCLEANUP: quic: remove unused qc param on stateless reset token
Amaury Denoyelle [Wed, 12 Apr 2023 13:48:51 +0000 (15:48 +0200)] 
CLEANUP: quic: remove unused qc param on stateless reset token

Remove quic_conn instance as first parameter of
quic_stateless_reset_token_init() and quic_stateless_reset_token_cpy()
functions. It was only used for trace purpose.

The main advantage is that it will be possible to allocate a QUIC CID
without a quic_conn instance using new_quic_cid() which is requires to
first check if a CID is existing before allocating a connection.

This should be backported up to 2.7.

2 years agoCLEANUP: quic: remove unused scid_node
Amaury Denoyelle [Wed, 12 Apr 2023 14:43:30 +0000 (16:43 +0200)] 
CLEANUP: quic: remove unused scid_node

Remove unused scid_node member for quic_conn structure. It was prepared
for QUIC backend support.

This should be backported up to 2.7.

2 years agoCLEANUP: quic: remove unused QUIC_LOCK label
Amaury Denoyelle [Mon, 3 Apr 2023 13:06:43 +0000 (15:06 +0200)] 
CLEANUP: quic: remove unused QUIC_LOCK label

QUIC_LOCK label is never used. Indeed, lock usage is minimal on QUIC as
every connection is pinned to its owned thread.

This should be backported up to 2.7.

2 years agoBUG/MINOR: task: allow to use tasklet_wakeup_after with tid -1
Amaury Denoyelle [Thu, 13 Apr 2023 09:48:50 +0000 (11:48 +0200)] 
BUG/MINOR: task: allow to use tasklet_wakeup_after with tid -1

Adjust BUG_ON() statement to allow tasklet_wakeup_after() for tasklets
with tid pinned to -1 (the current thread). This is similar to
tasklet_wakeup().

This should be backported up to 2.6.

2 years agoMINOR: mux-h2: make the max number of concurrent streams configurable per side
Willy Tarreau [Tue, 18 Apr 2023 13:57:03 +0000 (15:57 +0200)] 
MINOR: mux-h2: make the max number of concurrent streams configurable per side

For a long time the maximum number of concurrent streams was set once for
both sides (front and back) while the impacts are different. This commit
allows it to be configured separately for each side. The older settings
remains the fallback choice when other ones are not set.

2 years agoMINOR: mux-h2: make the initial window size configurable per side
Willy Tarreau [Mon, 17 Apr 2023 13:04:34 +0000 (15:04 +0200)] 
MINOR: mux-h2: make the initial window size configurable per side

For a long time the initial window size (per-stream size) was set once
for both directions, frontend and backend, resulting in a tradeoff between
upload speed and download fairness. This commit allows it to be configured
separately for each side. The older settings remains the fallback choice
when other ones are not set.

2 years agoMINOR: stconn: Propagate EOS from an applet to the attached stream-connector
Christopher Faulet [Mon, 17 Apr 2023 15:32:43 +0000 (17:32 +0200)] 
MINOR: stconn: Propagate EOS from an applet to the attached stream-connector

In the same way than for a stream-connector attached to a mux, an EOS is now
propagated from an applet to its stream-connector. To do so, sc_applet_eos()
function is added.

2 years agoMINOR: stconn: Propagate EOS from a mux to the attached stream-connector
Christopher Faulet [Mon, 17 Apr 2023 15:29:29 +0000 (17:29 +0200)] 
MINOR: stconn: Propagate EOS from a mux to the attached stream-connector

Now there is a SC flag to state the endpoint has reported an end-of-stream,
it is possible to distinguish an EOS from an abort at the stream-connector
level.

sc_conn_read0() function is renamed to sc_conn_eos() and it propagates an
EOS by setting SC_FL_EOS instead of SC_FL_ABRT_DONE. It only concernes
stream-connectors attached to a mux.

2 years agoMINOR: stconn: Add a flag to report EOS at the stream-connector level
Christopher Faulet [Mon, 17 Apr 2023 14:17:32 +0000 (16:17 +0200)] 
MINOR: stconn: Add a flag to report EOS at the stream-connector level

SC_FL_EOS flag is added to report the end-of-stream at the SC level. It will
be used to distinguish end of stream reported by the endoint, via the
SE_FL_EOS flag, and the abort triggered by the stream, via the
SC_FL_ABRT_DONE flag.

In this patch, the flag is defined and is systematically tested everywhere
SC_FL_ABRT_DONE is tested. It should be safe because it is never set.

2 years agoBUG/MEDIUM: log: Properly handle client aborts in syslog applet
Christopher Faulet [Mon, 17 Apr 2023 14:34:29 +0000 (16:34 +0200)] 
BUG/MEDIUM: log: Properly handle client aborts in syslog applet

In the syslog applet, when there is no output data, nothing is performed and
the applet leaves by requesting more data. But it is an issue because a
client abort is only handled if it reported with the last bytes of the
message. If the abort occurs after the message was handled, it is ignored.
The session remains opened and inactive until the client timeout is being
triggered. It no such timeout is configured, given that the default maxconn
is 10, all slots can be quickly busy and make the applet unresponsive.

To fix the issue, the best is to always try to read a message when the I/O
handle is called. This way, the abort can be handled. And if there is no
data, we leave as usual.

This patch should fix the issue #2112. It must be backported as far as 2.4.

2 years agoBUG/MEDIUM: http-ana: Properly switch the request in tunnel mode on upgrade
Christopher Faulet [Mon, 17 Apr 2023 06:52:10 +0000 (08:52 +0200)] 
BUG/MEDIUM: http-ana: Properly switch the request in tunnel mode on upgrade

Since the commit f2b02cfd9 ("MAJOR: http-ana: Review error handling during
HTTP payload forwarding"), during the payload forwarding, we are analyzing a
side, we stop to test the opposite side. It means when the HTTP request
forwarding analyzer is called, we no longer check the response side and vice
versa.

Unfortunately, since then, the HTTP tunneling is broken after a protocol
upgrade. On the response is switch in TUNNEL mode. The request remains in
DONE state. As a consequence, data received from the server are forwarded to
the client but not data received from the client.

To fix the bug, when both sides are in DONE state, both are switched in same
time in TUNNEL mode if it was requested. It is performed in the same way in
http_end_request() and http_end_response().

This patch should fix the issue #2125. It is 2.8-specific. No backport
needed.

2 years agoMINOR: ssl: remove OpenSSL 1.0.2 mention into certificate loading error
William Lallemand [Mon, 17 Apr 2023 12:32:25 +0000 (14:32 +0200)] 
MINOR: ssl: remove OpenSSL 1.0.2 mention into certificate loading error

Remove the mention to OpenSSL 1.0.2 in the certificate chain loading
error, which is not relevant.

Could be backported in 2.7.

2 years agoCLEANUP: use "offsetof" where appropriate
Ilya Shipitsin [Sat, 15 Apr 2023 21:39:43 +0000 (23:39 +0200)] 
CLEANUP: use "offsetof" where appropriate

let's use the C library macro "offsetof"

2 years agoBUG/MINOR: quic: Do not use ack delay during the handshakes
Frédéric Lécaille [Fri, 14 Apr 2023 07:56:17 +0000 (09:56 +0200)] 
BUG/MINOR: quic: Do not use ack delay during the handshakes

As revealed by GH #2120 opened by @Tristan971, there are cases where ACKs
have to be sent without packet to acknowledge because the ACK timer has
been triggered and the connection needs to probe the peer at the same time.
Indeed

Thank you to @Tristan971 for having reported this issue.

Must be backported to 2.6 and 2.7.

2 years agoBUG/MINOR: stconn: Don't set SE_FL_ERROR at the end of sc_conn_send()
Christopher Faulet [Fri, 14 Apr 2023 15:32:39 +0000 (17:32 +0200)] 
BUG/MINOR: stconn: Don't set SE_FL_ERROR at the end of sc_conn_send()

When I reworked my series, this code was first removed and reinserted by
error. So let's remove it again.

2 years agoMEDIUM: stconn: Rely on SC flags to handle errors instead of SE flags
Christopher Faulet [Fri, 14 Apr 2023 10:09:35 +0000 (12:09 +0200)] 
MEDIUM: stconn: Rely on SC flags to handle errors instead of SE flags

It is the last commit on this subject. we stop to use SE_FL_ERROR flag from
the SC, except at the I/O level. Otherwise, we rely on SC_FL_ERROR
flag. Now, there should be a real separation between SE flags and SC flags.

2 years agoMEDIUM: stream: Stop to use SE flags to detect endpoint errors
Christopher Faulet [Fri, 14 Apr 2023 10:07:26 +0000 (12:07 +0200)] 
MEDIUM: stream: Stop to use SE flags to detect endpoint errors

Here again, we stop to use SE_FL_ERROR flag from process_stream() and
sub-functions and we fully rely on SC_FL_ERROR to do so.

2 years agoMEDIUM: stream: Stop to use SE flags to detect read errors from analyzers
Christopher Faulet [Fri, 14 Apr 2023 10:05:55 +0000 (12:05 +0200)] 
MEDIUM: stream: Stop to use SE flags to detect read errors from analyzers

In the same way the previous commit, we stop to use SE_FL_ERROR flag from
analyzers and their sub-functions. We now fully rely on SC_FL_ERROR to do so.

2 years agoMEDIUM: backend: Stop to use SE flags to detect connection errors
Christopher Faulet [Fri, 14 Apr 2023 10:05:25 +0000 (12:05 +0200)] 
MEDIUM: backend: Stop to use SE flags to detect connection errors

SE_FL_ERROR flag is no longer set when an error is detected durign the
connection establishment. SC_FL_ERROR flag is set instead. So it is safe to
remove test on SE_FL_ERROR to detect connection establishment error.

2 years agoMEDIUM: tree-wide: Stop to set SE_FL_ERROR from upper layer
Christopher Faulet [Fri, 14 Apr 2023 10:03:50 +0000 (12:03 +0200)] 
MEDIUM: tree-wide: Stop to set SE_FL_ERROR from upper layer

We can now fully rely on SC_FL_ERROR flag from the stream. The first step is
to stop to set the SE_FL_ERROR flag. Only endpoints are responsible to set
this flag. It was a design limitation. It is now fixed.

2 years agoMINOR: tree-wide: Test SC_FL_ERROR with SE_FL_ERROR from upper layer
Christopher Faulet [Fri, 14 Apr 2023 09:59:15 +0000 (11:59 +0200)] 
MINOR: tree-wide: Test SC_FL_ERROR with SE_FL_ERROR from upper layer

From the stream, when SE_FL_ERROR flag is tested, we now also test the
SC_FL_ERROR flag. Idea is to stop to rely on the SE descriptor to detect
errors.

2 years agoMINOR: stream: Set SC_FL_ERROR on channels' buffer allocation error
Christopher Faulet [Fri, 14 Apr 2023 09:36:29 +0000 (11:36 +0200)] 
MINOR: stream: Set SC_FL_ERROR on channels' buffer allocation error

Set SC_FL_ERROR flag when we fail to allocate a buffer for a stream.

2 years agoMINOR: backend: Set SC_FL_ERROR on connection error
Christopher Faulet [Fri, 14 Apr 2023 09:35:07 +0000 (11:35 +0200)] 
MINOR: backend: Set SC_FL_ERROR on connection error

During connection establishement, if an error occurred, the SC_FL_ERROR flag
is now set. Concretely, it is set when SE_FL_ERROR is also set.

2 years agoMINOR: stconn: Add a flag to ack endpoint errors at SC level
Christopher Faulet [Fri, 14 Apr 2023 08:42:08 +0000 (10:42 +0200)] 
MINOR: stconn: Add a flag to ack endpoint errors at SC level

The flag SC_FL_ERROR is added to ack errors on the endpoint. When
SE_FL_ERROR flag is detected on the SE descriptor, the corresponding is set
on the SC. Idea is to avoid, as far as possible, to manipulated the SE
descriptor in upper layers and know when an error in the endpoint is handled
by the SC.

For now, this flag is only set and cleared but never tested.

2 years agoMINOR: stconn: Don't clear SE_FL_ERROR when endpoint is reset
Christopher Faulet [Fri, 14 Apr 2023 08:28:28 +0000 (10:28 +0200)] 
MINOR: stconn: Don't clear SE_FL_ERROR when endpoint is reset

There is no reason to remove this flag. When the SC endpoint is reset, it is
replaced by a new one. The old one is released. It was useful when the new
endpoint inherited some flags from the old one.  But it is no longer
performed. Thus there is no reason still unset this flag.

2 years agoMEDIUM: stconn: Forbid applets with more to deliver if EOI was reached
Christopher Faulet [Fri, 14 Apr 2023 07:45:41 +0000 (09:45 +0200)] 
MEDIUM: stconn: Forbid applets with more to deliver if EOI was reached

When an applet is woken up, before calling its io_handler, we pretend it has
no more data to deliver. So, after the io_handler execution, it is a bug if
an applet states it has more data to deliver while the end of input is
reached.

So a BUG_ON() is added to be sure it never happens.

2 years agoMINOR: stconn: Stop to set SE_FL_ERROR on sending path
Christopher Faulet [Fri, 14 Apr 2023 07:42:59 +0000 (09:42 +0200)] 
MINOR: stconn: Stop to set SE_FL_ERROR on sending path

It is not the SC responsibility to report errors on the SE descriptor. It is
the endpoint responsibility. It must switch SE_FL_ERR_PENDING into
SE_FL_ERROR if the end of stream was detected. It can even be considered as
a bug if it is not done by he endpoint.

So now, on sending path, a BUG_ON() is added to abort if SE_FL_EOS and
SE_FL_ERR_PENDING flags are set but not SE_FL_ERROR. It is trully important
to handle this case in the endpoint to be able to properly shut the endpoint
down.

2 years agoBUG/MINOR: cli: Don't close when SE_FL_ERR_PENDING is set in cli analyzer
Christopher Faulet [Fri, 14 Apr 2023 05:49:45 +0000 (07:49 +0200)] 
BUG/MINOR: cli: Don't close when SE_FL_ERR_PENDING is set in cli analyzer

SE_FL_ERR_PENDING is used to report an error on the write side. But it is
not a terminal error. Some incoming data may still be available. In the cli
analyzers, it is important to not close the stream when this flag is
set. Otherwise the response to a command can be truncated. It is probably
hard to observe. But it remains a bug.

While this patch could be backported to 2.7, there is no real reason to do
so, except if someone reports a bug about truncated responses.

2 years agoMINOR: tree-wide: Replace several chn_prod() by the corresponding SC
Christopher Faulet [Thu, 13 Apr 2023 14:44:18 +0000 (16:44 +0200)] 
MINOR: tree-wide: Replace several chn_prod() by the corresponding SC

At many places, call to chn_prod() can be easily replaced by the
corresponding SC. It is a bit easier to understand which side is
manipulated.

2 years agoMINOR: tree-wide: Replace several chn_cons() by the corresponding SC
Christopher Faulet [Thu, 13 Apr 2023 14:37:37 +0000 (16:37 +0200)] 
MINOR: tree-wide: Replace several chn_cons() by the corresponding SC

At many places, call to chn_cons() can be easily replaced by the
corresponding SC. It is a bit easier to understand which side is
manipulated.

2 years agoMINOR: channel/stconn: Replace sc_shutw() by sc_shutdown()
Christopher Faulet [Thu, 13 Apr 2023 14:23:48 +0000 (16:23 +0200)] 
MINOR: channel/stconn: Replace sc_shutw() by sc_shutdown()

All reference to a shutw is replaced by an abort. So sc_shutw() is renamed
sc_shutdown(). SC app ops functions are renamed accordingly.

2 years agoMINOR: stconn: Rename SC_FL_SHUTW in SC_FL_SHUT_DONE
Christopher Faulet [Thu, 13 Apr 2023 14:16:15 +0000 (16:16 +0200)] 
MINOR: stconn: Rename SC_FL_SHUTW in SC_FL_SHUT_DONE

Here again, it is just a flag renaming. In SC flags, there is no longer
shutdown for writes but shutdowns.

2 years agoMINOR: channel/stconn: Replace sc_shutr() by sc_abort()
Christopher Faulet [Thu, 13 Apr 2023 14:10:23 +0000 (16:10 +0200)] 
MINOR: channel/stconn: Replace sc_shutr() by sc_abort()

All reference to a shutr is replaced by an abort. So sc_shutr() is renamed
sc_abort(). SC app ops functions are renamed accordingly.

2 years agoMINOR: stconn: Rename SC_FL_SHUTR in SC_FL_ABRT_DONE
Christopher Faulet [Thu, 13 Apr 2023 14:05:13 +0000 (16:05 +0200)] 
MINOR: stconn: Rename SC_FL_SHUTR in SC_FL_ABRT_DONE

Here again, it is just a flag renaming. In SC flags, there is no longer
shutdown for reads but aborts. For now this flag is set when a read0 is
detected. It is of couse not accurate. This will be changed later.

2 years agoMINOR: channel/stconn: Replace channel_shutw_now() by sc_schedule_shutdown()
Christopher Faulet [Thu, 13 Apr 2023 13:56:26 +0000 (15:56 +0200)] 
MINOR: channel/stconn: Replace channel_shutw_now() by sc_schedule_shutdown()

After the flag renaming, it is now the turn for the channel function to be
renamed and moved in the SC scope. channel_shutw_now() is replaced by
sc_schedule_shutdown(). The request channel is replaced by the front SC and
the response is replace by the back SC.

2 years agoMINOR: stconn: Rename SC_FL_SHUTW_NOW in SC_FL_SHUT_WANTED
Christopher Faulet [Thu, 13 Apr 2023 13:45:24 +0000 (15:45 +0200)] 
MINOR: stconn: Rename SC_FL_SHUTW_NOW in SC_FL_SHUT_WANTED

Because shutowns for reads are now considered as aborts, the shudowns for
writes can now be considered as shutdowns. Here it is just a flag
renaming. SC_FL_SHUTW_NOW is renamed SC_FL_SHUT_WANTED.

2 years agoMINOR: channel/stconn: Replace channel_shutr_now() by sc_schedule_abort()
Christopher Faulet [Thu, 13 Apr 2023 13:40:10 +0000 (15:40 +0200)] 
MINOR: channel/stconn: Replace channel_shutr_now() by sc_schedule_abort()

After the flag renaming, it is now the turn for the channel function to be
renamed and moved in the SC scope. channel_shutr_now() is replaced by
sc_schedule_abort(). The request channel is replaced by the front SC and the
response is replace by the back SC.

2 years agoMINOR: stconn: Rename SC_FL_SHUTR_NOW in SC_FL_ABRT_WANTED
Christopher Faulet [Thu, 13 Apr 2023 13:39:30 +0000 (15:39 +0200)] 
MINOR: stconn: Rename SC_FL_SHUTR_NOW in SC_FL_ABRT_WANTED

It is the first step to transform shutdown for reads for the upper layer
into aborts. This patch is quite simple, it is just a flag renaming.

2 years agoMINOR: stream: Introduce stream_abort() to abort on both sides in same time
Christopher Faulet [Thu, 13 Apr 2023 13:22:29 +0000 (15:22 +0200)] 
MINOR: stream: Introduce stream_abort() to abort on both sides in same time

The function stream_abort() should now be called when an abort is performed
on the both channels in same time.

2 years agoMINOR: channel: Forwad close to other side on abort
Christopher Faulet [Thu, 13 Apr 2023 13:13:12 +0000 (15:13 +0200)] 
MINOR: channel: Forwad close to other side on abort

Most of calls to channel_abort() are associated to a call to
channel_auto_close(). Others are in areas where the auto close is the
default. So, it is now systematically enabled when an abort is performed on
a channel, as part of channel_abort() function.

2 years agoREGTESTS: fix the race conditions in log_uri.vtc
Christopher Faulet [Thu, 13 Apr 2023 13:11:23 +0000 (15:11 +0200)] 
REGTESTS: fix the race conditions in log_uri.vtc

A "Connection: close" header is added to responses to avoid any connection
reuse. This should avoid any "HTTP header incomplete" errors.

2 years agoMINOR: filters: Review and simplify errors handling
Christopher Faulet [Thu, 13 Apr 2023 12:49:04 +0000 (14:49 +0200)] 
MINOR: filters: Review and simplify errors handling

First, it is useless to abort the both channel explicitly. For HTTP streams,
http_reply_and_close() is called. This function already take care to abort
processing. For TCP streams, we can rely on stream_retnclose().

To set termination flags, we can also rely on http_set_term_flags() for HTTP
streams and sess_set_term_flags() for TCP streams. Thus no reason to handle
them by hand.

At the end, the error handling after filters evaluation is now quite simple.

2 years agoMINOR: stream: Uninline and export sess_set_term_flags() function
Christopher Faulet [Thu, 13 Apr 2023 12:46:01 +0000 (14:46 +0200)] 
MINOR: stream: Uninline and export sess_set_term_flags() function

This function will be used to set termination flags on TCP streams from
outside of process_stream(). Thus, it must be uninlined and exported.

2 years agoBUG/MEDIUM: stconn: Do nothing in sc_conn_recv() when the SC needs more room
Christopher Faulet [Wed, 12 Apr 2023 16:35:18 +0000 (18:35 +0200)] 
BUG/MEDIUM: stconn: Do nothing in sc_conn_recv() when the SC needs more room

We erroneously though that an attempt to receive data was not possible if the SC
was waiting for more room in the channel buffer. A BUG_ON() was added to detect
bugs. And in fact, it is possible.

The regression was added in commit 341a5783b ("BUG/MEDIUM: stconn: stop to
enable/disable reads from streams via si_update_rx").

This patch should fix the issue #2115. It must be backported if the commit
above is backported.

2 years agoBUG/MEDIUM: stream: Report write timeouts before testing the flags
Christopher Faulet [Wed, 12 Apr 2023 16:23:15 +0000 (18:23 +0200)] 
BUG/MEDIUM: stream: Report write timeouts before testing the flags

A regression was introduced when stream's timeouts were refactored. Write
timeouts are not testing is the right order. When timeous of the front SC
are handled, we must then test the read timeout on the request channel and
the write timeout on the response channel. But write timeout is tested on
the request channel instead. On the back SC, the same mix-up is performed.

We must be careful to handle timeouts before checking channel flags. To
avoid any confusions, all timeuts are handled first, on front and back SCs.
Then flags of the both channels are tested.

It is a 2.8-specific issue. No backport needed.

2 years agoBUG/MINOR: stream: Fix test on SE_FL_ERROR on the wrong entity
Christopher Faulet [Wed, 12 Apr 2023 12:20:36 +0000 (14:20 +0200)] 
BUG/MINOR: stream: Fix test on SE_FL_ERROR on the wrong entity

There is a bug at begining of process_stream(). The SE_FL_ERROR flag is
tested against backend stream-connector's flags instead of its SE
descriptor's flags. It is an old typo, introduced when the stream-interfaces
were replaced by the conn-streams.

This patch must be backported as far as 2.6.

2 years agoCI: enable monthly test on Fedora Rawhide
Ilya Shipitsin [Sat, 8 Apr 2023 11:30:42 +0000 (13:30 +0200)] 
CI: enable monthly test on Fedora Rawhide

Fedora Rawhide is shipped with the most recent compilers, not yet released with
more conservative distro. It is good to catch compile errors on those compilers.

2 years agoCI: bump "actions/checkout" to v3 for cross zoo matrix
Ilya Shipitsin [Sat, 8 Apr 2023 11:32:31 +0000 (13:32 +0200)] 
CI: bump "actions/checkout" to v3 for cross zoo matrix

actions/checkout@v2 is deprecated, accidently it was not updated in our
build definition

2 years agoBUG/MINOR: quic: Wrong Application encryption level selection when probing
Frédéric Lécaille [Thu, 13 Apr 2023 16:30:16 +0000 (18:30 +0200)] 
BUG/MINOR: quic: Wrong Application encryption level selection when probing

This bug arrived with this commit:

    MEDIUM: quic: Ack delay implementation

After having probed the Handshake packet number space, one must not select the
Application encryption level to continue trying building packets as this is done
when the connection is not probing. Indeed, if the ACK timer has been triggered
in the meantime, the packet builder will try to build a packet at the Application
encryption level to acknowledge the received packet. But there is very often
no 01RTT packet to acknowledge when the connection is probing before the
handshake is completed. This triggers a BUG_ON() in qc_do_build_pkt() which
checks that the tree of ACK ranges to be used is not empty.

Thank you to @Tristan971 for having reported this issue in GH #2109.

Must be backported to 2.6 and 2.7.

2 years agoMINOR: quic: Remove a useless test about probing in qc_prep_pkts()
Frédéric Lécaille [Thu, 13 Apr 2023 13:59:02 +0000 (15:59 +0200)] 
MINOR: quic: Remove a useless test about probing in qc_prep_pkts()

qel->pktns->tx.pto_probe is set to 0 after having prepared a probing
datagram. There is no reason to check this parameter. Furthermore
it is always 0 when the connection does not probe the peer.

Must be backported to 2.6 and 2.7.

2 years agoMINOR: quic: Display the packet number space flags in traces
Frédéric Lécaille [Thu, 13 Apr 2023 13:55:49 +0000 (15:55 +0200)] 
MINOR: quic: Display the packet number space flags in traces

Display this information when the encryption level is also displayed.

Must be backported to 2.6 and 2.7.

2 years agoBUG/MINOR: quic: SIGFPE in quic_cubic_update()
Frédéric Lécaille [Thu, 13 Apr 2023 08:46:42 +0000 (10:46 +0200)] 
BUG/MINOR: quic: SIGFPE in quic_cubic_update()

As reported by @Tristan971 in GH #2116, the congestion control window could be zero
due to an inversion in the code about the reduction factor to be applied.
On a new loss event, it must be applied to the slow start threshold and the window
should never be below ->min_cwnd (2*max_udp_payload_sz).

Same issue in both newReno and cubic algorithm. Furthermore in newReno, only the
threshold was decremented.

Must be backported to 2.6 and 2.7.

2 years agoBUG/MINOR: quic: Possible wrapped values used as ACK tree purging limit.
Frédéric Lécaille [Wed, 12 Apr 2023 18:49:29 +0000 (20:49 +0200)] 
BUG/MINOR: quic: Possible wrapped values used as ACK tree purging limit.

Add two missing checks not to substract too big values from another too little
one. In this case the resulted wrapped huge values could be passed to the function
which has to remove the last range of a tree of ACK ranges as encoded limit size
not to go below, cancelling the ACK ranges deletion. The consequence could be that
no ACK were sent.

Must be backported to 2.6 and 2.7.

2 years agoBUG/MEDIUM: quic: Code sanitization about acknowledgements requirements
Frédéric Lécaille [Wed, 12 Apr 2023 16:51:49 +0000 (18:51 +0200)] 
BUG/MEDIUM: quic: Code sanitization about acknowledgements requirements

qc_may_build_pkt() has been modified several times regardless of the conditions
the functions it is supposed to allow to send packets (qc_build_pkt()/qc_do_build_pkt())
really use to finally send packets just after having received others, leading
to contraditions and possible very long loops sending empty packets (PADDING only packets)
because qc_may_build_pkt() could allow qc_build_pkt()/qc_do_build_pkt to build packet,
and the latter did nothing except sending PADDING frames, because from its point
of view they had nothing to send.

For now on, this is the job of qc_may_build_pkt() to decide to if there is
packets to send just after having received others AND to provide this information
to the qc_build_pkt()/qc_do_build_pkt()

Note that the unique case where the acknowledgements are completely ignored is
when the endpoint must probe. But at least this is when sending at most two datagrams!

This commit also fixes the issue reported by Willy about a very low throughput
performance when the client serialized its requests.

Must be backported to 2.7 and 2.6.

2 years agoMINOR: quic: Add connection flags to traces
Frédéric Lécaille [Wed, 12 Apr 2023 11:41:54 +0000 (13:41 +0200)] 
MINOR: quic: Add connection flags to traces

This should help in diagnosing issues.

Some adjustments have to be done to avoid deferencing a quic_conn objects from
TRACE_*() calls.

Must be backported to 2.7 and 2.6.

2 years agoBUG/MINOR: quic: Ignored less than 1ms RTTs
Frédéric Lécaille [Thu, 6 Apr 2023 11:13:08 +0000 (13:13 +0200)] 
BUG/MINOR: quic: Ignored less than 1ms RTTs

Do not ignore very short RTTs (less than 1ms) before computing the smoothed
RTT initializing it to an "infinite" value (UINT_MAX).

Must be backported to 2.7 and 2.6.

2 years agoMINOR: quic: Add packet loss and maximum cc window to "show quic"
Frédéric Lécaille [Thu, 6 Apr 2023 08:19:17 +0000 (10:19 +0200)] 
MINOR: quic: Add packet loss and maximum cc window to "show quic"

Add the number of packet losts and the maximum congestion control window computed
by the algorithms to "show quic".
Same thing for the traces of existent congestion control algorithms.

Must be backported to 2.7 and 2.6.

2 years agoBUG/MEDIUM: fd: don't wait for tmask to stabilize if we're not in it.
Olivier Houchard [Thu, 13 Apr 2023 14:12:38 +0000 (16:12 +0200)] 
BUG/MEDIUM: fd: don't wait for tmask to stabilize if we're not in it.

In fd_update_events(), we loop until there's no bit in the running_mask
that is not in the thread_mask. Problem is, the thread sets its
running_mask bit before that loop, and so if 2 threads do the same, and
a 3rd one just closes the FD and sets the thread_mask to 0, then
running_mask will always be non-zero, and we will loop forever. This is
trivial to reproduce when using a DNS resolver that will just answer
"port unreachable", but could theoretically happen with other types of
file descriptors too.

To fix that, just don't bother looping if we're no longer in the
thread_mask, if that happens we know we won't have to take care of the
FD, anyway.

This should be backported to 2.7, 2.6 and 2.5.

2 years agoMINOR: bind-conf: support a new shards value: "by-group"
Willy Tarreau [Thu, 13 Apr 2023 15:25:43 +0000 (17:25 +0200)] 
MINOR: bind-conf: support a new shards value: "by-group"

Setting "shards by-group" will create one shard per thread group. This
can often be a reasonable tradeoff between a single one that can be
suboptimal on CPUs with many cores, and too many that will eat a lot
of file descriptors. It was shown to provide good results on a 224
thread machine, with a distribution that was even smoother than the
system's since here it can take into account the number of connections
per thread in the group. Depending on how popular it becomes, it could
even become the default setting in a future version.

2 years agoMINOR: receiver: reserve special values for "shards"
Willy Tarreau [Thu, 13 Apr 2023 15:11:23 +0000 (17:11 +0200)] 
MINOR: receiver: reserve special values for "shards"

Instead of artificially setting the shards count to MAX_THREAD when
"by-thread" is used, let's reserve special values for symbolic names
so that we can add more in the future. For now we use value -1 for
"by-thread", which requires to turn the type to signed int but it was
already used as such everywhere anyway.

2 years agoMINOR: fd: implement fd_migrate_on() to migrate on a non-local thread
Amaury Denoyelle [Mon, 3 Apr 2023 13:27:13 +0000 (15:27 +0200)] 
MINOR: fd: implement fd_migrate_on() to migrate on a non-local thread

fd_migrate_on() can be used to migrate an existing FD to any thread, even
one belonging to a different group from the current one and from the
caller's. All that is needed is to make sure the FD is still valid when
the operation is performed (which is the case when such operations happen).

This is potentially slightly expensive since it locks the tgid during the
delicate operation, but it is normally performed only from an owning
thread to offer the FD to another one (e.g. reassign a better thread upon
accept()).

2 years agoMINOR: fd: add a lock bit with the tgid
Willy Tarreau [Thu, 13 Apr 2023 12:27:48 +0000 (14:27 +0200)] 
MINOR: fd: add a lock bit with the tgid

In order to permit to migrate FDs from one thread group to another,
we'll need to be able to set a TGID that is compatible with no other
thread group. Either we use a special value or we dedicate a special
bit. Given that we already have way more bits than needed, let's just
sacrifice the topmost one to serve as a lock bit, indicating the tgid
is not valid anymore. This will make all fd_grab_tgid() fail to grab
it.

The new fd_lock_tgid() function now tries to assign a locked tgid to
an idle FD, and fd_unlock_tgid() simply drops the lock bit, revealing
the target tgid.

For now it's still unused so it must not have any effect.

2 years agoMINOR: fd: optimize fd_claim_tgid() for use in fd_insert()
Willy Tarreau [Thu, 13 Apr 2023 13:22:42 +0000 (15:22 +0200)] 
MINOR: fd: optimize fd_claim_tgid() for use in fd_insert()

fd_claim_tgid() uses a CAS to set the desired TGID on the FD. It's only
called from fd_insert() where in the vast majority of cases, the tgid
and refcount are zero before the call. However the loop was optimized
for the case where it was equal to the desired TGID, systematically
causing one extra round in the loop there. Better start assuming a
zero value.

2 years agoMINOR: thread: keep a bitmask of enabled groups in thread_set
Willy Tarreau [Wed, 1 Mar 2023 10:24:29 +0000 (11:24 +0100)] 
MINOR: thread: keep a bitmask of enabled groups in thread_set

We're only checking for 0, 1, or >1 groups enabled there, and we'll soon
need to be more precise and know quickly which groups are non-empty.
Let's just replace the count with a mask of enabled groups. This will
allow to quickly spot the presence of any such group in a set.

2 years agoBUG/MINOR: stick_table: alert when type len has incorrect characters
William Lallemand [Thu, 13 Apr 2023 12:33:52 +0000 (14:33 +0200)] 
BUG/MINOR: stick_table: alert when type len has incorrect characters

Alert when the len argument of a stick table type contains incorrect
characters.

Replace atol by strtol.

Could be backported in every maintained versions.

2 years agoMINOR: activity: add a line reporting the average CPU usage to "show activity"
Willy Tarreau [Tue, 11 Apr 2023 13:26:24 +0000 (15:26 +0200)] 
MINOR: activity: add a line reporting the average CPU usage to "show activity"

It was missing from the output but is sometimes convenient to observe
and understand how incoming connections are distributed. The CPU usage
is reported as the instant measurement of 100-idle_pct for each thread,
and the average value is shown for the aggregated value.

This could be backported as it's helpful in certain troublehsooting
sessions.

2 years agoMINOR: quic: Add a trace for packet with an ACK frame
Frédéric Lécaille [Fri, 7 Apr 2023 17:01:33 +0000 (19:01 +0200)] 
MINOR: quic: Add a trace for packet with an ACK frame

As the ACK frames are not added to the packet list of ack-eliciting frames,
it could not be traced. But there is a flag to identify such packet.
Let's use it to add this information to the traces of TX packets.

Must be backported to 2.6 and 2.7.

2 years agoMINOR: quic: Dump more information at proto level when building packets
Frédéric Lécaille [Fri, 7 Apr 2023 16:12:00 +0000 (18:12 +0200)] 
MINOR: quic: Dump more information at proto level when building packets

This should be helpful to debug issues at without too much traces.

Must be backported to 2.7 and 2.6.