summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mullvad-cli/src/cmds/status.rs170
-rw-r--r--mullvad-cli/src/format.rs162
2 files changed, 165 insertions, 167 deletions
diff --git a/mullvad-cli/src/cmds/status.rs b/mullvad-cli/src/cmds/status.rs
index b0c4d40ad0..76a4ed2e67 100644
--- a/mullvad-cli/src/cmds/status.rs
+++ b/mullvad-cli/src/cmds/status.rs
@@ -1,17 +1,7 @@
-use crate::{format::print_keygen_event, new_rpc_client, Command, Error, Result};
+use crate::{format, format::print_keygen_event, new_rpc_client, Command, Error, Result};
use mullvad_management_interface::{
- types::{
- daemon_event::Event as EventType,
- error_state::{
- firewall_policy_error::ErrorType as FirewallPolicyErrorType, Cause as ErrorStateCause,
- FirewallPolicyError, GenerationError,
- },
- ErrorState, ProxyType, TransportProtocol, TunnelEndpoint, TunnelState, TunnelType,
- },
- ManagementServiceClient,
+ types::daemon_event::Event as EventType, ManagementServiceClient,
};
-use mullvad_types::auth_failed::AuthFailed;
-use std::fmt::Write;
pub struct Status;
@@ -45,7 +35,7 @@ impl Command for Status {
let mut rpc = new_rpc_client().await?;
let state = rpc.get_tunnel_state(()).await?.into_inner();
- print_state(&state);
+ format::print_state(&state);
if matches.is_present("location") {
print_location(&mut rpc).await?;
}
@@ -58,7 +48,7 @@ impl Command for Status {
while let Some(event) = events.message().await? {
match event.event.unwrap() {
EventType::TunnelState(new_state) => {
- print_state(&new_state);
+ format::print_state(&new_state);
use mullvad_management_interface::types::tunnel_state::State::*;
match new_state.state.unwrap() {
Connected(..) | Disconnected(..) => {
@@ -98,151 +88,6 @@ impl Command for Status {
}
}
-fn print_state(state: &TunnelState) {
- use mullvad_management_interface::types::{tunnel_state, tunnel_state::State::*};
-
- print!("Tunnel status: ");
- match state.state.as_ref().unwrap() {
- Error(error) => print_error_state(error.error_state.as_ref().unwrap()),
- Connected(tunnel_state::Connected { relay_info }) => {
- let endpoint = relay_info
- .as_ref()
- .unwrap()
- .tunnel_endpoint
- .as_ref()
- .unwrap();
- println!("Connected to {}", format_endpoint(&endpoint));
- }
- Connecting(tunnel_state::Connecting { relay_info }) => {
- let endpoint = relay_info
- .as_ref()
- .unwrap()
- .tunnel_endpoint
- .as_ref()
- .unwrap();
- println!("Connecting to {}...", format_endpoint(&endpoint));
- }
- Disconnected(_) => println!("Disconnected"),
- Disconnecting(_) => println!("Disconnecting..."),
- }
-}
-
-fn format_endpoint(endpoint: &TunnelEndpoint) -> String {
- let mut out = format!(
- "{} {} over {}",
- match TunnelType::from_i32(endpoint.tunnel_type).expect("unknown tunnel protocol") {
- TunnelType::Wireguard => "WireGuard",
- TunnelType::Openvpn => "OpenVPN",
- },
- endpoint.address,
- format_protocol(
- TransportProtocol::from_i32(endpoint.protocol).expect("unknown transport protocol")
- ),
- );
-
- if let Some(ref proxy) = endpoint.proxy {
- write!(
- &mut out,
- " via {} {} over {}",
- match ProxyType::from_i32(proxy.proxy_type).expect("unknown proxy type") {
- ProxyType::Shadowsocks => "Shadowsocks",
- ProxyType::Custom => "custom bridge",
- },
- proxy.address,
- format_protocol(
- TransportProtocol::from_i32(proxy.protocol).expect("unknown transport protocol")
- ),
- )
- .unwrap();
- }
-
- out
-}
-
-fn print_error_state(error_state: &ErrorState) {
- if error_state.blocking_error.is_some() {
- eprintln!("Mullvad daemon failed to setup firewall rules!");
- eprintln!("Deamon cannot block traffic from flowing, non-local traffic will leak");
- }
-
- match ErrorStateCause::from_i32(error_state.cause) {
- Some(ErrorStateCause::AuthFailed) => {
- println!(
- "Blocked: {}",
- AuthFailed::from(error_state.auth_fail_reason.as_ref())
- );
- }
- #[cfg(target_os = "linux")]
- Some(ErrorStateCause::SetFirewallPolicyError) => {
- println!("Blocked: {}", error_state_to_string(error_state));
- println!("Your kernel might be terribly out of date or missing nftables");
- }
- _ => println!("Blocked: {}", error_state_to_string(error_state)),
- }
-}
-
-fn error_state_to_string(error_state: &ErrorState) -> String {
- use ErrorStateCause::*;
-
- let error_str = match ErrorStateCause::from_i32(error_state.cause).expect("unknown error cause")
- {
- AuthFailed => {
- return if error_state.auth_fail_reason.is_empty() {
- "Authentication with remote server failed".to_string()
- } else {
- format!(
- "Authentication with remote server failed: {}",
- error_state.auth_fail_reason
- )
- };
- }
- Ipv6Unavailable => "Failed to configure IPv6 because it's disabled in the platform",
- SetFirewallPolicyError => {
- return policy_error_to_string(error_state.policy_error.as_ref().unwrap())
- }
- SetDnsError => "Failed to set system DNS server",
- StartTunnelError => "Failed to start connection to remote server",
- TunnelParameterError => {
- return format!(
- "Failure to generate tunnel parameters: {}",
- tunnel_parameter_error_to_string(error_state.parameter_error)
- );
- }
- IsOffline => "This device is offline, no tunnels can be established",
- TapAdapterProblem => "A problem with the TAP adapter has been detected",
- #[cfg(target_os = "android")]
- VpnPermissionDenied => "The Android VPN permission was denied when creating the tunnel",
- #[cfg(not(target_os = "android"))]
- _ => unreachable!("unknown error cause"),
- };
-
- error_str.to_string()
-}
-
-fn tunnel_parameter_error_to_string(parameter_error: i32) -> &'static str {
- match GenerationError::from_i32(parameter_error).expect("unknown generation error") {
- GenerationError::NoMatchingRelay => "Failure to select a matching tunnel relay",
- GenerationError::NoMatchingBridgeRelay => "Failure to select a matching bridge relay",
- GenerationError::NoWireguardKey => "No wireguard key available",
- GenerationError::CustomTunnelHostResolutionError => {
- "Can't resolve hostname for custom tunnel host"
- }
- }
-}
-
-fn policy_error_to_string(policy_error: &FirewallPolicyError) -> String {
- let cause = match FirewallPolicyErrorType::from_i32(policy_error.r#type)
- .expect("unknown policy error")
- {
- FirewallPolicyErrorType::Generic => return "Failed to set firewall policy".to_string(),
- FirewallPolicyErrorType::Locked => format!(
- "An application prevented the firewall policy from being set: {} (pid {})",
- policy_error.lock_name, policy_error.lock_pid
- ),
- };
- format!("Failed to set firewall policy: {}", cause)
-}
-
async fn print_location(rpc: &mut ManagementServiceClient) -> Result<()> {
let location = rpc.get_current_location(()).await;
let location = match location {
@@ -278,10 +123,3 @@ async fn print_location(rpc: &mut ManagementServiceClient) -> Result<()> {
);
Ok(())
}
-
-fn format_protocol(protocol: TransportProtocol) -> &'static str {
- match protocol {
- TransportProtocol::Udp => "UDP",
- TransportProtocol::Tcp => "TCP",
- }
-}
diff --git a/mullvad-cli/src/format.rs b/mullvad-cli/src/format.rs
index 4f69d05317..92f6076e66 100644
--- a/mullvad-cli/src/format.rs
+++ b/mullvad-cli/src/format.rs
@@ -1,4 +1,14 @@
-use mullvad_management_interface::types::KeygenEvent;
+use mullvad_management_interface::types::{
+ error_state::{
+ firewall_policy_error::ErrorType as FirewallPolicyErrorType, Cause as ErrorStateCause,
+ FirewallPolicyError, GenerationError,
+ },
+ tunnel_state,
+ tunnel_state::State::*,
+ ErrorState, KeygenEvent, ProxyType, TransportProtocol, TunnelEndpoint, TunnelState, TunnelType,
+};
+use mullvad_types::auth_failed::AuthFailed;
+use std::fmt::Write;
pub fn print_keygen_event(key_event: &KeygenEvent) {
use mullvad_management_interface::types::keygen_event::KeygenEvent as EventType;
@@ -18,3 +28,153 @@ pub fn print_keygen_event(key_event: &KeygenEvent) {
}
}
}
+
+pub fn print_state(state: &TunnelState) {
+ print!("Tunnel status: ");
+ match state.state.as_ref().unwrap() {
+ Error(error) => print_error_state(error.error_state.as_ref().unwrap()),
+ Connected(tunnel_state::Connected { relay_info }) => {
+ let endpoint = relay_info
+ .as_ref()
+ .unwrap()
+ .tunnel_endpoint
+ .as_ref()
+ .unwrap();
+ println!("Connected to {}", format_endpoint(&endpoint));
+ }
+ Connecting(tunnel_state::Connecting { relay_info }) => {
+ let endpoint = relay_info
+ .as_ref()
+ .unwrap()
+ .tunnel_endpoint
+ .as_ref()
+ .unwrap();
+ println!("Connecting to {}...", format_endpoint(&endpoint));
+ }
+ Disconnected(_) => println!("Disconnected"),
+ Disconnecting(_) => println!("Disconnecting..."),
+ }
+}
+
+fn format_endpoint(endpoint: &TunnelEndpoint) -> String {
+ let mut out = format!(
+ "{} {} over {}",
+ match TunnelType::from_i32(endpoint.tunnel_type).expect("unknown tunnel protocol") {
+ TunnelType::Wireguard => "WireGuard",
+ TunnelType::Openvpn => "OpenVPN",
+ },
+ endpoint.address,
+ format_protocol(
+ TransportProtocol::from_i32(endpoint.protocol).expect("unknown transport protocol")
+ ),
+ );
+
+ if let Some(ref proxy) = endpoint.proxy {
+ write!(
+ &mut out,
+ " via {} {} over {}",
+ match ProxyType::from_i32(proxy.proxy_type).expect("unknown proxy type") {
+ ProxyType::Shadowsocks => "Shadowsocks",
+ ProxyType::Custom => "custom bridge",
+ },
+ proxy.address,
+ format_protocol(
+ TransportProtocol::from_i32(proxy.protocol).expect("unknown transport protocol")
+ ),
+ )
+ .unwrap();
+ }
+
+ out
+}
+
+fn print_error_state(error_state: &ErrorState) {
+ if error_state.blocking_error.is_some() {
+ eprintln!("Mullvad daemon failed to setup firewall rules!");
+ eprintln!("Deamon cannot block traffic from flowing, non-local traffic will leak");
+ }
+
+ match ErrorStateCause::from_i32(error_state.cause) {
+ Some(ErrorStateCause::AuthFailed) => {
+ println!(
+ "Blocked: {}",
+ AuthFailed::from(error_state.auth_fail_reason.as_ref())
+ );
+ }
+ #[cfg(target_os = "linux")]
+ Some(ErrorStateCause::SetFirewallPolicyError) => {
+ println!("Blocked: {}", error_state_to_string(error_state));
+ println!("Your kernel might be terribly out of date or missing nftables");
+ }
+ _ => println!("Blocked: {}", error_state_to_string(error_state)),
+ }
+}
+
+fn error_state_to_string(error_state: &ErrorState) -> String {
+ use ErrorStateCause::*;
+
+ let error_str = match ErrorStateCause::from_i32(error_state.cause).expect("unknown error cause")
+ {
+ AuthFailed => {
+ return if error_state.auth_fail_reason.is_empty() {
+ "Authentication with remote server failed".to_string()
+ } else {
+ format!(
+ "Authentication with remote server failed: {}",
+ error_state.auth_fail_reason
+ )
+ };
+ }
+ Ipv6Unavailable => "Failed to configure IPv6 because it's disabled in the platform",
+ SetFirewallPolicyError => {
+ return policy_error_to_string(error_state.policy_error.as_ref().unwrap())
+ }
+ SetDnsError => "Failed to set system DNS server",
+ StartTunnelError => "Failed to start connection to remote server",
+ TunnelParameterError => {
+ return format!(
+ "Failure to generate tunnel parameters: {}",
+ tunnel_parameter_error_to_string(error_state.parameter_error)
+ );
+ }
+ IsOffline => "This device is offline, no tunnels can be established",
+ TapAdapterProblem => "A problem with the TAP adapter has been detected",
+ #[cfg(target_os = "android")]
+ VpnPermissionDenied => "The Android VPN permission was denied when creating the tunnel",
+ #[cfg(not(target_os = "android"))]
+ _ => unreachable!("unknown error cause"),
+ };
+
+ error_str.to_string()
+}
+
+fn tunnel_parameter_error_to_string(parameter_error: i32) -> &'static str {
+ match GenerationError::from_i32(parameter_error).expect("unknown generation error") {
+ GenerationError::NoMatchingRelay => "Failure to select a matching tunnel relay",
+ GenerationError::NoMatchingBridgeRelay => "Failure to select a matching bridge relay",
+ GenerationError::NoWireguardKey => "No wireguard key available",
+ GenerationError::CustomTunnelHostResolutionError => {
+ "Can't resolve hostname for custom tunnel host"
+ }
+ }
+}
+
+fn policy_error_to_string(policy_error: &FirewallPolicyError) -> String {
+ let cause = match FirewallPolicyErrorType::from_i32(policy_error.r#type)
+ .expect("unknown policy error")
+ {
+ FirewallPolicyErrorType::Generic => return "Failed to set firewall policy".to_string(),
+ FirewallPolicyErrorType::Locked => format!(
+ "An application prevented the firewall policy from being set: {} (pid {})",
+ policy_error.lock_name, policy_error.lock_pid
+ ),
+ };
+ format!("Failed to set firewall policy: {}", cause)
+}
+
+fn format_protocol(protocol: TransportProtocol) -> &'static str {
+ match protocol {
+ TransportProtocol::Udp => "UDP",
+ TransportProtocol::Tcp => "TCP",
+ }
+}