mirror of
https://gitlab.com/veilid/veilid.git
synced 2025-01-13 00:09:47 -05:00
fix contact method for nodes on the same ipblock
This commit is contained in:
parent
b3c7c93f97
commit
7c7ea4e3c7
@ -15,11 +15,6 @@ impl Default for NetworkClass {
|
||||
}
|
||||
|
||||
impl NetworkClass {
|
||||
// Must an inbound relay be kept available?
|
||||
// In the case of InboundCapable, it is left up to the class of each DialInfo to determine if an inbound relay is required
|
||||
pub fn inbound_wants_relay(&self) -> bool {
|
||||
matches!(self, Self::OutboundOnly | Self::WebApp)
|
||||
}
|
||||
// Should an outbound relay be kept available?
|
||||
pub fn outbound_wants_relay(&self) -> bool {
|
||||
matches!(self, Self::WebApp)
|
||||
|
@ -319,17 +319,27 @@ impl RoutingDomainDetail for PublicInternetRoutingDomainDetail {
|
||||
}
|
||||
fn get_contact_method(
|
||||
&self,
|
||||
_rti: &RoutingTableInner,
|
||||
rti: &RoutingTableInner,
|
||||
peer_a: &PeerInfo,
|
||||
peer_b: &PeerInfo,
|
||||
dial_info_filter: DialInfoFilter,
|
||||
sequencing: Sequencing,
|
||||
dif_sort: Option<Arc<DialInfoDetailSort>>,
|
||||
) -> ContactMethod {
|
||||
let ip6_prefix_size = rti
|
||||
.unlocked_inner
|
||||
.config
|
||||
.get()
|
||||
.network
|
||||
.max_connections_per_ip6_prefix_size as usize;
|
||||
|
||||
// Get the nodeinfos for convenience
|
||||
let node_a = peer_a.signed_node_info().node_info();
|
||||
let node_b = peer_b.signed_node_info().node_info();
|
||||
|
||||
// Check to see if these nodes are on the same network
|
||||
let same_ipblock = node_a.node_is_on_same_ipblock(node_b, ip6_prefix_size);
|
||||
|
||||
// Get the node ids that would be used between these peers
|
||||
let cck = common_crypto_kinds(&peer_a.node_ids().kinds(), &peer_b.node_ids().kinds());
|
||||
let Some(best_ck) = cck.first().copied() else {
|
||||
@ -341,13 +351,20 @@ impl RoutingDomainDetail for PublicInternetRoutingDomainDetail {
|
||||
let node_b_id = peer_b.node_ids().get(best_ck).unwrap();
|
||||
|
||||
// Get the best match dial info for node B if we have it
|
||||
if let Some(target_did) = first_filtered_dial_info_detail_between_nodes(
|
||||
node_a,
|
||||
node_b,
|
||||
&dial_info_filter,
|
||||
sequencing,
|
||||
dif_sort.clone(),
|
||||
) {
|
||||
// Don't try direct inbound at all if the two nodes are on the same ipblock to avoid hairpin NAT issues
|
||||
// as well avoiding direct traffic between same-network nodes. This would be done in the LocalNetwork RoutingDomain.
|
||||
if let Some(target_did) = (!same_ipblock)
|
||||
.then(|| {
|
||||
first_filtered_dial_info_detail_between_nodes(
|
||||
node_a,
|
||||
node_b,
|
||||
&dial_info_filter,
|
||||
sequencing,
|
||||
dif_sort.clone(),
|
||||
)
|
||||
})
|
||||
.flatten()
|
||||
{
|
||||
// Do we need to signal before going inbound?
|
||||
if !target_did.class.requires_signal() {
|
||||
// Go direct without signaling
|
||||
@ -449,7 +466,7 @@ impl RoutingDomainDetail for PublicInternetRoutingDomainDetail {
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the node B has no direct dial info, it needs to have an inbound relay
|
||||
// If the node B has no direct dial info or is on the same ipblock, it needs to have an inbound relay
|
||||
else if let Some(node_b_relay) = peer_b.signed_node_info().relay_info() {
|
||||
// Note that relay_peer_info could be node_a, in which case a connection already exists
|
||||
// and we only get here if the connection had dropped, in which case node_b is unreachable until
|
||||
@ -481,13 +498,19 @@ impl RoutingDomainDetail for PublicInternetRoutingDomainDetail {
|
||||
///////// Reverse connection
|
||||
|
||||
// Get the best match dial info for an reverse inbound connection from node B to node A
|
||||
if let Some(reverse_did) = first_filtered_dial_info_detail_between_nodes(
|
||||
node_b,
|
||||
node_a,
|
||||
&dial_info_filter,
|
||||
sequencing,
|
||||
dif_sort.clone(),
|
||||
) {
|
||||
// unless both nodes are on the same ipblock
|
||||
if let Some(reverse_did) = (!same_ipblock)
|
||||
.then(|| {
|
||||
first_filtered_dial_info_detail_between_nodes(
|
||||
node_b,
|
||||
node_a,
|
||||
&dial_info_filter,
|
||||
sequencing,
|
||||
dif_sort.clone(),
|
||||
)
|
||||
})
|
||||
.flatten()
|
||||
{
|
||||
// Can we receive a direct reverse connection?
|
||||
if !reverse_did.class.requires_signal() {
|
||||
return ContactMethod::SignalReverse(node_b_relay_id, node_b_id);
|
||||
|
@ -146,7 +146,11 @@ impl RoutingTable {
|
||||
// Get all our outbound protocol/address types
|
||||
let outbound_dif = self.get_outbound_dial_info_filter(RoutingDomain::PublicInternet);
|
||||
let mapped_port_info = self.get_low_level_port_info();
|
||||
|
||||
let own_node_info = self
|
||||
.get_own_peer_info(RoutingDomain::PublicInternet)
|
||||
.signed_node_info()
|
||||
.node_info()
|
||||
.clone();
|
||||
let ip6_prefix_size = self
|
||||
.unlocked_inner
|
||||
.config
|
||||
@ -154,15 +158,6 @@ impl RoutingTable {
|
||||
.network
|
||||
.max_connections_per_ip6_prefix_size as usize;
|
||||
|
||||
let our_ip_blocks = self
|
||||
.get_own_peer_info(RoutingDomain::PublicInternet)
|
||||
.signed_node_info()
|
||||
.node_info()
|
||||
.dial_info_detail_list()
|
||||
.iter()
|
||||
.map(|did| ip_to_ipblock(ip6_prefix_size, did.dial_info.to_socket_addr().ip()))
|
||||
.collect::<HashSet<_>>();
|
||||
|
||||
move |e: &BucketEntryInner| {
|
||||
// Ensure this node is not on the local network and is on the public internet
|
||||
if e.has_node_info(RoutingDomain::LocalNetwork.into()) {
|
||||
@ -215,11 +210,8 @@ impl RoutingTable {
|
||||
}
|
||||
|
||||
// Exclude any nodes that have our same network block
|
||||
for did in dids {
|
||||
let ipblock = ip_to_ipblock(ip6_prefix_size, did.dial_info.to_socket_addr().ip());
|
||||
if our_ip_blocks.contains(&ipblock) {
|
||||
return false;
|
||||
}
|
||||
if own_node_info.node_is_on_same_ipblock(node_info, ip6_prefix_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
|
@ -175,4 +175,21 @@ impl NodeInfo {
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Does this appear on the same network within the routing domain
|
||||
pub fn node_is_on_same_ipblock(&self, node_b: &NodeInfo, ip6_prefix_size: usize) -> bool {
|
||||
let our_ip_blocks = self
|
||||
.dial_info_detail_list()
|
||||
.iter()
|
||||
.map(|did| ip_to_ipblock(ip6_prefix_size, did.dial_info.to_socket_addr().ip()))
|
||||
.collect::<HashSet<_>>();
|
||||
|
||||
for did in node_b.dial_info_detail_list() {
|
||||
let ipblock = ip_to_ipblock(ip6_prefix_size, did.dial_info.to_socket_addr().ip());
|
||||
if our_ip_blocks.contains(&ipblock) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user