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();
(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);
// Determine if our external address has likely changed
@ -1709,15 +1713,22 @@ impl NetworkManager {
};
if needs_public_address_detection {
// Reset the address check cache now so we can start detecting fresh
info!("Public address has changed, detecting public dial info");
if detect_address_changes {
// Reset the address check cache now so we can start detecting fresh
info!("Public address has changed, detecting public dial info");
let mut inner = self.inner.lock();
inner.public_address_check_cache.clear();
let mut inner = self.inner.lock();
inner.public_address_check_cache.clear();
// Reset the network class and dial info so we can re-detect it
routing_table.clear_dial_info_details(RoutingDomain::PublicInternet);
net.reset_network_class();
// Reset the network class and dial info so we can re-detect it
//routing_table.clear_dial_info_details(RoutingDomain::PublicInternet);
//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();
// If we have static public dialinfo, upgrade our network class
// xxx: force public address detection
// {
// let mut inner = self.inner.lock();
// if !inner.static_public_dialinfo.is_empty() {
// inner.network_class = Some(NetworkClass::InboundCapable);
// }
// }
let detect_address_changes = {
let c = self.config.get();
c.network.detect_address_changes
};
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");
self.inner.lock().network_started = true;
@ -746,23 +750,30 @@ impl Network {
}
pub async fn tick(&self) -> EyreResult<()> {
let network_class = self.get_network_class().unwrap_or(NetworkClass::Invalid);
let routing_table = self.routing_table();
let detect_address_changes = {
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 network_class == NetworkClass::Invalid {
let rth = routing_table.get_routing_table_health();
if detect_address_changes {
let network_class = self.get_network_class().unwrap_or(NetworkClass::Invalid);
if network_class == NetworkClass::Invalid {
let routing_table = self.routing_table();
let rth = routing_table.get_routing_table_health();
// Need at least two entries to do this
if rth.unreliable_entry_count + rth.reliable_entry_count >= 2 {
self.unlocked_inner.update_network_class_task.tick().await?;
// Need at least two entries to do this
if rth.unreliable_entry_count + rth.reliable_entry_count >= 2 {
self.unlocked_inner.update_network_class_task.tick().await?;
}
}
}
// If we aren't resetting the network already,
// check our network interfaces to see if they have changed
if !self.needs_restart() {
self.unlocked_inner.network_interfaces_task.tick().await?;
// If we aren't resetting the network already,
// check our network interfaces to see if they have changed
if !self.needs_restart() {
self.unlocked_inner.network_interfaces_task.tick().await?;
}
}
Ok(())

View File

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

View File

@ -253,12 +253,13 @@ impl Network {
pub(super) async fn start_udp_listeners(&self) -> EyreResult<()> {
trace!("starting udp listeners");
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();
(
c.network.protocol.udp.listen_address.clone(),
c.network.protocol.udp.public_address.clone(),
c.network.enable_local_peer_scope,
c.network.detect_address_changes,
)
};
@ -289,7 +290,10 @@ impl Network {
for di in &local_dial_info_list {
// If the local interface address is global, or we are enabling local peer scope
// 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(
RoutingDomain::PublicInternet,
di.clone(),
@ -318,11 +322,14 @@ impl Network {
let pdi = DialInfo::udp_from_socketaddr(pdi_addr);
// Register the public address
routing_table.register_dial_info(
RoutingDomain::PublicInternet,
pdi.clone(),
DialInfoClass::Direct,
)?;
if !detect_address_changes {
routing_table.register_dial_info(
RoutingDomain::PublicInternet,
pdi.clone(),
DialInfoClass::Direct,
)?;
static_public = true;
}
// 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| {
@ -340,8 +347,6 @@ impl Network {
DialInfoClass::Direct,
)?;
}
static_public = true;
}
}
@ -359,13 +364,14 @@ impl Network {
pub(super) async fn start_ws_listeners(&self) -> EyreResult<()> {
trace!("starting ws listeners");
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();
(
c.network.protocol.ws.listen_address.clone(),
c.network.protocol.ws.url.clone(),
c.network.protocol.ws.path.clone(),
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())
.wrap_err("try_ws failed")?;
routing_table.register_dial_info(
RoutingDomain::PublicInternet,
pdi.clone(),
DialInfoClass::Direct,
)?;
static_public = true;
if !detect_address_changes {
routing_table.register_dial_info(
RoutingDomain::PublicInternet,
pdi.clone(),
DialInfoClass::Direct,
)?;
static_public = true;
}
// See if this public address is also a local interface address
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_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
routing_table.register_dial_info(
RoutingDomain::PublicInternet,
@ -482,11 +493,12 @@ impl Network {
trace!("starting wss listeners");
let routing_table = self.routing_table();
let (listen_address, url) = {
let (listen_address, url, detect_address_changes) = {
let c = self.config.get();
(
c.network.protocol.wss.listen_address.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())
.wrap_err("try_wss failed")?;
routing_table.register_dial_info(
RoutingDomain::PublicInternet,
pdi.clone(),
DialInfoClass::Direct,
)?;
static_public = true;
if !detect_address_changes {
routing_table.register_dial_info(
RoutingDomain::PublicInternet,
pdi.clone(),
DialInfoClass::Direct,
)?;
static_public = true;
}
// See if this public address is also a local interface address
let is_interface_address = self.with_interface_addresses(|ip_addrs| {
@ -583,12 +597,13 @@ impl Network {
trace!("starting tcp listeners");
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();
(
c.network.protocol.tcp.listen_address.clone(),
c.network.protocol.tcp.public_address.clone(),
c.network.enable_local_peer_scope,
c.network.detect_address_changes,
)
};
@ -622,7 +637,10 @@ impl Network {
let di = DialInfo::tcp(socket_address);
// 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(
RoutingDomain::PublicInternet,
di.clone(),
@ -654,12 +672,14 @@ impl Network {
}
let pdi = DialInfo::tcp_from_socketaddr(pdi_addr);
routing_table.register_dial_info(
RoutingDomain::PublicInternet,
pdi.clone(),
DialInfoClass::Direct,
)?;
static_public = true;
if !detect_address_changes {
routing_table.register_dial_info(
RoutingDomain::PublicInternet,
pdi.clone(),
DialInfoClass::Direct,
)?;
static_public = true;
}
// See if this public address is also a local interface address
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.upnp" => 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.restricted_nat_retries" => Ok(Box::new(3u32)),
"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.natpmp, false);
assert_eq!(inner.network.detect_address_changes, true);
assert_eq!(inner.network.enable_local_peer_scope, false);
assert_eq!(inner.network.restricted_nat_retries, 3u32);
assert_eq!(inner.network.tls.certificate_path, get_certfile_path());

View File

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

View File

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

View File

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

View File

@ -98,6 +98,7 @@ core:
validate_dial_info_receipt_time_ms: 2000
upnp: false
natpmp: false
detect_address_changes: true
enable_local_peer_scope: false
restricted_nat_retries: 0
tls:
@ -587,6 +588,7 @@ pub struct Network {
pub dht: Dht,
pub upnp: bool,
pub natpmp: bool,
pub detect_address_changes: bool,
pub enable_local_peer_scope: bool,
pub restricted_nat_retries: u32,
pub tls: Tls,
@ -973,6 +975,7 @@ impl Settings {
);
set_config_value!(inner.core.network.upnp, 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.restricted_nat_retries, 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.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" => {
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.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.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.upnp": return false;
case "network.natpmp": return false;
case "network.detect_address_changes": return true;
case "network.address_filter": return true;
case "network.restricted_nat_retries": return 3;
case "network.tls.certificate_path": return "";