This is an automated email from the ASF dual-hosted git repository. hubcio pushed a commit to branch feat/iggy-server-hardening in repository https://gitbox.apache.org/repos/asf/iggy.git
commit 9ce4dd0fa90c1440ec299d94cdde5f0d9c05aa45 Author: Hubert Gruszecki <[email protected]> AuthorDate: Fri Jul 24 18:29:10 2026 +0200 fix(server-ng): source TLS grace from config, align listener backlog The HTTP-TLS accept path pinned its handshake grace in a local const that duplicated message_bus.handshake_grace, so raising the configured grace silently left HTTP handshakes on the stale 10s budget. Thread the bus value through the accept pump instead and drop the const; identical at defaults. The client listener also capped its accept backlog at 128 while the replica listener uses SOMAXCONN; align them, the kernel clamps to net.core.somaxconn either way. Drop the dead per-replica connection-count const while here. --- core/message_bus/src/cache/connection.rs | 2 -- core/message_bus/src/client_listener/mod.rs | 2 +- core/server-ng/src/http.rs | 8 ++++++-- core/server-ng/src/http/tls.rs | 29 +++++++++++++++++++---------- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/core/message_bus/src/cache/connection.rs b/core/message_bus/src/cache/connection.rs index f4373f7d3..8aded4271 100644 --- a/core/message_bus/src/cache/connection.rs +++ b/core/message_bus/src/cache/connection.rs @@ -22,8 +22,6 @@ use rand::seq::SliceRandom; use std::cell::{Cell, RefCell}; use std::collections::{HashMap, HashSet}; -pub const DEFAULT_MAX_CONNECTIONS_PER_REPLICA: usize = 8; - pub trait ShardedState { type Entry; type Delta; diff --git a/core/message_bus/src/client_listener/mod.rs b/core/message_bus/src/client_listener/mod.rs index 2503be876..8c65a6a16 100644 --- a/core/message_bus/src/client_listener/mod.rs +++ b/core/message_bus/src/client_listener/mod.rs @@ -130,7 +130,7 @@ pub async fn bind_nodelay_listener( .await .map_err(|_| IggyError::CannotBindToSocket(addr.to_string()))?; let listener = socket - .listen(128) + .listen(libc::SOMAXCONN) .await .map_err(|_| IggyError::CannotBindToSocket(addr.to_string()))?; let actual = listener diff --git a/core/server-ng/src/http.rs b/core/server-ng/src/http.rs index 423b5d58d..b13b845e2 100644 --- a/core/server-ng/src/http.rs +++ b/core/server-ng/src/http.rs @@ -146,8 +146,12 @@ pub async fn start( if http_config.tls.enabled { let server_config = tls::load_http_tls_server_config(&http_config.tls)?; - let (connections, pump) = - tls::spawn_accept_pump(listener, server_config, shard.bus.token()); + let (connections, pump) = tls::spawn_accept_pump( + listener, + server_config, + shard.bus.config().handshake_grace, + shard.bus.token(), + ); shard.bus.track_background(pump); info!(address = %bound_addr, "server-ng HTTPS listener started"); let handle = compio::runtime::spawn(tls::serve(connections, router, shard.bus.token())); diff --git a/core/server-ng/src/http/tls.rs b/core/server-ng/src/http/tls.rs index dd974c897..830e79d22 100644 --- a/core/server-ng/src/http/tls.rs +++ b/core/server-ng/src/http/tls.rs @@ -65,11 +65,6 @@ use crate::server_error::ServerNgError; const ALPN_H2: &[u8] = b"h2"; const ALPN_HTTP11: &[u8] = b"http/1.1"; -/// Handshake wall-clock bound for the accept pump. The HTTP listener has no -/// `MessageBusConfig` to source it from, so it mirrors the binary -/// transports' `DEFAULT_HANDSHAKE_GRACE` directly. -const HTTP_TLS_HANDSHAKE_GRACE: Duration = Duration::from_secs(10); - /// Depth of the handshaken-connection channel between the accept pump and /// the serve loop. The serve loop drains one per accept and immediately /// spawns a per-connection hyper task, so it rarely fills; the bound keeps @@ -101,16 +96,26 @@ pub fn load_http_tls_server_config( /// Bind the accept pump: build the acceptor, spawn the pump task, and hand /// back the handshaken-connection receiver for [`serve`] plus the pump's -/// join handle for the caller to track. +/// join handle for the caller to track. `handshake_grace` bounds each +/// connection's TLS handshake; the caller sources it from +/// `MessageBusConfig::handshake_grace` so the HTTPS listener shares the same +/// slowloris budget as the binary transports. pub fn spawn_accept_pump( listener: TcpListener, config: Arc<rustls::ServerConfig>, + handshake_grace: Duration, shutdown: ShutdownToken, ) -> (Receiver<Handshaken>, JoinHandle<()>) { let (connections_tx, connections_rx) = async_channel::bounded::<Handshaken>(ACCEPT_CHANNEL_DEPTH); let acceptor = TlsAcceptor::from(config); - let pump = compio::runtime::spawn(accept_pump(listener, acceptor, connections_tx, shutdown)); + let pump = compio::runtime::spawn(accept_pump( + listener, + acceptor, + connections_tx, + handshake_grace, + shutdown, + )); (connections_rx, pump) } @@ -205,6 +210,7 @@ async fn accept_pump( listener: TcpListener, acceptor: TlsAcceptor, connections: Sender<Handshaken>, + handshake_grace: Duration, shutdown: ShutdownToken, ) { loop { @@ -214,7 +220,9 @@ async fn accept_pump( break; } result = listener.accept().fuse() => match result { - Ok((stream, peer)) => spawn_handshake(&acceptor, &connections, stream, peer), + Ok((stream, peer)) => { + spawn_handshake(&acceptor, &connections, handshake_grace, stream, peer); + } Err(error) => error!(%error, "server-ng HTTPS accept failed"), }, } @@ -228,13 +236,14 @@ async fn accept_pump( fn spawn_handshake( acceptor: &TlsAcceptor, connections: &Sender<Handshaken>, + handshake_grace: Duration, stream: TcpStream, peer: SocketAddr, ) { let acceptor = acceptor.clone(); let connections = connections.clone(); compio::runtime::spawn(async move { - match compio::time::timeout(HTTP_TLS_HANDSHAKE_GRACE, acceptor.accept(stream)).await { + match compio::time::timeout(handshake_grace, acceptor.accept(stream)).await { Ok(Ok(tls)) => { // Drop on send error: the channel is closed only at // shutdown, when the serve loop is already tearing down. @@ -242,7 +251,7 @@ fn spawn_handshake( } Ok(Err(error)) => debug!(%peer, %error, "server-ng HTTPS handshake failed"), Err(_elapsed) => { - debug!(%peer, grace = ?HTTP_TLS_HANDSHAKE_GRACE, "server-ng HTTPS handshake timed out"); + debug!(%peer, grace = ?handshake_grace, "server-ng HTTPS handshake timed out"); } } })
