Hi, HAProxy 2.9-dev8 was released on 2023/10/20. It added 99 new commits after version 2.9-dev7.
Some crash issues were fixed, and the long-sought task leak affecting QUIC was fixed as well. Some of the last important parts were finally merged. These include: - mux-to-mux zero-copy forwarding (work started around 2.4). In short, the principle is to avoid buffering whenever we can avoid it, so as to save memory and preserve data in CPU caches as much as possible. The receiving side (typically the backend mux) will request the sending side (frontend mux) to borrow its buffer and receive the data directly into it, respecting flow control and available space. This means that if the output is clogged, we don't add to the buffer bloat. On a test involving h2 clients and h1 servers, we saw 18% more bandwidth and 8% CPU saving at the same time (the 100G link reached saturation) while saving ~10% of the RAM thanks to filling less buffers. For now only tcp, H1 and H2 are supported, QUIC will follow and I doubt fcgi would benefit from this at all. - log backends: this starts to address the 4yr old issue #401 about log server management. The first step here consists in supporting a new mode "log" for backends and to permit to log to such a backend from a "log" statement. In the backend, there are servers, in dgram or connected mode (udp/unix/tcp etc), and various LB algorithms (round-robin, hash, sticky, random). Since it's a backend, regular health check methods are supported. There's still a lot of work to be done there (we still do not identify named fields for hashing or masking, nor permit them to be represented differently, nor can we produce multiple logs at various steps). But at least it opens the way to this long rework. I know that some server keywords are still a bit too permissive and that there's ongoing work to better control them, but that looks functional enough. Please note that the logging performance remains basically unaffected, and that TCP continues to rely on a ring with its infamous lock that doesn't scale well with threads, but for moderate uses this will be fine anyway. And the rest is less sensitive but nonetheless interesting: - some cleanups were done for wolfssl and awslc, enabling some of the features that were previously ifdefed out, and refining some regtests. - some config updates to the reverse-http mechanism were brought: the protocol name to use is now consistently "rhttp@" instead of "rev@" or "@reverse". The number of connections a listener must set up is now defined by a new keyword "nbconn" on the bind line instead of abusing the closely related but confusing "maxconn". Most "bind" keywords that do not apply to reverse-http are now rejected there, just like the mix of both address types (rhttp and regular ones). As such if you already tried it, your config will fail but will be easy to adjust. - the h2 mux didn't update the counter of request errors when facing unparsable requests, in part because that started as an H2->H1 converter and also because for some time, any error would result in an instant breakage of the connection. But over time we've refined the lower-layer controls, offering more reasons to reject a request, so it was logical to update the tracked counters in this case, like h1 does. This means that if you've fine-tuned some http_req_rate thresholds, they may become slightly more sensitive, but also more accurate. - the json_query() sample fetch function can now also extract arrays - the "set-timeout" rule is now supported in "http-response" rulesets (very convenient to adapt to an expected response time advertised by the server via a header, e.g. for slow requests). - some traces and debugging improvements, and regtest cleanups Tristan reported a recent regression in quic-to-h1 transfers that brought back a transfer slowdown, and could bisect it so we'll have to have a look at this soon. We've also got a non-reproducible but quite analyzable report of one of the rare "spinning stream" bugs, so we might finally be able to understand what happens in this rare case. I could instrument the ssl_capture leak I'm observing on haproxy.org and figure that it's the SSL stack that doesn't release it! I have no idea why for now but placing counters there definitely shows that there are less objects released than calls to SSL_free() and friends, we'll need to compare to older versions. I also noticed a huge number of buffer pools allocated in the shared cache that do not seem to be release: > show pools (...) - Pool buffer (32768 bytes) : 28259 allocated (925990912 bytes), 27 used (~18 by thread caches), needed_avg 21, 0 failures, 1 users, @0x51182c0 [SHARED] - Pool ssl-capture (296 bytes) : 225525 allocated (66755400 bytes), 221862 used (~3 by thread caches), needed_avg 221736, 0 failures, 1 users, @0x1d2c200 [SHARED] It looks like at one point we needed to allocate a lot (since the needed_avg count went down very low) but I don't know why they're not flushed, I'll have to look at this. I already faced once a strange behaviour where launching violent injections and interrupting them would increase the memory usage, and could bisect it to my changes to shard the pools in 2.9-dev4, but and couldn't reproduce it since. It might be in this situation where the global cache is enabled, so now I have an idea what to look for. Anyway, we're approximately 1 month away from the release so there should not be important changes anymore, mostly cleanups, doc updates and bug fixes. Given the nature of the issues we're facing, I think we'll be on schedule. I would really like it if someone had a look at a better way to present the actions in the doc to put an end to the horrible copy-paste job that's done for each of them in tcp-request, http-request, response... Ideally we'd fix that before the release, but first we need to know how to present them. I doubt a matrix would work, but maybe starting from the actions and indicating what rule sets they are compatible with would be an improvement. Please find the usual URLs below : Site index : https://www.haproxy.org/ Documentation : https://docs.haproxy.org/ Wiki : https://github.com/haproxy/wiki/wiki Discourse : https://discourse.haproxy.org/ Slack channel : https://slack.haproxy.org/ Issue tracker : https://github.com/haproxy/haproxy/issues Sources : https://www.haproxy.org/download/2.9/src/ Git repository : https://git.haproxy.org/git/haproxy.git/ Git Web browsing : https://git.haproxy.org/?p=haproxy.git Changelog : https://www.haproxy.org/download/2.9/src/CHANGELOG Dataplane API : https://github.com/haproxytech/dataplaneapi/releases/latest Pending bugs : https://www.haproxy.org/l/pending-bugs Reviewed bugs : https://www.haproxy.org/l/reviewed-bugs Code reports : https://www.haproxy.org/l/code-reports Latest builds : https://www.haproxy.org/l/dev-packages Willy --- Complete changelog : Amaury Denoyelle (15): REORG: quic: cleanup traces definition BUG/MINOR: quic: reject packet with no frame BUG/MEDIUM: mux-quic: fix RESET_STREAM on send-only stream BUG/MINOR: mux-quic: support initial 0 max-stream-data BUG/MINOR: h3: strengthen host/authority header parsing BUG/MINOR: quic: fix qc.cids access on quic-conn fail alloc BUG/MINOR: quic: fix free on quic-conn fail alloc BUG/MINOR: mux-quic: fix free on qcs-new fail alloc BUG/MEDIUM: quic-conn: free unsent frames on retransmit to prevent crash MINOR: cfgparse: forbid mixing reverse and standard listeners MINOR: listener: add nbconn kw for reverse connect MINOR: server: convert @reverse to rev@ standard format MINOR: cfgparse: rename "rev@" prefix to "rhttp@" REGTESTS: remove maxconn from rhttp bind line MINOR: listener: forbid most keywords for reverse HTTP bind Aurelien DARRAGON (18): MEDIUM: tree-wide: logsrv struct becomes logger MEDIUM: log: introduce log target DOC: config: log <address> becomes log <target> in "log" related doc MEDIUM: sink/log: stop relying on AF_UNSPEC for rings MINOR: log: support explicit log target as argument in __do_send_log() MINOR: log: remove the logger dependency in do_send_log() MEDIUM: log/sink: simplify log header handling MEDIUM: sink: inherit from caller fmt in ring_write() when rings didn't set one MINOR: sink: add sink_new_from_srv() function MAJOR: log: introduce log backends MINOR: log/balance: support for the "sticky" lb algorithm MINOR: log/balance: support for the "random" lb algorithm MINOR: lbprm: support for the "none" hash-type function MINOR: lbprm: compute the hash avalanche in gen_hash() MINOR: sample: add sample_process_cnv() function MEDIUM: log/balance: support for the "hash" lb algorithm REGTEST: add a test for log-backend used as a log target MINOR: server: introduce "log-bufsize" kw Christopher Faulet (35): BUG/MEDIUM: stconn: Report a send activity everytime data were sent BUG/MEDIUM: applet: Report a send activity everytime data were sent BUG/MINOR: mux-h1: Send a 400-bad-request on shutdown before the first request CLEANUP: hlua: Remove dead-code on error path in hlua_socket_new() BUG/MEDIUM: mux-h1: do not forget TLR/EOT even when no data is sent BUG/MINOR: htpp-ana/stats: Specify that HTX redirect messages have a C-L header BUG/MEDIUM: mux-h2: Don't report an error on shutr if a shutw is pending MEDIUM: stconn/channel: Move pipes used for the splicing in the SE descriptors MINOR: stconn: Start to introduce mux-to-mux fast-forwarding notion MINOR: stconn: Extend iobuf to handle a buffer in addition to a pipe MINOR: connection: Add new mux callbacks to perform data fast-forwarding MINOR: stconn: Temporarily remove kernel splicing support MINOR: mux-pt: Temporarily remove splicing support MINOR: mux-h1: Temporarily remove splicing support MINOR: connection: Remove mux callbacks about splicing MEDIUM: stconn: Add mux-to-mux fast-forward support MINOR: mux-h1: Use HTX extra field only for responses with known length MEDIUM: mux-h1: Properly handle state transitions of chunked outgoing messages MEDIUM: raw-sock: Specifiy amount of data to send via snd_pipe callback MINOR: mux-h1: Add function to add size of a chunk to an outgoind message MEDIUM: mux-h1: Simplify zero-copy on sending path MEDIUM: mux-h1: Simplify payload formatting based on HTX blocks on sending path MEDIUM: mux-h1: Add fast-forwarding support MINOR: h2: Set the BODYLESS_RESP flag on the HTX start-line if necessary MEDIUM: mux-h2: Add consumer-side fast-forwarding support MEDIUM: channel: don't look at iobuf to report an empty channel MINOR: tree-wide: Only rely on co_data() to check channel emptyness REGTESTS: Reenable HTTP tests about splicing CLEAN: mux-h1: Remove useless __maybe_unused attribute on h1_make_chunk() MEDIUM: mux-pt: Add fast-forwarding support MINOR: global: Add an option to disable the zero-copy forwarding BUILD: mux-h1: Fix build without kernel splicing support REORG: stconn/muxes: Rename init step in fast-forwarding BUG/MEDIUM: peers: Be sure to always refresh recconnect timer in sync task BUG/MEDIUM: peers: Fix synchro for huge number of tables Frédéric Lécaille (1): BUG/MINOR: quic: Avoid crashing with unsupported cryptographic algos Jens Popp (1): MINOR: sample: Added support for Arrays in sample_conv_json_query in sample.c Vladimir Vdovin (1): MINOR: support for http-response set-timeout William Lallemand (16): MINOR: ssl: add an explicit error when 'ciphersuites' are not supported BUILD: ssl: enable 'ciphersuites' for WolfSSL BUILD: ssl: add 'ssl_c_r_dn' fetch for WolfSSL BUILD: ssl: add 'secure_memcmp' converter for WolfSSL and awslc BUILD: ssl: enable keylog for awslc CLEANUP: ssl: remove compat functions for openssl < 1.0.0 BUILD: ssl: enable keylog for WolfSSL REGTESTS: pki: add a pki for SSL tests REGTESTS: ssl: update common.pem with the new pki REGTESTS: ssl: disable ssl_dh.vtc for WolfSSL REGTESTS: wolfssl: temporarly disable some failing reg-tests CI: ssl: add wolfssl to build-ssl.sh CI: ssl: add git id support for wolfssl download CI: github: add a wolfssl entry to the CI CI: github: update wolfssl to git revision d83f2fa CI: github: add awslc 1.16.0 to the push CI Willy Tarreau (12): CLEANUP: connection: drop an uneeded leftover cast BUG/MAJOR: connection: make sure to always remove a connection from the tree BUG/MINOR: mux-h2: make up other blocked streams upon removal from list DEBUG: pool: store the memprof bin on alloc() and update it on free() BUG/MEDIUM: quic_conn: let the scheduler kill the task when needed MINOR: dgram: allow to set rcv/sndbuf for dgram sockets as well BUG/MINOR: mux-h2: fix http-request and http-keep-alive timeouts again BUG/MINOR: trace: fix trace parser error reporting MINOR: mux-h2/traces: explicitly show the error/refused stream states MINOR: mux-h2/traces: clarify the "rejected H2 request" event BUG/MINOR: mux-h2: commit the current stream ID even on reject BUG/MINOR: mux-h2: update tracked counters with req cnt/req err ---