mirror of
https://gitlab.com/veilid/veilid.git
synced 2025-03-12 17:06:37 -04:00
Merge branch 'fix-geolocation-after-refactor' into 'main'
Fix geolocation feature after recent refactor See merge request veilid/veilid!355
This commit is contained in:
commit
8de19e0d26
@ -235,6 +235,11 @@ impl RouteSpecStore {
|
|||||||
.relay_node(RoutingDomain::PublicInternet)
|
.relay_node(RoutingDomain::PublicInternet)
|
||||||
.map(|nr| nr.locked(rti));
|
.map(|nr| nr.locked(rti));
|
||||||
|
|
||||||
|
#[cfg(feature = "geolocation")]
|
||||||
|
let country_code_denylist = self
|
||||||
|
.config()
|
||||||
|
.with(|config| config.network.privacy.country_code_denylist.clone());
|
||||||
|
|
||||||
// Get list of all nodes, and sort them for selection
|
// Get list of all nodes, and sort them for selection
|
||||||
let cur_ts = Timestamp::now();
|
let cur_ts = Timestamp::now();
|
||||||
let filter = Box::new(
|
let filter = Box::new(
|
||||||
@ -277,78 +282,66 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// Exclude nodes from blacklisted countries
|
// Exclude nodes from blacklisted countries
|
||||||
#[cfg(feature = "geolocation")]
|
#[cfg(feature = "geolocation")]
|
||||||
{
|
if !country_code_denylist.is_empty() {
|
||||||
let country_code_denylist = self
|
let geolocation_info =
|
||||||
.unlocked_inner
|
sni.get_geolocation_info(RoutingDomain::PublicInternet);
|
||||||
.routing_table
|
|
||||||
.config
|
|
||||||
.get()
|
|
||||||
.network
|
|
||||||
.privacy
|
|
||||||
.country_code_denylist
|
|
||||||
.clone();
|
|
||||||
|
|
||||||
if !country_code_denylist.is_empty() {
|
// Since denylist is used, consider nodes with unknown countries to be automatically
|
||||||
let geolocation_info =
|
// excluded as well
|
||||||
sni.get_geolocation_info(RoutingDomain::PublicInternet);
|
if geolocation_info.country_code().is_none() {
|
||||||
|
veilid_log!(self
|
||||||
|
debug "allocate_route_inner: skipping node {} from unknown country",
|
||||||
|
e.best_node_id()
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Same thing applies to relays used by the node
|
||||||
|
if geolocation_info
|
||||||
|
.relay_country_codes()
|
||||||
|
.iter()
|
||||||
|
.any(Option::is_none)
|
||||||
|
{
|
||||||
|
veilid_log!(self
|
||||||
|
debug "allocate_route_inner: skipping node {} using relay from unknown country",
|
||||||
|
e.best_node_id()
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Since denylist is used, consider nodes with unknown countries to be automatically
|
// Ensure that node is not excluded
|
||||||
// excluded as well
|
// Safe to unwrap here, checked above
|
||||||
if geolocation_info.country_code().is_none() {
|
if country_code_denylist.contains(&geolocation_info.country_code().unwrap())
|
||||||
veilid_log!(self
|
{
|
||||||
debug "allocate_route_inner: skipping node {} from unknown country",
|
veilid_log!(self
|
||||||
e.best_node_id()
|
debug "allocate_route_inner: skipping node {} from excluded country {}",
|
||||||
);
|
e.best_node_id(),
|
||||||
return false;
|
geolocation_info.country_code().unwrap()
|
||||||
}
|
);
|
||||||
// Same thing applies to relays used by the node
|
return false;
|
||||||
if geolocation_info
|
}
|
||||||
.relay_country_codes()
|
|
||||||
.iter()
|
|
||||||
.any(Option::is_none)
|
|
||||||
{
|
|
||||||
veilid_log!(self
|
|
||||||
debug "allocate_route_inner: skipping node {} using relay from unknown country",
|
|
||||||
e.best_node_id()
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure that node is not excluded
|
// Ensure that node relays are not excluded
|
||||||
// Safe to unwrap here, checked above
|
// Safe to unwrap here, checked above
|
||||||
if country_code_denylist.contains(&geolocation_info.country_code().unwrap())
|
if geolocation_info
|
||||||
{
|
.relay_country_codes()
|
||||||
veilid_log!(self
|
.iter()
|
||||||
debug "allocate_route_inner: skipping node {} from excluded country {}",
|
.cloned()
|
||||||
e.best_node_id(),
|
.map(Option::unwrap)
|
||||||
geolocation_info.country_code().unwrap()
|
.any(|cc| country_code_denylist.contains(&cc))
|
||||||
);
|
{
|
||||||
return false;
|
veilid_log!(self
|
||||||
}
|
debug "allocate_route_inner: skipping node {} using relay from excluded country {:?}",
|
||||||
|
e.best_node_id(),
|
||||||
// Ensure that node relays are not excluded
|
geolocation_info
|
||||||
// Safe to unwrap here, checked above
|
.relay_country_codes()
|
||||||
if geolocation_info
|
.iter()
|
||||||
.relay_country_codes()
|
.cloned()
|
||||||
.iter()
|
.map(Option::unwrap)
|
||||||
.cloned()
|
.filter(|cc| country_code_denylist.contains(&cc))
|
||||||
.map(Option::unwrap)
|
.next()
|
||||||
.any(|cc| country_code_denylist.contains(&cc))
|
.unwrap()
|
||||||
{
|
);
|
||||||
veilid_log!(self
|
return false;
|
||||||
debug "allocate_route_inner: skipping node {} using relay from excluded country {:?}",
|
|
||||||
e.best_node_id(),
|
|
||||||
geolocation_info
|
|
||||||
.relay_country_codes()
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(Option::unwrap)
|
|
||||||
.filter(|cc| country_code_denylist.contains(&cc))
|
|
||||||
.next()
|
|
||||||
.unwrap()
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ pub fn fix_veilidconfiginner() -> VeilidConfigInner {
|
|||||||
},
|
},
|
||||||
#[cfg(feature = "geolocation")]
|
#[cfg(feature = "geolocation")]
|
||||||
privacy: VeilidConfigPrivacy {
|
privacy: VeilidConfigPrivacy {
|
||||||
country_code_denylist: vec![CountryCode([b'N', b'Z'])],
|
country_code_denylist: vec![CountryCode::from_str("NZ").unwrap()],
|
||||||
},
|
},
|
||||||
#[cfg(feature = "virtual-network")]
|
#[cfg(feature = "virtual-network")]
|
||||||
virtual_network: VeilidConfigVirtualNetwork {
|
virtual_network: VeilidConfigVirtualNetwork {
|
||||||
|
@ -1,17 +1,12 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
|
|
||||||
/// Two-letter country code. Case-insensitive when comparing.
|
/// Two-letter country code. Stored in upper case internally.
|
||||||
#[derive(Copy, Default, Clone, Ord, Eq, Serialize, Deserialize, JsonSchema)]
|
#[derive(
|
||||||
|
Copy, Default, Clone, Hash, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize, JsonSchema,
|
||||||
|
)]
|
||||||
#[serde(try_from = "String")]
|
#[serde(try_from = "String")]
|
||||||
#[serde(into = "String")]
|
#[serde(into = "String")]
|
||||||
pub struct CountryCode(pub [u8; 2]);
|
pub struct CountryCode([u8; 2]);
|
||||||
|
|
||||||
impl From<[u8; 2]> for CountryCode {
|
|
||||||
fn from(b: [u8; 2]) -> Self {
|
|
||||||
Self(b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<CountryCode> for String {
|
impl From<CountryCode> for String {
|
||||||
fn from(u: CountryCode) -> Self {
|
fn from(u: CountryCode) -> Self {
|
||||||
@ -22,7 +17,18 @@ impl From<CountryCode> for String {
|
|||||||
impl TryFrom<&[u8]> for CountryCode {
|
impl TryFrom<&[u8]> for CountryCode {
|
||||||
type Error = VeilidAPIError;
|
type Error = VeilidAPIError;
|
||||||
fn try_from(b: &[u8]) -> Result<Self, Self::Error> {
|
fn try_from(b: &[u8]) -> Result<Self, Self::Error> {
|
||||||
Ok(Self(b.try_into().map_err(VeilidAPIError::generic)?))
|
let cc: [u8; 2] = b.try_into().map_err(VeilidAPIError::generic)?;
|
||||||
|
|
||||||
|
if !cc[0].is_ascii_alphabetic() || !cc[1].is_ascii_alphabetic() {
|
||||||
|
return Err(VeilidAPIError::generic(
|
||||||
|
"country code must only contain alphabetic chars",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self([
|
||||||
|
cc[0].to_ascii_uppercase(),
|
||||||
|
cc[1].to_ascii_uppercase(),
|
||||||
|
]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,55 +41,21 @@ impl TryFrom<String> for CountryCode {
|
|||||||
|
|
||||||
impl fmt::Display for CountryCode {
|
impl fmt::Display for CountryCode {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
write!(f, "{}", String::from_utf8_lossy(&self.0))
|
// self.0 is guaranteed to be a valid ASCII string, checked in Self::try_from(&[u8])
|
||||||
|
write!(f, "{}{}", self.0[0] as char, self.0[1] as char)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for CountryCode {
|
impl fmt::Debug for CountryCode {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
write!(f, "{}", String::from_utf8_lossy(&self.0))
|
<Self as fmt::Display>::fmt(self, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for CountryCode {
|
impl FromStr for CountryCode {
|
||||||
type Err = VeilidAPIError;
|
type Err = VeilidAPIError;
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
Ok(Self(
|
Ok(Self::try_from(s.as_bytes())?)
|
||||||
s.as_bytes().try_into().map_err(VeilidAPIError::generic)?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Hash for CountryCode {
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
let this = [
|
|
||||||
self.0[0].to_ascii_uppercase(),
|
|
||||||
self.0[1].to_ascii_uppercase(),
|
|
||||||
];
|
|
||||||
|
|
||||||
state.write(&this[..]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for CountryCode {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.0[0].to_ascii_uppercase() == other.0[0].to_ascii_uppercase()
|
|
||||||
&& self.0[1].to_ascii_uppercase() == other.0[1].to_ascii_uppercase()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialOrd for CountryCode {
|
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
|
|
||||||
let this = [
|
|
||||||
self.0[0].to_ascii_uppercase(),
|
|
||||||
self.0[1].to_ascii_uppercase(),
|
|
||||||
];
|
|
||||||
let other = [
|
|
||||||
other.0[0].to_ascii_uppercase(),
|
|
||||||
other.0[1].to_ascii_uppercase(),
|
|
||||||
];
|
|
||||||
|
|
||||||
this.partial_cmp(&other)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user