,
_dummy_p: PhantomData,
}
@@ -178,7 +180,7 @@ impl GenericCloud {
#[allow(too_many_arguments)]
pub fn new(magic: HeaderMagic, device: Device, listen: u16, table: Box
,
peer_timeout: Duration, learning: bool, broadcast: bool, addresses: Vec,
- crypto: Crypto) -> Self {
+ crypto: Crypto, port_forwarding: Option) -> Self {
let socket4 = match UdpBuilder::new_v4().expect("Failed to obtain ipv4 socket builder")
.reuse_address(true).expect("Failed to set so_reuseaddr").bind(("0.0.0.0", listen)) {
Ok(socket) => socket,
@@ -208,6 +210,7 @@ impl GenericCloud {
update_freq: peer_timeout/2-60,
buffer_out: [0; 64*1024],
next_housekeep: now(),
+ port_forwarding: port_forwarding,
_dummy_p: PhantomData,
}
}
@@ -347,6 +350,10 @@ impl GenericCloud {
self.table.remove_all(&peer);
}
self.table.housekeep();
+ // Periodically extend the port-forwarding
+ if let Some(ref mut pfw) = self.port_forwarding {
+ pfw.check_extend();
+ }
// Periodically send peer list to peers
let now = now();
if self.next_peerlist <= now {
diff --git a/src/config.rs b/src/config.rs
index 69f5541..5a937f4 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -23,6 +23,7 @@ pub struct Config {
pub mode: Mode,
pub dst_timeout: Duration,
pub subnets: Vec,
+ pub port_forwarding: bool,
}
impl Default for Config {
@@ -34,7 +35,8 @@ impl Default for Config {
magic: None,
port: 3210, peers: vec![], peer_timeout: 1800,
mode: Mode::Normal, dst_timeout: 300,
- subnets: vec![]
+ subnets: vec![],
+ port_forwarding: true
}
}
}
@@ -80,6 +82,9 @@ impl Config {
if let Some(mut val) = file.subnets {
self.subnets.append(&mut val);
}
+ if let Some(val) = file.port_forwarding {
+ self.port_forwarding = val;
+ }
}
pub fn merge_args(&mut self, mut args: Args) {
@@ -122,6 +127,9 @@ impl Config {
self.dst_timeout = val;
}
self.subnets.append(&mut args.flag_subnet);
+ if args.flag_no_port_forwarding {
+ self.port_forwarding = false;
+ }
}
pub fn get_magic(&self) -> HeaderMagic {
@@ -160,4 +168,5 @@ pub struct ConfigFile {
pub mode: Option,
pub dst_timeout: Option,
pub subnets: Option>,
+ pub port_forwarding: Option
}
diff --git a/src/main.rs b/src/main.rs
index 2ba2cef..2aa6276 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -17,6 +17,7 @@ extern crate rand;
extern crate fnv;
extern crate net2;
extern crate yaml_rust;
+extern crate igd;
#[cfg(feature = "bench")] extern crate test;
#[macro_use] pub mod util;
@@ -30,6 +31,7 @@ pub mod device;
pub mod poll;
pub mod config;
pub mod configfile;
+pub mod port_forwarding;
#[cfg(test)] mod tests;
#[cfg(feature = "bench")] mod benches;
@@ -44,6 +46,7 @@ use ip::RoutingTable;
use types::{Mode, Range, Table, Protocol, HeaderMagic};
use cloud::GenericCloud;
use crypto::{Crypto, CryptoMethod};
+use port_forwarding::PortForwarding;
use util::Duration;
use config::Config;
@@ -72,7 +75,8 @@ pub struct Args {
flag_quiet: bool,
flag_ifup: Option,
flag_ifdown: Option,
- flag_version: bool
+ flag_version: bool,
+ flag_no_port_forwarding: bool
}
@@ -131,7 +135,12 @@ fn run (config: Config) {
Some(key) => Crypto::from_shared_key(config.crypto, &key),
None => Crypto::None
};
- let mut cloud = GenericCloud::::new(magic, device, config.port, table, peer_timeout, learning, broadcasting, ranges, crypto);
+ let port_forwarding = if config.port_forwarding {
+ PortForwarding::new(config.port)
+ } else {
+ None
+ };
+ let mut cloud = GenericCloud::::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());
}
diff --git a/src/port_forwarding.rs b/src/port_forwarding.rs
new file mode 100644
index 0000000..89a7f1e
--- /dev/null
+++ b/src/port_forwarding.rs
@@ -0,0 +1,128 @@
+use std::net::{SocketAddrV4, UdpSocket, SocketAddr};
+use std::io;
+
+use igd::*;
+
+use super::util::{Time, now};
+
+const LEASE_TIME: u32 = 300;
+const DESCRIPTION: &'static str = "VpnCloud";
+
+
+pub struct PortForwarding {
+ pub internal_addr: SocketAddrV4,
+ pub external_addr: SocketAddrV4,
+ pub gateway: Gateway,
+ pub next_extension: Option