2019-02-26 17:36:54 +00:00
|
|
|
// VpnCloud - Peer-to-Peer VPN
|
2021-02-08 09:11:20 +00:00
|
|
|
// Copyright (C) 2015-2021 Dennis Schwerdel
|
2019-02-26 17:36:54 +00:00
|
|
|
// This software is licensed under GPL-3 or newer (see LICENSE.md)
|
|
|
|
|
2019-12-04 12:09:20 +00:00
|
|
|
mod nat;
|
2019-02-26 17:36:54 +00:00
|
|
|
mod payload;
|
2019-12-04 08:32:35 +00:00
|
|
|
mod peers;
|
2019-02-26 17:36:54 +00:00
|
|
|
|
2019-12-04 12:09:20 +00:00
|
|
|
use std::{
|
2020-09-24 17:48:13 +00:00
|
|
|
collections::{HashMap, VecDeque},
|
2019-12-04 12:09:20 +00:00
|
|
|
io::Write,
|
2021-02-03 21:44:31 +00:00
|
|
|
net::SocketAddr,
|
2019-12-04 12:09:20 +00:00
|
|
|
sync::{
|
|
|
|
atomic::{AtomicUsize, Ordering},
|
|
|
|
Once
|
|
|
|
}
|
|
|
|
};
|
2019-12-04 08:32:35 +00:00
|
|
|
|
|
|
|
pub use super::{
|
|
|
|
cloud::GenericCloud,
|
2020-09-24 17:48:13 +00:00
|
|
|
config::{Config, CryptoConfig},
|
|
|
|
device::{MockDevice, Type},
|
2019-12-04 08:32:35 +00:00
|
|
|
net::MockSocket,
|
2020-09-24 17:48:13 +00:00
|
|
|
payload::{Frame, Packet, Protocol},
|
|
|
|
types::Range,
|
|
|
|
util::{MockTimeSource, Time, TimeSource}
|
2019-12-04 08:32:35 +00:00
|
|
|
};
|
2019-02-26 17:36:54 +00:00
|
|
|
|
|
|
|
|
2019-12-04 12:09:20 +00:00
|
|
|
static INIT_LOGGER: Once = Once::new();
|
|
|
|
|
|
|
|
pub fn init_debug_logger() {
|
|
|
|
INIT_LOGGER.call_once(|| {
|
|
|
|
log::set_boxed_logger(Box::new(DebugLogger)).unwrap();
|
|
|
|
log::set_max_level(log::LevelFilter::Debug);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-09-24 17:48:13 +00:00
|
|
|
static CURRENT_NODE: AtomicUsize = AtomicUsize::new(0);
|
|
|
|
|
2019-12-04 12:09:20 +00:00
|
|
|
struct DebugLogger;
|
|
|
|
|
2020-09-24 17:48:13 +00:00
|
|
|
impl DebugLogger {
|
|
|
|
pub fn set_node(node: usize) {
|
|
|
|
CURRENT_NODE.store(node, Ordering::SeqCst);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-04 12:09:20 +00:00
|
|
|
impl log::Log for DebugLogger {
|
|
|
|
#[inline]
|
|
|
|
fn enabled(&self, _metadata: &log::Metadata) -> bool {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn log(&self, record: &log::Record) {
|
|
|
|
if self.enabled(record.metadata()) {
|
2020-09-24 17:48:13 +00:00
|
|
|
eprintln!("Node {} - {} - {}", CURRENT_NODE.load(Ordering::SeqCst), record.level(), record.args());
|
2019-12-04 12:09:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn flush(&self) {
|
|
|
|
std::io::stderr().flush().expect("Failed to flush")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-09-24 17:48:13 +00:00
|
|
|
type TestNode<P> = GenericCloud<MockDevice, P, MockSocket, MockTimeSource>;
|
|
|
|
|
|
|
|
pub struct Simulator<P: Protocol> {
|
|
|
|
next_port: u16,
|
|
|
|
nodes: HashMap<SocketAddr, TestNode<P>>,
|
|
|
|
messages: VecDeque<(SocketAddr, SocketAddr, Vec<u8>)>
|
|
|
|
}
|
2019-02-26 17:36:54 +00:00
|
|
|
|
2020-09-24 17:48:13 +00:00
|
|
|
pub type TapSimulator = Simulator<Frame>;
|
2019-03-02 11:23:12 +00:00
|
|
|
#[allow(dead_code)]
|
2020-09-24 17:48:13 +00:00
|
|
|
pub type TunSimulator = Simulator<Packet>;
|
2019-02-26 17:36:54 +00:00
|
|
|
|
|
|
|
|
2020-09-24 17:48:13 +00:00
|
|
|
impl<P: Protocol> Simulator<P> {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
init_debug_logger();
|
|
|
|
MockTimeSource::set_time(0);
|
|
|
|
Self { next_port: 1, nodes: HashMap::default(), messages: VecDeque::default() }
|
|
|
|
}
|
2019-03-01 15:36:18 +00:00
|
|
|
|
2020-09-24 17:48:13 +00:00
|
|
|
pub fn add_node(&mut self, nat: bool, config: &Config) -> SocketAddr {
|
|
|
|
let mut config = config.clone();
|
|
|
|
MockSocket::set_nat(nat);
|
2021-02-03 21:44:31 +00:00
|
|
|
config.listen = format!("[::]:{}", self.next_port);
|
2021-02-04 22:38:08 +00:00
|
|
|
let addr = config.listen.parse::<SocketAddr>().unwrap();
|
2020-09-24 17:48:13 +00:00
|
|
|
if config.crypto.password.is_none() && config.crypto.private_key.is_none() {
|
|
|
|
config.crypto.password = Some("test123".to_string())
|
|
|
|
}
|
|
|
|
DebugLogger::set_node(self.next_port as usize);
|
|
|
|
self.next_port += 1;
|
2021-02-03 21:44:31 +00:00
|
|
|
let node = TestNode::new(&config, MockSocket::new(addr), MockDevice::new(), None, None);
|
2020-09-24 17:48:13 +00:00
|
|
|
DebugLogger::set_node(0);
|
2021-02-03 21:44:31 +00:00
|
|
|
self.nodes.insert(addr, node);
|
|
|
|
addr
|
2020-09-24 17:48:13 +00:00
|
|
|
}
|
2020-02-20 15:25:35 +00:00
|
|
|
|
2020-09-24 17:48:13 +00:00
|
|
|
#[allow(dead_code)]
|
|
|
|
pub fn get_node(&mut self, addr: SocketAddr) -> &mut TestNode<P> {
|
|
|
|
let node = self.nodes.get_mut(&addr).unwrap();
|
|
|
|
DebugLogger::set_node(node.get_num());
|
|
|
|
node
|
|
|
|
}
|
2019-03-03 13:56:59 +00:00
|
|
|
|
2020-09-24 17:48:13 +00:00
|
|
|
pub fn simulate_next_message(&mut self) {
|
|
|
|
if let Some((src, dst, data)) = self.messages.pop_front() {
|
|
|
|
if let Some(node) = self.nodes.get_mut(&dst) {
|
|
|
|
if node.socket().put_inbound(src, data) {
|
|
|
|
DebugLogger::set_node(node.get_num());
|
|
|
|
node.trigger_socket_event();
|
|
|
|
DebugLogger::set_node(0);
|
|
|
|
let sock = node.socket();
|
|
|
|
let src = dst;
|
|
|
|
while let Some((dst, data)) = sock.pop_outbound() {
|
|
|
|
self.messages.push_back((src, dst, data));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
warn!("Message to unknown node {}", dst);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-02-26 17:36:54 +00:00
|
|
|
|
2020-09-24 17:48:13 +00:00
|
|
|
pub fn simulate_all_messages(&mut self) {
|
|
|
|
while !self.messages.is_empty() {
|
|
|
|
self.simulate_next_message()
|
|
|
|
}
|
|
|
|
}
|
2019-02-26 17:36:54 +00:00
|
|
|
|
2020-09-24 17:48:13 +00:00
|
|
|
pub fn trigger_node_housekeep(&mut self, addr: SocketAddr) {
|
|
|
|
let node = self.nodes.get_mut(&addr).unwrap();
|
|
|
|
DebugLogger::set_node(node.get_num());
|
|
|
|
node.trigger_housekeep();
|
|
|
|
DebugLogger::set_node(0);
|
|
|
|
let sock = node.socket();
|
|
|
|
while let Some((dst, data)) = sock.pop_outbound() {
|
|
|
|
self.messages.push_back((addr, dst, data));
|
|
|
|
}
|
|
|
|
}
|
2019-02-26 17:36:54 +00:00
|
|
|
|
2020-09-24 17:48:13 +00:00
|
|
|
pub fn trigger_housekeep(&mut self) {
|
|
|
|
for (src, node) in &mut self.nodes {
|
|
|
|
DebugLogger::set_node(node.get_num());
|
|
|
|
node.trigger_housekeep();
|
|
|
|
DebugLogger::set_node(0);
|
|
|
|
let sock = node.socket();
|
|
|
|
while let Some((dst, data)) = sock.pop_outbound() {
|
|
|
|
self.messages.push_back((*src, dst, data));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-02-26 17:36:54 +00:00
|
|
|
|
2020-09-24 17:48:13 +00:00
|
|
|
pub fn set_time(&mut self, time: Time) {
|
|
|
|
MockTimeSource::set_time(time);
|
2019-12-04 12:09:20 +00:00
|
|
|
}
|
2019-02-26 17:36:54 +00:00
|
|
|
|
2020-09-24 17:48:13 +00:00
|
|
|
pub fn simulate_time(&mut self, time: Time) {
|
|
|
|
let mut t = MockTimeSource::now();
|
|
|
|
while t < time {
|
|
|
|
t += 1;
|
|
|
|
self.set_time(t);
|
|
|
|
self.trigger_housekeep();
|
|
|
|
self.simulate_all_messages();
|
2019-02-26 17:36:54 +00:00
|
|
|
}
|
|
|
|
}
|
2020-09-24 17:48:13 +00:00
|
|
|
|
|
|
|
pub fn connect(&mut self, src: SocketAddr, dst: SocketAddr) {
|
|
|
|
let node = self.nodes.get_mut(&src).unwrap();
|
|
|
|
DebugLogger::set_node(node.get_num());
|
|
|
|
node.connect(dst).unwrap();
|
|
|
|
DebugLogger::set_node(0);
|
|
|
|
let sock = node.socket();
|
|
|
|
while let Some((dst, data)) = sock.pop_outbound() {
|
|
|
|
self.messages.push_back((src, dst, data));
|
2019-02-26 17:36:54 +00:00
|
|
|
}
|
2020-09-24 17:48:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_connected(&self, src: SocketAddr, dst: SocketAddr) -> bool {
|
|
|
|
self.nodes.get(&src).unwrap().is_connected(&dst)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
pub fn node_addresses(&self) -> Vec<SocketAddr> {
|
|
|
|
self.nodes.keys().copied().collect()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
pub fn message_count(&self) -> usize {
|
|
|
|
self.messages.len()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn put_payload(&mut self, addr: SocketAddr, data: Vec<u8>) {
|
|
|
|
let node = self.nodes.get_mut(&addr).unwrap();
|
|
|
|
node.device().put_inbound(data);
|
|
|
|
DebugLogger::set_node(node.get_num());
|
|
|
|
node.trigger_device_event();
|
|
|
|
DebugLogger::set_node(0);
|
|
|
|
let sock = node.socket();
|
|
|
|
while let Some((dst, data)) = sock.pop_outbound() {
|
|
|
|
self.messages.push_back((addr, dst, data));
|
2019-02-26 17:36:54 +00:00
|
|
|
}
|
|
|
|
}
|
2020-09-24 17:48:13 +00:00
|
|
|
|
|
|
|
pub fn pop_payload(&mut self, node: SocketAddr) -> Option<Vec<u8>> {
|
|
|
|
self.nodes.get_mut(&node).unwrap().device().pop_outbound()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn drop_message(&mut self) {
|
|
|
|
self.messages.pop_front();
|
|
|
|
}
|
2019-12-04 08:32:35 +00:00
|
|
|
}
|