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
---