Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework the mullvad status listen command #6678

Merged
merged 3 commits into from
Sep 16, 2024
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Line wrap the file at 100 chars. Th
### Changed
- Never use OpenVPN as a fallback protocol when any of the following features is enabled:
multihop, quantum-resistant tunnels, or DAITA.
- Improved output format of `mullvad status` command, which now also prints feature indicators.

#### macOS
- Disable split tunnel interface when disconnected. This prevents traffic from being sent through
Expand Down
48 changes: 9 additions & 39 deletions mullvad-cli/src/cmds/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ pub struct StatusArgs {
}

impl Status {
pub async fn listen(mut rpc: MullvadProxyClient, args: StatusArgs) -> Result<()> {
let mut previous_tunnel_state = None;

pub async fn listen(
mut rpc: MullvadProxyClient,
args: StatusArgs,
mut previous_tunnel_state: TunnelState,
) -> Result<()> {
let mut event_stream = rpc.events_listen().await?;
while let Some(event) = event_stream.next().await {
match event? {
Expand All @@ -44,39 +46,8 @@ impl Status {
.context("Failed to format output as JSON")?;
println!("{json}");
} else {
// When we enter the connected or disconnected state, am.i.mullvad.net will
// be polled to get exit location. When it arrives, we will get another
// tunnel state of the same enum type, but with the location filled in. This
// match statement checks if the new state is an updated version of the old
// one and if so skips the print to avoid spamming the user. Note that for
// graphical frontends updating the drawn state with an identical one is
// invisible, so this is only an issue for the CLI.
match (&previous_tunnel_state, &new_state) {
(
Some(TunnelState::Disconnected {
location: _,
locked_down: was_locked_down,
}),
TunnelState::Disconnected {
location: _,
locked_down,
},
// Do print an updated state if the lockdown setting was changed
) if was_locked_down == locked_down => 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);
previous_tunnel_state = Some(new_state);
format::print_state(&new_state, Some(&previous_tunnel_state), args.verbose);
previous_tunnel_state = new_state;
}
}
DaemonEvent::Settings(settings) => {
Expand Down Expand Up @@ -116,12 +87,11 @@ pub async fn handle(cmd: Option<Status>, args: StatusArgs) -> Result<()> {
let json = serde_json::to_string(&state).context("Failed to format output as JSON")?;
println!("{json}");
} else {
format::print_state(&state, args.verbose);
format::print_location(&state);
format::print_state(&state, None, args.verbose);
}

if cmd == Some(Status::Listen) {
Status::listen(rpc, args).await?;
Status::listen(rpc, args, state).await?;
}
Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion mullvad-cli/src/cmds/tunnel_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ async fn wait_for_tunnel_state(
) -> Result<()> {
while let Some(state) = event_stream.next().await {
if let DaemonEvent::TunnelState(new_state) = state? {
format::print_state(&new_state, false);
format::print_state(&new_state, None, false);
if matches_event(&new_state)? {
return Ok(());
}
Expand Down
Loading
Loading