Add Nat PMP method to P2P module (#11210)
* Add Nat PMP method to P2P module * Add test fn * Use closure * print richer error messages. * reformat long code line * remove closures
This commit is contained in:
parent
2b1d148ceb
commit
e14d68e559
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -1379,6 +1379,7 @@ dependencies = [
|
|||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"natpmp 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-crypto 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-crypto 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2812,6 +2813,14 @@ name = "nan-preserving-float"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "natpmp"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cc 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "net2"
|
name = "net2"
|
||||||
version = "0.2.33"
|
version = "0.2.33"
|
||||||
@ -5612,6 +5621,7 @@ dependencies = [
|
|||||||
"checksum multibase 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b9c35dac080fd6e16a99924c8dfdef0af89d797dd851adab25feaffacf7850d6"
|
"checksum multibase 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b9c35dac080fd6e16a99924c8dfdef0af89d797dd851adab25feaffacf7850d6"
|
||||||
"checksum multihash 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c62469025f45dee2464ef9fc845f4683c543993792c1993e7d903c17a4546b74"
|
"checksum multihash 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c62469025f45dee2464ef9fc845f4683c543993792c1993e7d903c17a4546b74"
|
||||||
"checksum nan-preserving-float 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34d4f00fcc2f4c9efa8cc971db0da9e28290e28e97af47585e48691ef10ff31f"
|
"checksum nan-preserving-float 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34d4f00fcc2f4c9efa8cc971db0da9e28290e28e97af47585e48691ef10ff31f"
|
||||||
|
"checksum natpmp 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d85b74917d95eab8b26ab6fe28e21d3fede3a614411ca4d3b01265c05bf86a12"
|
||||||
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
||||||
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
|
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
|
||||||
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
||||||
|
@ -54,7 +54,7 @@ use network::{
|
|||||||
client_version::ClientVersion,
|
client_version::ClientVersion,
|
||||||
NetworkProtocolHandler, NetworkContext, PeerId, ProtocolId,
|
NetworkProtocolHandler, NetworkContext, PeerId, ProtocolId,
|
||||||
NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, Error,
|
NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, Error,
|
||||||
ConnectionFilter, IpFilter
|
ConnectionFilter, IpFilter, NatType
|
||||||
};
|
};
|
||||||
use snapshot::SnapshotService;
|
use snapshot::SnapshotService;
|
||||||
use parking_lot::{RwLock, Mutex};
|
use parking_lot::{RwLock, Mutex};
|
||||||
@ -742,6 +742,8 @@ pub struct NetworkConfiguration {
|
|||||||
pub udp_port: Option<u16>,
|
pub udp_port: Option<u16>,
|
||||||
/// Enable NAT configuration
|
/// Enable NAT configuration
|
||||||
pub nat_enabled: bool,
|
pub nat_enabled: bool,
|
||||||
|
/// Nat type
|
||||||
|
pub nat_type: NatType,
|
||||||
/// Enable discovery
|
/// Enable discovery
|
||||||
pub discovery_enabled: bool,
|
pub discovery_enabled: bool,
|
||||||
/// List of initial node addresses
|
/// List of initial node addresses
|
||||||
@ -786,6 +788,7 @@ impl NetworkConfiguration {
|
|||||||
public_address: match self.public_address { None => None, Some(addr) => Some(SocketAddr::from_str(&addr)?) },
|
public_address: match self.public_address { None => None, Some(addr) => Some(SocketAddr::from_str(&addr)?) },
|
||||||
udp_port: self.udp_port,
|
udp_port: self.udp_port,
|
||||||
nat_enabled: self.nat_enabled,
|
nat_enabled: self.nat_enabled,
|
||||||
|
nat_type: self.nat_type,
|
||||||
discovery_enabled: self.discovery_enabled,
|
discovery_enabled: self.discovery_enabled,
|
||||||
boot_nodes: self.boot_nodes,
|
boot_nodes: self.boot_nodes,
|
||||||
use_secret: self.use_secret,
|
use_secret: self.use_secret,
|
||||||
@ -810,6 +813,7 @@ impl From<BasicNetworkConfiguration> for NetworkConfiguration {
|
|||||||
public_address: other.public_address.and_then(|addr| Some(format!("{}", addr))),
|
public_address: other.public_address.and_then(|addr| Some(format!("{}", addr))),
|
||||||
udp_port: other.udp_port,
|
udp_port: other.udp_port,
|
||||||
nat_enabled: other.nat_enabled,
|
nat_enabled: other.nat_enabled,
|
||||||
|
nat_type: other.nat_type,
|
||||||
discovery_enabled: other.discovery_enabled,
|
discovery_enabled: other.discovery_enabled,
|
||||||
boot_nodes: other.boot_nodes,
|
boot_nodes: other.boot_nodes,
|
||||||
use_secret: other.use_secret,
|
use_secret: other.use_secret,
|
||||||
|
@ -53,7 +53,7 @@ use export_hardcoded_sync::ExportHsyncCmd;
|
|||||||
use presale::ImportWallet;
|
use presale::ImportWallet;
|
||||||
use account::{AccountCmd, NewAccount, ListAccounts, ImportAccounts, ImportFromGethAccounts};
|
use account::{AccountCmd, NewAccount, ListAccounts, ImportAccounts, ImportFromGethAccounts};
|
||||||
use snapshot_cmd::{self, SnapshotCommand};
|
use snapshot_cmd::{self, SnapshotCommand};
|
||||||
use network::{IpFilter};
|
use network::{IpFilter, NatType};
|
||||||
|
|
||||||
const DEFAULT_MAX_PEERS: u16 = 50;
|
const DEFAULT_MAX_PEERS: u16 = 50;
|
||||||
const DEFAULT_MIN_PEERS: u16 = 25;
|
const DEFAULT_MIN_PEERS: u16 = 25;
|
||||||
@ -743,7 +743,13 @@ impl Configuration {
|
|||||||
|
|
||||||
fn net_config(&self) -> Result<NetworkConfiguration, String> {
|
fn net_config(&self) -> Result<NetworkConfiguration, String> {
|
||||||
let mut ret = NetworkConfiguration::new();
|
let mut ret = NetworkConfiguration::new();
|
||||||
ret.nat_enabled = self.args.arg_nat == "any" || self.args.arg_nat == "upnp";
|
ret.nat_enabled = self.args.arg_nat == "any" || self.args.arg_nat == "upnp" || self.args.arg_nat == "natpmp";
|
||||||
|
ret.nat_type = match &self.args.arg_nat[..] {
|
||||||
|
"any" => NatType::Any,
|
||||||
|
"upnp" => NatType::UPnP,
|
||||||
|
"natpmp" => NatType::NatPMP,
|
||||||
|
_ => NatType::Nothing,
|
||||||
|
};
|
||||||
ret.boot_nodes = to_bootnodes(&self.args.arg_bootnodes)?;
|
ret.boot_nodes = to_bootnodes(&self.args.arg_bootnodes)?;
|
||||||
let (listen, public) = self.net_addresses()?;
|
let (listen, public) = self.net_addresses()?;
|
||||||
ret.listen_address = Some(format!("{}", listen));
|
ret.listen_address = Some(format!("{}", listen));
|
||||||
|
@ -202,6 +202,7 @@ pub fn to_bootnodes(bootnodes: &Option<String>) -> Result<Vec<String>, String> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn default_network_config() -> ::sync::NetworkConfiguration {
|
pub fn default_network_config() -> ::sync::NetworkConfiguration {
|
||||||
|
use network::NatType;
|
||||||
use sync::{NetworkConfiguration};
|
use sync::{NetworkConfiguration};
|
||||||
use super::network::IpFilter;
|
use super::network::IpFilter;
|
||||||
NetworkConfiguration {
|
NetworkConfiguration {
|
||||||
@ -211,6 +212,7 @@ pub fn default_network_config() -> ::sync::NetworkConfiguration {
|
|||||||
public_address: None,
|
public_address: None,
|
||||||
udp_port: None,
|
udp_port: None,
|
||||||
nat_enabled: true,
|
nat_enabled: true,
|
||||||
|
nat_type: NatType::Any,
|
||||||
discovery_enabled: true,
|
discovery_enabled: true,
|
||||||
boot_nodes: Vec::new(),
|
boot_nodes: Vec::new(),
|
||||||
use_secret: None,
|
use_secret: None,
|
||||||
|
@ -32,6 +32,7 @@ parity-snappy = "0.1"
|
|||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
lru-cache = "0.1"
|
lru-cache = "0.1"
|
||||||
|
natpmp = "0.2"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
env_logger = "0.5"
|
env_logger = "0.5"
|
||||||
|
@ -461,7 +461,7 @@ impl Host {
|
|||||||
let public_address = select_public_address(local_endpoint.address.port());
|
let public_address = select_public_address(local_endpoint.address.port());
|
||||||
let public_endpoint = NodeEndpoint { address: public_address, udp_port: local_endpoint.udp_port };
|
let public_endpoint = NodeEndpoint { address: public_address, udp_port: local_endpoint.udp_port };
|
||||||
if self.info.read().config.nat_enabled {
|
if self.info.read().config.nat_enabled {
|
||||||
match map_external_address(&local_endpoint) {
|
match map_external_address(&local_endpoint, &self.info.read().config.nat_type) {
|
||||||
Some(endpoint) => {
|
Some(endpoint) => {
|
||||||
info!("NAT mapped to external address {}", endpoint.address);
|
info!("NAT mapped to external address {}", endpoint.address);
|
||||||
endpoint
|
endpoint
|
||||||
|
@ -22,10 +22,17 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use igd::{PortMappingProtocol, search_gateway, SearchOptions};
|
use igd::{PortMappingProtocol, search_gateway, SearchOptions};
|
||||||
use ipnetwork::IpNetwork;
|
use ipnetwork::IpNetwork;
|
||||||
use log::debug;
|
use log::{trace, debug};
|
||||||
|
use natpmp::{Natpmp, Protocol, Response};
|
||||||
|
use network::NatType;
|
||||||
|
|
||||||
use crate::node_table::NodeEndpoint;
|
use crate::node_table::NodeEndpoint;
|
||||||
|
|
||||||
|
const NAT_PMP_PORT_MAPPING_LIFETIME: u32 = 30;
|
||||||
|
// Waiting duration in milliseconds for response from router after sending port mapping request.
|
||||||
|
// 50 milliseconds might be enough for low RTT.
|
||||||
|
const NAT_PMP_PORT_MAPPING_WAITING_DURATION: u64 = 50;
|
||||||
|
|
||||||
/// Socket address extension for rustc beta. To be replaces with now unstable API
|
/// Socket address extension for rustc beta. To be replaces with now unstable API
|
||||||
pub trait SocketAddrExt {
|
pub trait SocketAddrExt {
|
||||||
/// Returns true if the address appears to be globally routable.
|
/// Returns true if the address appears to be globally routable.
|
||||||
@ -310,20 +317,20 @@ pub fn select_public_address(port: u16) -> SocketAddr {
|
|||||||
SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), port))
|
SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), port))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_external_address(local: &NodeEndpoint) -> Option<NodeEndpoint> {
|
fn search_upnp(local: &NodeEndpoint) -> Option<NodeEndpoint> {
|
||||||
if let SocketAddr::V4(ref local_addr) = local.address {
|
if let SocketAddr::V4(ref local_addr) = local.address {
|
||||||
let local_ip = *local_addr.ip();
|
let local_ip = *local_addr.ip();
|
||||||
let local_port = local_addr.port();
|
let local_port = local_addr.port();
|
||||||
let local_udp_port = local.udp_port;
|
let local_udp_port = local.udp_port;
|
||||||
|
|
||||||
|
let search_options = SearchOptions {
|
||||||
|
timeout: Some(Duration::new(5, 0)),
|
||||||
|
// igd 0.7 used port 0 by default.
|
||||||
|
// Let's not change this behaviour
|
||||||
|
bind_addr: SocketAddr::V4(SocketAddrV4::new(local_ip, 0)),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
let search_gateway_child = ::std::thread::spawn(move || {
|
let search_gateway_child = ::std::thread::spawn(move || {
|
||||||
let search_options = SearchOptions {
|
|
||||||
timeout: Some(Duration::new(5, 0)),
|
|
||||||
// igd 0.7 used port 0 by default.
|
|
||||||
// Let's not change this behaviour
|
|
||||||
bind_addr: SocketAddr::V4(SocketAddrV4::new(local_ip, 0)),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
match search_gateway(search_options) {
|
match search_gateway(search_options) {
|
||||||
Err(ref err) => debug!("Gateway search error: {}", err),
|
Err(ref err) => debug!("Gateway search error: {}", err),
|
||||||
Ok(gateway) => {
|
Ok(gateway) => {
|
||||||
@ -358,6 +365,82 @@ pub fn map_external_address(local: &NodeEndpoint) -> Option<NodeEndpoint> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn search_natpmp(local: &NodeEndpoint) -> Option<NodeEndpoint> {
|
||||||
|
if let SocketAddr::V4(ref local_addr) = local.address {
|
||||||
|
let local_port = local_addr.port();
|
||||||
|
let local_udp_port = local.udp_port;
|
||||||
|
|
||||||
|
let search_gateway_child = ::std::thread::spawn(move || {
|
||||||
|
let mut n = Natpmp::new()?;
|
||||||
|
|
||||||
|
// this function call want to receive `Response::Gateway` response from router, if other then it is an Error.
|
||||||
|
n.send_public_address_request()?;
|
||||||
|
::std::thread::sleep(Duration::from_millis(NAT_PMP_PORT_MAPPING_WAITING_DURATION));
|
||||||
|
let gw = match n.read_response_or_retry() {
|
||||||
|
Ok(Response::Gateway(gw)) => Ok(gw),
|
||||||
|
Err(e) => {
|
||||||
|
debug!(target: "network", "IP request error: {}", e);
|
||||||
|
Err(e)
|
||||||
|
},
|
||||||
|
_ => Err(natpmp::Error::NATPMP_ERR_UNDEFINEDERROR.into())
|
||||||
|
}?;
|
||||||
|
|
||||||
|
// this function call want to receive `Response::TCP` response from router, if other then it is an Error.
|
||||||
|
n.send_port_mapping_request(Protocol::TCP, local_port, local_port, NAT_PMP_PORT_MAPPING_LIFETIME)?;
|
||||||
|
::std::thread::sleep(Duration::from_millis(NAT_PMP_PORT_MAPPING_WAITING_DURATION));
|
||||||
|
let tcp_r = match n.read_response_or_retry() {
|
||||||
|
Ok(Response::TCP(tcp)) => Ok(tcp),
|
||||||
|
Err(e) => {
|
||||||
|
debug!(target: "network", "Port mapping for TCP error: {}", e);
|
||||||
|
Err(e)
|
||||||
|
},
|
||||||
|
_ => Err(natpmp::Error::NATPMP_ERR_UNDEFINEDERROR.into())
|
||||||
|
}?;
|
||||||
|
|
||||||
|
// this function call want to receive `Response::UDP` response from router, if other then it is an Error.
|
||||||
|
n.send_port_mapping_request(Protocol::UDP, local_udp_port, local_udp_port, NAT_PMP_PORT_MAPPING_LIFETIME)?;
|
||||||
|
::std::thread::sleep(Duration::from_millis(NAT_PMP_PORT_MAPPING_WAITING_DURATION));
|
||||||
|
let udp_r = match n.read_response_or_retry() {
|
||||||
|
Ok(Response::UDP(udp)) => Ok(udp),
|
||||||
|
Err(e) => {
|
||||||
|
debug!(target: "network", "Port mapping for UDP error: {}", e);
|
||||||
|
Err(e)
|
||||||
|
},
|
||||||
|
_ => Err(natpmp::Error::NATPMP_ERR_UNDEFINEDERROR.into())
|
||||||
|
}?;
|
||||||
|
|
||||||
|
Ok(NodeEndpoint {
|
||||||
|
address: SocketAddr::V4(SocketAddrV4::new(*gw.public_address(), tcp_r.public_port())),
|
||||||
|
udp_port: udp_r.public_port()
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
return search_gateway_child.join().ok()?
|
||||||
|
.map_err(|e: natpmp::Error| debug!(target: "network", "NAT PMP port mapping error: {:?}", e))
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Port mapping using ether UPnP or Nat-PMP.
|
||||||
|
/// NAT PMP has higher priority than UPnP.
|
||||||
|
pub fn map_external_address(local: &NodeEndpoint, nat_type: &NatType) -> Option<NodeEndpoint> {
|
||||||
|
match *nat_type {
|
||||||
|
NatType::Any => {
|
||||||
|
match search_natpmp(local) {
|
||||||
|
Some(end_point) => Some(end_point),
|
||||||
|
None => search_upnp(local),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
NatType::NatPMP => search_natpmp(local),
|
||||||
|
NatType::UPnP => search_upnp(local),
|
||||||
|
_ => {
|
||||||
|
trace!(target: "network", "Can't map external address using NAT");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_select_public_address() {
|
fn can_select_public_address() {
|
||||||
let pub_address = select_public_address(40477);
|
let pub_address = select_public_address(40477);
|
||||||
@ -366,9 +449,16 @@ fn can_select_public_address() {
|
|||||||
|
|
||||||
#[ignore]
|
#[ignore]
|
||||||
#[test]
|
#[test]
|
||||||
fn can_map_external_address_or_fail() {
|
fn can_map_external_address_upnp_or_fail() {
|
||||||
let pub_address = select_public_address(40478);
|
let pub_address = select_public_address(40478);
|
||||||
let _ = map_external_address(&NodeEndpoint { address: pub_address, udp_port: 40478 });
|
let _ = map_external_address(&NodeEndpoint { address: pub_address, udp_port: 40478 }, &NatType::UPnP);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ignore]
|
||||||
|
#[test]
|
||||||
|
fn can_map_external_address_natpmp_or_fail() {
|
||||||
|
let pub_address = select_public_address(40479);
|
||||||
|
let _ = map_external_address(&NodeEndpoint { address: pub_address, udp_port: 40479 }, &NatType::NatPMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -174,6 +174,15 @@ impl Ord for SessionCapabilityInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Type of NAT resolving method
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
|
pub enum NatType {
|
||||||
|
Nothing,
|
||||||
|
Any,
|
||||||
|
UPnP,
|
||||||
|
NatPMP,
|
||||||
|
}
|
||||||
|
|
||||||
/// Network service configuration
|
/// Network service configuration
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct NetworkConfiguration {
|
pub struct NetworkConfiguration {
|
||||||
@ -189,6 +198,8 @@ pub struct NetworkConfiguration {
|
|||||||
pub udp_port: Option<u16>,
|
pub udp_port: Option<u16>,
|
||||||
/// Enable NAT configuration
|
/// Enable NAT configuration
|
||||||
pub nat_enabled: bool,
|
pub nat_enabled: bool,
|
||||||
|
/// Nat type
|
||||||
|
pub nat_type: NatType,
|
||||||
/// Enable discovery
|
/// Enable discovery
|
||||||
pub discovery_enabled: bool,
|
pub discovery_enabled: bool,
|
||||||
/// List of initial node addresses
|
/// List of initial node addresses
|
||||||
@ -229,6 +240,7 @@ impl NetworkConfiguration {
|
|||||||
public_address: None,
|
public_address: None,
|
||||||
udp_port: None,
|
udp_port: None,
|
||||||
nat_enabled: true,
|
nat_enabled: true,
|
||||||
|
nat_type: NatType::Any,
|
||||||
discovery_enabled: true,
|
discovery_enabled: true,
|
||||||
boot_nodes: Vec::new(),
|
boot_nodes: Vec::new(),
|
||||||
use_secret: None,
|
use_secret: None,
|
||||||
|
Loading…
Reference in New Issue
Block a user