Commit Graph

6275 Commits

Author SHA1 Message Date
Amaury Denoyelle
4335b39dc2 CLEANUP: mux-quic: do not export qc_get_ncbuf
qc_get_ncbuf() is only used internally : thus its prototype in QUIC MUX
include is not required.

(cherry picked from commit a441ec9c7a)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-31 10:43:54 +02:00
Frdric Lcaille
afae8d59d2 MINOR: quic: Dump version_information transport parameter
Implement quic_tp_version_info_dump() to dump such a transport parameter (only remote).
Call it from quic_transport_params_dump() which dump all the transport parameters.

Can be backported to 2.6 as it's useful for debugging.

(cherry picked from commit 4f5777a415)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-31 10:43:54 +02:00
Frdric Lcaille
6f5ad7fe5a CLEANUP: quic: Remove any reference to boringssl
I do not think we will support boringssl for QUIC soon ;)

(cherry picked from commit e06f7459fa)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-31 10:43:54 +02:00
Frdric Lcaille
b87f7bfd07 MEDIUM: quic: Compatible version negotiation implementation (draft-08)
At this time haproxy supported only incompatible version negotiation feature which
consists in sending a Version Negotiation packet after having received a long packet
without compatible value in its version field. This version value is the version
use to build the current packet. This patch does not modify this behavior.

This patch adds the support for compatible version negotiation feature which
allows endpoints to negotiate during the first flight or packets sent by the
client the QUIC version to use for the connection (or after the first flight).
This is done thanks to "version_information" parameter sent by both endpoints.
To be short, the client offers a list of supported versions by preference order.
The server (or haproxy listener) chooses the first version it also supported as
negotiated version.

This implementation has an impact on the tranport parameters handling (in both
direcetions). Indeed, the server must sent its version information, but only
after received and parsed the client transport parameters). So we cannot
encode these parameters at the same time we instantiated a new connection.

Add QUIC_TP_DRAFT_VERSION_INFORMATION(0xff73db) new transport parameter.
Add tp_version_information new C struct to handle this new parameter.
Implement quic_transport_param_enc_version_info() (resp.
quic_transport_param_dec_version_info()) to encode (resp. decode) this
parameter.
Add qc_conn_finalize() which encodes the transport parameters and configure
the TLS stack to send them.
Add ->negotiated_ictx quic_conn C struct new member to store the Initial
QUIC TLS context for the negotiated version. The Initial secrets derivation
is version dependent.
Rename ->version to ->original_version and add ->negotiated_version to
this C struct to reflect the QUIC-VN RFC denomination.
Modify most of the QUIC TLS API functions to pass a version as parameter.
Export the QUIC version definitions to be reused at least from quic_tp.c
(transport parameters.
Move the token check after the QUIC connection lookup. As this is the original
version which is sent into a Retry packet, and because this original version is
stored into the connection, we must check the token after having retreived this
connection.
Add packet version to traces.

See https://datatracker.ietf.org/doc/html/draft-ietf-quic-version-negotiation-08
for more information about this new feature.

(cherry picked from commit 301425b880)
[wt: note that the API temporarily differs due to force_ack already being there;
  also fixed an argument inversion to qc_build_pkt() that was later fixed by
  accident as part of 77ac6f566]
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-31 10:43:54 +02:00
Frdric Lcaille
271cc04be9 MEDIUM: quic: Add QUIC v2 draft support
This is becoming difficult to handle the QUIC TLS related definitions
which arrive with a QUIC version (draft or not). So, here we add
quic_version C struct which does not define only the QUIC version number,
but also the QUIC TLS definitions which depend on a QUIC version.
Modify consequently all the QUIC TLS API to reuse these definitions
through new quic_version C struct.
Implement quic_pkt_type() function which return a packet type (0 up to 3)
depending on the QUIC version number.
Stop harding the Retry packet first byte in send_retry(): this is not more
possible because the packet type field depends on the QUIC version.
Also modify quic_build_packet_long_header() for the same reason: the packet
type depends on the QUIC version.
Add a quic_version C struct member to quic_conn C struct.
Modify qc_lstnr_pkt_rcv() to set this member asap.
Remove the version member from quic_rx_packet C struct: a packet is attached
asap to a connection (or dropped) which is the unique object which should
store the QUIC version.
Modify qc_pkt_is_supported_version() to return a supported quic_version C
struct from a version number.
Add Initial salt for QUIC v2 draft (initial_salt_v2_draft).

(cherry picked from commit 86845c5171)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-31 10:43:54 +02:00
Frdric Lcaille
b51d512c0a CLEANUP: quid: QUIC draft-28 no more supported
Remove this useless definition.

(cherry picked from commit 83bf9ca25a)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-31 10:43:54 +02:00
Frdric Lcaille
be88aae12c MINOR: quic: Add several nonce and key definitions for Retry tag
The nonce and keys used to cipher the Retry tag depend on the QUIC version.
Add these definitions for 0xff00001d (draft-29) and v2 QUIC version. At least
draft-29 is useful for QUIC tracker tests with "quic-force-retry" enabled
on haproxy side.
Validated with -v 0xff00001d ngtcp2 option.
Could not validate the v2 nonce and key at this time because not supported.

(cherry picked from commit 3f96a0a4c1)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-31 10:43:54 +02:00
Amaury Denoyelle
523b8b3202 MINOR: qpack: reduce dependencies on other modules
Clean up QPACK decoder API by removing dependencies on ncbuf and
MUX-QUIC. This reduces includes statements. It will also help to
implement a standalone QPACK decoder.

(cherry picked from commit 53eef46b88)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-31 10:43:54 +02:00
Amaury Denoyelle
50f22fb934 MINOR: mux-quic/h3: adjust demuxing function return values
Clean the API used by decode_qcs() and transcoder internal functions.
Parsing functions now returns a ssize_t which represents the number of
consumed bytes or a negative error code. The total consumed bytes is
returned via decode_qcs().

The API is now unified and cleaner. The MUX can thus simply use the
return value of decode_qcs() instead of substracting the data bytes in
the buffer before and after the call. Transcoders functions are not
anymore obliged to remove consumed bytes from the buffer which was not
obvious.

(cherry picked from commit 1f21ebdd76)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-31 10:43:54 +02:00
Amaury Denoyelle
9ff784914b MINOR: mux-quic: simplify decode_qcs API
Slightly modify decode_qcs function used by transcoders. The MUX now
gives a buffer instance on which each transcoder is free to work on it.
At the return of the function, the MUX removes consume data from its own
buffer.

This reduces the number of invocation to qcs_consume at the end of a
full demuxing process. The API is also cleaner with the transcoders not
responsible of calling it with the risk of having the input buffer
freed if empty.

(cherry picked from commit 62eef85961)
[wt: ctx updates due to some parts that were already integrated in
     qcc_decode_qcs(), h3_headers_to_htx(), and h3_decode_qcs()]
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-31 10:43:54 +02:00
Christopher Faulet
7b3cee46ca MINOR: quic: Revert recent QUIC commits
This reverts following commits;

 * d4b45fced MINOR: quic: Add a trace to distinguish the datagram from the packets inside
 * efa5ee3a4 MINOR: quic: Replace MT_LISTs by LISTs for RX packets.
 * cacdc1465 BUG/MINOR: quic: Frames added to packets even if not built.
 * aaf95c19f CLEANUP: quic: Remove a useless check in qc_lstnr_pkt_rcv()
 * 2fd17a0d6 CLEANUP: quic: No more use ->rx_list MT_LIST entry point (quic_rx_packet)
 * 87af6f85a BUG/MINOR: quic: Stalled connections (missing I/O handler wakeup)
 * 51cf73061 BUG/MINOR: quic: Leak in qc_release_lost_pkts() for non in flight TX packets
 * c1b17a46c BUG/MINOR: quic: Safer QUIC frame builders
 * 0ebceedaf BUG/MINOR: quic: Wrong list_for_each_entry() use when building packets from qc_do_build_pkt()

QUIC implementation on 2.6 will be upgraded to match the state of
2.7-dev. This work was partially performed in a dedicated branch and commits
above were mistakenly backported.

It is 2.6-specific. There is no upstream ID and no backport is needed.
2022-08-31 08:28:26 +02:00
Frédéric Lécaille
efa5ee3a4e MINOR: quic: Replace MT_LISTs by LISTs for RX packets.
Replace ->rx.pqpkts quic_enc_level struct member MT_LIST by an LIST.
Same thing for ->list quic_rx_packet struct member MT_LIST.
Update the code consequently. This was a reminisence of the multithreading
support (several threads by connection).

Must be backported to 2.6

(cherry picked from commit a2d8ad20a3)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-08-29 17:16:32 +02:00
Frédéric Lécaille
2fd17a0d68 CLEANUP: quic: No more use ->rx_list MT_LIST entry point (quic_rx_packet)
This quic_rx_packet is definitively no more used.

Should be backported to 2.6 to ease the future backports.

(cherry picked from commit f34c1c9568)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-08-29 17:16:32 +02:00
William Lallemand
df135f08f1 MINOR: resolvers: shut the warning when "default" resolvers is implicit
Shut the connect() warning of resolvers_finalize_config() when the
configuration was not emitted manually.

This shuts the warning for the "default" resolvers which is created
automatically for the httpclient.

Must be backported in 2.6.

(cherry picked from commit b10b1196b8)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-08-29 17:16:32 +02:00
Christopher Faulet
549dc891e9 BUG/MINOR: tcpcheck: Disable QUICKACK only if data should be sent after connect
It is only a real problem for agent-checks when there is no agent string to
send. The condition to disable TCP_QUICKACK was only based on the action
type following the connect one. But it is not always accurate. indeed, for
agent-checks, there is always a SEND action. But if there is no "agent-send"
string defined, nothing is sent. In this case, this adds 200ms of latency
with no reason.

To fix the bug, a flag is now used on the CONNECT action to instruct there
are data that should be sent after the connect. For health-checks, this flag
is set if the action following the connect is a SEND action. For
agent-checks, it is set if an "agent-send" string is defined.

This patch should fix the issue #1836. It must be backported as far as 2.2.

(cherry picked from commit 871dd82117)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-08-29 17:16:32 +02:00
Willy Tarreau
cab224185b MINOR: applet: add a function to reset the svcctx of an applet
The CLI needs to reset the svcctx between commands, and there was nothing
done to handle this. Let's add appctx_reset_svcctx() to do that, it's the
closing equivalent of appctx_reserve_svcctx().

This will have to be backported to 2.6 as it will be used by a subsequent
patch to fix a bug.

(cherry picked from commit 1cc08a33e1)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-19 08:08:07 +02:00
Willy Tarreau
6a5348101c BUILD: debug: silence warning on gcc-5
In 2.6, 8a0fd3a36 ("BUILD: debug: work around gcc-12 excessive
-Warray-bounds warnings") disabled some warnings that were reported
around the the BUG() statement. But the -Wnull-dereference warning
isn't known from gcc-5, it only arrived in gcc-6, hence makes gcc-5
complain loudly that it doesn't know this directive. Let's just
condition this one to gcc-6.

(cherry picked from commit 481edaceb8)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-11 15:14:09 +02:00
Willy Tarreau
0380b7fbb3 BUG/MEDIUM: task: relax one thread consistency check in task_unlink_wq()
While testing the fix for the previous issue related to reloads with
hard_stop_after, I've met another one which could spuriously produce:

  FATAL: bug condition "t->tid >= 0 && t->tid != tid" matched at include/haproxy/task.h:266

In 2.3-dev2, we've added more consistency checks for a number of bug-
inducing programming errors related to the tasks, via commit e5d79bccc
("MINOR: tasks/debug: add a few BUG_ON() to detect use of wrong timer
queue"), and this check comes from there.

The problem that happens here is that when hard-stop-after is set, we
can abort the current thread even if there are still ongoing checks
(or connections in fact). In this case some tasks are present in a
thread's wait queue and are thus bound exclusively to this thread.

During deinit(), the collect and cleanup of all memory areas also
stops servers and kills their check tasks. And calling task_destroy()
does in turn call task_unlink_wq()... except that it's called from
thread 0 which doesn't match the initially planned thread number.

Several approaches are possible. One of them would consist in letting
threads perform their own cleanup (tasks, pools, FDs, etc). This would
possibly be even faster since done in parallel, but some corner cases
might be way more complicated (e.g. who will kill a check's task, or
what to do with a task found in a local wait queue or run queue, and
what about other consistency checks this could violate?).

Thus for now this patches takes an easier and more conservative
approach consisting in admitting that when the process is stopping,
this rule is not necessarily valid, and to let thread 0 collect all
other threads' garbage.

As such this patch can be backpoted to 2.4.

(cherry picked from commit 341ac99f4d)
[wt: no task->tid in 2.6, stay on thread_mask vs tid_bit]
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-11 14:12:45 +02:00
Ilya Shipitsin
8bd071d4fa CLEANUP: assorted typo fixes in the code and comments
This is 31st iteration of typo fixes

(cherry picked from commit 3b64a28e15)
[wt: dropped irrelevant entries for 2.6]
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-11 14:05:30 +02:00
Frdric Lcaille
f8e63fdc0d BUG/MINOR: quic: Missing in flight ack eliciting packet counter decrement
The decrement was missing in quic_pktns_tx_pkts_release() called each time a
packet number space is discarded. This is not sure this bug could have an impact
during handshakes. This counter is used to cancel the timer used both for packet
detection and PTO, setting its value to null. So there could be retransmissions
or probing which could be triggered for nothing.

Must be backported to 2.6.

(cherry picked from commit 8ddde4f05e)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-03 15:08:45 +02:00
Christopher Faulet
b45110ad06 REORG: server: Export srv_settings_cpy() function
This function will be used to init a proxy with settings of the default
proxy. It is mandatory to fix a bug. To do so, it must be exposed.

(cherry picked from commit b32cb9b515)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-03 14:59:10 +02:00
Amaury Denoyelle
9e44d57c7a CLEANUP: mux-quic: remove useless app_ops is_active callback
Timeout in QUIC MUX has evolved from the simple first implementation. At
the beginning, a connection was considered dead unless bidirectional
streams were opened. This was abstracted through an app callback
is_active().

Now this paradigm has been reversed and a connection is considered alive
by default, unless an error has been reported or a timeout has already
been fired. The callback is_active() is thus not used anymore and can be
safely removed to simplify qcc_is_dead().

This commit should be backported to 2.6.

(cherry picked from commit 4ea5090f55)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-03 14:55:53 +02:00
Willy Tarreau
a4aafe8f9c MINOR: ebtree: add ebmb_lookup_shorter() to pursue lookups
This function is designed to enlarge the scope of a lookup performed
by a caller via ebmb_lookup_longest() that was not satisfied with the
result. It will first visit next duplicates, and if none are found,
it will go up in the tree to visit similar keys with shorter prefixes
and will return them if they match. We only use the starting point's
value to perform the comparison since it was expected to be valid for
the looked up key, hence it has all bits in common with its own length.

The algorithm is a bit complex because when going up we may visit nodes
that are located beneath the level we just come from. However it is
guaranteed that keys having a shorter prefix will be present above the
current location, though they may be attached to the left branch of a
cover node, so we just visit all nodes as long as their prefix is too
large, possibly go down along the left branch on cover nodes, and stop
when either there's a match, or there's a non-matching prefix anymore.

The following tricky case now works fine and properly finds 10.0.0.0/7
when looking up 11.0.0.1 from tree version 1 though both belong to
different sub-trees:

  prepare map #1
    add map @1 #1 10.0.0.0/7 10.0.0.0/7
    add map @1 #1 10.0.0.0/7 10.0.0.0/7
  commit map @1 #1
  prepare map #1
    add map @2 #1 11.0.0.0/8 11.0.0.0/8
    add map @2 #1 11.0.0.0/8 11.0.0.0/8

  prepare map #1
    add map @1 #1 10.0.0.0/7 10.0.0.0/7
  commit map @1 #1
  prepare map #1
    add map @2 #1 10.0.0.0/7 10.0.0.0/7
    add map @2 #1 11.0.0.0/8 11.0.0.0/8
    add map @2 #1 11.0.0.0/8 11.0.0.0/8

(cherry picked from commit 81f3b80e32)
[wt: backported as needed by following patch]
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-03 14:55:25 +02:00
Frdric Lcaille
b9db88ea45 MINOR: quic: New "quic-cc-algo" bind keyword
As it could be interesting to be able to choose the QUIC control congestion
algorithm to be used by listener, add "quic-cc-algo" new keyword to do so.
Update the documentation consequently.

Must be backported to 2.6.

(cherry picked from commit 43910a9450)
[wt: minor ctx update in xprt_quic.c]
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-03 14:54:10 +02:00
Frdric Lcaille
4c7aabebe6 MEDIUM: quic: Cubic congestion control algorithm implementation
Cubic is the congestion control algorithm used by default by the Linux kernel
since 2.6.15 version. This algorithm is supposed to achieve good scalability and
fairness between flows using the same network path, it should also be used by QUIC
by default. This patch implements this algorithm and select it as default algorithm
for the congestion control.

Must be backported to 2.6.

(cherry picked from commit 1c9c2f6c02)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-03 14:53:30 +02:00
Frdric Lcaille
e0056a60e8 MINOR: quic: Congestion control architecture refactoring
Ease the integration of new congestion control algorithm to come.
Move the congestion controller state to a private array of uint32_t
to stop using a union. We do not want to continue using such long
paths cc->algo_state.<algo>.<var> to modify the internal state variable
for each algorithm.

Must be backported to 2.6

(cherry picked from commit c591459d11)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-03 14:53:25 +02:00
William Lallemand
425542423c DEBUG: fd: split the fd check
Split the BUG_ON(fd < 0 || fd >= global.maxsock) so it's easier to know
if it quits because of a -1.

(cherry picked from commit dc66f2f97d)
Signed-off-by: Willy Tarreau <w@1wt.eu>
2022-08-03 14:52:11 +02:00
Willy Tarreau
bf7f10efbd BUG/MINOR: tools: fix statistical_prng_range()'s output range
This function was added by commit 84ebfabf7 ("MINOR: tools: add
statistical_prng_range() to get a random number over a range") but it
contains a bug on the range, since mul32hi() covers the whole input
range, we must pass it range-1. For now it didn't have any impact, but
if used to find an array's index it will cause trouble.

This should be backported to 2.4.

(cherry picked from commit 03f3049df1)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-07-20 14:13:28 +02:00
Willy Tarreau
1dbb194015 BUG/MEDIUM: tools: avoid calling dlsym() in static builds (try 2)
The first approach in commit 288dc1d8e ("BUG/MEDIUM: tools: avoid calling
dlsym() in static builds") relied on dlopen() but on certain configs (at
least gcc-4.8+ld-2.27+glibc-2.17) it used to catch situations where it
ought not fail.

Let's have a second try on this using dladdr() instead. The variable was
renamed "build_is_static" as it's exactly what's being detected there.
We could even take it for reporting in -vv though that doesn't seem very
useful. At least the variable was made global to ease inspection via the
debugger, or in case it's useful later.

Now it properly detects a static build even with gcc-4.4+glibc-2.11.1 and
doesn't crash anymore.

(cherry picked from commit 5b3cd9561b)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-07-20 14:12:12 +02:00
Amaury Denoyelle
3157676fae MINOR: h3: add h3c pointer into h3s instance
As a mirror to qcc/qcs types, add a h3c pointer into h3s struct. This
should help to clean up H3 code and avoid to use qcs.qcc.ctx to retrieve
the h3c instance.

(cherry picked from commit c0156790e6)
 [ad: cherry-picked to simplify future backports]
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
2022-07-20 13:58:01 +02:00
Amaury Denoyelle
a648caba60 MINOR: ncbuf: implement ncb_is_fragmented()
Implement a new status function for ncbuf. It allows to quickly report
if a buffer contains data in a fragmented way, i.e. with gaps in between
or at start of the buffer.

To summarize, a buffer is considered as non-fragmented in the following
cases :
- a null or empty buffer
- a full buffer
- a buffer containing exactly one data block at the beginning, following
  by a gap until the end.

(cherry picked from commit e0a92a7e56)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-07-20 13:58:01 +02:00
Frédéric Lécaille
86bd4b4329 MINOR: quic: Increase the QUIC connections RX buffer size (upto 64Kb)
With ~1500 bytes QUIC datagrams, we can handle less than 200 datagrams
which is less than the default maxpollevents value. This should reduce
the chances of fulfilling the connections RX buffers as reported by
Tristan in GH #1737.

Must be backported to 2.6.

(cherry picked from commit 649b3fd9aa)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-07-20 13:58:01 +02:00
Frédéric Lécaille
21e0c31695 MINOR: task: Add tasklet_wakeup_after()
We want to be able to schedule a tasklet onto a thread after the current tasklet
is done. What we have to do is to insert this tasklet at the head of the thread
task list. Furthermore, we would like to serialize the tasklets. They must be
run in the same order as the order in which they have been scheduled. This is
implemented passing a list of tasklet as parameter (see <head> parameters) which
must be reused for subsequent calls.
_tasklet_wakeup_after_on() is implemented to accomplish this job.
tasklet_wakeup_after_on() and tasklet_wake_after() are only wrapper macros around
_tasklet_wakeup_after_on(). tasklet_wakeup_after_on() does exactly the same thing
as _tasklet_wakeup_after_on() without having to pass the filename and line in the
filename as parameters (usefull when DEBUG_TASK is enabled).
tasklet_wakeup_after() hides also the usage of the thread parameter which is
<tl> tasklet thread ID.

(cherry picked from commit ad548b54a7)
 [ad: backported for next commit.]
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
2022-07-20 13:58:01 +02:00
Frédéric Lécaille
19ac5361cd MINOR: quic: Duplicated QUIC_RX_BUFSZ definition
This macro is already defined in src/quic_sock.c which is the correct place.

Must be backported to 2.6

(cherry picked from commit 1ca14950e6)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-07-20 13:58:01 +02:00
Frédéric Lécaille
f395e89169 MINOR: quic: Add new stats counter to diagnose RX buffer overrun
Remove the call to qc_list_all_rx_pkts() which print messages on stderr
during RX buffer overruns and add a new counter for the number of dropped packets
because of such events.

Must be backported to 2.6

(cherry picked from commit 45a16295e3)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-07-20 13:58:01 +02:00
Frédéric Lécaille
1ddb3a66d0 BUILD: quic+h3: 32-bit compilation errors fixes
In GH #1760 (which is marked as being a feature), there were compilation
errors on MacOS which could be reproduced in Linux when building 32-bit code
(-m32 gcc option). Most of them were due to variables types mixing in QUIC_MIN macro
or using size_t type in place of uint64_t type.

Must be backported to 2.6.

(cherry picked from commit 628e89cfae)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-07-20 13:58:01 +02:00
Christopher Faulet
e0d82ea08b MINOR: http: Add function to detect default port
http_is_default_port() can be used to test if a port is a default HTTP/HTTPS
port. A scheme may be specified. In this case, it is used to detect defaults
ports, 80 for "http://" and 443 for "https://". Otherwise, with no scheme, both
are considered as default ports.

(cherry picked from commit ca7218aaf0)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-07-08 17:39:46 +02:00
Christopher Faulet
70bdf7042e MINOR: http: Add function to get port part of a host
http_get_host_port() function can be used to get the port part of a host. It
will be used to get the port of an uri authority or a host header
value. This function only look for a port starting from the end of the
host. It is the caller responsibility to call it with a valid host value. An
indirect string is returned.

(cherry picked from commit 658f971621)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-07-08 17:39:46 +02:00
Emeric Brun
e670806410 MINOR: fd: Add BUG_ON checks on fd_insert()
This patch adds two BUG_ON on fd_insert() into the fdtab checking
if the fd has been correctly re-initialized into the fdtab
before a new insert.

It will raise a BUG if we try to insert the same fd multiple times
without an intermediate fd_delete().

First one checks that the owner for this fd in fdtab was reset to NULL.

Second one checks that the state flags for this fd in fdtab was reset
to 0.

This patch could be backported on version >= 2.4

(cherry picked from commit 36d9097cf3)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-07-08 17:39:46 +02:00
Emeric Brun
7e47164fe3 MINOR: fd: add a new FD_DISOWN flag to prevent from closing a deleted FD
Some FDs might be offered to some external code (external libraries)
which will deal with them until they close them. As such we must not
close them upon fd_delete() but we need to delete them anyway so that
they do not appear anymore in the fdtab. This used to be handled by
fd_remove() before 2.3 but we don't have this anymore.

This patch introduces a new flag FD_DISOWN to let fd_delete() know that
the core doesn't own the fd and it must not be closed upon removal from
the fd_tab. This way it's totally unregistered from the poller but still
open.

This patch must be backported on branches >= 2.3 because it will be
needed to fix a bug affecting SSL async. it should be adapted on 2.3
because state flags were stored in a different way (via bits in the
structure).

(cherry picked from commit f41a3f6762)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-07-08 17:39:46 +02:00
Frédéric Lécaille
938dc62537 BUG/MINOR: quic: Unexpected half open connection counter wrapping
This counter must be incremented only one time by connection and decremented
as soon as the handshake has failed or succeeded. This is a gauge. Under certain
conditions this counter could be decremented twice. For instance
after having received a TLS alert, then upon SSL_do_handshake() failure.
To stop having to deal to all the current combinations which can lead to such a
situation (and the next to come), add a connection flag to denote if this counter
has been already decremented for a connection. So, this counter must be decremented
only if this flag has not been already set.

Must be backported up to 2.6.

(cherry picked from commit 2aebaa49b1)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
2022-06-21 12:11:49 +02:00
Christopher Faulet
7560c24f6d BUG/MEDIUM: stream: Properly handle destructive client connection upgrades
When the protocol is changed for a client connection at the stream level
(from TCP to H1/H2), there are two cases. The stream may be reused or
not. The first case, when the stream is reused is working. The second one is
buggy since the conn-stream refactoring and leads to a crash.

In this case, the new mux don't reuse the stream. It must be silently
aborted. However, its front stream connector is still referencing the
connection. So it must be detached. But it must be performed in two stages,
to be sure to not loose the context for the upgrade and to be able to
rollback on error. So now, before the upgrade, we prepare to detach the
stconn and it is finally detached if the upgrade succeeds. There is a trick
here. Because we pretend the stconn is detached but its state is preserved.

This patch must be backported to 2.6.

(cherry picked from commit b68f77d626)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
2022-06-21 12:11:49 +02:00
Frédéric Lécaille
983698d92a BUG/MINOR: quic: Wrong PTO calculation
Due to missing brackets around the ternary C operator, quic_pto() could return zero
at the first run, before the QUIC connection was completely initialized. This leaded
the idle timeout task to be executed before this initialization completion. Then
this connection could be immediately released.

This bug was revealed by the multi_packet_client_hello QUIC tracker test.

Must be backported to 2.6.

(cherry picked from commit fa94f77bc5)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
2022-06-21 12:11:49 +02:00
Amaury Denoyelle
2317890bea BUG/MINOR: h3/qpack: deal with too many headers
ensures that we never insert too many entries in a headers input list.
On the decoding side, a new error QPACK_ERR_TOO_LARGE is reported in
this case.

This prevents crash if headers number on a H3 request or response is
superior to tune.http.maxhdr config value. Previously, a crash would
occur in QPACK decoding function.

Note that the process still crashes later with ABORT_NOW() because error
reporting on frame parsing is not implemented for now. It should be
treated with a RESET_STREAM frame in most cases.

This can be backported up to 2.6.

(cherry picked from commit 60ef19f137)
[ad: adjusted context]
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
2022-06-21 12:11:49 +02:00
Amaury Denoyelle
33446e8232 MINOR: qpack: add comments and remove a useless trace
Add comments on the decoding function to facilitate code analysis.

Also remove the qpack_debug_hexdump() which prints the whole left buffer
on each header parsing. With large HEADERS frame payload, QPACK traces
are complicated to debug with this statement.

(cherry picked from commit c5d31ed8be)
[ad: this commit was cherry-picked to align context for future QPACK/H3
 fixes]
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
2022-06-21 12:11:49 +02:00
Amaury Denoyelle
850a92d470 BUG/MEDIUM: mux-quic: fix flow control connection Tx level
The flow control enforced at connection level is incorrectly calculated.
There is a risk of exceeding the limit. In most cases, this results in a
segfault produced by a BUG_ON which is here to catch this kind of error.
If not compiled with DEBUG_STRICT, this should generate a connection
closed by the client due to the flow control overflow.

The problem is encountered when transfered payload is big enough to fill
the transport congestion window. In this case, some data are rejected by
the transport layer and kept by the MUX to be reemitted later. However,
these preserved data are not counted on the connection flow control when
resubmitted, which gradually amplify the gap between expected and real
consumed flow control.

To fix this, handle the flow-control at the connection level in the same
way as the stream level. A new field qcc.tx.offsets is incremented as
soon as data are transfered between stream TX buffers. The field
qcc.tx.sent_offsets is preserved to count bytes handled by the transport
layer and stop the MUX transfer if limit is reached.

As already stated, this bug can occur during transfers with enough
emitted data, over multiple streams. When using a single stream, the
flow control at the stream level hides it.

The BUG_ON crash is reproduced systematically with quiche client :
$ quiche-client --no-verify --http-version HTTP/3 -n 10000 https://127.0.0.1:20443/10K

This must be backported up to 2.6 when confirmed to work as expected.

This should fix github issue #1738.

(cherry picked from commit b9e0640405)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-06-13 14:49:48 +02:00
Amaury Denoyelle
1ee82d88a0 BUG/MINOR: h3: fix frame type definition
Frame type has changed during HTTP/3 specification process. Adjust it to
reflect the latest RFC 9114 status.

Concretly, type for GOAWAY and MAX_PUSH_ID frames has been adjusted.
The impact of this bug is limited as currently these frames are not
handled by haproxy and are ignored.

This can be backported up to 2.6.

(cherry picked from commit c715eb7898)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-06-13 14:49:48 +02:00
Willy Tarreau
2229d18cd8 BUILD: compiler: implement unreachable for older compilers too
Benoit Dolez reported that gcc-4.4 emits several "may be used
uninitialized" warnings around places where there are BUG_ON()
or ABORT_NOW(). The reason is that __builtin_unreachable() was
introduced in gcc-4.5 thus older ones do not know that the code
after such statements is not reachable.

This patch solves the problem by deplacing the statement with
an infinite loop on older versions. The compiler knows that the
code following it cannot be reached, and this is quite cheap
(2 to 4 bytes depending on architectures). It even reduces the
code size a little bit as the compiler doesn't have to optimize
for branches that do not exist.

This may be backported to older versions.

(cherry picked from commit 7d318ed8cc)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2022-06-08 15:31:06 +02:00
Willy Tarreau
b2c1e081f7 MINOR: version: mention that it's LTS now.
The version will be maintained up to around Q2 2027. Let's
also update the INSTALL file to mention this.
2022-05-31 16:53:13 +02:00
Willy Tarreau
91a87918c9 BUILD: quic: use inttypes.h instead of stdint.h
The usual build joke on uncommon systems (AIX this time, though some
versions of Solaris are known for missing it as well).
2022-05-30 16:37:17 +02:00