keep network from going down when external ip addresses haven't changed
This commit is contained in:
parent
084d4ae98b
commit
54c403ebfb
veilid-core/src/network_manager/native
@ -39,8 +39,11 @@ struct DiscoveryContextInner {
|
||||
struct DiscoveryContextUnlockedInner {
|
||||
routing_table: RoutingTable,
|
||||
net: Network,
|
||||
clear_network_callback: ClearNetworkCallback,
|
||||
|
||||
// per-protocol
|
||||
intf_addrs: Vec<SocketAddress>,
|
||||
existing_external_address: Option<SocketAddress>,
|
||||
protocol_type: ProtocolType,
|
||||
address_type: AddressType,
|
||||
}
|
||||
@ -51,21 +54,45 @@ pub struct DiscoveryContext {
|
||||
inner: Arc<Mutex<DiscoveryContextInner>>,
|
||||
}
|
||||
|
||||
pub type ClearNetworkCallback = Arc<dyn Fn() -> SendPinBoxFuture<()> + Send + Sync>;
|
||||
|
||||
impl DiscoveryContext {
|
||||
pub fn new(
|
||||
routing_table: RoutingTable,
|
||||
net: Network,
|
||||
protocol_type: ProtocolType,
|
||||
address_type: AddressType,
|
||||
clear_network_callback: ClearNetworkCallback,
|
||||
) -> Self {
|
||||
let intf_addrs =
|
||||
Self::get_local_addresses(routing_table.clone(), protocol_type, address_type);
|
||||
|
||||
// Get the existing external address to check to see if it has changed
|
||||
let existing_dial_info = routing_table.all_filtered_dial_info_details(
|
||||
RoutingDomain::PublicInternet.into(),
|
||||
&DialInfoFilter::default()
|
||||
.with_address_type(address_type)
|
||||
.with_protocol_type(protocol_type),
|
||||
);
|
||||
let existing_external_address = if existing_dial_info.len() == 1 {
|
||||
Some(
|
||||
existing_dial_info
|
||||
.first()
|
||||
.unwrap()
|
||||
.dial_info
|
||||
.socket_address(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Self {
|
||||
unlocked_inner: Arc::new(DiscoveryContextUnlockedInner {
|
||||
routing_table,
|
||||
net,
|
||||
clear_network_callback,
|
||||
intf_addrs,
|
||||
existing_external_address,
|
||||
protocol_type,
|
||||
address_type,
|
||||
}),
|
||||
@ -631,6 +658,22 @@ impl DiscoveryContext {
|
||||
return;
|
||||
}
|
||||
|
||||
// Did external addresses change from the last time we made dialinfo?
|
||||
let some_clear_network_callback = {
|
||||
let inner = self.inner.lock();
|
||||
let ext_1 = inner.external_1.as_ref().unwrap().address;
|
||||
let ext_2 = inner.external_2.as_ref().unwrap().address;
|
||||
if (ext_1 != ext_2) || Some(ext_1) != self.unlocked_inner.existing_external_address {
|
||||
// External address was not found, or has changed, go ahead and clear the network so we can do better
|
||||
Some(self.unlocked_inner.clear_network_callback.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
if let Some(clear_network_callback) = some_clear_network_callback {
|
||||
clear_network_callback().await;
|
||||
}
|
||||
|
||||
// UPNP Automatic Mapping
|
||||
///////////
|
||||
if enable_upnp {
|
||||
|
@ -99,6 +99,8 @@ struct NetworkInner {
|
||||
enable_ipv6_local: bool,
|
||||
/// set if we need to calculate our public dial info again
|
||||
needs_public_dial_info_check: bool,
|
||||
/// set if we have yet to clear the network during public dial info checking
|
||||
network_already_cleared: bool,
|
||||
/// the punishment closure to enax
|
||||
public_dial_info_check_punishment: Option<Box<dyn FnOnce() + Send + 'static>>,
|
||||
/// udp socket record for bound-first sockets, which are used to guarantee a port is available before
|
||||
@ -148,6 +150,7 @@ impl Network {
|
||||
network_started: false,
|
||||
network_needs_restart: false,
|
||||
needs_public_dial_info_check: false,
|
||||
network_already_cleared: false,
|
||||
public_dial_info_check_punishment: None,
|
||||
protocol_config: Default::default(),
|
||||
static_public_dialinfo: ProtocolTypeSet::empty(),
|
||||
|
@ -22,7 +22,6 @@ impl Network {
|
||||
|
||||
editor.clear_dial_info_details(None, None);
|
||||
editor.set_network_class(Some(NetworkClass::OutboundOnly));
|
||||
editor.clear_relay_node();
|
||||
editor.commit(true).await;
|
||||
}
|
||||
}
|
||||
@ -103,7 +102,7 @@ impl Network {
|
||||
) -> EyreResult<()> {
|
||||
// Figure out if we can optimize TCP/WS checking since they are often on the same port
|
||||
let (protocol_config, tcp_same_port) = {
|
||||
let inner = self.inner.lock();
|
||||
let mut inner = self.inner.lock();
|
||||
let protocol_config = inner.protocol_config.clone();
|
||||
let tcp_same_port = if protocol_config.inbound.contains(ProtocolType::TCP)
|
||||
&& protocol_config.inbound.contains(ProtocolType::WS)
|
||||
@ -112,6 +111,10 @@ impl Network {
|
||||
} else {
|
||||
false
|
||||
};
|
||||
// Allow network to be cleared if external addresses change
|
||||
inner.network_already_cleared = false;
|
||||
|
||||
//
|
||||
(protocol_config, tcp_same_port)
|
||||
};
|
||||
|
||||
@ -125,8 +128,7 @@ impl Network {
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
// Clear public dialinfo and network class in prep for discovery
|
||||
|
||||
// Set most permissive network config
|
||||
let mut editor = self
|
||||
.routing_table()
|
||||
.edit_routing_domain(RoutingDomain::PublicInternet);
|
||||
@ -136,11 +138,30 @@ impl Network {
|
||||
protocol_config.family_global,
|
||||
protocol_config.public_internet_capabilities.clone(),
|
||||
);
|
||||
editor.clear_dial_info_details(None, None);
|
||||
editor.set_network_class(None);
|
||||
editor.clear_relay_node();
|
||||
editor.commit(true).await;
|
||||
|
||||
// Create a callback to clear the network if we need to 'start over'
|
||||
let this = self.clone();
|
||||
let clear_network_callback: ClearNetworkCallback = Arc::new(move || {
|
||||
let this = this.clone();
|
||||
Box::pin(async move {
|
||||
// Ensure we only do this once per network class discovery
|
||||
{
|
||||
let mut inner = this.inner.lock();
|
||||
if inner.network_already_cleared {
|
||||
return;
|
||||
}
|
||||
inner.network_already_cleared = true;
|
||||
}
|
||||
let mut editor = this
|
||||
.routing_table()
|
||||
.edit_routing_domain(RoutingDomain::PublicInternet);
|
||||
editor.clear_dial_info_details(None, None);
|
||||
editor.set_network_class(None);
|
||||
editor.commit(true).await;
|
||||
})
|
||||
});
|
||||
|
||||
// Process all protocol and address combinations
|
||||
let mut unord = FuturesUnordered::new();
|
||||
// Do UDPv4+v6 at the same time as everything else
|
||||
@ -152,6 +173,7 @@ impl Network {
|
||||
self.clone(),
|
||||
ProtocolType::UDP,
|
||||
AddressType::IPV4,
|
||||
clear_network_callback.clone(),
|
||||
);
|
||||
udpv4_context
|
||||
.discover(&mut unord)
|
||||
@ -166,6 +188,7 @@ impl Network {
|
||||
self.clone(),
|
||||
ProtocolType::UDP,
|
||||
AddressType::IPV6,
|
||||
clear_network_callback.clone(),
|
||||
);
|
||||
udpv6_context
|
||||
.discover(&mut unord)
|
||||
@ -182,6 +205,7 @@ impl Network {
|
||||
self.clone(),
|
||||
ProtocolType::TCP,
|
||||
AddressType::IPV4,
|
||||
clear_network_callback.clone(),
|
||||
);
|
||||
tcpv4_context
|
||||
.discover(&mut unord)
|
||||
@ -195,6 +219,7 @@ impl Network {
|
||||
self.clone(),
|
||||
ProtocolType::WS,
|
||||
AddressType::IPV4,
|
||||
clear_network_callback.clone(),
|
||||
);
|
||||
wsv4_context
|
||||
.discover(&mut unord)
|
||||
@ -211,6 +236,7 @@ impl Network {
|
||||
self.clone(),
|
||||
ProtocolType::TCP,
|
||||
AddressType::IPV6,
|
||||
clear_network_callback.clone(),
|
||||
);
|
||||
tcpv6_context
|
||||
.discover(&mut unord)
|
||||
@ -225,6 +251,7 @@ impl Network {
|
||||
self.clone(),
|
||||
ProtocolType::WS,
|
||||
AddressType::IPV6,
|
||||
clear_network_callback.clone(),
|
||||
);
|
||||
wsv6_context
|
||||
.discover(&mut unord)
|
||||
|
Loading…
Reference in New Issue
Block a user