detection work

This commit is contained in:
John Smith 2022-08-07 14:55:48 -04:00
parent 4aa9f6d2b9
commit 0204af263d
10 changed files with 119 additions and 58 deletions

View File

@ -1651,6 +1651,10 @@ impl NetworkManager {
let routing_table = inner.routing_table.as_ref().unwrap().clone(); let routing_table = inner.routing_table.as_ref().unwrap().clone();
(net, routing_table) (net, routing_table)
}; };
let detect_address_changes = {
let c = self.config.get();
c.network.detect_address_changes
};
let network_class = net.get_network_class().unwrap_or(NetworkClass::Invalid); let network_class = net.get_network_class().unwrap_or(NetworkClass::Invalid);
// Determine if our external address has likely changed // Determine if our external address has likely changed
@ -1709,6 +1713,7 @@ impl NetworkManager {
}; };
if needs_public_address_detection { if needs_public_address_detection {
if detect_address_changes {
// Reset the address check cache now so we can start detecting fresh // Reset the address check cache now so we can start detecting fresh
info!("Public address has changed, detecting public dial info"); info!("Public address has changed, detecting public dial info");
@ -1716,8 +1721,14 @@ impl NetworkManager {
inner.public_address_check_cache.clear(); inner.public_address_check_cache.clear();
// Reset the network class and dial info so we can re-detect it // Reset the network class and dial info so we can re-detect it
routing_table.clear_dial_info_details(RoutingDomain::PublicInternet); //routing_table.clear_dial_info_details(RoutingDomain::PublicInternet);
net.reset_network_class(); //net.reset_network_class();
// Do a full network reset since this doesn't take that long and ensures we get the local network stuff correct too
net.restart_network();
} else {
warn!("Public address may have changed. Restarting the server may be required.");
}
} }
} }

View File

@ -653,13 +653,17 @@ impl Network {
self.free_bound_first_ports(); self.free_bound_first_ports();
// If we have static public dialinfo, upgrade our network class // If we have static public dialinfo, upgrade our network class
// xxx: force public address detection let detect_address_changes = {
// { let c = self.config.get();
// let mut inner = self.inner.lock(); c.network.detect_address_changes
// if !inner.static_public_dialinfo.is_empty() { };
// inner.network_class = Some(NetworkClass::InboundCapable);
// } if !detect_address_changes {
// } let mut inner = self.inner.lock();
if !inner.static_public_dialinfo.is_empty() {
inner.network_class = Some(NetworkClass::InboundCapable);
}
}
info!("network started"); info!("network started");
self.inner.lock().network_started = true; self.inner.lock().network_started = true;
@ -746,11 +750,17 @@ impl Network {
} }
pub async fn tick(&self) -> EyreResult<()> { pub async fn tick(&self) -> EyreResult<()> {
let network_class = self.get_network_class().unwrap_or(NetworkClass::Invalid); let detect_address_changes = {
let routing_table = self.routing_table(); let config = self.network_manager().config();
let c = config.get();
c.network.detect_address_changes
};
// If we need to figure out our network class, tick the task for it // If we need to figure out our network class, tick the task for it
if detect_address_changes {
let network_class = self.get_network_class().unwrap_or(NetworkClass::Invalid);
if network_class == NetworkClass::Invalid { if network_class == NetworkClass::Invalid {
let routing_table = self.routing_table();
let rth = routing_table.get_routing_table_health(); let rth = routing_table.get_routing_table_health();
// Need at least two entries to do this // Need at least two entries to do this
@ -764,6 +774,7 @@ impl Network {
if !self.needs_restart() { if !self.needs_restart() {
self.unlocked_inner.network_interfaces_task.tick().await?; self.unlocked_inner.network_interfaces_task.tick().await?;
} }
}
Ok(()) Ok(())
} }

View File

@ -439,6 +439,7 @@ impl Network {
"Skipping detection for public dialinfo for {:?}:IPV4", "Skipping detection for public dialinfo for {:?}:IPV4",
protocol_type protocol_type
); );
context.set_detected_network_class(NetworkClass::InboundCapable);
return Ok(()); return Ok(());
} }
@ -511,6 +512,7 @@ impl Network {
"Skipping detection for public dialinfo for {:?}:IPV6", "Skipping detection for public dialinfo for {:?}:IPV6",
protocol_type protocol_type
); );
context.set_detected_network_class(NetworkClass::InboundCapable);
return Ok(()); return Ok(());
} }
// Start doing ipv6 protocol // Start doing ipv6 protocol

View File

@ -253,12 +253,13 @@ impl Network {
pub(super) async fn start_udp_listeners(&self) -> EyreResult<()> { pub(super) async fn start_udp_listeners(&self) -> EyreResult<()> {
trace!("starting udp listeners"); trace!("starting udp listeners");
let routing_table = self.routing_table(); let routing_table = self.routing_table();
let (listen_address, public_address, enable_local_peer_scope) = { let (listen_address, public_address, enable_local_peer_scope, detect_address_changes) = {
let c = self.config.get(); let c = self.config.get();
( (
c.network.protocol.udp.listen_address.clone(), c.network.protocol.udp.listen_address.clone(),
c.network.protocol.udp.public_address.clone(), c.network.protocol.udp.public_address.clone(),
c.network.enable_local_peer_scope, c.network.enable_local_peer_scope,
c.network.detect_address_changes,
) )
}; };
@ -289,7 +290,10 @@ impl Network {
for di in &local_dial_info_list { for di in &local_dial_info_list {
// If the local interface address is global, or we are enabling local peer scope // If the local interface address is global, or we are enabling local peer scope
// register global dial info if no public address is specified // register global dial info if no public address is specified
if public_address.is_none() && (di.is_global() || enable_local_peer_scope) { if !detect_address_changes
&& public_address.is_none()
&& (di.is_global() || enable_local_peer_scope)
{
routing_table.register_dial_info( routing_table.register_dial_info(
RoutingDomain::PublicInternet, RoutingDomain::PublicInternet,
di.clone(), di.clone(),
@ -318,11 +322,14 @@ impl Network {
let pdi = DialInfo::udp_from_socketaddr(pdi_addr); let pdi = DialInfo::udp_from_socketaddr(pdi_addr);
// Register the public address // Register the public address
if !detect_address_changes {
routing_table.register_dial_info( routing_table.register_dial_info(
RoutingDomain::PublicInternet, RoutingDomain::PublicInternet,
pdi.clone(), pdi.clone(),
DialInfoClass::Direct, DialInfoClass::Direct,
)?; )?;
static_public = true;
}
// See if this public address is also a local interface address we haven't registered yet // See if this public address is also a local interface address we haven't registered yet
let is_interface_address = self.with_interface_addresses(|ip_addrs| { let is_interface_address = self.with_interface_addresses(|ip_addrs| {
@ -340,8 +347,6 @@ impl Network {
DialInfoClass::Direct, DialInfoClass::Direct,
)?; )?;
} }
static_public = true;
} }
} }
@ -359,13 +364,14 @@ impl Network {
pub(super) async fn start_ws_listeners(&self) -> EyreResult<()> { pub(super) async fn start_ws_listeners(&self) -> EyreResult<()> {
trace!("starting ws listeners"); trace!("starting ws listeners");
let routing_table = self.routing_table(); let routing_table = self.routing_table();
let (listen_address, url, path, enable_local_peer_scope) = { let (listen_address, url, path, enable_local_peer_scope, detect_address_changes) = {
let c = self.config.get(); let c = self.config.get();
( (
c.network.protocol.ws.listen_address.clone(), c.network.protocol.ws.listen_address.clone(),
c.network.protocol.ws.url.clone(), c.network.protocol.ws.url.clone(),
c.network.protocol.ws.path.clone(), c.network.protocol.ws.path.clone(),
c.network.enable_local_peer_scope, c.network.enable_local_peer_scope,
c.network.detect_address_changes,
) )
}; };
@ -413,12 +419,14 @@ impl Network {
let pdi = DialInfo::try_ws(SocketAddress::from_socket_addr(gsa), url.clone()) let pdi = DialInfo::try_ws(SocketAddress::from_socket_addr(gsa), url.clone())
.wrap_err("try_ws failed")?; .wrap_err("try_ws failed")?;
if !detect_address_changes {
routing_table.register_dial_info( routing_table.register_dial_info(
RoutingDomain::PublicInternet, RoutingDomain::PublicInternet,
pdi.clone(), pdi.clone(),
DialInfoClass::Direct, DialInfoClass::Direct,
)?; )?;
static_public = true; static_public = true;
}
// See if this public address is also a local interface address // See if this public address is also a local interface address
let is_interface_address = self.with_interface_addresses(|ip_addrs| { let is_interface_address = self.with_interface_addresses(|ip_addrs| {
@ -450,7 +458,10 @@ impl Network {
let local_url = format!("ws://{}/{}", socket_address, path); let local_url = format!("ws://{}/{}", socket_address, path);
let local_di = DialInfo::try_ws(socket_address, local_url).wrap_err("try_ws failed")?; let local_di = DialInfo::try_ws(socket_address, local_url).wrap_err("try_ws failed")?;
if url.is_none() && (socket_address.address().is_global() || enable_local_peer_scope) { if !detect_address_changes
&& url.is_none()
&& (socket_address.address().is_global() || enable_local_peer_scope)
{
// Register public dial info // Register public dial info
routing_table.register_dial_info( routing_table.register_dial_info(
RoutingDomain::PublicInternet, RoutingDomain::PublicInternet,
@ -482,11 +493,12 @@ impl Network {
trace!("starting wss listeners"); trace!("starting wss listeners");
let routing_table = self.routing_table(); let routing_table = self.routing_table();
let (listen_address, url) = { let (listen_address, url, detect_address_changes) = {
let c = self.config.get(); let c = self.config.get();
( (
c.network.protocol.wss.listen_address.clone(), c.network.protocol.wss.listen_address.clone(),
c.network.protocol.wss.url.clone(), c.network.protocol.wss.url.clone(),
c.network.detect_address_changes,
) )
}; };
@ -539,12 +551,14 @@ impl Network {
let pdi = DialInfo::try_wss(SocketAddress::from_socket_addr(gsa), url.clone()) let pdi = DialInfo::try_wss(SocketAddress::from_socket_addr(gsa), url.clone())
.wrap_err("try_wss failed")?; .wrap_err("try_wss failed")?;
if !detect_address_changes {
routing_table.register_dial_info( routing_table.register_dial_info(
RoutingDomain::PublicInternet, RoutingDomain::PublicInternet,
pdi.clone(), pdi.clone(),
DialInfoClass::Direct, DialInfoClass::Direct,
)?; )?;
static_public = true; static_public = true;
}
// See if this public address is also a local interface address // See if this public address is also a local interface address
let is_interface_address = self.with_interface_addresses(|ip_addrs| { let is_interface_address = self.with_interface_addresses(|ip_addrs| {
@ -583,12 +597,13 @@ impl Network {
trace!("starting tcp listeners"); trace!("starting tcp listeners");
let routing_table = self.routing_table(); let routing_table = self.routing_table();
let (listen_address, public_address, enable_local_peer_scope) = { let (listen_address, public_address, enable_local_peer_scope, detect_address_changes) = {
let c = self.config.get(); let c = self.config.get();
( (
c.network.protocol.tcp.listen_address.clone(), c.network.protocol.tcp.listen_address.clone(),
c.network.protocol.tcp.public_address.clone(), c.network.protocol.tcp.public_address.clone(),
c.network.enable_local_peer_scope, c.network.enable_local_peer_scope,
c.network.detect_address_changes,
) )
}; };
@ -622,7 +637,10 @@ impl Network {
let di = DialInfo::tcp(socket_address); let di = DialInfo::tcp(socket_address);
// Register global dial info if no public address is specified // Register global dial info if no public address is specified
if public_address.is_none() && (di.is_global() || enable_local_peer_scope) { if !detect_address_changes
&& public_address.is_none()
&& (di.is_global() || enable_local_peer_scope)
{
routing_table.register_dial_info( routing_table.register_dial_info(
RoutingDomain::PublicInternet, RoutingDomain::PublicInternet,
di.clone(), di.clone(),
@ -654,12 +672,14 @@ impl Network {
} }
let pdi = DialInfo::tcp_from_socketaddr(pdi_addr); let pdi = DialInfo::tcp_from_socketaddr(pdi_addr);
if !detect_address_changes {
routing_table.register_dial_info( routing_table.register_dial_info(
RoutingDomain::PublicInternet, RoutingDomain::PublicInternet,
pdi.clone(), pdi.clone(),
DialInfoClass::Direct, DialInfoClass::Direct,
)?; )?;
static_public = true; static_public = true;
}
// See if this public address is also a local interface address // See if this public address is also a local interface address
let is_interface_address = self.with_interface_addresses(|ip_addrs| { let is_interface_address = self.with_interface_addresses(|ip_addrs| {

View File

@ -223,6 +223,7 @@ fn config_callback(key: String) -> ConfigCallbackReturn {
"network.dht.validate_dial_info_receipt_time_ms" => Ok(Box::new(5_000u32)), "network.dht.validate_dial_info_receipt_time_ms" => Ok(Box::new(5_000u32)),
"network.upnp" => Ok(Box::new(false)), "network.upnp" => Ok(Box::new(false)),
"network.natpmp" => Ok(Box::new(false)), "network.natpmp" => Ok(Box::new(false)),
"network.detect_address_changes" => Ok(Box::new(true)),
"network.enable_local_peer_scope" => Ok(Box::new(false)), "network.enable_local_peer_scope" => Ok(Box::new(false)),
"network.restricted_nat_retries" => Ok(Box::new(3u32)), "network.restricted_nat_retries" => Ok(Box::new(3u32)),
"network.tls.certificate_path" => Ok(Box::new(get_certfile_path())), "network.tls.certificate_path" => Ok(Box::new(get_certfile_path())),
@ -352,6 +353,7 @@ pub async fn test_config() {
assert_eq!(inner.network.upnp, false); assert_eq!(inner.network.upnp, false);
assert_eq!(inner.network.natpmp, false); assert_eq!(inner.network.natpmp, false);
assert_eq!(inner.network.detect_address_changes, true);
assert_eq!(inner.network.enable_local_peer_scope, false); assert_eq!(inner.network.enable_local_peer_scope, false);
assert_eq!(inner.network.restricted_nat_retries, 3u32); assert_eq!(inner.network.restricted_nat_retries, 3u32);
assert_eq!(inner.network.tls.certificate_path, get_certfile_path()); assert_eq!(inner.network.tls.certificate_path, get_certfile_path());

View File

@ -136,6 +136,7 @@ pub struct VeilidConfigNetwork {
pub dht: VeilidConfigDHT, pub dht: VeilidConfigDHT,
pub upnp: bool, pub upnp: bool,
pub natpmp: bool, pub natpmp: bool,
pub detect_address_changes: bool,
pub enable_local_peer_scope: bool, pub enable_local_peer_scope: bool,
pub restricted_nat_retries: u32, pub restricted_nat_retries: u32,
pub tls: VeilidConfigTLS, pub tls: VeilidConfigTLS,
@ -354,6 +355,7 @@ impl VeilidConfig {
get_config!(inner.network.rpc.max_route_hop_count); get_config!(inner.network.rpc.max_route_hop_count);
get_config!(inner.network.upnp); get_config!(inner.network.upnp);
get_config!(inner.network.natpmp); get_config!(inner.network.natpmp);
get_config!(inner.network.detect_address_changes);
get_config!(inner.network.enable_local_peer_scope); get_config!(inner.network.enable_local_peer_scope);
get_config!(inner.network.restricted_nat_retries); get_config!(inner.network.restricted_nat_retries);
get_config!(inner.network.tls.certificate_path); get_config!(inner.network.tls.certificate_path);

View File

@ -84,6 +84,7 @@ Future<VeilidConfig> getDefaultVeilidConfig() async {
), ),
upnp: true, upnp: true,
natpmp: true, natpmp: true,
detectAddressChanges: true,
enableLocalPeerScope: false, enableLocalPeerScope: false,
restrictedNatRetries: 3, restrictedNatRetries: 3,
tls: VeilidConfigTLS( tls: VeilidConfigTLS(

View File

@ -740,6 +740,7 @@ class VeilidConfigNetwork {
VeilidConfigDHT dht; VeilidConfigDHT dht;
bool upnp; bool upnp;
bool natpmp; bool natpmp;
bool detectAddressChanges;
bool enableLocalPeerScope; bool enableLocalPeerScope;
int restrictedNatRetries; int restrictedNatRetries;
VeilidConfigTLS tls; VeilidConfigTLS tls;
@ -765,6 +766,7 @@ class VeilidConfigNetwork {
required this.dht, required this.dht,
required this.upnp, required this.upnp,
required this.natpmp, required this.natpmp,
required this.detectAddressChanges,
required this.enableLocalPeerScope, required this.enableLocalPeerScope,
required this.restrictedNatRetries, required this.restrictedNatRetries,
required this.tls, required this.tls,
@ -792,6 +794,7 @@ class VeilidConfigNetwork {
'dht': dht.json, 'dht': dht.json,
'upnp': upnp, 'upnp': upnp,
'natpmp': natpmp, 'natpmp': natpmp,
'detect_address_changes': detectAddressChanges,
'enable_local_peer_scope': enableLocalPeerScope, 'enable_local_peer_scope': enableLocalPeerScope,
'restricted_nat_retries': restrictedNatRetries, 'restricted_nat_retries': restrictedNatRetries,
'tls': tls.json, 'tls': tls.json,
@ -822,6 +825,7 @@ class VeilidConfigNetwork {
dht = VeilidConfigDHT.fromJson(json['dht']), dht = VeilidConfigDHT.fromJson(json['dht']),
upnp = json['upnp'], upnp = json['upnp'],
natpmp = json['natpmp'], natpmp = json['natpmp'],
detectAddressChanges = json['detect_address_changes'],
enableLocalPeerScope = json['enable_local_peer_scope'], enableLocalPeerScope = json['enable_local_peer_scope'],
restrictedNatRetries = json['restricted_nat_retries'], restrictedNatRetries = json['restricted_nat_retries'],
tls = VeilidConfigTLS.fromJson(json['tls']), tls = VeilidConfigTLS.fromJson(json['tls']),

View File

@ -98,6 +98,7 @@ core:
validate_dial_info_receipt_time_ms: 2000 validate_dial_info_receipt_time_ms: 2000
upnp: false upnp: false
natpmp: false natpmp: false
detect_address_changes: true
enable_local_peer_scope: false enable_local_peer_scope: false
restricted_nat_retries: 0 restricted_nat_retries: 0
tls: tls:
@ -587,6 +588,7 @@ pub struct Network {
pub dht: Dht, pub dht: Dht,
pub upnp: bool, pub upnp: bool,
pub natpmp: bool, pub natpmp: bool,
pub detect_address_changes: bool,
pub enable_local_peer_scope: bool, pub enable_local_peer_scope: bool,
pub restricted_nat_retries: u32, pub restricted_nat_retries: u32,
pub tls: Tls, pub tls: Tls,
@ -973,6 +975,7 @@ impl Settings {
); );
set_config_value!(inner.core.network.upnp, value); set_config_value!(inner.core.network.upnp, value);
set_config_value!(inner.core.network.natpmp, value); set_config_value!(inner.core.network.natpmp, value);
set_config_value!(inner.core.network.detect_address_changes, value);
set_config_value!(inner.core.network.enable_local_peer_scope, value); set_config_value!(inner.core.network.enable_local_peer_scope, value);
set_config_value!(inner.core.network.restricted_nat_retries, value); set_config_value!(inner.core.network.restricted_nat_retries, value);
set_config_value!(inner.core.network.tls.certificate_path, value); set_config_value!(inner.core.network.tls.certificate_path, value);
@ -1171,6 +1174,9 @@ impl Settings {
)), )),
"network.upnp" => Ok(Box::new(inner.core.network.upnp)), "network.upnp" => Ok(Box::new(inner.core.network.upnp)),
"network.natpmp" => Ok(Box::new(inner.core.network.natpmp)), "network.natpmp" => Ok(Box::new(inner.core.network.natpmp)),
"network.detect_address_changes" => {
Ok(Box::new(inner.core.network.detect_address_changes))
}
"network.enable_local_peer_scope" => { "network.enable_local_peer_scope" => {
Ok(Box::new(inner.core.network.enable_local_peer_scope)) Ok(Box::new(inner.core.network.enable_local_peer_scope))
} }
@ -1496,6 +1502,7 @@ mod tests {
// //
assert_eq!(s.core.network.upnp, false); assert_eq!(s.core.network.upnp, false);
assert_eq!(s.core.network.natpmp, false); assert_eq!(s.core.network.natpmp, false);
assert_eq!(s.core.network.detect_address_changes, true);
assert_eq!(s.core.network.enable_local_peer_scope, false); assert_eq!(s.core.network.enable_local_peer_scope, false);
assert_eq!(s.core.network.restricted_nat_retries, 0u32); assert_eq!(s.core.network.restricted_nat_retries, 0u32);
// //

View File

@ -61,6 +61,7 @@ fn init_callbacks() {
case "network.dht.validate_dial_info_receipt_time": return 5000000; case "network.dht.validate_dial_info_receipt_time": return 5000000;
case "network.upnp": return false; case "network.upnp": return false;
case "network.natpmp": return false; case "network.natpmp": return false;
case "network.detect_address_changes": return true;
case "network.address_filter": return true; case "network.address_filter": return true;
case "network.restricted_nat_retries": return 3; case "network.restricted_nat_retries": return 3;
case "network.tls.certificate_path": return ""; case "network.tls.certificate_path": return "";