From 83f53c16d76628e5bc0ffa9bf131f8142b3b6476 Mon Sep 17 00:00:00 2001 From: Dennis Schwerdel Date: Sun, 22 Nov 2015 23:34:54 +0100 Subject: [PATCH] Behavior --- src/cloud.rs | 30 +++++++++++++++++++++++++----- src/ip.rs | 4 ++-- src/main.rs | 13 +++++++++---- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/cloud.rs b/src/cloud.rs index 64896d0..2206301 100644 --- a/src/cloud.rs +++ b/src/cloud.rs @@ -18,6 +18,11 @@ use super::ip::{InternetProtocol, IpAddress, RoutingTable}; pub type NetworkId = u64; +#[derive(RustcDecodable, Debug)] +pub enum Behavior { + Normal, Hub, Switch, Router +} + pub trait Address: Sized + fmt::Debug + Clone { fn from_bytes(&[u8]) -> Result; fn to_bytes(&self) -> Vec; @@ -347,14 +352,20 @@ impl, M: Protocol, I: VirtualInterfac pub type TapCloud = GenericCloud; impl TapCloud { - pub fn new_tap_cloud(device: &str, listen: String, network_id: Option, mac_timeout: Duration, peer_timeout: Duration) -> Self { + pub fn new_tap_cloud(device: &str, listen: String, behavior: Behavior, network_id: Option, mac_timeout: Duration, peer_timeout: Duration) -> Self { let device = match TapDevice::new(device) { Ok(device) => device, _ => panic!("Failed to open tap device") }; info!("Opened tap device {}", device.ifname()); let table = MacTable::new(mac_timeout); - Self::new(device, listen, network_id, table, peer_timeout, true, true, vec![]) + let (learning, broadcasting) = match behavior { + Behavior::Normal => (true, true), + Behavior::Switch => (true, true), + Behavior::Hub => (false, true), + Behavior::Router => (false, false) + }; + Self::new(device, listen, network_id, table, peer_timeout, learning, broadcasting, vec![]) } } @@ -362,14 +373,23 @@ impl TapCloud { pub type TunCloud = GenericCloud; impl TunCloud { - pub fn new_tun_cloud(device: &str, listen: String, network_id: Option, subnet: String, peer_timeout: Duration) -> Self { + pub fn new_tun_cloud(device: &str, listen: String, behavior: Behavior, network_id: Option, subnets: Vec, peer_timeout: Duration) -> Self { let device = match TunDevice::new(device) { Ok(device) => device, _ => panic!("Failed to open tun device") }; info!("Opened tun device {}", device.ifname()); let table = RoutingTable::new(); - let subnet = IpAddress::from_str(&subnet).expect("Invalid subnet"); - Self::new(device, listen, network_id, table, peer_timeout, false, false, vec![subnet]) + let mut addrs = Vec::with_capacity(subnets.len()); + for s in subnets { + addrs.push(IpAddress::from_str(&s).expect("Invalid subnet")); + } + let (learning, broadcasting) = match behavior { + Behavior::Normal => (false, false), + Behavior::Switch => (true, true), + Behavior::Hub => (false, true), + Behavior::Router => (false, false) + }; + Self::new(device, listen, network_id, table, peer_timeout, learning, broadcasting, addrs) } } diff --git a/src/ip.rs b/src/ip.rs index 12e5e39..3f466d2 100644 --- a/src/ip.rs +++ b/src/ip.rs @@ -187,12 +187,12 @@ impl Table for RoutingTable { match src { IpAddress::V4(_) => (), IpAddress::V4Net(base, prefix_len) => { - info!("Adding to routing table: {:?} => {}", src, addr); + info!("Adding to routing table: {}/{} => {}", base, prefix_len, addr); self.add(IpAddress::V4(base).to_bytes(), prefix_len, addr); }, IpAddress::V6(_) => (), IpAddress::V6Net(base, prefix_len) => { - info!("Adding to routing table: {:?} => {}", src, addr); + info!("Adding to routing table: {}/{} => {}", base, prefix_len, addr); self.add(IpAddress::V6(base).to_bytes(), prefix_len, addr); } } diff --git a/src/main.rs b/src/main.rs index e34505e..ef5f4af 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,9 +16,11 @@ use docopt::Docopt; use std::hash::{Hash, SipHasher, Hasher}; -use cloud::{Error, TapCloud, TunCloud}; +use cloud::{Error, TapCloud, TunCloud, Behavior}; +//TODO: hub behavior +//TODO: L2 routing/L3 switching //TODO: Implement IPv6 //TODO: Encryption //TODO: Call close @@ -44,19 +46,19 @@ Usage: Options: -t , --type Set the type of network [default: tap] + --behavior The behavior of the vpn [default: normal] -d , --device Name of the virtual device [default: cloud%d] -l , --listen Address to listen on [default: 0.0.0.0:3210] -c , --connect List of peers (addr:port) to connect to --network-id Optional token that identifies the network --peer-timeout Peer timeout in seconds [default: 1800] - --subnet The local subnet to use (only for tun) + --subnet ... The local subnets to use (only for tun) --mac-timeout Mac table entry timeout in seconds (only for tap) [default: 300] -v, --verbose Log verbosely -q, --quiet Only print error messages -h, --help Display the help "; - #[derive(RustcDecodable, Debug)] enum Type { Tun, Tap @@ -65,7 +67,8 @@ enum Type { #[derive(RustcDecodable, Debug)] struct Args { flag_type: Type, - flag_subnet: String, + flag_behavior: Behavior, + flag_subnet: Vec, flag_device: String, flag_listen: String, flag_network_id: Option, @@ -80,6 +83,7 @@ fn tap_cloud(args: Args) { let mut tapcloud = TapCloud::new_tap_cloud( &args.flag_device, args.flag_listen, + args.flag_behavior, args.flag_network_id.map(|name| { let mut s = SipHasher::new(); name.hash(&mut s); @@ -98,6 +102,7 @@ fn tun_cloud(args: Args) { let mut tuncloud = TunCloud::new_tun_cloud( &args.flag_device, args.flag_listen, + args.flag_behavior, args.flag_network_id.map(|name| { let mut s = SipHasher::new(); name.hash(&mut s);