Hi,

HAProxy 3.5-dev4 was released on 2026/08/06. It added 157 new commits
after version 3.5-dev3.

This looks like a large -dev but it's not that much, it's just that it
contains around 54 fixes for issues that were covered in recent stable
releases so I won't rehash them here.

Here are the main changes in this version:

- we now experimentally support a split file descriptor table that allows
  each thread group to have its own file descriptors. It can significantly
  lower the load on very large systems dealing with high connection rates,
  because the system must lock the file descriptor table for each socket
  creation and deletion. With this new mechanism, the lock is per-group
  and the overhead much lower. During some quick tests on a 80-core ARM
  and a 64-core EPYC, we found that the connection rate could almost be
  doubled depending on the number of thread groups and threads per group
  (4-8 threads per group generally showing the highest benefit). The
  feature is enabled via the global "tune.fd.tables" parameter, which takes
  "shared" (the default) or "per-thread-group" (the new experimental mode).
  Those dealing with many health checks or with frequent connection-based
  DDoSes might be particularly interested in giving it a try. It's very
  likely that some rare corner cases of FDs that need to have a process-wide
  visibility were overlooked, but we have not found any for now. Maybe some
  TLS engines (deprecated) or stuff like this maybe could stop working well.
  Note that this will have some visible impacts in debugging outputs, such
  as "show fd" or "show sess" which now systematically report the thread
  group in front of the FD (since the same FD number can exist in different
  groups).

- ECH support with AWS-LC: Encrypted Client Hello is now supported with
  AWS-LC, however the ECH PEM files cannot be updated at runtime via the
  CLI commands (show/add/set/del ssl ech) due to some API limitations.
  William would like to receive some feedback from testers on this point.

- servers: the "default-server" directive now supports a "name" argument
  permitting to define multiple server profiles at the same time. In
  parallel, "server" lines support a new "from" directive after which one
  can indicate "be:<name>" or "srv:<name>" to inherit from the default-server
  section of the specified backend, or a specific server or default-server.
  The CLI's "add server" directive also supports this "from", which now
  permits to create servers explicitly inheriting a default-server section
  or even to duplicate an existing server's settings. All parameters used
  by "from" are used as presets, exactly as is currently done with the
  default-server mechanism, except that now it is possible to indicate
  where the defaults come from. This will greatly simplify dynamic server
  management for those who want to rely on parameters set in default-server.

- backends now support "be-unpublished" which is comparable to "disabled"
  except that the backend starts present and populated, just in unpublished
  state (i.e. not visible from use_backend rules).

- counters: "clear counters server <server>" allows to reset a server's
  counters.

- SSL: a new global setting "tune.ssl.keyupdate-rate-limit" allows to set
  a limit to the number of per-connection key updates per second, and the
  default is 100 per second (should never even need to go that far). The
  only reason to change it should be to lower it to better deal with some
  attacks.

- halog: a new "-hdr-match" argument permits to filter on log lines whose
  positional captures match the specified values.

- haload: request rate limiting is now there, with -R like on h1load. A
  new option also allows to show status code counts per HTTP version.

- proxies and servers: some internal lists were turned to a doubly-linked
  list in order to speed up addition and removal (adding a proxy or a
  server was fast until a few thousands, but at 10-20k backends you started
  to feel that it was slowing down). Now addition and removal are roughly
  done in O(1) time. A pair of new CLI commands "show defaults" and
  "show default-server" was added to visualize available default sections.
  There must be no visible impact (beyond faster operations), so if you now
  face issues such as unlisted servers or proxies, please report them.

- patterns: parsing of IPv6 addresses in ACLs and maps used to be done
  after DNS resolution attempts. This could take a huge amount of time to
  boot for configs with many IPv6 addresses, because one DNS request was
  issued for each line.

- logs: while the date placed in the log header is cached in its latest
  form as long as the date doesn't change, it was not the same for other
  date fields (e.g. accept date). And the conversion to localtime or gmtime
  could involve a mutex in libc that was serializing all accesses and not
  even showing a big CPU usage, beyond some kernel-side locking that is
  normally triggered by FDs being touched by many threads. A new cache was
  implemented for these time conversion functions so that the mutex is no
  longer on the fast path.

- The oldest supported OpenSSL version is now 1.1.1, and the support for
  1.0.2 is no longer tested in the CI.

The rest is mostly cleanups all over the code and doc updates.

There are definitely significant changes in this version, so please test
it, particularly if you're using many connections, if you're using ECH,
or if you're using dynamic servers and/or backends.

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.5/src/
   Git repository   : https://git.haproxy.org/git/haproxy.git/
   Git Web browsing : https://git.haproxy.org/?p=haproxy.git
   Changelog        : https://www.haproxy.org/download/3.5/src/CHANGELOG
   Dataplane API    : 
https://github.com/haproxytech/dataplaneapi/releases/latest
   OpenTelemetry    : https://github.com/haproxytech/haproxy-opentelemetry
   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 :
Alexander Stephan (5):
      BUG/MEDIUM: counters: preserve shared.tg pointer on 'clear counters all'
      MINOR: counters: add max-only reset helpers and use them for clear 
counters
      MINOR: server: add 'clear counters server <backend>/<server>' CLI command
      REGTESTS: stats: add test for 'clear counters server'
      DOC: management: document 'clear counters server'

Amaury Denoyelle (50):
      CLEANUP: mux_quic: remove unused prototype
      BUG/MEDIUM: proxy: protect "show errors" against backend deletion
      MINOR: proxy: stress "show errors" handler
      MINOR: log: use curproxy during config parsing
      MINOR: config: define wrapper for proxies loop during check config
      MINOR: log: convert list to standard doubly linked one
      MINOR: sink: convert list to standard doubly linked one
      MINOR: proxy: centralize proxies_list insert during config parsing
      MINOR: proxy: define proxies_list iteration functions
      MAJOR: proxy: convert proxies_list to a doubly linked struct list
      OPTIM/MEDIUM: proxy: avoid main proxies list reordering on startup
      CLEANUP: proxy/config: clean up after proxies list conversion
      MINOR: proxy: rename proxies list to all_proxies
      MINOR: server: rename global servers_list to all_servers
      MINOR: server: do not return next server on srv_drop()
      MINOR: proxy: define server list iteration functions
      MAJOR: proxy: convert server list to a doubly linked struct list
      OPTIM/MEDIUM: proxy/server: avoid server list reordering on startup
      MINOR: server: improve parsing error for server-template
      BUG/MINOR: server: fix QUIC on server-template
      BUG/MINOR: server: duplicate server alt_proto in srv_settings_cpy()
      MINOR: server: ensure check-reuse-pool is init in srv_settings_init()
      BUG/MINOR: server: fix check reuse-pool in srv_settings_cpy()
      BUILD: tools: fix C23 incompatible strrchr usage
      CLEANUP: server: remove wrong comments about server-template ID
      MINOR: errors: further improve parsing error for server-template
      BUG/MINOR: server: check strdup return value on server ID
      MINOR: server: do not ignore errors during server-template init
      BUG/MINOR: server: check strdup return on server-template ID generation
      MINOR: server: detect name conflict earlier during parsing
      MINOR: server: treat proxy server tree as without duplicate
      BUG/MINOR: proxy: fix default-server leak on post-parsing cleanup
      MINOR: proxy: implement unpublished backend keyword
      MINOR: server: define _srv_parse_from() for server "from" keyword
      MINOR: server: implement "from none"
      MINOR: proxy: keep default-server unless empty setting
      MINOR: proxy: extend global tune.defaults.purge for default-server
      MEDIUM: server: implement from be:
      MINOR: server: set default-server id to NULL
      MEDIUM: proxy: implement named default-server
      MINOR: server: prevent name collision with a default-server
      MEDIUM: server: implement "from srv:"
      CLEANUP: xprt_quic: remove dead callbacks prepare_srv/destroy_srv
      DOC: explain better that named defaults are preserved
      DOC: better explain that default-server are now preserved
      BUG/MINOR: proxy: fix "show backend"
      MINOR: list: define watcher_is_attached()
      MINOR: proxy: implement "show default-server"
      MINOR: proxy: complete "add backend" reg-test
      MINOR: proxy: implement "show defaults"

Andre Brait (1):
      OPTIM: pattern: try literal IPv6 parsing before DNS resolution in 
pat_parse_ip

Christopher Faulet (12):
      REORG: h1-htx: Move h1 headers map in h1-htx
      BUG/MEDIUM: mux-h1: Always adjust case for all outgoing headers as 
expected
      MINOR: mux-h1: Lower the case for Sec-Websocket-* headers when manually 
added
      MINOR: mux-h1: Use htx version to send default low-level errors
      BUG/MEDIUM: http-fetch: don't parse a non-HTTP check buffer as an HTX 
message
      BUG/MEDIUM: tools: make string encoding possible to fail instead of 
truncating
      CLEANUP: http-conv: Remove useless enc_type init to ENC_QUERY
      CLEANUP: http-conf: rename local trash variable
      BUG/MINOR: htx: Perform raw copy for messages of same size in 
htx_copy_msg()
      BUG/MINOR: htx: Transfer HTX_FL_EOM flag on success in htx_append_msg()
      BUG/MINOR: http-rules: fix release of a failed "set-cookie-fmt" redirect 
rule
      BUG/MEDIUM: filter: Disable auto-close on channel during TCP payload 
filtering

Frederic Lecaille (12):
      BUG/MINOR: haload: fix use-after-free upon updating task expiration
      BUG/MINOR: haload: set default thread count to 1
      BUG/MINOR: haload: fix display glitches by flushing stdout in summary
      MINOR: haload: add rate limiting support using -R option
      BUG/MINOR: haload: fix CPU topology detection by omitting forced 
"nbthread"
      CLEANUP: haload: use <arg_thrd> instead of <global.nbthread> where 
applicable
      CLEANUP: haload: embed rate_task into hld_thr_info structure
      CLEANUP: haload: factor out user scheduling into hld_usr_schedule()
      BUG/MINOR: haload: fix rate limit bypass during stream errors
      CLEANUP: haload: drop unused flags field from struct hld_url
      BUG/MINOR: haload: fix stale global variables affecting URL allocations
      MINOR: haload: support HTTP status code by version

Matt Suiche (3):
      BUG/MEDIUM: peers: check the available room before encoding dict values
      BUG/MEDIUM: sample: reject the deprecated protobuf group wire types
      BUG/MAJOR: ssl/ocsp: lock the OCSP response around reads in the stapling 
callback

Olivier Houchard (29):
      BUG/MEDIUM: ssl: Spell HAVE_VANILLA_OPENSSL correctly
      BUG/MEDIUM: ssl: Handle non-application data record while splicing
      MEDIUM: ssl: Add a way to rate-limit TLSv1.3 KeyUpdate
      DOC: ssl: Document tune.ssl.keyupdate-rate-limit
      BUG/MEDIUM: ssl: Put CO_ER_SSL_KEYUPDATE at the right place
      BUILD: ssl: Do not use SSL3_MT_KEY_UPDATE, hardcode 24 instead
      BUG/MINOR: cli: use the current argument to parse the FD spec in "show fd"
      BUG/MINOR: cli: do not reject the "/<fd>" form of "show fd"
      MEDIUM: fd: Remove fdinfo
      MEDIUM: fd: Make it possible to have one fdtab per thread-group
      MEDIUM: pollers: Allow one polled_mask per thread group
      MEDIUM: pollers: Create the poller pipes before we create the thread
      MEDIUM: listeners: Don't always balance connections across thread groups
      MEDIUM: backend: Do not always allow takeover across thread groups
      MEDIUM: listener: Properly handle unshared fd tables between tgroups
      MEDIUM: cli: Transfer sockets with unshared file descriptor tables
      MEDIUM: pollers: Only allow epoll when each tgroup has its fd table
      MEDIUM: pipes: Have one pool of free pipes per thread group
      MINOR: cli: Make "show fd" aware of per-thread-group FD tables
      MINOR: debug: Report the current tgid in "debug dev fd"
      MINOR: cli: Report the tgid along the FD in "show sess"
      MEDIUM: dns: Stick the TCP nameserver tasks to the resolvers' thread
      MEDIUM: server: Do not close other thread groups' connections at deinit
      MEDIUM: resolvers: Do not close another thread group's socket at deinit
      MEDIUM: quic: Do not use another thread group's listener FD
      MINOR: connection: Do not retrieve src/dst on another thread group's FD
      MEDIUM: fd: Add the tune.fd.tables option
      BUILD: listener: Fix the build on platforms without MSG_CMSG_CLOEXEC
      DOC: config: Document the tune.fd.tables option

Tim Duesterhus (3):
      MINOR: halog: Add reusable function to extract the value of header 
captures
      CLEANUP: halog: Clean up naming for variables related to `-hdr` processing
      MINOR: halog: Add support filtering on header capture values using 
-hdr-match

William Lallemand (8):
      BUG/MINOR: ech: propagate error from load_echkeys()
      BUG/MINOR: ech: reject an ECH store with no usable private key
      BUG/MINOR: ech: fix label at end of compound statement
      MINOR: ech: introduce an ech_store type and helpers in load_echkeys()
      MEDIUM: ech: implement a lighter ECH feature for AWS-LC
      CI: github: add USE_ECH=1 in OpenSSL and AWS-LC jobs
      DOC: stop supporting OpenSSL version < 1.1.1
      CI: github: remove OpenSSL 1.0.2 job

Willy Tarreau (34):
      OPTIM: tools: keep a cache of recent localtime() and gmtime()
      DEBUG: fd: catch access attempts to closed FDs
      BUG/MINOR: http-htx: fix the length moved when removing a header value
      BUG/MEDIUM: http-fetch: reject a negative capture id in 
capture.{req,res}.hdr
      BUG/MINOR: http-fetch: fix a NULL channel dereference in smp_fetch_body()
      BUG/MINOR: http: fix an out-of-bounds read in http_get_host_port() on 
empty host
      BUG/MINOR: http-htx: check the trash allocation in 
http_scheme_based_normalize()
      BUG/MINOR: h1: report the right error position on authority/host mismatch
      BUG/MINOR: h2: don't use a block pointer to roll back a partial HTX 
conversion
      BUG/MINOR: h3: don't use a block pointer to roll back a partial HTX 
conversion
      BUG/MINOR: http-ana: fix a one-byte over-read in the client-side cookie 
parser
      CLEANUP: htx: remove the unreachable "append_data" label in 
htx_reserve_max_data()
      CLEANUP: flt-comp: remove a no-op http_remove_header() call
      BUG/MINOR: http-act: fix a double free of the regex on a rule parsing 
error
      BUG/MINOR: http-act: fix a double free of the map reference on a parsing 
error
      BUG/MINOR: http-act: restore the response buffer state in the early-hint 
action
      BUG/MINOR: http-act: work on a copy of the sample in del-headers-bin
      BUG/MINOR: http-act: reject a negative capture id in the capture actions
      CLEANUP: http-conv: index the captures array with hdr->index in the 
converters
      BUG/MINOR: http-htx: check the strdup() of the "lf-string" http reply 
argument
      BUG/MINOR: slz: do not read past the end of the input around the match 
loop
      CLEANUP: slz: fix the documented worst case size of flush() and finish()
      BUG/MINOR: slz: use the exact switch cost for the last literals of a block
      BUG/MEDIUM: slz: bound the bits wasted by the 9-bit literals
      BUG/MINOR: slz: do not append a block to an already finished stream
      BUG/MINOR: slz: fix the adler32 accumulators signedness on 32-bit
      BUG/MINOR: slz: avoid undefined shifts when building the word byte by byte
      CLEANUP: slz: clarify that the size promise applies to the stream, not to 
a call
      IMPORT: cebtree: private: fix the duplicate detection in the lookup 
shortcut
      DEV: patchbot: add an "O" filter to hide original lines without new notes
      DEV: patchbot: retrieve the shared state on page load, with a timeout
      DEV: patchbot: support passing the page settings in the URL fragment
      OPTIM: tools/str2net: only duplicate the string when a slash is present
      MINOR: sample: make the param converter support control characters

---


Reply via email to