From 1386a49a99e375ea35f3ab782431cc3d2a67fa7c Mon Sep 17 00:00:00 2001 From: durch Date: Tue, 16 Dec 2025 20:22:29 +0100 Subject: [PATCH] Add forward_timeout to LP client config Add forward_timeout (30s default) to LpConfig and wrap send_forward_packet's connect_send_receive call with tokio::time::timeout, matching the pattern used by register() with registration_timeout. This prevents indefinite hangs when forwarding packets through entry gateway. --- .../src/lp_client/client.rs | 25 +++++++++++++------ .../src/lp_client/config.rs | 10 ++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/nym-registration-client/src/lp_client/client.rs b/nym-registration-client/src/lp_client/client.rs index 251d83df00..e20795fd33 100644 --- a/nym-registration-client/src/lp_client/client.rs +++ b/nym-registration-client/src/lp_client/client.rs @@ -838,15 +838,24 @@ impl LpRegistrationClient { .ok() .and_then(|s| s.outer_aead_key()); - // 5. Send and receive on fresh connection - let response_packet = Self::connect_send_receive( - self.gateway_lp_address, - &forward_packet, - send_key.as_ref(), - recv_key.as_ref(), - &self.config, + // 5. Send and receive on fresh connection with timeout + let response_packet = tokio::time::timeout( + self.config.forward_timeout, + Self::connect_send_receive( + self.gateway_lp_address, + &forward_packet, + send_key.as_ref(), + recv_key.as_ref(), + &self.config, + ), ) - .await?; + .await + .map_err(|_| { + LpClientError::Transport(format!( + "Forward packet timeout after {:?}", + self.config.forward_timeout + )) + })??; tracing::trace!("Received response packet from entry gateway"); // 6. Decrypt via state machine diff --git a/nym-registration-client/src/lp_client/config.rs b/nym-registration-client/src/lp_client/config.rs index 0d18a0299a..def4ca8f97 100644 --- a/nym-registration-client/src/lp_client/config.rs +++ b/nym-registration-client/src/lp_client/config.rs @@ -16,6 +16,7 @@ use std::time::Duration; /// - `connect_timeout`: 10 seconds - reasonable for real network conditions /// - `handshake_timeout`: 15 seconds - allows for Noise handshake round-trips /// - `registration_timeout`: 30 seconds - includes credential verification and response +/// - `forward_timeout`: 30 seconds - forward packet send/receive to exit gateway /// - `tcp_nodelay`: true - lower latency for small registration messages /// - `tcp_keepalive`: None - not needed for short-lived registration connections /// @@ -46,6 +47,13 @@ pub struct LpConfig { /// Default: 30 seconds. pub registration_timeout: Duration, + /// Forward packet send/receive timeout. + /// + /// Maximum time to wait for forward packet send + response receive via entry gateway. + /// Covers the entire round-trip through entry to exit gateway and back. + /// Default: 30 seconds. + pub forward_timeout: Duration, + /// Enable TCP_NODELAY (disable Nagle's algorithm) (nym-104). /// /// When true, disables Nagle's algorithm for lower latency. @@ -68,6 +76,7 @@ impl Default for LpConfig { connect_timeout: Duration::from_secs(10), handshake_timeout: Duration::from_secs(15), registration_timeout: Duration::from_secs(30), + forward_timeout: Duration::from_secs(30), // nym-104: Optimized for registration-only protocol tcp_nodelay: true, // Lower latency for small messages @@ -87,6 +96,7 @@ mod tests { assert_eq!(config.connect_timeout, Duration::from_secs(10)); assert_eq!(config.handshake_timeout, Duration::from_secs(15)); assert_eq!(config.registration_timeout, Duration::from_secs(30)); + assert_eq!(config.forward_timeout, Duration::from_secs(30)); assert!(config.tcp_nodelay); assert_eq!(config.tcp_keepalive, None); }