keep network from going down when external ip addresses haven't changed
This commit is contained in:
parent
084d4ae98b
commit
54c403ebfb
@ -39,8 +39,11 @@ struct DiscoveryContextInner {
|
|||||||
struct DiscoveryContextUnlockedInner {
|
struct DiscoveryContextUnlockedInner {
|
||||||
routing_table: RoutingTable,
|
routing_table: RoutingTable,
|
||||||
net: Network,
|
net: Network,
|
||||||
|
clear_network_callback: ClearNetworkCallback,
|
||||||
|
|
||||||
// per-protocol
|
// per-protocol
|
||||||
intf_addrs: Vec<SocketAddress>,
|
intf_addrs: Vec<SocketAddress>,
|
||||||
|
existing_external_address: Option<SocketAddress>,
|
||||||
protocol_type: ProtocolType,
|
protocol_type: ProtocolType,
|
||||||
address_type: AddressType,
|
address_type: AddressType,
|
||||||
}
|
}
|
||||||
@ -51,21 +54,45 @@ pub struct DiscoveryContext {
|
|||||||
inner: Arc<Mutex<DiscoveryContextInner>>,
|
inner: Arc<Mutex<DiscoveryContextInner>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type ClearNetworkCallback = Arc<dyn Fn() -> SendPinBoxFuture<()> + Send + Sync>;
|
||||||
|
|
||||||
impl DiscoveryContext {
|
impl DiscoveryContext {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
routing_table: RoutingTable,
|
routing_table: RoutingTable,
|
||||||
net: Network,
|
net: Network,
|
||||||
protocol_type: ProtocolType,
|
protocol_type: ProtocolType,
|
||||||
address_type: AddressType,
|
address_type: AddressType,
|
||||||
|
clear_network_callback: ClearNetworkCallback,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let intf_addrs =
|
let intf_addrs =
|
||||||
Self::get_local_addresses(routing_table.clone(), protocol_type, address_type);
|
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 {
|
Self {
|
||||||
unlocked_inner: Arc::new(DiscoveryContextUnlockedInner {
|
unlocked_inner: Arc::new(DiscoveryContextUnlockedInner {
|
||||||
routing_table,
|
routing_table,
|
||||||
net,
|
net,
|
||||||
|
clear_network_callback,
|
||||||
intf_addrs,
|
intf_addrs,
|
||||||
|
existing_external_address,
|
||||||
protocol_type,
|
protocol_type,
|
||||||
address_type,
|
address_type,
|
||||||
}),
|
}),
|
||||||
@ -631,6 +658,22 @@ impl DiscoveryContext {
|
|||||||
return;
|
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
|
// UPNP Automatic Mapping
|
||||||
///////////
|
///////////
|
||||||
if enable_upnp {
|
if enable_upnp {
|
||||||
|
@ -99,6 +99,8 @@ struct NetworkInner {
|
|||||||
enable_ipv6_local: bool,
|
enable_ipv6_local: bool,
|
||||||
/// set if we need to calculate our public dial info again
|
/// set if we need to calculate our public dial info again
|
||||||
needs_public_dial_info_check: bool,
|
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
|
/// the punishment closure to enax
|
||||||
public_dial_info_check_punishment: Option<Box<dyn FnOnce() + Send + 'static>>,
|
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
|
/// 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_started: false,
|
||||||
network_needs_restart: false,
|
network_needs_restart: false,
|
||||||
needs_public_dial_info_check: false,
|
needs_public_dial_info_check: false,
|
||||||
|
network_already_cleared: false,
|
||||||
public_dial_info_check_punishment: None,
|
public_dial_info_check_punishment: None,
|
||||||
protocol_config: Default::default(),
|
protocol_config: Default::default(),
|
||||||
static_public_dialinfo: ProtocolTypeSet::empty(),
|
static_public_dialinfo: ProtocolTypeSet::empty(),
|
||||||
|
@ -22,7 +22,6 @@ impl Network {
|
|||||||
|
|
||||||
editor.clear_dial_info_details(None, None);
|
editor.clear_dial_info_details(None, None);
|
||||||
editor.set_network_class(Some(NetworkClass::OutboundOnly));
|
editor.set_network_class(Some(NetworkClass::OutboundOnly));
|
||||||
editor.clear_relay_node();
|
|
||||||
editor.commit(true).await;
|
editor.commit(true).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,7 +102,7 @@ impl Network {
|
|||||||
) -> EyreResult<()> {
|
) -> EyreResult<()> {
|
||||||
// Figure out if we can optimize TCP/WS checking since they are often on the same port
|
// Figure out if we can optimize TCP/WS checking since they are often on the same port
|
||||||
let (protocol_config, tcp_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 protocol_config = inner.protocol_config.clone();
|
||||||
let tcp_same_port = if protocol_config.inbound.contains(ProtocolType::TCP)
|
let tcp_same_port = if protocol_config.inbound.contains(ProtocolType::TCP)
|
||||||
&& protocol_config.inbound.contains(ProtocolType::WS)
|
&& protocol_config.inbound.contains(ProtocolType::WS)
|
||||||
@ -112,6 +111,10 @@ impl Network {
|
|||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
// Allow network to be cleared if external addresses change
|
||||||
|
inner.network_already_cleared = false;
|
||||||
|
|
||||||
|
//
|
||||||
(protocol_config, tcp_same_port)
|
(protocol_config, tcp_same_port)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -125,8 +128,7 @@ impl Network {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Clear public dialinfo and network class in prep for discovery
|
// Set most permissive network config
|
||||||
|
|
||||||
let mut editor = self
|
let mut editor = self
|
||||||
.routing_table()
|
.routing_table()
|
||||||
.edit_routing_domain(RoutingDomain::PublicInternet);
|
.edit_routing_domain(RoutingDomain::PublicInternet);
|
||||||
@ -136,11 +138,30 @@ impl Network {
|
|||||||
protocol_config.family_global,
|
protocol_config.family_global,
|
||||||
protocol_config.public_internet_capabilities.clone(),
|
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;
|
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
|
// Process all protocol and address combinations
|
||||||
let mut unord = FuturesUnordered::new();
|
let mut unord = FuturesUnordered::new();
|
||||||
// Do UDPv4+v6 at the same time as everything else
|
// Do UDPv4+v6 at the same time as everything else
|
||||||
@ -152,6 +173,7 @@ impl Network {
|
|||||||
self.clone(),
|
self.clone(),
|
||||||
ProtocolType::UDP,
|
ProtocolType::UDP,
|
||||||
AddressType::IPV4,
|
AddressType::IPV4,
|
||||||
|
clear_network_callback.clone(),
|
||||||
);
|
);
|
||||||
udpv4_context
|
udpv4_context
|
||||||
.discover(&mut unord)
|
.discover(&mut unord)
|
||||||
@ -166,6 +188,7 @@ impl Network {
|
|||||||
self.clone(),
|
self.clone(),
|
||||||
ProtocolType::UDP,
|
ProtocolType::UDP,
|
||||||
AddressType::IPV6,
|
AddressType::IPV6,
|
||||||
|
clear_network_callback.clone(),
|
||||||
);
|
);
|
||||||
udpv6_context
|
udpv6_context
|
||||||
.discover(&mut unord)
|
.discover(&mut unord)
|
||||||
@ -182,6 +205,7 @@ impl Network {
|
|||||||
self.clone(),
|
self.clone(),
|
||||||
ProtocolType::TCP,
|
ProtocolType::TCP,
|
||||||
AddressType::IPV4,
|
AddressType::IPV4,
|
||||||
|
clear_network_callback.clone(),
|
||||||
);
|
);
|
||||||
tcpv4_context
|
tcpv4_context
|
||||||
.discover(&mut unord)
|
.discover(&mut unord)
|
||||||
@ -195,6 +219,7 @@ impl Network {
|
|||||||
self.clone(),
|
self.clone(),
|
||||||
ProtocolType::WS,
|
ProtocolType::WS,
|
||||||
AddressType::IPV4,
|
AddressType::IPV4,
|
||||||
|
clear_network_callback.clone(),
|
||||||
);
|
);
|
||||||
wsv4_context
|
wsv4_context
|
||||||
.discover(&mut unord)
|
.discover(&mut unord)
|
||||||
@ -211,6 +236,7 @@ impl Network {
|
|||||||
self.clone(),
|
self.clone(),
|
||||||
ProtocolType::TCP,
|
ProtocolType::TCP,
|
||||||
AddressType::IPV6,
|
AddressType::IPV6,
|
||||||
|
clear_network_callback.clone(),
|
||||||
);
|
);
|
||||||
tcpv6_context
|
tcpv6_context
|
||||||
.discover(&mut unord)
|
.discover(&mut unord)
|
||||||
@ -225,6 +251,7 @@ impl Network {
|
|||||||
self.clone(),
|
self.clone(),
|
||||||
ProtocolType::WS,
|
ProtocolType::WS,
|
||||||
AddressType::IPV6,
|
AddressType::IPV6,
|
||||||
|
clear_network_callback.clone(),
|
||||||
);
|
);
|
||||||
wsv6_context
|
wsv6_context
|
||||||
.discover(&mut unord)
|
.discover(&mut unord)
|
||||||
|
Loading…
Reference in New Issue
Block a user