1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
use anyhow::{Result, bail};
use mullvad_management_interface::MullvadProxyClient;
use mullvad_types::{
constraints::Constraint,
relay_constraints::{RelayConstraints, RelaySettings},
};
#[derive(clap::Subcommand, Debug)]
pub enum DebugCommands {
/// Block all internet connection by setting an invalid relay constraint.
BlockConnection,
/// Relay
#[clap(subcommand)]
Relay(RelayDebugCommands),
/// Handy commands for interacting with the app release rollout system.
#[clap(subcommand)]
Rollout(RolloutDebugCommands),
}
#[derive(clap::Subcommand, Debug)]
pub enum RelayDebugCommands {
/// Inactivate this _category of relays_ - a category can be one of the following: a relay, a
/// city, a country.
Disable { relay: String },
/// (Re)Activate this _category of relays_ - a category can be one of the following: a relay, a
/// city, a country.
Enable { relay: String },
}
#[derive(clap::Subcommand, Debug)]
pub enum RolloutDebugCommands {
/// Print your rollout threshold.
Get,
/// Generate a new rollout threshold (overwrites the current threshold value)
Reroll,
/// Set your rollout threshold seed to a known value.
///
/// The seed is used to generate a rollout threshold.
Seed { value: u32 },
}
impl DebugCommands {
pub async fn handle(self) -> Result<()> {
match self {
DebugCommands::BlockConnection => {
let mut rpc = MullvadProxyClient::new().await?;
let settings = rpc.get_settings().await?;
let relay_settings = settings.get_relay_settings();
let mut constraints = match relay_settings {
RelaySettings::Normal(normal) => normal,
RelaySettings::CustomTunnelEndpoint(_custom) => {
println!("Removing custom relay settings");
RelayConstraints::default()
}
};
constraints.location = Constraint::Only(
mullvad_types::relay_constraints::LocationConstraint::Location(
mullvad_types::relay_constraints::GeographicLocationConstraint::Country(
"xx".into(),
),
),
);
rpc.set_relay_settings(RelaySettings::Normal(constraints))
.await?;
rpc.connect_tunnel().await?;
eprintln!("WARNING: ENTERED BLOCKED MODE");
Ok(())
}
DebugCommands::Relay(RelayDebugCommands::Disable { relay }) => {
let mut rpc = MullvadProxyClient::new().await?;
rpc.disable_relay(relay.clone()).await?;
println!("{relay} is now marked as inactive");
Ok(())
}
DebugCommands::Relay(RelayDebugCommands::Enable { relay }) => {
let mut rpc = MullvadProxyClient::new().await?;
rpc.enable_relay(relay.clone()).await?;
println!("{relay} is now marked as active");
Ok(())
}
DebugCommands::Rollout(rollout_cmd) => rollout_cmd.handle().await,
}
}
}
impl RolloutDebugCommands {
pub async fn handle(self) -> Result<()> {
let mut rpc = MullvadProxyClient::new().await?;
match self {
RolloutDebugCommands::Get => {
let Ok(threshold) = rpc.get_rollout_threshold().await else {
bail!("Failed to get rollout");
};
println!("{threshold}");
Ok(())
}
RolloutDebugCommands::Reroll => {
let Ok(threshold) = rpc.generate_new_rollout_threshold().await else {
bail!("Failed to get rollout");
};
println!("{threshold}");
Ok(())
}
RolloutDebugCommands::Seed { value: seed } => {
if rpc.set_new_rollout_threshold_seed(seed).await.is_err() {
bail!("Failed to update rollout seed");
}
Ok(())
}
}
}
}
|