Simplified router tests
This commit is contained in:
@@ -331,6 +331,10 @@ impl<C: Callbacks, T: Tun, B: Bind> Peer<C, T, B> {
|
|||||||
*self.state.endpoint.lock() = Some(endpoint.into());
|
*self.state.endpoint.lock() = Some(endpoint.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_endpoint(&self) -> Option<SocketAddr> {
|
||||||
|
self.state.endpoint.lock().as_ref().map(|e| (*e).into())
|
||||||
|
}
|
||||||
|
|
||||||
/// Add a new keypair
|
/// Add a new keypair
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ use super::{Device, SIZE_MESSAGE_PREFIX};
|
|||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
|
const SIZE_KEEPALIVE: usize = 32;
|
||||||
|
|
||||||
/* Error implementation */
|
/* Error implementation */
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -65,6 +67,7 @@ impl fmt::Display for TunError {
|
|||||||
|
|
||||||
/* Endpoint implementation */
|
/* Endpoint implementation */
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
struct UnitEndpoint {}
|
struct UnitEndpoint {}
|
||||||
|
|
||||||
impl From<SocketAddr> for UnitEndpoint {
|
impl From<SocketAddr> for UnitEndpoint {
|
||||||
@@ -88,11 +91,11 @@ impl Tun for TunTest {
|
|||||||
1500
|
1500
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(&self, buf: &mut [u8], offset: usize) -> Result<usize, Self::Error> {
|
fn read(&self, _buf: &mut [u8], _offset: usize) -> Result<usize, Self::Error> {
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&self, src: &[u8]) -> Result<(), Self::Error> {
|
fn write(&self, _src: &[u8]) -> Result<(), Self::Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,33 +221,64 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use env_logger;
|
use env_logger;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use std::sync::atomic::AtomicU64;
|
use std::sync::atomic::{AtomicU64, AtomicUsize};
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
|
||||||
fn get_tests() -> Vec<(&'static str, u32, &'static str, bool)> {
|
// type for tracking events inside the router module
|
||||||
vec![
|
struct Flags {
|
||||||
("192.168.1.0", 24, "192.168.1.20", true),
|
send: Mutex<Vec<(usize, bool, bool)>>,
|
||||||
("172.133.133.133", 32, "172.133.133.133", true),
|
recv: Mutex<Vec<(usize, bool, bool)>>,
|
||||||
("172.133.133.133", 32, "172.133.133.132", false),
|
need_key: Mutex<Vec<()>>,
|
||||||
(
|
}
|
||||||
"2001:db8::ff00:42:0000",
|
|
||||||
112,
|
#[derive(Clone)]
|
||||||
"2001:db8::ff00:42:3242",
|
struct Opaque(Arc<Flags>);
|
||||||
true,
|
|
||||||
),
|
impl Opaque {
|
||||||
(
|
fn new() -> Opaque {
|
||||||
"2001:db8::ff00:42:8000",
|
Opaque(Arc::new(Flags {
|
||||||
113,
|
send: Mutex::new(vec![]),
|
||||||
"2001:db8::ff00:42:0660",
|
recv: Mutex::new(vec![]),
|
||||||
false,
|
need_key: Mutex::new(vec![]),
|
||||||
),
|
}))
|
||||||
(
|
}
|
||||||
"2001:db8::ff00:42:8000",
|
|
||||||
113,
|
fn reset(&self) {
|
||||||
"2001:db8::ff00:42:ffff",
|
self.0.send.lock().unwrap().clear();
|
||||||
true,
|
self.0.recv.lock().unwrap().clear();
|
||||||
),
|
self.0.need_key.lock().unwrap().clear();
|
||||||
]
|
}
|
||||||
|
|
||||||
|
fn send(&self) -> Option<(usize, bool, bool)> {
|
||||||
|
self.0.send.lock().unwrap().pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recv(&self) -> Option<(usize, bool, bool)> {
|
||||||
|
self.0.recv.lock().unwrap().pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn need_key(&self) -> Option<()> {
|
||||||
|
self.0.need_key.lock().unwrap().pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
let send = self.0.send.lock().unwrap();
|
||||||
|
let recv = self.0.recv.lock().unwrap();
|
||||||
|
let need_key = self.0.need_key.lock().unwrap();
|
||||||
|
send.is_empty() && recv.is_empty() && need_key.is_empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn callback_send(t: &Opaque, size: usize, data: bool, sent: bool) {
|
||||||
|
t.0.send.lock().unwrap().push((size, data, sent))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn callback_recv(t: &Opaque, size: usize, data: bool, sent: bool) {
|
||||||
|
t.0.recv.lock().unwrap().push((size, data, sent))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn callback_need_key(t: &Opaque) {
|
||||||
|
t.0.need_key.lock().unwrap().push(());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init() {
|
fn init() {
|
||||||
@@ -272,25 +306,22 @@ mod tests {
|
|||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_outbound(b: &mut Bencher) {
|
fn bench_outbound(b: &mut Bencher) {
|
||||||
init();
|
type Opaque = Arc<AtomicUsize>;
|
||||||
|
|
||||||
// type for tracking number of packets
|
|
||||||
type Opaque = Arc<AtomicU64>;
|
|
||||||
|
|
||||||
// create device
|
// create device
|
||||||
let router = Device::new(
|
let router = Device::new(
|
||||||
num_cpus::get(),
|
num_cpus::get(),
|
||||||
TunTest {},
|
TunTest {},
|
||||||
VoidBind::new(),
|
VoidBind::new(),
|
||||||
|t: &Opaque, _size: usize, _data: bool, _sent: bool| {
|
|t: &Opaque, size: usize, _data: bool, _sent: bool| {
|
||||||
t.fetch_add(1, Ordering::SeqCst);
|
t.fetch_add(size, Ordering::SeqCst);
|
||||||
},
|
},
|
||||||
|_t: &Opaque, _size: usize, _data: bool, _sent: bool| {},
|
|t: &Opaque, _size: usize, _data: bool, _sent: bool| {},
|
||||||
|_t: &Opaque| {},
|
|t: &Opaque| (),
|
||||||
);
|
);
|
||||||
|
|
||||||
// add new peer
|
// add new peer
|
||||||
let opaque = Arc::new(AtomicU64::new(0));
|
let opaque = Arc::new(AtomicUsize::new(0));
|
||||||
let peer = router.new_peer(opaque.clone());
|
let peer = router.new_peer(opaque.clone());
|
||||||
peer.add_keypair(dummy_keypair(true));
|
peer.add_keypair(dummy_keypair(true));
|
||||||
|
|
||||||
@@ -314,39 +345,46 @@ mod tests {
|
|||||||
fn test_outbound() {
|
fn test_outbound() {
|
||||||
init();
|
init();
|
||||||
|
|
||||||
// type for tracking events inside the router module
|
|
||||||
struct Flags {
|
|
||||||
send: AtomicBool,
|
|
||||||
recv: AtomicBool,
|
|
||||||
need_key: AtomicBool,
|
|
||||||
}
|
|
||||||
type Opaque = Arc<Flags>;
|
|
||||||
|
|
||||||
// create device
|
// create device
|
||||||
let router = Device::new(
|
let router = Device::new(
|
||||||
1,
|
1,
|
||||||
TunTest {},
|
TunTest {},
|
||||||
VoidBind::new(),
|
VoidBind::new(),
|
||||||
|t: &Opaque, _size: usize, _data: bool, _sent: bool| {
|
callback_send,
|
||||||
t.send.store(true, Ordering::SeqCst)
|
callback_recv,
|
||||||
},
|
callback_need_key,
|
||||||
|t: &Opaque, _size: usize, _data: bool, _sent: bool| {
|
|
||||||
t.recv.store(true, Ordering::SeqCst)
|
|
||||||
},
|
|
||||||
|t: &Opaque| t.need_key.store(true, Ordering::SeqCst),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let tests = get_tests();
|
let tests = vec![
|
||||||
|
("192.168.1.0", 24, "192.168.1.20", true),
|
||||||
|
("172.133.133.133", 32, "172.133.133.133", true),
|
||||||
|
("172.133.133.133", 32, "172.133.133.132", false),
|
||||||
|
(
|
||||||
|
"2001:db8::ff00:42:0000",
|
||||||
|
112,
|
||||||
|
"2001:db8::ff00:42:3242",
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"2001:db8::ff00:42:8000",
|
||||||
|
113,
|
||||||
|
"2001:db8::ff00:42:0660",
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"2001:db8::ff00:42:8000",
|
||||||
|
113,
|
||||||
|
"2001:db8::ff00:42:ffff",
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
for (num, (mask, len, ip, okay)) in tests.iter().enumerate() {
|
for (num, (mask, len, ip, okay)) in tests.iter().enumerate() {
|
||||||
for set_key in vec![true, false] {
|
for set_key in vec![true, false] {
|
||||||
debug!("index = {}, set_key = {}", num, set_key);
|
debug!("index = {}, set_key = {}", num, set_key);
|
||||||
|
|
||||||
// add new peer
|
// add new peer
|
||||||
let opaque = Arc::new(Flags {
|
let opaque = Opaque::new();
|
||||||
send: AtomicBool::new(false),
|
|
||||||
recv: AtomicBool::new(false),
|
|
||||||
need_key: AtomicBool::new(false),
|
|
||||||
});
|
|
||||||
let peer = router.new_peer(opaque.clone());
|
let peer = router.new_peer(opaque.clone());
|
||||||
let mask: IpAddr = mask.parse().unwrap();
|
let mask: IpAddr = mask.parse().unwrap();
|
||||||
|
|
||||||
@@ -370,36 +408,37 @@ mod tests {
|
|||||||
// cryptkey routing succeeded
|
// cryptkey routing succeeded
|
||||||
assert!(res.is_ok(), "crypt-key routing should succeed");
|
assert!(res.is_ok(), "crypt-key routing should succeed");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
opaque.need_key.load(Ordering::Acquire),
|
opaque.need_key().is_some(),
|
||||||
!set_key,
|
!set_key,
|
||||||
"should have requested a new key, if no encryption state was set"
|
"should have requested a new key, if no encryption state was set"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
opaque.send.load(Ordering::Acquire),
|
opaque.send().is_some(),
|
||||||
set_key,
|
set_key,
|
||||||
"transmission should have been attempted"
|
"transmission should have been attempted"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert!(
|
||||||
opaque.recv.load(Ordering::Acquire),
|
opaque.recv().is_none(),
|
||||||
false,
|
|
||||||
"no messages should have been marked as received"
|
"no messages should have been marked as received"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// no such cryptkey route
|
// no such cryptkey route
|
||||||
assert!(res.is_err(), "crypt-key routing should fail");
|
assert!(res.is_err(), "crypt-key routing should fail");
|
||||||
assert_eq!(
|
assert!(
|
||||||
opaque.need_key.load(Ordering::Acquire),
|
opaque.need_key().is_none(),
|
||||||
false,
|
|
||||||
"should not request a new-key if crypt-key routing failed"
|
"should not request a new-key if crypt-key routing failed"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
opaque.send.load(Ordering::Acquire),
|
opaque.send(),
|
||||||
false,
|
if set_key {
|
||||||
"transmission should not have been attempted",
|
Some((SIZE_KEEPALIVE, false, false))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
"transmission should only happen if key was set (keepalive)",
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert!(
|
||||||
opaque.recv.load(Ordering::Acquire),
|
opaque.recv().is_none(),
|
||||||
false,
|
|
||||||
"no messages should have been marked as received",
|
"no messages should have been marked as received",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -415,46 +454,13 @@ mod tests {
|
|||||||
fn test_outbound_inbound() {
|
fn test_outbound_inbound() {
|
||||||
init();
|
init();
|
||||||
|
|
||||||
// type for tracking events inside the router module
|
|
||||||
|
|
||||||
struct Flags {
|
|
||||||
send: AtomicBool,
|
|
||||||
recv: AtomicBool,
|
|
||||||
need_key: AtomicBool,
|
|
||||||
}
|
|
||||||
type Opaque = Arc<Flags>;
|
|
||||||
|
|
||||||
fn reset(opaq: &Opaque) {
|
|
||||||
opaq.send.store(false, Ordering::SeqCst);
|
|
||||||
opaq.recv.store(false, Ordering::SeqCst);
|
|
||||||
opaq.need_key.store(false, Ordering::SeqCst);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test(opaq: &Opaque, send: bool, recv: bool, need_key: bool) {
|
|
||||||
assert_eq!(
|
|
||||||
opaq.send.load(Ordering::Acquire),
|
|
||||||
send,
|
|
||||||
"send did not match"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
opaq.recv.load(Ordering::Acquire),
|
|
||||||
recv,
|
|
||||||
"recv did not match"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
opaq.need_key.load(Ordering::Acquire),
|
|
||||||
need_key,
|
|
||||||
"need_key did not match"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let tests = [(
|
let tests = [(
|
||||||
false,
|
false,
|
||||||
("192.168.1.0", 24, "192.168.1.20", true),
|
("192.168.1.0", 24, "192.168.1.20", true),
|
||||||
("172.133.133.133", 32, "172.133.133.133", true),
|
("172.133.133.133", 32, "172.133.133.133", true),
|
||||||
)];
|
)];
|
||||||
|
|
||||||
for (num, (stage, p1, p2)) in tests.iter().enumerate() {
|
for (stage, p1, p2) in tests.iter() {
|
||||||
let (bind1, bind2) = bind_pair();
|
let (bind1, bind2) = bind_pair();
|
||||||
|
|
||||||
// create matching devices
|
// create matching devices
|
||||||
@@ -463,41 +469,24 @@ mod tests {
|
|||||||
1,
|
1,
|
||||||
TunTest {},
|
TunTest {},
|
||||||
bind1.clone(),
|
bind1.clone(),
|
||||||
|t: &Opaque, _size: usize, _data: bool, _sent: bool| {
|
callback_send,
|
||||||
t.send.store(true, Ordering::SeqCst)
|
callback_recv,
|
||||||
},
|
callback_need_key,
|
||||||
|t: &Opaque, _size: usize, _data: bool, _sent: bool| {
|
|
||||||
t.recv.store(true, Ordering::SeqCst)
|
|
||||||
},
|
|
||||||
|t: &Opaque| t.need_key.store(true, Ordering::SeqCst),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let router2 = Device::new(
|
let router2 = Device::new(
|
||||||
1,
|
1,
|
||||||
TunTest {},
|
TunTest {},
|
||||||
bind2.clone(),
|
bind2.clone(),
|
||||||
|t: &Opaque, _size: usize, _data: bool, _sent: bool| {
|
callback_send,
|
||||||
t.send.store(true, Ordering::SeqCst)
|
callback_recv,
|
||||||
},
|
callback_need_key,
|
||||||
|t: &Opaque, _size: usize, _data: bool, _sent: bool| {
|
|
||||||
t.recv.store(true, Ordering::SeqCst)
|
|
||||||
},
|
|
||||||
|t: &Opaque| t.need_key.store(true, Ordering::SeqCst),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// prepare opaque values for tracing callbacks
|
// prepare opaque values for tracing callbacks
|
||||||
|
|
||||||
let opaq1 = Arc::new(Flags {
|
let opaq1 = Opaque::new();
|
||||||
send: AtomicBool::new(false),
|
let opaq2 = Opaque::new();
|
||||||
recv: AtomicBool::new(false),
|
|
||||||
need_key: AtomicBool::new(false),
|
|
||||||
});
|
|
||||||
|
|
||||||
let opaq2 = Arc::new(Flags {
|
|
||||||
send: AtomicBool::new(false),
|
|
||||||
recv: AtomicBool::new(false),
|
|
||||||
need_key: AtomicBool::new(false),
|
|
||||||
});
|
|
||||||
|
|
||||||
// create peers with matching keypairs and assign subnets
|
// create peers with matching keypairs and assign subnets
|
||||||
|
|
||||||
@@ -505,8 +494,6 @@ mod tests {
|
|||||||
let peer1 = router1.new_peer(opaq1.clone());
|
let peer1 = router1.new_peer(opaq1.clone());
|
||||||
let mask: IpAddr = mask.parse().unwrap();
|
let mask: IpAddr = mask.parse().unwrap();
|
||||||
peer1.add_subnet(mask, *len);
|
peer1.add_subnet(mask, *len);
|
||||||
peer1.set_endpoint("127.0.0.1:8080".parse().unwrap());
|
|
||||||
|
|
||||||
peer1.add_keypair(dummy_keypair(false));
|
peer1.add_keypair(dummy_keypair(false));
|
||||||
|
|
||||||
let (mask, len, _ip, _okay) = p2;
|
let (mask, len, _ip, _okay) = p2;
|
||||||
@@ -521,15 +508,29 @@ mod tests {
|
|||||||
let msg = make_packet(1024, ip.parse().unwrap());
|
let msg = make_packet(1024, ip.parse().unwrap());
|
||||||
router2.send(msg).expect("failed to sent staged packet");
|
router2.send(msg).expect("failed to sent staged packet");
|
||||||
wait();
|
wait();
|
||||||
test(&opaq2, false, false, true);
|
assert!(opaq2.recv().is_none());
|
||||||
reset(&opaq2);
|
assert!(
|
||||||
|
opaq2.send().is_none(),
|
||||||
|
"sending should fail as not key is set"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
opaq2.need_key().is_some(),
|
||||||
|
"a new key should be requested since a packet was attempted transmitted"
|
||||||
|
);
|
||||||
|
assert!(opaq2.is_empty(), "callbacks should only run once");
|
||||||
}
|
}
|
||||||
|
|
||||||
// this should cause a key-confirmation packet (keepalive or staged packet)
|
// this should cause a key-confirmation packet (keepalive or staged packet)
|
||||||
|
// this also causes peer1 to learn the "endpoint" for peer2
|
||||||
|
assert!(peer1.get_endpoint().is_none());
|
||||||
peer2.add_keypair(dummy_keypair(true));
|
peer2.add_keypair(dummy_keypair(true));
|
||||||
|
|
||||||
wait();
|
wait();
|
||||||
test(&opaq2, true, false, false);
|
assert!(opaq2.send().is_some());
|
||||||
|
assert!(opaq2.recv().is_none());
|
||||||
|
assert!(opaq2.need_key().is_none());
|
||||||
|
assert!(opaq2.is_empty());
|
||||||
|
assert!(opaq1.is_empty(), "nothing should happend on peer1");
|
||||||
|
|
||||||
// read confirming message received by the other end ("across the internet")
|
// read confirming message received by the other end ("across the internet")
|
||||||
let mut buf = vec![0u8; 1024];
|
let mut buf = vec![0u8; 1024];
|
||||||
@@ -538,29 +539,49 @@ mod tests {
|
|||||||
router1.recv(from, buf).unwrap();
|
router1.recv(from, buf).unwrap();
|
||||||
|
|
||||||
wait();
|
wait();
|
||||||
test(&opaq1, false, true, false);
|
assert!(opaq1.send().is_none());
|
||||||
|
assert!(opaq1.recv().is_some());
|
||||||
|
assert!(opaq1.need_key().is_none());
|
||||||
|
assert!(opaq1.is_empty());
|
||||||
|
assert!(peer1.get_endpoint().is_some());
|
||||||
|
assert!(opaq2.is_empty(), "nothing should happend on peer2");
|
||||||
|
|
||||||
// start crypt-key routing packets
|
// how that peer1 has an endpoint
|
||||||
|
// route packets : peer1 -> peer2
|
||||||
|
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
reset(&opaq1);
|
assert!(
|
||||||
reset(&opaq2);
|
opaq1.is_empty(),
|
||||||
|
"we should have asserted a value for every callback on peer1"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
opaq2.is_empty(),
|
||||||
|
"we should have asserted a value for every callback on peer2"
|
||||||
|
);
|
||||||
|
|
||||||
// pass IP packet to router
|
// pass IP packet to router
|
||||||
let (_mask, _len, ip, _okay) = p1;
|
let (_mask, _len, ip, _okay) = p1;
|
||||||
let msg = make_packet(1024, ip.parse().unwrap());
|
let msg = make_packet(1024, ip.parse().unwrap());
|
||||||
router1.send(msg).unwrap();
|
router1.send(msg).unwrap();
|
||||||
|
|
||||||
wait();
|
wait();
|
||||||
test(&opaq1, true, false, false);
|
assert!(opaq1.send().is_some());
|
||||||
|
assert!(opaq1.recv().is_none());
|
||||||
|
assert!(opaq1.need_key().is_none());
|
||||||
|
|
||||||
// receive ("across the internet") on the other end
|
// receive ("across the internet") on the other end
|
||||||
let mut buf = vec![0u8; 2048];
|
let mut buf = vec![0u8; 2048];
|
||||||
let (len, from) = bind2.recv(&mut buf).unwrap();
|
let (len, from) = bind2.recv(&mut buf).unwrap();
|
||||||
buf.truncate(len);
|
buf.truncate(len);
|
||||||
router2.recv(from, buf).unwrap();
|
router2.recv(from, buf).unwrap();
|
||||||
|
|
||||||
wait();
|
wait();
|
||||||
test(&opaq2, false, true, false);
|
assert!(opaq2.send().is_none());
|
||||||
|
assert!(opaq2.recv().is_some());
|
||||||
|
assert!(opaq2.need_key().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// route packets : peer2 -> peer1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -213,8 +213,7 @@ pub fn worker_outbound<C: Callbacks, T: Tun, B: Bind>(
|
|||||||
(device.call_send)(
|
(device.call_send)(
|
||||||
&peer.opaque,
|
&peer.opaque,
|
||||||
buf.msg.len(),
|
buf.msg.len(),
|
||||||
buf.msg.len()
|
buf.msg.len() > SIZE_TAG + mem::size_of::<TransportHeader>(),
|
||||||
> CHACHA20_POLY1305.nonce_len() + mem::size_of::<TransportHeader>(),
|
|
||||||
xmit,
|
xmit,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
pub trait Endpoint: Into<SocketAddr> + From<SocketAddr> + Send {}
|
pub trait Endpoint: Into<SocketAddr> + From<SocketAddr> + Copy + Send {}
|
||||||
|
|
||||||
impl<T> Endpoint for T where T: Into<SocketAddr> + From<SocketAddr> + Send {}
|
impl<T> Endpoint for T where T: Into<SocketAddr> + From<SocketAddr> + Copy + Send {}
|
||||||
|
|||||||
Reference in New Issue
Block a user