summaryrefslogtreecommitdiffhomepage
path: root/mullvad-cli/src
diff options
context:
space:
mode:
authorJoakim Hulthe <joakim@hulthe.net>2024-07-09 11:10:08 +0200
committerMarkus Pettersson <markus.pettersson@mullvad.net>2024-08-01 15:27:02 +0200
commit7992055557e32fdbed2f8267ae6fb1b57ed9c1d8 (patch)
tree7b5c505570d2f64221ddc5a89f53593f4569492f /mullvad-cli/src
parent2b59f823d60de3063fa6b1c3da206d198f6218d0 (diff)
downloadmullvadvpn-7992055557e32fdbed2f8267ae6fb1b57ed9c1d8.tar.xz
mullvadvpn-7992055557e32fdbed2f8267ae6fb1b57ed9c1d8.zip
Implement feature indicators in daemon
- Add a GetFeatureIndicators gRPC call that get's the current set of active "features" that should be shown in the UI. - Extend the TunnelState with a FeatureIndicators value. Clients who listens for TunnelState events will get updates automatically.
Diffstat (limited to 'mullvad-cli/src')
-rw-r--r--mullvad-cli/src/cmds/status.rs12
-rw-r--r--mullvad-cli/src/format.rs54
2 files changed, 37 insertions, 29 deletions
diff --git a/mullvad-cli/src/cmds/status.rs b/mullvad-cli/src/cmds/status.rs
index 939beeca4a..96631d02d0 100644
--- a/mullvad-cli/src/cmds/status.rs
+++ b/mullvad-cli/src/cmds/status.rs
@@ -54,9 +54,15 @@ impl Status {
// Do print an updated state if the lockdown setting was changed
) if was_locked_down == locked_down => continue,
(
- Some(TunnelState::Connected { .. }),
- TunnelState::Connected { .. },
- ) => continue,
+ Some(TunnelState::Connected {
+ feature_indicators: old_feature_indicators,
+ ..
+ }),
+ TunnelState::Connected {
+ feature_indicators, ..
+ },
+ // Do print an updated state if the feature indicators changed
+ ) if old_feature_indicators == feature_indicators => continue,
_ => {}
}
format::print_state(&new_state, args.verbose);
diff --git a/mullvad-cli/src/format.rs b/mullvad-cli/src/format.rs
index 8660683919..63395ea87a 100644
--- a/mullvad-cli/src/format.rs
+++ b/mullvad-cli/src/format.rs
@@ -1,4 +1,8 @@
-use mullvad_types::{auth_failed::AuthFailed, location::GeoIpLocation, states::TunnelState};
+use itertools::Itertools;
+use mullvad_types::{
+ auth_failed::AuthFailed, features::FeatureIndicators, location::GeoIpLocation,
+ states::TunnelState,
+};
use talpid_types::{
net::{Endpoint, TunnelEndpoint},
tunnel::ErrorState,
@@ -19,18 +23,30 @@ pub fn print_state(state: &TunnelState, verbose: bool) {
match state {
Error(error) => print_error_state(error),
- Connected { endpoint, location } => {
+ Connected {
+ endpoint,
+ location,
+ feature_indicators,
+ } => {
println!(
"Connected to {}",
format_relay_connection(endpoint, location.as_ref(), verbose)
);
if verbose {
+ println!(
+ "Active features: {}",
+ format_feature_indicators(feature_indicators)
+ );
if let Some(tunnel_interface) = &endpoint.tunnel_interface {
println!("Tunnel interface: {tunnel_interface}")
}
}
}
- Connecting { endpoint, location } => {
+ Connecting {
+ endpoint,
+ location,
+ feature_indicators: _,
+ } => {
let ellipsis = if !verbose { "..." } else { "" };
println!(
"Connecting to {}{ellipsis}",
@@ -166,44 +182,30 @@ fn format_relay_connection(
} else {
String::new()
};
- let quantum_resistant = if !verbose {
- ""
- } else if endpoint.quantum_resistant {
- "\nQuantum resistant tunnel: yes"
- } else {
- "\nQuantum resistant tunnel: no"
- };
-
- #[cfg(daita)]
- let daita = if !verbose {
- ""
- } else if endpoint.daita {
- "\nDAITA: yes"
- } else {
- "\nDAITA: no"
- };
- #[cfg(not(daita))]
- let daita = "";
let mut bridge_type = String::new();
- let mut obfuscator_type = String::new();
if verbose {
if let Some(bridge) = &endpoint.proxy {
bridge_type = format!("\nBridge type: {}", bridge.proxy_type);
}
- if let Some(obfuscator) = &endpoint.obfuscation {
- obfuscator_type = format!("\nObfuscator: {}", obfuscator.obfuscation_type);
- }
}
format!(
- "{exit_endpoint}{first_hop}{bridge}{obfuscator}{tunnel_type}{quantum_resistant}{daita}{bridge_type}{obfuscator_type}",
+ "{exit_endpoint}{first_hop}{bridge}{obfuscator}{tunnel_type}{bridge_type}",
first_hop = first_hop.unwrap_or_default(),
bridge = bridge.unwrap_or_default(),
obfuscator = obfuscator.unwrap_or_default(),
)
}
+fn format_feature_indicators(feature_indicators: &FeatureIndicators) -> String {
+ feature_indicators
+ .active_features()
+ // Sort the features alphabetically (Just to have some order, arbitrarily chosen)
+ .sorted_by_key(|feature| feature.to_string())
+ .join(", ")
+}
+
fn format_endpoint(hostname: Option<&str>, endpoint: &Endpoint, verbose: bool) -> String {
match (hostname, verbose) {
(Some(hostname), true) => format!("{hostname} ({endpoint})"),