xfer
This commit is contained in:
parent
39ddb6534a
commit
4e8c1d5b4a
@ -45,6 +45,7 @@ pub const PUBLIC_ADDRESS_CHANGE_DETECTION_COUNT: usize = 3;
|
|||||||
pub const PUBLIC_ADDRESS_CHECK_CACHE_SIZE: usize = 8;
|
pub const PUBLIC_ADDRESS_CHECK_CACHE_SIZE: usize = 8;
|
||||||
pub const PUBLIC_ADDRESS_CHECK_TASK_INTERVAL_SECS: u32 = 60;
|
pub const PUBLIC_ADDRESS_CHECK_TASK_INTERVAL_SECS: u32 = 60;
|
||||||
pub const PUBLIC_ADDRESS_INCONSISTENCY_TIMEOUT_US: u64 = 300_000_000u64; // 5 minutes
|
pub const PUBLIC_ADDRESS_INCONSISTENCY_TIMEOUT_US: u64 = 300_000_000u64; // 5 minutes
|
||||||
|
pub const PUBLIC_ADDRESS_INCONSISTENCY_PUNISHMENT_TIMEOUT_US: u64 = 3600_000_000u64; // 60 minutes
|
||||||
pub const BOOT_MAGIC: &[u8; 4] = b"BOOT";
|
pub const BOOT_MAGIC: &[u8; 4] = b"BOOT";
|
||||||
pub const BOOTSTRAP_TXT_VERSION: u8 = 0;
|
pub const BOOTSTRAP_TXT_VERSION: u8 = 0;
|
||||||
|
|
||||||
@ -1702,6 +1703,9 @@ impl NetworkManager {
|
|||||||
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
|
||||||
|
let mut bad_public_address_detection_punishment: Option<
|
||||||
|
Box<dyn FnOnce() + Send + 'static>,
|
||||||
|
> = None;
|
||||||
let needs_public_address_detection =
|
let needs_public_address_detection =
|
||||||
if matches!(network_class, NetworkClass::InboundCapable) {
|
if matches!(network_class, NetworkClass::InboundCapable) {
|
||||||
// Get the dial info filter for this connection so we can check if we have any public dialinfo that may have changed
|
// Get the dial info filter for this connection so we can check if we have any public dialinfo that may have changed
|
||||||
@ -1721,7 +1725,6 @@ impl NetworkManager {
|
|||||||
// then we zap the network class and re-detect it
|
// then we zap the network class and re-detect it
|
||||||
let inner = &mut *self.inner.lock();
|
let inner = &mut *self.inner.lock();
|
||||||
let mut inconsistencies = Vec::new();
|
let mut inconsistencies = Vec::new();
|
||||||
let mut inconsistent = false;
|
|
||||||
// Iteration goes from most recent to least recent node/address pair
|
// Iteration goes from most recent to least recent node/address pair
|
||||||
let pacc = inner
|
let pacc = inner
|
||||||
.public_address_check_cache
|
.public_address_check_cache
|
||||||
@ -1737,24 +1740,41 @@ impl NetworkManager {
|
|||||||
if !current_addresses.contains(a) && !pait.contains_key(reporting_ip_block) {
|
if !current_addresses.contains(a) && !pait.contains_key(reporting_ip_block) {
|
||||||
// Record the origin of the inconsistency
|
// Record the origin of the inconsistency
|
||||||
inconsistencies.push(*reporting_ip_block);
|
inconsistencies.push(*reporting_ip_block);
|
||||||
|
|
||||||
// If we have enough inconsistencies to consider changing our public dial info,
|
|
||||||
// add them to our denylist (throttling) and go ahead and check for new
|
|
||||||
// public dialinfo
|
|
||||||
if inconsistencies.len() >= PUBLIC_ADDRESS_CHANGE_DETECTION_COUNT {
|
|
||||||
let exp_ts =
|
|
||||||
intf::get_timestamp() + PUBLIC_ADDRESS_INCONSISTENCY_TIMEOUT_US;
|
|
||||||
for i in inconsistencies {
|
|
||||||
pait.insert(i, exp_ts);
|
|
||||||
}
|
|
||||||
|
|
||||||
inconsistent = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have enough inconsistencies to consider changing our public dial info,
|
||||||
|
// add them to our denylist (throttling) and go ahead and check for new
|
||||||
|
// public dialinfo
|
||||||
|
let inconsistent = if inconsistencies.len() >= PUBLIC_ADDRESS_CHANGE_DETECTION_COUNT
|
||||||
|
{
|
||||||
|
let exp_ts = intf::get_timestamp() + PUBLIC_ADDRESS_INCONSISTENCY_TIMEOUT_US;
|
||||||
|
for i in &inconsistencies {
|
||||||
|
pait.insert(*i, exp_ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run this routine if the inconsistent nodes turn out to be lying
|
||||||
|
let this = self.clone();
|
||||||
|
bad_public_address_detection_punishment = Some(Box::new(move || {
|
||||||
|
let mut inner = this.inner.lock();
|
||||||
|
let pait = inner
|
||||||
|
.public_address_inconsistencies_table
|
||||||
|
.entry(key)
|
||||||
|
.or_insert_with(|| HashMap::new());
|
||||||
|
let exp_ts = intf::get_timestamp()
|
||||||
|
+ PUBLIC_ADDRESS_INCONSISTENCY_PUNISHMENT_TIMEOUT_US;
|
||||||
|
for i in inconsistencies {
|
||||||
|
pait.insert(i, exp_ts);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
// // debug code
|
// // debug code
|
||||||
// if changed {
|
// if inconsistent {
|
||||||
// trace!("public_address_check_cache: {:#?}\ncurrent_addresses: {:#?}\ninconsistencies: {}", inner
|
// trace!("public_address_check_cache: {:#?}\ncurrent_addresses: {:#?}\ninconsistencies: {}", inner
|
||||||
// .public_address_check_cache, current_addresses, inconsistencies);
|
// .public_address_check_cache, current_addresses, inconsistencies);
|
||||||
// }
|
// }
|
||||||
@ -1799,9 +1819,8 @@ impl NetworkManager {
|
|||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
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
|
// Re-detect the public dialinfo
|
||||||
routing_table.clear_dial_info_details(RoutingDomain::PublicInternet);
|
net.set_needs_public_dial_info_check(bad_public_address_detection_punishment);
|
||||||
net.reset_network_class();
|
|
||||||
} else {
|
} else {
|
||||||
let inner = self.inner.lock();
|
let inner = self.inner.lock();
|
||||||
warn!("Public address may have changed. Restarting the server may be required.");
|
warn!("Public address may have changed. Restarting the server may be required.");
|
||||||
|
@ -48,6 +48,10 @@ struct NetworkInner {
|
|||||||
enable_ipv4: bool,
|
enable_ipv4: bool,
|
||||||
enable_ipv6_global: bool,
|
enable_ipv6_global: bool,
|
||||||
enable_ipv6_local: bool,
|
enable_ipv6_local: bool,
|
||||||
|
// public dial info check
|
||||||
|
needs_public_dial_info_check: bool,
|
||||||
|
doing_public_dial_info_check: bool,
|
||||||
|
public_dial_info_check_punishment: Option<Box<dyn FnOnce() + Send + 'static>>,
|
||||||
// udp
|
// udp
|
||||||
bound_first_udp: BTreeMap<u16, Option<(socket2::Socket, socket2::Socket)>>,
|
bound_first_udp: BTreeMap<u16, Option<(socket2::Socket, socket2::Socket)>>,
|
||||||
inbound_udp_protocol_handlers: BTreeMap<SocketAddr, RawUdpProtocolHandler>,
|
inbound_udp_protocol_handlers: BTreeMap<SocketAddr, RawUdpProtocolHandler>,
|
||||||
@ -89,6 +93,9 @@ impl Network {
|
|||||||
NetworkInner {
|
NetworkInner {
|
||||||
network_started: false,
|
network_started: false,
|
||||||
network_needs_restart: false,
|
network_needs_restart: false,
|
||||||
|
needs_public_dial_info_check: false,
|
||||||
|
doing_public_dial_info_check: false,
|
||||||
|
public_dial_info_check_punishment: None,
|
||||||
protocol_config: None,
|
protocol_config: None,
|
||||||
static_public_dialinfo: ProtocolTypeSet::empty(),
|
static_public_dialinfo: ProtocolTypeSet::empty(),
|
||||||
network_class: None,
|
network_class: None,
|
||||||
@ -770,17 +777,30 @@ impl Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
|
pub fn set_needs_public_dial_info_check(
|
||||||
|
&self,
|
||||||
|
punishment: Option<Box<dyn FnOnce() + Send + 'static>>,
|
||||||
|
) {
|
||||||
|
let mut inner = self.inner.lock();
|
||||||
|
inner.needs_public_dial_info_check = true;
|
||||||
|
inner.public_dial_info_check_punishment = punishment;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn needs_public_dial_info_check(&self) -> bool {
|
||||||
|
let inner = self.inner.lock();
|
||||||
|
inner.needs_public_dial_info_check
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn doing_public_dial_info_check(&self) -> bool {
|
||||||
|
let inner = self.inner.lock();
|
||||||
|
inner.doing_public_dial_info_check
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_network_class(&self) -> Option<NetworkClass> {
|
pub fn get_network_class(&self) -> Option<NetworkClass> {
|
||||||
let inner = self.inner.lock();
|
let inner = self.inner.lock();
|
||||||
inner.network_class
|
inner.network_class
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip_all)]
|
|
||||||
pub fn reset_network_class(&self) {
|
|
||||||
let mut inner = self.inner.lock();
|
|
||||||
inner.network_class = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(self), err)]
|
#[instrument(level = "trace", skip(self), err)]
|
||||||
@ -842,7 +862,8 @@ impl Network {
|
|||||||
// 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 {
|
if detect_address_changes {
|
||||||
let network_class = self.get_network_class().unwrap_or(NetworkClass::Invalid);
|
let network_class = self.get_network_class().unwrap_or(NetworkClass::Invalid);
|
||||||
if network_class == NetworkClass::Invalid {
|
let needs_public_dial_info_check = self.needs_public_dial_info_check();
|
||||||
|
if network_class == NetworkClass::Invalid || needs_public_dial_info_check {
|
||||||
let routing_table = self.routing_table();
|
let routing_table = self.routing_table();
|
||||||
let rth = routing_table.get_routing_table_health();
|
let rth = routing_table.get_routing_table_health();
|
||||||
|
|
||||||
|
@ -605,16 +605,13 @@ impl Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(self), err)]
|
#[instrument(level = "trace", skip(self), err)]
|
||||||
pub async fn update_network_class_task_routine(
|
pub async fn do_public_dial_info_check(
|
||||||
self,
|
&self,
|
||||||
stop_token: StopToken,
|
stop_token: StopToken,
|
||||||
_l: u64,
|
_l: u64,
|
||||||
_t: u64,
|
_t: u64,
|
||||||
) -> EyreResult<()> {
|
) -> EyreResult<()> {
|
||||||
// Ensure we aren't trying to update this without clearing it first
|
// Figure out if we can optimize TCP/WS checking since they are often on the same port
|
||||||
let old_network_class = self.inner.lock().network_class;
|
|
||||||
assert_eq!(old_network_class, None);
|
|
||||||
|
|
||||||
let protocol_config = self.inner.lock().protocol_config.unwrap_or_default();
|
let protocol_config = self.inner.lock().protocol_config.unwrap_or_default();
|
||||||
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)
|
||||||
@ -823,6 +820,26 @@ impl Network {
|
|||||||
network_manager.send_node_info_updates(true).await;
|
network_manager.send_node_info_updates(true).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !changed {}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
#[instrument(level = "trace", skip(self), err)]
|
||||||
|
pub async fn update_network_class_task_routine(
|
||||||
|
self,
|
||||||
|
stop_token: StopToken,
|
||||||
|
l: u64,
|
||||||
|
t: u64,
|
||||||
|
) -> EyreResult<()> {
|
||||||
|
// Note that we are doing the public dial info check
|
||||||
|
self.inner.lock().doing_public_dial_info_check = true;
|
||||||
|
|
||||||
|
// Do the public dial info check
|
||||||
|
let out = self.do_public_dial_info_check(stop_token, l, t);
|
||||||
|
|
||||||
|
// Done with public dial info check
|
||||||
|
self.inner.lock().doing_public_dial_info_check = false;
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,6 +291,11 @@ impl Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
|
|
||||||
|
pub fn set_needs_public_dial_info_check(&self) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_network_class(&self) -> Option<NetworkClass> {
|
pub fn get_network_class(&self) -> Option<NetworkClass> {
|
||||||
// xxx eventually detect tor browser?
|
// xxx eventually detect tor browser?
|
||||||
return if self.inner.lock().network_started {
|
return if self.inner.lock().network_started {
|
||||||
@ -300,11 +305,6 @@ impl Network {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset_network_class(&self) {
|
|
||||||
//let mut inner = self.inner.lock();
|
|
||||||
//inner.network_class = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_protocol_config(&self) -> Option<ProtocolConfig> {
|
pub fn get_protocol_config(&self) -> Option<ProtocolConfig> {
|
||||||
self.inner.lock().protocol_config.clone()
|
self.inner.lock().protocol_config.clone()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user