xfer
This commit is contained in:
		| @@ -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_TASK_INTERVAL_SECS: u32 = 60; | ||||
| 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 BOOTSTRAP_TXT_VERSION: u8 = 0; | ||||
|  | ||||
| @@ -1702,6 +1703,9 @@ impl NetworkManager { | ||||
|         let network_class = net.get_network_class().unwrap_or(NetworkClass::Invalid); | ||||
|  | ||||
|         // 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 = | ||||
|             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 | ||||
| @@ -1721,7 +1725,6 @@ impl NetworkManager { | ||||
|                 // then we zap the network class and re-detect it | ||||
|                 let inner = &mut *self.inner.lock(); | ||||
|                 let mut inconsistencies = Vec::new(); | ||||
|                 let mut inconsistent = false; | ||||
|                 // Iteration goes from most recent to least recent node/address pair | ||||
|                 let pacc = inner | ||||
|                     .public_address_check_cache | ||||
| @@ -1737,24 +1740,41 @@ impl NetworkManager { | ||||
|                     if !current_addresses.contains(a) && !pait.contains_key(reporting_ip_block) { | ||||
|                         // Record the origin of the inconsistency | ||||
|                         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 | ||||
|                 // if changed { | ||||
|                 // if inconsistent { | ||||
|                 //     trace!("public_address_check_cache: {:#?}\ncurrent_addresses: {:#?}\ninconsistencies: {}", inner | ||||
|                 //                 .public_address_check_cache, current_addresses, inconsistencies); | ||||
|                 // } | ||||
| @@ -1799,9 +1819,8 @@ impl NetworkManager { | ||||
|                 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(); | ||||
|                 // Re-detect the public dialinfo | ||||
|                 net.set_needs_public_dial_info_check(bad_public_address_detection_punishment); | ||||
|             } else { | ||||
|                 let inner = self.inner.lock(); | ||||
|                 warn!("Public address may have changed. Restarting the server may be required."); | ||||
|   | ||||
| @@ -48,6 +48,10 @@ struct NetworkInner { | ||||
|     enable_ipv4: bool, | ||||
|     enable_ipv6_global: 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 | ||||
|     bound_first_udp: BTreeMap<u16, Option<(socket2::Socket, socket2::Socket)>>, | ||||
|     inbound_udp_protocol_handlers: BTreeMap<SocketAddr, RawUdpProtocolHandler>, | ||||
| @@ -89,6 +93,9 @@ impl Network { | ||||
|         NetworkInner { | ||||
|             network_started: 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, | ||||
|             static_public_dialinfo: ProtocolTypeSet::empty(), | ||||
|             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> { | ||||
|         let inner = self.inner.lock(); | ||||
|         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)] | ||||
| @@ -842,7 +862,8 @@ impl Network { | ||||
|         // 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 { | ||||
|             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 rth = routing_table.get_routing_table_health(); | ||||
|  | ||||
|   | ||||
| @@ -605,16 +605,13 @@ impl Network { | ||||
|     } | ||||
|  | ||||
|     #[instrument(level = "trace", skip(self), err)] | ||||
|     pub async fn update_network_class_task_routine( | ||||
|         self, | ||||
|     pub async fn do_public_dial_info_check( | ||||
|         &self, | ||||
|         stop_token: StopToken, | ||||
|         _l: u64, | ||||
|         _t: u64, | ||||
|     ) -> EyreResult<()> { | ||||
|         // Ensure we aren't trying to update this without clearing it first | ||||
|         let old_network_class = self.inner.lock().network_class; | ||||
|         assert_eq!(old_network_class, None); | ||||
|  | ||||
|         // Figure out if we can optimize TCP/WS checking since they are often on the same port | ||||
|         let protocol_config = self.inner.lock().protocol_config.unwrap_or_default(); | ||||
|         let tcp_same_port = if protocol_config.inbound.contains(ProtocolType::TCP) | ||||
|             && protocol_config.inbound.contains(ProtocolType::WS) | ||||
| @@ -823,6 +820,26 @@ impl Network { | ||||
|             network_manager.send_node_info_updates(true).await; | ||||
|         } | ||||
|  | ||||
|         if !changed {} | ||||
|  | ||||
|         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> { | ||||
|         // xxx eventually detect tor browser? | ||||
|         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> { | ||||
|         self.inner.lock().protocol_config.clone() | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user