Willy Tarreau [Wed, 2 Mar 2022 16:59:04 +0000 (17:59 +0100)]
BUG/MINOR: pool: always align pool_heads to 64 bytes
This is the pool equivalent of commit 97ea9c49f ("BUG/MEDIUM: fd: always
align fdtab[] to 64 bytes"). After a careful code review, it happens that
the pool heads are the other structures allocated with malloc/calloc that
claim to be aligned to a size larger than what the allocator can offer.
While no issue was reported on them, no memset() is performed and no type
is large, this is a problem waiting to happen, so better fix it. In
addition, it's relatively easy to do by storing the allocation address
inside the pool_head itself and use it at free() time. Finally, threads
might benefit from the fact that the caches will really be aligned and
that there will be no false sharing.
This should be backported to all versions where it applies easily.
Willy Tarreau [Wed, 2 Mar 2022 14:52:03 +0000 (15:52 +0100)]
DEBUG: reduce the footprint of BUG_ON() calls
Many inline functions involve some BUG_ON() calls and because of the
partial complexity of the functions, they're not inlined anymore (e.g.
co_data()). The reason is that the expression instantiates the message,
its size, sometimes a counter, then the atomic OR to taint the process,
and the back trace. That can be a lot for an inline function and most
of it is always the same.
This commit modifies this by delegating the common parts to a dedicated
function "complain()" that takes care of updating the counter if needed,
writing the message and measuring its length, and tainting the process.
This way the caller only has to check a condition, pass a pointer to the
preset message, and the info about the type (bug or warn) for the tainting,
then decide whether to dump or crash. Note that this part could also be
moved to the function but resulted in complain() always being at the top
of the stack, which didn't seem like an improvement.
Thanks to these changes, the BUG_ON() calls do not result in uninlining
functions anymore and the overall code size was reduced by 60 to 120 kB
depending on the build options.
Willy Tarreau [Wed, 2 Mar 2022 13:54:44 +0000 (14:54 +0100)]
BUILD: tcpcheck: do not declare tcp_check_keywords_register() inline
This one is referenced in initcalls by its pointer, it makes no sense
to declare it inline. At best it causes function duplication, at worst
it doesn't build on older compilers.
Willy Tarreau [Wed, 2 Mar 2022 13:53:00 +0000 (14:53 +0100)]
BUILD: trace: do not declare trace_registre_source() inline
This one is referenced in initcalls by its pointer, it makes no sense
to declare it inline. At best it causes function duplication, at worst
it doesn't build on older compilers.
Willy Tarreau [Wed, 2 Mar 2022 13:50:38 +0000 (14:50 +0100)]
BUILD: http_rules: do not declare http_*_keywords_registre() inline
The 3 functions http_{req,res,after_res}_keywords_register() are
referenced in initcalls by their pointer, it makes no sense to declare
them inline. At best it causes function duplication, at worst it doesn't
build on older compilers.
Willy Tarreau [Wed, 2 Mar 2022 13:46:45 +0000 (14:46 +0100)]
BUILD: connection: do not declare register_mux_proto() inline
This one is referenced in initcalls by its pointer, it makes no sense
to declare it inline. At best it causes function duplication, at worst
it doesn't build on older compilers.
Willy Tarreau [Wed, 2 Mar 2022 13:38:11 +0000 (14:38 +0100)]
BUILD: conn_stream: avoid null-deref warnings on gcc 6
gcc 6 continues its saga with excessive reports of null-deref warnings.
This time it was in the IS_HTX_CS() macro. Let's use __cs_conn() after
cs_conn() was checked.
MINOR: quic: Assemble QUIC TLS flags at the same level
Do not distinguish the direction (TX/RX) when settings TLS secrets flags.
There is not such a distinction in the RFC 9001.
Assemble them at the same level: at the upper context level.
MINOR: quic: Drop the packets of discarded packet number spaces
This is required since this previous commit:
"MINOR: quic: Post handshake I/O callback switching"
If not, such packets remain endlessly in the RX buffer and cannot be parsed
by the new I/O callback used after the handshake has been confirmed.
MINOR: quic: Ensure PTO timer is not set in the past
Wakeup asap the timer task when setting its timer in the past.
Take also the opportunity of this patch to make simplify quic_pto_pktns():
calling tick_first() is useless here to compare <lpto> with <tmp_pto>.
CLEANUP: stream: Remove useless tests on conn-stream in stream_dump()
Since the recent refactoring on the conn-streams, a stream has always a
defined frontend and backend conn-streams. Thus, in stream_dump(), there is
no reason to still test if these conn-streams are defined.
In addition, still in stream_dump(), get the stream-interfaces using the
conn-streams and not the opposite.
REGTESTS: fix the race conditions in secure_memcmp.vtc
In the same way than for normalize_uri.vtc, a "Connection: close" header is
added to all responses to avoid any connection reuse. This should avoid any
"HTTP header incomplete" errors.
Amaury Denoyelle [Mon, 28 Feb 2022 10:37:48 +0000 (11:37 +0100)]
MEDIUM: quic: rearchitecture Rx path for bidirectional STREAM frames
Reorganize the Rx path for STREAM frames on bidirectional streams. A new
function qcc_recv is implemented on the MUX. It will handle the STREAM
frames copy and offset calculation from transport to MUX.
Another function named qcc_decode_qcs from the MUX can be called by
transport each time new STREAM data has been copied.
The architecture is now cleaner with the MUX layer in charge of parsing
the STREAM frames offsets. This is required to be able to implement the
flow-control on the MUX layer.
Note that as a convenience, a STREAM frame is not partially copied to
the MUX buffer. This simplify the implementation for the moment but it
may change in the future to optimize the STREAM frames handling.
For the moment, only bidirectional streams benefit from this change. In
the future, it may be extended to unidirectional streams to unify the
STREAM frames processing.
Amaury Denoyelle [Mon, 28 Feb 2022 10:38:36 +0000 (11:38 +0100)]
BUG/MINOR: quic: support FIN on Rx-buffered STREAM frames
FIN flag on a STREAM frame was not detected if the frame was previously
buffered on qcs.rx.frms before being handled.
To fix this, copy the fin field from the quic_stream instance to
quic_rx_strm_frm. This is required to properly notify the FIN flag on
qc_treat_rx_strm_frms for the MUX layer.
Without this fix, the request channel might be left opened after the
last STREAM frame reception if there is out-of-order frames on the Rx
path.
Amaury Denoyelle [Mon, 28 Feb 2022 10:36:57 +0000 (11:36 +0100)]
MINOR: mux-quic: define flag for last received frame
This flag is set when the STREAM frame with FIN set has been received on
a qcs instance. For now, this is only used as a BUG_ON guard to prevent
against multiple frames with FIN set. It will also be useful when
reorganize the RX path and move some of its code in the mux.
Amaury Denoyelle [Fri, 25 Feb 2022 16:36:31 +0000 (17:36 +0100)]
MINOR: quic: handle partially received buffered stream frame
Adjust the function to handle buffered STREAM frames. If the offset of
the frame was already fully received, discard the frame. If only
partially received, compute the difference and copy only the newly
offset.
Before this change, a buffered frame representing a fully or partially
received offset caused the loop to be interrupted. The frame was
preserved, thus preventing frames with greater offset to be handled.
This may fix some occurences of stalled transfer on the request channel
if there is out-of-order STREAM frames on the Rx path.
Amaury Denoyelle [Mon, 28 Feb 2022 09:00:54 +0000 (10:00 +0100)]
MINOR: quic: simplify copy of STREAM frames to RX buffer
qc_strm_cpy can be simplified by simply using b_putblk which already
handle wrapping of the destination buffer. The function is kept to
update the frame length and offset fields.
Willy Tarreau [Tue, 1 Mar 2022 07:31:50 +0000 (08:31 +0100)]
DOC: install: describe how to choose options used in the DEBUG variable
This enumerates a few of the options that are expected to have an effect
on the process' self-checks at the expense of more or less performance,
and how to choose sets of options for different deployments.
Tim Duesterhus [Fri, 25 Feb 2022 20:44:27 +0000 (21:44 +0100)]
MINOR: connection: Transform safety check in PROXYv2 parsing into BUG_ON()
With BUG_ON() being enabled by default it is more useful to use a BUG_ON()
instead of an effectively never-taken if, as any incorrect assumptions will
become much more visible.
see 488ee7fb6 ("BUG/MAJOR: proxy_protocol: Properly validate TLV lengths")
Tim Duesterhus [Fri, 25 Feb 2022 20:44:26 +0000 (21:44 +0100)]
CLEANUP: connection: Indicate unreachability to the compiler in conn_recv_proxy
Transform the unreachability comment into a call to `my_unreachable()` to allow
the compiler from benefitting from it.
see d1b15b6e9 ("MINOR: proxy_protocol: Ingest PP2_TYPE_UNIQUE_ID on incoming connections")
see 615f81eb5 ("MINOR: connection: Use a `struct ist` to store proxy_authority")
Willy Tarreau [Mon, 28 Feb 2022 16:57:19 +0000 (17:57 +0100)]
BUILD: debug: fix build warning on older compilers around DEBUG_STRICT_ACTION
The new macro was introduced with commit 86bcc5308 ("DEBUG: implement 4
levels of choices between warn and crash.") but some older compilers can
complain that we test the value when the macro is not defined despite
having already been checked in a previous #if directive. Let's just
repeat the test for the definition.
DEBUG: stream-int: Fix BUG_ON used to test appctx in si_applet_ops callbacks
693b23bb1 ("MEDIUM: tree-wide: Use unsafe conn-stream API when it is
relevant") introduced a regression in DEBUG_STRICT mode because some BUG_ON
conditions were inverted. It should ok now.
In addition, ALREADY_CHECKED macro was removed from appctx_wakeup() function
because it is useless now.
REGTESTS: fix the race conditions in normalize_uri.vtc
There is no connection reuse to avoid race conditions in HTTP reg-tests. But
time to time, normalize_uri.vtc still report "HTTP header incomplete"
error. It seems to be because HTTP keep-alive is still used at the session
level. Thus when the same server section is used to handle multiple requests
for the same client, via a "-repeat" statement, a new request for this client
may be handled by HAProxy before the server is restarted.
To avoid any trouble, HTTP keep-alive is disabled on the server side by
adding "Connection: close" header in responses. It seems to be ok now. We
let the CI decide.
BUG/MEDIUM: htx: Fix a possible null derefs in htx_xfer_blks()
In htx_xfer_blks() function, when headers or trailers are partially
transferred, we rollback the copy by removing copied blocks. Internally, all
blocks between <dstref> and <dstblk> are removed. But if the transfer was
stopped because we failed to reserve a block, the variable <dstblk> is
NULL. Thus, we must not try to remove it. It is unexpected to call
htx_remove_blk() in this case.
htx_remove_blk() was updated to test <blk> variable inside the existing
BUG_ON(). The block must be defined.
For now, this bug may only be encountered when H2 trailers are copied. On H2
headers, the destination buffer is empty. Thus a swap is performed.
This patch should fix the issue #1578. It must be backported as far as 2.4.
BUG/MEDIUM: mux-fcgi: Don't rely on SI src/dst addresses for FCGI health-checks
When an HTTP health-check is performed in FCGI, we must not rely on the SI
source and destination addresses to set default parameters
(REMOTE_ADDR/REMOTE_PORT and SERVER_NAME/SERVER_PORT) because the backend
conn-stream is not attached to a stream but to a healt-check. Thus, there is
no stream-interface. In addition, there is no client connection because it
is an "internal" session.
Thus, for now, in this case, there is only the server connection that can be
used. So src/dst addresses are retrieved from the server connection when the
CS application is a health-check.
This patch should solve issue #1572. It must be backported to 2.5. Note than
the CS api has changed. Thus, on HAProxy 2.5, we should test the session's
origin instead:
REORG: stream-int: Uninline si_sync_recv() and make si_cs_recv() private
This way si_*_recv() and si_*_sned() API are defined the same
way. si_sync_snd/si_sync_recv are both exported and defined in the C
file. And si_cs_send/si_cs_recv are private and only used by
stream-interface internals.
MEDIUM: tree-wide: Use unsafe conn-stream API when it is relevant
The unsafe conn-stream API (__cs_*) is now used when we are sure the good
endpoint or application is attached to the conn-stream. This avoids compiler
warnings about possible null derefs. It also simplify the code and clear up
any ambiguity about manipulated entities.
MINOR: conn-stream: Improve API to have safe/unsafe accessors
Depending on the context, we know the endpoint or the application attached
to the conn_stream is defined and we know its type. However, having
accessors testing the endpoint or the application may lead the compiler to
report possible null derefs here and there. The alternative is to add
useless tests or use ALREAD_CHECKED/DISGUISE macros. It is tedious and
inelegant.
So now, similarily to the ob API, the safe API, testing
endpoint/application, relies on an unsafe one (same name prefixed with
'__'). This way, any caller may use the unsafe API when it is relevant.
In addition, there is no reason to test the conn-stream itself. It is the
caller responsibility to be sure there is a conn-stream to get its endpoint
or its application. And most of type, we are sure to have a conn-stream.
Willy Tarreau [Mon, 28 Feb 2022 15:55:51 +0000 (16:55 +0100)]
DEBUG: channel: add consistency checks using BUG_ON_HOT() in some key functions
A few functions such as c_adv(), c_rew(), co_set_data() or co_skip() got a
BUG_ON_HOT() to make sure they're not used to push more data than available
in the buffer. Note that with HTX the margin can be high and will less easily
trigger, but the goal is to detect a misuse early enough.
co_data() should never be called with a wrong c->output. At least it never
happens in regtests, but we're adding a CHECK_IF_HOT() there to avoid crashing
but report it if it ever happened when the hot path checks are enabled.
Willy Tarreau [Mon, 28 Feb 2022 15:51:23 +0000 (16:51 +0100)]
MINOR: channel: don't use co_set_data() to decrement output
The use of co_set_data() should be strictly limited to setting the amount
of existing data to be transmitted. It ought not be used to decrement the
output after the data have left the buffer, because doing so involves
performing incorrect calculations using co_data() that still comprises
data that are not in the buffer anymore. Let's use c_rew() for this, which
is made exactly for this purpose, i.e. decrement c->output by as much as
requested. This is cleaner, faster, and will permit stricter checks.
Willy Tarreau [Mon, 28 Feb 2022 15:11:33 +0000 (16:11 +0100)]
DEBUG: buf: add BUG_ON_HOT() to most buffer management functions
A number of tests are now performed in low-level buffer management
functions to verify that we're not appending data to a full buffer
for example, or that the buffer passed in argument is consistent in
that its data don't outweigh its size. The few functions that already
involve memcpy() or memmove() instead got a BUG_ON() that will always
be enabled, since the overhead remains minimalist.
Willy Tarreau [Mon, 28 Feb 2022 15:10:00 +0000 (16:10 +0100)]
DEBUG: buf: replace some sensitive BUG_ON() with BUG_ON_HOT()
The buffer ring management functions br_* were all stuffed with BUG_ON()
statements that never triggered and that are on some fast paths (e.g. in
mux_h2). Let's turn them to BUG_ON_HOT() instead.
Willy Tarreau [Mon, 28 Feb 2022 14:25:58 +0000 (15:25 +0100)]
DEBUG: add two new macros to enable debugging in hot paths
Two new BUG_ON variants, BUG_ON_HOT() and CHECK_IF_HOT() are introduced
to debug hot paths (such as low-level API functions). These ones must
not be enabled by default as they would significantly affect performance
but they may be enabled by setting DEBUG_STRICT to a value above 1. In
this case, DEBUG_STRICT_ACTION is mostly respected with a small change,
which is that the no_crash variant of BUG_ON() isn't turned to a regular
warning but to a one-time warning so as not to spam with warnings in a
hot path. It is for this reason that there is no WARN_ON_HOT().
Willy Tarreau [Mon, 28 Feb 2022 13:59:25 +0000 (14:59 +0100)]
DEBUG: implement 4 levels of choices between warn and crash.
We used to have DEBUG_STRICT_NOCRASH to disable crashes on BUG_ON().
Now we have other levels (WARN_ON(), CHECK_IF()) so we need something
finer-grained.
This patch introduces DEBUG_STRICT_ACTION which takes an integer value.
0 disables crashes and is the equivalent of DEBUG_STRICT_NOCRASH. 1 is
the default and only enables crashes on BUG_ON(). 2 also enables crashes
on WARN_ON(), and 3 also enables warnings on CHECK_IF(), and is suited
to developers and CI.
Willy Tarreau [Mon, 28 Feb 2022 13:15:41 +0000 (14:15 +0100)]
DEBUG: improve BUG_ON output message accuracy
Now we'll explicitly mention if the test was a bug/warn/check, and
"FATAL" is only displayed when the process crashes. The non-crashing
BUG_ON() also suggests to report to developers.
Willy Tarreau [Mon, 28 Feb 2022 10:51:23 +0000 (11:51 +0100)]
DEBUG: rename WARN_ON_ONCE() to CHECK_IF()
The only reason for warning once is to check if a condition really
happens. Let's use a term that better translates the intent, that's
important when reading the code.
Willy Tarreau [Fri, 25 Feb 2022 16:12:11 +0000 (17:12 +0100)]
[RELEASE] Released version 2.6-dev2
Released version 2.6-dev2 with the following main changes :
- DOC: management: rework the Master CLI section
- DOC: management: add expert and experimental mode in 9.4.1
- CLEANUP: cleanup a commentary in pcli_parse_request()
- BUG/MINOR: mworker/cli: don't display help on master applet
- MINOR: mworker/cli: mcli-debug-mode enables every command
- MINOR: mworker/cli: add flags in the prompt
- BUG/MINOR: httpclient: Revisit HC request and response buffers allocation
- BUG/MEDIUM: httpclient: Xfer the request when the stream is created
- MINOR: httpclient: Don't limit data transfer to 1024 bytes
- BUILD: ssl: adjust guard for X509_get_X509_PUBKEY(x)
- REGTESTS: ssl: skip show_ssl_ocspresponse.vtc when BoringSSL is used
- MINOR: quic: Do not modify a marked as consumed datagram
- MINOR: quic: Wrong datagram buffer passed to quic_lstnr_dgram_dispatch()
- MINOR: quic: Remove a useless test in quic_get_dgram_dcid()
- BUG/MINOR: ssl: Remove empty lines from "show ssl ocsp-response <id>" output
- CLEANUP: ssl: Remove unused ssl_sock_create_cert function
- MINOR: ssl: Use high level OpenSSL APIs in sha2 converter
- MINOR: ssl: Remove EC_KEY related calls when preparing SSL context
- REGTESTS: ssl: Add test for "curves" and "ecdhe" SSL options
- MINOR: ssl: Remove EC_KEY related calls when creating a certificate
- REGTESTS: ssl: Add test for "generate-certificates" SSL option
- MINOR: ssl: Remove call to SSL_CTX_set_tlsext_ticket_key_cb with OpenSSLv3
- MINOR: ssl: Remove call to HMAC_Init_ex with OpenSSLv3
- MINOR: h3: hardcode the stream id of control stream
- MINOR: mux-quic: remove quic_transport_params_update
- MINOR: quic: rename local tid variable
- MINOR: quic: remove unused xprt rcv_buf operation
- MINOR: quic: take out xprt snd_buf operation
- CI: enable QUIC for Coverity scan
- BUG/MINOR: mworker: does not erase the pidfile upon reload
- MINOR: ssl: Remove call to ERR_func_error_string with OpenSSLv3
- MINOR: ssl: Remove call to ERR_load_SSL_strings with OpenSSLv3
- REGTESTS: ssl: Add tests for DH related options
- MINOR: ssl: Create HASSL_DH wrapper structure
- MINOR: ssl: Add ssl_sock_get_dh_from_bio helper function
- MINOR: ssl: Factorize ssl_get_tmp_dh and append a cbk to its name
- MINOR: ssl: Add ssl_sock_set_tmp_dh helper function
- MINOR: ssl: Add ssl_sock_set_tmp_dh_from_pkey helper function
- MINOR: ssl: Add ssl_new_dh_fromdata helper function
- MINOR: ssl: Build local DH of right size when needed
- MINOR: ssl: Set default dh size to 2048
- MEDIUM: ssl: Replace all DH objects by EVP_PKEY on OpenSSLv3 (via HASSL_DH type)
- MINOR: ssl: Remove calls to SSL_CTX_set_tmp_dh_callback on OpenSSLv3
- MINOR: quic: Remove an RX buffer useless lock
- MINOR: quic: Variable used before being checked in ha_quic_add_handshake_data()
- MINOR: quic: EINTR error ignored
- MINOR: quic: Potential overflow expression in qc_parse_frm()
- MINOR: quic: Possible overflow in qpack_get_varint()
- CLEANUP: h3: Unreachable target in h3_uqs_init()
- MINOR: quic: Possible memleak in qc_new_conn()
- MINOR: quic: Useless statement in quic_crypto_data_cpy()
- BUG/MEDIUM: pools: ensure items are always large enough for the pool_cache_item
- BUG/MINOR: pools: always flush pools about to be destroyed
- CLEANUP: pools: don't needlessly set a call mark during refilling of caches
- DEBUG: pools: add extra sanity checks when picking objects from a local cache
- DEBUG: pools: let's add reverse mapping from cache heads to thread and pool
- DEBUG: pools: replace the link pointer with the caller's address on pool_free()
- BUG/MAJOR: sched: prevent rare concurrent wakeup of multi-threaded tasks
- MINOR: quic: use a global dghlrs for each thread
- BUG/MEDIUM: quic: fix crash on CC if mux not present
- MINOR: qpack: fix typo in trace
- BUG/MINOR: quic: fix FIN stream signaling
- BUG/MINOR: h3: fix the header length for QPACK decoding
- MINOR: h3: remove transfer-encoding header
- MINOR: h3: add documentation on h3_decode_qcs
- MINOR: h3: set properly HTX EOM/BODYLESS on HEADERS parsing
- MINOR: mux-quic: implement rcv_buf
- MINOR: mux-quic: set EOS on rcv_buf
- MINOR: h3: set CS_FL_NOT_FIRST
- MINOR: h3: report frames bigger than rx buffer
- MINOR: h3: extract HEADERS parsing in a dedicated function
- MINOR: h3: implement DATA parsing
- MINOR: quic: Wrong smoothed rtt initialization
- MINOR: quic: Wrong loss delay computation
- MINOR: quic: Code never reached in qc_ssl_sess_init()
- MINOR: quic: ha_quic_set_encryption_secrets without server specific code
- MINOR: quic: Avoid warning about NULL pointer dereferences
- MINOR: quic: Useless test in quic_lstnr_dghdlr()
- MINOR: quic: Non checked returned value for cs_new() in hq_interop_decode_qcs()
- MINOR: h3: Dead code in h3_uqs_init()
- MINOR: quic: Non checked returned value for cs_new() in h3_decode_qcs()
- MINOR: quic: Possible frame parsers array overrun
- MINOR: quic: Do not retransmit too much packets.
- MINOR: quic: Move quic_rxbuf_pool pool out of xprt part
- MINOR: h3: report error on HEADERS/DATA parsing
- BUG/MINOR: jwt: Double free in deinit function
- BUG/MINOR: jwt: Missing pkey free during cleanup
- BUG/MINOR: jwt: Memory leak if same key is used in multiple jwt_verify calls
- BUG/MINOR: httpclient/cli: display junk characters in vsn
- MINOR: h3: remove unused return value on decode_qcs
- BUG/MAJOR: http/htx: prevent unbounded loop in http_manage_server_side_cookies
- BUG/MAJOR: spoe: properly detach all agents when releasing the applet
- REGTESTS: server: close an occasional race on dynamic_server_ssl.vtc
- REGTESTS: peers: leave a bit more time to peers to synchronize
- BUG/MEDIUM: h2/hpack: fix emission of HPACK DTSU after settings change
- BUG/MINOR: mux-h2: update the session's idle delay before creating the stream
- BUG/MINOR: httpclient: reinit flags in httpclient_start()
- BUG/MINOR: mailers: negotiate SMTP, not ESMTP
- MINOR: httpclient: sets an alternative destination
- MINOR: httpclient/lua: add 'dst' optionnal field
- BUG/MINOR: ssl: Add missing return value check in ssl_ocsp_response_print
- BUG/MINOR: ssl: Fix leak in "show ssl ocsp-response" CLI command
- BUG/MINOR: ssl: Missing return value check in ssl_ocsp_response_print
- CLEANUP: httpclient/cli: fix indentation alignment of the help message
- BUG/MINOR: tools: url2sa reads ipv4 too far
- BUG/MEDIUM: httpclient: limit transfers to the maximum available room
- DEBUG: buffer: check in __b_put_blk() whether the buffer room is respected
- MINOR: mux-quic: fix a possible null dereference in qc_timeout_task
- BUG/MEDIUM: htx: Be sure to have a buffer to perform a raw copy of a message
- BUG/MEDIUM: mux-h1: Don't wake h1s if mux is blocked on lack of output buffer
- BUG/MAJOR: mux-h2: Be sure to always report HTX parsing error to the app layer
- DEBUG: stream-int: Check CS_FL_WANT_ROOM is not set with an empty input buffer
- MINOR: quic: do not modify offset node if quic_rx_strm_frm in tree
- MINOR: h3: fix compiler warning variable set but not used
- MINOR: mux-quic: fix uninitialized return on qc_send
- MINOR: quic: fix handling of out-of-order received STREAM frames
- MINOR: pools: mark most static pool configuration variables as read-mostly
- CLEANUP: pools: remove the now unused pool_is_crowded()
- REGTESTS: fix the race conditions in 40be_2srv_odd_health_checks
- BUG/MEDIUM: stream: Abort processing if response buffer allocation fails
- MINOR: httpclient/lua: ability to set a server timeout
- BUG/MINOR: httpclient/lua: missing pop for new timeout parameter
- DOC: httpclient/lua: fix the type of the dst parameter
- CLEANUP: httpclient: initialize the client in stage INIT not REGISTER
- CLEANUP: muxes: do not use a dynamic trash in list_mux_protos()
- CLEANUP: vars: move the per-process variables initialization to vars.c
- CLEANUP: init: remove the ifdef on HAPROXY_MEMMAX
- MINOR: pools: disable redundant poisonning on pool_free()
- MINOR: pools: introduce a new pool_debugging global variable
- MINOR: pools: switch the fail-alloc test to runtime only
- MINOR: pools: switch DEBUG_DONT_SHARE_POOLS to runtime
- MINOR: pools: add a new debugging flag POOL_DBG_COLD_FIRST
- MINOR: pools: add a new debugging flag POOL_DBG_INTEGRITY
- MINOR: pools: make the global pools a runtime option.
- MEDIUM: pools: replace CONFIG_HAP_POOLS with a runtime "NO_CACHE" flag.
- MINOR: pools: store the allocated size for each pool
- MINOR: pools: get rid of POOL_EXTRA
- MINOR: pools: replace DEBUG_POOL_TRACING with runtime POOL_DBG_CALLER
- MINOR: pools: replace DEBUG_MEMORY_POOLS with runtime POOL_DBG_TAG
- MINOR: pools: add a debugging flag for memory poisonning option
- MEDIUM: initcall: move STG_REGISTER earlier
- MEDIUM: init: split the early initialization in its own function
- MINOR: init: extract args parsing to their own function
- MEDIUM: init: handle arguments earlier
- MINOR: pools: delegate parsing of command line option -dM to a new function
- MINOR: pools: support setting debugging options using -dM
- BUILD: makefile: enable both DEBUG_STRICT and DEBUG_MEMORY_POOLS by default
- CI: github: enable pool debugging by default
- DOC: Fix usage/examples of deprecated ACLs
- DOC: internal: update the pools API to mention boot-time settings
- DOC: design: add design thoughts for later simplification of the pools
- DOC: design: commit the temporary design notes on thread groups
- MINOR: stream-int: Handle appctx case first when releasing the endpoint
- MINOR: connection: Be prepared to handle conn-stream with no connection
- MINOR: stream: Handle appctx case first when creating a new stream
- MINOR: connection: Add a function to detach a conn-stream from the connection
- MINOR: stream-int: Add function to reset a SI endpoint
- MINOR: stream-int: Add function to attach a connection to a SI
- MINOR: stream-int: Be able to allocate a CS without connection
- MEDIUM: stream: No longer release backend conn-stream on connection retry
- MEDIUM: stream: Allocate backend CS when the stream is created
- REORG: conn_stream: move conn-stream stuff in dedicated files
- MEDIUM: conn-stream: No longer access connection field directly
- MEDIUM: conn-stream: Be prepared to use an appctx as conn-stream endpoint
- MAJOR: conn_stream/stream-int: move the appctx to the conn-stream
- MEDIUM: applet: Set the conn-stream as appctx owner instead of the stream-int
- MEDIUM: conn_stream: Add a pointer to the app object into the conn-stream
- MINOR: stream: Add pointer to front/back conn-streams into stream struct
- MINOR: stream: Slightly rework stream_new to separate CS/SI initialization
- MINOR: stream-int: Always access the stream-int via the conn-stream
- MINOR: backend: Always access the stream-int via the conn-stream
- MINOR: stream: Always access the stream-int via the conn-stream
- MINOR: http-ana: Always access the stream-int via the conn-stream
- MINOR: cli: Always access the stream-int via the conn-stream
- MINOR: log: Always access the stream-int via the conn-stream
- MINOR: frontend: Always access the stream-int via the conn-stream
- MINOR: proxy: Always access the stream-int via the conn-stream
- MINOR: peers: Always access the stream-int via the conn-stream
- MINOR: debug: Always access the stream-int via the conn-stream
- MINOR: hlua: Always access the stream-int via the conn-stream
- MINOR: cache: Always access the stream-int via the conn-stream
- MINOR: dns: Always access the stream-int via the conn-stream
- MINOR: http-act: Always access the stream-int via the conn-stream
- MINOR: httpclient: Always access the stream-int via the conn-stream
- MINOR: tcp-act: Always access the stream-int via the conn-stream
- MINOR: sink: Always access the stream-int via the conn-stream
- MINOR: conn-stream: Rename cs_detach() to cs_detach_endp()
- CLEANUP: conn-stream: Don't export conn-stream pool
- MAJOR: stream/conn_stream: Move the stream-interface into the conn-stream
- CLEANUP: stream-int: rename si_reset() to si_init()
- MINOR: conn-stream: Release a CS when both app and endp are detached
- MINOR: stream: Don't destroy conn-streams but detach app and endp
- MAJOR: check: Use a persistent conn-stream for health-checks
- CLEANUP: conn-stream: Remove cs_destroy()
- CLEANUP: backend: Don't export connect_server anymore
- BUG/MINOR: h3/hq_interop: Fix CS and stream creation
- BUILD: tree-wide: Avoid warnings about undefined entities retrieved from a CS
- BUG/MINOR: proxy: preset the error message pointer to NULL in parse_new_proxy()
- BUG/MEDIUM: quic: fix received ACK stream calculation
- BUILD: stream: fix build warning with older compilers
- BUG/MINOR: debug: fix get_tainted() to properly read an atomic value
- DEBUG: move the tainted stuff to bug.h for easier inclusion
- DEBUG: cleanup back trace generation
- DEBUG: cleanup BUG_ON() configuration
- DEBUG: mark ABORT_NOW() as unreachable
- DBEUG: add a new WARN_ON() macro
- DEBUG: make the _BUG_ON() macro return the condition
- DEBUG: add a new WARN_ON_ONCE() macro
- DEBUG: report BUG_ON() and WARN_ON() in the tainted flags
- MINOR: quic: adjust buffer handling for STREAM transmission
- MINOR: quic: liberate the TX stream buffer after ACK processing
- MINOR: quic: add a TODO for a memleak frame on ACK consume
Amaury Denoyelle [Thu, 24 Feb 2022 09:50:58 +0000 (10:50 +0100)]
MINOR: quic: add a TODO for a memleak frame on ACK consume
The quic_frame instance containing the quic_stream must be freed when
the corresponding ACK has been received. However when implementing this
on qcs_try_to_consume, some data transfers are interrupted and cannot
complete (DC test from interop test suite).
Amaury Denoyelle [Thu, 24 Feb 2022 09:56:33 +0000 (10:56 +0100)]
MINOR: quic: liberate the TX stream buffer after ACK processing
The sending buffer of each stream is cleared when processing ACKs
corresponding to STREAM emitted frames. If the buffer is empty, free it
and offer it as with other dynamic buffers usage.
This should reduce memory consumption as before an opened stream
confiscate a buffer during its whole lifetime even if there is no more
data to transmit.
Amaury Denoyelle [Wed, 23 Feb 2022 09:54:42 +0000 (10:54 +0100)]
MINOR: quic: adjust buffer handling for STREAM transmission
Simplify the data manipulation of STREAM frames on TX. Only stream data
and len field are used to generate a valid STREAM frames from the
buffer. Do not use the offset field, which required that a single buffer
instance should be shared for every frames on a single stream.
Willy Tarreau [Fri, 25 Feb 2022 07:55:11 +0000 (08:55 +0100)]
DEBUG: add a new WARN_ON_ONCE() macro
This one will maintain a static counter per call place and will only
emit the warning on the first call. It may be used to invite users to
report an unexpected event without spamming them with messages.
Willy Tarreau [Fri, 25 Feb 2022 07:52:39 +0000 (08:52 +0100)]
DBEUG: add a new WARN_ON() macro
This is the same as BUG_ON() except that it never crashes and only emits
a warning and a backtrace, inviting users to report the problem. This will
be usable for non-fatal issues that should not happen and need to be fixed.
This way the BUG_ON() when using DEBUG_STRICT_NOCRASH is effectively an
equivalent of WARN_ON().
Willy Tarreau [Fri, 25 Feb 2022 08:01:36 +0000 (09:01 +0100)]
DEBUG: mark ABORT_NOW() as unreachable
The purpose is to make the program die at this point, so let's help the
compiler optimise the code (especially in sensitive areas) by telling it
that ABORT_NOW() does not return. This reduces the overall code size by
~0.5%.
Willy Tarreau [Fri, 25 Feb 2022 07:45:52 +0000 (08:45 +0100)]
DEBUG: cleanup BUG_ON() configuration
The BUG_ON() macro handling is complicated because it relies on a
conditional CRASH_NOW() macro whose definition depends on DEBUG_STRICT
and DEBUG_STRICT_NOCRASH. Let's rethink the whole thing differently,
and instead make the underlying _BUG_ON() macro take a crash argument
to decide whether to crash or not, as well as a prefix and a suffix for
the message, that will allow to distinguish between variants. Now the
suffix is set to a message explaining we don't crash when needed.
This also allows to get rid of the CRASH_NOW() macro and to define
much simpler new macros.
Willy Tarreau [Fri, 25 Feb 2022 09:10:00 +0000 (10:10 +0100)]
DEBUG: move the tainted stuff to bug.h for easier inclusion
The functions needed to manipulate the "tainted" flags were located in
too high a level to be callable from the lower code layers. Let's move
them to bug.h.
Willy Tarreau [Fri, 25 Feb 2022 08:56:29 +0000 (09:56 +0100)]
BUG/MINOR: debug: fix get_tainted() to properly read an atomic value
get_tainted() was using an atomic store from the atomic value to a
local one instead of using an atomic load. In practice it has no effect
given the relatively rare updates of this field and the fact that it's
read only when dumping "show info" output, but better fix it.
Willy Tarreau [Thu, 24 Feb 2022 18:35:05 +0000 (19:35 +0100)]
BUILD: stream: fix build warning with older compilers
GCC 6 was not very good at value propagation and is often mislead about
risks of null derefs. Since 2.6-dev commit 13a35e575 ("MAJOR: conn_stream/
stream-int: move the appctx to the conn-stream"), it sees a risk of null-
deref in stream_upgrade_from_cs() after checking cs_conn_mux(cs). Let's
disguise the result so that it doesn't complain anymore. The output code
is exactly the same. The same method could be used to shut warnings at
-O1 that affect the same compiler by the way.
Amaury Denoyelle [Thu, 24 Feb 2022 16:39:57 +0000 (17:39 +0100)]
BUG/MEDIUM: quic: fix received ACK stream calculation
Adjust the handling of ACK for STREAM frames. When receiving a ACK, the
corresponding frames from the acknowledged packet are retrieved. If a
frame is of type STREAM, we compare the frame STREAM offset with the
last offset known of the qcs instance.
The comparison was incomplete as it did not treat a acked offset smaller
than the known offset. Previously, the acked frame was incorrectly
buffered in the qcs.tx.acked_frms. On reception of future ACKs, when
trying to process the buffered acks via qcs_try_to_consume, the loop is
interrupted on the smallest offset different from the qcs known offset :
in this case it will be the previous smaller range. This is a real bug
as it prevents all buffered ACKs to be processed, eventually filling the
qcs sending buffer and cause the transfer to stall.
Fix this by properly properly handle smaller acked offset. First check
if the offset length is greater than the qcs offset and mark as
acknowledged the difference on the qcs. If not, the frame is not
buffered and simply ignored.
Willy Tarreau [Thu, 24 Feb 2022 15:37:19 +0000 (16:37 +0100)]
BUG/MINOR: proxy: preset the error message pointer to NULL in parse_new_proxy()
As reported by Coverity in issue #1568, a missing initialization of the
error message pointer in parse_new_proxy() may result in displaying garbage
or crashing in case of memory allocation error when trying to create a new
proxy on startup.
BUILD: tree-wide: Avoid warnings about undefined entities retrieved from a CS
Since recent changes related to the conn-stream/stream-interface
refactoring, GCC reports potential null pointer dereferences when we get the
appctx, the stream or the stream-interface from the conn-strem. Of course,
depending on the time, these entities may be null. But at many places, we
know they are defined and it is safe to get them without any check. Thus, we
use ALREADY_CHECKED() macro to silent these warnings.
Note that the refactoring is unfinished, so it is not a real issue for now.
MAJOR: check: Use a persistent conn-stream for health-checks
In the same way a stream has always valid conn-streams, when a health-checks
is created, a conn-stream is now created and the health-check is attached on
it, as an app. This simplify a bit the connect part when a health-check is
running.
MINOR: conn-stream: Release a CS when both app and endp are detached
cs_detach_app() function is added to detach an app from a conn-stream. And
now, both cs_detach_app() and cs_detach_endp() release the conn-stream when
both the app and the endpoint are detached.
MAJOR: stream/conn_stream: Move the stream-interface into the conn-stream
Thanks to all previous changes, it is now possible to move the
stream-interface into the conn-stream. To do so, some SI functions are
removed and their conn-stream counterparts are added. In addition, the
conn-stream is now responsible to create and release the
stream-interface. While the stream-interfaces were inlined in the stream
structure, there is now a pointer in the conn-stream. stream-interfaces are
now dynamically allocated. Thus a dedicated pool is added. It is a temporary
change because, at the end, the stream-interface structure will most
probably disappear.
MINOR: conn-stream: Rename cs_detach() to cs_detach_endp()
Because cs_detach() is releated to the endpoint only, the function is
renamed. The main purpose of this patch is to be able to add a function to
detach the conn-stream from the application.
MINOR: sink: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the sink part.
MINOR: tcp-act: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the tcp-act part.
MINOR: httpclient: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the httpclient part.
MINOR: http-act: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the http-act part.
MINOR: dns: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the dns part.
MINOR: cache: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the cache part.
MINOR: hlua: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the hlua part.
MINOR: debug: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the debug part.
MINOR: peers: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the peers part.
MINOR: proxy: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the proxy part.
MINOR: frontend: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the frontend part.
MINOR: log: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the log part.
MINOR: cli: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the cli part.
MINOR: http-ana: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream, all
access to the SI is done via the conn-stream. This patch is limited to the
http-ana part.
MINOR: stream: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the stream part.
MINOR: backend: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the backend part.
MINOR: stream-int: Always access the stream-int via the conn-stream
To be able to move the stream-interface from the stream to the conn-stream,
all access to the SI is done via the conn-stream. This patch is limited to
the stream-interface part.
MINOR: stream: Add pointer to front/back conn-streams into stream struct
frontend and backend conn-streams are now directly accesible from the
stream. This way, and with some other changes, it will be possible to remove
the stream-interfaces from the stream structure.
MEDIUM: conn_stream: Add a pointer to the app object into the conn-stream
In the same way the conn-stream has a pointer to the stream endpoint , this
patch adds a pointer to the application entity in the conn-stream
structure. For now, it is a stream or a health-check. It is mandatory to
merge the stream-interface with the conn-stream.
MEDIUM: applet: Set the conn-stream as appctx owner instead of the stream-int
Because appctx is now an endpoint of the conn-stream, there is no reason to
still have the stream-interface as appctx owner. Thus, the conn-stream is
now the appctx owner.
MAJOR: conn_stream/stream-int: move the appctx to the conn-stream
Thanks to previous changes, it is now possible to set an appctx as endpoint
for a conn-stream. This means the appctx is no longer linked to the
stream-interface but to the conn-stream. Thus, a pointer to the conn-stream
is explicitly stored in the stream-interface. The endpoint (connection or
appctx) can be retrieved via the conn-stream.
MEDIUM: conn-stream: No longer access connection field directly
To be able to handle applets as a conn-stream endpoint, we must be prepared
to handle different types of endpoints. First of all, the conn-strream's
connection must no longer be used directly.
MEDIUM: stream: Allocate backend CS when the stream is created
Because the backend conn-stream is no longer released during connection
retry and because it is valid to have conn-stream with no connection, it is
possible to allocated it when the stream is created. This means, from now, a
stream has always valid frontend and backend conn-streams. It is the first
step to merge the SI and the CS.
MEDIUM: stream: No longer release backend conn-stream on connection retry
The backend conn-stream is no longer released on connection retry. This
means the conn-stream is detached from the underlying connection but not
released. Thus, during connection retries, the stream has always an
allocated conn-stream with no connection. All previous changes were made to
make this possible.
Note that .attach() mux callback function was changed to get the conn-stream
as argument. The muxes are no longer responsible to create the conn-stream
when a server connection is attached to a stream.