This commit is contained in:
Dennis Schwerdel 2015-11-22 23:34:54 +01:00
parent 64342d1288
commit 83f53c16d7
3 changed files with 36 additions and 11 deletions

View File

@ -18,6 +18,11 @@ use super::ip::{InternetProtocol, IpAddress, RoutingTable};
pub type NetworkId = u64; pub type NetworkId = u64;
#[derive(RustcDecodable, Debug)]
pub enum Behavior {
Normal, Hub, Switch, Router
}
pub trait Address: Sized + fmt::Debug + Clone { pub trait Address: Sized + fmt::Debug + Clone {
fn from_bytes(&[u8]) -> Result<Self, Error>; fn from_bytes(&[u8]) -> Result<Self, Error>;
fn to_bytes(&self) -> Vec<u8>; fn to_bytes(&self) -> Vec<u8>;
@ -347,14 +352,20 @@ impl<A: Address, T: Table<Address=A>, M: Protocol<Address=A>, I: VirtualInterfac
pub type TapCloud = GenericCloud<EthAddr, MacTable, Frame, TapDevice>; pub type TapCloud = GenericCloud<EthAddr, MacTable, Frame, TapDevice>;
impl TapCloud { impl TapCloud {
pub fn new_tap_cloud(device: &str, listen: String, network_id: Option<NetworkId>, mac_timeout: Duration, peer_timeout: Duration) -> Self { pub fn new_tap_cloud(device: &str, listen: String, behavior: Behavior, network_id: Option<NetworkId>, mac_timeout: Duration, peer_timeout: Duration) -> Self {
let device = match TapDevice::new(device) { let device = match TapDevice::new(device) {
Ok(device) => device, Ok(device) => device,
_ => panic!("Failed to open tap device") _ => panic!("Failed to open tap device")
}; };
info!("Opened tap device {}", device.ifname()); info!("Opened tap device {}", device.ifname());
let table = MacTable::new(mac_timeout); 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<IpAddress, RoutingTable, InternetProtocol, TunDevice>; pub type TunCloud = GenericCloud<IpAddress, RoutingTable, InternetProtocol, TunDevice>;
impl TunCloud { impl TunCloud {
pub fn new_tun_cloud(device: &str, listen: String, network_id: Option<NetworkId>, subnet: String, peer_timeout: Duration) -> Self { pub fn new_tun_cloud(device: &str, listen: String, behavior: Behavior, network_id: Option<NetworkId>, subnets: Vec<String>, peer_timeout: Duration) -> Self {
let device = match TunDevice::new(device) { let device = match TunDevice::new(device) {
Ok(device) => device, Ok(device) => device,
_ => panic!("Failed to open tun device") _ => panic!("Failed to open tun device")
}; };
info!("Opened tun device {}", device.ifname()); info!("Opened tun device {}", device.ifname());
let table = RoutingTable::new(); let table = RoutingTable::new();
let subnet = IpAddress::from_str(&subnet).expect("Invalid subnet"); let mut addrs = Vec::with_capacity(subnets.len());
Self::new(device, listen, network_id, table, peer_timeout, false, false, vec![subnet]) 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)
} }
} }

View File

@ -187,12 +187,12 @@ impl Table for RoutingTable {
match src { match src {
IpAddress::V4(_) => (), IpAddress::V4(_) => (),
IpAddress::V4Net(base, prefix_len) => { 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); self.add(IpAddress::V4(base).to_bytes(), prefix_len, addr);
}, },
IpAddress::V6(_) => (), IpAddress::V6(_) => (),
IpAddress::V6Net(base, prefix_len) => { 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); self.add(IpAddress::V6(base).to_bytes(), prefix_len, addr);
} }
} }

View File

@ -16,9 +16,11 @@ use docopt::Docopt;
use std::hash::{Hash, SipHasher, Hasher}; 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: Implement IPv6
//TODO: Encryption //TODO: Encryption
//TODO: Call close //TODO: Call close
@ -44,19 +46,19 @@ Usage:
Options: Options:
-t <type>, --type <type> Set the type of network [default: tap] -t <type>, --type <type> Set the type of network [default: tap]
--behavior <behavior> The behavior of the vpn [default: normal]
-d <device>, --device <device> Name of the virtual device [default: cloud%d] -d <device>, --device <device> Name of the virtual device [default: cloud%d]
-l <listen>, --listen <listen> Address to listen on [default: 0.0.0.0:3210] -l <listen>, --listen <listen> Address to listen on [default: 0.0.0.0:3210]
-c <connect>, --connect <connect> List of peers (addr:port) to connect to -c <connect>, --connect <connect> List of peers (addr:port) to connect to
--network-id <network_id> Optional token that identifies the network --network-id <network_id> Optional token that identifies the network
--peer-timeout <peer_timeout> Peer timeout in seconds [default: 1800] --peer-timeout <peer_timeout> Peer timeout in seconds [default: 1800]
--subnet <subnet> The local subnet to use (only for tun) --subnet <subnet>... The local subnets to use (only for tun)
--mac-timeout <mac_timeout> Mac table entry timeout in seconds (only for tap) [default: 300] --mac-timeout <mac_timeout> Mac table entry timeout in seconds (only for tap) [default: 300]
-v, --verbose Log verbosely -v, --verbose Log verbosely
-q, --quiet Only print error messages -q, --quiet Only print error messages
-h, --help Display the help -h, --help Display the help
"; ";
#[derive(RustcDecodable, Debug)] #[derive(RustcDecodable, Debug)]
enum Type { enum Type {
Tun, Tap Tun, Tap
@ -65,7 +67,8 @@ enum Type {
#[derive(RustcDecodable, Debug)] #[derive(RustcDecodable, Debug)]
struct Args { struct Args {
flag_type: Type, flag_type: Type,
flag_subnet: String, flag_behavior: Behavior,
flag_subnet: Vec<String>,
flag_device: String, flag_device: String,
flag_listen: String, flag_listen: String,
flag_network_id: Option<String>, flag_network_id: Option<String>,
@ -80,6 +83,7 @@ fn tap_cloud(args: Args) {
let mut tapcloud = TapCloud::new_tap_cloud( let mut tapcloud = TapCloud::new_tap_cloud(
&args.flag_device, &args.flag_device,
args.flag_listen, args.flag_listen,
args.flag_behavior,
args.flag_network_id.map(|name| { args.flag_network_id.map(|name| {
let mut s = SipHasher::new(); let mut s = SipHasher::new();
name.hash(&mut s); name.hash(&mut s);
@ -98,6 +102,7 @@ fn tun_cloud(args: Args) {
let mut tuncloud = TunCloud::new_tun_cloud( let mut tuncloud = TunCloud::new_tun_cloud(
&args.flag_device, &args.flag_device,
args.flag_listen, args.flag_listen,
args.flag_behavior,
args.flag_network_id.map(|name| { args.flag_network_id.map(|name| {
let mut s = SipHasher::new(); let mut s = SipHasher::new();
name.hash(&mut s); name.hash(&mut s);