diff --git a/common/nym-kkt/src/error.rs b/common/nym-kkt/src/error.rs index 0a733d572d..14511b1edb 100644 --- a/common/nym-kkt/src/error.rs +++ b/common/nym-kkt/src/error.rs @@ -16,28 +16,28 @@ pub enum KKTError { #[error(transparent)] MaskedByteError(#[from] MaskedByteError), - #[error("KEM mapping failure: {}", info)] + #[error("KEM mapping failure: {info}")] KEMMapping { info: &'static str }, #[error("Insecure Encapsulation Key Hash Length")] InsecureHashLen, - #[error("KKT Frame Decoding Error: {}", info)] + #[error("KKT Frame Decoding Error: {info}")] FrameDecodingError { info: String }, - #[error("KKT Frame Encoding Error: {}", info)] + #[error("KKT Frame Encoding Error: {info}")] FrameEncodingError { info: String }, - #[error("KKT Incompatibility Error: {}", info)] + #[error("KKT Incompatibility Error: {info}")] IncompatibilityError { info: &'static str }, - #[error("KKT Responder Flagged Error: {}", status)] + #[error("KKT Responder Flagged Error: {status}")] ResponderFlaggedError { status: KKTStatus }, - #[error("PSQ KEM Error: {}", info)] + #[error("PSQ KEM Error: {info}")] KEMError { info: &'static str }, - #[error("Local Function Input Error: {}", info)] + #[error("Local Function Input Error: {info}")] FunctionInputError { info: &'static str }, #[error("{info}")] diff --git a/nym-registration-client/src/lp_client/client.rs b/nym-registration-client/src/lp_client/client.rs index b770134d96..7eae1652c7 100644 --- a/nym-registration-client/src/lp_client/client.rs +++ b/nym-registration-client/src/lp_client/client.rs @@ -503,7 +503,7 @@ where /// sends the registration request, and receives the response /// on the same underlying connection. /// Do note that this method does **not** perform retries on network failures, - /// for that please use [`Self::register_with_retry`] instead + /// for that please use [`Self::handshake_and_register_with_retry`] instead /// /// # Arguments /// * `rng` - RNG instance for generating PSK @@ -631,7 +631,7 @@ where /// # Note /// Unlike `register()`, this method handles the full flow including handshake. /// Do NOT call `perform_handshake()` before this method. - pub async fn register_with_retry( + pub async fn handshake_and_register_with_retry( &mut self, rng: &mut R, wg_keypair: &x25519::KeyPair, @@ -645,6 +645,7 @@ where { tracing::debug!("Starting resilient registration (max_retries={max_retries})",); + // attempt to perform handshake with retries let mut last_error = None; for attempt in 0..=max_retries { let attempt_display = attempt + 1; @@ -671,33 +672,23 @@ where continue; } } - - match self - .register_dvpn( - rng, - wg_keypair, - gateway_identity, - bandwidth_controller, - ticket_type, - ) - .await - { - Ok(data) => { - if attempt > 0 { - tracing::info!("Registration succeeded on retry attempt {attempt_display}"); - } - return Ok(data); - } - Err(e) => { - tracing::warn!("Registration attempt {attempt_display} failed: {e}"); - last_error = Some(e); - } - } } - Err(last_error.unwrap_or(LpClientError::RegistrationFailure { - message: "Registration failed after all retries".to_string(), - })) + if self.transport_session.is_none() { + return Err(last_error.unwrap_or(LpClientError::RegistrationFailure { + message: "Registration failed after all retries".to_string(), + })); + } + + self.register_dvpn( + rng, + wg_keypair, + gateway_identity, + bandwidth_controller, + ticket_type, + ) + .await + .inspect_err(|e| tracing::warn!("Registration failed: {e}")) } /// Get the LP session ID (receiver_idx) for this client. diff --git a/nym-registration-client/src/lp_client/nested_session/mod.rs b/nym-registration-client/src/lp_client/nested_session/mod.rs index a1e3002976..c1eeb39207 100644 --- a/nym-registration-client/src/lp_client/nested_session/mod.rs +++ b/nym-registration-client/src/lp_client/nested_session/mod.rs @@ -284,7 +284,7 @@ impl NestedLpSession { LpDvpnRegistrationResponseMessageContent::RegistrationFailure(res) => { let reason = res.error; // the registration has failed - tracing::warn!("Gateway rejected registration: {reason}"); + warn!("Gateway rejected registration: {reason}"); Err(LpClientError::RegistrationRejected { reason }) } LpDvpnRegistrationResponseMessageContent::CompletedRegistration(res) => Ok(res.config), @@ -379,7 +379,7 @@ impl NestedLpSession { LpDvpnRegistrationResponseMessageContent::RegistrationFailure(res) => { let reason = res.error; // the registration has failed - tracing::warn!("Gateway rejected registration: {reason}"); + warn!("Gateway rejected registration: {reason}"); return Err(LpClientError::RegistrationRejected { reason }); } LpDvpnRegistrationResponseMessageContent::CompletedRegistration(res) => res.config, @@ -434,7 +434,7 @@ impl NestedLpSession { /// - Forwarding through entry gateway fails /// - Response decryption/deserialization fails /// - Gateway rejects the registration - pub(crate) async fn handshake_and_register_dvpn( + pub async fn handshake_and_register_dvpn( &mut self, outer_client: &mut LpRegistrationClient, rng: &mut R, @@ -509,8 +509,11 @@ impl NestedLpSession { max_retries ); + // attempt to perform handshake with retries let mut last_error = None; for attempt in 0..=max_retries { + let attempt_display = attempt + 1; + if attempt > 0 { // Verify outer session is still usable before retry if !outer_client.is_handshake_complete() { @@ -524,45 +527,36 @@ impl NestedLpSession { let jitter_ms: u64 = rand09::rng().random_range(0..(base_delay_ms / 4 + 1)); let delay = std::time::Duration::from_millis(base_delay_ms + jitter_ms); tracing::info!( - "Retrying exit registration (attempt {}) after {:?}", - attempt + 1, - delay + "Retrying exit registration (attempt {attempt_display}) after {delay:?}", ); tokio::time::sleep(delay).await; // Clear state machine before retry - handshake needs fresh start self.transport_session = None; - } - match self - .handshake_and_register_dvpn( - outer_client, - rng, - wg_keypair, - gateway_identity, - bandwidth_controller, - ticket_type, - ) - .await - { - Ok(data) => { - if attempt > 0 { - tracing::info!( - "Exit registration succeeded on retry attempt {}", - attempt + 1 - ); - } - return Ok(data); - } - Err(e) => { - tracing::warn!("Exit registration attempt {} failed: {}", attempt + 1, e); + if let Err(e) = self.perform_handshake(outer_client).await { + warn!("Handshake failed on attempt {attempt_display}: {e}"); last_error = Some(e); + continue; } } } - Err(last_error.unwrap_or(LpClientError::RegistrationFailure { - message: "Exit Registration failed after all retries".to_string(), - })) + if self.transport_session.is_none() { + return Err(last_error.unwrap_or(LpClientError::RegistrationFailure { + message: "Exit Registration failed after all retries".to_string(), + })); + } + + self.register_dvpn( + outer_client, + rng, + wg_keypair, + gateway_identity, + bandwidth_controller, + ticket_type, + ) + .await + .inspect_err(|e| warn!("Exit Registration failed: {e}")) } }