Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions nym-vpn-app/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Show the picked gateway name the tunnel is connected to, when
connecting/connected and the selected node is a country
- Add QUIC mode and Domain-fronting (aka stealth API) settings options
- Add a new screen for gateway details

### Fixed

Expand Down
94 changes: 94 additions & 0 deletions nym-vpn-app/src-tauri/src/grpc/gateway.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::country::Country;

use anyhow::{Result, anyhow};
use nym_vpn_proto::proto as p;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -26,6 +27,46 @@ pub enum Score {
High,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, TS, Default)]
#[ts(export)]
#[serde(rename_all = "kebab-case")]
pub enum AsnType {
#[default]
Other,
Residential,
}

#[derive(Serialize, Deserialize, Clone, Debug, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct Asn {
pub asn: String,
pub name: String,
#[serde(rename = "type")]
pub kind: AsnType,
}

#[derive(Serialize, Deserialize, Clone, Debug, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct Location {
pub latitude: f64,
pub longitude: f64,
pub city: String,
pub region: String,
}

#[derive(Serialize, Deserialize, Clone, Debug, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct Performance {
pub score: Score,
pub load: Score,
pub last_updated_utc: String,
/// uptime percentage on the last 24 hours
pub uptime_24h: f32,
}

#[derive(Serialize, Deserialize, Clone, Debug, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
Expand All @@ -35,8 +76,14 @@ pub struct Gateway {
pub kind: GatewayType,
pub name: String,
pub country: Country,
pub location: Location,
pub asn: Option<Asn>,
pub mx_score: Score,
pub wg_score: Score,
pub wg_performance: Option<Performance>,
pub exit_ipv4: Option<String>,
pub exit_ipv6: Option<String>,
pub build_version: Option<String>,
}

impl Gateway {
Expand All @@ -62,20 +109,31 @@ impl Gateway {

let wg_score = gateway
.wg_performance
.as_ref()
.map(|s| {
p::Score::try_from(s.score)
.inspect_err(|e| error!("failed to parse proto gw wireguard score: {}", e))
})
.transpose()?
.unwrap_or(p::Score::Offline);

let asn = location.asn.clone().map(|a| a.into());
let exit_ipv4 = gateway.exit_ipv4s.first().cloned();
let exit_ipv6 = gateway.exit_ipv6s.first().cloned();

Ok(Self {
id: id.id,
kind: gw_type,
name: gateway.moniker,
country: Country::try_from(&location)?,
location: location.into(),
asn,
mx_score: Score::from(mx_score),
wg_score: Score::from(wg_score),
wg_performance: gateway.wg_performance.map(|p| p.into()),
exit_ipv4,
exit_ipv6,
build_version: gateway.build_version,
})
}
}
Expand Down Expand Up @@ -111,6 +169,42 @@ impl From<GatewayType> for p::GatewayType {
}
}

impl From<p::RichLocation> for Location {
fn from(proto: p::RichLocation) -> Self {
Location {
latitude: proto.latitude,
longitude: proto.longitude,
city: proto.city,
region: proto.region,
}
}
}

impl From<p::Asn> for Asn {
fn from(proto: p::Asn) -> Self {
let asn_kind = &proto.kind();
Asn {
asn: proto.asn,
name: proto.name,
kind: match asn_kind {
p::AsnKind::Residential => AsnType::Residential,
p::AsnKind::Other => AsnType::Other,
},
}
}
}

impl From<p::Performance> for Performance {
fn from(proto: p::Performance) -> Self {
Performance {
score: Score::from(proto.score()),
load: Score::from(proto.load()),
last_updated_utc: proto.last_updated_utc,
uptime_24h: proto.uptime_percentage_last_24_hours,
}
}
}

impl fmt::Display for Gateway {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}] ({}) {}", self.id, self.name, self.country)
Expand Down
1 change: 1 addition & 0 deletions nym-vpn-app/src-tauri/src/grpc/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::country::Country;
#[serde(rename_all = "lowercase")]
#[serde(untagged)]
#[ts(export)]
#[allow(clippy::large_enum_variant)]
pub enum NodeConnect {
Country(Country),
Gateway(Gateway),
Expand Down
4 changes: 4 additions & 0 deletions nym-vpn-app/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,7 @@ export const SentryPrivacyPolicyUrl = 'https://sentry.io/privacy/';
export const AnonNetworkStatsUrl = 'https://nym.com/anonymous-stats';
export const QuicUrl = 'https://nym.com/features/quic';
export const DomainFrontingUrl = 'https://nym.com/features/stealth-api-connect';
export const IpInfoIoUrl = 'https://ipinfo.io';
export const SupportServerLocationUrl =
'https://support.nym.com/hc/en-us/articles/26448676449297-How-is-server-location-determined-by-NymVPN';
export const NetworkExplorerNodeUrl = 'https://nym.com/explorer/nym-node';
Loading