Hi, HAProxy 3.1.0 was released on 2024/11/26. It added 41 new commits after version 3.1-dev14.
That's a final version as I like them, with two long-standing bugs fixed, a few cross-platform build issues addressed as well, and the rest being doc updates, CLI help messages and tiny code tidying patches. As with every release, you'll hear me say that this is the best ever release with tons of fixes and improvements, blah blah blah. So this time I took the time to review all of the 1119 commits since 3.0.0 to summarize everything below, and judge by yourself: First, due to the significant amount of time spent dealing with increasingly complex bug reports from recent versions during this development cycle, a large part of the time left for development was dedicated to improving the troubleshooting and observability in order to reduce the number of round trips between developers and users when chasing a problem, as well as to limit the guess work on the developers' side. The principle essentially consists in focusing on certain specific events in logs, traces, and even core dumps while minimizing the user impact of enabling the collection of these precious information. In this specific area, we can mention: - Log production and processing: - new last_entity and waiting_entity to indicate in the logs what internal entity was being processed, or blocked waiting for more data (filters, compression, Lua, request body, file:line of a rule etc). These allow to better understand what was happening when a timeout or error struck. - fc.debug_str / bc.debug_str: reports lots of internal information from the front and back connections (stream ID, connection flags, etc). These are mostly used by developers and can take a lot of room on the log line. See converter "when" below. - converter "when": allows to pass the contents of its input to the output only when a defined condition is met. The condition might be "error", "stopping", "acl:<acl_name>" and a few others, in order to define what's of interest to extend the log output. Combined with "fc/bc.debug_str", it allows to only emit detailed info when something abnormal happens (e.g. unusually long response). - glitch counters: now the HTTP/2 and QUIC multiplexers are able to count small anomalies that are not necessarily fatal for a connection but may be used to force a connection to be closed above a certain threshold. These can be retrieved at log time so that logs indicate a level of suspiciousness of the request. - connection-level error happening during data transfers are now reported upstream so that they can appear numerically in "fc_err" and "bc_err", or as full strings in "fc_err_str" and "bc_err_str", or as short strings (mostly errno-like) in the new "fc_err_name" and "bc_err_name". For example ERESET will indicate that recv() or send() faced an ECONNRESET status code by the operating system. This can be useful when the logs conflict with network capture, to detect that something else is acting in the OS itself (e.g. internal firewall rules, resource limits in the TCP stack, or bug at the kernel level). - CLI: - the "show info" command will now report the current and total number of streams, hence requests. It can help quickly detect if a slowdown is caused on the client side or the server side, as well as ease the production of activity metrics. - a new option "show-uri" of the command "show sess" to show the URI of a request in progress. This can help figure if a certain URL is mostly responsible for slow responses for example. - the number of calls to filters and other internal entities attached to a stream is now reported on "show sess". This is particularly convenient when using Lua filters or SPOE extensions, to figure if and where something odd is happening. - the "show dev" output will indicate many process-specific info such as permissions, capabilities, resource limits etc at both boot and runtime. These can sometimes explain some suspiciously low limits (e.g. users running in containers sometimes see their settings ignored for various reasons, now they'll be able to control after starting the process). - "show quic" now produces way more internal information about the internal state of the congestion control algorithm, and other dynamic metrics (window size, bytes in flight, counters etc). - Traces: - a new "traces" section permits to configure traces and to enable them at startup time if desired. The old "trace" keyword in the global section which was under experimental status is no longer accepted, and the traces do not require the experimental status anymore. The "trace" keyword now supports grouping operations between multiple sources, and to perform multiple operations in a single command, both on the CLI and in the "traces" section. - a new "follow" mechanism allows some traces to be preconfigured but dormant until another source is activated, in which case the other traces configured on other sources of the same session will automatically be enabled as well. This means that an HTTP/3 request received on the frontend and caught by the H3 trace can automatically trigger the production of HTTP/1 or HTTP/2 traces for the same request going to the backend, allowing to figure what changed or what event on any side had an effect on the other side. This also means that "session" also becomes a valid trace source. - the H2 traces were poor in terms of correlation with external indicators (logs, network captures) as certain important events were missing (flags, stream IDs etc). They've been significantly extended to report such precious information which now allow to better understand the likely cause of certain events. - likewise, the H1 and H3/QUIC traces now expose much more internal information that are also needed in certain cases. - the H2 and H3 traces now produce a trace on stream creation, which used not to be the case, making it difficult to figure when exactly a stream started. - code/traffic debugging: a new COUNT_IF() macro allows to place event counters anywhere in the code. Those are also automatically added to track glitches. The "debug counters" command then allows to list all known counters with their exact location in the code, and a likely cause when a meaning is known. This allows to detect and count some unexpected conditions, as well as figure what is causing trouble (typically by looking at glitch counters even when no request was instantiated and no log produced). - watchdog improvements: the watchdog timer used to trigger after a thread stopped making progress for one second followed by up to one extra second probation period. One of the problems is that certain poorly efficient configurations (e.g. long map_reg() files) can trigger it without a prior warning, so users facing this can only rely on counting when the watchdog triggers, which is not convenient to optimize their configuration. In 3.1, the watchdog watches much more often, every 100ms, and it will emit a warning every time it triggers, listing only the stuck thread with some hints about a possible cause, and will only stop the process if the offending thread makes no progress for one full second after the first warning. This allows to detect pathological configurations long before they can cause an outage, and also allows to better observe what was happening since it takes 10 warnings to end the process. The number of warnings emitted is also reported as "BlockedTrafficWarnings" in the "show info" output. - core dump exploitation: when the watchdog fires, as well as when a bug is detected, the system will normally dump a core file. Sometimes these are difficult to process (and they can even be truncated or the symbols can be missing on the binary to exploit them fully). A new internal structure "post_mortem" that can always be found contains pointers to many of the important internal structures that allow to navigate through the process' memory, therefore significantly reducing the analysis time, and saving the users from having to adjust their settings to try to fix the output. In addition, the output messages containing the thread dumps are now also present in the the core files for each and every thread, allowing to recover the cause of a problem even when the output was missing. - memory profiling: the accuracy of the memory profiler was significantly improved by better tracking the association between allocations and releases, and by intercepting more calls, including non-portable ones (strndup(), memalign() etc). In addition, a summary is now provided per external dependency, permitting at a quick glance to detect if a given library is leaking, and where. - short timeouts: some issues are sometimes reported about breakage under high load, which are caused by extremely short timeouts. The default unit for timeouts is the millisecond, but admittedly it's very easy to think differently when reading "timeout 30" which is totally valid and easily makes one believe it's seconds. As such, warnings will now be emitted for most timeouts and intervals below 100ms and not having any unit. The warning will suggest how to write the directive to avoid the warning (typically by appending "ms" if the intent was really this). Great efforts were also made on improving stability and reliability in general, as an effort to reduce the number of problem reports in the first place: - the master-worker model was heavily reworked for improved stability. Previously, the master process would parse the configuration, then fork a worker process from it, re-exec itself to release all the memory while trying hard not to lose the communication with existing workers, and properly close all relevant file descriptors but not too many. Needless to say, this model had to take care of numerous special cases, and was periodically broken by subtle changes in listeners, file descriptor management, environment variables, rings affecting startup-logs, and it was quite difficult to maintain forward compatibility between major versions to support seamless upgrades. The new model is completely different, the master process does nothing except start the worker and wait for it to declare itself ready or to fail. The worker, in turn, parses the configuration and starts its listeners. As such the master doesn't need to re-execute itself anymore, which closes a number of race conditions (such as the worker dying during the master's re-execution). However, the master still needs to parse some pieces of the configuration to discover the presence of the "master" keyword, the "localpeer" one, or to deal with "setenv" variables that may condition further parts of the configuration. This means that the configuration file needs to be buffered first so that both process read exactly the same. And if the configuration is read from stdin, it will be limited to a very unlikely size for such behavior (10 MB). A visible change will be that environment variables observed on the master and the worker will be much more consistent, since only those which have an impact on the process will be shared, and the worker will no longer know certain master-specific variables. Overall this new model is much more robust and more extensible. During the rework it was figured how brittle the "program" section was, and the only cause for no problem reports about it is mainly that users quickly abandon it as too limited for their use cases or found not to be trustable enough. As a result, this section is now deprecated in 3.1 and will be removed in 3.3. - some configurations were quite unreliable due to the ongoing support for duplicate server names within a same proxy, for colliding names between a frontend and a backend, as well as conflicts between peers or log-forward and proxies. Stick-tables couldn't appear in two such similarly named sections, and special code was dedicate to checking for this, consuming time during config parsing. Logs were ambiguous when showing the same name in the frontend and backend, not making it possible to figure if the request ended in the frontend or reached the backend. Also certain issues with the state-file and the stats-file were solely caused by the difficulty to sort out these possibilities of supporting duplicate names. All these old excentricities are now deprecated and will emit a warning, and will be definitely rejected in 3.3. - the SPOE engine was completely rewritten to benefit from the new facilities offered over the last 8 years. Previously a second stream was created to handle long-lived connections and deal with their load balancing at the connection level. This means that a connection established on a thread was dedicated to this thread and couldn't even be reused differently to better balance the traffic among servers, reason why it was often desirable to close the connections periodically. Also the model was a bit heavy in processing cost due to the need to make two streams communicate, and the difficulty to deal with server-side errors. And on modern CPUs with many cores, it was particularly difficult to tune since each thread needed to have a few connections, which together were sometimes too much for the server. The new model is completely different, it implements a new mux that is much lower in the stack, can have its idle connections shared between threads, and which will apply load-balancing at the request level. The first benefit is a significantly improved reliability by relying on proven mechanisms. The second is that heavily threaded machines will no longer overwhelm the servers (nor risk to deplete source ports). In addition, the per-request load balancing algorithm allows to rely on per-request elements to choose the server (e.g. hash of a URI in the parent request). And finally fixes in the future will be limited to purely SPOE parts and will no longer concern parts that already exist in a totally different form somewhere else. I.e. any fix to idle connections, LB algorithms, queuing, resource management in general will instantly benefit to SPOE. - with some new operating systems, the file descriptor hard limit was raised from the common 1 million to 1 billion. Given that haproxy automatically allocates the structures needed to deal with the current number of file descriptors, this used to take ages to boot, most often to even fail on out of memory. One option was to force a maxconn value in the configuration, but a new problem happens, which is that configs are no longer portable nor adaptable to the machine's resource (common in VMs where users just want to change the sizing of the VM). Now a new fd-hard-limit parameter was added to fix too high a hard limit without changing the configured value. This allows to cap the number of FDs and to continue to rely on other parameters (e.g. RAM size) to fix a decent limit. The new default hard limit is set to 1 million, like modern operating systems used to rely on for more than a decade without problems. - some users faced issues with time jumping after boot. Sadly, the timekeeping code had been made able to detect and correct such forward and backward time jumps for a very long time, but it appears that certain jumps at very precise places couldn't always be caught with enough precision, resulting in sometimes visible time variations during heavy abuse of the system's time. Since the vast majority of modern operating systems support a precise monotonic time that HAProxy already uses for profiling, it was decided to now use it by default as the main clock source whenever detected as working. - QUIC will now always send a NEW_TOKEN frame to new clients, for reuse in a subsequent connection. This is useful to permit to the client to reconnect after having already been validated, without having to be subject to the address validation mechanism again on the next connection. One of the benefits is that the new connection will more robustly establish when the listener is under attack, or over a lossy network. - the "ring" sections support servers (e.g. to send traces remotely or to access a TCP syslog server). But during a disconnection initiated by haproxy (e.g. after a max-reuse limit was reached), the connection used to be abruptly closed in order to avoid accumulating TIME_WAIT states that risk to deplete the source ports. But this doesn't really make sense for rings, and one bad effect of this is that it results in contents truncation of the data in flight. This is particularly annoying with logs where any close results in lost logs. Now these ring connections to servers will be gracefully closed, only once all the data are ACKed by the server so that outgoing data are no longer truncated. Fortunately there were performance improvements as well in multiple areas: - QUIC: - pacing is now implemented in experimental status. Pacing consists in limiting the risk of losing packets in network buffers all along the path by smoothing their distribution over time: instead of sending a large burst of packets and doing nothing while waiting for acknowledgements, they're now better distributed over the time needed to send them. A test on a client on an FTTH access downloading a large file showed a download time reduction by a factor of 16x, due to losses being mostly eliminated and allowing the window to grow much higher. It is still experimental and not enabled by default because the code is quite new and we don't want to possibly expose users to last-minute issues, but the goal is to achieve production-grade quality for 3.2 and obviously backport the fixes (if any) to 3.1, so feedback is welcome on this. - the BBR congestion control algorithm ("Bottleneck Bandwidth and Round-trip propagation time") was also implemented in experimental status (it requires pacing and as such is also experimental. The main principle of this algorithm is to accept that spurious losses do happen are not always caused by congestion. So instead it uses the data sent to measure the effective link bandwidth and round-trip time and tries to use it at its maximum capacity regardless of occasional random losses. It will provide much better experience than the default Cubic algorithm over lossy networks. - the transmission path was significantly revamped, so that it's no longer needed to set a maximum tx buffer size (it will now adapt to the current send window size), and makes use of GSO ("Generic Send Offload") to let the kernel send multiple packets in a single system call. In practice, modern network cards are able to do that, so it means much less processing from HAProxy and the kernel needs to be done, and is instead offloaded by the hardware. This is an even higher benefit in virtual machines where system calls can be particularly expensive. - TCP logs: - receive path: the line-by-line parser applied to input buffers, initially only used by the CLI, is now also used by the TCP log forwarder and happens to be a bottleneck due to its original focus of small and simple code. It was refreshed with performance in mind, resulting in a 56% performance gain on TCP log forwarding. - send path: before connecting to a server declared in a ring section, the ring sending code will first check the threads' load and will assign the outgoing connection to the least loaded thread. This is particularly important for log servers, where it was common to see all the servers of the same ring pinned to the first thread by default, and even servers from different rings all bound to the same thread, causing a significant bottleneck. In addition to this, the rings now feature a new directive "max-reuse" allowing to close the connection and reconnect after sending a certain amount of messages, thus helping to maintain a fair load level between all threads. - H2: the mux was optimised to wake up less often for no reason, and this resulted in up to around 30% less instructions in average to download the same objcets, resulting in CPU savings. In addition, it now allows to share the whole connection buffers fairly between the receiving streams, which significantly speeds up uploads (24x measured with default settings, more by changing the default rx buffer size), and finally fixes the long-lasting problem of head-of-line blocking that was affecting downloads from H2 servers. - pattern cache: it was reported by a few high-performance users that the pattern LRU cache was consuming a lot of CPU when dealing with low cache hit ratios, for example during an attack. At the same time, the cache is often not needed, e.g. when there are very few patterns to evaluate. In this version, some hints are used and the cache will simply not be involved for expressions or maps having few different patterns (their count varies with their type, hence average evaluation cost). - Config checking: large configs using many servers per backend could take quite a bunch of time to process, just due to duplicate server name detection, which was initially very basic. Now that servers are properly indexed and that the detection can leverage this, the startup time for such large configs could be reduced by a factor of 4. - Vars: for similar reasons, variable names used to just be stored in a list at a time when there were very few. Now that they're much more commonly used, this is starting to cost a lot. Moving them to a tree resulted in a 67% global performance gain for a configuration involving 100 such variables. - Expressions: by simply avoiding trivial casts between samples and converters of the same type, an average 7% pearformance gain was observed. This concerns most arithmetic and string operators which are commonly chained at multiple levels. - Lua: core.set_map() had its speed doubled by avoiding performing a lookup prior to a change that itself performs the same lookup. - The QUIC/H3 buffer handling was reworked so that small frames now use small buffers. This improves both the memory usage (no longer needed to pin a 16kB buffer when 1kB is sufficient), and CPU usage (e.g. when it is needed to realign the buffer). - On setups involving large number of file descriptors and many threads, some tables have to be updated on startup for each thread. At boot time, the number of file descriptors is very low (only listeners), but all of them were individually initialized. By simply keeping track of the highest one used during boot, it was possible to shorten the initialization time from 1.6s to 10ms for 2M configured FDs. This means much smoother reloads on large setups. - Test coverage: there are now about 216 regression test scripts totaling a bit more than 5100 tests, that are executed for virtually each commit on 25 platform combinations (OS, architecture, compiler, SSL library, build options). And finally many new features aiming at easing integration and offering more flexibility were added: - Init: support for Linux Capabilities version 3 was added. This extends the API to expose more (hence finer) capabilities in the future, and also avoids a kernel warning during startup on certain systems. - Logs: - in order to add more flexibility about what and when to log, the new concept of "log-steps" now permits to define when log events must be generated (e.g. connect, request, close etc). This means that a single connection with a single request may produce multiple logs along its progress. This is particularly convenient for log connections or long transfers, so that logs will indicate when they started and later when they stop. This makes "option logasap" much less relevant. - a new section "log-profile" allows to associate groups of log servers with log formats and log steps. This means that it is for example possible to define that for a given log step, a specific log format must be used, and that when sent to a given server it must follow a special encoding, or mask certain fields (e.g. log raw addresses for local short-lived debugging logs but mask them for archives). - automatic encoding: logs can now be emitted in a structured way, using JSON or CBOR, with each field named after its original name or via an explicit alias described in the log-format line (using "%(...)", see sections 8.2.6 and 8.3.5). This naming will later also permit to perform some operations, matching, or on-the-fly transformations. - a new "do-log" action was added so as to permit to emit any log in any format at any instant. This can be convenient to emit debug logs for example. - Network-level stuff: - a new "quic-initial" rule set applies to QUIC initial packets and allows to perform the usual datagram-level filtering before creating a connection (accept/dgram-drop/reject) as well as sending a retry (send-retry), e.g. to validate the sender's address. - the support for the MPTCP protocol (Multi-Path TCP) that was started years ago when internal architecture was not ready to accept it was finally merged. It allows TCP connections to follow multiple paths in parallel for increased performance and resilency. - abstract namespace sockets ("abns") exist in two flavors depending on products. The man page mentions that a 0 byte doesn't necessarily mark the end of the string and is part of the address, making it suitable for fully random addresses for example. This is what HAProxy and a few other tools implement. For simplicity reasons, other projects instead use a valid text string, stopping at the first zero byte, making it more suitable for user-fed configuration. Version 3.1 introduces a variant ("abnsz") that completes the first one by implementing the second approach, in order to ease interaction with such other projects. - HTTP: - the new "date" converter converts an input string containing an HTTP date into a UNIX timestamp suitable for age or expiration calculation. - the new option "h1-do-not-close-on-insecure-transfer-encoding" makes a backend accept to violate the standard by keeping a connection alive after a bogus and possibly dangerous responses from a server that contains both Transfer-Encoding and Content-Length. Such messages are dangerous because if they cross an HTTP/1.0 proxy while the content-length does not reflect the real length, they may provoke a desynchronization between that proxy and the rest (haproxy and server) and expose them to request smuggling attacks and cache injection. Closing the connection after that fixes the problem. But some very old applications still continue to do that and are not necessarily easy to fix, and sometimes suffer from the connection closure, hence this optoin. - the "accept-invalid-http-request" and "accept-invalid-http-response" directives have been marked as deprecated and were now renamed to "accept-unsafe-violations-in-http-request" / "...-response", in order to clarify what they're dealing with and later allow to define new ones for some specific cases. In addition, the new response oriented directive now also makes proxies tolerate invalid transfer codings in responses (e.g. double "chunked"), which some bogus applications also seldom use. - the HTTP/1 multiplexer can now return 414 (uri too long) or 431 (request too large) when it cannot decode a request. This eases debugging of the cause on client applications. - "option httpchk" used to be severely abused over the last decade, due to most application servers requiring HTTP/1.1 with a "Host" header field, that used to be injected into the health check as a bare string appended to the version field. Now there is an explicit 4th argument on this directive to avoid this hack and make it easier to write valid health checks. - "option tcplog clf" was added, to produce TCP logs in a CLF-like format that allows to unify the log consumption from TCP and HTTP proxies. In addition, new environment variables were added to define the default TCP/HTTP CLF log formats. - A series of converters were added to transform IP addresses, strings or integers from/to RFC7239 elements. This is used to parse and/or produce a custom RFC7239 header field ("Forwarded"), which is used to pass the client's IP address to a next hop. One usage can simply be to hide (or replace) part of the client's address before passing it to an untrusted server. - The "query" sample-fetch function now has a new option "with_qm" to return the question mark with the string when it's present. This eases construction of redirects, which no longer require two rules. - the "redirect" action now supports a "keep-query" option to ask for the query-string to be preserved, and a "set-cookie-fmt" option that defines the format of a set-cookie header to be passed along with a redirect. This can avoid writing Lua code or writing more complex "return" actions. - the "retry-on" backend directive now also supports the 429 status ("too many requests") allowing to try again on another server. - SSL/TLS: - ECDSA+RSA certificates and the CHACHA20_POLY1305 symmetric algorithm are now supported with the AWS-LC library - signature algoritms ("sigalgs") are now supported with the AWS-LC library. - The signature algorithms and supported versions can now be extracted from the Client Hello message using "ssl_fc_sigalgs_bin" and "ssl_fc_supported_versions_bin" respectively, in order to help refine its fingerprinting, e.g. to sort out good from bad traffic during an attack. - The new "ssl_c_san" sample fetch function reports the list of Subject Alt Names of a client certificate. - other simplifications / improvements: - most size fields now support a unit. E.g. a ring size indicating "10G" will now be understood as 10737418240 bytes, and no longer silently misunderstand as "10 bytes". - the "bwlim" filter now supports a size multiplicator, for those who need to match more than 4GB per period. This has an impact on the data stored in the stick-table, which is scaled down by that factor before being stored and/or exchanged. - new commands on the CLI: "echo" to echo a line (mostly provide a delimitor between successive commands during a dump), "show env" is now supported on the master process to ease debugging, "dump ssl cert" dumps a certificate in PEM format, "show proc debug" on the master shares more internal info about the process' state. - rings now support forward declaration, i.e. a ring name may now be referenced by a "trace", "log" or debug() action before it is declared in the configuration; the resolution happens after the configuration is fully parsed. - the SystemD API is now always enabled (even on non-Linux systems). As it doesn't come with any external dependencies (it just needs to write a short string on a file descriptor), this simplifies the code and allows to run the regression tests fully on all operating systems. - the Prometheus exporter now exports the global node and description as well as proxies' description as metrics. - glitches: the new glitches mechanism described above these can be tracked in a stick-table so that it becomes easy to preserve the scoring across reloads and even share it across a whole cluster, to help admins keep away those triggering them too often (generally indicating an attack). - the server "init-state" directive allows to set the desired initial state of a server after leaving maintenance mode or upon startup. For a long time, the default used to be "up until first failure", but now it supports the full 4 ("full-up", "up", "down", "fully-down"). This is particularly important to some users once combined to DNS service discovery (and different users have strongly different expectations there). - the SPOE engine can now use any backend configured with "mode spop", it's no longer strictly necessary to have a separate configuration file. - variable names support references to the parent stream by prepending a "p" to their scope ("psess", "ptxn", "preq", "pres"). The purpose is to permit a sub-stream (Lua, SPOE) to take into consideration a variable present in the stream that originated it. For example SPOE will make it easier to set some fields from the parent's, or even to make load-balancing algorithm depend on them. - the old "legacy" mailers are now deprecated. A message suggests to switch to the much more flexible and configurable Lua implementation that supports sending to multiple addresses, to customize the contents etc. The "mailers" section remains there since it's what configures the service. - the agent-check can now learn an absolute weight, not just a relative one. Be aware that some features are deprecated in this version and are planned for removal in 3.3 (they were mentioned above but better repeat them more prominently here). Their use will produce a warning at boot, which can be ignored or silenced using "expose-deprecated-directives" in the global section: - old native mailers - duplicate server/proxy names - "program" section Please consider regularly checking the wiki page for deprecated features, and keep in mind that features are normally not deprecated in future LTS versions (even number after the dot), only in the regular stable ones (odd number after the dot): https://github.com/haproxy/wiki/wiki/Breaking-changes I noticed that this time my coworkers at haproxytech beat me at publishing the blog article summarizing changes and use cases, congrats to them! The article is already online here for those who want more information: https://www.haproxy.com/blog/announcing-haproxy-3-1 As usual, huge thanks to contributors, to the numerous bug reporters, to those who dedicate a part of their time (and sometimes their SLA) to run many or all development versions and catch most of the bugs before they hit a stable version, to those who spend their time triaging the issues and responding to questions here on the list, often saving precious time that allows developers to stabilize the code meeting deadlines, and those who operate the various tools (CI, ML, packages, images, doc, issues etc). I know that most of you underestimate the importance of your efforts but they're critical to saving the time left assigned to implementing new ideas, and when you figure that bug fixes represent nearly 25% of this release, you start to understand how important this participation is for the resulting quality. Keep up the good work, and let's start to make 3.2 even better (3.2-dev0 is already running on haproxy.org)! 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.1/src/ Git repository : https://git.haproxy.org/git/haproxy-3.1.git/ Git Web browsing : https://git.haproxy.org/?p=haproxy-3.1.git Changelog : https://www.haproxy.org/download/3.1/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 [Quick note for Tim: I think I got the changes right on the site this time, but as usual, feel free to prove me wrong ;-) I still have to update the quick news and to summarize the changelog there, though.] Have fun! Willy --- Complete changelog since 3.1-dev14: Amaury Denoyelle (5): BUG/MINOR: mux-quic: fix show quic report of QCS prepared bytes BUG/MEDIUM: quic: fix sending performance due to qc_prep_pkts() return MINOR: mux-quic: use sched call time for pacing MINOR: cfgparse-quic: strengthen quic-cc-algo parsing BUG/MEDIUM: quic: prevent EMSGSIZE with GSO for larger bufsize Christopher Faulet (4): BUG/MAJOR: mux-h1: Properly handle wrapping on obuf when dumping the first-line DEV: lags/show-sess-to-flags: Properly handle fd state on server side BUG/MEDIUM: http-ana: Don't release too early the L7 buffer MINOR: version: mention that 3.1 is stable now Frederic Lecaille (4): BUG/MINOR: quic: Avoid BUG_ON() on ->on_pkt_lost() BBR callback call BUG/MAJOR: quic: fix wrong packet building due to already acked frames MINOR: quic: make bbr consider the max window size setting DOC: quic: Amend the pacing information about BBR. Olivier Houchard (2): MINOR: cli: Add a "help" keyword to show sess MINOR: cli/quic: Add a "help" keyword to show quic Valentine Krasnobaeva (10): MINOR: proto_sockpair: send_fd_uxst: init iobuf, cmsghdr, cmsgbuf to zeros MINOR: startup: rename on_new_child_failure to mworker_on_new_child_failure REORG: startup: move on_new_child_failure in mworker.c MINOR: startup: prefix prepare_master and run_master with mworker_* REORG: startup: move mworker_prepare_master in mworker.c MINOR: startup: keep updating verbosity modes only in haproxy.c REORG: startup: move mworker_run_master and mworker_loop in mworker.c REORG: startup: move mworker_reexec and mworker_reload in mworker.c MINOR: startup: prefix apply_master_worker_mode with mworker_* REORG: startup: move mworker_apply_master_worker_mode in mworker.c William Lallemand (9): CI: update to the latest AWS-LC version CI: update to the latest WolfSSL version Revert "CI: update to the latest WolfSSL version" CI: github: add a WolfSSL job which tries the latest version CI: github: improve the Wolfssl job CI: github: improve the AWS-LC job CI: github: allow to run the Illumos job manually BUILD: tcp_sample: var_fc_counter defined but not used CI: github: add 'workflow_dispatch' on remaining build jobs Willy Tarreau (7): BUILD: activity/memprofile: fix a build warning in the posix_memalign handler DOC: ot: mention planned deprecation of the OT filter BUILD: systemd: fix usage of reserved name "sun" in the address field BUILD: init: use the more portable FD_CLOEXEC for /dev/null DOC: config: refine a little bit the text on QUIC pacing DOC: management: mention "show sess help" and "show quic help" DOC: install: update the list of supported versions ---