From caeaed3e2d9ec63db528e7652cb9ecca9438b77f Mon Sep 17 00:00:00 2001 From: David Palm Date: Tue, 2 Jul 2019 11:35:50 +0200 Subject: [PATCH 1/2] Allow --nat extip:your.host.here.org Closes #10604 --- parity/configuration.rs | 45 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/parity/configuration.rs b/parity/configuration.rs index 541637fd411..c4f117b3acf 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -16,7 +16,7 @@ use std::time::Duration; use std::io::Read; -use std::net::SocketAddr; +use std::net::{SocketAddr, ToSocketAddrs}; use std::path::PathBuf; use std::collections::{HashSet, BTreeMap}; use std::iter::FromIterator; @@ -725,9 +725,19 @@ impl Configuration { let port = self.args.arg_ports_shift + self.args.arg_port; let listen_address = SocketAddr::new(self.interface(&self.args.arg_interface).parse().unwrap(), port); let public_address = if self.args.arg_nat.starts_with("extip:") { - let host = &self.args.arg_nat[6..]; - let host = host.parse().map_err(|_| format!("Invalid host given with `--nat extip:{}`", host))?; - Some(SocketAddr::new(host, port)) + use regex::Regex; + let re = Regex::new(r":.*$").expect("regex is valid"); + let host = format!("{}:{}", re.replace_all(&self.args.arg_nat[6..], ""), port); + match host.to_socket_addrs() { + Ok(mut addr_iter) => { + if let Some(addr) = addr_iter.next() { + Some(addr) + } else { + return Err(format!("Invalid host given with `--nat extip:{}`", &self.args.arg_nat[6..])) + } + }, + Err(_) => return Err(format!("Invalid host given with `--nat extip:{}`", &self.args.arg_nat[6..])) + } } else { None }; @@ -1844,6 +1854,33 @@ mod tests { assert_eq!(conf1.ipfs_config().port, 5002); } + #[test] + fn should_resolve_external_nat_hosts() { + // Ip works + let conf = parse(&["parity", "--nat", "extip:1.1.1.1"]); + assert_eq!(conf.net_addresses().unwrap().1.unwrap().ip().to_string(), "1.1.1.1"); + assert_eq!(conf.net_addresses().unwrap().1.unwrap().port(), 30303); + + // Ip with port works, port is discarded + let conf = parse(&["parity", "--nat", "extip:192.168.1.1:123"]); + assert_eq!(conf.net_addresses().unwrap().1.unwrap().ip().to_string(), "192.168.1.1"); + assert_eq!(conf.net_addresses().unwrap().1.unwrap().port(), 30303); + + // Hostname works + let conf = parse(&["parity", "--nat", "extip:ethereum.org"]); + assert!(conf.net_addresses().unwrap().1.is_some()); + assert_eq!(conf.net_addresses().unwrap().1.unwrap().port(), 30303); + + // Hostname works, garbage at the end is discarded + let conf = parse(&["parity", "--nat", "extip:ethereum.org:whatever bla bla 123"]); + assert!(conf.net_addresses().unwrap().1.is_some()); + assert_eq!(conf.net_addresses().unwrap().1.unwrap().port(), 30303); + + // Garbage is error + let conf = parse(&["parity", "--nat", "extip:blabla"]); + assert!(conf.net_addresses().is_err()); + } + #[test] fn should_expose_all_servers() { // given From ac8184f6b053e7e977b9eb1cdd7d72d8ebd1f1cc Mon Sep 17 00:00:00 2001 From: David Palm Date: Tue, 2 Jul 2019 20:58:44 +0200 Subject: [PATCH 2/2] Use split instead of Regex --- parity/configuration.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/parity/configuration.rs b/parity/configuration.rs index c4f117b3acf..e864eabade1 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -725,9 +725,8 @@ impl Configuration { let port = self.args.arg_ports_shift + self.args.arg_port; let listen_address = SocketAddr::new(self.interface(&self.args.arg_interface).parse().unwrap(), port); let public_address = if self.args.arg_nat.starts_with("extip:") { - use regex::Regex; - let re = Regex::new(r":.*$").expect("regex is valid"); - let host = format!("{}:{}", re.replace_all(&self.args.arg_nat[6..], ""), port); + let host = self.args.arg_nat[6..].split(':').next().expect("split has at least one part; qed"); + let host = format!("{}:{}", host, port); match host.to_socket_addrs() { Ok(mut addr_iter) => { if let Some(addr) = addr_iter.next() {