Hi,

HAProxy 3.3.0 was released on 2025/11/26. It added 26 new commits
after version 3.3-dev14.

The final fixes are pretty minor overall, mainly harmless QUIC fixes,
so there's no reason for further postponing the release.

Here's a sum up of the changes in 3.3:

1. NEW MAJOR FEATURES

- While not urgently needed yet, we've implemented backend support for
  QUIC. There are multiple reasons for this. The first one is to make sure
  we don't hit painful showstoppers the day we absolutely need it, and to
  prepare the internals to welcome this new user. The second one is that
  this will speed up and extend interoperability tests since now it
  becomes possible to chain two layers of haproxy using QUIC and stress
  them beyond what has ever been possible with existing tools. This
  already managed to raise a non negligible number of issues that were
  since fixed. The third reason is that by having the end-to-end stack
  ready, it will be less difficult to catch up with new extensions that
  are regularly coming with the protocol.

  The support is still marked experimental, and QUIC addresses may only be
  used on servers when "expose-experimental-directives" is set. While the
  code does work pretty well right now, there has still been too little
  feedback (and that's normal) to make us totally confident in the fact
  that the config will not change at all or that any particular deployment
  issue or resource management trick will not require to change a few
  defaults. With that said, tests and reports are welcome!

  The current implementation supports SNI, session resumption, NEW_TOKEN,
  0-RTT and connection reuse. Currently connections cannot be shared yet
  between threads, so "tune.idle-pool.shared" will have no effect.

- Persistent stats across reloads: stats counters have been classified in
  two categories: volatile (marked as "V" in "show stats typed") or
  persistent ("P") to help distinguish process-specific from service-wide
  metrics. Using "shm-stats-file", persistent counters can now be
  preserved across reloads and restarts and continue to be fed in parallel
  by both older and the new process, enabling continuous, uninterrupted
  metrics for dashboards and alerting systems. Up to 64 processes update
  the same file at once, which should be more than sufficient. This is
  still marked as experimental essentially due to minimal production
  feedback, but we estimate that it will satisfy a long awaited need for
  contiguous stats. It may also enable a new form of stats retrieval
  directly from the shared memory file instead of bothering the worker
  process, but this possibility has not yet been further explored.

- ACME enhancements: ACME now supports automatic certificate generation
  when no cert is available, finally allowing to start without having to
  create a dummy expired cert. Also the scheduler has been reworked to use
  a scalable tree instead of a list, in anticipation for setups involving
  high numbers of certificates. DNS-01 challenges are now supported via
  the dataplane API which can communicate over the CLI via the dpapi event
  ring. A new "haproxy-dump-certs" script allows to periodically save
  newly renewed certificates.

- The "ssl-passphrase-cmd" directive allows running a command to retrieve
  passphrases for protected certificates, simplifying the secure
  deployment of passphrase-protected certificates.

- KTLS: Kernel TLS as implemented in Linux kernel version >=4.17 is now
  supported by default for the "linux-glibc" target, including with
  splicing. This means that it is possible to transfer data from server to
  client (or conversely) in real zero-copy mode again, even with TLS. This
  works better with hardware offloading NICs since in this case the data
  transits in clear inside the machine and is decrypted/encrypted in the
  NICs, but even if the crypto is done by the kernel, at least a bunch of
  memory copies can be saved, and this matters at high speed andor large
  numbers of connections. KTLS can be enabled per "bind" and "server" line
  using "ktls on".

- TLS ECH (Encrypted Client Hello): this encrypts the whole Client Hello
  record, mainly focusing on the SNI part so that it is no longer possible
  for someone sniffing the traffic to know what site a user is visiting
  when using TLS. This feature is particularly demanded from people
  connecting from places considered unsafe, as well as in order to bypass
  SNI-based access filtering policies. Now their browser will be able to
  retrieve the server's public key in the DNS and use it to encrypt the
  Client Hello so that only the server can decrypt it, thereby preserving
  their privacy.


2. PERFORMANCE IMPROVEMENTS

- The default CPU policy is now set to "performance" by default, allowing
  HAProxy to utilize all available CPUs, even on NUMA systems. This means
  that on large systems with more that 64 CPUs, all of them will now be
  enabled by default, and thread groups will automatically be created for
  CPU sets which are not close enough to communicate quickly together
  (distinct nodes or L3 caches in distinct CCX). Users dealing a lot with
  SSL, regex, Lua or other expensive processing will benefit from the
  increased processing capacity or from the ease of configuration since
  it's no longer needed to configure cpu-maps to enable extra
  CPUs. Additionally, thread-group creation at L3 cache boundaries results
  in significant performance increases on some non-uniform cache
  architectures.

- Per-thread group counters: counters for frontends, backends, and servers
  are now per-thread group, to reduce the overhead of atomic operations on
  large systems in high-throughput deployments. On some very large systems
  during benchmarks, it was indeed witnessed that the numerous stats we
  keep up to date could sometimes account for up to almost half of the CPU
  usage!

- stick-table locking was revisited and pushed to the limit of what can be
  done without a full re-architecture. Under high load and lots of peers
  traffic, the sustained performance is now significantly increased, and
  it's much rarer to see the watchdog issue a warning.

- the default load balancing algorithm, when not set, changed from
  "roundrobin" to the much lighter "random(2)". Not only it significantly
  reduces CPU usage on large systems, but it also improves the load
  distribution in contexts were servers are not all equally sized, or when
  there are multiple front load balancers.

- general reduction of memory usage: proxies and servers now have smaller
  structures, so large configurations will consume less memory. In
  addition, cross-references between servers (e.g. "track") are now looked
  up using a binary tree instead of a list, yielding faster startups on
  such large configs.

- more CPU-friendly alignment of structures that are often on the critical
  path, resulting in less false sharing between CPUs and the ability for
  compilers to make more optimal use of vector instructions when available.


3. RELIABILITY IMPROVEMENTS

- QUIC: some rework had to be done in areas where client connection failures
  were starting to be observed. One of them is a much more robust handling
  of crypto frames reordering, especially with recent versions of Firefox
  and ngtcp2, which can reorder frames with minimal spacing, and the other
  one is a better detection of colliding connection IDs. Both of these
  have finally been backported to 3.2 as they address stability issues.

- resolvers: DNS resolution now uses sendto() instead of connect(),
  avoiding a longstanding problem where DNS could permanently fail after a
  temporary network outage until the next restart. The "dns-accept-family"
  is now set to "auto" by default, based on the detection of IPv6
  reachability. The resolvers tasks are now single-threaded to avoid some
  issues where they would occasionally trigger the watchdog in the past.
  Note that some of these changes have already been backported to latest
  3.2 versions as they contribute to stabilizing the service.


4. CONFIGURATION

- several previously deprecated configuration options have now been
  removed. These include "dispatch", "option transparent", and the
  "program" section. Naming collisions between frontends and backends, and
  between servers are no longer accepted.

- empty variables in config files are now handled correctly and will no
  longer truncate the configuration line. Unresolved variables are
  explicitly reported with suggestions for closest matches. This means
  that the cases where "${FOO}" appended at the end of a line has been
  working by accident in 3.2 when FOO is not declared will now report an
  error. The syntax "${FOO[*]}" that has been supported since 2.3 can of
  course still be used to drop empty fields anywhere on the line
  (e.g. when passing config keywords from environment variables).

- The "http-send-name-header" directive now prohibits setting headers like
  "connection", "content-length", "host", or "transfer-encoding",
  preventing protocol violations and making sure we don't hamper our
  future ability to increase protection against new forms of smuggling
  attacks for example.

- strict-sni and default-crt conflict warning: Using "strict-sni" and
  "default-crt" together now emits a warning, as this combination is
  logically inconsistent and likely stems from misconfiguration.

- starting haproxy as root without an explicit "user" directive now
  triggers a warning, encouraging users to adopt secure practices and
  avoiding incorrect beliefs that can have nasty consequences.

- when statically built, using "user" or "group" directives now emits a
  warning, as resolution may fail or cause runtime crashes due to missing
  libc dependencies.

- "option abortonclose" is now set by default in HTTP backends so as to
  better match most common use cases. It is still possible to disable it
  using "no option abortonclose".

- new configuration predicates like "awslc_api_atleast()" and
  "ssllib_name_startswith()" allow fine-grained control over TLS stack
  selection based on API version or library name. Right now this is
  essentially used by regression tests, but could also be used during
  migrations from one lib to another if some parameters need to be
  adjusted.


5. OBSERVABILITY / MANAGEMENT / DEBUGGING

- improved SSL traces: SSL traces now include detailed information such as
  ciphers, curves, and signature algorithms, aiding in troubleshooting.

- new sample fetch functions now give access to more precise byte counters
  with "{req,res}.bytes_{in,out}" to distinguish between input and output
  bytes, which is important when dealing with compression or caching.

- faster and more consistent CLI behavior: the protocol used on the CLI
  requires that each command emits an empty line to mark the end of its
  output. However we've noticed that sending them one at a time for
  pipelined commands saturates some clients such as socat and are slowing
  down large map uploads. Those line feeds are now sent in larger batches
  at once and updates are now faster.

- the "daemon" keyword in the global section will trigger a warning when
  combined with -Ws on the command line, which requests to start in
  master-worker mode for systemd, as it will cause trouble since this
  latter wants it to run in foreground.

- the "master-worker" keyword alone in the global section will now trigger
  a warning, suggesting to only set the master mode from the CLI with -W,
  so as to stay consistent with the init system's expectations.

- when multiple "-m" (match method) arguments are set on the same ACL
  definition, a warning will be emitted. This also counts for the misuse
  of certain pre-set keywords (e.g. "path_beg" which means "path -m beg")
  when combined with another "-m".

- the old deprecated legacy mailers mechanism is now gone. Those who need
  mailers have to use the examples/lua/mailers.lua file instead, which is
  much more customizable. In order to make sure users don't overlook this,
  a "mailers" section loaded without the Lua-based mailers implementation
  triggers a warning.

- the "jwt_verify()" converter now has a "jwt_verify_cert()" twin that
  instead of a private key takes a certificate, allowing JWT certs to be
  managed via the CLI ("add/del/show") like any regular certificate.

- the default maximum number of old worker processes upon reloads is now
  set to 50. This means that a worker process that is still present after
  50 reloads will quit anyway. Previously it was almost infinite,
  sometimes causing problems to those seeing an accumulation of older
  processes during fast reloads. This can still be changed by
  "mworker-max-reloads".


6. OTHER:

- new converters were added:
  - "le2dec()" for decoding little-endian inputs to decimal,
  - "base2" for converting raw data or IPs to binary form,

- optional AAD support was brought to "aes_gcm_dec()" and "aes_gcm_enc()"

- new command-line options ("-vq", "-vqb", "-vqs") allow users to show
  only the version in various formats, making it easier to script or
  automate version checks.

- the "make install" target no longer installs admin tools like "halog",
  which are now installed via "make install-admin" to prevent mismatches
  in build options.

- the default minimum Linux kernel version for the linux-glibc target has
  been updated to 4.17 to support kTLS by default, aligning with currently
  maintained LTS distributions. Older systems can continue using
  "linux-glibc-legacy" or disabling specific features.

- TCP MD5 signatures are now supported on listeners and servers, and are
  essentially used with BGP.

- the TCP congestion control algorithm can be set on Linux on "bind" and
  "server" lines.

- the HTTP client will add a Content-Length header when the payload is
  known. This is more friendly to some servers which do not support
  chunked encoded requests.


I'm pretty sure I'm missing certain points, but that's basically what I
found by reviewing all previous announce messages. As usual, there will
soon be a much more detailed blog post on the HAProxyTech site here:

   https://www.haproxy.com/blog/announcing-haproxy-3-3

BTW we've had a total of 1155 commits from 26 people, which is slightly
more than for 3.2 and 3.1.

I noticed that we got less feedback from testers this time than with 3.2,
it is possible that users invest more time testing future LTS than future
stable releases. Maybe there are less heavy users of non-LTS releases, in
which case it's understandable (I don't remember for 3.1). If some users
are used to skipping non-LTS, I'm very interested in knowing their opinion
on this (maybe we can tweak the release cycle a little bit if that helps,
or produce less development releases). In any case, thanks a lot to those
who tested and reported issues and suggestions!

And once again I particularly want to thank those who operate the tools
behind the curtains, such as Discourse, the mailing list & servers, the
CI, issues, and of course distro maintainers.

As every 6 months, 3.4-dev0 was already created and will become the next
LTS version in 6 months. And like with every release, please be gentle
with distro maintainers, it takes time to integrate a new major release,
please do not complain to them if you don't see it in the next few days.

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
   Q&A from devs    : https://github.com/orgs/haproxy/discussions
   Sources          : https://www.haproxy.org/download/3.3/src/
   Git repository   : https://git.haproxy.org/git/haproxy-3.3.git/
   Git Web browsing : https://git.haproxy.org/?p=haproxy-3.3.git
   Changelog        : https://www.haproxy.org/download/3.3/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 (13):
      BUG/MEDIUM: server: do not use default SNI if manually set
      BUG/MEDIUM: quic: do not prevent sending if no BE token
      BUG/MINOR: quic/server: free quic_retry_token on srv drop
      MINOR: quic: split global CID tree between FE and BE sides
      MINOR: quic: use separate global quic_conns FE/BE lists
      MINOR: quic: add "clo" filter on show quic
      MINOR: quic: dump backend connections on show quic
      MINOR: quic: mark backend conns on show quic
      BUG/MINOR: quic: fix uninit list on show quic handler
      BUG/MINOR: quic: release BE quic_conn on connect failure
      BUG/MINOR: server: fix srv_drop() crash on partially init srv
      BUG/MINOR: h3: do no crash on forwarding multiple chained response
      BUG/MINOR: h3: handle properly buf alloc failure on response forwarding

Christopher Faulet (2):
      BUG/MEDIUM: server/ssl: Unset the SNI for new server connections if none 
is set
      Revert "BUG/MEDIUM: server/ssl: Unset the SNI for new server connections 
if none is set"

Jacques Heunis (1):
      BUG/MINOR: freq_ctr: Prevent possible signed overflow in 
freq_ctr_overshoot_period

Maxime Henrion (1):
      BUG/MINOR: acme: fix ha_alert() call

Olivier Houchard (2):
      DOC: ssl: Document the restrictions on 0RTT.
      DOC: ssl: Note that 0rtt works fork QUIC with QuicTLS too.

William Lallemand (3):
      BUG/MINOR: acme: better challenge_ready processing
      BUG/MINOR: acme: warning ‘ctx’ may be used uninitialized
      MINOR: httpclient: complete the https log

Willy Tarreau (4):
      BUG/MINOR: sock-inet: ignore conntrack for transparent sockets on Linux
      DEV: patchbot: prepare for new version 3.4-dev
      DOC: update INSTALL with the range of gcc compilers and openssl versions
      MINOR: version: mention that 3.3 is stable now

---


Reply via email to