Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package haproxy for openSUSE:Factory checked in at 2026-05-12 19:26:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/haproxy (Old) and /work/SRC/openSUSE:Factory/.haproxy.new.1966 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "haproxy" Tue May 12 19:26:53 2026 rev:184 rq:1352527 version:3.3.10+git0.0a72d7f9f Changes: -------- --- /work/SRC/openSUSE:Factory/haproxy/haproxy.changes 2026-05-06 19:25:06.946948923 +0200 +++ /work/SRC/openSUSE:Factory/.haproxy.new.1966/haproxy.changes 2026-05-12 19:27:35.181370080 +0200 @@ -1,0 +2,23 @@ +Mon May 11 16:02:58 UTC 2026 - Marcus Rueckert <[email protected]> + +- Update to version 3.3.10+git0.0a72d7f9f: + * [RELEASE] Released version 3.3.10 + * BUG/MEDIUM: tasks: Keep the TASK_RUNNING flag until queued + * BUG/MINOR: cfgparse-listen: do not emit extraneous line in rule order warnings + * BUG/MEDIUM: servers: Only requeue servers if they are up + * BUG/MINOR: mux_quic: refresh timeout only if I/O performed + * BUG/MEDIUM: mux_quic: adjust qcc_is_dead() to account detached streams + * BUG/MEDIUM: stick-table: properly check permissions on CLI's set/clear cmd + * BUG/MEDIUM: mux-h2: fix the detection of the ext connect support + * Revert "BUG/MINOR: mux-h2: condition the processing of 8441 extension to global setting" + +------------------------------------------------------------------- +Thu May 07 15:32:58 UTC 2026 - Marcus Rueckert <[email protected]> + +- Update to version 3.3.9+git4.129865971: + * Revert "BUG/MEDIUM: cli: fix master CLI connection slot leak on client disconnect" + * BUG/MEDIUM: mux-h2: Properly consume padding for DATA frames + * BUG/MINOR: mux_quic: fix max stream ID reuse estimation + * BUG/MINOR: ssl: Use the sequence number with kTLS and TLS 1.2 + +------------------------------------------------------------------- Old: ---- haproxy-3.3.9+git0.aa6f85a2f.tar.gz New: ---- haproxy-3.3.10+git0.0a72d7f9f.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ haproxy.spec ++++++ --- /var/tmp/diff_new_pack.rWOysI/_old 2026-05-12 19:27:36.037405558 +0200 +++ /var/tmp/diff_new_pack.rWOysI/_new 2026-05-12 19:27:36.037405558 +0200 @@ -35,7 +35,7 @@ %bcond_with ech Name: haproxy -Version: 3.3.9+git0.aa6f85a2f +Version: 3.3.10+git0.0a72d7f9f Release: 0 # Summary: The Reliable, High Performance TCP/HTTP Load Balancer ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.rWOysI/_old 2026-05-12 19:27:36.129409371 +0200 +++ /var/tmp/diff_new_pack.rWOysI/_new 2026-05-12 19:27:36.137409702 +0200 @@ -1,7 +1,8 @@ <servicedata> <service name="tar_scm"> <param name="url">http://git.haproxy.org/git/haproxy-3.3.git/</param> - <param name="changesrevision">aa6f85a2f5d72a48643b790d75a5e3ccfbbbc0b2</param> + <param name="changesrevision">0a72d7f9f45c1e8ca476492edf8328913ce2277a</param> </service> </servicedata> +(No newline at EOF) ++++++ haproxy-3.3.9+git0.aa6f85a2f.tar.gz -> haproxy-3.3.10+git0.0a72d7f9f.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/CHANGELOG new/haproxy-3.3.10+git0.0a72d7f9f/CHANGELOG --- old/haproxy-3.3.9+git0.aa6f85a2f/CHANGELOG 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/CHANGELOG 2026-05-11 17:09:08.000000000 +0200 @@ -1,6 +1,20 @@ ChangeLog : =========== +2026/05/11 : 3.3.10 + - BUG/MINOR: ssl: Use the sequence number with kTLS and TLS 1.2 + - BUG/MINOR: mux_quic: fix max stream ID reuse estimation + - BUG/MEDIUM: mux-h2: Properly consume padding for DATA frames + - Revert "BUG/MEDIUM: cli: fix master CLI connection slot leak on client disconnect" + - Revert "BUG/MINOR: mux-h2: condition the processing of 8441 extension to global setting" + - BUG/MEDIUM: mux-h2: fix the detection of the ext connect support + - BUG/MEDIUM: stick-table: properly check permissions on CLI's set/clear cmd + - BUG/MEDIUM: mux_quic: adjust qcc_is_dead() to account detached streams + - BUG/MINOR: mux_quic: refresh timeout only if I/O performed + - BUG/MEDIUM: servers: Only requeue servers if they are up + - BUG/MINOR: cfgparse-listen: do not emit extraneous line in rule order warnings + - BUG/MEDIUM: tasks: Keep the TASK_RUNNING flag until queued + 2026/05/06 : 3.3.9 - BUG/MINOR: sink: do not free existing sinks on allocation error - BUG/MINOR: vars: make parse_store() return error on var_set() failure diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/VERDATE new/haproxy-3.3.10+git0.0a72d7f9f/VERDATE --- old/haproxy-3.3.9+git0.aa6f85a2f/VERDATE 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/VERDATE 2026-05-11 17:09:08.000000000 +0200 @@ -1,2 +1,2 @@ $Format:%ci$ -2026/05/06 +2026/05/11 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/VERSION new/haproxy-3.3.10+git0.0a72d7f9f/VERSION --- old/haproxy-3.3.9+git0.aa6f85a2f/VERSION 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/VERSION 2026-05-11 17:09:08.000000000 +0200 @@ -1 +1 @@ -3.3.9 +3.3.10 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/doc/configuration.txt new/haproxy-3.3.10+git0.0a72d7f9f/doc/configuration.txt --- old/haproxy-3.3.9+git0.aa6f85a2f/doc/configuration.txt 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/doc/configuration.txt 2026-05-11 17:09:08.000000000 +0200 @@ -3,7 +3,7 @@ Configuration Manual ---------------------- version 3.3 - 2026/05/06 + 2026/05/11 This document covers the configuration language as implemented in the version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/include/haproxy/mux_quic.h new/haproxy-3.3.10+git0.0a72d7f9f/include/haproxy/mux_quic.h --- old/haproxy-3.3.9+git0.aa6f85a2f/include/haproxy/mux_quic.h 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/include/haproxy/mux_quic.h 2026-05-11 17:09:08.000000000 +0200 @@ -93,9 +93,10 @@ int qcc_install_app_ops(struct qcc *qcc, const struct qcc_app_ops *app_ops); -/* Register <qcs> stream for http-request timeout. If the stream is not yet - * attached in the configured delay, qcc timeout task will be triggered. This - * means the full header section was not received in time. +/* Flags <qcs> as a request stream. The connection will be considered as active + * until all request streams are closed or on inactivity timeout. On the + * frontend side, http-request timeout will be applied on the stream to ensure + * headers are received in time. * * This function should be called by the application protocol layer on request * streams initialization. @@ -112,6 +113,11 @@ * restriction is needed here. */ LIST_APPEND(&qcc->opening_list, &qcs->el_opening); + + /* Ensure flag is only set once per stream to avoid nb_hreq counter wrapping. */ + BUG_ON_HOT(qcs->flags & QC_SF_HREQ_RECV); + qcs->flags |= QC_SF_HREQ_RECV; + ++qcc->nb_hreq; } void qcc_show_quic(struct qcc *qcc); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/include/haproxy/task.h new/haproxy-3.3.10+git0.0a72d7f9f/include/haproxy/task.h --- old/haproxy-3.3.9+git0.aa6f85a2f/include/haproxy/task.h 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/include/haproxy/task.h 2026-05-11 17:09:08.000000000 +0200 @@ -736,7 +736,6 @@ when = tick_first(when, task->expire); task->expire = when; - task_drop_running(task, 0); if (!task_in_wq(task) || tick_is_lt(task->expire, task->wq.key)) { if (likely(caller)) { caller = HA_ATOMIC_XCHG(&task->caller, caller); @@ -747,6 +746,7 @@ } __task_queue(task, &tg_ctx->timers); } + task_drop_running(task, 0); HA_RWLOCK_WRUNLOCK(TASK_WQ_LOCK, &wq_lock); } else #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/reg-tests/http-messaging/protocol_upgrade.vtc new/haproxy-3.3.10+git0.0a72d7f9f/reg-tests/http-messaging/protocol_upgrade.vtc --- old/haproxy-3.3.9+git0.aa6f85a2f/reg-tests/http-messaging/protocol_upgrade.vtc 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/reg-tests/http-messaging/protocol_upgrade.vtc 2026-05-11 17:09:08.000000000 +0200 @@ -72,7 +72,7 @@ txresp \ -status 200 } -run -} -repeat 4 -start +} -repeat 2 -start # http2 server without support for RFC8441 server srv_h2_no_ws { @@ -219,8 +219,7 @@ client c2_h2 -connect ${hap_frt_h2_sock} { txpri stream 0 { - # manually send RFC8441 SETTINGS_ENABLE_CONNECT_PROTOCOL - sendhex "00 00 06 04 00 00 00 00 00 00 08 00 00 00 01" + txsettings rxsettings txsettings -ack rxsettings @@ -242,62 +241,11 @@ } -run } -run -# connect to h2 server frontend without extension: must fail -client c2_h2_rej1 -connect ${hap_frt_h2_sock} { - txpri - stream 0 { - # no extension sent - txsettings - rxsettings - txsettings -ack - rxsettings - expect settings.ack == true - } -run - - stream 1 { - txreq \ - -req "CONNECT" \ - -scheme "http" \ - -url "/" \ - -hdr ":authority" "127.0.0.1" \ - -hdr ":protocol" "custom_protocol" \ - -nostrend - - rxrst - } -run -} -run - -# connect to h2 server with ext but :proto with bad method: must fail -client c2_h2_rej2 -connect ${hap_frt_h2_sock} { - txpri - stream 0 { - # manually send RFC8441 SETTINGS_ENABLE_CONNECT_PROTOCOL - sendhex "00 00 06 04 00 00 00 00 00 00 08 00 00 00 01" - rxsettings - txsettings -ack - rxsettings - expect settings.ack == true - } -run - - stream 1 { - txreq \ - -req "GET" \ - -scheme "http" \ - -url "/" \ - -hdr ":authority" "127.0.0.1" \ - -hdr ":protocol" "custom_protocol" \ - -nostrend - - rxrst - } -run -} -run - # connect to h2 translation frontend client c3_h2_h1 -connect ${hap_frt_h2_h1_sock} { txpri stream 0 { - # manually send RFC8441 SETTINGS_ENABLE_CONNECT_PROTOCOL - sendhex "00 00 06 04 00 00 00 00 00 00 08 00 00 00 01" + txsettings rxsettings txsettings -ack rxsettings @@ -391,8 +339,7 @@ client c9_h2c -connect ${hap_frt_h2_h1_sock} { txpri stream 0 { - # manually send RFC8441 SETTINGS_ENABLE_CONNECT_PROTOCOL - sendhex "00 00 06 04 00 00 00 00 00 00 08 00 00 00 01" + txsettings rxsettings txsettings -ack rxsettings diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/reg-tests/http-messaging/websocket.vtc new/haproxy-3.3.10+git0.0a72d7f9f/reg-tests/http-messaging/websocket.vtc --- old/haproxy-3.3.9+git0.aa6f85a2f/reg-tests/http-messaging/websocket.vtc 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/reg-tests/http-messaging/websocket.vtc 2026-05-11 17:09:08.000000000 +0200 @@ -177,8 +177,7 @@ client c4 -connect ${hap_fe3_sock} { txpri stream 0 { - # manually send RFC8441 SETTINGS_ENABLE_CONNECT_PROTOCOL - sendhex "00 00 06 04 00 00 00 00 00 00 08 00 00 00 01" + txsettings rxsettings txsettings -ack rxsettings @@ -206,8 +205,7 @@ client c5 -connect ${hap_fe4_sock} { txpri stream 0 { - # manually send RFC8441 SETTINGS_ENABLE_CONNECT_PROTOCOL - sendhex "00 00 06 04 00 00 00 00 00 00 08 00 00 00 01" + txsettings rxsettings txsettings -ack rxsettings diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/reg-tests/mcli/mcli_master_socket_leak.vtc new/haproxy-3.3.10+git0.0a72d7f9f/reg-tests/mcli/mcli_master_socket_leak.vtc --- old/haproxy-3.3.9+git0.aa6f85a2f/reg-tests/mcli/mcli_master_socket_leak.vtc 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/reg-tests/mcli/mcli_master_socket_leak.vtc 1970-01-01 01:00:00.000000000 +0100 @@ -1,66 +0,0 @@ -varnishtest "Bug fix: master CLI connection slots freed on client disconnect" - -# Regression test for a master CLI socket connection leak in master-worker mode. -# -# mworker_proxy has a fixed maxconn of 10. When clients connect to the master -# socket, send a command that is forwarded to a busy worker, and then close -# the connection due to a client-side receive timeout, haproxy must free each -# slot as the client disconnects. -# -# Without the fix: slots remain occupied after the client disconnects, so the -# master CLI becomes unreachable once all 10 slots are filled. -# With the fix: slots are freed on client disconnect and the master CLI keeps -# accepting new connections. -# -# The worker is made unresponsive using "debug dev delay" (expert-mode) with -# nbthread 1 so a single delay blocks the entire worker CLI. This avoids -# using SIGSTOP/SIGCONT which can be unreliable in CI environments. - -#REGTEST_TYPE=bug - -feature cmd "command -v socat" -feature cmd "command -v timeout" -feature ignore_unknown_macro - -server s1 { -} -start - -haproxy h1 -W -S -conf { - global - nbthread 1 - - defaults - mode http - timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" - timeout client "${HAPROXY_TEST_TIMEOUT-5s}" - timeout server "${HAPROXY_TEST_TIMEOUT-5s}" - - frontend fe - bind "fd@${fe}" - default_backend be - - backend be - server s1 ${s1_addr}:${s1_port} -} -start - -# Fill all 10 master CLI slots (mworker_proxy->maxconn is hardcoded to 10). -# Each socat sends "expert-mode on" followed by "@1 debug dev delay 10000" -# which blocks the single worker thread for 10 s. After 2 s the timeout(1) -# wrapper kills socat, simulating a client-side receive timeout. "wait" -# ensures all background processes have exited before proceeding. -shell { - for i in $(seq 1 10); do - (printf "expert-mode on\n@1 debug dev delay 10000\n" \ - | timeout 2 socat TCP:${h1_mcli_addr}:${h1_mcli_port} - 2>/dev/null) & - done - wait -} - -# This is the key assertion: after all 10 clients have disconnected, a new -# connection to the master CLI must succeed. With the bug all 10 slots are -# still marked occupied and this connect is refused or times out. -haproxy h1 -mcli { - send "show version" - expect ~ "3." -} - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/src/cfgparse-listen.c new/haproxy-3.3.10+git0.0a72d7f9f/src/cfgparse-listen.c --- old/haproxy-3.3.9+git0.aa6f85a2f/src/cfgparse-listen.c 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/src/cfgparse-listen.c 2026-05-11 17:09:08.000000000 +0200 @@ -3245,12 +3245,14 @@ /* prepare error message just in case */ rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, curr_defproxy, file, linenum, &errmsg); if (rc < 0) { - ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg); + if (errmsg) + ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg); err_code |= ERR_ALERT | ERR_FATAL; goto out; } else if (rc > 0) { - ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg); + if (errmsg) + ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg); err_code |= ERR_WARN; goto out; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/src/cli.c new/haproxy-3.3.10+git0.0a72d7f9f/src/cli.c --- old/haproxy-3.3.9+git0.aa6f85a2f/src/cli.c 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/src/cli.c 2026-05-11 17:09:08.000000000 +0200 @@ -3735,9 +3735,8 @@ mworker_proxy->mode = PR_MODE_CLI; /* default to 10 concurrent connections */ mworker_proxy->maxconn = 10; - mworker_proxy->timeout.client = 0; /* no timeout */ - mworker_proxy->timeout.serverfin = MS_TO_TICKS(1000); /* 1s timeout in case worker is not responding on shutdown */ - + /* no timeout */ + mworker_proxy->timeout.client = 0; mworker_proxy->conf.file = strdup("MASTER"); mworker_proxy->conf.line = 0; mworker_proxy->accept = frontend_accept; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/src/mux_h2.c new/haproxy-3.3.10+git0.0a72d7f9f/src/mux_h2.c --- old/haproxy-3.3.9+git0.aa6f85a2f/src/mux_h2.c 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/src/mux_h2.c 2026-05-11 17:09:08.000000000 +0200 @@ -2908,8 +2908,7 @@ } break; case H2_SETTINGS_ENABLE_CONNECT_PROTOCOL: - /* setting only considered if rfc8441 not disabled */ - if (arg == 1 && !(global.tune.options & GTUNE_DISABLE_H2_WEBSOCKET)) + if (arg == 1) h2c->flags |= H2_CF_RCVD_RFC8441; break; } @@ -6271,8 +6270,16 @@ /* If an Extended CONNECT has been sent on this stream, set message flag * to convert 200 response to 101 htx response. We only support this if * the connection supports RFC8441. + * On the backend, that means the origin server advertised the setting. + * On the frontend, RFC 8441 �3 only requires the server (us) to + * advertise it; clients are not required to echo it back. Use whether + * we ourselves advertised it as the gate. */ - msgf |= (h2c->flags & H2_CF_RCVD_RFC8441) ? H2_MSGF_EXT_CONN_OK : 0; + if (h2c->flags & H2_CF_IS_BACK) + msgf |= (h2c->flags & H2_CF_RCVD_RFC8441) ? H2_MSGF_EXT_CONN_OK : 0; + else if (!(global.tune.options & GTUNE_DISABLE_H2_WEBSOCKET)) + msgf |= H2_MSGF_EXT_CONN_OK; + msgf |= (*flags & H2_SF_EXT_CONNECT_SENT) ? H2_MSGF_EXT_CONNECT: 0; /* when dealing with trailers, we need to check the content-length */ @@ -6505,8 +6512,22 @@ end_transfer: /* here we're done with the frame, all the payload (except padding) was - * transferred. + * transferred. So let's consume the padding now. + * + * The padding may not have been fully received, so we must take care to + * not consume more than avaiable and eventually retry later. */ + BUG_ON(h2c->dfl != h2c->dpl); + flen = b_data(&h2c->dbuf); + if (flen > h2c->dfl) + flen = h2c->dfl; + b_del(&h2c->dbuf, flen); + h2c->dfl -= flen; + h2c->dpl -= flen; + h2c->rcvd_c += flen; + h2c->rcvd_s += flen; + if (h2c->dfl) + goto fail; if (!(h2s->flags & H2_SF_BODY_TUNNEL) && (h2c->dff & H2_F_DATA_END_STREAM)) { /* no more data are expected for this message. This add the EOM @@ -6521,9 +6542,6 @@ } } - h2c->rcvd_c += h2c->dpl; - h2c->rcvd_s += h2c->dpl; - h2c->dpl = 0; h2c->st0 = H2_CS_FRAME_A; // send the corresponding window update htx_to_buf(htx, scbuf); TRACE_LEAVE(H2_EV_RX_FRAME|H2_EV_RX_DATA, h2c->conn, h2s); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/src/mux_quic.c new/haproxy-3.3.10+git0.0a72d7f9f/src/mux_quic.c --- old/haproxy-3.3.9+git0.aa6f85a2f/src/mux_quic.c 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/src/mux_quic.c 2026-05-11 17:09:08.000000000 +0200 @@ -94,6 +94,11 @@ sedesc_free(qcs->sd); qcs->sd = NULL; + if (qcs->flags & QC_SF_HREQ_RECV) { + BUG_ON(!qcc->nb_hreq); + --qcc->nb_hreq; + } + /* Release app-layer context. */ if (qcs->ctx && qcc->app_ops->detach) qcc->app_ops->detach(qcs); @@ -239,31 +244,12 @@ { BUG_ON(!qcc->nb_sc); /* Ensure sc count is always valid (ie >=0). */ --qcc->nb_sc; - - /* Reset qcc idle start for http-keep-alive timeout. Timeout will be - * refreshed after this on stream detach. - */ - if (!qcc->nb_sc && !qcc->nb_hreq) - qcc_reset_idle_start(qcc); -} - -/* Decrement <qcc> hreq. */ -static forceinline void qcc_rm_hreq(struct qcc *qcc) -{ - BUG_ON(!qcc->nb_hreq); /* Ensure http req count is always valid (ie >=0). */ - --qcc->nb_hreq; - - /* Reset qcc idle start for http-keep-alive timeout. Timeout will be - * refreshed after this on I/O handler. - */ - if (!qcc->nb_sc && !qcc->nb_hreq) - qcc_reset_idle_start(qcc); } static inline int qcc_is_dead(const struct qcc *qcc) { - /* Maintain connection if stream endpoints are still active. */ - if (qcc->nb_sc) + /* Maintain connection if there is still request streams active. */ + if (qcc->nb_hreq) return 0; /* Connection considered dead if either : @@ -421,9 +407,6 @@ if (quic_stream_is_bidi(qcs->id)) { qcs->st = (qcs->st == QC_SS_HREM) ? QC_SS_CLO : QC_SS_HLOC; - - if (qcs->flags & QC_SF_HREQ_RECV) - qcc_rm_hreq(qcs->qcc); } else { /* Only local uni streams are valid for this operation. */ @@ -960,13 +943,9 @@ return -1; } - /* QC_SF_HREQ_RECV must be set once for a stream. Else, nb_hreq counter - * will be incorrect for the connection. - */ - BUG_ON_HOT(qcs->flags & QC_SF_HREQ_RECV); - qcs->flags |= QC_SF_HREQ_RECV; + /* QCS must be identified as request stream prior to stconn instantiation. */ + BUG_ON(!(qcs->flags & QC_SF_HREQ_RECV)); ++qcc->nb_sc; - ++qcc->nb_hreq; ++qcc->tot_sc; /* TODO duplicated from mux_h2 */ @@ -2377,6 +2356,12 @@ qcs_free(qcs); + /* Rearm http-keep-alive timeout when last request stream is freed. */ + if (!conn_is_back(qcc->conn) && qcc_may_expire(qcc) && !qcc->nb_hreq) { + qcc_reset_idle_start(qcc); + qcc_refresh_timeout(qcc); + } + TRACE_LEAVE(QMUX_EV_QCS_END, conn); } @@ -3098,12 +3083,12 @@ /* Proceed on receiving. Loop on streams subscribed in recv_list and performed * STREAM frames decoding upon them. * - * Returns 0 on success else non-zero. + * Returns the number of newly transcoded bytes. */ static int qcc_io_recv(struct qcc *qcc) { struct qcs *qcs; - int ret; + int total = 0, ret; TRACE_ENTER(QMUX_EV_QCC_RECV, qcc->conn); @@ -3127,12 +3112,13 @@ if (ret <= 0) goto done; + total += ret; } } done: TRACE_LEAVE(QMUX_EV_QCC_RECV, qcc->conn); - return 0; + return total; } /* Calculate the number of bidirectional streams which can still be opened for @@ -3155,9 +3141,11 @@ ret = MIN(ret, max_reuse); } - /* Ensure we do not exceed the maximum usable stream ID. */ - if (unlikely(ret > QCS_ID_MAX_STRM_CL_BIDI - qcc->next_bidi_l)) - ret = QCS_ID_MAX_STRM_CL_BIDI - qcc->next_bidi_l; + /* Do not exceed maximum usable stream ID. To simplify the calcul, + * limit is only applied when one or zero stream remains. + */ + if (ret && unlikely(qcc->next_bidi_l >= QCS_ID_MAX_STRM_CL_BIDI)) + ret = qcc->next_bidi_l == QCS_ID_MAX_STRM_CL_BIDI ? 1 : 0; return ret; } @@ -3400,7 +3388,7 @@ { struct qcc *qcc = ctx; struct connection *conn; - int conn_in_list; + int total = 0, conn_in_list; if (state & TASK_F_USR1) { /* the tasklet was idling on an idle connection, it might have @@ -3448,16 +3436,17 @@ } if (!(qcc->wait_event.events & SUB_RETRY_SEND)) - qcc_io_send(qcc); + total += qcc_io_send(qcc); - qcc_io_recv(qcc); + total += qcc_io_recv(qcc); if (qcc_io_process(qcc)) { TRACE_STATE("releasing dead connection", QMUX_EV_QCC_WAKE, conn); goto release; } - qcc_refresh_timeout(qcc); + if (total) + qcc_refresh_timeout(qcc); /* Trigger pacing task is emission should be retried after some delay. */ if (qcc_is_pacing_active(conn)) { @@ -3580,11 +3569,9 @@ * shutdown should occurs. For all other cases, an immediate close * seems legitimate. */ - if (qcc_is_dead(qcc)) { - TRACE_STATE("releasing dead connection", QMUX_EV_QCC_WAKE, qcc->conn); - qcc_shutdown(qcc); - qcc_release(qcc); - } + TRACE_STATE("releasing dead connection", QMUX_EV_QCC_WAKE, qcc->conn); + qcc_shutdown(qcc); + qcc_release(qcc); out: TRACE_LEAVE(QMUX_EV_QCC_WAKE); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/src/server.c new/haproxy-3.3.10+git0.0a72d7f9f/src/server.c --- old/haproxy-3.3.9+git0.aa6f85a2f/src/server.c 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/src/server.c 2026-05-11 17:09:08.000000000 +0200 @@ -6007,7 +6007,8 @@ * failed to queue itself when brought up, which could happen if * a memory allocation failed. */ - tasklet_wakeup(t); + if (srv->cur_state != SRV_ST_STOPPED) + tasklet_wakeup(t); return ERR_NONE; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/src/ssl_sock.c new/haproxy-3.3.10+git0.0a72d7f9f/src/ssl_sock.c --- old/haproxy-3.3.9+git0.aa6f85a2f/src/ssl_sock.c 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/src/ssl_sock.c 2026-05-11 17:09:08.000000000 +0200 @@ -6653,9 +6653,7 @@ info.info.cipher_type = known_ciphers[i].tls_cipher; if (is_tls_12) { - unsigned char iv[iv_size]; int block_key_size = 2 * key_size + 2 * salt_size; - int i; /* * We may have to increase buf size if new ciphers are @@ -6687,10 +6685,9 @@ */ seq = SSL_get_read_sequence(ssl); seq = my_htonll(seq); - for (i = 0; i < iv_size; i++) - iv[i] = (unsigned char)statistical_prng_range(256); - /* IV */ - memcpy(&info.buf[0], &iv, iv_size); + + /* Use the sequence number as the explicit nonce */ + memcpy(&info.buf[0], &seq, iv_size); if (!conn_is_back(ctx->conn)) { /* Key */ @@ -6714,9 +6711,8 @@ */ seq = SSL_get_write_sequence(ssl); seq = my_htonll(seq); - for (i = 0; i < iv_size; i++) - iv[i] = (unsigned char)statistical_prng_range(256); - memcpy(&info.buf[0], &iv, iv_size); + /* Use the sequence number as the explicit nonce */ + memcpy(&info.buf[0], &seq, iv_size); if (!conn_is_back(ctx->conn)) { /* Key */ memcpy(&info.buf[iv_size], &buf[key_size], key_size); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/haproxy-3.3.9+git0.aa6f85a2f/src/stick_table.c new/haproxy-3.3.10+git0.0a72d7f9f/src/stick_table.c --- old/haproxy-3.3.9+git0.aa6f85a2f/src/stick_table.c 2026-05-06 17:30:17.000000000 +0200 +++ new/haproxy-3.3.10+git0.0a72d7f9f/src/stick_table.c 2026-05-11 17:09:08.000000000 +0200 @@ -5702,6 +5702,10 @@ return 0; } + /* only "show" is permitted to level user, others (clear/set) require "oper" */ + if (ctx->action != STK_CLI_ACT_SHOW && !cli_has_level(appctx, ACCESS_LVL_OPER)) + return 1; + if (strcmp(args[3], "key") == 0) return table_process_entry_per_key(appctx, args); if (strcmp(args[3], "ptr") == 0)
