mirror of https://github.com/dswd/vpncloud.git
Compare commits
3 Commits
8e581ad005
...
43382bbe33
Author | SHA1 | Date |
---|---|---|
Dennis Schwerdel | 43382bbe33 | |
Dennis Schwerdel | 35c2b3479f | |
Dennis Schwerdel | 4f2b09d92c |
|
@ -69,9 +69,9 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.60"
|
version = "1.0.61"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c"
|
checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
|
@ -461,9 +461,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.58"
|
version = "1.0.59"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a230ea9107ca2220eea9d46de97eddcb04cd00e92d13dda78e478dd33fa82bd4"
|
checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
@ -512,9 +512,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "standback"
|
name = "standback"
|
||||||
version = "0.2.10"
|
version = "0.2.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "33a71ea1ea5f8747d1af1979bfb7e65c3a025a70609f04ceb78425bc5adad8e6"
|
checksum = "f4e0831040d2cf2bdfd51b844be71885783d489898a192f254ae25d57cce725c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
@ -600,9 +600,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.42"
|
version = "1.0.45"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c51d92969d209b54a98397e1b91c8ae82d8c87a7bb87df0b29aa2ad81454228"
|
checksum = "ea9c5432ff16d6152371f808fb5a871cd67368171b09bb21b43df8e4a47a3556"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
@ -388,6 +388,7 @@ pub struct InitState<P: Payload> {
|
||||||
last_message: Option<Vec<u8>>,
|
last_message: Option<Vec<u8>>,
|
||||||
crypto: Option<CryptoCore>,
|
crypto: Option<CryptoCore>,
|
||||||
algorithms: Algorithms,
|
algorithms: Algorithms,
|
||||||
|
selected_algorithm: Option<&'static Algorithm>,
|
||||||
failed_retries: usize
|
failed_retries: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,6 +414,7 @@ impl<P: Payload> InitState<P> {
|
||||||
last_message: None,
|
last_message: None,
|
||||||
crypto: None,
|
crypto: None,
|
||||||
ecdh_private_key: None,
|
ecdh_private_key: None,
|
||||||
|
selected_algorithm: None,
|
||||||
algorithms,
|
algorithms,
|
||||||
failed_retries: 0,
|
failed_retries: 0,
|
||||||
close_time: 60
|
close_time: 60
|
||||||
|
@ -605,6 +607,7 @@ impl<P: Payload> InitState<P> {
|
||||||
|
|
||||||
// do ecdh agreement and derive master key
|
// do ecdh agreement and derive master key
|
||||||
let algorithm = self.select_algorithm(&algorithms)?;
|
let algorithm = self.select_algorithm(&algorithms)?;
|
||||||
|
self.selected_algorithm = algorithm.map(|a| a.0);
|
||||||
if let Some((algorithm, _speed)) = algorithm {
|
if let Some((algorithm, _speed)) = algorithm {
|
||||||
let master_key = self.derive_master_key(algorithm, my_ecdh_private_key, &ecdh_public_key);
|
let master_key = self.derive_master_key(algorithm, my_ecdh_private_key, &ecdh_public_key);
|
||||||
self.crypto = Some(CryptoCore::new(master_key, self.salted_node_id_hash > salted_node_id_hash));
|
self.crypto = Some(CryptoCore::new(master_key, self.salted_node_id_hash > salted_node_id_hash));
|
||||||
|
@ -620,6 +623,7 @@ impl<P: Payload> InitState<P> {
|
||||||
// do ecdh agreement and derive master key
|
// do ecdh agreement and derive master key
|
||||||
let ecdh_private_key = self.ecdh_private_key.take().unwrap();
|
let ecdh_private_key = self.ecdh_private_key.take().unwrap();
|
||||||
let algorithm = self.select_algorithm(&algorithms)?;
|
let algorithm = self.select_algorithm(&algorithms)?;
|
||||||
|
self.selected_algorithm = algorithm.map(|a| a.0);
|
||||||
if let Some((algorithm, _speed)) = algorithm {
|
if let Some((algorithm, _speed)) = algorithm {
|
||||||
let master_key = self.derive_master_key(algorithm, ecdh_private_key, &ecdh_public_key);
|
let master_key = self.derive_master_key(algorithm, ecdh_private_key, &ecdh_public_key);
|
||||||
self.crypto = Some(CryptoCore::new(master_key, self.salted_node_id_hash > salted_node_id_hash));
|
self.crypto = Some(CryptoCore::new(master_key, self.salted_node_id_hash > salted_node_id_hash));
|
||||||
|
@ -793,11 +797,138 @@ mod tests {
|
||||||
assert_eq!(sender.stage(), CLOSING);
|
assert_eq!(sender.stage(), CLOSING);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Test: duplicated message or replay attacks
|
#[test]
|
||||||
|
fn untrusted_peer() {
|
||||||
|
let (mut sender, _) = create_pair();
|
||||||
|
let (_, mut receiver) = create_pair();
|
||||||
|
let mut out = MsgBuffer::new(8);
|
||||||
|
sender.send_ping(&mut out);
|
||||||
|
assert_eq!(sender.stage(), STAGE_PONG);
|
||||||
|
assert!(receiver.handle_init(&mut out).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
// TODO Test: untrusted peers
|
#[test]
|
||||||
|
fn manipulated_message() {
|
||||||
|
let (mut sender, mut receiver) = create_pair();
|
||||||
|
let mut out = MsgBuffer::new(8);
|
||||||
|
sender.send_ping(&mut out);
|
||||||
|
assert_eq!(sender.stage(), STAGE_PONG);
|
||||||
|
out.message_mut()[10] ^= 0x01;
|
||||||
|
assert!(receiver.handle_init(&mut out).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
// TODO Test: manipulated message
|
#[test]
|
||||||
|
fn connect_to_self() {
|
||||||
|
let (mut sender, _) = create_pair();
|
||||||
|
let mut out = MsgBuffer::new(8);
|
||||||
|
sender.send_ping(&mut out);
|
||||||
|
assert_eq!(sender.stage(), STAGE_PONG);
|
||||||
|
assert!(sender.handle_init(&mut out).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
// TODO Test: algorithm negotiation
|
fn test_algorithm_negotiation(
|
||||||
|
algos1: Algorithms, algos2: Algorithms, success: bool, selected: Option<&'static Algorithm>
|
||||||
|
) {
|
||||||
|
let (mut sender, mut receiver) = create_pair();
|
||||||
|
sender.algorithms = algos1;
|
||||||
|
receiver.algorithms = algos2;
|
||||||
|
let mut out = MsgBuffer::new(8);
|
||||||
|
sender.send_ping(&mut out);
|
||||||
|
let res = receiver.handle_init(&mut out);
|
||||||
|
assert_eq!(res.is_ok(), success);
|
||||||
|
if !success {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sender.handle_init(&mut out).unwrap();
|
||||||
|
receiver.handle_init(&mut out).unwrap();
|
||||||
|
assert_eq!(sender.selected_algorithm, selected);
|
||||||
|
assert_eq!(sender.selected_algorithm, receiver.selected_algorithm);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn algorithm_negotiation() {
|
||||||
|
// Equal algorithms
|
||||||
|
test_algorithm_negotiation(
|
||||||
|
Algorithms {
|
||||||
|
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
|
||||||
|
allow_unencrypted: false
|
||||||
|
},
|
||||||
|
Algorithms {
|
||||||
|
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
|
||||||
|
allow_unencrypted: false
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
Some(&AES_128_GCM)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Overlapping but different
|
||||||
|
test_algorithm_negotiation(
|
||||||
|
Algorithms {
|
||||||
|
algorithm_speeds: smallvec![(&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
|
||||||
|
allow_unencrypted: false
|
||||||
|
},
|
||||||
|
Algorithms {
|
||||||
|
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0)],
|
||||||
|
allow_unencrypted: false
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
Some(&AES_256_GCM)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Select fastest pair
|
||||||
|
test_algorithm_negotiation(
|
||||||
|
Algorithms {
|
||||||
|
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
|
||||||
|
allow_unencrypted: false
|
||||||
|
},
|
||||||
|
Algorithms {
|
||||||
|
algorithm_speeds: smallvec![(&AES_128_GCM, 40.0), (&AES_256_GCM, 50.0), (&CHACHA20_POLY1305, 60.0)],
|
||||||
|
allow_unencrypted: false
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
Some(&CHACHA20_POLY1305)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Select unencrypted if supported by both
|
||||||
|
test_algorithm_negotiation(
|
||||||
|
Algorithms {
|
||||||
|
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
|
||||||
|
allow_unencrypted: true
|
||||||
|
},
|
||||||
|
Algorithms {
|
||||||
|
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
|
||||||
|
allow_unencrypted: true
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
None
|
||||||
|
);
|
||||||
|
|
||||||
|
// Do not select unencrypted if only supported by one
|
||||||
|
test_algorithm_negotiation(
|
||||||
|
Algorithms {
|
||||||
|
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
|
||||||
|
allow_unencrypted: true
|
||||||
|
},
|
||||||
|
Algorithms {
|
||||||
|
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
|
||||||
|
allow_unencrypted: false
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
Some(&AES_128_GCM)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fail if no match
|
||||||
|
test_algorithm_negotiation(
|
||||||
|
Algorithms {
|
||||||
|
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0)],
|
||||||
|
allow_unencrypted: true
|
||||||
|
},
|
||||||
|
Algorithms {
|
||||||
|
algorithm_speeds: smallvec![(&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
|
||||||
|
allow_unencrypted: false
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
Some(&AES_128_GCM)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -318,9 +318,91 @@ mod tests {
|
||||||
assert_eq!(key.use_for_sending, true);
|
assert_eq!(key.use_for_sending, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test duplication
|
#[test]
|
||||||
|
fn test_duplication() {
|
||||||
|
let mut out1 = MsgBuffer::new(8);
|
||||||
|
let mut out2 = MsgBuffer::new(8);
|
||||||
|
|
||||||
// TODO: test lost message
|
let mut node1 = RotationState::new(true, &mut out1).unwrap();
|
||||||
|
let mut node2 = RotationState::new(false, &mut out2).unwrap();
|
||||||
|
let msg1 = out1.clone().msg().unwrap();
|
||||||
|
let msg1_copy = out1.msg().unwrap();
|
||||||
|
node2.process_message(msg1);
|
||||||
|
assert!(node2.process_message(msg1_copy).is_none());
|
||||||
|
node1.cycle(&mut out1).unwrap();
|
||||||
|
node2.cycle(&mut out2).unwrap();
|
||||||
|
let msg2 = out2.clone().msg().unwrap();
|
||||||
|
let msg2_copy = out2.msg().unwrap();
|
||||||
|
// Message 2
|
||||||
|
assert!(node1.process_message(msg2).is_some());
|
||||||
|
assert!(node1.process_message(msg2_copy).is_none());
|
||||||
|
// Cycle 2
|
||||||
|
node1.cycle(&mut out1).unwrap();
|
||||||
|
node2.cycle(&mut out2).unwrap();
|
||||||
|
let msg1 = out1.clone().msg().unwrap();
|
||||||
|
let msg1_copy = out1.msg().unwrap();
|
||||||
|
// Message 3
|
||||||
|
assert!(node2.process_message(msg1).is_some());
|
||||||
|
assert!(node2.process_message(msg1_copy).is_none());
|
||||||
|
// Cycle 3
|
||||||
|
node1.cycle(&mut out1).unwrap();
|
||||||
|
node2.cycle(&mut out2).unwrap();
|
||||||
|
let msg2 = out2.clone().msg().unwrap();
|
||||||
|
let msg2_copy = out2.msg().unwrap();
|
||||||
|
// Message 4
|
||||||
|
assert!(node1.process_message(msg2).is_some());
|
||||||
|
assert!(node1.process_message(msg2_copy).is_none());
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: test potential attack: reflect message back to sender
|
#[test]
|
||||||
|
fn test_lost_message() {
|
||||||
|
let mut out1 = MsgBuffer::new(8);
|
||||||
|
let mut out2 = MsgBuffer::new(8);
|
||||||
|
|
||||||
|
let mut node1 = RotationState::new(true, &mut out1).unwrap();
|
||||||
|
let mut node2 = RotationState::new(false, &mut out2).unwrap();
|
||||||
|
let _msg1 = out1.msg().unwrap();
|
||||||
|
// drop msg1
|
||||||
|
node1.cycle(&mut out1).unwrap();
|
||||||
|
node2.cycle(&mut out2).unwrap();
|
||||||
|
assert!(out2.msg().is_none());
|
||||||
|
// Cycle 2
|
||||||
|
node1.cycle(&mut out1).unwrap();
|
||||||
|
node2.cycle(&mut out2).unwrap();
|
||||||
|
let msg1 = out1.msg().unwrap();
|
||||||
|
// Message 3
|
||||||
|
assert!(node2.process_message(msg1).is_none());
|
||||||
|
// Cycle 3
|
||||||
|
node1.cycle(&mut out1).unwrap();
|
||||||
|
node2.cycle(&mut out2).unwrap();
|
||||||
|
let msg2 = out2.msg().unwrap();
|
||||||
|
// Message 4
|
||||||
|
assert!(node1.process_message(msg2).is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_reflect_back() {
|
||||||
|
let mut out1 = MsgBuffer::new(8);
|
||||||
|
let mut out2 = MsgBuffer::new(8);
|
||||||
|
|
||||||
|
let mut node1 = RotationState::new(true, &mut out1).unwrap();
|
||||||
|
let mut node2 = RotationState::new(false, &mut out2).unwrap();
|
||||||
|
let msg1 = out1.msg().unwrap();
|
||||||
|
assert!(node1.process_message(msg1).is_none());
|
||||||
|
node1.cycle(&mut out1).unwrap();
|
||||||
|
node2.cycle(&mut out2).unwrap();
|
||||||
|
assert!(out2.msg().is_none());
|
||||||
|
// Cycle 2
|
||||||
|
node1.cycle(&mut out1).unwrap();
|
||||||
|
node2.cycle(&mut out2).unwrap();
|
||||||
|
let msg1 = out1.msg().unwrap();
|
||||||
|
// Message 3
|
||||||
|
assert!(node2.process_message(msg1).is_none());
|
||||||
|
// Cycle 3
|
||||||
|
node1.cycle(&mut out1).unwrap();
|
||||||
|
node2.cycle(&mut out2).unwrap();
|
||||||
|
let msg2 = out2.msg().unwrap();
|
||||||
|
// Message 4
|
||||||
|
assert!(node1.process_message(msg2).is_some());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
types::{Address, Range, RangeList},
|
types::{Address, Range, RangeList},
|
||||||
util::{Duration, Time, TimeSource, addr_nice}
|
util::{addr_nice, Duration, Time, TimeSource}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,3 +132,5 @@ impl<TS: TimeSource> ClaimTable<TS> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: test
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ethernet_delivers() {
|
fn switch_delivers() {
|
||||||
let config = Config { device_type: Type::Tap, ..Config::default() };
|
let config = Config { device_type: Type::Tap, ..Config::default() };
|
||||||
let mut sim = TapSimulator::new();
|
let mut sim = TapSimulator::new();
|
||||||
let node1 = sim.add_node(false, &config);
|
let node1 = sim.add_node(false, &config);
|
||||||
|
@ -66,20 +66,119 @@ fn switch_learns() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn switch_honours_vlans() {
|
fn switch_honours_vlans() {
|
||||||
// TODO Test
|
let config = Config { device_type: Type::Tap, ..Config::default() };
|
||||||
|
let mut sim = TapSimulator::new();
|
||||||
|
let node1 = sim.add_node(false, &config);
|
||||||
|
let node2 = sim.add_node(false, &config);
|
||||||
|
let node3 = sim.add_node(false, &config);
|
||||||
|
|
||||||
|
sim.connect(node1, node2);
|
||||||
|
sim.connect(node1, node3);
|
||||||
|
sim.connect(node2, node3);
|
||||||
|
sim.simulate_all_messages();
|
||||||
|
assert!(sim.is_connected(node1, node2));
|
||||||
|
assert!(sim.is_connected(node2, node1));
|
||||||
|
assert!(sim.is_connected(node1, node3));
|
||||||
|
assert!(sim.is_connected(node3, node1));
|
||||||
|
assert!(sim.is_connected(node2, node3));
|
||||||
|
assert!(sim.is_connected(node3, node2));
|
||||||
|
|
||||||
|
let payload = vec![2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0x81, 0, 0, 0x67, 1, 2, 3, 4, 5];
|
||||||
|
|
||||||
|
// Nothing learnt so far, node1 broadcasts
|
||||||
|
|
||||||
|
sim.put_payload(node1, payload.clone());
|
||||||
|
sim.simulate_all_messages();
|
||||||
|
|
||||||
|
assert_eq!(Some(payload.clone()), sim.pop_payload(node2));
|
||||||
|
assert_eq!(Some(payload), sim.pop_payload(node3));
|
||||||
|
|
||||||
|
let payload = vec![1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 0x81, 0, 0, 0x67, 5, 4, 3, 2, 1];
|
||||||
|
|
||||||
|
// Node 2 learned the address by receiving it, does not broadcast
|
||||||
|
|
||||||
|
sim.put_payload(node2, payload.clone());
|
||||||
|
sim.simulate_all_messages();
|
||||||
|
|
||||||
|
assert_eq!(Some(payload), sim.pop_payload(node1));
|
||||||
|
assert_eq!(None, sim.pop_payload(node3));
|
||||||
|
|
||||||
|
let payload = vec![1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 0x81, 0, 0, 0x68, 5, 4, 3, 2, 1];
|
||||||
|
|
||||||
|
// Different VLANs, node 2 does not learn, still broadcasts
|
||||||
|
|
||||||
|
sim.put_payload(node2, payload.clone());
|
||||||
|
sim.simulate_all_messages();
|
||||||
|
|
||||||
|
assert_eq!(Some(payload.clone()), sim.pop_payload(node1));
|
||||||
|
assert_eq!(Some(payload), sim.pop_payload(node3));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore]
|
||||||
fn switch_forgets() {
|
fn switch_forgets() {
|
||||||
// TODO Test
|
// TODO Test
|
||||||
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn router_delivers() {
|
fn router_delivers() {
|
||||||
// TODO Test
|
let config1 = Config {
|
||||||
|
device_type: Type::Tun,
|
||||||
|
auto_claim: false,
|
||||||
|
claims: vec!["1.1.1.1/32".to_string()],
|
||||||
|
..Config::default()
|
||||||
|
};
|
||||||
|
let config2 = Config {
|
||||||
|
device_type: Type::Tun,
|
||||||
|
auto_claim: false,
|
||||||
|
claims: vec!["2.2.2.2/32".to_string()],
|
||||||
|
..Config::default()
|
||||||
|
};
|
||||||
|
let mut sim = TunSimulator::new();
|
||||||
|
let node1 = sim.add_node(false, &config1);
|
||||||
|
let node2 = sim.add_node(false, &config2);
|
||||||
|
|
||||||
|
sim.connect(node1, node2);
|
||||||
|
sim.simulate_all_messages();
|
||||||
|
assert!(sim.is_connected(node1, node2));
|
||||||
|
assert!(sim.is_connected(node2, node1));
|
||||||
|
|
||||||
|
let payload = vec![0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2];
|
||||||
|
|
||||||
|
sim.put_payload(node1, payload.clone());
|
||||||
|
sim.simulate_all_messages();
|
||||||
|
|
||||||
|
assert_eq!(Some(payload), sim.pop_payload(node2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn router_drops_unknown_dest() {
|
fn router_drops_unknown_dest() {
|
||||||
// TODO Test
|
let config1 = Config {
|
||||||
|
device_type: Type::Tun,
|
||||||
|
auto_claim: false,
|
||||||
|
claims: vec!["1.1.1.1/32".to_string()],
|
||||||
|
..Config::default()
|
||||||
|
};
|
||||||
|
let config2 = Config {
|
||||||
|
device_type: Type::Tun,
|
||||||
|
auto_claim: false,
|
||||||
|
claims: vec!["2.2.2.2/32".to_string()],
|
||||||
|
..Config::default()
|
||||||
|
};
|
||||||
|
let mut sim = TunSimulator::new();
|
||||||
|
let node1 = sim.add_node(false, &config1);
|
||||||
|
let node2 = sim.add_node(false, &config2);
|
||||||
|
|
||||||
|
sim.connect(node1, node2);
|
||||||
|
sim.simulate_all_messages();
|
||||||
|
assert!(sim.is_connected(node1, node2));
|
||||||
|
assert!(sim.is_connected(node2, node1));
|
||||||
|
|
||||||
|
let payload = vec![0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3, 3, 3, 3];
|
||||||
|
|
||||||
|
sim.put_payload(node1, payload);
|
||||||
|
sim.simulate_all_messages();
|
||||||
|
|
||||||
|
assert_eq!(None, sim.pop_payload(node2));
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,26 +144,36 @@ fn lost_init_peng() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore]
|
||||||
fn peer_exchange() {
|
fn peer_exchange() {
|
||||||
// TODO Test
|
// TODO Test
|
||||||
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore]
|
||||||
fn lost_peer_exchange() {
|
fn lost_peer_exchange() {
|
||||||
// TODO Test
|
// TODO Test
|
||||||
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore]
|
||||||
fn remove_dead_peers() {
|
fn remove_dead_peers() {
|
||||||
// TODO Test
|
// TODO Test
|
||||||
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore]
|
||||||
fn update_primary_address() {
|
fn update_primary_address() {
|
||||||
// TODO Test
|
// TODO Test
|
||||||
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore]
|
||||||
fn automatic_peer_timeout() {
|
fn automatic_peer_timeout() {
|
||||||
// TODO Test
|
// TODO Test
|
||||||
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue