Hi, HAProxy 3.0.5 was released on 2024/09/19. It added 68 new commits after version 3.0.4.
As announced by Willy after the 3.0.4, a bunch of backports were missing. All of those are included in this release with another set of fixes as usual. So following bugs were fixed: * A temporary leak of sessions was fixed in the H1 multiplexer when the zero-copy data forwarding was inuse. When the H1 connection was about to be closed, the event was not properly handled in case of zero-copy data forwarding, leaving the connection in CLOSING state till the timeout was reached. This could be detected by an excess of connections in CLOSE_WAIT state. * HTTP applets (stats, cache and promex) were starting to process the request and reply without worrying about whether the request analysis was finished or not. In the vast majority of cases, it is not an issue because the request analysis is indeed finished in the same time the applet on server side is created. But if a filter delayed the request analysis, it might happens. In that case, some undefined and hardly prédictible behaviors were able to be experienced, like responses sent too early or even crashes. Among others, the compression filter was pretty sensitive in this case because it is mandatory to filter the request before the response. To fix the issue, there is now a check in backend HTTP applets to wait for the end of the request analysis. * Several commits concerned the clock part to fix handling of time jumps. In case of large time jump, it was possible to no longer update the global time offset, leading to a wrong "date" value. Among other things, this could lead to wrong internal rates computation. By fixing the clock issues, a bug in the busy polling was revealed. The time and status passed to clock_update_local_date() was incorrect. * Some unhandled aborts were fixed in the H2 multiplexer. The end of message could be reported twice for tunneled streams, leaving the second one blocked at the channel level because of the first one. In additions, termination flags were not always properly propagated from the H2 stream to the stream-endpoint descriptor. Because of these both bugs, it was possible from time to time to block streams infinitely. * The zero-copy data forwarding in H1 was erroneously disabled when a tunnel was established because the response message was flagged to have no data. While such response has no HTTP payload, tunneled data are expected. * Write error on client side when HAproxy was waiting for the server response was not properly handled. The stream was not properly aborted as usual. It was not an issue if no filter was used. But with a filter, it was possible to infinitely block the stream because data could remain blocked in the response channel buffer. * Same kind of issue was fixed but at the H1/pass-though multiplexer level. The pipe used for the kernel splicing was not properly released on write error, preventing the stream to be released when a filter was used because the corresponding channel always appeared as non-empty. On write error, the pipe can be safely released because no more data can be sent. * The pipeline modes on the master CLI was broken since the 3.0-dev4. On older versions, this still works but a warning is emitted. When the pipeline modes was fixed to match the documentation (having a semi-colon between commands and a new-line at the end) for the worker CLI, we forgot to reflect the change to the master CLI. It is now fixed. * The fix concerning the session queuing in the 3.0.4 introduced a regression, leading to a infinite loop in assign_server_and_queue() because of a race condition between dequeuing and queuing mechanisms. The bug was mainly due to the fact that a trylock was used to dequeue a session when a server slot was released. A trylock was used to be sure no thread was waiting to dequeue sessions if another one was still doing it, because it is an expensive task. However, the trylock could also fail when a session is queued. So, to fix the bug, a flag is now used instead of a trylock. * Because of optimisations performed on the stick-tables during the 3.0 development cycle, when entries for a local table were learned from a unique remote peer upon resynchro, local updates on such entries were not advertised to the peer anymore, until they eventually expired and were able to be recreated upon local updates. Still on peers, A wakeup loop was fixed when a peer applet was waiting for a synchro with the global synchronisation task. In that case, the applet must explicitly state it won't consume data otherwise it is woken up again and again. * Several bugs were fixed on QUIC: - A 0-RTT session may be opened with a spoofed IP address, trusted by HAProxy because of a previously established connection, by-passing this way IP allow/block list. The problem was reported by Michael Wedl. To mitigate this vulnerability, the NEW_TOKEN frame support was added so as to always be able to validate reachability of the client during 0-RTT. It allows to deliver an IP-based token to the client for use later, and if the address changes, then we can use a regular RETRY token. - It was possible to freeze a connection because of 0-RTT undeciphered content. Another freeze was possible because of early QUIC stream closure, before transmitting any data. - The MAX_STREAM ID value was not properly checked and it was possible to send too big value. It is now fixed. Thanks to this patch, this also ensure that the peer cannot open a stream with an invalid ID as this would cause a flow-control violation instead. - Retransmit for empty STREAM frames with FIN flag set was not properly handled. On retransmission, this frame was discarded and could cause the transfer to freeze with the client waiting indefinitely for the FIN notification. - Too short datagram during packet building failures could lead to a crash. It was reported by Ilya when HAProxy was built against AWS-LC. - Some issues with the QUIC traces were fixed. * On H3, when a response is formatted to be sent to the client, the handling of responses with a too long header list was fixed to no longer abort the process but to return proper error. * Some bugs related to pattern expressions handling loaded from file were fixed. * A wakeup on applets could be missed after a successful synchronous send, when all data were sent at once, blocking the applet till a timeout was reached. This issue only concerns newly refactored applets (stats, cache, cli). * Some updates for server's address and port could be missed because of a bug in the task responsible to handle these updates. This could happen with too many updates, when the task was interrupted. The next event to be processed when the interrupt occurred was lost. In addition, it was not released, leading to a memory leak. * 0-RTT support with AWS-LC was erroneously deactivated. It was reactivated. In addition, still for AWS-LC, 0-RTT initialization was performed at the wrong place. * When a listen() failed for TCP and Unix sockets, the file descriptor was not removed from the fdtab[] array, leading to a possible crash because of a BUG_ON() when this FD was reused. The FD is now properly removed from fdtab[] in that case. In addition to these bug fixes, two improvments were added: * QUIC crypto with EVP_AEAD was implemented: The QUIC crypto is using the EVP_CIPHER API in order to achieve authenticated encryption, this was the API which was used with OpenSSL. With libraries that inspires from BoringSSL (libreSSL and AWS-LC), the AEAD algorithms are implemented using the EVP_AEAD API. The call to the EVP_CIPHER API when called in the contex of AEAD cryptography for QUIC are now converted. This was mainly done for AWS-LC but this could be useful for other libraries. This should finally allow to use CHACHA20_POLY1305 with AWS-LC. * Some invalid Transfer-Encoding values are now accepted during the H1 response parsing when accept-invalid-http-response option is enabled, even if it is forbidden by the RFC-9112. So, now, with this option, multiple "chunked" values are accepted, as well as empty values. When several "chunked" values are found, the payload will still be considered as encoded once and the header will be sanitized when sent to the client. The request parsing was not changed. This remains forbidden because it is highly suspicious if a client is sending an invalid T-E header. On server side, we can consider the server as trusted. But you must still remain careful with such behavior. And, of course, the best is to fix the application. Thanks everyone for your help !x Note that other releases, up to 2.6, should be emitted soon. Feel free to upgrade to test this one and as usual, report bugs if you observe any strange behavior. 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/3.0/src/ Git repository : https://git.haproxy.org/git/haproxy-3.0.git/ Git Web browsing : https://git.haproxy.org/?p=haproxy-3.0.git Changelog : https://www.haproxy.org/download/3.0/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 --- Complete changelog : Amaury Denoyelle (7): BUG/MEDIUM: quic: prevent conn freeze on 0RTT undeciphered content BUG/MINOR: mux-quic: do not send too big MAX_STREAMS ID BUG/MINOR: h3: properly reject too long header responses MINOR: quic: convert qc_stream_desc release field to flags MINOR: quic: implement function to check if STREAM is fully acked BUG/MEDIUM: quic: handle retransmit for standalone FIN STREAM BUG/MINOR: quic: prevent freeze after early QCS closure Aurelien DARRAGON (5): BUG/MEDIUM: server/addr: fix tune.events.max-events-at-once event miss and leak BUG/MINOR: pattern: prevent const sample from being tampered in pat_match_beg() BUG/MEDIUM: pattern: prevent UAF on reused pattern expr BUG/MINOR: peers: local entries updates may not be advertised after resync BUG/MINOR: cfgparse-listen: fix option httpslog override warning message Christopher Faulet (14): BUG/MEDIUM: stconn: Report error on SC on send if a previous SE error was set BUG/MEDIUM: mux-pt/mux-h1: Release the pipe on connection error on sending path BUILD: mux-pt: Use the right name for the sedesc variable BUG/MEDIUM: http-ana: Report error on write error waiting for the response BUG/MEDIUM: h2: Only report early HTX EOM for tunneled streams BUG/MEDIUM: mux-h2: Propagate term flags to SE on error in h2s_wake_one_stream BUG/MEDIUM: peer: Notify the applet won't consume data when it waits for sync BUG/MAJOR: mux-h1: Wake SC to perform 0-copy forwarding in CLOSING state BUG/MINOR: h1-htx: Don't flag response as bodyless when a tunnel is established MEDIUM: h1: Accept invalid T-E values with accept-invalid-http-response option DOC: config: Explicitly list relaxing rules for accept-invalid-http-* options BUG/MEDIUM: sc_strm/applet: Wake applet after a successfull synchronous send BUG/MEDIUM: cache/stats: Wait to have the request before sending the response BUG/MEDIUM: promex: Wait to have the request before sending the response Frederic Lecaille (11): BUILD: quic: 32bits build broken by wrong integer conversions for printf() MINOR: tools: Implement ipaddrcpy(). MINOR: quic: Implement quic_tls_derive_token_secret(). MINOR: quic: Token for future connections implementation. BUG/MINOR: quic: Missing incrementation in NEW_TOKEN frame builder MINOR: quic: Modify NEW_TOKEN frame structure (qf_new_token struct) MINOR: quic: Implement qc_ssl_eary_data_accepted(). MINOR: quic: Add trace for QUIC_EV_CONN_IO_CB event. BUG/MEDIUM: quic: always validate sender address on 0-RTT BUG/MINOR: quic: Crash from trace dumping SSL eary data status (AWS-LC) BUG/MINOR: quic: Too short datagram during packet building failures (aws-lc only) Ilia Shipitsin (1): BUG/MINOR: fcgi-app: handle a possible strdup() failure Nathan Wehrman (1): DOC: config: correct the table for option tcplog Valentine Krasnobaeva (6): BUG/MINOR: proto_tcp: delete fd from fdtab if listen() fails BUG/MINOR: proto_tcp: keep error msg if listen() fails BUG/MINOR: proto_uxst: delete fd from fdtab if listen() fails BUG/MINOR: pattern: pat_ref_set: fix UAF reported by coverity BUG/MINOR: pattern: pat_ref_set: return 0 if err was found BUG/MINOR: cfgparse-global: remove tune.fast-forward from common_kw_list William Lallemand (6): BUG/MEDIUM: ssl: reactivate 0-RTT for AWS-LC BUG/MEDIUM: ssl: 0-RTT initialized at the wrong place for AWS-LC MINOR: channel: implement ci_insert() function BUG/MEDIUM: mworker/cli: fix pipelined modes on master CLI REGTESTS: mcli: test the pipelined commands on master CLI MEDIUM: ssl/quic: implement quic crypto with EVP_AEAD Willy Tarreau (17): BUG/MINOR: stconn: bs.id and fs.id had their dependencies incorrect DOC: configuration: fix alphabetical ordering of {bs,fs}.aborted BUG/MINOR: trace/quic: enable conn/session pointer recovery from quic_conn BUG/MINOR: trace/quic: permit to lock on frontend/connect/session etc BUG/MEDIUM: trace: fix null deref in lockon mechanism since TRACE_ENABLED() BUG/MINOR: trace: automatically start in waiting mode with "start <evt>" BUG/MINOR: trace/quic: make "qconn" selectable as a lockon criterion BUG/MINOR: quic/trace: make quic_conn_enc_level_init() emit NEW not CLOSE BUG/MEDIUM: clock: also update the date offset on time jumps DOC: configuration: place the HAPROXY_HTTP_LOG_FMT example on the correct line REGTESTS: fix random failures with wrong_ip_port_logging.vtc under load BUG/MEDIUM: clock: detect and cover jumps during execution BUG/MINOR: pattern: do not leave a leading comma on "set" error messages BUG/MINOR: polling: fix time reporting when using busy polling BUG/MINOR: clock: make time jump corrections a bit more accurate BUG/MINOR: clock: validate that now_offset still applies to the current date BUG/MEDIUM: queue: implement a flag to check for the dequeuing -- Christopher Faulet