diff --git a/changelog.md b/changelog.md index fa83702..68c2ecb 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,11 @@ # Changelog +## 2026-03-16 - 4.6.1 - fix(remoteingress-core) +avoid spurious tunnel disconnect events and increase control channel capacity + +- Emit TunnelDisconnected only after an established connection is actually lost, preventing false disconnect events during failed reconnect attempts. +- Increase edge and hub control-channel buffer sizes from 64 to 256 to better prioritize control frames under load. + ## 2026-03-16 - 4.6.0 - feat(remoteingress-core) add adaptive per-stream flow control based on active stream counts diff --git a/rust/crates/remoteingress-core/src/edge.rs b/rust/crates/remoteingress-core/src/edge.rs index 157bf98..9ddd2aa 100644 --- a/rust/crates/remoteingress-core/src/edge.rs +++ b/rust/crates/remoteingress-core/src/edge.rs @@ -232,7 +232,11 @@ async fn edge_main_loop( } *connected.write().await = false; - let _ = event_tx.try_send(EdgeEvent::TunnelDisconnected); + // Only emit disconnect event on actual disconnection, not on failed reconnects. + // Failed reconnects never reach line 335 (handshake success), so was_connected is false. + if was_connected { + let _ = event_tx.try_send(EdgeEvent::TunnelDisconnected); + } active_streams.store(0, Ordering::Relaxed); // Reset stream ID counter for next connection cycle next_stream_id.store(1, Ordering::Relaxed); @@ -375,7 +379,7 @@ async fn connect_to_hub_and_run( // QoS dual-channel tunnel writer: control frames (PONG/WINDOW_UPDATE/CLOSE/OPEN) // have priority over data frames (DATA). Prevents PING starvation under load. - let (tunnel_ctrl_tx, mut tunnel_ctrl_rx) = mpsc::channel::>(64); + let (tunnel_ctrl_tx, mut tunnel_ctrl_rx) = mpsc::channel::>(256); let (tunnel_data_tx, mut tunnel_data_rx) = mpsc::channel::>(4096); // Legacy alias — control channel for PONG, CLOSE, WINDOW_UPDATE, OPEN let tunnel_writer_tx = tunnel_ctrl_tx.clone(); diff --git a/rust/crates/remoteingress-core/src/hub.rs b/rust/crates/remoteingress-core/src/hub.rs index 205af89..10c9acd 100644 --- a/rust/crates/remoteingress-core/src/hub.rs +++ b/rust/crates/remoteingress-core/src/hub.rs @@ -378,7 +378,7 @@ async fn handle_edge_connection( // QoS dual-channel tunnel writer: control frames (PING/PONG/WINDOW_UPDATE/CLOSE) // have priority over data frames (DATA_BACK). This prevents PING starvation under load. - let (ctrl_tx, mut ctrl_rx) = mpsc::channel::>(64); + let (ctrl_tx, mut ctrl_rx) = mpsc::channel::>(256); let (data_tx, mut data_rx) = mpsc::channel::>(4096); // Legacy alias for code that sends both control and data (will be migrated) let frame_writer_tx = ctrl_tx.clone(); diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index bb827b8..e2b2e05 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@serve.zone/remoteingress', - version: '4.6.0', + version: '4.6.1', description: 'Edge ingress tunnel for DcRouter - accepts incoming TCP connections at network edge and tunnels them to DcRouter SmartProxy preserving client IP via PROXY protocol v1.' }