mod network_interfaces_task;
mod update_dial_info;
mod upnp_task;
use super::*;
impl Network {
pub fn setup_tasks(&self) {
let this = self.clone();
self.update_dial_info_task.set_routine(move |s, l, t| {
let this = this.clone();
Box::pin(async move {
this.update_dial_info_task_routine(s, Timestamp::new(l), Timestamp::new(t))
.await
})
});
let this = self.clone();
self.network_interfaces_task.set_routine(move |s, l, t| {
let this = this.clone();
Box::pin(async move {
this.network_interfaces_task_routine(s, Timestamp::new(l), Timestamp::new(t))
.await
})
});
{
let this = self.clone();
self.upnp_task.set_routine(move |s, l, t| {
let this = this.clone();
Box::pin(async move {
this.upnp_task_routine(s, Timestamp::new(l), Timestamp::new(t))
.await
})
});
}
}
fn wants_update_dial_info_tick(&self) -> bool {
let routing_table = self.routing_table();
let (routing_domain_inbound_stage, current_peer_info, entry_summary) = {
let rdc = routing_table.get_routing_domain_controller(RoutingDomain::PublicInternet);
let state = rdc.state();
let rdd = rdc.read();
(
state.inbound_stage,
rdd.get_peer_info(),
rdd.get_entry_summary(),
)
};
let (state_wants_dial_info, state_is_publishable) = match routing_domain_inbound_stage {
RoutingDomainInboundStage::Invalid | RoutingDomainInboundStage::Unusable => {
return false;
}
RoutingDomainInboundStage::NeedsDialInfoConfirmation => {
(true, false)
}
RoutingDomainInboundStage::NeedsRelays | RoutingDomainInboundStage::ReadyToPublish => {
(false, true)
}
};
let needs_update_dial_info = self.needs_update_dial_info();
if needs_update_dial_info
|| state_wants_dial_info
|| (state_is_publishable
&& !current_peer_info.node_info().has_dial_info()
&& self.inner.lock().next_outbound_only_dial_info_check <= Timestamp::now())
{
let mut has_enough_nodes = true;
for ck in VALID_CRYPTO_KINDS {
if entry_summary
.per_crypto_kind
.get(&ck)
.map(|cc| cc.live.connectivity_capabilities)
.unwrap_or_default()
< EXTERNAL_INFO_VALIDATIONS
{
has_enough_nodes = false;
break;
}
}
has_enough_nodes
} else {
false
}
}
#[cfg_attr(
feature = "instrument",
instrument(level = "trace", target = "net", name = "Network::tick", skip_all, err, fields(__VEILID_LOG_KEY = self.log_key()))
)]
pub async fn tick(&self) -> EyreResult<()> {
let Ok(_guard) = self.startup_lock.enter() else {
veilid_log!(self debug "ignoring 'Network::tick' due to not started up");
return Ok(());
};
if self.needs_restart() {
return Ok(());
}
let (upnp, require_inbound_relay) = {
let config = self.config();
(
config.network.upnp,
config.network.privacy.require_inbound_relay,
)
};
if require_inbound_relay {
return Ok(());
}
if self.resolved_detect_address_changes() {
self.network_interfaces_task.tick().await?;
if self.wants_update_dial_info_tick() {
self.update_dial_info_task.tick().await?;
}
}
if upnp {
self.upnp_task.tick().await?;
}
Ok(())
}
pub async fn cancel_tasks(&self) {
veilid_log!(self debug "stopping upnp task");
if let Err(e) = self.upnp_task.stop().await {
veilid_log!(self warn "upnp_task not stopped: {}", e);
}
veilid_log!(self debug "stopping network interfaces task");
if let Err(e) = self.network_interfaces_task.stop().await {
veilid_log!(self warn "network_interfaces_task not stopped: {}", e);
}
veilid_log!(self debug "stopping update network class task");
if let Err(e) = self.update_dial_info_task.stop().await {
veilid_log!(self warn "update_dial_info_task not stopped: {}", e);
}
}
}