use super::*;
use crate::PeerIdentity;
use crate::transport::{LinkDirection, TransportAddr, packet_channel};
use crate::utils::index::SessionIndex;
use std::time::Duration;
mod acl;
#[cfg(target_os = "linux")]
mod ble;
mod bloom;
mod bloom_poison;
mod bootstrap;
mod decrypt_failure;
mod disconnect;
mod discovery;
#[cfg(target_os = "linux")]
mod ethernet;
mod forwarding;
mod handshake;
mod routing;
mod session;
mod spanning_tree;
mod tcp;
mod unit;
pub(super) fn make_node() -> Node {
let config = Config::new();
Node::new(config).unwrap()
}
pub(super) fn make_node_addr(val: u8) -> NodeAddr {
let mut bytes = [0u8; 16];
bytes[0] = val;
NodeAddr::from_bytes(bytes)
}
pub(super) fn make_peer_identity() -> PeerIdentity {
let identity = Identity::generate();
PeerIdentity::from_pubkey(identity.pubkey())
}
pub(super) fn seed_dataplane_fmp_srtt_for_test(node: &mut Node, peer_addr: NodeAddr, srtt_ms: u64) {
let peer_session_elapsed_ms = node
.get_peer(&peer_addr)
.expect("dataplane FMP SRTT seed needs an active peer")
.session_elapsed_ms();
assert!(node.sync_dataplane_fmp_owner(&peer_addr));
let srtt_ms = u32::try_from(srtt_ms).expect("test SRTT fits u32");
let now_ms = Node::now_ms().saturating_add(u64::from(srtt_ms) + 1);
let timestamp_echo = peer_session_elapsed_ms.saturating_add(1);
let report = crate::mmp::ReceiverReport {
highest_counter: 1,
cumulative_packets_recv: 1,
cumulative_bytes_recv: 128,
timestamp_echo,
dwell_time: 0,
max_burst_loss: 0,
mean_burst_loss: 0,
jitter: 0,
ecn_ce_count: 0,
owd_trend: 0,
burst_loss_count: 0,
cumulative_reorder_count: 0,
interval_packets_recv: 1,
interval_bytes_recv: 128,
};
node.dataplane
.process_fmp_mmp_receiver_report(&peer_addr, &report, now_ms, std::time::Instant::now())
.expect("dataplane FMP receiver report should process");
}
pub(super) fn seed_dataplane_fmp_rx_for_test(node: &mut Node, peer_addr: NodeAddr, age: Duration) {
assert!(node.sync_dataplane_fmp_owner(&peer_addr));
node.dataplane
.record_authenticated_fmp_mmp_receive(
crate::dataplane::DataplaneAuthenticatedFmpMmpReceive::new(
peer_addr,
1,
100,
64,
false,
false,
std::time::Instant::now() - age,
),
)
.expect("dataplane FMP receive bookkeeping should record");
}
fn populate_all_coord_caches(nodes: &mut [spanning_tree::TestNode]) {
let now_ms = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_millis() as u64;
let all_coords: Vec<(NodeAddr, crate::tree::TreeCoordinate)> = nodes
.iter()
.map(|tn| {
(
*tn.node.node_addr(),
tn.node.tree_state().my_coords().clone(),
)
})
.collect();
for tn in nodes.iter_mut() {
for (addr, coords) in &all_coords {
if addr != tn.node.node_addr() {
tn.node
.coord_cache_mut()
.insert(*addr, coords.clone(), now_ms);
}
}
}
}
pub(super) fn ensure_dataplane_fsp_owner_for_test(node: &mut Node, dest_addr: NodeAddr) {
node.dataplane.register_owner_if_missing(
crate::dataplane::OwnerId::fsp_node(dest_addr),
crate::dataplane::OwnerConfig::new(1, 8)
.with_fsp_session_start_ms(1_000)
.with_fsp_mmp(node.config.node.session_mmp.clone(), true),
);
}
pub(super) fn seed_dataplane_fsp_data_sent_for_test(
node: &mut Node,
dest_addr: NodeAddr,
next_hop: NodeAddr,
now_ms: u64,
) {
ensure_dataplane_fsp_owner_for_test(node, dest_addr);
assert!(node.dataplane.record_fsp_data_sent(
dest_addr,
next_hop,
512,
crate::dataplane::ActivityTick::new(now_ms),
));
}
pub(super) fn seed_dataplane_fsp_data_rx_for_test(
node: &mut Node,
source_addr: NodeAddr,
previous_hop: NodeAddr,
now_ms: u64,
) {
ensure_dataplane_fsp_owner_for_test(node, source_addr);
let body_len = 512;
assert!(
node.dataplane
.record_authenticated_fsp_session(
crate::dataplane::DataplaneAuthenticatedFspSession::new(
source_addr,
previous_hop,
crate::protocol::SessionMessageType::EndpointData.to_byte(),
body_len,
crate::dataplane::FspReceiveSync {
counter: 2,
received_k_bit: false,
timestamp: 0,
plaintext_len: crate::node::session_wire::FSP_INNER_HEADER_SIZE + body_len,
ce_flag: false,
path_mtu: u16::MAX,
spin_bit: false,
},
Some(crate::dataplane::ActivityTick::new(now_ms)),
std::time::Instant::now(),
),
)
.is_some()
);
}
pub(super) fn make_completed_connection(
node: &mut Node,
link_id: LinkId,
transport_id: TransportId,
current_time_ms: u64,
) -> (PeerConnection, PeerIdentity) {
let peer_identity_full = Identity::generate();
let peer_identity = PeerIdentity::from_pubkey_full(peer_identity_full.pubkey_full());
let mut conn = PeerConnection::outbound(link_id, peer_identity, current_time_ms);
let our_keypair = node.identity.keypair();
let msg1 = conn
.start_handshake(our_keypair, node.startup_epoch, current_time_ms)
.unwrap();
let mut resp_conn = PeerConnection::inbound(LinkId::new(999), current_time_ms);
let peer_keypair = peer_identity_full.keypair();
let mut resp_epoch = [0u8; 8];
rand::Rng::fill_bytes(&mut rand::rng(), &mut resp_epoch);
let msg2 = resp_conn
.receive_handshake_init(peer_keypair, resp_epoch, &msg1, current_time_ms)
.unwrap();
conn.complete_handshake(&msg2, current_time_ms).unwrap();
let our_index = node.index_allocator.allocate().unwrap();
conn.set_our_index(our_index);
conn.set_their_index(SessionIndex::new(42));
conn.set_transport_id(transport_id);
conn.set_source_addr(TransportAddr::from_string("127.0.0.1:5000"));
(conn, peer_identity)
}