filtering cleanup
This commit is contained in:
@@ -56,8 +56,10 @@ pub type BootstrapRecordMap = BTreeMap<DHTKey, BootstrapRecord>;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub struct ProtocolConfig {
|
||||
pub outbound: ProtocolSet,
|
||||
pub inbound: ProtocolSet,
|
||||
pub outbound: ProtocolTypeSet,
|
||||
pub inbound: ProtocolTypeSet,
|
||||
pub family_global: AddressTypeSet,
|
||||
pub family_local: AddressTypeSet,
|
||||
}
|
||||
|
||||
// Things we get when we start up and go away when we shut down
|
||||
@@ -135,6 +137,11 @@ struct NetworkManagerInner {
|
||||
client_whitelist: LruCache<DHTKey, ClientWhitelistEntry>,
|
||||
relay_node: Option<NodeRef>,
|
||||
public_address_check_cache: LruCache<DHTKey, SocketAddress>,
|
||||
protocol_config: Option<ProtocolConfig>,
|
||||
public_inbound_dial_info_filter: Option<DialInfoFilter>,
|
||||
local_inbound_dial_info_filter: Option<DialInfoFilter>,
|
||||
public_outbound_dial_info_filter: Option<DialInfoFilter>,
|
||||
local_outbound_dial_info_filter: Option<DialInfoFilter>,
|
||||
}
|
||||
|
||||
struct NetworkManagerUnlockedInner {
|
||||
@@ -166,6 +173,11 @@ impl NetworkManager {
|
||||
client_whitelist: LruCache::new_unbounded(),
|
||||
relay_node: None,
|
||||
public_address_check_cache: LruCache::new(8),
|
||||
protocol_config: None,
|
||||
public_inbound_dial_info_filter: None,
|
||||
local_inbound_dial_info_filter: None,
|
||||
public_outbound_dial_info_filter: None,
|
||||
local_outbound_dial_info_filter: None,
|
||||
}
|
||||
}
|
||||
fn new_unlocked_inner(config: VeilidConfig) -> NetworkManagerUnlockedInner {
|
||||
@@ -343,6 +355,41 @@ impl NetworkManager {
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
// Store copy of protocol config and dial info filters
|
||||
{
|
||||
let mut inner = self.inner.lock();
|
||||
let pc = inner
|
||||
.components
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.net
|
||||
.get_protocol_config()
|
||||
.unwrap();
|
||||
|
||||
inner.public_inbound_dial_info_filter = Some(
|
||||
DialInfoFilter::global()
|
||||
.with_protocol_type_set(pc.inbound)
|
||||
.with_address_type_set(pc.family_global),
|
||||
);
|
||||
inner.local_inbound_dial_info_filter = Some(
|
||||
DialInfoFilter::local()
|
||||
.with_protocol_type_set(pc.inbound)
|
||||
.with_address_type_set(pc.family_local),
|
||||
);
|
||||
inner.public_outbound_dial_info_filter = Some(
|
||||
DialInfoFilter::global()
|
||||
.with_protocol_type_set(pc.outbound)
|
||||
.with_address_type_set(pc.family_global),
|
||||
);
|
||||
inner.local_outbound_dial_info_filter = Some(
|
||||
DialInfoFilter::local()
|
||||
.with_protocol_type_set(pc.outbound)
|
||||
.with_address_type_set(pc.family_local),
|
||||
);
|
||||
|
||||
inner.protocol_config = Some(pc);
|
||||
}
|
||||
|
||||
// Inform routing table entries that our dial info has changed
|
||||
self.send_node_info_updates(true).await;
|
||||
|
||||
@@ -405,6 +452,11 @@ impl NetworkManager {
|
||||
let mut inner = self.inner.lock();
|
||||
inner.components = None;
|
||||
inner.relay_node = None;
|
||||
inner.public_inbound_dial_info_filter = None;
|
||||
inner.local_inbound_dial_info_filter = None;
|
||||
inner.public_outbound_dial_info_filter = None;
|
||||
inner.local_outbound_dial_info_filter = None;
|
||||
inner.protocol_config = None;
|
||||
}
|
||||
|
||||
// send update
|
||||
@@ -544,11 +596,42 @@ impl NetworkManager {
|
||||
}
|
||||
|
||||
// Return what protocols we have enabled
|
||||
pub fn get_protocol_config(&self) -> Option<ProtocolConfig> {
|
||||
if let Some(components) = &self.inner.lock().components {
|
||||
components.net.get_protocol_config()
|
||||
} else {
|
||||
None
|
||||
pub fn get_protocol_config(&self) -> ProtocolConfig {
|
||||
let inner = self.inner.lock();
|
||||
inner.protocol_config.as_ref().unwrap().clone()
|
||||
}
|
||||
|
||||
// Return a dial info filter for what we can receive
|
||||
pub fn get_inbound_dial_info_filter(&self, routing_domain: RoutingDomain) -> DialInfoFilter {
|
||||
let inner = self.inner.lock();
|
||||
match routing_domain {
|
||||
RoutingDomain::PublicInternet => inner
|
||||
.public_inbound_dial_info_filter
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone(),
|
||||
RoutingDomain::LocalNetwork => inner
|
||||
.local_inbound_dial_info_filter
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
// Return a dial info filter for what we can send out
|
||||
pub fn get_outbound_dial_info_filter(&self, routing_domain: RoutingDomain) -> DialInfoFilter {
|
||||
let inner = self.inner.lock();
|
||||
match routing_domain {
|
||||
RoutingDomain::PublicInternet => inner
|
||||
.public_outbound_dial_info_filter
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone(),
|
||||
RoutingDomain::LocalNetwork => inner
|
||||
.local_outbound_dial_info_filter
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -692,15 +775,18 @@ impl NetworkManager {
|
||||
};
|
||||
|
||||
// Get the udp direct dialinfo for the hole punch
|
||||
peer_nr.filter_protocols(ProtocolSet::only(ProtocolType::UDP));
|
||||
let outbound_dif = self
|
||||
.get_outbound_dial_info_filter(RoutingDomain::PublicInternet)
|
||||
.with_protocol_type(ProtocolType::UDP);
|
||||
peer_nr.set_filter(Some(outbound_dif));
|
||||
let hole_punch_dial_info_detail = peer_nr
|
||||
.first_filtered_dial_info_detail(Some(RoutingDomain::PublicInternet))
|
||||
.ok_or_else(|| eyre!("No hole punch capable dialinfo found for node"))?;
|
||||
|
||||
// Now that we picked a specific dialinfo, further restrict the noderef to the specific address type
|
||||
let mut filter = peer_nr.take_filter().unwrap();
|
||||
filter.peer_scope = PeerScope::Global;
|
||||
filter.address_type = Some(hole_punch_dial_info_detail.dial_info.address_type());
|
||||
let filter = peer_nr.take_filter().unwrap();
|
||||
let filter =
|
||||
filter.with_address_type(hole_punch_dial_info_detail.dial_info.address_type());
|
||||
peer_nr.set_filter(Some(filter));
|
||||
|
||||
// Do our half of the hole punch by sending an empty packet
|
||||
@@ -827,26 +913,11 @@ impl NetworkManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Figure out how to reach a node
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
fn get_contact_method(&self, mut target_node_ref: NodeRef) -> ContactMethod {
|
||||
let routing_table = self.routing_table();
|
||||
|
||||
// Get our network class and protocol config and node id
|
||||
let our_network_class = self.get_network_class().unwrap_or(NetworkClass::Invalid);
|
||||
let our_protocol_config = self.get_protocol_config().unwrap();
|
||||
|
||||
fn get_contact_method_public(&self, target_node_ref: NodeRef) -> ContactMethod {
|
||||
// Scope noderef down to protocols we can do outbound
|
||||
if !target_node_ref.filter_protocols(our_protocol_config.outbound) {
|
||||
return ContactMethod::Unreachable;
|
||||
}
|
||||
|
||||
// Get the best matching local direct dial info if we have it
|
||||
let opt_target_local_did =
|
||||
target_node_ref.first_filtered_dial_info_detail(Some(RoutingDomain::LocalNetwork));
|
||||
if let Some(target_local_did) = opt_target_local_did {
|
||||
return ContactMethod::Direct(target_local_did.dial_info);
|
||||
}
|
||||
let public_outbound_dif = self.get_outbound_dial_info_filter(RoutingDomain::PublicInternet);
|
||||
let target_node_ref = target_node_ref.filtered_clone(public_outbound_dif.clone());
|
||||
|
||||
// Get the best match internet dial info if we have it
|
||||
let opt_target_public_did =
|
||||
@@ -861,17 +932,25 @@ impl NetworkManager {
|
||||
// Get the target's inbound relay, it must have one or it is not reachable
|
||||
// Note that .relay() never returns our own node. We can't relay to ourselves.
|
||||
if let Some(inbound_relay_nr) = target_node_ref.relay() {
|
||||
// Scope down to protocols we can do outbound
|
||||
let inbound_relay_nr = inbound_relay_nr.filtered_clone(public_outbound_dif.clone());
|
||||
// Can we reach the inbound relay?
|
||||
if inbound_relay_nr
|
||||
.first_filtered_dial_info_detail(Some(RoutingDomain::PublicInternet))
|
||||
.is_some()
|
||||
{
|
||||
// Can we receive anything inbound ever?
|
||||
let our_network_class =
|
||||
self.get_network_class().unwrap_or(NetworkClass::Invalid);
|
||||
if matches!(our_network_class, NetworkClass::InboundCapable) {
|
||||
let routing_table = self.routing_table();
|
||||
|
||||
///////// Reverse connection
|
||||
|
||||
// Get the best match dial info for an reverse inbound connection
|
||||
let reverse_dif = DialInfoFilter::global().with_protocol_set(
|
||||
target_node_ref.outbound_protocols().unwrap_or_default(),
|
||||
);
|
||||
let reverse_dif = self
|
||||
.get_inbound_dial_info_filter(RoutingDomain::PublicInternet)
|
||||
.filtered(target_node_ref.node_info_outbound_filter());
|
||||
if let Some(reverse_did) = routing_table.first_filtered_dial_info_detail(
|
||||
Some(RoutingDomain::PublicInternet),
|
||||
&reverse_dif,
|
||||
@@ -885,35 +964,33 @@ impl NetworkManager {
|
||||
}
|
||||
}
|
||||
|
||||
// Does we and the target have outbound protocols to hole-punch?
|
||||
if our_protocol_config.outbound.contains(ProtocolType::UDP)
|
||||
&& target_node_ref
|
||||
.outbound_protocols()
|
||||
.unwrap_or_default()
|
||||
.contains(ProtocolType::UDP)
|
||||
{
|
||||
// Do the target and self nodes have a direct udp dialinfo
|
||||
let udp_dif =
|
||||
DialInfoFilter::global().with_protocol_type(ProtocolType::UDP);
|
||||
let mut udp_target_nr = target_node_ref.clone();
|
||||
udp_target_nr.filter_protocols(ProtocolSet::only(ProtocolType::UDP));
|
||||
let target_has_udp_dialinfo = target_node_ref
|
||||
.first_filtered_dial_info_detail(Some(
|
||||
RoutingDomain::PublicInternet,
|
||||
))
|
||||
.is_some();
|
||||
let self_has_udp_dialinfo = routing_table
|
||||
.first_filtered_dial_info_detail(
|
||||
Some(RoutingDomain::PublicInternet),
|
||||
&udp_dif,
|
||||
)
|
||||
.is_some();
|
||||
if target_has_udp_dialinfo && self_has_udp_dialinfo {
|
||||
return ContactMethod::SignalHolePunch(
|
||||
inbound_relay_nr,
|
||||
udp_target_nr,
|
||||
);
|
||||
}
|
||||
///////// UDP hole-punch
|
||||
|
||||
// Does the target have a direct udp dialinfo we can reach?
|
||||
let udp_target_nr = target_node_ref.filtered_clone(
|
||||
DialInfoFilter::global().with_protocol_type(ProtocolType::UDP),
|
||||
);
|
||||
let target_has_udp_dialinfo = udp_target_nr
|
||||
.first_filtered_dial_info_detail(Some(RoutingDomain::PublicInternet))
|
||||
.is_some();
|
||||
|
||||
// Does the self node have a direct udp dialinfo the target can reach?
|
||||
let inbound_udp_dif = self
|
||||
.get_inbound_dial_info_filter(RoutingDomain::PublicInternet)
|
||||
.filtered(target_node_ref.node_info_outbound_filter())
|
||||
.filtered(
|
||||
DialInfoFilter::global().with_protocol_type(ProtocolType::UDP),
|
||||
);
|
||||
let self_has_udp_dialinfo = routing_table
|
||||
.first_filtered_dial_info_detail(
|
||||
Some(RoutingDomain::PublicInternet),
|
||||
&inbound_udp_dif,
|
||||
)
|
||||
.is_some();
|
||||
|
||||
// Does the target and ourselves have a udp dialinfo that they can reach?
|
||||
if target_has_udp_dialinfo && self_has_udp_dialinfo {
|
||||
return ContactMethod::SignalHolePunch(inbound_relay_nr, udp_target_nr);
|
||||
}
|
||||
// Otherwise we have to inbound relay
|
||||
}
|
||||
@@ -922,7 +999,7 @@ impl NetworkManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the other node is not inbound capable at all, it is using a full relay
|
||||
// If the other node is not inbound capable at all, it needs to have an inbound relay
|
||||
else if let Some(target_inbound_relay_nr) = target_node_ref.relay() {
|
||||
// Can we reach the full relay?
|
||||
if target_inbound_relay_nr
|
||||
@@ -933,10 +1010,48 @@ impl NetworkManager {
|
||||
}
|
||||
}
|
||||
|
||||
ContactMethod::Unreachable
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
fn get_contact_method_local(&self, target_node_ref: NodeRef) -> ContactMethod {
|
||||
// Scope noderef down to protocols we can do outbound
|
||||
let local_outbound_dif = self.get_outbound_dial_info_filter(RoutingDomain::LocalNetwork);
|
||||
let target_node_ref = target_node_ref.filtered_clone(local_outbound_dif);
|
||||
|
||||
// Get the best matching local direct dial info if we have it
|
||||
// ygjghhtiygiukuymyg
|
||||
if target_node_ref.is_filter_dead() {
|
||||
return ContactMethod::Unreachable;
|
||||
}
|
||||
let opt_target_local_did =
|
||||
target_node_ref.first_filtered_dial_info_detail(Some(RoutingDomain::LocalNetwork));
|
||||
if let Some(target_local_did) = opt_target_local_did {
|
||||
return ContactMethod::Direct(target_local_did.dial_info);
|
||||
}
|
||||
return ContactMethod::Unreachable;
|
||||
}
|
||||
|
||||
// Figure out how to reach a node
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
fn get_contact_method(&self, target_node_ref: NodeRef) -> ContactMethod {
|
||||
// Try local first
|
||||
let out = self.get_contact_method_local(target_node_ref.clone());
|
||||
if !matches!(out, ContactMethod::Unreachable) {
|
||||
return out;
|
||||
}
|
||||
|
||||
// Try public next
|
||||
let out = self.get_contact_method_public(target_node_ref.clone());
|
||||
if !matches!(out, ContactMethod::Unreachable) {
|
||||
return out;
|
||||
}
|
||||
|
||||
// If we can't reach the node by other means, try our outbound relay if we have one
|
||||
if let Some(relay_node) = self.relay_node() {
|
||||
return ContactMethod::OutboundRelay(relay_node);
|
||||
}
|
||||
|
||||
// Otherwise, we can't reach this node
|
||||
debug!("unable to reach node {:?}", target_node_ref);
|
||||
ContactMethod::Unreachable
|
||||
@@ -1020,7 +1135,7 @@ impl NetworkManager {
|
||||
// Ensure we are filtered down to UDP (the only hole punch protocol supported today)
|
||||
assert!(target_nr
|
||||
.filter_ref()
|
||||
.map(|dif| dif.protocol_set == ProtocolSet::only(ProtocolType::UDP))
|
||||
.map(|dif| dif.protocol_set == ProtocolTypeSet::only(ProtocolType::UDP))
|
||||
.unwrap_or_default());
|
||||
|
||||
// Build a return receipt for the signal
|
||||
@@ -1118,11 +1233,13 @@ impl NetworkManager {
|
||||
.await?
|
||||
{
|
||||
None => {
|
||||
return Ok(if descriptor.matches_peer_scope(PeerScope::Local) {
|
||||
NetworkResult::value(SendDataKind::LocalDirect)
|
||||
} else {
|
||||
NetworkResult::value(SendDataKind::GlobalDirect)
|
||||
});
|
||||
return Ok(
|
||||
if descriptor.matches_peer_scope(PeerScopeSet::only(PeerScope::Local)) {
|
||||
NetworkResult::value(SendDataKind::LocalDirect)
|
||||
} else {
|
||||
NetworkResult::value(SendDataKind::GlobalDirect)
|
||||
},
|
||||
);
|
||||
}
|
||||
Some(d) => d,
|
||||
}
|
||||
|
@@ -35,7 +35,7 @@ struct NetworkInner {
|
||||
network_started: bool,
|
||||
network_needs_restart: bool,
|
||||
protocol_config: Option<ProtocolConfig>,
|
||||
static_public_dialinfo: ProtocolSet,
|
||||
static_public_dialinfo: ProtocolTypeSet,
|
||||
network_class: Option<NetworkClass>,
|
||||
join_handles: Vec<MustJoinHandle<()>>,
|
||||
stop_source: Option<StopSource>,
|
||||
@@ -43,6 +43,9 @@ struct NetworkInner {
|
||||
tcp_port: u16,
|
||||
ws_port: u16,
|
||||
wss_port: u16,
|
||||
enable_ipv4: bool,
|
||||
enable_ipv6_global: bool,
|
||||
enable_ipv6_local: bool,
|
||||
// udp
|
||||
bound_first_udp: BTreeMap<u16, Option<(socket2::Socket, socket2::Socket)>>,
|
||||
inbound_udp_protocol_handlers: BTreeMap<SocketAddr, RawUdpProtocolHandler>,
|
||||
@@ -79,7 +82,7 @@ impl Network {
|
||||
network_started: false,
|
||||
network_needs_restart: false,
|
||||
protocol_config: None,
|
||||
static_public_dialinfo: ProtocolSet::empty(),
|
||||
static_public_dialinfo: ProtocolTypeSet::empty(),
|
||||
network_class: None,
|
||||
join_handles: Vec::new(),
|
||||
stop_source: None,
|
||||
@@ -87,6 +90,9 @@ impl Network {
|
||||
tcp_port: 0u16,
|
||||
ws_port: 0u16,
|
||||
wss_port: 0u16,
|
||||
enable_ipv4: true,
|
||||
enable_ipv6_global: true,
|
||||
enable_ipv6_local: true,
|
||||
bound_first_udp: BTreeMap::new(),
|
||||
inbound_udp_protocol_handlers: BTreeMap::new(),
|
||||
outbound_udpv4_protocol_handler: None,
|
||||
@@ -540,6 +546,24 @@ impl Network {
|
||||
// initialize interfaces
|
||||
self.unlocked_inner.interfaces.refresh().await?;
|
||||
|
||||
// determine if we have ipv4/ipv6 addresses
|
||||
{
|
||||
let mut inner = self.inner.lock();
|
||||
for addr in self.unlocked_inner.interfaces.best_addresses() {
|
||||
if addr.is_ipv4() {
|
||||
inner.enable_ipv4 = true;
|
||||
} else if addr.is_ipv6() {
|
||||
let address = crate::Address::from_ip_addr(addr);
|
||||
if address.is_global() {
|
||||
inner.enable_ipv6_global = true;
|
||||
} else if address.is_local() {
|
||||
inner.enable_ipv6_local = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build our protocol config to share it with other nodes
|
||||
let protocol_config = {
|
||||
let mut inner = self.inner.lock();
|
||||
|
||||
@@ -549,7 +573,7 @@ impl Network {
|
||||
// get protocol config
|
||||
let protocol_config = {
|
||||
let c = self.config.get();
|
||||
let mut inbound = ProtocolSet::new();
|
||||
let mut inbound = ProtocolTypeSet::new();
|
||||
|
||||
if c.network.protocol.udp.enabled && c.capabilities.protocol_udp {
|
||||
inbound.insert(ProtocolType::UDP);
|
||||
@@ -564,7 +588,7 @@ impl Network {
|
||||
inbound.insert(ProtocolType::WSS);
|
||||
}
|
||||
|
||||
let mut outbound = ProtocolSet::new();
|
||||
let mut outbound = ProtocolTypeSet::new();
|
||||
if c.network.protocol.udp.enabled && c.capabilities.protocol_udp {
|
||||
outbound.insert(ProtocolType::UDP);
|
||||
}
|
||||
@@ -578,7 +602,25 @@ impl Network {
|
||||
outbound.insert(ProtocolType::WSS);
|
||||
}
|
||||
|
||||
ProtocolConfig { inbound, outbound }
|
||||
let mut family_global = AddressTypeSet::new();
|
||||
let mut family_local = AddressTypeSet::new();
|
||||
if inner.enable_ipv4 {
|
||||
family_global.insert(AddressType::IPV4);
|
||||
family_local.insert(AddressType::IPV4);
|
||||
}
|
||||
if inner.enable_ipv6_global {
|
||||
family_global.insert(AddressType::IPV6);
|
||||
}
|
||||
if inner.enable_ipv6_local {
|
||||
family_local.insert(AddressType::IPV6);
|
||||
}
|
||||
|
||||
ProtocolConfig {
|
||||
inbound,
|
||||
outbound,
|
||||
family_global,
|
||||
family_local,
|
||||
}
|
||||
};
|
||||
inner.protocol_config = Some(protocol_config);
|
||||
protocol_config
|
||||
|
@@ -280,7 +280,8 @@ impl NetworkManager {
|
||||
k,
|
||||
SignedNodeInfo::with_no_signature(NodeInfo {
|
||||
network_class: NetworkClass::InboundCapable, // Bootstraps are always inbound capable
|
||||
outbound_protocols: ProtocolSet::empty(), // Bootstraps do not participate in relaying and will not make outbound requests
|
||||
outbound_protocols: ProtocolTypeSet::only(ProtocolType::UDP), // Bootstraps do not participate in relaying and will not make outbound requests, but will have UDP enabled
|
||||
address_types: AddressTypeSet::all(), // Bootstraps are always IPV4 and IPV6 capable
|
||||
min_version: v.min_version, // Minimum protocol version specified in txt record
|
||||
max_version: v.max_version, // Maximum protocol version specified in txt record
|
||||
dial_info_detail_list: v.dial_info_details, // Dial info is as specified in the bootstrap list
|
||||
|
@@ -231,7 +231,11 @@ impl Network {
|
||||
outbound.insert(ProtocolType::WSS);
|
||||
}
|
||||
|
||||
ProtocolConfig { inbound, outbound }
|
||||
// XXX: See issue #92
|
||||
let family_global = AddressSet::all();
|
||||
let family_local = AddressSet::all();
|
||||
|
||||
ProtocolConfig { inbound, outbound, family_global, family_local }
|
||||
});
|
||||
|
||||
self.inner.lock().network_started = true;
|
||||
|
Reference in New Issue
Block a user