From 637ca97dc63ff5c62976de8b0470db13055ace7b Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 10 Feb 2016 18:11:10 +0100 Subject: [PATCH] Synchronous UPnP. --- parity/main.rs | 34 +++++++++++++++++----------------- util/Cargo.toml | 1 + util/src/lib.rs | 1 + util/src/network/host.rs | 25 +++++++++++++++++++++---- 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/parity/main.rs b/parity/main.rs index b28a3569e..385e10969 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -90,7 +90,6 @@ fn setup_log(init: &str) { builder.init().unwrap(); } - #[cfg(feature = "rpc")] fn setup_rpc_server(client: Arc, sync: Arc, url: &str) { use rpc::v1::*; @@ -107,18 +106,8 @@ fn setup_rpc_server(client: Arc, sync: Arc, url: &str) { fn setup_rpc_server(_client: Arc, _sync: Arc, _url: &str) { } -struct Configuration { - args: Args -} -impl Configuration { - fn parse() -> Self { - Configuration { - args: Args::docopt().decode().unwrap_or_else(|e| e.exit()) - } - } - - fn print_version(&self) { - println!("\ +fn print_version() { + println!("\ Parity version {} ({}-{}-{}) Copyright 2015, 2016 Ethcore (UK) Limited License GPLv3+: GNU GPL version 3 or later . @@ -127,6 +116,17 @@ There is NO WARRANTY, to the extent permitted by law. By Wood/Paronyan/Kotewicz/Drwięga/Volf.\ ", env!("CARGO_PKG_VERSION"), Target::arch(), Target::env(), Target::os()); +} + +struct Configuration { + args: Args +} + +impl Configuration { + fn parse() -> Self { + Configuration { + args: Args::docopt().decode().unwrap_or_else(|e| e.exit()) + } } fn get_spec(&self) -> Spec { @@ -179,7 +179,7 @@ fn wait_for_exit(client_service: &ClientService) { fn main() { let conf = Configuration::parse(); if conf.args.flag_version { - conf.print_version(); + print_version(); return; } @@ -191,10 +191,10 @@ fn main() { unsafe { ::fdlimit::raise_fd_limit(); } // Configure network - let init_nodes = conf.get_init_nodes(&spec); - let (listen, public) = conf.get_net_addresses(); let mut net_settings = NetworkConfiguration::new(); - net_settings.boot_nodes = init_nodes; + net_settings.nat_enabled = conf.args.flag_upnp; + net_settings.boot_nodes = conf.get_init_nodes(&spec); + let (listen, public) = conf.get_net_addresses(); net_settings.listen_address = listen; net_settings.public_address = public; diff --git a/util/Cargo.toml b/util/Cargo.toml index a123aecca..733b08701 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -29,3 +29,4 @@ serde = "0.6.7" clippy = "0.0.37" json-tests = { path = "json-tests" } target_info = "0.1.0" +igd = "0.4.2" diff --git a/util/src/lib.rs b/util/src/lib.rs index 260ef4301..bdd595014 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -100,6 +100,7 @@ extern crate crossbeam; extern crate serde; #[macro_use] extern crate log as rlog; +extern crate igd; pub mod standard; #[macro_use] diff --git a/util/src/network/host.rs b/util/src/network/host.rs index 3888cdf60..fb1e8e1df 100644 --- a/util/src/network/host.rs +++ b/util/src/network/host.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::net::{SocketAddr}; +use std::net::{SocketAddr, SocketAddrV4}; use std::collections::{HashMap}; use std::hash::{Hasher}; use std::str::{FromStr}; @@ -36,6 +36,7 @@ use network::NetworkProtocolHandler; use network::node::*; use network::stats::NetworkStats; use network::error::DisconnectReason; +use igd::{PortMappingProtocol,search_gateway}; type Slab = ::slab::Slab; @@ -89,11 +90,27 @@ impl NetworkConfiguration { /// Conduct NAT if needed. pub fn prepared(self) -> Self { - let listen = self.listen_address; - let public = self.public_address; + let mut listen = self.listen_address; + let mut public = self.public_address; if self.nat_enabled { - info!("Enabling NAT"); + info!("Enabling NAT..."); + match search_gateway() { + Err(ref err) => info!("Error: {}", err), + Ok(gateway) => { + let int_addr = SocketAddrV4::from_str("127.0.0.1:30304").unwrap(); + match gateway.get_any_address(PortMappingProtocol::TCP, int_addr, 0, "Parity Node/TCP") { + Err(ref err) => { + info!("There was an error! {}", err); + }, + Ok(ext_addr) => { + info!("Local gateway: {}, External ip address: {}", gateway, ext_addr); + public = SocketAddr::V4(ext_addr); + listen = SocketAddr::V4(int_addr); + }, + } + }, + } } NetworkConfiguration {