Change receiver index to u32 and regorganize crates
This commit is contained in:
committed by
Jędrzej Stuczyński
parent
3f500af7a7
commit
1ddbb970d0
Generated
-35
@@ -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",
|
||||
|
||||
+1
-3
@@ -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 = [
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
[package]
|
||||
name = "nym-lp-common"
|
||||
version = "0.1.0"
|
||||
edition = { workspace = true }
|
||||
license = { workspace = true }
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,10 +1,10 @@
|
||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||
// 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() -> (
|
||||
|
||||
+11
-10
@@ -1,15 +1,16 @@
|
||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||
// 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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
// Copyright 2026 - Nym Technologies SA <contact@nymtech.net>
|
||||
// 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
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2026 - Nym Technologies SA <contact@nymtech.net>
|
||||
// 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() {
|
||||
@@ -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;
|
||||
@@ -1,9 +1,8 @@
|
||||
// Copyright 2026 - Nym Technologies SA <contact@nymtech.net>
|
||||
// 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<u8>,
|
||||
}
|
||||
|
||||
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())?)
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,4 @@
|
||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||
// 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
|
||||
@@ -1,8 +1,4 @@
|
||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||
// 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<String, fmt::Error> {
|
||||
let mut out = String::new();
|
||||
@@ -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<u64, LpError> {
|
||||
) -> Result<LpReceiverIndex, LpError> {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Copyright 2026 - Nym Technologies SA <contact@nymtech.net>
|
||||
// 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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<Self, LpError> {
|
||||
// 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
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<u64, LpStateMachine>,
|
||||
state_machines: HashMap<LpReceiverIndex, LpStateMachine>,
|
||||
}
|
||||
|
||||
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<Option<LpAction>, 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<LpAction, LpError> {
|
||||
pub fn send_data(&mut self, lp_id: LpReceiverIndex, data: LpData) -> Result<LpAction, LpError> {
|
||||
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<Option<LpAction>, LpError> {
|
||||
self.process_input(lp_id, LpInput::ReceivePacket(packet))
|
||||
}
|
||||
|
||||
pub fn closed(&self, lp_id: u64) -> Result<bool, LpError> {
|
||||
pub fn closed(&self, lp_id: LpReceiverIndex) -> Result<bool, LpError> {
|
||||
Ok(self.get_state(lp_id)? == LpStateBare::Closed)
|
||||
}
|
||||
|
||||
pub fn transport(&self, lp_id: u64) -> Result<bool, LpError> {
|
||||
pub fn transport(&self, lp_id: LpReceiverIndex) -> Result<bool, LpError> {
|
||||
Ok(self.get_state(lp_id)? == LpStateBare::Transport)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn get_state_machine_id(&self, lp_id: u64) -> Result<u64, LpError> {
|
||||
fn get_state_machine_id(&self, lp_id: LpReceiverIndex) -> Result<LpReceiverIndex, LpError> {
|
||||
self.with_state_machine(lp_id, |sm| sm.receiver_index())?
|
||||
}
|
||||
|
||||
pub fn get_state(&self, lp_id: u64) -> Result<LpStateBare, LpError> {
|
||||
pub fn get_state(&self, lp_id: LpReceiverIndex) -> Result<LpStateBare, LpError> {
|
||||
self.with_state_machine(lp_id, |sm| Ok(sm.bare_state()))?
|
||||
}
|
||||
|
||||
pub fn current_packet_cnt(&self, lp_id: u64) -> Result<PacketCount, LpError> {
|
||||
pub fn current_packet_cnt(&self, lp_id: LpReceiverIndex) -> Result<PacketCount, LpError> {
|
||||
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<F, R>(&self, lp_id: u64, f: F) -> Result<R, LpError>
|
||||
pub fn with_state_machine<F, R>(&self, lp_id: LpReceiverIndex, f: F) -> Result<R, LpError>
|
||||
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<F, R>(&mut self, lp_id: u64, f: F) -> Result<R, LpError>
|
||||
pub fn with_state_machine_mut<F, R>(
|
||||
&mut self,
|
||||
lp_id: LpReceiverIndex,
|
||||
f: F,
|
||||
) -> Result<R, LpError>
|
||||
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<u64, LpError> {
|
||||
pub fn create_session_state_machine(
|
||||
&mut self,
|
||||
lp_session: LpSession,
|
||||
) -> Result<LpReceiverIndex, LpError> {
|
||||
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()
|
||||
|
||||
@@ -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<u64, LpError> {
|
||||
pub fn receiver_index(&self) -> Result<LpReceiverIndex, LpError> {
|
||||
Ok(self.session()?.receiver_index())
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
// Copyright 2026 - Nym Technologies SA <contact@nymtech.net>
|
||||
// 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<Self, LpTransportError> {
|
||||
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
|
||||
@@ -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]
|
||||
|
||||
@@ -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<Option<LpRegistrationResponse>, 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<LpRegistrationResponse, GatewayWireguardError> {
|
||||
|
||||
@@ -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<LpRegistrationResponse, GatewayWireguardError> {
|
||||
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<LpRegistrationResponse, GatewayWireguardError> {
|
||||
// 1. check if there's any pending registration associated with this peer
|
||||
let pending_data = self
|
||||
|
||||
@@ -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<RwLock<HashMap<u64, PendingRegistration>>>,
|
||||
pub(crate) lp: Arc<RwLock<HashMap<LpReceiverIndex, PendingRegistration>>>,
|
||||
}
|
||||
|
||||
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<PendingRegistration> {
|
||||
pub(crate) async fn check_lp(
|
||||
&self,
|
||||
receiver_index: LpReceiverIndex,
|
||||
) -> Option<PendingRegistration> {
|
||||
self.lp.read().await.get(&receiver_index).cloned()
|
||||
}
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Copyright 2026 - Nym Technologies SA <contact@nymtech.net>
|
||||
// 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")]
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||
// 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<S = TcpStream> {
|
||||
/// 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<ReceiverIndex>,
|
||||
bound_receiver_idx: Option<LpReceiverIndex>,
|
||||
|
||||
/// 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<ReceiverIndex, LpHandlerError> {
|
||||
fn bound_receiver_index(&self) -> Result<LpReceiverIndex, LpHandlerError> {
|
||||
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<u8>,
|
||||
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
|
||||
|
||||
@@ -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<DashMap<ReceiverIndex, TimestampedState<LpStateMachine>>>,
|
||||
pub session_states: Arc<DashMap<LpReceiverIndex, TimestampedState<LpStateMachine>>>,
|
||||
|
||||
/// 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<DashMap<ReceiverIndex, TimestampedState<LpStateMachine>>>,
|
||||
session_states: &Arc<DashMap<LpReceiverIndex, TimestampedState<LpStateMachine>>>,
|
||||
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<DashMap<ReceiverIndex, TimestampedState<LpStateMachine>>>,
|
||||
session_states: Arc<DashMap<LpReceiverIndex, TimestampedState<LpStateMachine>>>,
|
||||
cfg: LpDebug,
|
||||
shutdown: nym_task::ShutdownToken,
|
||||
_metrics: NymNodeMetrics,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||
// 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<LpDvpnRegistrationRequestMessage>,
|
||||
) -> 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();
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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<u64> {
|
||||
pub fn session_id(&self) -> Result<LpReceiverIndex> {
|
||||
self.state_machine()?
|
||||
.session()
|
||||
.map(|s| s.receiver_index())
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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::{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user