filtering cleanup
This commit is contained in:
parent
4fd8a562ba
commit
54f8676340
@ -207,20 +207,26 @@ struct NodeStatus {
|
|||||||
willValidateDialInfo @4 :Bool;
|
willValidateDialInfo @4 :Bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProtocolSet {
|
struct ProtocolTypeSet {
|
||||||
udp @0 :Bool;
|
udp @0 :Bool;
|
||||||
tcp @1 :Bool;
|
tcp @1 :Bool;
|
||||||
ws @2 :Bool;
|
ws @2 :Bool;
|
||||||
wss @3 :Bool;
|
wss @3 :Bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct AddressTypeSet {
|
||||||
|
ipv4 @0 :Bool;
|
||||||
|
ipv6 @1 :Bool;
|
||||||
|
}
|
||||||
|
|
||||||
struct NodeInfo {
|
struct NodeInfo {
|
||||||
networkClass @0 :NetworkClass; # network class of this node
|
networkClass @0 :NetworkClass; # network class of this node
|
||||||
outboundProtocols @1 :ProtocolSet; # protocols that can go outbound
|
outboundProtocols @1 :ProtocolTypeSet; # protocols that can go outbound
|
||||||
minVersion @2 :UInt8; # minimum protocol version for rpc
|
addressTypes @2 :AddressTypeSet; # address types supported
|
||||||
maxVersion @3 :UInt8; # maximum protocol version for rpc
|
minVersion @3 :UInt8; # minimum protocol version for rpc
|
||||||
dialInfoDetailList @4 :List(DialInfoDetail); # inbound dial info details for this node
|
maxVersion @4 :UInt8; # maximum protocol version for rpc
|
||||||
relayPeerInfo @5 :PeerInfo; # (optional) relay peer info for this node
|
dialInfoDetailList @5 :List(DialInfoDetail); # inbound dial info details for this node
|
||||||
|
relayPeerInfo @6 :PeerInfo; # (optional) relay peer info for this node
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SignedNodeInfo {
|
struct SignedNodeInfo {
|
||||||
|
@ -413,7 +413,7 @@ impl PlatformSupportApple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ask for all the addresses we have
|
// Ask for all the addresses we have
|
||||||
let ifaddrs = IfAddrs::new().map_err(map_to_string)?;
|
let ifaddrs = IfAddrs::new().wrap_err("failed to get interface addresses")?;
|
||||||
for ifaddr in ifaddrs.iter() {
|
for ifaddr in ifaddrs.iter() {
|
||||||
// Get the interface name
|
// Get the interface name
|
||||||
let ifname = unsafe { CStr::from_ptr(ifaddr.ifa_name) }
|
let ifname = unsafe { CStr::from_ptr(ifaddr.ifa_name) }
|
||||||
|
@ -56,8 +56,10 @@ pub type BootstrapRecordMap = BTreeMap<DHTKey, BootstrapRecord>;
|
|||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Default)]
|
#[derive(Copy, Clone, Debug, Default)]
|
||||||
pub struct ProtocolConfig {
|
pub struct ProtocolConfig {
|
||||||
pub outbound: ProtocolSet,
|
pub outbound: ProtocolTypeSet,
|
||||||
pub inbound: ProtocolSet,
|
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
|
// 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>,
|
client_whitelist: LruCache<DHTKey, ClientWhitelistEntry>,
|
||||||
relay_node: Option<NodeRef>,
|
relay_node: Option<NodeRef>,
|
||||||
public_address_check_cache: LruCache<DHTKey, SocketAddress>,
|
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 {
|
struct NetworkManagerUnlockedInner {
|
||||||
@ -166,6 +173,11 @@ impl NetworkManager {
|
|||||||
client_whitelist: LruCache::new_unbounded(),
|
client_whitelist: LruCache::new_unbounded(),
|
||||||
relay_node: None,
|
relay_node: None,
|
||||||
public_address_check_cache: LruCache::new(8),
|
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 {
|
fn new_unlocked_inner(config: VeilidConfig) -> NetworkManagerUnlockedInner {
|
||||||
@ -343,6 +355,41 @@ impl NetworkManager {
|
|||||||
return Err(e);
|
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
|
// Inform routing table entries that our dial info has changed
|
||||||
self.send_node_info_updates(true).await;
|
self.send_node_info_updates(true).await;
|
||||||
|
|
||||||
@ -405,6 +452,11 @@ impl NetworkManager {
|
|||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
inner.components = None;
|
inner.components = None;
|
||||||
inner.relay_node = 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
|
// send update
|
||||||
@ -544,11 +596,42 @@ impl NetworkManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return what protocols we have enabled
|
// Return what protocols we have enabled
|
||||||
pub fn get_protocol_config(&self) -> Option<ProtocolConfig> {
|
pub fn get_protocol_config(&self) -> ProtocolConfig {
|
||||||
if let Some(components) = &self.inner.lock().components {
|
let inner = self.inner.lock();
|
||||||
components.net.get_protocol_config()
|
inner.protocol_config.as_ref().unwrap().clone()
|
||||||
} else {
|
}
|
||||||
None
|
|
||||||
|
// 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
|
// 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
|
let hole_punch_dial_info_detail = peer_nr
|
||||||
.first_filtered_dial_info_detail(Some(RoutingDomain::PublicInternet))
|
.first_filtered_dial_info_detail(Some(RoutingDomain::PublicInternet))
|
||||||
.ok_or_else(|| eyre!("No hole punch capable dialinfo found for node"))?;
|
.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
|
// Now that we picked a specific dialinfo, further restrict the noderef to the specific address type
|
||||||
let mut filter = peer_nr.take_filter().unwrap();
|
let filter = peer_nr.take_filter().unwrap();
|
||||||
filter.peer_scope = PeerScope::Global;
|
let filter =
|
||||||
filter.address_type = Some(hole_punch_dial_info_detail.dial_info.address_type());
|
filter.with_address_type(hole_punch_dial_info_detail.dial_info.address_type());
|
||||||
peer_nr.set_filter(Some(filter));
|
peer_nr.set_filter(Some(filter));
|
||||||
|
|
||||||
// Do our half of the hole punch by sending an empty packet
|
// Do our half of the hole punch by sending an empty packet
|
||||||
@ -827,26 +913,11 @@ impl NetworkManager {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Figure out how to reach a node
|
|
||||||
#[instrument(level = "trace", skip(self), ret)]
|
#[instrument(level = "trace", skip(self), ret)]
|
||||||
fn get_contact_method(&self, mut target_node_ref: NodeRef) -> ContactMethod {
|
fn get_contact_method_public(&self, 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();
|
|
||||||
|
|
||||||
// Scope noderef down to protocols we can do outbound
|
// Scope noderef down to protocols we can do outbound
|
||||||
if !target_node_ref.filter_protocols(our_protocol_config.outbound) {
|
let public_outbound_dif = self.get_outbound_dial_info_filter(RoutingDomain::PublicInternet);
|
||||||
return ContactMethod::Unreachable;
|
let target_node_ref = target_node_ref.filtered_clone(public_outbound_dif.clone());
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the best match internet dial info if we have it
|
// Get the best match internet dial info if we have it
|
||||||
let opt_target_public_did =
|
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
|
// 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.
|
// Note that .relay() never returns our own node. We can't relay to ourselves.
|
||||||
if let Some(inbound_relay_nr) = target_node_ref.relay() {
|
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?
|
// Can we reach the inbound relay?
|
||||||
if inbound_relay_nr
|
if inbound_relay_nr
|
||||||
.first_filtered_dial_info_detail(Some(RoutingDomain::PublicInternet))
|
.first_filtered_dial_info_detail(Some(RoutingDomain::PublicInternet))
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
// Can we receive anything inbound ever?
|
// 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) {
|
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
|
// Get the best match dial info for an reverse inbound connection
|
||||||
let reverse_dif = DialInfoFilter::global().with_protocol_set(
|
let reverse_dif = self
|
||||||
target_node_ref.outbound_protocols().unwrap_or_default(),
|
.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(
|
if let Some(reverse_did) = routing_table.first_filtered_dial_info_detail(
|
||||||
Some(RoutingDomain::PublicInternet),
|
Some(RoutingDomain::PublicInternet),
|
||||||
&reverse_dif,
|
&reverse_dif,
|
||||||
@ -885,35 +964,33 @@ impl NetworkManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does we and the target have outbound protocols to hole-punch?
|
///////// UDP hole-punch
|
||||||
if our_protocol_config.outbound.contains(ProtocolType::UDP)
|
|
||||||
&& target_node_ref
|
// Does the target have a direct udp dialinfo we can reach?
|
||||||
.outbound_protocols()
|
let udp_target_nr = target_node_ref.filtered_clone(
|
||||||
.unwrap_or_default()
|
DialInfoFilter::global().with_protocol_type(ProtocolType::UDP),
|
||||||
.contains(ProtocolType::UDP)
|
);
|
||||||
{
|
let target_has_udp_dialinfo = udp_target_nr
|
||||||
// Do the target and self nodes have a direct udp dialinfo
|
.first_filtered_dial_info_detail(Some(RoutingDomain::PublicInternet))
|
||||||
let udp_dif =
|
.is_some();
|
||||||
DialInfoFilter::global().with_protocol_type(ProtocolType::UDP);
|
|
||||||
let mut udp_target_nr = target_node_ref.clone();
|
// Does the self node have a direct udp dialinfo the target can reach?
|
||||||
udp_target_nr.filter_protocols(ProtocolSet::only(ProtocolType::UDP));
|
let inbound_udp_dif = self
|
||||||
let target_has_udp_dialinfo = target_node_ref
|
.get_inbound_dial_info_filter(RoutingDomain::PublicInternet)
|
||||||
.first_filtered_dial_info_detail(Some(
|
.filtered(target_node_ref.node_info_outbound_filter())
|
||||||
RoutingDomain::PublicInternet,
|
.filtered(
|
||||||
))
|
DialInfoFilter::global().with_protocol_type(ProtocolType::UDP),
|
||||||
.is_some();
|
);
|
||||||
let self_has_udp_dialinfo = routing_table
|
let self_has_udp_dialinfo = routing_table
|
||||||
.first_filtered_dial_info_detail(
|
.first_filtered_dial_info_detail(
|
||||||
Some(RoutingDomain::PublicInternet),
|
Some(RoutingDomain::PublicInternet),
|
||||||
&udp_dif,
|
&inbound_udp_dif,
|
||||||
)
|
)
|
||||||
.is_some();
|
.is_some();
|
||||||
if target_has_udp_dialinfo && self_has_udp_dialinfo {
|
|
||||||
return ContactMethod::SignalHolePunch(
|
// Does the target and ourselves have a udp dialinfo that they can reach?
|
||||||
inbound_relay_nr,
|
if target_has_udp_dialinfo && self_has_udp_dialinfo {
|
||||||
udp_target_nr,
|
return ContactMethod::SignalHolePunch(inbound_relay_nr, udp_target_nr);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Otherwise we have to inbound relay
|
// 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() {
|
else if let Some(target_inbound_relay_nr) = target_node_ref.relay() {
|
||||||
// Can we reach the full relay?
|
// Can we reach the full relay?
|
||||||
if target_inbound_relay_nr
|
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 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() {
|
if let Some(relay_node) = self.relay_node() {
|
||||||
return ContactMethod::OutboundRelay(relay_node);
|
return ContactMethod::OutboundRelay(relay_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, we can't reach this node
|
// Otherwise, we can't reach this node
|
||||||
debug!("unable to reach node {:?}", target_node_ref);
|
debug!("unable to reach node {:?}", target_node_ref);
|
||||||
ContactMethod::Unreachable
|
ContactMethod::Unreachable
|
||||||
@ -1020,7 +1135,7 @@ impl NetworkManager {
|
|||||||
// Ensure we are filtered down to UDP (the only hole punch protocol supported today)
|
// Ensure we are filtered down to UDP (the only hole punch protocol supported today)
|
||||||
assert!(target_nr
|
assert!(target_nr
|
||||||
.filter_ref()
|
.filter_ref()
|
||||||
.map(|dif| dif.protocol_set == ProtocolSet::only(ProtocolType::UDP))
|
.map(|dif| dif.protocol_set == ProtocolTypeSet::only(ProtocolType::UDP))
|
||||||
.unwrap_or_default());
|
.unwrap_or_default());
|
||||||
|
|
||||||
// Build a return receipt for the signal
|
// Build a return receipt for the signal
|
||||||
@ -1118,11 +1233,13 @@ impl NetworkManager {
|
|||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
None => {
|
None => {
|
||||||
return Ok(if descriptor.matches_peer_scope(PeerScope::Local) {
|
return Ok(
|
||||||
NetworkResult::value(SendDataKind::LocalDirect)
|
if descriptor.matches_peer_scope(PeerScopeSet::only(PeerScope::Local)) {
|
||||||
} else {
|
NetworkResult::value(SendDataKind::LocalDirect)
|
||||||
NetworkResult::value(SendDataKind::GlobalDirect)
|
} else {
|
||||||
});
|
NetworkResult::value(SendDataKind::GlobalDirect)
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Some(d) => d,
|
Some(d) => d,
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ struct NetworkInner {
|
|||||||
network_started: bool,
|
network_started: bool,
|
||||||
network_needs_restart: bool,
|
network_needs_restart: bool,
|
||||||
protocol_config: Option<ProtocolConfig>,
|
protocol_config: Option<ProtocolConfig>,
|
||||||
static_public_dialinfo: ProtocolSet,
|
static_public_dialinfo: ProtocolTypeSet,
|
||||||
network_class: Option<NetworkClass>,
|
network_class: Option<NetworkClass>,
|
||||||
join_handles: Vec<MustJoinHandle<()>>,
|
join_handles: Vec<MustJoinHandle<()>>,
|
||||||
stop_source: Option<StopSource>,
|
stop_source: Option<StopSource>,
|
||||||
@ -43,6 +43,9 @@ struct NetworkInner {
|
|||||||
tcp_port: u16,
|
tcp_port: u16,
|
||||||
ws_port: u16,
|
ws_port: u16,
|
||||||
wss_port: u16,
|
wss_port: u16,
|
||||||
|
enable_ipv4: bool,
|
||||||
|
enable_ipv6_global: bool,
|
||||||
|
enable_ipv6_local: bool,
|
||||||
// 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>,
|
||||||
@ -79,7 +82,7 @@ impl Network {
|
|||||||
network_started: false,
|
network_started: false,
|
||||||
network_needs_restart: false,
|
network_needs_restart: false,
|
||||||
protocol_config: None,
|
protocol_config: None,
|
||||||
static_public_dialinfo: ProtocolSet::empty(),
|
static_public_dialinfo: ProtocolTypeSet::empty(),
|
||||||
network_class: None,
|
network_class: None,
|
||||||
join_handles: Vec::new(),
|
join_handles: Vec::new(),
|
||||||
stop_source: None,
|
stop_source: None,
|
||||||
@ -87,6 +90,9 @@ impl Network {
|
|||||||
tcp_port: 0u16,
|
tcp_port: 0u16,
|
||||||
ws_port: 0u16,
|
ws_port: 0u16,
|
||||||
wss_port: 0u16,
|
wss_port: 0u16,
|
||||||
|
enable_ipv4: true,
|
||||||
|
enable_ipv6_global: true,
|
||||||
|
enable_ipv6_local: true,
|
||||||
bound_first_udp: BTreeMap::new(),
|
bound_first_udp: BTreeMap::new(),
|
||||||
inbound_udp_protocol_handlers: BTreeMap::new(),
|
inbound_udp_protocol_handlers: BTreeMap::new(),
|
||||||
outbound_udpv4_protocol_handler: None,
|
outbound_udpv4_protocol_handler: None,
|
||||||
@ -540,6 +546,24 @@ impl Network {
|
|||||||
// initialize interfaces
|
// initialize interfaces
|
||||||
self.unlocked_inner.interfaces.refresh().await?;
|
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 protocol_config = {
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
|
|
||||||
@ -549,7 +573,7 @@ impl Network {
|
|||||||
// get protocol config
|
// get protocol config
|
||||||
let protocol_config = {
|
let protocol_config = {
|
||||||
let c = self.config.get();
|
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 {
|
if c.network.protocol.udp.enabled && c.capabilities.protocol_udp {
|
||||||
inbound.insert(ProtocolType::UDP);
|
inbound.insert(ProtocolType::UDP);
|
||||||
@ -564,7 +588,7 @@ impl Network {
|
|||||||
inbound.insert(ProtocolType::WSS);
|
inbound.insert(ProtocolType::WSS);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut outbound = ProtocolSet::new();
|
let mut outbound = ProtocolTypeSet::new();
|
||||||
if c.network.protocol.udp.enabled && c.capabilities.protocol_udp {
|
if c.network.protocol.udp.enabled && c.capabilities.protocol_udp {
|
||||||
outbound.insert(ProtocolType::UDP);
|
outbound.insert(ProtocolType::UDP);
|
||||||
}
|
}
|
||||||
@ -578,7 +602,25 @@ impl Network {
|
|||||||
outbound.insert(ProtocolType::WSS);
|
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);
|
inner.protocol_config = Some(protocol_config);
|
||||||
protocol_config
|
protocol_config
|
||||||
|
@ -280,7 +280,8 @@ impl NetworkManager {
|
|||||||
k,
|
k,
|
||||||
SignedNodeInfo::with_no_signature(NodeInfo {
|
SignedNodeInfo::with_no_signature(NodeInfo {
|
||||||
network_class: NetworkClass::InboundCapable, // Bootstraps are always inbound capable
|
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
|
min_version: v.min_version, // Minimum protocol version specified in txt record
|
||||||
max_version: v.max_version, // Maximum 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
|
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);
|
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;
|
self.inner.lock().network_started = true;
|
||||||
|
@ -126,9 +126,11 @@ impl RoutingTable {
|
|||||||
pub fn get_own_node_info(&self) -> NodeInfo {
|
pub fn get_own_node_info(&self) -> NodeInfo {
|
||||||
let netman = self.network_manager();
|
let netman = self.network_manager();
|
||||||
let relay_node = netman.relay_node();
|
let relay_node = netman.relay_node();
|
||||||
|
let pc = netman.get_protocol_config();
|
||||||
NodeInfo {
|
NodeInfo {
|
||||||
network_class: netman.get_network_class().unwrap_or(NetworkClass::Invalid),
|
network_class: netman.get_network_class().unwrap_or(NetworkClass::Invalid),
|
||||||
outbound_protocols: netman.get_protocol_config().unwrap_or_default().outbound,
|
outbound_protocols: pc.outbound,
|
||||||
|
address_types: pc.family_global,
|
||||||
min_version: MIN_VERSION,
|
min_version: MIN_VERSION,
|
||||||
max_version: MAX_VERSION,
|
max_version: MAX_VERSION,
|
||||||
dial_info_detail_list: self.dial_info_details(RoutingDomain::PublicInternet),
|
dial_info_detail_list: self.dial_info_details(RoutingDomain::PublicInternet),
|
||||||
|
@ -50,19 +50,41 @@ impl NodeRef {
|
|||||||
self.filter = filter
|
self.filter = filter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if some protocols can still pass the filter and false if no protocols remain
|
pub fn merge_filter(&mut self, filter: DialInfoFilter) {
|
||||||
pub fn filter_protocols(&mut self, protocol_set: ProtocolSet) -> bool {
|
if let Some(self_filter) = self.filter.take() {
|
||||||
if protocol_set != ProtocolSet::all() {
|
self.filter = Some(self_filter.filtered(filter));
|
||||||
let mut dif = self.filter.clone().unwrap_or_default();
|
} else {
|
||||||
dif.protocol_set &= protocol_set;
|
self.filter = Some(filter);
|
||||||
self.filter = Some(dif);
|
|
||||||
}
|
}
|
||||||
self.filter
|
|
||||||
.as_ref()
|
|
||||||
.map(|f| !f.protocol_set.is_empty())
|
|
||||||
.unwrap_or(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn filtered_clone(&self, filter: DialInfoFilter) -> Self {
|
||||||
|
let mut out = self.clone();
|
||||||
|
out.merge_filter(filter);
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_filter_dead(&self) -> bool {
|
||||||
|
if let Some(filter) = &self.filter {
|
||||||
|
filter.is_dead()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if some protocols can still pass the filter and false if no protocols remain
|
||||||
|
// pub fn filter_protocols(&mut self, protocol_set: ProtocolSet) -> bool {
|
||||||
|
// if protocol_set != ProtocolSet::all() {
|
||||||
|
// let mut dif = self.filter.clone().unwrap_or_default();
|
||||||
|
// dif.protocol_set &= protocol_set;
|
||||||
|
// self.filter = Some(dif);
|
||||||
|
// }
|
||||||
|
// self.filter
|
||||||
|
// .as_ref()
|
||||||
|
// .map(|f| !f.protocol_set.is_empty())
|
||||||
|
// .unwrap_or(true)
|
||||||
|
// }
|
||||||
|
|
||||||
pub fn operate<T, F>(&self, f: F) -> T
|
pub fn operate<T, F>(&self, f: F) -> T
|
||||||
where
|
where
|
||||||
F: FnOnce(&BucketEntryInner) -> T,
|
F: FnOnce(&BucketEntryInner) -> T,
|
||||||
@ -89,9 +111,23 @@ impl NodeRef {
|
|||||||
pub fn network_class(&self) -> Option<NetworkClass> {
|
pub fn network_class(&self) -> Option<NetworkClass> {
|
||||||
self.operate(|e| e.node_info().map(|n| n.network_class))
|
self.operate(|e| e.node_info().map(|n| n.network_class))
|
||||||
}
|
}
|
||||||
pub fn outbound_protocols(&self) -> Option<ProtocolSet> {
|
pub fn outbound_protocols(&self) -> Option<ProtocolTypeSet> {
|
||||||
self.operate(|e| e.node_info().map(|n| n.outbound_protocols))
|
self.operate(|e| e.node_info().map(|n| n.outbound_protocols))
|
||||||
}
|
}
|
||||||
|
pub fn address_types(&self) -> Option<AddressTypeSet> {
|
||||||
|
self.operate(|e| e.node_info().map(|n| n.address_types))
|
||||||
|
}
|
||||||
|
pub fn node_info_outbound_filter(&self) -> DialInfoFilter {
|
||||||
|
let mut dif = DialInfoFilter::all();
|
||||||
|
if let Some(outbound_protocols) = self.outbound_protocols() {
|
||||||
|
dif = dif.with_protocol_type_set(outbound_protocols);
|
||||||
|
}
|
||||||
|
if let Some(address_types) = self.address_types() {
|
||||||
|
dif = dif.with_address_type_set(address_types);
|
||||||
|
}
|
||||||
|
dif
|
||||||
|
}
|
||||||
|
|
||||||
pub fn relay(&self) -> Option<NodeRef> {
|
pub fn relay(&self) -> Option<NodeRef> {
|
||||||
let target_rpi = self.operate(|e| e.node_info().map(|n| n.relay_peer_info))?;
|
let target_rpi = self.operate(|e| e.node_info().map(|n| n.relay_peer_info))?;
|
||||||
target_rpi.and_then(|t| {
|
target_rpi.and_then(|t| {
|
||||||
@ -116,15 +152,7 @@ impl NodeRef {
|
|||||||
) -> Option<DialInfoDetail> {
|
) -> Option<DialInfoDetail> {
|
||||||
self.operate(|e| {
|
self.operate(|e| {
|
||||||
// Prefer local dial info first unless it is filtered out
|
// Prefer local dial info first unless it is filtered out
|
||||||
if (routing_domain == None || routing_domain == Some(RoutingDomain::LocalNetwork))
|
if routing_domain == None || routing_domain == Some(RoutingDomain::LocalNetwork) {
|
||||||
&& matches!(
|
|
||||||
self.filter
|
|
||||||
.as_ref()
|
|
||||||
.map(|f| f.peer_scope)
|
|
||||||
.unwrap_or(PeerScope::All),
|
|
||||||
PeerScope::All | PeerScope::Local
|
|
||||||
)
|
|
||||||
{
|
|
||||||
e.local_node_info().and_then(|l| {
|
e.local_node_info().and_then(|l| {
|
||||||
l.first_filtered_dial_info(|di| {
|
l.first_filtered_dial_info(|di| {
|
||||||
if let Some(filter) = self.filter.as_ref() {
|
if let Some(filter) = self.filter.as_ref() {
|
||||||
@ -142,15 +170,7 @@ impl NodeRef {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
if (routing_domain == None || routing_domain == Some(RoutingDomain::PublicInternet))
|
if routing_domain == None || routing_domain == Some(RoutingDomain::PublicInternet) {
|
||||||
&& matches!(
|
|
||||||
self.filter
|
|
||||||
.as_ref()
|
|
||||||
.map(|f| f.peer_scope)
|
|
||||||
.unwrap_or(PeerScope::All),
|
|
||||||
PeerScope::All | PeerScope::Global
|
|
||||||
)
|
|
||||||
{
|
|
||||||
e.node_info().and_then(|n| {
|
e.node_info().and_then(|n| {
|
||||||
n.first_filtered_dial_info_detail(|did| {
|
n.first_filtered_dial_info_detail(|did| {
|
||||||
if let Some(filter) = self.filter.as_ref() {
|
if let Some(filter) = self.filter.as_ref() {
|
||||||
@ -174,15 +194,7 @@ impl NodeRef {
|
|||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
self.operate(|e| {
|
self.operate(|e| {
|
||||||
// Prefer local dial info first unless it is filtered out
|
// Prefer local dial info first unless it is filtered out
|
||||||
if (routing_domain == None || routing_domain == Some(RoutingDomain::LocalNetwork))
|
if routing_domain == None || routing_domain == Some(RoutingDomain::LocalNetwork) {
|
||||||
&& matches!(
|
|
||||||
self.filter
|
|
||||||
.as_ref()
|
|
||||||
.map(|f| f.peer_scope)
|
|
||||||
.unwrap_or(PeerScope::All),
|
|
||||||
PeerScope::All | PeerScope::Local
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if let Some(lni) = e.local_node_info() {
|
if let Some(lni) = e.local_node_info() {
|
||||||
for di in lni.all_filtered_dial_info(|di| {
|
for di in lni.all_filtered_dial_info(|di| {
|
||||||
if let Some(filter) = self.filter.as_ref() {
|
if let Some(filter) = self.filter.as_ref() {
|
||||||
@ -198,15 +210,7 @@ impl NodeRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (routing_domain == None || routing_domain == Some(RoutingDomain::PublicInternet))
|
if routing_domain == None || routing_domain == Some(RoutingDomain::PublicInternet) {
|
||||||
&& matches!(
|
|
||||||
self.filter
|
|
||||||
.as_ref()
|
|
||||||
.map(|f| f.peer_scope)
|
|
||||||
.unwrap_or(PeerScope::All),
|
|
||||||
PeerScope::All | PeerScope::Global
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if let Some(ni) = e.node_info() {
|
if let Some(ni) = e.node_info() {
|
||||||
out.append(&mut ni.all_filtered_dial_info_details(|did| {
|
out.append(&mut ni.all_filtered_dial_info_details(|did| {
|
||||||
if let Some(filter) = self.filter.as_ref() {
|
if let Some(filter) = self.filter.as_ref() {
|
||||||
|
25
veilid-core/src/rpc_processor/coders/address_type_set.rs
Normal file
25
veilid-core/src/rpc_processor/coders/address_type_set.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use crate::*;
|
||||||
|
use rpc_processor::*;
|
||||||
|
|
||||||
|
pub fn encode_address_type_set(
|
||||||
|
address_type_set: &AddressTypeSet,
|
||||||
|
builder: &mut veilid_capnp::address_type_set::Builder,
|
||||||
|
) -> Result<(), RPCError> {
|
||||||
|
builder.set_ipv4(address_type_set.contains(AddressType::IPV4));
|
||||||
|
builder.set_ipv6(address_type_set.contains(AddressType::IPV6));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decode_address_type_set(
|
||||||
|
reader: &veilid_capnp::address_type_set::Reader,
|
||||||
|
) -> Result<AddressTypeSet, RPCError> {
|
||||||
|
let mut out = AddressTypeSet::new();
|
||||||
|
if reader.reborrow().get_ipv4() {
|
||||||
|
out.insert(AddressType::IPV4);
|
||||||
|
}
|
||||||
|
if reader.reborrow().get_ipv6() {
|
||||||
|
out.insert(AddressType::IPV6);
|
||||||
|
}
|
||||||
|
Ok(out)
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
mod address;
|
mod address;
|
||||||
|
mod address_type_set;
|
||||||
mod block_id;
|
mod block_id;
|
||||||
mod dial_info;
|
mod dial_info;
|
||||||
mod dial_info_class;
|
mod dial_info_class;
|
||||||
@ -11,7 +12,7 @@ mod nonce;
|
|||||||
mod operations;
|
mod operations;
|
||||||
mod peer_info;
|
mod peer_info;
|
||||||
mod private_safety_route;
|
mod private_safety_route;
|
||||||
mod protocol_set;
|
mod protocol_type_set;
|
||||||
mod public_key;
|
mod public_key;
|
||||||
mod sender_info;
|
mod sender_info;
|
||||||
mod signal_info;
|
mod signal_info;
|
||||||
@ -23,6 +24,7 @@ mod value_data;
|
|||||||
mod value_key;
|
mod value_key;
|
||||||
|
|
||||||
pub use address::*;
|
pub use address::*;
|
||||||
|
pub use address_type_set::*;
|
||||||
pub use block_id::*;
|
pub use block_id::*;
|
||||||
pub use dial_info::*;
|
pub use dial_info::*;
|
||||||
pub use dial_info_class::*;
|
pub use dial_info_class::*;
|
||||||
@ -35,7 +37,7 @@ pub use nonce::*;
|
|||||||
pub use operations::*;
|
pub use operations::*;
|
||||||
pub use peer_info::*;
|
pub use peer_info::*;
|
||||||
pub use private_safety_route::*;
|
pub use private_safety_route::*;
|
||||||
pub use protocol_set::*;
|
pub use protocol_type_set::*;
|
||||||
pub use public_key::*;
|
pub use public_key::*;
|
||||||
pub use sender_info::*;
|
pub use sender_info::*;
|
||||||
pub use signal_info::*;
|
pub use signal_info::*;
|
||||||
|
@ -8,7 +8,10 @@ pub fn encode_node_info(
|
|||||||
builder.set_network_class(encode_network_class(node_info.network_class));
|
builder.set_network_class(encode_network_class(node_info.network_class));
|
||||||
|
|
||||||
let mut ps_builder = builder.reborrow().init_outbound_protocols();
|
let mut ps_builder = builder.reborrow().init_outbound_protocols();
|
||||||
encode_protocol_set(&node_info.outbound_protocols, &mut ps_builder)?;
|
encode_protocol_type_set(&node_info.outbound_protocols, &mut ps_builder)?;
|
||||||
|
|
||||||
|
let mut ats_builder = builder.reborrow().init_address_types();
|
||||||
|
encode_address_type_set(&node_info.address_types, &mut ats_builder)?;
|
||||||
|
|
||||||
builder.set_min_version(node_info.min_version);
|
builder.set_min_version(node_info.min_version);
|
||||||
builder.set_max_version(node_info.max_version);
|
builder.set_max_version(node_info.max_version);
|
||||||
@ -47,13 +50,20 @@ pub fn decode_node_info(
|
|||||||
.map_err(RPCError::protocol)?,
|
.map_err(RPCError::protocol)?,
|
||||||
);
|
);
|
||||||
|
|
||||||
let outbound_protocols = decode_protocol_set(
|
let outbound_protocols = decode_protocol_type_set(
|
||||||
&reader
|
&reader
|
||||||
.reborrow()
|
.reborrow()
|
||||||
.get_outbound_protocols()
|
.get_outbound_protocols()
|
||||||
.map_err(RPCError::protocol)?,
|
.map_err(RPCError::protocol)?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let address_types = decode_address_type_set(
|
||||||
|
&reader
|
||||||
|
.reborrow()
|
||||||
|
.get_address_types()
|
||||||
|
.map_err(RPCError::protocol)?,
|
||||||
|
)?;
|
||||||
|
|
||||||
let min_version = reader.reborrow().get_min_version();
|
let min_version = reader.reborrow().get_min_version();
|
||||||
let max_version = reader.reborrow().get_max_version();
|
let max_version = reader.reborrow().get_max_version();
|
||||||
|
|
||||||
@ -90,6 +100,7 @@ pub fn decode_node_info(
|
|||||||
Ok(NodeInfo {
|
Ok(NodeInfo {
|
||||||
network_class,
|
network_class,
|
||||||
outbound_protocols,
|
outbound_protocols,
|
||||||
|
address_types,
|
||||||
min_version,
|
min_version,
|
||||||
max_version,
|
max_version,
|
||||||
dial_info_detail_list,
|
dial_info_detail_list,
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
use crate::*;
|
|
||||||
use rpc_processor::*;
|
|
||||||
|
|
||||||
pub fn encode_protocol_set(
|
|
||||||
protocol_set: &ProtocolSet,
|
|
||||||
builder: &mut veilid_capnp::protocol_set::Builder,
|
|
||||||
) -> Result<(), RPCError> {
|
|
||||||
builder.set_udp(protocol_set.contains(ProtocolType::UDP));
|
|
||||||
builder.set_tcp(protocol_set.contains(ProtocolType::TCP));
|
|
||||||
builder.set_ws(protocol_set.contains(ProtocolType::WS));
|
|
||||||
builder.set_wss(protocol_set.contains(ProtocolType::WSS));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decode_protocol_set(
|
|
||||||
reader: &veilid_capnp::protocol_set::Reader,
|
|
||||||
) -> Result<ProtocolSet, RPCError> {
|
|
||||||
let mut out = ProtocolSet::new();
|
|
||||||
if reader.reborrow().get_udp() {
|
|
||||||
out.insert(ProtocolType::UDP);
|
|
||||||
}
|
|
||||||
if reader.reborrow().get_tcp() {
|
|
||||||
out.insert(ProtocolType::TCP);
|
|
||||||
}
|
|
||||||
if reader.reborrow().get_ws() {
|
|
||||||
out.insert(ProtocolType::WS);
|
|
||||||
}
|
|
||||||
if reader.reborrow().get_wss() {
|
|
||||||
out.insert(ProtocolType::WSS);
|
|
||||||
}
|
|
||||||
Ok(out)
|
|
||||||
}
|
|
33
veilid-core/src/rpc_processor/coders/protocol_type_set.rs
Normal file
33
veilid-core/src/rpc_processor/coders/protocol_type_set.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use crate::*;
|
||||||
|
use rpc_processor::*;
|
||||||
|
|
||||||
|
pub fn encode_protocol_type_set(
|
||||||
|
protocol_type_set: &ProtocolTypeSet,
|
||||||
|
builder: &mut veilid_capnp::protocol_type_set::Builder,
|
||||||
|
) -> Result<(), RPCError> {
|
||||||
|
builder.set_udp(protocol_type_set.contains(ProtocolType::UDP));
|
||||||
|
builder.set_tcp(protocol_type_set.contains(ProtocolType::TCP));
|
||||||
|
builder.set_ws(protocol_type_set.contains(ProtocolType::WS));
|
||||||
|
builder.set_wss(protocol_type_set.contains(ProtocolType::WSS));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decode_protocol_type_set(
|
||||||
|
reader: &veilid_capnp::protocol_type_set::Reader,
|
||||||
|
) -> Result<ProtocolTypeSet, RPCError> {
|
||||||
|
let mut out = ProtocolTypeSet::new();
|
||||||
|
if reader.reborrow().get_udp() {
|
||||||
|
out.insert(ProtocolType::UDP);
|
||||||
|
}
|
||||||
|
if reader.reborrow().get_tcp() {
|
||||||
|
out.insert(ProtocolType::TCP);
|
||||||
|
}
|
||||||
|
if reader.reborrow().get_ws() {
|
||||||
|
out.insert(ProtocolType::WS);
|
||||||
|
}
|
||||||
|
if reader.reborrow().get_wss() {
|
||||||
|
out.insert(ProtocolType::WSS);
|
||||||
|
}
|
||||||
|
Ok(out)
|
||||||
|
}
|
@ -402,7 +402,8 @@ pub struct NodeStatus {
|
|||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct NodeInfo {
|
pub struct NodeInfo {
|
||||||
pub network_class: NetworkClass,
|
pub network_class: NetworkClass,
|
||||||
pub outbound_protocols: ProtocolSet,
|
pub outbound_protocols: ProtocolTypeSet,
|
||||||
|
pub address_types: AddressTypeSet,
|
||||||
pub min_version: u8,
|
pub min_version: u8,
|
||||||
pub max_version: u8,
|
pub max_version: u8,
|
||||||
pub dial_info_detail_list: Vec<DialInfoDetail>,
|
pub dial_info_detail_list: Vec<DialInfoDetail>,
|
||||||
@ -557,14 +558,23 @@ impl ProtocolType {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub type ProtocolTypeSet = EnumSet<ProtocolType>;
|
||||||
|
|
||||||
pub type ProtocolSet = EnumSet<ProtocolType>;
|
#[allow(clippy::derive_hash_xor_eq)]
|
||||||
|
#[derive(Debug, PartialOrd, Ord, Hash, Serialize, Deserialize, EnumSetType)]
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Serialize, Deserialize)]
|
|
||||||
pub enum AddressType {
|
pub enum AddressType {
|
||||||
IPV4,
|
IPV4,
|
||||||
IPV6,
|
IPV6,
|
||||||
}
|
}
|
||||||
|
pub type AddressTypeSet = EnumSet<AddressType>;
|
||||||
|
|
||||||
|
#[allow(clippy::derive_hash_xor_eq)]
|
||||||
|
#[derive(Debug, Ord, PartialOrd, Hash, Serialize, Deserialize, EnumSetType)]
|
||||||
|
pub enum PeerScope {
|
||||||
|
Global,
|
||||||
|
Local,
|
||||||
|
}
|
||||||
|
pub type PeerScopeSet = EnumSet<PeerScope>;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Serialize, Deserialize)]
|
||||||
pub enum Address {
|
pub enum Address {
|
||||||
@ -585,6 +595,12 @@ impl Address {
|
|||||||
SocketAddr::V6(v6) => Address::IPV6(*v6.ip()),
|
SocketAddr::V6(v6) => Address::IPV6(*v6.ip()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn from_ip_addr(addr: IpAddr) -> Address {
|
||||||
|
match addr {
|
||||||
|
IpAddr::V4(v4) => Address::IPV4(v4),
|
||||||
|
IpAddr::V6(v6) => Address::IPV6(v6),
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn address_type(&self) -> AddressType {
|
pub fn address_type(&self) -> AddressType {
|
||||||
match self {
|
match self {
|
||||||
Address::IPV4(_) => AddressType::IPV4,
|
Address::IPV4(_) => AddressType::IPV4,
|
||||||
@ -715,17 +731,17 @@ impl FromStr for SocketAddress {
|
|||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct DialInfoFilter {
|
pub struct DialInfoFilter {
|
||||||
pub peer_scope: PeerScope,
|
pub peer_scope_set: PeerScopeSet,
|
||||||
pub protocol_set: ProtocolSet,
|
pub protocol_set: ProtocolTypeSet,
|
||||||
pub address_type: Option<AddressType>,
|
pub address_set: AddressTypeSet,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DialInfoFilter {
|
impl Default for DialInfoFilter {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
peer_scope: PeerScope::All,
|
peer_scope_set: PeerScopeSet::all(),
|
||||||
protocol_set: ProtocolSet::all(),
|
protocol_set: ProtocolTypeSet::all(),
|
||||||
address_type: None,
|
address_set: AddressTypeSet::all(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -733,55 +749,72 @@ impl Default for DialInfoFilter {
|
|||||||
impl DialInfoFilter {
|
impl DialInfoFilter {
|
||||||
pub fn all() -> Self {
|
pub fn all() -> Self {
|
||||||
Self {
|
Self {
|
||||||
peer_scope: PeerScope::All,
|
peer_scope_set: PeerScopeSet::all(),
|
||||||
protocol_set: ProtocolSet::all(),
|
protocol_set: ProtocolTypeSet::all(),
|
||||||
address_type: None,
|
address_set: AddressTypeSet::all(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn global() -> Self {
|
pub fn global() -> Self {
|
||||||
Self {
|
Self {
|
||||||
peer_scope: PeerScope::Global,
|
peer_scope_set: PeerScopeSet::only(PeerScope::Global),
|
||||||
protocol_set: ProtocolSet::all(),
|
protocol_set: ProtocolTypeSet::all(),
|
||||||
address_type: None,
|
address_set: AddressTypeSet::all(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn local() -> Self {
|
pub fn local() -> Self {
|
||||||
Self {
|
Self {
|
||||||
peer_scope: PeerScope::Local,
|
peer_scope_set: PeerScopeSet::only(PeerScope::Local),
|
||||||
protocol_set: ProtocolSet::all(),
|
protocol_set: ProtocolTypeSet::all(),
|
||||||
address_type: None,
|
address_set: AddressTypeSet::all(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn scoped(peer_scope: PeerScope) -> Self {
|
pub fn scoped(peer_scope: PeerScope) -> Self {
|
||||||
Self {
|
Self {
|
||||||
peer_scope,
|
peer_scope_set: PeerScopeSet::only(peer_scope),
|
||||||
protocol_set: ProtocolSet::all(),
|
protocol_set: ProtocolTypeSet::all(),
|
||||||
address_type: None,
|
address_set: AddressTypeSet::all(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn with_protocol_type(mut self, protocol_type: ProtocolType) -> Self {
|
pub fn with_protocol_type(mut self, protocol_type: ProtocolType) -> Self {
|
||||||
self.protocol_set = ProtocolSet::only(protocol_type);
|
self.protocol_set = ProtocolTypeSet::only(protocol_type);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn with_protocol_set(mut self, protocol_set: ProtocolSet) -> Self {
|
pub fn with_protocol_type_set(mut self, protocol_set: ProtocolTypeSet) -> Self {
|
||||||
self.protocol_set = protocol_set;
|
self.protocol_set = protocol_set;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn with_address_type(mut self, address_type: AddressType) -> Self {
|
pub fn with_address_type(mut self, address_type: AddressType) -> Self {
|
||||||
self.address_type = Some(address_type);
|
self.address_set = AddressTypeSet::only(address_type);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
pub fn with_address_type_set(mut self, address_set: AddressTypeSet) -> Self {
|
||||||
|
self.address_set = address_set;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
pub fn filtered(mut self, other_dif: DialInfoFilter) -> Self {
|
||||||
|
self.peer_scope_set &= other_dif.peer_scope_set;
|
||||||
|
self.protocol_set &= other_dif.protocol_set;
|
||||||
|
self.address_set &= other_dif.address_set;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
pub fn is_dead(&self) -> bool {
|
||||||
|
self.peer_scope_set.is_empty()
|
||||||
|
|| self.protocol_set.is_empty()
|
||||||
|
|| self.address_set.is_empty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for DialInfoFilter {
|
impl fmt::Debug for DialInfoFilter {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
out += &format!("{:?}", self.peer_scope);
|
if self.peer_scope_set != PeerScopeSet::all() {
|
||||||
if self.protocol_set != ProtocolSet::all() {
|
out += &format!("+{:?}", self.peer_scope_set);
|
||||||
|
}
|
||||||
|
if self.protocol_set != ProtocolTypeSet::all() {
|
||||||
out += &format!("+{:?}", self.protocol_set);
|
out += &format!("+{:?}", self.protocol_set);
|
||||||
}
|
}
|
||||||
if let Some(at) = self.address_type {
|
if self.address_set != AddressTypeSet::all() {
|
||||||
out += &format!("+{:?}", at);
|
out += &format!("+{:?}", self.address_set);
|
||||||
}
|
}
|
||||||
write!(f, "[{}]", out)
|
write!(f, "[{}]", out)
|
||||||
}
|
}
|
||||||
@ -1107,28 +1140,39 @@ impl DialInfo {
|
|||||||
let port = socket_address.port();
|
let port = socket_address.port();
|
||||||
(address.is_global() || address.is_local()) && port > 0
|
(address.is_global() || address.is_local()) && port > 0
|
||||||
}
|
}
|
||||||
pub fn matches_peer_scope(&self, scope: PeerScope) -> bool {
|
pub fn peer_scope(&self) -> Option<PeerScope> {
|
||||||
match scope {
|
let addr = self.socket_address().address();
|
||||||
PeerScope::All => true,
|
if addr.is_global() {
|
||||||
PeerScope::Global => self.is_global(),
|
return Some(PeerScope::Global);
|
||||||
PeerScope::Local => self.is_local(),
|
}
|
||||||
|
if addr.is_local() {
|
||||||
|
return Some(PeerScope::Local);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
pub fn matches_peer_scope(&self, scope: PeerScopeSet) -> bool {
|
||||||
|
if let Some(ps) = self.peer_scope() {
|
||||||
|
scope.contains(ps)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_filter(&self, scoped: bool) -> DialInfoFilter {
|
pub fn make_filter(&self, scoped: bool) -> DialInfoFilter {
|
||||||
DialInfoFilter {
|
DialInfoFilter {
|
||||||
peer_scope: if scoped {
|
peer_scope_set: if scoped {
|
||||||
if self.is_global() {
|
if self.is_global() {
|
||||||
PeerScope::Global
|
PeerScopeSet::only(PeerScope::Global)
|
||||||
} else if self.is_local() {
|
} else if self.is_local() {
|
||||||
PeerScope::Local
|
PeerScopeSet::only(PeerScope::Local)
|
||||||
} else {
|
} else {
|
||||||
PeerScope::All
|
PeerScopeSet::empty()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PeerScope::All
|
PeerScopeSet::all()
|
||||||
},
|
},
|
||||||
protocol_set: ProtocolSet::only(self.protocol_type()),
|
protocol_set: ProtocolTypeSet::only(self.protocol_type()),
|
||||||
address_type: Some(self.address_type()),
|
address_set: AddressTypeSet::only(self.address_type()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1313,16 +1357,14 @@ impl DialInfo {
|
|||||||
|
|
||||||
impl MatchesDialInfoFilter for DialInfo {
|
impl MatchesDialInfoFilter for DialInfo {
|
||||||
fn matches_filter(&self, filter: &DialInfoFilter) -> bool {
|
fn matches_filter(&self, filter: &DialInfoFilter) -> bool {
|
||||||
if !self.matches_peer_scope(filter.peer_scope) {
|
if !self.matches_peer_scope(filter.peer_scope_set) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if !filter.protocol_set.contains(self.protocol_type()) {
|
if !filter.protocol_set.contains(self.protocol_type()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if let Some(at) = filter.address_type {
|
if !filter.address_set.contains(self.address_type()) {
|
||||||
if self.address_type() != at {
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -1330,18 +1372,6 @@ impl MatchesDialInfoFilter for DialInfo {
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
|
|
||||||
pub enum PeerScope {
|
|
||||||
All,
|
|
||||||
Global,
|
|
||||||
Local,
|
|
||||||
}
|
|
||||||
impl Default for PeerScope {
|
|
||||||
fn default() -> Self {
|
|
||||||
PeerScope::All
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signed NodeInfo that can be passed around amongst peers and verifiable
|
// Signed NodeInfo that can be passed around amongst peers and verifiable
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct SignedNodeInfo {
|
pub struct SignedNodeInfo {
|
||||||
@ -1487,27 +1517,35 @@ impl ConnectionDescriptor {
|
|||||||
pub fn address_type(&self) -> AddressType {
|
pub fn address_type(&self) -> AddressType {
|
||||||
self.remote.address_type()
|
self.remote.address_type()
|
||||||
}
|
}
|
||||||
pub fn matches_peer_scope(&self, scope: PeerScope) -> bool {
|
pub fn peer_scope(&self) -> Option<PeerScope> {
|
||||||
match scope {
|
let addr = self.remote.socket_address.address();
|
||||||
PeerScope::All => true,
|
if addr.is_global() {
|
||||||
PeerScope::Global => self.remote.socket_address.address().is_global(),
|
return Some(PeerScope::Global);
|
||||||
PeerScope::Local => self.remote.socket_address.address().is_local(),
|
}
|
||||||
|
if addr.is_local() {
|
||||||
|
return Some(PeerScope::Local);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
pub fn matches_peer_scope(&self, scope: PeerScopeSet) -> bool {
|
||||||
|
if let Some(ps) = self.peer_scope() {
|
||||||
|
scope.contains(ps)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MatchesDialInfoFilter for ConnectionDescriptor {
|
impl MatchesDialInfoFilter for ConnectionDescriptor {
|
||||||
fn matches_filter(&self, filter: &DialInfoFilter) -> bool {
|
fn matches_filter(&self, filter: &DialInfoFilter) -> bool {
|
||||||
if !self.matches_peer_scope(filter.peer_scope) {
|
if !self.matches_peer_scope(filter.peer_scope_set) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if !filter.protocol_set.contains(self.protocol_type()) {
|
if !filter.protocol_set.contains(self.protocol_type()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if let Some(at) = filter.address_type {
|
if !filter.address_set.contains(self.address_type()) {
|
||||||
if self.address_type() != at {
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user