Commit Graph

16945 Commits

Author SHA1 Message Date
Frédéric Lécaille
000162e1d6 BUG/MINOR: h3: Missing wait event struct field initialization
This one has been detected by valgrind:
==2179331== Conditional jump or move depends on uninitialised value(s)
==2179331==    at 0x1B6EDE: qcs_notify_recv (mux_quic.c:201)
==2179331==    by 0x1A17C5: qc_handle_uni_strm_frm (xprt_quic.c:2254)
==2179331==    by 0x1A1982: qc_handle_strm_frm (xprt_quic.c:2286)
==2179331==    by 0x1A2CDB: qc_parse_pkt_frms (xprt_quic.c:2550)
==2179331==    by 0x1A6068: qc_treat_rx_pkts (xprt_quic.c:3463)
==2179331==    by 0x1A6C3D: quic_conn_app_io_cb (xprt_quic.c:3589)
==2179331==    by 0x3AA566: run_tasks_from_lists (task.c:580)
==2179331==    by 0x3AB197: process_runnable_tasks (task.c:883)
==2179331==    by 0x357E56: run_poll_loop (haproxy.c:2750)
==2179331==    by 0x358366: run_thread_poll_loop (haproxy.c:2921)
==2179331==    by 0x3598D2: main (haproxy.c:3538)
==2179331==
2022-04-01 16:26:06 +02:00
Frédéric Lécaille
b823bb7f7f MINOR: quic: Add traces about list of frames
This should be useful to have an idea of the list of frames which could be built
towards the list of available frames when building packets.
Same thing about the frames which could not be built because of a lack of room
in the TX buffer.
2022-04-01 16:26:06 +02:00
Frédéric Lécaille
6c01b74ffa MINOR: quic: Useless call to SSL_CTX_set_default_verify_paths()
This call to SSL_CTX_set_default_verify_paths() is useless for haproxy.
2022-04-01 16:26:06 +02:00
Frédéric Lécaille
12fd259363 BUG/MINOR: quic: Too much prepared retransmissions due to anti-amplification
We must not re-enqueue frames if we can detect in advance they will not be
transmitted due to the anti-amplification limit.
2022-04-01 16:26:06 +02:00
Frédéric Lécaille
009016c0cd BUG/MINOR: quic: Non duplicated frames upon fast retransmission
We must duplicate the frames to be sent again from packets which are not deemed
lost.
2022-04-01 16:26:06 +02:00
Frédéric Lécaille
5cfb4edca7 BUG/MINOR: quic: Do not probe from an already probing packet number space
During a handshake, after having prepared a probe upon a PTO expiration from
process_timer(), we wake up the I/O handler to make it send probing packets.
This handler first treat incoming packets  which trigger a fast retransmission
leading to send too much probing (duplicated) packets. In this cas we cancel
the fast retranmission.
2022-04-01 16:26:05 +02:00
Frédéric Lécaille
03235d78ae MINOR: quic: Do not display any timer value from process_timer()
This is confusing to display the connection timer from this function as it is not
supposed to update it. Only qc_set_timer() should do that.
2022-04-01 16:22:52 +02:00
Frédéric Lécaille
05bd92bbc5 BUG/MINOR: quic: Discard Initial packet number space only one time
When discarding a packet number space, we at least reset the PTO backoff counter.
Doing this several times have an impact on the PTO duration calculation.
We must not discard a packet number space several times (this is already the case
for the handshake packet number space).
2022-04-01 16:22:52 +02:00
Frédéric Lécaille
d6570e1789 BUG/MINOR: quic: Missing probing packets when coalescing
Before having a look at the next encryption level to build packets if there is
no more ack-eliciting frames to send we must check we have not to probe from
the current encryption level anymore. If not, we only send one datagram instead
of sending two datagrams giving less chance to recover from packet loss.
2022-04-01 16:22:52 +02:00
Frédéric Lécaille
b002145e9f MEDIUM: quic: Send ACK frames asap
Due to a erroneous interpretation of the RFC 9000 (quic-transport), ACKs frames
were always sent only after having received two ack-eliciting packets.
This could trigger useless retransmissions for tail packets on the peer side.
For now on, we send as soon as possible ACK frames as soon as we have ACK to send,
in the same packets as the ack-eliciting frame packets, and we also send ACK
frames after having received 2 ack-eliciting packets since the last time we sent
an ACK frame with other ack-eliciting frames.
2022-04-01 16:22:52 +02:00
Frédéric Lécaille
205e4f359e CLEANUP: quic: Remove all atomic operations on packet number spaces
As such variables are handled by the QUIC connection I/O handler which runs
always on the thread, there is no need to continue to use such atomic operations
2022-04-01 16:22:47 +02:00
Frédéric Lécaille
fc79006c92 CLEANUP: quic: Remove all atomic operations on quic_conn struct
As the QUIC connections are always handled by the same thread there is no need
anymore to continue to use atomic operations on such variables.
2022-04-01 16:22:44 +02:00
Frédéric Lécaille
f44d19eb91 BUG/MEDIUM: quic: Possible crash in ha_quic_set_encryption_secrets()
This bug has come with this commit:
   1fc5e16c4 MINOR: quic: More accurate immediately close
As mentionned in this commit we do not want to derive anymore secret when in closing
state. But the flag which denote secrets were derived was set. Add a label at
the correct flag to skip the secrets derivation without setting this flag.
2022-04-01 16:22:40 +02:00
Ilya Shipitsin
6e7440b918 CI: github actions: update OpenSSL to 3.0.2 2022-03-31 17:00:22 +02:00
Aleksandar Lazic
332258a778 DOC: remove double blanks in configuration.txt
Double blanks in keywords are not good for the html documentation parser.
This commit fixes the double blanks for tcp-request content use-service.
2022-03-31 16:58:52 +02:00
Willy Tarreau
413713f02a BUG/MAJOR: mux_pt: always report the connection error to the conn_stream
Over time we've tried hard to abstract connection errors from the upper
layers so that they're reported per stream and not per connection. As
early as 1.8-rc1, commit 4ff3b8964 ("MINOR: connection: make conn_stream
users also check for per-stream error flag") did precisely this, but
strangely only for rx, not for tx (probably that by then send errors
were not imagined to be reported that way).

And this lack of Tx error check was just revealed in 2.6 by recent commit
d1480cc8a ("BUG/MEDIUM: stream-int: do not rely on the connection error
once established") that causes wakeup loops between si_cs_send() failing
to send via mux_pt_snd_buf() and subscribing against si_cs_io_cb() in
loops because the function now rightfully only checks for CS_FL_ERROR
and not CO_FL_ERROR.

As found by Amaury, this causes aborted "show events -w" to cause
haproxy to loop at 100% CPU.

This fix theoretically needs to be backported to all versions, though
it will be necessary and sufficient to backport it wherever 4ff3b8964
gets backported.
2022-03-31 16:55:52 +02:00
William Lallemand
a662275e84 DOC: management: add missing dot in 9.4.1
The 9.4.1 chapter is missing the dot at the end of the chapter numbers.
Which broke the haproxy-dconv html generation.

No backport needed, 2.6 only.
2022-03-31 15:28:42 +02:00
Willy Tarreau
c40c407268 BUG/MINOR: cli/stream: fix "shutdown session" to iterate over all threads
The list of streams was modified in 2.4 to become per-thread with commit
a698eb673 ("MINOR: streams: use one list per stream instead of a global
one"). However the change applied to cli_parse_shutdown_session() is
wrong, as it uses the nullity of the stream pointer to continue on next
threads, but this one is not null once the list_for_each_entry() loop
is finished, it points to the list's head again, so the loop doesn't
check other threads, and no message is printed either to say that the
stream was not found.

Instead we should check if the stream is equal to the requested pointer
since this is the condition to break out of the loop.

Thus must be backported to 2.4. Thanks to Maciej Zdeb for reporting this.
2022-03-31 15:00:45 +02:00
Amaury Denoyelle
d8e680cbaf MEDIUM: mux-quic: remove qcs tree node
The new qc_stream_desc type has a tree node for storage. Thus, we can
remove the node in the qcs structure.

When initializing a new stream, it is stored into the qcc streams_by_id
tree. When the MUX releases it, it will freed as soon as its buffer is
emptied. Before this, the quic-conn is responsible to store it inside
its own streams_by_id tree.
2022-03-30 16:26:59 +02:00
Amaury Denoyelle
7272cd76fc MEDIUM: quic: move transport fields from qcs to qc_conn_stream
Move the xprt-buf and ack related fields from qcs to the qc_stream_desc
structure. In exchange, qcs has a pointer to the low-level stream. For
each new qcs, a qc_stream_desc is automatically allocated.

This simplify the transport layer by removing qcs/mux manipulation
during ACK frame parsing. An additional check is done to not notify the
MUX on sending if the stream is already released : this case may now
happen on retransmission.

To complete this change, the quic_stream frame now references the
quic_stream instance instead of a qcs.
2022-03-30 16:19:48 +02:00
Amaury Denoyelle
5c3859c509 MINOR: quic: implement stream descriptor for transport layer
Currently, the mux qcs streams manage the Tx buffering, even after
sending it to the transport layer. Buffers are emptied when
acknowledgement are treated by the transport layer. This complicates the
MUX liberation and we may loose some data after the MUX free.

Change this paradigm by moving the buffering on the transport layer. For
this goal, a new type is implemented as low-level stream at the
transport layer, as a counterpart of qcs mux instances. This structure
is called qc_stream_desc. This will allow to free the qcs/qcc instances
without having to wait for acknowledge reception.

For the moment, the quic-conn is responsible to store the qc_stream_desc
in a new tree named streams_by_id. This will sligthly change in the next
commits to remove the qcs node which has a similar purpose :
qc_stream_desc instances will be shared between the qcc MUX and the
quic-conn.

This patch only introduces the new type definition and the function to
manipulate it. The following commit will bring the rearchitecture in the
qcs structure.
2022-03-30 16:16:07 +02:00
Amaury Denoyelle
95e50fbeff CLEANUP: quic: complete comment on qcs_try_to_consume
Specify the return value usage.
2022-03-30 16:12:18 +02:00
Amaury Denoyelle
f89094510c BUG/MINOR: mux-quic: ensure to free all qcs on MUX release
Remove qcs instances left during qcc MUX release. This can happen when
the MUX is closed before the completion of all the transfers, such as on
a timeout or process termination.

This may free some memory leaks on the connection.
2022-03-30 16:12:18 +02:00
Amaury Denoyelle
8347f27221 BUG/MINOR: h3: release resources on close
Implement the release app-ops ops for H3 layer. This is used to clean up
uni-directional streams and the h3 context.

This prevents a memory leak on H3 resources for each connection.
2022-03-30 16:12:18 +02:00
Amaury Denoyelle
cbc13b71c6 MINOR: mux-quic: define release app-ops
Define a new callback release inside qcc_app_ops. It is called when the
qcc MUX is freed via qc_release. This will allows to implement cleaning
on the app layer.
2022-03-30 16:12:18 +02:00
Amaury Denoyelle
dccbd733f0 MINOR: mux-quic: reorganize qcs free
Regroup some cleaning operations inside a new function qcs_free. This
can be used for all streams, both through qcs_destroy and with
uni-directional streams.
2022-03-30 16:12:18 +02:00
Amaury Denoyelle
50742294f5 MINOR: mux-quic: return qcs instance from qcc_get_qcs
Refactoring on qcc_get_qcs : return the qcs instance instead of the tree
node. This is useful to hide some eb64_entry macros for better
readability.
2022-03-30 16:12:18 +02:00
Amaury Denoyelle
8d5def0bab BUG/MEDIUM: quic: do not use qcs from quic_stream on ACK parsing
The quic_stream frame stores the qcs instance. On ACK parsing, qcs is
accessed to clear the stream buffer. This can cause a segfault if the
MUX or the qcs is already released.

Consider the following scenario :

1. a STREAM frame is generated by the MUX
   transport layer emits the frame with PKN=1
   upper layer has finished the transfer so related qcs is detached

2. transport layer reemits the frame with PKN=2 because ACK was not
   received

3. ACK for PKN=1 is received, stream buffer is cleared
   at this stage, qcs may be freed by the MUX as it is detached

4. ACK for PKN=2 is received
   qcs for STREAM frame is dereferenced which will lead to a crash

To prevent this, qcs is never accessed from the quic_stream during ACK
parsing. Instead, a lookup is done on the MUX streams tree. If the MUX
is already released, no lookup is done. These checks prevents a possible
segfault.

This change may have an impact on the perf as now we are forced to use a
tree lookup operation. If this is the case, an alternative solution may
be to implement a refcount on qcs instances.
2022-03-30 16:12:18 +02:00
William Lallemand
10cea5cd6d DOC: lua: CertCache class documentation
Document the CertCache API which is used to update a certificate file in
memory using lua.
2022-03-30 16:02:43 +02:00
William Lallemand
5213918fe2 BUILD: ssl/lua: CacheCert needs OpenSSL
Return an lua error when trying to use CacheCert.set() and OpenSSL was
not used to build HAProxy.
2022-03-30 15:05:42 +02:00
William Lallemand
30fcca18a5 MINOR: ssl/lua: CertCache.set() allows to update an SSL certificate file
The CertCache.set() function allows to update an SSL certificate file
stored in the memory of the HAProxy process. This function does the same
as "set ssl cert" + "commit ssl cert" over the CLI.

This could be used to update the crt and key, as well as the OCSP, the
SCTL, and the OSCP issuer.

The implementation does yield every 10 ckch instances, the same way the
"commit ssl cert" do.
2022-03-30 14:56:10 +02:00
William Lallemand
26654e7a59 MINOR: ssl: add "crt" in the cert_exts array
The cert_exts array does handle "crt" the default way, however
you might stil want to look for these extensions in the array.
2022-03-30 14:55:53 +02:00
William Lallemand
e60c7d6e59 MINOR: ssl: export ckch_inst_rebuild()
ckch_inst_rebuild() will be needed to regenerate the ckch instances from
the lua code, we need to export it.
2022-03-30 12:18:16 +02:00
William Lallemand
ff8bf988b9 MINOR: ssl: simplify the certificate extensions array
Simplify the "cert_exts" array which is used for the selection of the
parsing function depending on the extension.

It now uses a pointer to an array element instead of an index, which is
simplier for the declaration of the array.

This way also allows to have multiple extension using the same type.
2022-03-30 12:18:16 +02:00
William Lallemand
aaacc7e8ad MINOR: ssl: move the cert_exts and the CERT_TYPE enum
Move the cert_exts declaration and the CERT_TYPE enum in the .h in order
to reuse them in another file.
2022-03-30 12:18:16 +02:00
William Lallemand
3b5a3a6c03 MINOR: ssl: split the cert commit io handler
Extract the code that replace the ckch_store and its dependencies into
the ckch_store_replace() function.

This function must be used under the global ckch lock.
It frees everything related to the old ckch_store.
2022-03-30 12:18:16 +02:00
William Lallemand
7177a95f89 MEDIUM: httpclient/lua: be stricter with httpclient parameters
Checks the argument passed to the httpclient send functions so we don't
add a mispelled argument.
2022-03-30 12:18:16 +02:00
Willy Tarreau
3f0b2e85f3 MINOR: services: alphabetically sort service names
Note that we cannot reuse dump_act_rules() because the output format
may be adjusted depending on the call place (this is also used from
haproxy -vv). The principle is the same however.
2022-03-30 12:12:44 +02:00
Willy Tarreau
0f99637353 MINOR: filters: alphabetically sort the list of filter names
There are very few but they're registered from constructors, hence
in a random order. The scope had to be copied when retrieving the
next keyword. Note that this also has the effect of listing them
sorted in haproxy -vv.
2022-03-30 12:08:00 +02:00
Willy Tarreau
4465171593 MINOR: cli: alphanumerically sort the dump of supported commands
Like for previous keyword classes, we're sorting the output. But this
time as it's not trivial to do it with multiple words, instead we're
proceeding like the help command, we sort them on their usage message
when present, and fall back to the first word of the command when there
is no usage message (e.g. "help" command).
2022-03-30 12:02:35 +02:00
Willy Tarreau
800bd78944 MINOR: acl: alphanumerically sort the ACL dump
The mechanism is similar to others. We take care of sorting on the
keyword only and not the fetch_kw which is not unique.
2022-03-30 11:49:59 +02:00
Willy Tarreau
5e0f90a930 MINOR: sample: alphanumerically sort sample & conv keyword dumps
It's much more convenient to sort these keywords on output to detect
changes, and it's easy to do. The patch looks big but most of it is
only caused by an indent change in the loop, as "git diff -b" shows.
2022-03-30 11:30:36 +02:00
Willy Tarreau
d905826000 MINOR: config: alphanumerically sort config keywords output
The output produced by dump_registered_keywords() really deserves to be
sorted in order to ease comparisons. The function now implements a tiny
sorting mechanism that's suitable for each two-level list, and makes
use of dump_act_rules() to dump rulesets. The code is not significantly
more complicated and some parts (e.g options) could even be factored.
The output is much more exploitable to detect differences now.
2022-03-30 11:21:32 +02:00
Willy Tarreau
2100b383ab MINOR: action: add a function to dump the list of actions for a ruleset
The new function dump_act_rules() now dumps the list of actions supported
by a ruleset. These actions are alphanumerically sorted first so that the
produced output is easy to compare.
2022-03-30 11:19:22 +02:00
Willy Tarreau
3ff476e9ef MINOR: tools: add strordered() to check whether strings are ordered
When trying to sort sets of strings, it's often needed to required to
compare 3 strings to see if the chosen one fits well between the two
others. That's what this function does, in addition to being able to
ignore extremities when they're NULL (typically for the first iteration
for example).
2022-03-30 10:02:56 +02:00
Willy Tarreau
29d799d591 MINOR: sample: list registered sample converter functions
Similar to the sample fetch keywords, let's also list the converter
keywords. They're much simpler since there's no compatibility matrix.
Instead the input and output types are listed. This is called by
dump_registered_keywords() for the "cnv" keywords class.
2022-03-29 18:01:37 +02:00
Willy Tarreau
f78813f74f MINOR: samples: add a function to list register sample fetch keywords
New function smp_dump_fetch_kw lists registered sample fetch keywords
with their compatibility matrix, mandatory and optional argument types,
and output types. It's called from dump_registered_keywords() with class
"smp".
2022-03-29 18:01:37 +02:00
Willy Tarreau
6ff7d1b9a5 MINOR: acl: add a function to dump the list of known ACL keywords
New function acl_dump_kwd() dumps the registered ACL keywords and their
sample-fetch equivalent to stdout. It's called by dump_registered_keywords()
for keyword class "acl".
2022-03-29 18:01:37 +02:00
Willy Tarreau
06d0e2e034 MINOR: cli: add a new keyword dump function
New function cli_list_keywords() scans the list of registered CLI keywords
and dumps them on stdout. It's now called from dump_registered_keywords()
for the class "cli".

Some keywords are valid for the master, they'll be suffixed with
"[MASTER]". Others are valid for the worker, they'll have "[WORKER]".
Those accessible only in expert mode will show "[EXPERT]" and the
experimental ones will show "[EXPERIM]".
2022-03-29 18:01:37 +02:00
Willy Tarreau
5fcc100d91 MINOR: services: extend list_services() to dump to stdout
When no output stream is passed, stdout is used with one entry per line,
and this is called from dump_registered_services() when passed the class
"svc".
2022-03-29 18:01:37 +02:00