Skip to content

Commit

Permalink
Merge pull request #326 from nymtech/jon/pass-entry-gateway-in-connect
Browse files Browse the repository at this point in the history
Support connect arguments
  • Loading branch information
octol authored Apr 24, 2024
2 parents 3b481ee + 594e03a commit 8f62866
Show file tree
Hide file tree
Showing 14 changed files with 555 additions and 155 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion crates/nym-gateway-directory/src/entries/entry_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ pub enum EntryPoint {
// An explicit entry gateway identity.
Gateway { identity: NodeIdentity },
// Select a random entry gateway in a specific location.
// NOTE: Consider using a crate with strongly typed country codes instead of strings
Location { location: String },
// Select a random entry gateway but increasey probability of selecting a low latency gateway
// as determined by ping times.
Expand Down
3 changes: 2 additions & 1 deletion nym-vpn-cli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,11 @@ pub(crate) struct CliExit {
#[clap(long, alias = "exit-address")]
pub(crate) exit_router_address: Option<String>,

/// Mixnet public ID of the exit gateway.
#[clap(long, alias = "exit-id")]
pub(crate) exit_gateway_id: Option<String>,

/// Mixnet recipient address.
/// Auto-select exit gateway by country ISO.
#[clap(long, alias = "exit-country")]
pub(crate) exit_gateway_country: Option<String>,
}
Expand Down
1 change: 1 addition & 0 deletions nym-vpnc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ tokio = { workspace = true, features = ["macros", "rt-multi-thread"]}
tonic.workspace = true
tower.workspace = true

nym-gateway-directory = { path = "../crates/nym-gateway-directory" }
nym-vpn-proto = { path = "../crates/nym-vpn-proto" }

[build-dependencies]
Expand Down
177 changes: 177 additions & 0 deletions nym-vpnc/src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
// Copyright 2024 - Nym Technologies SA <[email protected]>
// SPDX-License-Identifier: Apache-2.0

use anyhow::{anyhow, Result};
use clap::{Args, Parser, Subcommand};
use nym_gateway_directory::{EntryPoint, ExitPoint, NodeIdentity, Recipient};
use std::path::PathBuf;

#[derive(Parser)]
#[clap(author = "Nymtech", version, about)]
pub(crate) struct CliArgs {
/// Use HTTP instead of socket file for IPC with the daemon.
#[arg(long)]
pub(crate) http: bool,

#[command(subcommand)]
pub(crate) command: Command,
}

#[derive(Subcommand)]
pub(crate) enum Command {
Connect(ConnectArgs),
Disconnect,
Status,
ImportCredential(ImportCredentialArgs),
}

#[derive(Args)]
pub(crate) struct ConnectArgs {
#[command(flatten)]
pub(crate) entry: CliEntry,

#[command(flatten)]
pub(crate) exit: CliExit,

/// Disable routing all traffic through the nym TUN device. When the flag is set, the nym TUN
/// device will be created, but to route traffic through it you will need to do it manually,
/// e.g. ping -Itun0.
#[arg(long)]
pub(crate) disable_routing: bool,

/// Enable two-hop mixnet traffic. This means that traffic jumps directly from entry gateway to
/// exit gateway.
#[arg(long)]
pub(crate) enable_two_hop: bool,

/// Enable Poisson process rate limiting of outbound traffic.
#[arg(long)]
pub(crate) enable_poisson_rate: bool,

/// Disable constant rate background loop cover traffic.
#[arg(long)]
pub(crate) disable_background_cover_traffic: bool,

/// Enable credentials mode.
#[arg(long)]
pub(crate) enable_credentials_mode: bool,
}

#[derive(Args)]
#[group(multiple = false)]
pub(crate) struct CliEntry {
/// Mixnet public ID of the entry gateway.
#[clap(long, alias = "entry-id")]
pub(crate) entry_gateway_id: Option<String>,

/// Auto-select entry gateway by country ISO.
#[clap(long, alias = "entry-country")]
pub(crate) entry_gateway_country: Option<String>,

/// Auto-select entry gateway by latency
#[clap(long, alias = "entry-fastest")]
pub(crate) entry_gateway_low_latency: bool,

/// Auto-select entry gateway randomly.
#[clap(long, alias = "entry-random")]
pub(crate) entry_gateway_random: bool,
}

#[derive(Args)]
#[group(multiple = false)]
pub(crate) struct CliExit {
/// Mixnet recipient address.
#[clap(long, alias = "exit-address")]
pub(crate) exit_router_address: Option<String>,

/// Mixnet public ID of the exit gateway.
#[clap(long, alias = "exit-id")]
pub(crate) exit_gateway_id: Option<String>,

/// Auto-select exit gateway by country ISO.
#[clap(long, alias = "exit-country")]
pub(crate) exit_gateway_country: Option<String>,

/// Auto-select exit gateway randomly.
#[clap(long, alias = "exit-random")]
pub(crate) exit_gateway_random: bool,
}

#[derive(Args)]
pub(crate) struct ImportCredentialArgs {
#[command(flatten)]
pub(crate) credential_type: ImportCredentialType,

// currently hidden as there exists only a single serialization standard
#[arg(long, hide = true)]
pub(crate) version: Option<u8>,
}

#[derive(Args, Clone)]
#[group(required = true, multiple = false)]
pub(crate) struct ImportCredentialType {
/// Credential encoded using base58.
#[arg(long)]
pub(crate) credential_data: Option<String>,

/// Path to the credential file.
#[arg(long)]
pub(crate) credential_path: Option<PathBuf>,
}

// Workaround until clap supports enums for ArgGroups
pub(crate) enum ImportCredentialTypeEnum {
Path(PathBuf),
Data(String),
}

impl From<ImportCredentialType> for ImportCredentialTypeEnum {
fn from(ict: ImportCredentialType) -> Self {
match (ict.credential_data, ict.credential_path) {
(Some(data), None) => ImportCredentialTypeEnum::Data(data),
(None, Some(path)) => ImportCredentialTypeEnum::Path(path),
_ => unreachable!(),
}
}
}

pub(crate) fn parse_entry_point(args: &ConnectArgs) -> Result<Option<EntryPoint>> {
if let Some(ref entry_gateway_id) = args.entry.entry_gateway_id {
Ok(Some(EntryPoint::Gateway {
identity: NodeIdentity::from_base58_string(entry_gateway_id.clone())
.map_err(|_| anyhow!("Failed to parse gateway id"))?,
}))
} else if let Some(ref entry_gateway_country) = args.entry.entry_gateway_country {
Ok(Some(EntryPoint::Location {
location: entry_gateway_country.clone(),
}))
} else if args.entry.entry_gateway_low_latency {
Ok(Some(EntryPoint::RandomLowLatency))
} else if args.entry.entry_gateway_random {
Ok(Some(EntryPoint::Random))
} else {
Ok(None)
}
}

pub(crate) fn parse_exit_point(args: &ConnectArgs) -> Result<Option<ExitPoint>> {
if let Some(ref exit_router_address) = args.exit.exit_router_address {
Ok(Some(ExitPoint::Address {
address: Recipient::try_from_base58_string(exit_router_address.clone())
.map_err(|_| anyhow!("Failed to parse exit node address"))?,
}))
} else if let Some(ref exit_router_id) = args.exit.exit_gateway_id {
Ok(Some(ExitPoint::Gateway {
identity: NodeIdentity::from_base58_string(exit_router_id.clone())
.map_err(|_| anyhow!("Failed to parse gateway id"))?,
}))
} else if let Some(ref exit_gateway_country) = args.exit.exit_gateway_country {
Ok(Some(ExitPoint::Location {
location: exit_gateway_country.clone(),
}))
} else if args.exit.exit_gateway_random {
Ok(Some(ExitPoint::Random))
} else {
Ok(None)
}
}
12 changes: 12 additions & 0 deletions nym-vpnc/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright 2024 - Nym Technologies SA <[email protected]>
// SPDX-License-Identifier: Apache-2.0

use std::path::{Path, PathBuf};

pub(crate) fn get_socket_path() -> PathBuf {
Path::new("/var/run/nym-vpn.sock").to_path_buf()
}

pub(crate) fn default_endpoint() -> String {
"http://[::1]:53181".to_string()
}
Loading

0 comments on commit 8f62866

Please sign in to comment.