Reduce number of type parameters in router

Merge multiple related type parameters into trait,
allowing for easier refactoring and better maintainability.
This commit is contained in:
Mathias Hall-Andersen
2019-08-31 20:25:16 +02:00
parent c823af1a9c
commit 46d76b80c6
8 changed files with 137 additions and 72 deletions

View File

@@ -5,7 +5,7 @@ use std::sync::{Arc, Weak};
use std::thread;
use std::time::Instant;
use crossbeam_deque::{Injector, Steal, Stealer, Worker};
use crossbeam_deque::{Injector, Worker};
use spin;
use treebitmap::IpLookupTable;
@@ -15,24 +15,25 @@ use super::anti_replay::AntiReplay;
use super::peer;
use super::peer::{Peer, PeerInner};
use super::types::{Callback, KeyCallback, Opaque};
use super::types::{Callback, Callbacks, CallbacksPhantom, KeyCallback, Opaque};
use super::workers::{worker_parallel, JobParallel};
pub struct DeviceInner<T: Opaque, S: Callback<T>, R: Callback<T>, K: KeyCallback<T>> {
pub struct DeviceInner<C: Callbacks, T: Tun> {
// IO & timer generics
pub tun: T,
pub call_recv: C::CallbackRecv,
pub call_send: C::CallbackSend,
pub call_need_key: C::CallbackKey,
// threading and workers
pub running: AtomicBool, // workers running?
pub parked: AtomicBool, // any workers parked?
pub injector: Injector<JobParallel>, // parallel enc/dec task injector
// unboxed callbacks (used for timers and handshake requests)
pub event_send: S, // called when authenticated message send
pub event_recv: R, // called when authenticated message received
pub event_need_key: K, // called when new key material is required
// routing
pub recv: spin::RwLock<HashMap<u32, DecryptionState<T, S, R, K>>>, // receiver id -> decryption state
pub ipv4: spin::RwLock<IpLookupTable<Ipv4Addr, Weak<PeerInner<T, S, R, K>>>>, // ipv4 cryptkey routing
pub ipv6: spin::RwLock<IpLookupTable<Ipv6Addr, Weak<PeerInner<T, S, R, K>>>>, // ipv6 cryptkey routing
pub recv: spin::RwLock<HashMap<u32, DecryptionState<C, T>>>, // receiver id -> decryption state
pub ipv4: spin::RwLock<IpLookupTable<Ipv4Addr, Weak<PeerInner<C, T>>>>, // ipv4 cryptkey routing
pub ipv6: spin::RwLock<IpLookupTable<Ipv6Addr, Weak<PeerInner<C, T>>>>, // ipv6 cryptkey routing
}
pub struct EncryptionState {
@@ -43,21 +44,18 @@ pub struct EncryptionState {
// (birth + reject-after-time - keepalive-timeout - rekey-timeout)
}
pub struct DecryptionState<T: Opaque, S: Callback<T>, R: Callback<T>, K: KeyCallback<T>> {
pub struct DecryptionState<C: Callbacks, T: Tun> {
pub key: [u8; 32],
pub keypair: Weak<KeyPair>,
pub confirmed: AtomicBool,
pub protector: spin::Mutex<AntiReplay>,
pub peer: Weak<PeerInner<T, S, R, K>>,
pub peer: Weak<PeerInner<C, T>>,
pub death: Instant, // time when the key can no longer be used for decryption
}
pub struct Device<T: Opaque, S: Callback<T>, R: Callback<T>, K: KeyCallback<T>>(
Arc<DeviceInner<T, S, R, K>>,
Vec<thread::JoinHandle<()>>,
);
pub struct Device<C: Callbacks, T: Tun>(Arc<DeviceInner<C, T>>, Vec<thread::JoinHandle<()>>);
impl<T: Opaque, S: Callback<T>, R: Callback<T>, K: KeyCallback<T>> Drop for Device<T, S, R, K> {
impl<C: Callbacks, T: Tun> Drop for Device<C, T> {
fn drop(&mut self) {
// mark device as stopped
let device = &self.0;
@@ -75,18 +73,22 @@ impl<T: Opaque, S: Callback<T>, R: Callback<T>, K: KeyCallback<T>> Drop for Devi
}
}
impl<T: Opaque, S: Callback<T>, R: Callback<T>, K: KeyCallback<T>> Device<T, S, R, K> {
impl<O: Opaque, R: Callback<O>, S: Callback<O>, K: KeyCallback<O>, T: Tun>
Device<CallbacksPhantom<O, R, S, K>, T>
{
pub fn new(
num_workers: usize,
event_recv: R,
event_send: S,
event_need_key: K,
) -> Device<T, S, R, K> {
tun: T,
call_recv: R,
call_send: S,
call_need_key: K,
) -> Device<CallbacksPhantom<O, R, S, K>, T> {
// allocate shared device state
let inner = Arc::new(DeviceInner {
event_recv,
event_send,
event_need_key,
tun,
call_recv,
call_send,
call_need_key,
parked: AtomicBool::new(false),
running: AtomicBool::new(true),
injector: Injector::new(),
@@ -95,7 +97,7 @@ impl<T: Opaque, S: Callback<T>, R: Callback<T>, K: KeyCallback<T>> Device<T, S,
ipv6: spin::RwLock::new(IpLookupTable::new()),
});
// alloacate work pool resources
// allocate work pool resources
let mut workers = Vec::with_capacity(num_workers);
let mut stealers = Vec::with_capacity(num_workers);
for _ in 0..num_workers {
@@ -118,13 +120,15 @@ impl<T: Opaque, S: Callback<T>, R: Callback<T>, K: KeyCallback<T>> Device<T, S,
// return exported device handle
Device(inner, threads)
}
}
impl<C: Callbacks, T: Tun> Device<C, T> {
/// Adds a new peer to the device
///
/// # Returns
///
/// A atomic ref. counted peer (with liftime matching the device)
pub fn new_peer(&self, opaque: T) -> Peer<T, S, R, K> {
pub fn new_peer(&self, opaque: C::Opaque) -> Peer<C, T> {
peer::new_peer(self.0.clone(), opaque)
}