#![allow(unused_imports)]
#![allow(unused_variables)]
#![allow(unused_mut)]
#![allow(clippy::all)]
mod datapath {
use arcbox_net::datapath::ring::MpmcRing;
use arcbox_net::datapath::{DatapathStats, LockFreeRing, PacketPool, ZeroCopyPacket};
#[test]
fn test_packet_flow_through_datapath() {
let pool = PacketPool::new(64).unwrap();
let ring: LockFreeRing<u32> = LockFreeRing::new(64);
for i in 0..10 {
if let Some(idx) = pool.alloc_index() {
let buffer = unsafe { pool.get_mut(idx) };
buffer.as_full_mut_slice()[0..4].copy_from_slice(&[i as u8, 0, 0, 0]);
buffer.set_len(4);
ring.enqueue(idx).unwrap();
}
}
assert_eq!(ring.len(), 10);
for expected_i in 0..10 {
let idx = ring.dequeue().unwrap();
let buffer = unsafe { pool.get(idx) };
assert_eq!(buffer.as_full_slice()[0], expected_i as u8);
unsafe { pool.free_by_index(idx) };
}
assert!(ring.is_empty());
}
#[test]
fn test_batch_operations() {
let ring: LockFreeRing<u64> = LockFreeRing::new(128);
let items: Vec<u64> = (0..64).collect();
let enqueued = ring.enqueue_batch(&items);
assert_eq!(enqueued, 64);
let mut out = vec![0u64; 128];
let dequeued = ring.dequeue_batch(&mut out);
assert_eq!(dequeued, 64);
for i in 0..64 {
assert_eq!(out[i], i as u64);
}
}
#[test]
fn test_zero_copy_packet_metadata() {
let mut packet_data = vec![0u8; 64];
packet_data[12] = 0x08; packet_data[13] = 0x00;
packet_data[14] = 0x45; packet_data[23] = 6;
packet_data[26..30].copy_from_slice(&[192, 168, 1, 100]); packet_data[30..34].copy_from_slice(&[10, 0, 0, 1]);
packet_data[34..36].copy_from_slice(&8080u16.to_be_bytes()); packet_data[36..38].copy_from_slice(&80u16.to_be_bytes());
let packet = unsafe {
ZeroCopyPacket::from_raw_parts(packet_data.as_ptr(), packet_data.len() as u32, 0)
};
assert_eq!(packet.len(), 64);
assert_eq!(unsafe { packet.as_slice()[12] }, 0x08);
assert_eq!(unsafe { packet.as_slice()[13] }, 0x00);
}
#[test]
fn test_datapath_stats() {
let stats = DatapathStats::new();
for i in 0..100 {
stats.record_tx(1, (1000 + i) as u64);
stats.record_rx(1, (500 + i) as u64);
}
let snapshot = stats.snapshot();
assert_eq!(snapshot.tx_packets, 100);
assert_eq!(snapshot.rx_packets, 100);
assert!(snapshot.tx_bytes > 100_000);
assert!(snapshot.rx_bytes > 50_000);
for _ in 0..5 {
stats.record_tx_drop();
stats.record_rx_drop();
}
let snapshot = stats.snapshot();
assert_eq!(snapshot.tx_dropped, 5);
assert_eq!(snapshot.rx_dropped, 5);
}
#[test]
fn test_pool_exhaustion_recovery() {
let pool = PacketPool::new(8).unwrap();
let mut indices = Vec::new();
while let Some(idx) = pool.alloc_index() {
indices.push(idx);
}
assert_eq!(indices.len(), 8);
assert!(pool.alloc_index().is_none());
for idx in indices.drain(..4) {
unsafe { pool.free_by_index(idx) };
}
let new_idx = pool.alloc_index();
assert!(new_idx.is_some());
if let Some(idx) = new_idx {
unsafe { pool.free_by_index(idx) };
}
for idx in indices {
unsafe { pool.free_by_index(idx) };
}
}
#[test]
fn test_mpmc_ring_basic() {
let ring = MpmcRing::<u32>::new(16);
ring.enqueue(1).unwrap();
ring.enqueue(2).unwrap();
ring.enqueue(3).unwrap();
assert_eq!(ring.dequeue(), Some(1));
assert_eq!(ring.dequeue(), Some(2));
assert_eq!(ring.dequeue(), Some(3));
assert_eq!(ring.dequeue(), None);
}
}
mod nat_engine {
use arcbox_net::nat_engine::checksum::incremental_checksum_update_32;
use arcbox_net::nat_engine::{
NatDirection, NatEngine, NatEngineConfig, NatResult, incremental_checksum_update,
};
use std::net::Ipv4Addr;
fn create_tcp_packet(
src_ip: [u8; 4],
dst_ip: [u8; 4],
src_port: u16,
dst_port: u16,
) -> Vec<u8> {
let mut packet = vec![0u8; 54];
packet[12] = 0x08;
packet[13] = 0x00;
packet[14] = 0x45;
packet[23] = 6;
packet[26..30].copy_from_slice(&src_ip);
packet[30..34].copy_from_slice(&dst_ip);
packet[34..36].copy_from_slice(&src_port.to_be_bytes());
packet[36..38].copy_from_slice(&dst_port.to_be_bytes());
packet
}
#[test]
fn test_nat_roundtrip() {
let mut engine = NatEngine::with_external_ip(Ipv4Addr::new(203, 0, 113, 1));
engine.set_internal_network(Ipv4Addr::new(10, 0, 0, 0), 24);
let guest_ip = [10, 0, 0, 50];
let server_ip = [93, 184, 216, 34]; let guest_port = 45678u16;
let server_port = 443u16;
let mut outbound = create_tcp_packet(guest_ip, server_ip, guest_port, server_port);
let result = engine.translate(&mut outbound, NatDirection::Outbound);
assert_eq!(result.unwrap(), NatResult::Translated);
assert_eq!(&outbound[26..30], &[203, 0, 113, 1]);
let nat_port = u16::from_be_bytes([outbound[34], outbound[35]]);
assert_ne!(nat_port, guest_port);
let mut inbound = create_tcp_packet(server_ip, [203, 0, 113, 1], server_port, nat_port);
let result = engine.translate(&mut inbound, NatDirection::Inbound);
assert_eq!(result.unwrap(), NatResult::Translated);
assert_eq!(&inbound[30..34], &guest_ip);
let restored_port = u16::from_be_bytes([inbound[36], inbound[37]]);
assert_eq!(restored_port, guest_port);
}
#[test]
fn test_multiple_connections() {
let mut engine = NatEngine::with_external_ip(Ipv4Addr::new(198, 51, 100, 1));
engine.set_internal_network(Ipv4Addr::new(172, 16, 0, 0), 16);
let destinations = [
([1, 1, 1, 1], 53u16), ([8, 8, 8, 8], 53u16), ([93, 184, 216, 34], 80u16), ([93, 184, 216, 34], 443u16), ];
let mut nat_ports = Vec::new();
for (i, (dst_ip, dst_port)) in destinations.iter().enumerate() {
let src_ip = [172, 16, 0, (i + 1) as u8];
let src_port = (40000 + i) as u16;
let mut packet = create_tcp_packet(src_ip, *dst_ip, src_port, *dst_port);
let result = engine.translate(&mut packet, NatDirection::Outbound);
assert_eq!(result.unwrap(), NatResult::Translated);
let nat_port = u16::from_be_bytes([packet[34], packet[35]]);
nat_ports.push(nat_port);
}
let unique_ports: std::collections::HashSet<_> = nat_ports.iter().collect();
assert_eq!(unique_ports.len(), nat_ports.len());
assert_eq!(engine.connection_count(), 4);
}
#[test]
fn test_connection_expiration() {
let config = NatEngineConfig::new(Ipv4Addr::new(192, 0, 2, 1)).with_timeout(0);
let mut engine = NatEngine::new(&config);
engine.set_internal_network(Ipv4Addr::new(10, 10, 0, 0), 16);
let mut packet = create_tcp_packet([10, 10, 1, 1], [8, 8, 8, 8], 12345, 53);
engine
.translate(&mut packet, NatDirection::Outbound)
.unwrap();
assert_eq!(engine.connection_count(), 1);
let expired = engine.expire_connections();
assert!(expired == 0 || expired == 1);
}
#[test]
fn test_checksum_consistency() {
let old_checksum = 0xABCDu16;
let old_value = 0x1234u16;
let new_value = 0x5678u16;
let new_checksum = incremental_checksum_update(old_checksum, old_value, new_value);
assert_ne!(old_checksum, new_checksum);
let restored = incremental_checksum_update(new_checksum, new_value, old_value);
assert_eq!(restored, old_checksum);
}
#[test]
fn test_checksum_consistency_32bit() {
let old_checksum = 0xABCDu16;
let old_value = 0x12345678u32;
let new_value = 0x87654321u32;
let new_checksum = incremental_checksum_update_32(old_checksum, old_value, new_value);
assert_ne!(old_checksum, new_checksum);
let restored = incremental_checksum_update_32(new_checksum, new_value, old_value);
assert_eq!(restored, old_checksum);
}
#[test]
fn test_nat_udp() {
let mut engine = NatEngine::with_external_ip(Ipv4Addr::new(100, 64, 0, 1));
engine.set_internal_network(Ipv4Addr::new(192, 168, 100, 0), 24);
let mut packet = vec![0u8; 54];
packet[12] = 0x08; packet[13] = 0x00;
packet[14] = 0x45;
packet[23] = 17;
packet[26..30].copy_from_slice(&[192, 168, 100, 10]); packet[30..34].copy_from_slice(&[8, 8, 4, 4]);
packet[34..36].copy_from_slice(&54321u16.to_be_bytes()); packet[36..38].copy_from_slice(&53u16.to_be_bytes());
let result = engine.translate(&mut packet, NatDirection::Outbound);
assert_eq!(result.unwrap(), NatResult::Translated);
assert_eq!(&packet[26..30], &[100, 64, 0, 1]);
}
#[test]
fn test_passthrough_non_internal() {
let mut engine = NatEngine::with_external_ip(Ipv4Addr::new(1, 2, 3, 4));
engine.set_internal_network(Ipv4Addr::new(192, 168, 0, 0), 24);
let mut packet = create_tcp_packet(
[8, 8, 8, 8], [1, 1, 1, 1], 12345,
80,
);
let result = engine.translate(&mut packet, NatDirection::Outbound);
assert_eq!(result.unwrap(), NatResult::PassThrough);
assert_eq!(&packet[26..30], &[8, 8, 8, 8]);
}
#[test]
fn test_passthrough_icmp() {
let mut engine = NatEngine::with_external_ip(Ipv4Addr::new(1, 2, 3, 4));
engine.set_internal_network(Ipv4Addr::new(192, 168, 0, 0), 24);
let mut packet = vec![0u8; 54];
packet[12] = 0x08;
packet[13] = 0x00;
packet[14] = 0x45;
packet[23] = 1;
packet[26..30].copy_from_slice(&[192, 168, 0, 10]);
packet[30..34].copy_from_slice(&[8, 8, 8, 8]);
let result = engine.translate(&mut packet, NatDirection::Outbound);
assert_eq!(result.unwrap(), NatResult::PassThrough);
}
}
mod stress {
use arcbox_net::datapath::ring::MpmcRing;
use arcbox_net::datapath::{LockFreeRing, PacketPool};
use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
use std::thread;
#[test]
fn test_spsc_ring_stress() {
let ring = Arc::new(LockFreeRing::<u64>::new(4096));
let ring_producer = Arc::clone(&ring);
let ring_consumer = Arc::clone(&ring);
let count = 1_000_000u64;
let producer = thread::spawn(move || {
for i in 0..count {
loop {
if ring_producer.enqueue(i).is_ok() {
break;
}
std::hint::spin_loop();
}
}
});
let consumer = thread::spawn(move || {
let mut sum = 0u64;
let mut received = 0u64;
while received < count {
if let Some(v) = ring_consumer.dequeue() {
sum = sum.wrapping_add(v);
received += 1;
} else {
std::hint::spin_loop();
}
}
sum
});
producer.join().unwrap();
let sum = consumer.join().unwrap();
let expected = (count - 1) * count / 2;
assert_eq!(sum, expected);
}
#[test]
fn test_mpmc_ring_stress() {
let ring = Arc::new(MpmcRing::<u64>::new(1024));
let total_items = 100_000u64;
let num_producers = 4;
let num_consumers = 4;
let items_per_producer = total_items / num_producers as u64;
let produced = Arc::new(AtomicU64::new(0));
let consumed = Arc::new(AtomicU64::new(0));
let mut handles = Vec::new();
for p in 0..num_producers {
let ring: Arc<MpmcRing<u64>> = Arc::clone(&ring);
let produced = Arc::clone(&produced);
handles.push(thread::spawn(move || {
for i in 0..items_per_producer {
let value = p as u64 * items_per_producer + i;
loop {
if ring.enqueue(value).is_ok() {
produced.fetch_add(1, Ordering::Relaxed);
break;
}
std::hint::spin_loop();
}
}
}));
}
for _ in 0..num_consumers {
let ring: Arc<MpmcRing<u64>> = Arc::clone(&ring);
let consumed = Arc::clone(&consumed);
let produced = Arc::clone(&produced);
handles.push(thread::spawn(move || {
loop {
if ring.dequeue().is_some() {
consumed.fetch_add(1, Ordering::Relaxed);
} else if consumed.load(Ordering::Relaxed) >= total_items {
break;
} else if produced.load(Ordering::Relaxed) >= total_items
&& consumed.load(Ordering::Relaxed) >= total_items
{
break;
} else {
std::hint::spin_loop();
}
}
}));
}
for handle in handles {
handle.join().unwrap();
}
assert_eq!(consumed.load(Ordering::Relaxed), total_items);
}
#[test]
fn test_pool_concurrent_stress() {
let pool = Arc::new(PacketPool::new(256).unwrap());
let iterations = 10_000;
let num_threads = 4;
let mut handles = Vec::new();
for _ in 0..num_threads {
let pool = Arc::clone(&pool);
handles.push(thread::spawn(move || {
let mut allocated = Vec::new();
for _ in 0..iterations {
for _ in 0..4 {
if let Some(idx) = pool.alloc_index() {
allocated.push(idx);
}
}
while allocated.len() > 2 {
let idx = allocated.pop().unwrap();
unsafe { pool.free_by_index(idx) };
}
}
for idx in allocated {
unsafe { pool.free_by_index(idx) };
}
}));
}
for handle in handles {
handle.join().unwrap();
}
}
}
mod error_handling {
use arcbox_net::nat_engine::{NatDirection, NatEngine, TranslateError};
use std::net::Ipv4Addr;
#[test]
fn test_packet_too_short() {
let mut engine = NatEngine::with_external_ip(Ipv4Addr::new(1, 1, 1, 1));
let mut short_packet = vec![0u8; 10];
let result = engine.translate(&mut short_packet, NatDirection::Outbound);
assert!(matches!(result, Err(TranslateError::PacketTooShort)));
}
#[test]
fn test_invalid_ip_version() {
let mut engine = NatEngine::with_external_ip(Ipv4Addr::new(1, 1, 1, 1));
let mut packet = vec![0u8; 54];
packet[12] = 0x08;
packet[13] = 0x00;
packet[14] = 0x65;
let result = engine.translate(&mut packet, NatDirection::Outbound);
assert!(matches!(result, Err(TranslateError::InvalidIpHeader)));
}
#[test]
fn test_invalid_ihl() {
let mut engine = NatEngine::with_external_ip(Ipv4Addr::new(1, 1, 1, 1));
let mut packet = vec![0u8; 54];
packet[12] = 0x08;
packet[13] = 0x00;
packet[14] = 0x41;
let result = engine.translate(&mut packet, NatDirection::Outbound);
assert!(matches!(result, Err(TranslateError::InvalidIpHeader)));
}
#[test]
fn test_non_ipv4_passthrough() {
let mut engine = NatEngine::with_external_ip(Ipv4Addr::new(1, 1, 1, 1));
let mut packet = vec![0u8; 54];
packet[12] = 0x08;
packet[13] = 0x06;
let result = engine.translate(&mut packet, NatDirection::Outbound);
assert!(result.is_ok());
}
}
mod network_manager {
use arcbox_net::{NetConfig, NetworkManager, NetworkMode};
#[test]
fn test_network_manager_creation() {
let config = NetConfig::default();
let manager = NetworkManager::new(config);
assert_eq!(manager.config().mode, NetworkMode::Nat);
assert_eq!(manager.config().mtu, 1500);
assert!(!manager.config().multiqueue);
}
#[test]
fn test_network_manager_custom_config() {
let config = NetConfig {
mode: NetworkMode::Bridge,
mac: Some([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]),
mtu: 9000,
bridge: Some("br0".to_string()),
multiqueue: true,
num_queues: 4,
};
let manager = NetworkManager::new(config);
assert_eq!(manager.config().mode, NetworkMode::Bridge);
assert_eq!(manager.config().mtu, 9000);
assert!(manager.config().multiqueue);
assert_eq!(manager.config().num_queues, 4);
}
#[test]
fn test_network_manager_start_stop() {
let config = NetConfig::default();
let mut manager = NetworkManager::new(config);
assert!(manager.start().is_ok());
assert!(manager.stop().is_ok());
}
}