From 1ddbb970d092dd607bd060eb63a5e97f29dd1781 Mon Sep 17 00:00:00 2001 From: Georgio Nicolas Date: Thu, 26 Feb 2026 20:55:27 +0100 Subject: [PATCH] Change receiver index to u32 and regorganize crates --- Cargo.lock | 35 ---------------- Cargo.toml | 4 +- common/nym-lp-common/Cargo.toml | 8 ---- common/nym-lp-packet/Cargo.toml | 24 ----------- common/nym-lp-transport/Cargo.toml | 30 ------------- common/nym-lp/Cargo.toml | 8 ++-- common/nym-lp/src/codec.rs | 6 +-- common/nym-lp/src/error.rs | 21 +++++----- common/nym-lp/src/lib.rs | 13 +++--- .../src => nym-lp/src/packet}/error.rs | 0 .../src => nym-lp/src/packet}/header.rs | 26 ++++++------ .../src => nym-lp/src/packet}/message.rs | 4 +- .../src/lib.rs => nym-lp/src/packet/mod.rs} | 13 ++++++ .../src => nym-lp/src/packet}/packet.rs | 7 ++-- .../src/{packet.rs => packet/replay.rs} | 19 +-------- .../src/lib.rs => nym-lp/src/packet/utils.rs} | 6 +-- common/nym-lp/src/peer_config.rs | 8 ++-- common/nym-lp/src/psq/handshake_message.rs | 3 +- common/nym-lp/src/psq/initiator.rs | 2 +- common/nym-lp/src/psq/mod.rs | 4 +- common/nym-lp/src/psq/responder.rs | 2 +- common/nym-lp/src/session.rs | 13 +++--- common/nym-lp/src/session_integration/mod.rs | 2 +- common/nym-lp/src/session_manager.rs | 42 +++++++++++-------- common/nym-lp/src/state_machine.rs | 5 ++- .../src => nym-lp/src/transport}/error.rs | 0 .../lib.rs => nym-lp/src/transport/mod.rs} | 0 .../src => nym-lp/src/transport}/traits.rs | 12 +++--- gateway/Cargo.toml | 2 + .../wireguard/new_peer_registration/lp.rs | 5 ++- .../wireguard/new_peer_registration/mod.rs | 5 ++- .../new_peer_registration/pending.rs | 10 +++-- integration-tests/Cargo.toml | 3 +- nym-node/Cargo.toml | 1 - nym-node/src/node/lp/data_handler.rs | 2 +- nym-node/src/node/lp/error.rs | 12 +++--- nym-node/src/node/lp/handler.rs | 25 ++++++----- nym-node/src/node/lp/mod.rs | 11 +++-- nym-node/src/node/lp/registration.rs | 10 ++--- nym-registration-client/Cargo.toml | 1 - .../src/lp_client/client.rs | 11 ++--- .../src/lp_client/error.rs | 5 ++- .../src/lp_client/helpers.rs | 2 +- .../lp_client/nested_session/connection.rs | 7 ++-- .../src/lp_client/nested_session/mod.rs | 7 ++-- .../src/lp_client/state_machine_helpers.rs | 2 +- 46 files changed, 173 insertions(+), 265 deletions(-) delete mode 100644 common/nym-lp-common/Cargo.toml delete mode 100644 common/nym-lp-packet/Cargo.toml delete mode 100644 common/nym-lp-transport/Cargo.toml rename common/{nym-lp-packet/src => nym-lp/src/packet}/error.rs (100%) rename common/{nym-lp-packet/src => nym-lp/src/packet}/header.rs (85%) rename common/{nym-lp-packet/src => nym-lp/src/packet}/message.rs (99%) rename common/{nym-lp-packet/src/lib.rs => nym-lp/src/packet/mod.rs} (56%) rename common/{nym-lp-packet/src => nym-lp/src/packet}/packet.rs (91%) rename common/nym-lp/src/{packet.rs => packet/replay.rs} (69%) rename common/{nym-lp-common/src/lib.rs => nym-lp/src/packet/utils.rs} (84%) rename common/{nym-lp-transport/src => nym-lp/src/transport}/error.rs (100%) rename common/{nym-lp-transport/src/lib.rs => nym-lp/src/transport/mod.rs} (100%) rename common/{nym-lp-transport/src => nym-lp/src/transport}/traits.rs (97%) diff --git a/Cargo.lock b/Cargo.lock index c4ca3f07e9..8f6e059831 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4124,7 +4124,6 @@ dependencies = [ "nym-kkt", "nym-kkt-ciphersuite", "nym-lp", - "nym-lp-transport", "nym-node", "nym-registration-client", "nym-test-utils", @@ -6886,9 +6885,6 @@ dependencies = [ "nym-crypto", "nym-kkt", "nym-kkt-ciphersuite", - "nym-lp-common", - "nym-lp-packet", - "nym-lp-transport", "nym-test-utils", "rand 0.9.2", "thiserror 2.0.12", @@ -6934,35 +6930,6 @@ dependencies = [ "url", ] -[[package]] -name = "nym-lp-common" -version = "0.1.0" - -[[package]] -name = "nym-lp-packet" -version = "1.20.4" -dependencies = [ - "bytes", - "num_enum", - "nym-crypto", - "nym-lp-common", - "thiserror 2.0.12", - "tracing", -] - -[[package]] -name = "nym-lp-transport" -version = "0.1.0" -dependencies = [ - "nym-kkt-ciphersuite", - "nym-kkt-context", - "nym-lp-packet", - "nym-test-utils", - "thiserror 2.0.12", - "tokio", - "tracing", -] - [[package]] name = "nym-metrics" version = "1.20.4" @@ -7201,7 +7168,6 @@ dependencies = [ "nym-ip-packet-router", "nym-kkt", "nym-lp", - "nym-lp-transport", "nym-metrics", "nym-mixnet-client", "nym-network-requester", @@ -7561,7 +7527,6 @@ dependencies = [ "nym-ip-packet-client", "nym-kkt", "nym-lp", - "nym-lp-transport", "nym-registration-common", "nym-sdk", "nym-test-utils", diff --git a/Cargo.toml b/Cargo.toml index e3d94ce7e6..4f7ebfae70 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,7 +74,6 @@ members = [ "common/nym-id", "common/nym-kcp", "common/nym-lp", - "common/nym-lp-common", "common/nym-kkt", "common/nym-metrics", "common/nym_offline_compact_ecash", @@ -174,8 +173,7 @@ members = [ "wasm/zknym-lib", # "nym-gateway-probe", "integration-tests", - "common/nym-lp-transport", - "common/nym-kkt-ciphersuite", "common/nym-lp-packet", "common/nym-kkt-context", + "common/nym-kkt-ciphersuite", "common/nym-kkt-context", ] default-members = [ diff --git a/common/nym-lp-common/Cargo.toml b/common/nym-lp-common/Cargo.toml deleted file mode 100644 index b84b617154..0000000000 --- a/common/nym-lp-common/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "nym-lp-common" -version = "0.1.0" -edition = { workspace = true } -license = { workspace = true } -publish = false - -[dependencies] diff --git a/common/nym-lp-packet/Cargo.toml b/common/nym-lp-packet/Cargo.toml deleted file mode 100644 index 15c490f8ce..0000000000 --- a/common/nym-lp-packet/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "nym-lp-packet" -authors.workspace = true -repository.workspace = true -homepage.workspace = true -documentation.workspace = true -edition.workspace = true -license.workspace = true -rust-version.workspace = true -readme.workspace = true -version.workspace = true -publish = false - -[dependencies] -bytes = { workspace = true } -thiserror = { workspace = true } -num_enum = { workspace = true } -tracing = { workspace = true } - -nym-crypto = { workspace = true, features = ["asymmetric"] } -nym-lp-common = { path = "../nym-lp-common" } - -[lints] -workspace = true diff --git a/common/nym-lp-transport/Cargo.toml b/common/nym-lp-transport/Cargo.toml deleted file mode 100644 index 267128d2f8..0000000000 --- a/common/nym-lp-transport/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "nym-lp-transport" -version = "0.1.0" -authors.workspace = true -repository.workspace = true -homepage.workspace = true -documentation.workspace = true -edition.workspace = true -license.workspace = true -rust-version.workspace = true -readme.workspace = true -publish = false - -[dependencies] -thiserror = { workspace = true } -tokio = { workspace = true, features = ["net", "io-util"] } -tracing = { workspace = true } - -nym-lp-packet = { path = "../nym-lp-packet" } -nym-kkt-ciphersuite = { path = "../nym-kkt-ciphersuite" } -nym-kkt-context = { path = "../nym-kkt-context" } - - -nym-test-utils = { path = "../test-utils", optional = true } - -[features] -io-mocks = ["nym-test-utils"] - -[lints] -workspace = true diff --git a/common/nym-lp/Cargo.toml b/common/nym-lp/Cargo.toml index a69f0ab1d4..cbfaf75bbd 100644 --- a/common/nym-lp/Cargo.toml +++ b/common/nym-lp/Cargo.toml @@ -12,19 +12,18 @@ bytes = { workspace = true } tracing = { workspace = true } rand09 = { workspace = true } tls_codec = { workspace = true } +tokio = { workspace = true, features = ["net", "io-util"] } nym-crypto = { path = "../crypto", features = ["hashing"] } nym-kkt = { path = "../nym-kkt" } nym-kkt-ciphersuite = { workspace = true } -nym-lp-common = { path = "../nym-lp-common" } -nym-lp-transport = { path = "../nym-lp-transport" } -nym-lp-packet = { path = "../nym-lp-packet" } # libcrux dependencies for PSQ (Post-Quantum PSK derivation) libcrux-psq = { workspace = true, features = ["test-utils"] } num_enum = { workspace = true } zeroize = { workspace = true, features = ["zeroize_derive"] } + # needed for the 'mock 'feature nym-test-utils = { workspace = true, optional = true } @@ -33,7 +32,6 @@ criterion = { version = "0.5", features = ["html_reports"] } nym-test-utils = { workspace = true } anyhow = { workspace = true } tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } -nym-lp-transport = { path = "../nym-lp-transport", features = ["io-mocks"] } [features] @@ -41,4 +39,4 @@ mock = ["nym-test-utils"] [[bench]] name = "replay_protection" -harness = false +harness = false \ No newline at end of file diff --git a/common/nym-lp/src/codec.rs b/common/nym-lp/src/codec.rs index cce6a13e55..276df6c26a 100644 --- a/common/nym-lp/src/codec.rs +++ b/common/nym-lp/src/codec.rs @@ -1,10 +1,10 @@ // Copyright 2025 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::{LpError, LpMessage}; +use crate::LpError; +use crate::packet::{EncryptedLpPacket, InnerHeader, LpHeader, LpMessage, LpPacket}; use bytes::BytesMut; use libcrux_psq::Channel; -use nym_lp_packet::{EncryptedLpPacket, InnerHeader, LpHeader, LpPacket}; // needs to be equal or above to the actual overhead pub(crate) const SANE_ENC_OVERHEAD: usize = 32; @@ -82,12 +82,12 @@ pub(crate) fn decrypt_lp_packet( mod tests { use crate::LpError; use crate::codec::{decrypt_data, decrypt_lp_packet, encrypt_data, encrypt_lp_packet}; + use crate::packet::{EncryptedLpPacket, LpHeader, LpMessage, LpPacket, MessageType}; use crate::peer::mock_peers; use crate::psq::initiator::{build_psq_ciphersuite, build_psq_principal}; use crate::psq::{PSQ_MSG2_SIZE, psq_msg1_size, responder}; use libcrux_psq::{Channel, IntoSession}; use nym_kkt_ciphersuite::KEM; - use nym_lp_packet::{EncryptedLpPacket, LpHeader, LpMessage, LpPacket, MessageType}; use nym_test_utils::helpers::u64_seeded_rng_09; fn mock_transport() -> ( diff --git a/common/nym-lp/src/error.rs b/common/nym-lp/src/error.rs index 46883e4498..ff586d8b1f 100644 --- a/common/nym-lp/src/error.rs +++ b/common/nym-lp/src/error.rs @@ -1,15 +1,16 @@ // Copyright 2025 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::packet::MalformedLpPacketError; +use crate::peer_config::LpReceiverIndex; use crate::replay::ReplayError; +use crate::transport::LpTransportError; use libcrux_psq::handshake::HandshakeError; use libcrux_psq::handshake::builders::BuilderError; use libcrux_psq::session::SessionError; -use nym_crypto::asymmetric::ed25519::Ed25519RecoveryError; +// use nym_crypto::asymmetric::ed25519::Ed25519RecoveryError; use nym_kkt::error::KKTError; use nym_kkt_ciphersuite::{HashFunction, KEM}; -use nym_lp_packet::MalformedLpPacketError; -use nym_lp_transport::LpTransportError; use thiserror::Error; #[derive(Error, Debug)] @@ -27,7 +28,7 @@ pub enum LpError { SessionClosed, #[error("There already exists an LP session with receiver index {0}")] - DuplicateSessionId(u64), + DuplicateSessionId(LpReceiverIndex), #[error("Internal error: {0}")] Internal(String), @@ -46,7 +47,7 @@ pub enum LpError { /// Session ID from incoming packet does not match any known session. #[error("Received packet with unknown session ID: {0}")] - UnknownSessionId(u64), + UnknownSessionId(LpReceiverIndex), /// Invalid state transition attempt in the state machine. #[error("Invalid input '{input}' for current state '{state}'")] @@ -61,12 +62,12 @@ pub enum LpError { LpSessionProcessing, /// State machine not found. - #[error("State machine not found for lp_id: {lp_id}")] - StateMachineNotFound { lp_id: u64 }, + #[error("State machine not found for lp_id: {0}")] + StateMachineNotFound(LpReceiverIndex), - /// Ed25519 to X25519 conversion error. - #[error("Ed25519 key conversion error: {0}")] - Ed25519RecoveryError(#[from] Ed25519RecoveryError), + // /// Ed25519 to X25519 conversion error. + // #[error("Ed25519 key conversion error: {0}")] + // Ed25519RecoveryError(#[from] Ed25519RecoveryError), #[error("attempted to create an LP responder without providing a valid KEM keys")] ResponderWithMissingKEMKeys, diff --git a/common/nym-lp/src/lib.rs b/common/nym-lp/src/lib.rs index 06e4458ca2..7f2c80b404 100644 --- a/common/nym-lp/src/lib.rs +++ b/common/nym-lp/src/lib.rs @@ -12,16 +12,14 @@ pub mod session; mod session_integration; pub mod session_manager; pub mod state_machine; +pub mod transport; pub use error::LpError; pub use nym_kkt_ciphersuite::{ Ciphersuite, HashFunction, HashLength, KEM, KEMKeyDigests, SignatureScheme, }; -pub use nym_lp_packet::{ - EncryptedLpPacket, InnerHeader, LpHeader, LpMessage, LpPacket, MessageType, OuterHeader, - error::MalformedLpPacketError, - message::{ApplicationData, ExpectedResponseSize, ForwardPacketData}, -}; + +#[cfg(any(feature = "mock", test))] pub use replay::{ReceivingKeyCounterValidator, ReplayError}; pub use session::LpSession; pub use session_manager::SessionManager; @@ -49,7 +47,8 @@ pub struct SessionsMock { impl SessionsMock { pub fn mock_seeded_post_handshake(seed: u64, kem: KEM) -> SessionsMock { use crate::peer::mock_peers; - use nym_test_utils::helpers::RngCore09; + use crate::peer_config::LpReceiverIndex; + use rand09::Rng; let (init, resp) = mock_peers(); let resp_remote = resp.as_remote(); @@ -57,7 +56,7 @@ impl SessionsMock { let mut init_rng = u64_seeded_rng_09(seed); let resp_rng = u64_seeded_rng_09(seed + 1); - let receiver_index = init_rng.next_u64(); + let receiver_index: LpReceiverIndex = init_rng.random(); let kem_keys = resp.kem_keypairs.as_ref().unwrap(); diff --git a/common/nym-lp-packet/src/error.rs b/common/nym-lp/src/packet/error.rs similarity index 100% rename from common/nym-lp-packet/src/error.rs rename to common/nym-lp/src/packet/error.rs diff --git a/common/nym-lp-packet/src/header.rs b/common/nym-lp/src/packet/header.rs similarity index 85% rename from common/nym-lp-packet/src/header.rs rename to common/nym-lp/src/packet/header.rs index 37c86de9f5..fb4653efb8 100644 --- a/common/nym-lp-packet/src/header.rs +++ b/common/nym-lp/src/packet/header.rs @@ -1,27 +1,27 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::error::MalformedLpPacketError; -use crate::message::MessageType; -use crate::version; +use crate::packet::message::MessageType; +use crate::packet::version; +use crate::{packet::error::MalformedLpPacketError, peer_config::LpReceiverIndex}; use bytes::{BufMut, BytesMut}; +// use nym_lp::peer_config::LpReceiverIndex; use tracing::warn; /// Outer header (12 bytes) - always cleartext, used for routing. /// /// This is the first 12 bytes of every LP packet, containing only the fields /// needed for session lookup (receiver_idx) and replay protection (counter). -/// For encrypted packets, this is the AAD (additional authenticated data). #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct OuterHeader { - pub receiver_idx: u64, + pub receiver_idx: LpReceiverIndex, pub counter: u64, } impl OuterHeader { - pub const SIZE: usize = 16; // receiver_idx(8) + counter(8) + pub const SIZE: usize = 12; // receiver_idx(4) + counter(8) - pub fn new(receiver_idx: u64, counter: u64) -> Self { + pub fn new(receiver_idx: LpReceiverIndex, counter: u64) -> Self { Self { receiver_idx, counter, @@ -34,15 +34,15 @@ impl OuterHeader { } #[allow(clippy::unwrap_used)] Ok(Self { - receiver_idx: u64::from_le_bytes(src[0..8].try_into().unwrap()), - counter: u64::from_le_bytes(src[8..16].try_into().unwrap()), + receiver_idx: LpReceiverIndex::from_le_bytes(src[0..4].try_into().unwrap()), + counter: u64::from_le_bytes(src[4..12].try_into().unwrap()), }) } pub fn to_bytes(&self) -> [u8; Self::SIZE] { let mut bytes = [0u8; Self::SIZE]; - bytes[0..8].copy_from_slice(&self.receiver_idx.to_le_bytes()); - bytes[8..16].copy_from_slice(&self.counter.to_le_bytes()); + bytes[0..4].copy_from_slice(&self.receiver_idx.to_le_bytes()); + bytes[4..12].copy_from_slice(&self.counter.to_le_bytes()); bytes } @@ -130,7 +130,7 @@ pub struct LpHeader { impl LpHeader { pub fn new( - receiver_idx: u64, + receiver_idx: LpReceiverIndex, counter: u64, protocol_version: u8, message_type: MessageType, @@ -159,7 +159,7 @@ impl LpHeader { } /// Get the sender index from the header - pub fn receiver_idx(&self) -> u64 { + pub fn receiver_idx(&self) -> LpReceiverIndex { self.outer.receiver_idx } } diff --git a/common/nym-lp-packet/src/message.rs b/common/nym-lp/src/packet/message.rs similarity index 99% rename from common/nym-lp-packet/src/message.rs rename to common/nym-lp/src/packet/message.rs index 870c48c7fc..84574d1b93 100644 --- a/common/nym-lp-packet/src/message.rs +++ b/common/nym-lp/src/packet/message.rs @@ -1,7 +1,7 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::error::MalformedLpPacketError; +use crate::packet::error::MalformedLpPacketError; use bytes::{BufMut, BytesMut}; use num_enum::{IntoPrimitive, TryFromPrimitive}; use std::fmt; @@ -418,7 +418,7 @@ impl EnsureEmptyContent for &[u8] { #[cfg(test)] mod tests { use super::*; - use crate::{InnerHeader, LpHeader, LpPacket, OuterHeader}; + use crate::packet::{InnerHeader, LpHeader, LpPacket, OuterHeader}; #[test] fn encoding() { diff --git a/common/nym-lp-packet/src/lib.rs b/common/nym-lp/src/packet/mod.rs similarity index 56% rename from common/nym-lp-packet/src/lib.rs rename to common/nym-lp/src/packet/mod.rs index 39ce837dd2..4c52553227 100644 --- a/common/nym-lp-packet/src/lib.rs +++ b/common/nym-lp/src/packet/mod.rs @@ -5,6 +5,8 @@ pub mod error; pub mod header; pub mod message; pub mod packet; +pub mod replay; +pub mod utils; pub use error::MalformedLpPacketError; pub use header::{InnerHeader, LpHeader, OuterHeader}; @@ -15,3 +17,14 @@ pub mod version { /// The current version of the Lewes Protocol that is put into each new constructed header. pub const CURRENT: u8 = 1; } + +#[allow(dead_code)] +pub(crate) const UDP_HEADER_LEN: usize = 8; +#[allow(dead_code)] +pub(crate) const IP_HEADER_LEN: usize = 40; // v4 - 20, v6 - 40 +#[allow(dead_code)] +pub(crate) const MTU: usize = 1500; +#[allow(dead_code)] +pub(crate) const UDP_OVERHEAD: usize = UDP_HEADER_LEN + IP_HEADER_LEN; +#[allow(dead_code)] +pub(crate) const UDP_PAYLOAD_SIZE: usize = MTU - UDP_OVERHEAD; diff --git a/common/nym-lp-packet/src/packet.rs b/common/nym-lp/src/packet/packet.rs similarity index 91% rename from common/nym-lp-packet/src/packet.rs rename to common/nym-lp/src/packet/packet.rs index daa45e77ef..991c7d5ba9 100644 --- a/common/nym-lp-packet/src/packet.rs +++ b/common/nym-lp/src/packet/packet.rs @@ -1,9 +1,8 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::{LpHeader, LpMessage, MessageType, OuterHeader}; +use crate::packet::{LpHeader, LpMessage, MessageType, OuterHeader, utils::format_debug_bytes}; use bytes::{BufMut, BytesMut}; -use nym_lp_common::format_debug_bytes; use std::fmt::{Debug, Formatter}; #[derive(Clone)] @@ -15,8 +14,8 @@ pub struct EncryptedLpPacket { pub(crate) ciphertext: Vec, } -impl Debug for EncryptedLpPacket { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl std::fmt::Debug for EncryptedLpPacket { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", format_debug_bytes(&self.debug_bytes())?) } } diff --git a/common/nym-lp/src/packet.rs b/common/nym-lp/src/packet/replay.rs similarity index 69% rename from common/nym-lp/src/packet.rs rename to common/nym-lp/src/packet/replay.rs index 5cc04ba867..5cbdc3c0d2 100644 --- a/common/nym-lp/src/packet.rs +++ b/common/nym-lp/src/packet/replay.rs @@ -1,21 +1,4 @@ -// Copyright 2025 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use crate::LpError; -use crate::replay::ReceivingKeyCounterValidator; -use nym_lp_packet::LpPacket; -#[allow(dead_code)] -pub(crate) const UDP_HEADER_LEN: usize = 8; -#[allow(dead_code)] -pub(crate) const IP_HEADER_LEN: usize = 40; // v4 - 20, v6 - 40 -#[allow(dead_code)] -pub(crate) const MTU: usize = 1500; -#[allow(dead_code)] -pub(crate) const UDP_OVERHEAD: usize = UDP_HEADER_LEN + IP_HEADER_LEN; -#[allow(dead_code)] -pub(crate) const UDP_PAYLOAD_SIZE: usize = MTU - UDP_OVERHEAD; - -pub use nym_lp_packet::version; +use crate::{LpError, packet::LpPacket, replay::ReceivingKeyCounterValidator}; pub trait LpPacketReplayExt { /// Validate packet counter against a replay protection validator diff --git a/common/nym-lp-common/src/lib.rs b/common/nym-lp/src/packet/utils.rs similarity index 84% rename from common/nym-lp-common/src/lib.rs rename to common/nym-lp/src/packet/utils.rs index 98da6cebd3..4abe90c213 100644 --- a/common/nym-lp-common/src/lib.rs +++ b/common/nym-lp/src/packet/utils.rs @@ -1,8 +1,4 @@ -// Copyright 2025 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use std::fmt; -use std::fmt::Write; +use std::fmt::{self, Write}; pub fn format_debug_bytes(bytes: &[u8]) -> Result { let mut out = String::new(); diff --git a/common/nym-lp/src/peer_config.rs b/common/nym-lp/src/peer_config.rs index 12eaaf1c8a..19c4e8e608 100644 --- a/common/nym-lp/src/peer_config.rs +++ b/common/nym-lp/src/peer_config.rs @@ -10,6 +10,8 @@ use rand09::{self, CryptoRng, Rng}; use tls_codec::Serialize; use zeroize::Zeroize; +pub type LpReceiverIndex = u32; + pub const MAX_HOPS: u8 = 16; pub const LP_PEER_CONFIG_SIZE: usize = 20; @@ -290,13 +292,13 @@ impl LpPeerConfig { self.hop_id == 0 && !self.is_exit && self.node_initiator } - // This returns a u64 made out of the first 8 bytes from + // This returns a LpReceiverIndex made out of the first 4 bytes from // KDF(RECEIVER_INDEX_DERIVATION_CONTEXT, initiator_pub_key || responder_kem_key, seed) pub fn derive_receiver_index( &self, initiator_public_key: &Authenticator, responder_kem_pk: &EncapsulationKey, - ) -> Result { + ) -> Result { let initiator_public_key = initiator_public_key.tls_serialize_detached().map_err(|_| { LpError::Internal( "Failed to serialize initiator public key when computing receiver index".into(), @@ -307,7 +309,7 @@ impl LpPeerConfig { &[initiator_public_key.as_slice(), responder_kem_pk.as_bytes()], self.seed(), ); - let index = u64::from_le_bytes([h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]]); + let index = LpReceiverIndex::from_le_bytes([h[0], h[1], h[2], h[3]]); h.zeroize(); Ok(index) } diff --git a/common/nym-lp/src/psq/handshake_message.rs b/common/nym-lp/src/psq/handshake_message.rs index 73f3d254eb..2877049b46 100644 --- a/common/nym-lp/src/psq/handshake_message.rs +++ b/common/nym-lp/src/psq/handshake_message.rs @@ -2,10 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::psq::{PSQ_MSG2_SIZE, psq_msg1_size}; +use crate::transport::{LpTransportError, traits::HandshakeMessage}; use nym_kkt::context::KKTMode; use nym_kkt_ciphersuite::KEM; -use nym_lp_transport::LpTransportError; -use nym_lp_transport::traits::HandshakeMessage; use std::ops::Deref; pub struct KKTRequest(nym_kkt::message::KKTRequest); diff --git a/common/nym-lp/src/psq/initiator.rs b/common/nym-lp/src/psq/initiator.rs index f0467d0399..ef450158f0 100644 --- a/common/nym-lp/src/psq/initiator.rs +++ b/common/nym-lp/src/psq/initiator.rs @@ -10,6 +10,7 @@ use crate::psq::{ PSQHandshakeState, SESSION_CONTEXT_V1, handshake_message, psq_msg1_size, }; use crate::session::PersistentSessionBinding; +use crate::transport::traits::LpHandshakeChannel; use crate::{LpError, LpSession}; use libcrux_psq::handshake::RegistrationInitiator; use libcrux_psq::handshake::builders::{ @@ -20,7 +21,6 @@ use libcrux_psq::{Channel, IntoSession}; use nym_kkt::initiator::KKTInitiator; use nym_kkt::keys::EncapsulationKey; use nym_kkt::message::{KKTRequest, KKTResponse}; -use nym_lp_transport::traits::LpHandshakeChannel; use rand09::SeedableRng; use tracing::debug; diff --git a/common/nym-lp/src/psq/mod.rs b/common/nym-lp/src/psq/mod.rs index 24c5299a5b..b00ba087f0 100644 --- a/common/nym-lp/src/psq/mod.rs +++ b/common/nym-lp/src/psq/mod.rs @@ -1,10 +1,10 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::packet::version; use crate::peer::{LpLocalPeer, LpRemotePeer}; +use crate::transport::traits::LpHandshakeChannel; use nym_kkt_ciphersuite::{HashFunction, IntoEnumIterator, KEM, SignatureScheme}; -use nym_lp_packet::version; -use nym_lp_transport::traits::LpHandshakeChannel; pub(crate) mod handshake_message; mod helpers; diff --git a/common/nym-lp/src/psq/responder.rs b/common/nym-lp/src/psq/responder.rs index 35f17dadfd..1b85202602 100644 --- a/common/nym-lp/src/psq/responder.rs +++ b/common/nym-lp/src/psq/responder.rs @@ -10,6 +10,7 @@ use crate::psq::{ handshake_message, psq_msg1_size, }; use crate::session::PersistentSessionBinding; +use crate::transport::traits::{HandshakeMessage, LpHandshakeChannel}; use crate::{LpError, LpSession}; use libcrux_psq::handshake::Responder; use libcrux_psq::handshake::builders::{ @@ -20,7 +21,6 @@ use nym_kkt::context::KKTMode; use nym_kkt::message::{KKTRequest, KKTResponse, ProcessedKKTRequest}; use nym_kkt::responder::KKTResponder; use nym_kkt_ciphersuite::KEM; -use nym_lp_transport::traits::{HandshakeMessage, LpHandshakeChannel}; use rand09::SeedableRng; use tracing::debug; diff --git a/common/nym-lp/src/session.rs b/common/nym-lp/src/session.rs index 893dfae9d6..19f7674504 100644 --- a/common/nym-lp/src/session.rs +++ b/common/nym-lp/src/session.rs @@ -6,19 +6,20 @@ //! This module implements session management functionality, including replay protection use crate::codec::{decrypt_lp_packet, encrypt_lp_packet}; +use crate::packet::{ApplicationData, EncryptedLpPacket, LpHeader, LpMessage, LpPacket}; use crate::peer::{LpLocalPeer, LpRemotePeer}; +use crate::peer_config::LpReceiverIndex; use crate::psq::{ InitiatorData, PSQHandshakeState, PSQHandshakeStateInitiator, PSQHandshakeStateResponder, ResponderData, }; use crate::replay::validator::PacketCount; -use crate::{LpError, LpMessage, LpPacket, ReceivingKeyCounterValidator}; +use crate::transport::LpHandshakeChannel; +use crate::{LpError, replay::ReceivingKeyCounterValidator}; use libcrux_psq::handshake::types::{Authenticator, DHPublicKey}; use libcrux_psq::session::{Session, SessionBinding}; use nym_kkt::keys::EncapsulationKey; use nym_kkt_ciphersuite::Ciphersuite; -use nym_lp_packet::{ApplicationData, EncryptedLpPacket, LpHeader}; -use nym_lp_transport::LpHandshakeChannel; use std::fmt::{Debug, Formatter}; pub type SessionId = [u8; 32]; @@ -39,7 +40,7 @@ pub struct LpSession { active_transport: libcrux_psq::session::Transport, /// Look-up index established during the initial KKT exchange - receiver_index: u64, + receiver_index: LpReceiverIndex, /// Negotiated protocol version from handshake. protocol_version: u8, @@ -105,7 +106,7 @@ impl LpSession { pub fn new( mut psq_session: Session, session_binding: PersistentSessionBinding, - receiver_index: u64, + receiver_index: LpReceiverIndex, protocol_version: u8, ) -> Result { // attempt to derive initial transport @@ -168,7 +169,7 @@ impl LpSession { self.psq_session.identifier() } - pub fn receiver_index(&self) -> u64 { + pub fn receiver_index(&self) -> LpReceiverIndex { self.receiver_index } diff --git a/common/nym-lp/src/session_integration/mod.rs b/common/nym-lp/src/session_integration/mod.rs index 7612e791c5..00486a1fb8 100644 --- a/common/nym-lp/src/session_integration/mod.rs +++ b/common/nym-lp/src/session_integration/mod.rs @@ -1,9 +1,9 @@ #[cfg(test)] mod tests { + use crate::packet::EncryptedLpPacket; use crate::state_machine::{LpAction, LpData, LpInput, LpStateBare}; use crate::{LpError, SessionManager, SessionsMock}; use nym_kkt_ciphersuite::{IntoEnumIterator, KEM}; - use nym_lp_packet::EncryptedLpPacket; // helpers to make tests smaller trait ActionExtract { diff --git a/common/nym-lp/src/session_manager.rs b/common/nym-lp/src/session_manager.rs index 1c987501af..0ad99b4c85 100644 --- a/common/nym-lp/src/session_manager.rs +++ b/common/nym-lp/src/session_manager.rs @@ -6,9 +6,10 @@ //! This module implements session lifecycle management functionality, handling //! creation, retrieval, and storage of sessions. +use crate::packet::EncryptedLpPacket; +use crate::peer_config::LpReceiverIndex; use crate::state_machine::{LpAction, LpData, LpInput, LpStateBare}; use crate::{LpError, LpSession, LpStateMachine}; -use nym_lp_packet::EncryptedLpPacket; use std::collections::HashMap; pub use crate::replay::validator::PacketCount; @@ -18,7 +19,7 @@ pub use crate::replay::validator::PacketCount; /// The SessionManager is responsible for creating, storing, and retrieving sessions pub struct SessionManager { /// Manages state machines directly, keyed by lp_id - state_machines: HashMap, + state_machines: HashMap, } impl Default for SessionManager { @@ -37,43 +38,43 @@ impl SessionManager { pub fn process_input( &mut self, - lp_id: u64, + lp_id: LpReceiverIndex, input: LpInput, ) -> Result, LpError> { self.with_state_machine_mut(lp_id, |sm| sm.process_input(input).transpose())? } - pub fn send_data(&mut self, lp_id: u64, data: LpData) -> Result { + pub fn send_data(&mut self, lp_id: LpReceiverIndex, data: LpData) -> Result { self.process_input(lp_id, LpInput::SendData(data))? .ok_or(LpError::NotInTransport) } pub fn receive_packet( &mut self, - lp_id: u64, + lp_id: LpReceiverIndex, packet: EncryptedLpPacket, ) -> Result, LpError> { self.process_input(lp_id, LpInput::ReceivePacket(packet)) } - pub fn closed(&self, lp_id: u64) -> Result { + pub fn closed(&self, lp_id: LpReceiverIndex) -> Result { Ok(self.get_state(lp_id)? == LpStateBare::Closed) } - pub fn transport(&self, lp_id: u64) -> Result { + pub fn transport(&self, lp_id: LpReceiverIndex) -> Result { Ok(self.get_state(lp_id)? == LpStateBare::Transport) } #[cfg(test)] - fn get_state_machine_id(&self, lp_id: u64) -> Result { + fn get_state_machine_id(&self, lp_id: LpReceiverIndex) -> Result { self.with_state_machine(lp_id, |sm| sm.receiver_index())? } - pub fn get_state(&self, lp_id: u64) -> Result { + pub fn get_state(&self, lp_id: LpReceiverIndex) -> Result { self.with_state_machine(lp_id, |sm| Ok(sm.bare_state()))? } - pub fn current_packet_cnt(&self, lp_id: u64) -> Result { + pub fn current_packet_cnt(&self, lp_id: LpReceiverIndex) -> Result { self.with_state_machine(lp_id, |sm| Ok(sm.session()?.current_packet_cnt()))? } @@ -81,34 +82,41 @@ impl SessionManager { self.state_machines.len() } - pub fn state_machine_exists(&self, lp_id: u64) -> bool { + pub fn state_machine_exists(&self, lp_id: LpReceiverIndex) -> bool { self.state_machines.contains_key(&lp_id) } - pub fn with_state_machine(&self, lp_id: u64, f: F) -> Result + pub fn with_state_machine(&self, lp_id: LpReceiverIndex, f: F) -> Result where F: FnOnce(&LpStateMachine) -> R, { if let Some(sm) = self.state_machines.get(&lp_id) { Ok(f(sm)) } else { - Err(LpError::StateMachineNotFound { lp_id }) + Err(LpError::StateMachineNotFound(lp_id)) } } // For mutable access (like running process_input) - pub fn with_state_machine_mut(&mut self, lp_id: u64, f: F) -> Result + pub fn with_state_machine_mut( + &mut self, + lp_id: LpReceiverIndex, + f: F, + ) -> Result where F: FnOnce(&mut LpStateMachine) -> R, // Closure takes mutable ref { if let Some(sm) = self.state_machines.get_mut(&lp_id) { Ok(f(sm)) } else { - Err(LpError::StateMachineNotFound { lp_id }) + Err(LpError::StateMachineNotFound(lp_id)) } } - pub fn create_session_state_machine(&mut self, lp_session: LpSession) -> Result { + pub fn create_session_state_machine( + &mut self, + lp_session: LpSession, + ) -> Result { let session_id = lp_session.receiver_index(); if self.state_machines.contains_key(&session_id) { @@ -121,7 +129,7 @@ impl SessionManager { } /// Method to remove a state machine - pub fn remove_state_machine(&mut self, lp_id: u64) -> bool { + pub fn remove_state_machine(&mut self, lp_id: LpReceiverIndex) -> bool { let removed = self.state_machines.remove(&lp_id); removed.is_some() diff --git a/common/nym-lp/src/state_machine.rs b/common/nym-lp/src/state_machine.rs index fc6133f1bc..733f48b694 100644 --- a/common/nym-lp/src/state_machine.rs +++ b/common/nym-lp/src/state_machine.rs @@ -5,11 +5,12 @@ //! State machine ensures protocol steps execute in correct order. Invalid transitions //! return LpError, preventing protocol violations. +use crate::packet::{EncryptedLpPacket, LpMessage}; +use crate::peer_config::LpReceiverIndex; use crate::session::SessionId; use crate::{LpError, session::LpSession}; use bytes::{Buf, Bytes}; use num_enum::{IntoPrimitive, TryFromPrimitive}; -use nym_lp_packet::{EncryptedLpPacket, LpMessage}; use std::mem; #[derive(Debug)] @@ -186,7 +187,7 @@ impl LpStateMachine { Ok(*self.session()?.session_identifier()) } - pub fn receiver_index(&self) -> Result { + pub fn receiver_index(&self) -> Result { Ok(self.session()?.receiver_index()) } diff --git a/common/nym-lp-transport/src/error.rs b/common/nym-lp/src/transport/error.rs similarity index 100% rename from common/nym-lp-transport/src/error.rs rename to common/nym-lp/src/transport/error.rs diff --git a/common/nym-lp-transport/src/lib.rs b/common/nym-lp/src/transport/mod.rs similarity index 100% rename from common/nym-lp-transport/src/lib.rs rename to common/nym-lp/src/transport/mod.rs diff --git a/common/nym-lp-transport/src/traits.rs b/common/nym-lp/src/transport/traits.rs similarity index 97% rename from common/nym-lp-transport/src/traits.rs rename to common/nym-lp/src/transport/traits.rs index b80ef78768..f3c39af0af 100644 --- a/common/nym-lp-transport/src/traits.rs +++ b/common/nym-lp/src/transport/traits.rs @@ -1,16 +1,16 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::error::LpTransportError; +use crate::packet::{EncryptedLpPacket, OuterHeader}; +use crate::transport::error::LpTransportError; +use nym_kkt::context::KKTMode; use nym_kkt_ciphersuite::KEM; -use nym_kkt_context::KKTMode; -use nym_lp_packet::{EncryptedLpPacket, OuterHeader}; use std::net::SocketAddr; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; use tokio::net::TcpStream; use tracing::debug; -#[cfg(feature = "io-mocks")] +#[cfg(any(feature = "mock", test))] use nym_test_utils::mocks::async_read_write::MockIOStream; pub const MAX_TRANSPORT_PACKET_SIZE: usize = 65536; // 64KB max @@ -256,7 +256,7 @@ impl LpTransportChannel for TcpStream { } } -#[cfg(feature = "io-mocks")] +#[cfg(any(feature = "mock", test))] impl LpTransportChannel for MockIOStream { async fn connect(_endpoint: SocketAddr) -> Result { Ok(MockIOStream::default()) @@ -280,7 +280,7 @@ impl LpTransportChannel for MockIOStream { } } -#[cfg(feature = "io-mocks")] +#[cfg(any(feature = "mock", test))] impl LpHandshakeChannel for MockIOStream { async fn write_all_and_flush(&mut self, data: &[u8]) -> Result<(), LpTransportError> { write_all_and_flush_async_write(self, data).await diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 123c01a272..51e3c98c6c 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -80,6 +80,8 @@ nym-id = { workspace = true } nym-service-provider-requests-common = { workspace = true } nym-registration-common = { path = "../common/registration" } +nym-lp = { path = "../common/nym-lp" } + defguard_wireguard_rs = { workspace = true } [dev-dependencies] diff --git a/gateway/src/node/wireguard/new_peer_registration/lp.rs b/gateway/src/node/wireguard/new_peer_registration/lp.rs index 14601e634e..9e7a45d057 100644 --- a/gateway/src/node/wireguard/new_peer_registration/lp.rs +++ b/gateway/src/node/wireguard/new_peer_registration/lp.rs @@ -7,6 +7,7 @@ use crate::node::wireguard::new_peer_registration::pending::{ use crate::node::wireguard::{GatewayWireguardError, PeerRegistrator}; use defguard_wireguard_rs::host::Peer; use defguard_wireguard_rs::key::Key; +use nym_lp::peer_config::LpReceiverIndex; use nym_registration_common::{LpRegistrationResponse, WireguardRegistrationData}; use nym_wireguard::ip_pool::{allocated_ip_pair, IpPair}; use nym_wireguard_types::PeerPublicKey; @@ -57,7 +58,7 @@ impl PeerRegistrator { pub(super) async fn check_pending_lp_registration( &self, - receiver_index: u64, + receiver_index: LpReceiverIndex, ) -> Result, GatewayWireguardError> { let Some(pending_registration) = self.pending_registrations.check_lp(receiver_index).await else { @@ -104,7 +105,7 @@ impl PeerRegistrator { pub(super) async fn process_fresh_initial_lp_registration( &self, - receiver_index: u64, + receiver_index: LpReceiverIndex, remote_public: PeerPublicKey, psk: Key, ) -> Result { diff --git a/gateway/src/node/wireguard/new_peer_registration/mod.rs b/gateway/src/node/wireguard/new_peer_registration/mod.rs index 5e0e503d33..b2f89accf7 100644 --- a/gateway/src/node/wireguard/new_peer_registration/mod.rs +++ b/gateway/src/node/wireguard/new_peer_registration/mod.rs @@ -31,6 +31,7 @@ use nym_credentials_interface::{BandwidthCredential, CredentialSpendingData}; use nym_crypto::asymmetric::x25519; use nym_gateway_requests::models::CredentialSpendingRequest; use nym_gateway_storage::models::PersistedBandwidth; +use nym_lp::peer_config::LpReceiverIndex; use nym_registration_common::dvpn::{ LpDvpnRegistrationFinalisation, LpDvpnRegistrationInitialRequest, }; @@ -309,7 +310,7 @@ impl PeerRegistrator { pub async fn on_initial_lp_request( &self, init_msg: LpDvpnRegistrationInitialRequest, - receiver_index: u64, + receiver_index: LpReceiverIndex, ) -> Result { let remote_public = init_msg.wg_public_key; let psk = Key::new(init_msg.psk); @@ -340,7 +341,7 @@ impl PeerRegistrator { pub async fn on_final_lp_request( &self, final_msg: LpDvpnRegistrationFinalisation, - receiver_index: u64, + receiver_index: LpReceiverIndex, ) -> Result { // 1. check if there's any pending registration associated with this peer let pending_data = self diff --git a/gateway/src/node/wireguard/new_peer_registration/pending.rs b/gateway/src/node/wireguard/new_peer_registration/pending.rs index 6a4936e4f1..1899ccf8c8 100644 --- a/gateway/src/node/wireguard/new_peer_registration/pending.rs +++ b/gateway/src/node/wireguard/new_peer_registration/pending.rs @@ -8,6 +8,7 @@ use crate::node::wireguard::GatewayWireguardError; use defguard_wireguard_rs::key::Key; use nym_authenticator_requests::AuthenticatorVersion; use nym_crypto::asymmetric::x25519; +use nym_lp::peer_config::LpReceiverIndex; use nym_registration_common::{LpRegistrationResponse, WireguardRegistrationData}; use nym_sdk::mixnet::Recipient; use nym_wireguard::ip_pool::IpPair; @@ -116,7 +117,7 @@ pub(crate) struct PendingRegistrations { /// Registrations in progress received from the LP Listener via the /// `LpConnectionHandler` and handle through `LpHandlerState` - pub(crate) lp: Arc>>, + pub(crate) lp: Arc>>, } impl PendingRegistrations { @@ -131,11 +132,14 @@ impl PendingRegistrations { self.authenticator.write().await.remove(peer); } - pub(crate) async fn remove_lp(&self, receiver_index: u64) { + pub(crate) async fn remove_lp(&self, receiver_index: LpReceiverIndex) { self.lp.write().await.remove(&receiver_index); } - pub(crate) async fn check_lp(&self, receiver_index: u64) -> Option { + pub(crate) async fn check_lp( + &self, + receiver_index: LpReceiverIndex, + ) -> Option { self.lp.read().await.get(&receiver_index).cloned() } diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 768708552c..aaeced8b6d 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -22,9 +22,8 @@ nym-credential-verification = { path = "../common/credential-verification" } nym-credentials-interface = { path = "../common/credentials-interface" } nym-test-utils = { path = "../common/test-utils" } nym-registration-client = { path = "../nym-registration-client" } -nym-lp-transport = { path = "../common/nym-lp-transport", features = ["io-mocks"] } nym-node = { path = "../nym-node" } -nym-lp = { path = "../common/nym-lp" } +nym-lp = { path = "../common/nym-lp", features = ["mock"] } sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite"] } tracing = { workspace = true } futures = { workspace = true } diff --git a/nym-node/Cargo.toml b/nym-node/Cargo.toml index 574d06eee3..4845997d7b 100644 --- a/nym-node/Cargo.toml +++ b/nym-node/Cargo.toml @@ -118,7 +118,6 @@ nym-ip-packet-router = { path = "../service-providers/ip-packet-router" } # LP dependencies nym-lp = { path = "../common/nym-lp" } -nym-lp-transport = { path = "../common/nym-lp-transport" } nym-registration-common = { path = "../common/registration" } bincode = { workspace = true } diff --git a/nym-node/src/node/lp/data_handler.rs b/nym-node/src/node/lp/data_handler.rs index 620113f1a9..9c842fd159 100644 --- a/nym-node/src/node/lp/data_handler.rs +++ b/nym-node/src/node/lp/data_handler.rs @@ -18,7 +18,7 @@ use super::LpHandlerState; use crate::error::NymNodeError; use crate::node::lp::error::LpHandlerError; -use nym_lp::OuterHeader; +use nym_lp::packet::OuterHeader; use nym_metrics::inc; use std::net::SocketAddr; use std::sync::Arc; diff --git a/nym-node/src/node/lp/error.rs b/nym-node/src/node/lp/error.rs index d8e5c38e2d..d8c9da439a 100644 --- a/nym-node/src/node/lp/error.rs +++ b/nym-node/src/node/lp/error.rs @@ -1,10 +1,10 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::node::lp::ReceiverIndex; +use crate::node::lp::LpReceiverIndex; use nym_lp::state_machine::{LpAction, LpDataKind}; -use nym_lp::{LpError, MalformedLpPacketError}; -use nym_lp_transport::LpTransportError; +use nym_lp::transport::LpTransportError; +use nym_lp::{LpError, packet::MalformedLpPacketError}; use std::net::SocketAddr; use thiserror::Error; @@ -17,7 +17,7 @@ pub enum LpHandlerError { LpTransportError(#[from] LpTransportError), #[error("missing session state for {receiver_index} - has it been removed due to inactivity?")] - MissingLpSession { receiver_index: ReceiverIndex }, + MissingLpSession { receiver_index: LpReceiverIndex }, #[error(transparent)] LpProtocolError(#[from] LpError), @@ -27,8 +27,8 @@ pub enum LpHandlerError { #[error("receiver_idx mismatch: connection bound to {established}, packet has {received}")] MismatchedReceiverIndex { - established: ReceiverIndex, - received: ReceiverIndex, + established: LpReceiverIndex, + received: LpReceiverIndex, }, #[error("no action has been emitted from the LP State Machine")] diff --git a/nym-node/src/node/lp/handler.rs b/nym-node/src/node/lp/handler.rs index 3046e81c5b..76c0678c33 100644 --- a/nym-node/src/node/lp/handler.rs +++ b/nym-node/src/node/lp/handler.rs @@ -1,14 +1,13 @@ // Copyright 2025 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use super::{LpHandlerState, ReceiverIndex, TimestampedState}; +use super::{LpHandlerState, LpReceiverIndex, TimestampedState}; use crate::node::lp::error::LpHandlerError; +use nym_lp::packet::{EncryptedLpPacket, ForwardPacketData}; use nym_lp::state_machine::{LpAction, LpData, LpDataKind, LpInput}; -use nym_lp::{ - EncryptedLpPacket, ExpectedResponseSize, ForwardPacketData, LpSession, LpStateMachine, -}; -use nym_lp_transport::LpHandshakeChannel; -use nym_lp_transport::traits::LpTransportChannel; +use nym_lp::transport::LpHandshakeChannel; +use nym_lp::transport::traits::LpTransportChannel; +use nym_lp::{LpSession, LpStateMachine, packet::message::ExpectedResponseSize}; use nym_metrics::{add_histogram_obs, inc}; use nym_registration_common::{LpRegistrationRequest, RegistrationStatus}; use std::net::SocketAddr; @@ -83,7 +82,7 @@ pub struct LpConnectionHandler { /// Bound receiver_idx for this connection (set after first packet). /// All subsequent packets on this connection must use this receiver_idx. /// Set from ClientHello's proposed receiver_index, or from header for non-bootstrap packets. - bound_receiver_idx: Option, + bound_receiver_idx: Option, /// Persistent connection to exit gateway for forwarding. /// Opened on first forward, reused for subsequent forwards, closed when client disconnects. @@ -206,13 +205,13 @@ where Ok(()) } - fn bound_receiver_index(&self) -> Result { + fn bound_receiver_index(&self) -> Result { self.bound_receiver_idx .ok_or_else(|| LpHandlerError::IncompleteHandshake) } /// Validate that the receiver_idx matches the bound session. - fn validate_binding(&self, receiver_idx: ReceiverIndex) -> Result<(), LpHandlerError> { + fn validate_binding(&self, receiver_idx: LpReceiverIndex) -> Result<(), LpHandlerError> { let bound_receiver_idx = self.bound_receiver_index()?; if bound_receiver_idx != receiver_idx { @@ -292,7 +291,7 @@ where /// Handle decrypted transport payload (registration or forwarding request) async fn handle_decrypted_payload( &mut self, - receiver_idx: ReceiverIndex, + receiver_idx: LpReceiverIndex, decrypted_data: LpData, ) -> Result<(), LpHandlerError> { let remote = self.remote_addr; @@ -332,7 +331,7 @@ where /// Attempt to wrap and send specified response back to the client async fn send_response_packet( &mut self, - receiver_index: ReceiverIndex, + receiver_index: LpReceiverIndex, serialised_response: Vec, response_kind: LpDataKind, ) -> Result<(), LpHandlerError> { @@ -366,7 +365,7 @@ where /// Handle registration request on an established session async fn handle_registration_request( &mut self, - receiver_idx: ReceiverIndex, + receiver_idx: LpReceiverIndex, request: LpRegistrationRequest, ) -> Result<(), LpHandlerError> { // Process registration (might modify state) @@ -406,7 +405,7 @@ where /// to exit gateway, receives response, encrypts it, and sends back to client. async fn handle_forwarding_request( &mut self, - receiver_idx: ReceiverIndex, + receiver_idx: LpReceiverIndex, forward_data: ForwardPacketData, ) -> Result<(), LpHandlerError> { // Forward the packet to the target gateway and retrieve its response diff --git a/nym-node/src/node/lp/mod.rs b/nym-node/src/node/lp/mod.rs index 8adf6a5e52..78e1eaee80 100644 --- a/nym-node/src/node/lp/mod.rs +++ b/nym-node/src/node/lp/mod.rs @@ -72,6 +72,7 @@ use crate::error::NymNodeError; use dashmap::DashMap; use nym_gateway::node::wireguard::PeerRegistrator; use nym_lp::peer::LpLocalPeer; +use nym_lp::peer_config::LpReceiverIndex; use nym_lp::state_machine::LpStateMachine; use nym_mixnet_client::forwarder::MixForwardingSender; use nym_node_metrics::NymNodeMetrics; @@ -90,8 +91,6 @@ pub mod error; pub mod handler; mod registration; -pub type ReceiverIndex = u64; - /// Wrapper for state entries with timestamp tracking for cleanup /// /// This wrapper adds `created_at` and `last_activity` timestamps to state entries, @@ -189,7 +188,7 @@ pub struct LpHandlerState { /// subsession/rekeying support. The state machine handles subsession initiation /// (SubsessionKK1/KK2/Ready) during transport phase, allowing long-lived connections /// to rekey without re-authentication. - pub session_states: Arc>>, + pub session_states: Arc>>, /// Semaphore limiting concurrent forward connections /// @@ -394,7 +393,7 @@ impl LpListener { pub(crate) mod cleanup_task { use crate::config::lp::LpDebug; - use crate::node::lp::{ReceiverIndex, TimestampedState}; + use crate::node::lp::{LpReceiverIndex, TimestampedState}; use dashmap::DashMap; use nym_lp::LpStateMachine; use nym_metrics::inc_by; @@ -403,7 +402,7 @@ pub(crate) mod cleanup_task { use tracing::{debug, info}; async fn perform_cleanup( - session_states: &Arc>>, + session_states: &Arc>>, cfg: LpDebug, ) { let session_ttl = cfg.session_ttl; @@ -444,7 +443,7 @@ pub(crate) mod cleanup_task { /// Demoted sessions (ReadOnlyTransport) use shorter TTL since they /// only need to drain in-flight packets after subsession promotion. pub(crate) async fn cleanup_loop( - session_states: Arc>>, + session_states: Arc>>, cfg: LpDebug, shutdown: nym_task::ShutdownToken, _metrics: NymNodeMetrics, diff --git a/nym-node/src/node/lp/registration.rs b/nym-node/src/node/lp/registration.rs index 294b0d47e7..52b6975c5b 100644 --- a/nym-node/src/node/lp/registration.rs +++ b/nym-node/src/node/lp/registration.rs @@ -1,7 +1,7 @@ // Copyright 2025 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use crate::node::lp::{LpHandlerState, ReceiverIndex}; +use crate::node::lp::{LpHandlerState, LpReceiverIndex}; use nym_metrics::{add_histogram_obs, inc}; use nym_registration_common::dvpn::{ LpDvpnRegistrationFinalisation, LpDvpnRegistrationInitialRequest, @@ -31,7 +31,7 @@ const LP_REGISTRATION_DURATION_BUCKETS: &[f64] = &[ impl LpHandlerState { async fn process_dvpn_initial_registration( &self, - sender: ReceiverIndex, + sender: LpReceiverIndex, request: LpDvpnRegistrationInitialRequest, ) -> LpRegistrationResponse { let Some(registrator) = self.peer_registrator.as_ref() else { @@ -54,7 +54,7 @@ impl LpHandlerState { async fn process_dvpn_registration_finalisation( &self, - sender: ReceiverIndex, + sender: LpReceiverIndex, request: LpDvpnRegistrationFinalisation, ) -> LpRegistrationResponse { let Some(registrator) = self.peer_registrator.as_ref() else { @@ -77,7 +77,7 @@ impl LpHandlerState { async fn process_dvpn_registration( &self, - sender: ReceiverIndex, + sender: LpReceiverIndex, request: Box, ) -> LpRegistrationResponse { // Track dVPN registration attempts @@ -108,7 +108,7 @@ impl LpHandlerState { /// Process an LP registration request pub async fn process_registration( &self, - sender: ReceiverIndex, + sender: LpReceiverIndex, request: LpRegistrationRequest, ) -> LpRegistrationResponse { let registration_start = std::time::Instant::now(); diff --git a/nym-registration-client/Cargo.toml b/nym-registration-client/Cargo.toml index e674aa9524..a1c3aa335a 100644 --- a/nym-registration-client/Cargo.toml +++ b/nym-registration-client/Cargo.toml @@ -31,7 +31,6 @@ nym-credentials-interface = { workspace = true } nym-crypto = { workspace = true, features = ["asymmetric", "libcrux_x25519"] } nym-ip-packet-client = { workspace = true } nym-lp = { path = "../common/nym-lp" } -nym-lp-transport = { path = "../common/nym-lp-transport" } nym-registration-common = { workspace = true } nym-sdk = { workspace = true } nym-validator-client = { workspace = true } diff --git a/nym-registration-client/src/lp_client/client.rs b/nym-registration-client/src/lp_client/client.rs index 4376371e6a..81d6c5f67d 100644 --- a/nym-registration-client/src/lp_client/client.rs +++ b/nym-registration-client/src/lp_client/client.rs @@ -13,10 +13,11 @@ use nym_credentials_interface::TicketType; use nym_crypto::asymmetric::{ed25519, x25519}; use nym_lp::LpSession; use nym_lp::peer::{DHKeyPair, LpLocalPeer, LpRemotePeer}; +use nym_lp::peer_config::LpReceiverIndex; use nym_lp::state_machine::LpStateMachine; -use nym_lp::{Ciphersuite, EncryptedLpPacket, packet::version}; -use nym_lp_transport::traits::LpTransportChannel; -use nym_lp_transport::{LpHandshakeChannel, LpTransportError}; +use nym_lp::transport::traits::LpTransportChannel; +use nym_lp::transport::{LpHandshakeChannel, LpTransportError}; +use nym_lp::{Ciphersuite, packet::EncryptedLpPacket, packet::version}; use nym_registration_common::dvpn::LpDvpnRegistrationResponseMessageContent; use nym_registration_common::{ LpRegistrationRequest, LpRegistrationResponse, WireguardConfiguration, @@ -707,11 +708,11 @@ where /// the gateway to look up the session for decryption. /// /// # Returns - /// * `Ok(u64)` - The session ID + /// * `Ok(LpReceiverIndex)` - The session ID /// /// # Errors /// Returns an error if handshake has not been completed. - pub fn session_id(&self) -> Result { + pub fn session_id(&self) -> Result { self.state_machine()? .session() .map(|s| s.receiver_index()) diff --git a/nym-registration-client/src/lp_client/error.rs b/nym-registration-client/src/lp_client/error.rs index 67aa838918..681d34d01e 100644 --- a/nym-registration-client/src/lp_client/error.rs +++ b/nym-registration-client/src/lp_client/error.rs @@ -3,9 +3,10 @@ //! Error types for LP (Lewes Protocol) client operations. +use nym_lp::LpError; +use nym_lp::packet::MalformedLpPacketError; use nym_lp::state_machine::{LpAction, LpDataKind}; -use nym_lp::{LpError, MalformedLpPacketError}; -use nym_lp_transport::LpTransportError; +use nym_lp::transport::LpTransportError; use thiserror::Error; /// Errors that can occur during LP client operations. diff --git a/nym-registration-client/src/lp_client/helpers.rs b/nym-registration-client/src/lp_client/helpers.rs index 4479389b4f..9de8cb5a19 100644 --- a/nym-registration-client/src/lp_client/helpers.rs +++ b/nym-registration-client/src/lp_client/helpers.rs @@ -4,7 +4,7 @@ #![allow(dead_code)] use crate::LpClientError; -use nym_lp::ForwardPacketData; +use nym_lp::packet::ForwardPacketData; use nym_lp::peer::LpRemotePeer; use nym_lp::state_machine::{LpAction, LpData, LpDataKind, LpInput}; use nym_registration_common::{ diff --git a/nym-registration-client/src/lp_client/nested_session/connection.rs b/nym-registration-client/src/lp_client/nested_session/connection.rs index b09e0372e8..70432e9bb0 100644 --- a/nym-registration-client/src/lp_client/nested_session/connection.rs +++ b/nym-registration-client/src/lp_client/nested_session/connection.rs @@ -4,10 +4,11 @@ use crate::lp_client::helpers::{convert_forward_data, try_convert_forward_response}; use crate::{LpClientError, LpRegistrationClient}; use bytes::{BufMut, BytesMut}; +use nym_lp::KEM; +use nym_lp::packet::{EncryptedLpPacket, ForwardPacketData, message::ExpectedResponseSize}; use nym_lp::state_machine::{LpAction, LpInput}; -use nym_lp::{EncryptedLpPacket, ExpectedResponseSize, ForwardPacketData, KEM}; -use nym_lp_transport::traits::{HandshakeMessage, LpTransportChannel}; -use nym_lp_transport::{LpHandshakeChannel, LpTransportError}; +use nym_lp::transport::traits::{HandshakeMessage, LpTransportChannel}; +use nym_lp::transport::{LpHandshakeChannel, LpTransportError}; use std::io; use std::net::SocketAddr; 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 9c7115cf00..a4e1c5681c 100644 --- a/nym-registration-client/src/lp_client/nested_session/mod.rs +++ b/nym-registration-client/src/lp_client/nested_session/mod.rs @@ -25,12 +25,13 @@ use crate::lp_client::state_machine_helpers::{extract_forwarded_response, prepar use nym_bandwidth_controller::{BandwidthTicketProvider, DEFAULT_TICKETS_TO_SPEND}; use nym_credentials_interface::TicketType; use nym_crypto::asymmetric::{ed25519, x25519}; +use nym_lp::packet::EncryptedLpPacket; use nym_lp::packet::version; use nym_lp::peer::{DHKeyPair, LpLocalPeer, LpRemotePeer}; use nym_lp::state_machine::{LpData, LpStateMachine}; -use nym_lp::{Ciphersuite, EncryptedLpPacket, KEM, LpSession}; -use nym_lp_transport::LpHandshakeChannel; -use nym_lp_transport::traits::LpTransportChannel; +use nym_lp::transport::LpHandshakeChannel; +use nym_lp::transport::traits::LpTransportChannel; +use nym_lp::{Ciphersuite, KEM, LpSession}; use nym_registration_common::dvpn::LpDvpnRegistrationResponseMessageContent; use nym_registration_common::{ LpRegistrationRequest, LpRegistrationResponse, WireguardConfiguration, diff --git a/nym-registration-client/src/lp_client/state_machine_helpers.rs b/nym-registration-client/src/lp_client/state_machine_helpers.rs index 5410a67a8d..bfa3f9edc5 100644 --- a/nym-registration-client/src/lp_client/state_machine_helpers.rs +++ b/nym-registration-client/src/lp_client/state_machine_helpers.rs @@ -3,7 +3,7 @@ use crate::LpClientError; use nym_lp::state_machine::{LpAction, LpData, LpInput}; -use nym_lp::{EncryptedLpPacket, LpStateMachine}; +use nym_lp::{LpStateMachine, packet::EncryptedLpPacket}; /// Attempt to prepare the provided data for sending by wrapping it in appropriate `LpAction`, /// and attempting to extract `EncryptedLpPacket` from the provided state machine.