This commit is contained in:
durch
2025-10-23 20:01:06 +02:00
parent 5f2122688f
commit ec90a218df
10 changed files with 83 additions and 110 deletions
+10 -7
View File
@@ -10,7 +10,7 @@ fn bench_sequential_counters(c: &mut Criterion) {
group.sample_size(1000);
for size in [100, 1000, 10000] {
group.throughput(Throughput::Elements(size as u64));
group.throughput(Throughput::Elements(size));
group.bench_with_input(
BenchmarkId::new("sequential_counters", size),
@@ -69,7 +69,7 @@ fn bench_thread_safety(c: &mut Criterion) {
group.sample_size(1000);
for size in [100, 1000, 10000] {
group.throughput(Throughput::Elements(size as u64));
group.throughput(Throughput::Elements(size));
group.bench_with_input(
BenchmarkId::new("thread_safe_validator", size),
@@ -103,7 +103,7 @@ fn bench_window_sliding(c: &mut Criterion) {
group.sample_size(100);
for window_size in [128, 512, 1024] {
group.throughput(Throughput::Elements(window_size as u64));
group.throughput(Throughput::Elements(window_size));
group.bench_with_input(
BenchmarkId::new("window_sliding", window_size),
@@ -138,7 +138,7 @@ fn bench_core_operations(c: &mut Criterion) {
group.sample_size(1000);
// Create validators with different states
let mut empty_validator = ReceivingKeyCounterValidator::default();
let empty_validator = ReceivingKeyCounterValidator::default();
let mut half_full_validator = ReceivingKeyCounterValidator::default();
let mut full_validator = ReceivingKeyCounterValidator::default();
@@ -156,7 +156,8 @@ fn bench_core_operations(c: &mut Criterion) {
b.iter(|| {
let mut validator = empty_validator.clone();
// Force window sliding that will clear bitmap
black_box(validator.mark_did_receive_branchless(2000).unwrap());
let _: () = validator.mark_did_receive_branchless(2000).unwrap();
black_box(());
})
});
@@ -164,7 +165,8 @@ fn bench_core_operations(c: &mut Criterion) {
b.iter(|| {
let mut validator = half_full_validator.clone();
// Force window sliding that will clear bitmap
black_box(validator.mark_did_receive_branchless(2000).unwrap());
let _: () = validator.mark_did_receive_branchless(2000).unwrap();
black_box(());
})
});
@@ -172,7 +174,8 @@ fn bench_core_operations(c: &mut Criterion) {
b.iter(|| {
let mut validator = full_validator.clone();
// Force window sliding that will clear bitmap
black_box(validator.mark_did_receive_branchless(2000).unwrap());
let _: () = validator.mark_did_receive_branchless(2000).unwrap();
black_box(());
})
});
-16
View File
@@ -110,22 +110,6 @@ mod tests {
use crate::LpError;
use bytes::BytesMut;
// Helper function to create a test packet's BytesMut representation directly
fn create_test_packet_bytes(counter: u64, message: LpMessage, trailer_fill: u8) -> BytesMut {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
session_id: 42,
counter,
},
message,
trailer: [trailer_fill; TRAILER_LEN],
};
let mut buf = BytesMut::new();
serialize_lp_packet(&packet, &mut buf).unwrap();
buf
}
// === Updated Encode/Decode Tests ===
#[test]
+40 -40
View File
@@ -37,13 +37,13 @@ pub fn sessions_for_tests() -> (LpSession, LpSession) {
let keypair_1 = Keypair::default();
let keypair_2 = Keypair::default();
let id = make_lp_id(&keypair_1.public_key(), &keypair_2.public_key());
let id = make_lp_id(keypair_1.public_key(), keypair_2.public_key());
// Use consistent salt for deterministic tests
let salt = [1u8; 32];
// Initiator derives PSK from their perspective
let initiator_psk = derive_psk(keypair_1.private_key(), &keypair_2.public_key(), &salt);
let initiator_psk = derive_psk(keypair_1.private_key(), keypair_2.public_key(), &salt);
let initiator_session = LpSession::new(
id,
@@ -55,7 +55,7 @@ pub fn sessions_for_tests() -> (LpSession, LpSession) {
.expect("Test session creation failed");
// Responder derives same PSK from their perspective
let responder_psk = derive_psk(keypair_2.private_key(), &keypair_1.public_key(), &salt);
let responder_psk = derive_psk(keypair_2.private_key(), keypair_1.public_key(), &salt);
let responder_session = LpSession::new(
id,
@@ -69,6 +69,40 @@ pub fn sessions_for_tests() -> (LpSession, LpSession) {
(initiator_session, responder_session)
}
/// Generates a deterministic u32 session ID for the Lewes Protocol
/// based on two public keys. The order of the keys does not matter.
///
/// Uses a different internal delimiter than `make_conv_id` to avoid
/// potential collisions if the same key pairs were used in both contexts.
fn make_id(key1_bytes: &[u8], key2_bytes: &[u8], sep: u8) -> u32 {
let mut hasher = DefaultHasher::new();
// Ensure consistent order for hashing to make the ID order-independent.
// This guarantees make_lp_id(a, b) == make_lp_id(b, a).
if key1_bytes < key2_bytes {
hasher.write(key1_bytes);
// Use a delimiter specific to Lewes Protocol ID generation
// (0xCC chosen arbitrarily, could be any value different from 0xFF)
hasher.write_u8(sep);
hasher.write(key2_bytes);
} else {
hasher.write(key2_bytes);
hasher.write_u8(sep);
hasher.write(key1_bytes);
}
// Truncate the u64 hash result to u32
(hasher.finish() & 0xFFFF_FFFF) as u32
}
pub fn make_lp_id(key1_bytes: &PublicKey, key2_bytes: &PublicKey) -> u32 {
make_id(key1_bytes.as_bytes(), key2_bytes.as_bytes(), 0xCC)
}
pub fn make_conv_id(src: &[u8], dst: &[u8]) -> u32 {
make_id(src, dst, 0xFF)
}
#[cfg(test)]
mod tests {
use crate::keypair::Keypair;
@@ -184,12 +218,12 @@ mod tests {
let remote_manager = SessionManager::new();
let local_keypair = Keypair::default();
let remote_keypair = Keypair::default();
let lp_id = make_lp_id(&local_keypair.public_key(), &remote_keypair.public_key());
let lp_id = make_lp_id(local_keypair.public_key(), remote_keypair.public_key());
// Create a session via manager
let _ = local_manager
.create_session_state_machine(
&local_keypair,
&remote_keypair.public_key(),
remote_keypair.public_key(),
true,
&[2u8; 32],
)
@@ -198,7 +232,7 @@ mod tests {
let _ = remote_manager
.create_session_state_machine(
&remote_keypair,
&local_keypair.public_key(),
local_keypair.public_key(),
false,
&[2u8; 32],
)
@@ -293,37 +327,3 @@ mod tests {
// Do not mark received
}
}
/// Generates a deterministic u32 session ID for the Lewes Protocol
/// based on two public keys. The order of the keys does not matter.
///
/// Uses a different internal delimiter than `make_conv_id` to avoid
/// potential collisions if the same key pairs were used in both contexts.
fn make_id(key1_bytes: &[u8], key2_bytes: &[u8], sep: u8) -> u32 {
let mut hasher = DefaultHasher::new();
// Ensure consistent order for hashing to make the ID order-independent.
// This guarantees make_lp_id(a, b) == make_lp_id(b, a).
if key1_bytes < key2_bytes {
hasher.write(key1_bytes);
// Use a delimiter specific to Lewes Protocol ID generation
// (0xCC chosen arbitrarily, could be any value different from 0xFF)
hasher.write_u8(sep);
hasher.write(key2_bytes);
} else {
hasher.write(key2_bytes);
hasher.write_u8(sep);
hasher.write(key1_bytes);
}
// Truncate the u64 hash result to u32
(hasher.finish() & 0xFFFF_FFFF) as u32
}
pub fn make_lp_id(key1_bytes: &PublicKey, key2_bytes: &PublicKey) -> u32 {
make_id(key1_bytes.as_bytes(), key2_bytes.as_bytes(), 0xCC)
}
pub fn make_conv_id(src: &[u8], dst: &[u8]) -> u32 {
make_id(src, dst, 0xFF)
}
+9 -9
View File
@@ -71,12 +71,12 @@ mod tests {
// Derive PSK twice with same inputs
let psk1 = derive_psk(
keypair_1.private_key(),
&keypair_2.public_key(),
keypair_2.public_key(),
&salt,
);
let psk2 = derive_psk(
keypair_1.private_key(),
&keypair_2.public_key(),
keypair_2.public_key(),
&salt,
);
@@ -92,14 +92,14 @@ mod tests {
// Client derives PSK
let client_psk = derive_psk(
keypair_1.private_key(),
&keypair_2.public_key(),
keypair_2.public_key(),
&salt,
);
// Gateway derives PSK from their perspective
let gateway_psk = derive_psk(
keypair_2.private_key(),
&keypair_1.public_key(),
keypair_1.public_key(),
&salt,
);
@@ -117,8 +117,8 @@ mod tests {
let salt1 = [1u8; 32];
let salt2 = [2u8; 32];
let psk1 = derive_psk(keypair_1.private_key(), &keypair_2.public_key(), &salt1);
let psk2 = derive_psk(keypair_1.private_key(), &keypair_2.public_key(), &salt2);
let psk1 = derive_psk(keypair_1.private_key(), keypair_2.public_key(), &salt1);
let psk2 = derive_psk(keypair_1.private_key(), keypair_2.public_key(), &salt2);
assert_ne!(psk1, psk2, "Different salts should produce different PSKs");
}
@@ -130,8 +130,8 @@ mod tests {
let keypair_3 = Keypair::default();
let salt = [3u8; 32];
let psk1 = derive_psk(keypair_1.private_key(), &keypair_2.public_key(), &salt);
let psk2 = derive_psk(keypair_1.private_key(), &keypair_3.public_key(), &salt);
let psk1 = derive_psk(keypair_1.private_key(), keypair_2.public_key(), &salt);
let psk2 = derive_psk(keypair_1.private_key(), keypair_3.public_key(), &salt);
assert_ne!(
psk1, psk2,
@@ -145,7 +145,7 @@ mod tests {
let keypair_2 = Keypair::default();
let salt = [4u8; 32];
let psk = derive_psk(keypair_1.private_key(), &keypair_2.public_key(), &salt);
let psk = derive_psk(keypair_1.private_key(), keypair_2.public_key(), &salt);
assert_eq!(psk.len(), 32, "PSK should be exactly 32 bytes");
}
+2 -2
View File
@@ -728,7 +728,7 @@ mod tests {
// Check final state of the validator
let final_state = validator.lock().unwrap();
let (next, receive_cnt) = final_state.current_packet_cnt();
let (_next, receive_cnt) = final_state.current_packet_cnt();
// Verify that the received count matches our successful operations
assert_eq!(receive_cnt, total_successes as u64);
@@ -786,7 +786,7 @@ mod tests {
}
// Create a copy for comparison
let original_bitmap = validator.bitmap;
let _original_bitmap = validator.bitmap;
// Simulate SIMD clear (4 words at a time)
#[cfg(target_feature = "avx2")]
+1 -2
View File
@@ -450,13 +450,12 @@ mod tests {
let responder_session =
create_handshake_test_session(false, &responder_keys, &initiator_keys.public, &psk);
let mut initiator_to_responder_msg = None;
let mut responder_to_initiator_msg = None;
let mut rounds = 0;
const MAX_ROUNDS: usize = 10; // Safety break for the loop
// Start by priming the initiator message
initiator_to_responder_msg = initiator_session.prepare_handshake_message().unwrap().ok();
let mut initiator_to_responder_msg = initiator_session.prepare_handshake_message().unwrap().ok();
assert!(
initiator_to_responder_msg.is_some(),
"Initiator did not produce initial message"
+12 -12
View File
@@ -50,16 +50,16 @@ mod tests {
// 2. Generate keys and PSK
let peer_a_keys = Keypair::default();
let peer_b_keys = Keypair::default();
let lp_id = make_lp_id(&peer_a_keys.public_key(), &peer_b_keys.public_key());
let lp_id = make_lp_id(peer_a_keys.public_key(), peer_b_keys.public_key());
let psk = [1u8; 32]; // Define a pre-shared key for the test
// 4. Create sessions using the pre-built Noise states
let peer_a_sm = session_manager_1
.create_session_state_machine(&peer_a_keys, &peer_b_keys.public_key(), true, &psk)
.create_session_state_machine(&peer_a_keys, peer_b_keys.public_key(), true, &psk)
.expect("Failed to create session A");
let peer_b_sm = session_manager_2
.create_session_state_machine(&peer_b_keys, &peer_a_keys.public_key(), false, &psk)
.create_session_state_machine(&peer_b_keys, peer_a_keys.public_key(), false, &psk)
.expect("Failed to create session B");
// Verify session count
@@ -452,14 +452,14 @@ mod tests {
// 2. Setup sessions and complete handshake (similar to test_full_session_flow)
let peer_a_keys = Keypair::default();
let peer_b_keys = Keypair::default();
let lp_id = make_lp_id(&peer_a_keys.public_key(), &peer_b_keys.public_key());
let lp_id = make_lp_id(peer_a_keys.public_key(), peer_b_keys.public_key());
let psk = [2u8; 32];
let peer_a_sm = session_manager_1
.create_session_state_machine(&peer_a_keys, &peer_b_keys.public_key(), true, &psk)
.create_session_state_machine(&peer_a_keys, peer_b_keys.public_key(), true, &psk)
.unwrap();
let peer_b_sm = session_manager_2
.create_session_state_machine(&peer_b_keys, &peer_a_keys.public_key(), false, &psk)
.create_session_state_machine(&peer_b_keys, peer_a_keys.public_key(), false, &psk)
.unwrap();
// Drive handshake to completion (simplified)
@@ -618,11 +618,11 @@ mod tests {
let keys = Keypair::default();
let psk = [3u8; 32];
let lp_id = make_lp_id(&keys.public_key(), &keys.public_key());
let lp_id = make_lp_id(keys.public_key(), keys.public_key());
// 2. Create a session (using real noise state)
let _session = session_manager
.create_session_state_machine(&keys, &keys.public_key(), true, &psk)
.create_session_state_machine(&keys, keys.public_key(), true, &psk)
.expect("Failed to create session");
// 3. Try to get a non-existent session
@@ -638,7 +638,7 @@ mod tests {
// 5. Create and immediately remove a session
let _temp_session = session_manager
.create_session_state_machine(&keys, &keys.public_key(), true, &psk)
.create_session_state_machine(&keys, keys.public_key(), true, &psk)
.expect("Failed to create temp session");
assert!(
@@ -717,15 +717,15 @@ mod tests {
// 2. Generate keys and PSK
let peer_a_keys = Keypair::default();
let peer_b_keys = Keypair::default();
let lp_id = make_lp_id(&peer_a_keys.public_key(), &peer_b_keys.public_key());
let lp_id = make_lp_id(peer_a_keys.public_key(), peer_b_keys.public_key());
let psk = [1u8; 32];
// 3. Create sessions state machines
assert!(session_manager_1
.create_session_state_machine(&peer_a_keys, &peer_b_keys.public_key(), true, &psk) // Initiator
.create_session_state_machine(&peer_a_keys, peer_b_keys.public_key(), true, &psk) // Initiator
.is_ok());
assert!(session_manager_2
.create_session_state_machine(&peer_b_keys, &peer_a_keys.public_key(), false, &psk) // Responder
.create_session_state_machine(&peer_b_keys, peer_a_keys.public_key(), false, &psk) // Responder
.is_ok());
assert_eq!(session_manager_1.session_count(), 1);
+5 -5
View File
@@ -462,7 +462,7 @@ mod tests {
let psk = vec![0u8; 32];
let remote_pub_key = resp_key.public_key();
let initiator_sm = LpStateMachine::new(true, &init_key, &remote_pub_key, &psk);
let initiator_sm = LpStateMachine::new(true, &init_key, remote_pub_key, &psk);
assert!(initiator_sm.is_ok());
let initiator_sm = initiator_sm.unwrap();
assert!(matches!(
@@ -472,7 +472,7 @@ mod tests {
let init_session = initiator_sm.session().unwrap();
assert!(init_session.is_initiator());
let responder_sm = LpStateMachine::new(false, &resp_key, &init_key.public_key(), &psk);
let responder_sm = LpStateMachine::new(false, &resp_key, init_key.public_key(), &psk);
assert!(responder_sm.is_ok());
let responder_sm = responder_sm.unwrap();
assert!(matches!(
@@ -483,7 +483,7 @@ mod tests {
assert!(!resp_session.is_initiator());
// Check lp_id is the same
let expected_lp_id = make_lp_id(&init_key.public_key(), remote_pub_key);
let expected_lp_id = make_lp_id(init_key.public_key(), remote_pub_key);
assert_eq!(init_session.id(), expected_lp_id);
assert_eq!(resp_session.id(), expected_lp_id);
}
@@ -499,7 +499,7 @@ mod tests {
let mut initiator = LpStateMachine::new(
true, // is_initiator
&init_key,
&resp_key.public_key(),
resp_key.public_key(),
&psk.clone(),
)
.unwrap();
@@ -507,7 +507,7 @@ mod tests {
let mut responder = LpStateMachine::new(
false, // is_initiator
&resp_key,
&init_key.public_key(),
init_key.public_key(),
&psk,
)
.unwrap();
+4 -3
View File
@@ -79,9 +79,10 @@ impl LpRegistrationRequest {
ticket_type,
mode: RegistrationMode::Dvpn,
client_ip,
#[allow(clippy::expect_used)]
timestamp: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.expect("System time before UNIX epoch")
.as_secs(),
}
}
@@ -139,7 +140,7 @@ mod tests {
public_key: nym_crypto::asymmetric::x25519::PublicKey::from(nym_sphinx::PublicKey::from([1u8; 32])),
private_ipv4: Ipv4Addr::new(10, 0, 0, 1),
private_ipv6: Ipv6Addr::new(0xfc00, 0, 0, 0, 0, 0, 0, 1),
endpoint: "192.168.1.1:8080".parse().unwrap(),
endpoint: "192.168.1.1:8080".parse().expect("Valid test endpoint"),
}
}
@@ -162,7 +163,7 @@ mod tests {
assert_eq!(response.allocated_bandwidth, allocated_bandwidth);
assert_eq!(response.session_id, session_id);
let returned_gw_data = response.gateway_data.unwrap();
let returned_gw_data = response.gateway_data.expect("Gateway data should be present in success response");
assert_eq!(returned_gw_data.public_key, gateway_data.public_key);
assert_eq!(returned_gw_data.private_ipv4, gateway_data.private_ipv4);
assert_eq!(returned_gw_data.private_ipv6, gateway_data.private_ipv6);
@@ -259,18 +259,4 @@ async fn register_wg_peer(
},
client_id,
))
}
// Helper function to convert bandwidth to ClientBandwidth if needed
// This would integrate with the actual bandwidth controller
#[allow(dead_code)]
async fn store_client_bandwidth(
client_id: String,
bandwidth: i64,
_storage: &nym_gateway_storage::GatewayStorage,
) -> Result<(), GatewayError> {
// This would integrate with the actual bandwidth storage
// For now, just log it
info!("Storing bandwidth {} for client {}", bandwidth, client_id);
Ok(())
}