Removed a layer of indirection from inner loop

pull/29/head
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
- [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] Removed a layer of indirection from inner loop
- [fixed] Fixed two problems with routing table
### v0.8.0 (2016-11-25)

View File

@ -150,9 +150,9 @@ fn epoll_wait(b: &mut Bencher) {
#[bench]
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,
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];
data[105] = 45;
@ -164,9 +164,9 @@ fn handle_interface_data(b: &mut Bencher) {
#[bench]
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,
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 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,
node_id: NodeId,
peers: PeerList,
@ -176,7 +176,7 @@ pub struct GenericCloud<P: Protocol> {
broadcast: bool,
reconnect_peers: Vec<ReconnectEntry>,
blacklist_peers: Vec<SocketAddr>,
table: Box<Table>,
table: T,
socket4: UdpSocket,
socket6: UdpSocket,
device: Device,
@ -189,10 +189,10 @@ pub struct GenericCloud<P: Protocol> {
_dummy_p: PhantomData<P>,
}
impl<P: Protocol> GenericCloud<P> {
impl<P: Protocol, T: Table> GenericCloud<P, T> {
#[allow(unknown_lints)]
#[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>,
crypto: Crypto, port_forwarding: Option<PortForwarding>) -> Self {
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 ethernet::SwitchTable;
use ip::RoutingTable;
use types::{Mode, Range, Table, Protocol, HeaderMagic};
use types::{Mode, Range, Protocol, HeaderMagic, Error};
use cloud::GenericCloud;
use crypto::{Crypto, CryptoMethod};
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),
"Failed to open virtual {} interface {}: {}", config.device_type, config.device_name);
info!("Opened device {}", device.ifname());
@ -148,14 +203,14 @@ fn run<T: Protocol> (config: Config) {
}
let dst_timeout = config.dst_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 {
Type::Tap => (true, true, Box::new(SwitchTable::new(dst_timeout, 10))),
Type::Tun => (false, false, Box::new(RoutingTable::new()))
Type::Tap => (true, true, AnyTable::Switch(SwitchTable::new(dst_timeout, 10))),
Type::Tun => (false, false, AnyTable::Routing(RoutingTable::new()))
},
Mode::Router => (false, false, Box::new(RoutingTable::new())),
Mode::Switch => (true, true, Box::new(SwitchTable::new(dst_timeout, 10))),
Mode::Hub => (false, true, Box::new(SwitchTable::new(dst_timeout, 10)))
Mode::Router => (false, false, AnyTable::Routing(RoutingTable::new())),
Mode::Switch => (true, true, AnyTable::Switch(SwitchTable::new(dst_timeout, 10))),
Mode::Hub => (false, true, AnyTable::Switch(SwitchTable::new(dst_timeout, 10)))
};
let magic = config.get_magic();
Crypto::init();
@ -168,7 +223,7 @@ fn run<T: Protocol> (config: Config) {
} else {
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 {
run_script(&script, cloud.ifname());
}