Removed a layer of indirection from inner loop

This commit is contained in:
Dennis Schwerdel 2017-05-04 08:22:24 +02:00
parent 87097cc59f
commit 68af49bf29
4 changed files with 75 additions and 18 deletions

View File

@ -5,8 +5,10 @@ This project follows [semantic versioning](http://semver.org).
### UNRELEASED ### UNRELEASED
- [added] Added more tests - [added] Added more tests
- [changed] Updated dependencies and libsodium - [changed] Updated dependencies
- [changed] Updated libsodium to 1.0.12
- [changed] Small fixes to make clippy happy - [changed] Small fixes to make clippy happy
- [changed] Removed a layer of indirection from inner loop
- [fixed] Fixed two problems with routing table - [fixed] Fixed two problems with routing table
### v0.8.0 (2016-11-25) ### v0.8.0 (2016-11-25)

View File

@ -150,9 +150,9 @@ fn epoll_wait(b: &mut Bencher) {
#[bench] #[bench]
fn handle_interface_data(b: &mut Bencher) { fn handle_interface_data(b: &mut Bencher) {
let mut node = GenericCloud::<Frame>::new( let mut node = GenericCloud::<Frame, SwitchTable>::new(
MAGIC, Device::dummy("vpncloud0", "/dev/null", Type::Tap).unwrap(), 0, MAGIC, Device::dummy("vpncloud0", "/dev/null", Type::Tap).unwrap(), 0,
Box::new(SwitchTable::new(300, 10)), 1800, true, true, vec![], Crypto::None, None SwitchTable::new(300, 10), 1800, true, true, vec![], Crypto::None, None
); );
let mut data = [0; 1500]; let mut data = [0; 1500];
data[105] = 45; data[105] = 45;
@ -164,9 +164,9 @@ fn handle_interface_data(b: &mut Bencher) {
#[bench] #[bench]
fn handle_net_message(b: &mut Bencher) { fn handle_net_message(b: &mut Bencher) {
let mut node = GenericCloud::<Frame>::new( let mut node = GenericCloud::<Frame, SwitchTable>::new(
MAGIC, Device::dummy("vpncloud0", "/dev/null", Type::Tap).unwrap(), 0, MAGIC, Device::dummy("vpncloud0", "/dev/null", Type::Tap).unwrap(), 0,
Box::new(SwitchTable::new(300, 10)), 1800, true, true, vec![], Crypto::None, None SwitchTable::new(300, 10), 1800, true, true, vec![], Crypto::None, None
); );
let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 1)); let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 1));
let mut data = [0; 1500]; let mut data = [0; 1500];

View File

@ -167,7 +167,7 @@ pub struct ReconnectEntry {
} }
pub struct GenericCloud<P: Protocol> { pub struct GenericCloud<P: Protocol, T: Table> {
magic: HeaderMagic, magic: HeaderMagic,
node_id: NodeId, node_id: NodeId,
peers: PeerList, peers: PeerList,
@ -176,7 +176,7 @@ pub struct GenericCloud<P: Protocol> {
broadcast: bool, broadcast: bool,
reconnect_peers: Vec<ReconnectEntry>, reconnect_peers: Vec<ReconnectEntry>,
blacklist_peers: Vec<SocketAddr>, blacklist_peers: Vec<SocketAddr>,
table: Box<Table>, table: T,
socket4: UdpSocket, socket4: UdpSocket,
socket6: UdpSocket, socket6: UdpSocket,
device: Device, device: Device,
@ -189,10 +189,10 @@ pub struct GenericCloud<P: Protocol> {
_dummy_p: PhantomData<P>, _dummy_p: PhantomData<P>,
} }
impl<P: Protocol> GenericCloud<P> { impl<P: Protocol, T: Table> GenericCloud<P, T> {
#[allow(unknown_lints)] #[allow(unknown_lints)]
#[allow(too_many_arguments)] #[allow(too_many_arguments)]
pub fn new(magic: HeaderMagic, device: Device, listen: u16, table: Box<Table>, pub fn new(magic: HeaderMagic, device: Device, listen: u16, table: T,
peer_timeout: Duration, learning: bool, broadcast: bool, addresses: Vec<Range>, peer_timeout: Duration, learning: bool, broadcast: bool, addresses: Vec<Range>,
crypto: Crypto, port_forwarding: Option<PortForwarding>) -> Self { crypto: Crypto, port_forwarding: Option<PortForwarding>) -> Self {
let socket4 = match UdpBuilder::new_v4().expect("Failed to obtain ipv4 socket builder") let socket4 = match UdpBuilder::new_v4().expect("Failed to obtain ipv4 socket builder")

View File

@ -48,7 +48,7 @@ use std::io::{self, Write};
use device::{Device, Type}; use device::{Device, Type};
use ethernet::SwitchTable; use ethernet::SwitchTable;
use ip::RoutingTable; use ip::RoutingTable;
use types::{Mode, Range, Table, Protocol, HeaderMagic}; use types::{Mode, Range, Protocol, HeaderMagic, Error};
use cloud::GenericCloud; use cloud::GenericCloud;
use crypto::{Crypto, CryptoMethod}; use crypto::{Crypto, CryptoMethod};
use port_forwarding::PortForwarding; use port_forwarding::PortForwarding;
@ -138,7 +138,62 @@ fn run_script(script: &str, ifname: &str) {
} }
} }
fn run<T: Protocol> (config: Config) { enum AnyTable {
Switch(SwitchTable),
Routing(RoutingTable)
}
enum AnyCloud<P: Protocol> {
Switch(GenericCloud<P, SwitchTable>),
Routing(GenericCloud<P, RoutingTable>)
}
impl<P: Protocol> AnyCloud<P> {
#[allow(unknown_lints,too_many_arguments)]
fn new(magic: HeaderMagic, device: Device, listen: u16, table: AnyTable,
peer_timeout: Duration, learning: bool, broadcast: bool, addresses: Vec<Range>,
crypto: Crypto, port_forwarding: Option<PortForwarding>) -> Self {
match table {
AnyTable::Switch(t) => AnyCloud::Switch(GenericCloud::<P, SwitchTable>::new(
magic, device, listen, t, peer_timeout, learning, broadcast, addresses, crypto, port_forwarding
)),
AnyTable::Routing(t) => AnyCloud::Routing(GenericCloud::<P, RoutingTable>::new(
magic, device, listen, t, peer_timeout, learning, broadcast, addresses, crypto, port_forwarding
))
}
}
fn ifname(&self) -> &str {
match *self {
AnyCloud::Switch(ref c) => c.ifname(),
AnyCloud::Routing(ref c) => c.ifname()
}
}
fn run(&mut self) {
match *self {
AnyCloud::Switch(ref mut c) => c.run(),
AnyCloud::Routing(ref mut c) => c.run()
}
}
fn connect(&mut self, a: &str) -> Result<(), Error> {
match *self {
AnyCloud::Switch(ref mut c) => c.connect(a),
AnyCloud::Routing(ref mut c) => c.connect(a)
}
}
fn add_reconnect_peer(&mut self, a: String) {
match *self {
AnyCloud::Switch(ref mut c) => c.add_reconnect_peer(a),
AnyCloud::Routing(ref mut c) => c.add_reconnect_peer(a)
}
}
}
fn run<P: Protocol> (config: Config) {
let device = try_fail!(Device::new(&config.device_name, config.device_type), let device = try_fail!(Device::new(&config.device_name, config.device_type),
"Failed to open virtual {} interface {}: {}", config.device_type, config.device_name); "Failed to open virtual {} interface {}: {}", config.device_type, config.device_name);
info!("Opened device {}", device.ifname()); info!("Opened device {}", device.ifname());
@ -148,14 +203,14 @@ fn run<T: Protocol> (config: Config) {
} }
let dst_timeout = config.dst_timeout; let dst_timeout = config.dst_timeout;
let peer_timeout = config.peer_timeout; let peer_timeout = config.peer_timeout;
let (learning, broadcasting, table): (bool, bool, Box<Table>) = match config.mode { let (learning, broadcasting, table) = match config.mode {
Mode::Normal => match config.device_type { Mode::Normal => match config.device_type {
Type::Tap => (true, true, Box::new(SwitchTable::new(dst_timeout, 10))), Type::Tap => (true, true, AnyTable::Switch(SwitchTable::new(dst_timeout, 10))),
Type::Tun => (false, false, Box::new(RoutingTable::new())) Type::Tun => (false, false, AnyTable::Routing(RoutingTable::new()))
}, },
Mode::Router => (false, false, Box::new(RoutingTable::new())), Mode::Router => (false, false, AnyTable::Routing(RoutingTable::new())),
Mode::Switch => (true, true, Box::new(SwitchTable::new(dst_timeout, 10))), Mode::Switch => (true, true, AnyTable::Switch(SwitchTable::new(dst_timeout, 10))),
Mode::Hub => (false, true, Box::new(SwitchTable::new(dst_timeout, 10))) Mode::Hub => (false, true, AnyTable::Switch(SwitchTable::new(dst_timeout, 10)))
}; };
let magic = config.get_magic(); let magic = config.get_magic();
Crypto::init(); Crypto::init();
@ -168,7 +223,7 @@ fn run<T: Protocol> (config: Config) {
} else { } else {
None None
}; };
let mut cloud = GenericCloud::<T>::new(magic, device, config.port, table, peer_timeout, learning, broadcasting, ranges, crypto, port_forwarding); let mut cloud = AnyCloud::<P>::new(magic, device, config.port, table, peer_timeout, learning, broadcasting, ranges, crypto, port_forwarding);
if let Some(script) = config.ifup { if let Some(script) = config.ifup {
run_script(&script, cloud.ifname()); run_script(&script, cloud.ifname());
} }