Hi,

HAProxy 3.3-dev9 was released on 2025/10/03. It added 218 new commits
after version 3.3-dev8.

The past two weeks have been quite busy for a number of us away from the
keyboard, yet that release is quite big due to the merge of several long
time pending branches.

First, an overview of the most significant bugs that were fixed
(approx 52 total):

  - an issue in the mjson JSON decoder causes number with large exponents
    to eat a lot of CPU and possibly even to trigger the watchdog and kill
    the process. It affects converters "json_query()", "jwt_header_query()",
    and "jwt_payload_query()". There's no work around for this because the
    issue is at a really low level in the decoder, so one cannot really
    count on a reasonable regex or such a thing to fix this. This bug was
    assigned CVE-2025-11230 and affects all versions featuring the JSON
    decoder, or 2.4 and above. Only an update will fix this. We'd like to
    thank Oula Kivalo for reporting the issue with a reproducer. As a note,
    we were notified that CVE-2023-30421 had already been assigned to the
    mjson library two years ago about the same issue but no fix had been
    issued and it was not mentioned in the project (though an issue about
    this was reported). Please watch for stable announcements for stable
    versions.

  - a second attempt at fixing detection of synchronous sends was made;
    the previous one could cause some shutdowns to be missed in 3.3-dev8.

  - the rest is spread all over the code (H2, ACME, resolvers, SSL)

Aside bugs, some improvements were made:

  - the SNI is now automatically set to the Host header field on outgoing
    TLS connections. This will simplify end-to-end TLS setups so that it
    is no longer required to enter "sni req.hdr(host)".

  - "option abortonclose" will now also work to avoid computing TLS
    handshakes on connections that are already closed. On some saturated
    machines, the situation can sometimes arise (e.g. after a failover)
    where calculating all the new keys takes too long compared to the
    rate of arrival, and that connection are aborted (impatient users
    or client timeouts), and in this case we'd rather avoid to waste
    precious CPU cycles doing asymmetric crypto for a connection that
    is being aborted. Note that this is only done when abortonclose is
    set so as not to break possible TLS client-hello health checks that
    other components might run in front of haproxy. The question of
    whether or not this option could be turned on by default could be
    debated though.

  - the locking between stick-tables and peers was partially relaxed so
    that we don't insist too long anymore when detecting contention. Such
    contention used to cause severe performance degradation on some
    systems, sometimes even triggering the watchdog due to multiple
    milliseconds delays multiplied by the number of entries processed at
    once. More batching and delayed work was used instead, resulting in
    higher overall performance and a much smoother traffic flow.

  - a number of multi-threaded tasks were moved to single thread (e.g.
    table expiration, resolvers connections etc), because these were
    found to cause a lot of contention in the scheduler on high CPU count
    machines, for no added value.

  - the compact binary trees implementation was updated to support
    duplicates, and was more broadly used in various config-time elements
    (object names), as well as idle connections. This resulted in about 4%
    memory savings on large configs with thousands of servers, and about
    2% request rate increase.

  - and some more minor changes in various other areas (ring optimizations,
    locking time measurements for task profiling, new acme options)

  - new scripts to more easily dump certificates (see admin/dump-certs)

  - and usual build fixes, CI updates and cleanups.

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.git/
   Git Web browsing : https://git.haproxy.org/?p=haproxy.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


---
Complete changelog :
Amaury Denoyelle (11):
      CLEANUP: quic: fix typo in quic_tx trace
      TESTS: quic: add unit-tests for QUIC TX part
      MINOR: quic: restore QUIC_HP_SAMPLE_LEN constant
      BUG/MINOR: quic: properly support GSO on backend side
      BUG/MINOR: hq-interop: adjust parsing/encoding on backend side
      OPTIM: check: do not delay MUX for ALPN if SSL not active
      BUG/MEDIUM: checks: fix ALPN inheritance from server
      BUG/MINOR: check: ensure checks are compatible with QUIC servers
      MINOR: check: reject invalid check config on a QUIC server
      MINOR: quic: display build warning for compat layer on recent OpenSSL
      DOC: quic: clarifies limited-quic support

Aurelien DARRAGON (9):
      BUG/MEDIUM: proxy: fix crash with stop_proxy() called during init
      MINOR: stats-file: use explicit unsigned integer bitshift for user slots
      BUG/MEDIUM: http_ana: fix potential NULL deref in 
http_process_req_common()
      MEDIUM: log/proxy: store log-steps selection using a bitmask, not an eb 
tree
      CLEANUP: log: remove deadcode in px_parse_log_steps()
      MINOR: counters: document that tg shared counters are tied to 
shm-stats-file mapping
      DOC: internals: document the shm-stats-file format/mapping
      BUG/MEDIUM: sink: fix unexpected double postinit of sink backend
      MEDIUM: stats: consider that shared stats pointers may be NULL

Ben Kallus (2):
      IMPORT: ebtree: Fix UB from clz(0)
      IMPORT: ebtree: replace hand-rolled offsetof to avoid UB

Chris Staite (2):
      MINOR: backend: srv_queue helper
      MINOR: backend: srv_is_up converter

Christopher Faulet (33):
      BUG/MINOR: acl: Fix error message about several '-m' parameters
      MINOR: server: Parse sni and pool-conn-name expressions in a dedicated 
function
      BUG/MEDIUM: server: Use sni as pool connection name for SSL server only
      BUG/MINOR: server: Update healthcheck when server settings are changed 
via CLI
      OPTIM: backend: Don't set SNI for non-ssl connections
      OPTIM: proto_rhttp: Don't set SNI for non-ssl connections
      OPTIM: tcpcheck: Don't set SNI and ALPN for non-ssl connections
      BUG/MINOR: tcpcheck: Don't use sni as pool-conn-name for non-SSL 
connections
      MEDIUM: server/ssl: Base the SNI value to the HTTP host header by default
      MEDIUM: httpcheck/ssl: Base the SNI value on the HTTP host header by 
default
      OPTIM: tcpcheck: Reorder tcpchek_connect structure fields to fill holes
      REGTESTS: ssl: Add a script to test the automatic SNI selection
      REGTESTS: ssl: Fix the script about automatic SNI selection
      BUG/MINOR: pools: Fix the dump of pools info to deal with buffers 
limitations
      MINOR: pools: Don't dump anymore info about pools when purge is forced
      BUG/MEDIUM: mux-h2: Reset MUX blocking flags when a send error is caught
      BUG/MEDIUM: mux-h2; Don't block reveives in H2_CS_ERROR and H2_CS_ERROR2 
states
      BUG/MEDIUM: mux-h2: Restart reading when mbuf ring is no longer full
      BUG/MINOR: mux-h2: Remove H2_CF_DEM_DFULL flags when the demux buffer is 
reset
      BUG/MEDIUM: mux-h2: Report RST/error to app-layer stream during 0-copy 
fwding
      BUG/MEDIUM: mux-h2: Reinforce conditions to report an error to app-layer 
stream
      BUG/MAJOR: stream: Force channel analysis on successful synchronous send
      BUG/MEDIUM: resolvers: Properly cache do-resolv resolution
      BUG/MINOR: resolvers: Restore round-robin selection on records in DNS 
answers
      BUG/MEDIUM: resolvers: Test for empty tree when getting a record from DNS 
answer
      BUG/MEDIUM: resolvers: Make resolution owns its hostname_dn value
      BUG/MEDIUM: resolvers: Accept to create resolution without hostname
      BUG/MEDIUM: resolvers: Wake resolver task up whne unlinking a stream 
requester
      Revert "BUG/MINOR: ocsp: Crash when updating CA during ocsp updates"
      BUG/MEDIUM: http-client: Fix the test on the response start-line
      BUG/MINOR: compression: Test payload size only if content-length is 
specified
      BUG/MINOR: pattern: Properly flag virtual maps as using samples
      BUG/MINOR: pattern: Fix pattern lookup for map with opt@ prefix

Collison, Steven (1):
      DOC: proxy-protocol: Add TLS group and sig scheme TLVs

Frederic Lecaille (5):
      MINOR: quic: add useful trace about padding params values
      BUG/MINOR: quic: too short PADDING frame for too short packets
      MINOR: quic: SSL session reuse for QUIC
      MINOR: quic: get rid of ->target quic_conn struct member
      MINOR: quic-be: make SSL/QUIC objects use their own indexes 
(ssl_qc_app_data_index)

Ilia Shipitsin (1):
      CI: move VTest preparation & friends to dedicated composite action

Olivier Houchard (15):
      BUG/MEDIUM: ssl: Properly initialize msg_controllen.
      BUG/MEDIUM: h1: Allow reception if we have early data
      BUG/MEDIUM: ssl: create the mux immediately on early data
      MINOR: ssl: Add a flag to let it known we have an ALPN negociated
      MINOR: ssl: Use the new flag to know when the ALPN has been set.
      MEDIUM: server: Introduce the concept of path parameters
      MEDIUM: server: Make use of the stored ALPN stored in the server
      BUG/MEDIUM: ssl: Fix a crash when using QUIC
      BUG/MEDIUM: ssl: Fix a crash if we failed to create the mux
      BUG/MEDIUM: stick-tables: Don't let table_process_entry() handle refcnt
      MINOR: mt_list: Implement MT_LIST_POP_LOCKED()
      BUG/MEDIUM: stick-tables: Make sure not to free a pending entry
      MEDIUM: servers: Schedule the server requeue target on creation
      MEDIUM: fwlc: Make it so fwlc_srv_reposition works with unqueued srv
      BUG/MEDIUM: fwlc: Handle memory allocation failures.

Remi Tricot-Le Breton (4):
      BUG/MINOR: ssl: Potential NULL deref in trace macro
      BUG/MINOR: ssl: Fix potential NULL deref in trace callback
      BUG/MINOR: ocsp: Crash when updating CA during ocsp updates
      BUG/MINOR: ocsp: Crash when updating CA during ocsp updates

Valentine Krasnobaeva (1):
      BUG/MINOR: resolvers: always normalize FQDN from response

William Lallemand (34):
      BUG/MINOR: acme: null pointer dereference upon allocation failure
      BUG/MEDIUM: jws: return size_t in JWS functions
      BUG/MINOR: ocsp: prototype inconsistency
      MINOR: ocsp: put internal functions as static ones
      MINOR: ssl: set functions as static when no protypes in the .h
      BUILD: ssl: functions defined but not used
      CI: scripts: add support for git in openssl builds
      CI: github: add an OpenSSL + ECH job
      CI: scripts: mkdir BUILDSSL_TMPDIR
      MINOR: acme: acme-vars allow to pass data to the dpapi sink
      MINOR: acme: check acme-vars allocation during escaping
      BUG/MINOR: acme/cli: wrong description for "acme challenge_ready"
      BUG/MINOR: acme: possible overflow on scheduling computation
      BUG/MINOR: acme: possible overflow in acme_will_expire()
      CLEANUP: acme: acme_will_expire() uses acme_schedule_date()
      CI: scripts: build curl with ECH support
      CI: github: add curl+ech build into openssl-ech job
      BUG/MEDIUM: ssl: ca-file directory mode must read every certificates of a 
file
      MINOR: acme: provider-name for dpapi sink
      BUILD: acme: fix false positive null pointer dereference
      BUILD: halog: misleading indentation in halog.c
      CI: github: build halog on the vtest job
      BUG/MINOR: acme: don't unlink from acme_ctx_destroy()
      BUG/MEDIUM: acme: cfg_postsection_acme() don't init correctly acme 
sections
      MINOR: acme: implement "reuse-key" option
      ADMIN: haproxy-dump-certs: implement a certificate dumper
      ADMIN: dump-certs: don't update the file if it's up to date
      ADMIN: dump-certs: create files in a tmpdir
      ADMIN: dump-certs: fix lack of / in -p
      ADMIN: dump-certs: use same error format as haproxy
      ADMIN: reload: add a synchronous reload helper
      BUG/MEDIUM: acme: free() of i2d_X509_REQ() with AWS-LC
      ADMIN: reload: introduce verbose and silent mode
      ADMIN: reload: introduce -vv mode

Willy Tarreau (98):
      BUG/MINOR: cpu_topo: work around a small bug in musl's CPU_ISSET()
      MINOR: debug: report the process id in warnings and panics
      DEBUG: stream: count the number of passes in the connect loop
      MINOR: debug: report the number of loops and ctxsw for each thread
      MINOR: debug: report the time since last wakeup and call
      DEBUG: peers: export functions that use locks
      MINOR: stick-table: permit stksess_new() to temporarily allocate more 
entries
      MEDIUM: stick-tables: relax stktable_trash_oldest() to only purge what is 
needed
      MEDIUM: stick-tables: give up on lock contention in process_table_expire()
      MEDIUM: stick-tables: don't wait indefinitely in 
stktable_add_pend_updates()
      MEDIUM: peers: don't even try to process updates under contention
      CLEANUP: backend: clarify the role of the init_mux variable in 
connect_server()
      CLEANUP: backend: invert the condition to start the mux in 
connect_server()
      CLEANUP: backend: simplify the complex ifdef related to 0RTT in 
connect_server()
      CLEANUP: backend: clarify the cases where we want to use early data
      BUILD: ssl: address a recent build warning when QUIC is enabled
      BUG/MINOR: activity: fix reporting of task latency
      MINOR: activity: indicate the number of calls on "show tasks"
      MINOR: tools: don't emit "+0" for symbol names which exactly match known 
ones
      BUG/MEDIUM: stick-tables: don't loop on non-expirable entries
      DEBUG: stick-tables: export stktable_add_pend_updates() for better 
reporting
      MEDIUM: dns: bind the nameserver sockets to the initiating thread
      MEDIUM: resolvers: make the process_resolvers() task single-threaded
      BUG/MINOR: stick-table: make sure never to miss a process_table_expire 
update
      MEDIUM: stick-table: move process_table_expire() to a single thread
      MEDIUM: peers: move process_peer_sync() to a single thread
      MINOR: activity: don't report the lat_tot column for show profiling tasks
      MINOR: activity: add a new lkw_avg column to show profiling stats
      MINOR: activity: collect time spent waiting on a lock for each task
      MINOR: thread: add a lock level information in the thread_ctx
      MINOR: activity: add a new lkd_avg column to show profiling stats
      MINOR: activity: collect time spent with a lock held for each task
      MINOR: activity: add a new mem_avg column to show profiling stats
      MINOR: activity: collect CPU time spent on memory allocations for each 
task
      MINOR: activity/memory: count allocations performed under a lock
      BUILD: makefile: implement support for running a command in range
      IMPORT: cebtree: import version 0.5.0 to support duplicates
      MEDIUM: migrate the patterns reference to cebs_tree
      MEDIUM: guid: switch guid to more compact cebuis_tree
      MEDIUM: server: switch addr_node to cebis_tree
      MEDIUM: server: switch conf.name to cebis_tree
      MEDIUM: server: switch the host_dn member to cebis_tree
      MEDIUM: proxy: switch conf.name to cebis_tree
      MEDIUM: stktable: index table names using compact trees
      MINOR: proxy: add proxy_get_next_id() to find next free proxy ID
      MINOR: listener: add listener_get_next_id() to find next free listener ID
      MINOR: server: add server_get_next_id() to find next free server ID
      CLEANUP: server: use server_find_by_id() when looking for already used IDs
      MINOR: server: add server_index_id() to index a server by its ID
      MINOR: listener: add listener_index_id() to index a listener by its ID
      MINOR: proxy: add proxy_index_id() to index a proxy by its ID
      MEDIUM: proxy: index proxy ID using compact trees
      MEDIUM: listener: index listener ID using compact trees
      MEDIUM: server: index server ID using compact trees
      CLEANUP: server: slightly reorder fields in the struct to plug holes
      CLEANUP: proxy: slightly reorganize fields to plug some holes
      CLEANUP: backend: factor the connection lookup loop
      CLEANUP: server: use eb64_entry() not ebmb_entry() to convert an eb64
      MINOR: server: pass the server and thread to srv_migrate_conns_to_remove()
      CLEANUP: backend: use a single variable for removed in 
srv_cleanup_idle_conns()
      MINOR: connection: pass the thread number to conn_delete_from_tree()
      MEDIUM: connection: move idle connection trees to ceb64
      MEDIUM: connection: reintegrate conn_hash_node into connection
      CLEANUP: tools: use the item API for the file names tree
      CLEANUP: vars: use the item API for the variables trees
      BUG/MEDIUM: pattern: fix possible infinite loops on deletion
      Revert "BUG/MEDIUM: pattern: fix possible infinite loops on deletion"
      BUG/MEDIUM: pattern: fix possible infinite loops on deletion (try 2)
      IMPORT: ebtree: delete unusable ebpttree.c
      IMPORT: eb32/eb64: reorder the lookup loop for modern CPUs
      IMPORT: eb32/eb64: use a more parallelizable check for lack of common bits
      IMPORT: eb32: drop the now useless node_bit variable
      IMPORT: eb32/eb64: place an unlikely() on the leaf test
      IMPORT: ebmb: optimize the lookup for modern CPUs
      IMPORT: eb32/64: optimize insert for modern CPUs
      IMPORT: ebtree: only use __builtin_prefetch() when supported
      IMPORT: ebst: use prefetching in lookup() and insert()
      IMPORT: ebtree: add a definition of offsetof()
      MINOR: listener: add the "cc" bind keyword to set the TCP congestion 
controller
      MINOR: server: add the "cc" keyword to set the TCP congestion controller
      BUG/MEDIUM: ring: invert the length check to avoid an int overflow
      MINOR: trace: don't call strlen() on the thread-id numeric encoding
      MINOR: trace: don't call strlen() on the function's name
      OPTIM: sink: reduce contention on sink_announce_dropped()
      OPTIM: sink: don't waste time calling sink_announce_dropped() if busy
      CLEANUP: ring: rearrange the wait loop in ring_write()
      OPTIM: ring: always relax in the ring lock and leader wait loop
      OPTIM: ring: check the queue's owner using a CAS on x86
      OPTIM: ring: avoid reloading the tail_ofs value before the CAS in 
ring_write()
      MINOR: sched: let's permit to share the local ctx between threads
      MINOR: sched: pass the thread number to is_sched_alive()
      BUG/MEDIUM: wdt: improve stuck task detection accuracy
      MINOR: ssl: add the ssl_bc_sni sample fetch function to retrieve backend 
SNI
      MINOR: rawsock: introduce CO_RFL_TRY_HARDER to detect closures on 
complete reads
      MEDIUM: ssl: don't always process pending handshakes on closed connections
      DOC: config: clarify some known limitations of the json_query() converter
      BUG/CRITICAL: mjson: fix possible DoS when parsing numbers
      BUG/MEDIUM: resolvers: break an infinite loop in 
resolv_get_ip_from_response()

zhanhb (2):
      BUG/MINOR: h2: forbid 'Z' as well in header field names checks
      BUG/MINOR: h3: forbid 'Z' as well in header field names checks

--
Christopher Faulet


Reply via email to