summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls <emils@mullvad.net>2019-12-02 16:10:13 +0000
committerEmīls <emils@mullvad.net>2019-12-09 11:23:07 +0000
commit709df311b8965df262d4d54185bbd66a79ab1b35 (patch)
tree2774929907f63ac0849edc0186bc6378763b805b
parent345bebcf9cd75dc29328b1355c2feacbf7b65aad (diff)
downloadmullvadvpn-709df311b8965df262d4d54185bbd66a79ab1b35.tar.xz
mullvadvpn-709df311b8965df262d4d54185bbd66a79ab1b35.zip
Change blocked state to error state
-rw-r--r--mullvad-daemon/src/lib.rs26
-rw-r--r--mullvad-types/src/states.rs10
-rw-r--r--talpid-core/src/tunnel_state_machine/connected_state.rs18
-rw-r--r--talpid-core/src/tunnel_state_machine/connecting_state.rs36
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnected_state.rs6
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnecting_state.rs20
-rw-r--r--talpid-core/src/tunnel_state_machine/error_state.rs (renamed from talpid-core/src/tunnel_state_machine/blocked_state.rs)45
-rw-r--r--talpid-core/src/tunnel_state_machine/mod.rs12
-rw-r--r--talpid-types/src/tunnel.rs41
9 files changed, 125 insertions, 89 deletions
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs
index e78649ac63..aabcbb6952 100644
--- a/mullvad-daemon/src/lib.rs
+++ b/mullvad-daemon/src/lib.rs
@@ -64,7 +64,7 @@ use talpid_core::{
use talpid_types::android::AndroidContext;
use talpid_types::{
net::{openvpn, TransportProtocol, TunnelParameters},
- tunnel::{BlockReason, ParameterGenerationError, TunnelStateTransition},
+ tunnel::{ErrorStateCause, ParameterGenerationError, TunnelStateTransition},
ErrorExt,
};
@@ -565,7 +565,7 @@ where
TunnelStateTransition::Disconnecting(after_disconnect) => {
TunnelState::Disconnecting(after_disconnect)
}
- TunnelStateTransition::Blocked(reason) => TunnelState::Blocked(reason.clone()),
+ TunnelStateTransition::Error(error_state) => TunnelState::Error(error_state.clone()),
};
self.unschedule_reconnect();
@@ -573,10 +573,20 @@ where
debug!("New tunnel state: {:?}", tunnel_state);
match tunnel_state {
TunnelState::Disconnected => self.state.disconnected(),
- TunnelState::Blocked(ref reason) => {
- info!("Blocking all network connections, reason: {}", reason);
+ TunnelState::Error(ref error_state) => {
+ if error_state.is_blocking() {
+ info!(
+ "Blocking all network connections, reason: {}",
+ error_state.cause()
+ );
+ } else {
+ error!(
+ "FAILED TO BLOCK NETWORK CONNECTIONS, ENTERED ERROR STATE BECAUSE: {}",
+ error_state.cause()
+ );
+ }
- if let BlockReason::AuthFailed(_) = reason {
+ if let ErrorStateCause::AuthFailed(_) = error_state.cause() {
self.schedule_reconnect(Duration::from_secs(60))
}
}
@@ -925,7 +935,7 @@ where
}
fn on_reconnect(&mut self) {
- if self.target_state == TargetState::Secured || self.tunnel_state.is_blocked() {
+ if self.target_state == TargetState::Secured || self.tunnel_state.is_in_error_state() {
self.connect_tunnel();
} else {
debug!("Ignoring reconnect command. Currently not in secured state");
@@ -955,7 +965,7 @@ where
.map(Some),
)
}
- Blocked(..) => {
+ Error(..) => {
// We are not online at all at this stage so no location data is available.
Box::new(future::result(Ok(None)))
}
@@ -1485,7 +1495,7 @@ where
/// progress towards that state.
/// Returns an error if trying to set secured state, but no account token is present.
fn set_target_state(&mut self, new_state: TargetState) {
- if new_state != self.target_state || self.tunnel_state.is_blocked() {
+ if new_state != self.target_state || self.tunnel_state.is_in_error_state() {
debug!("Target state {:?} => {:?}", self.target_state, new_state);
self.target_state = new_state;
match self.target_state {
diff --git a/mullvad-types/src/states.rs b/mullvad-types/src/states.rs
index e905f329c5..805210a7aa 100644
--- a/mullvad-types/src/states.rs
+++ b/mullvad-types/src/states.rs
@@ -4,7 +4,7 @@ use jnix::IntoJava;
use serde::{Deserialize, Serialize};
use talpid_types::{
net::TunnelEndpoint,
- tunnel::{ActionAfterDisconnect, BlockReason},
+ tunnel::{ActionAfterDisconnect, ErrorState},
};
/// Represents the state the client strives towards.
@@ -34,14 +34,14 @@ pub enum TunnelState {
location: Option<GeoIpLocation>,
},
Disconnecting(ActionAfterDisconnect),
- Blocked(BlockReason),
+ Error(ErrorState),
}
impl TunnelState {
- /// Returns true if the tunnel state is the blocked state.
- pub fn is_blocked(&self) -> bool {
+ /// Returns true if the tunnel state is in the error state.
+ pub fn is_in_error_state(&self) -> bool {
match self {
- TunnelState::Blocked(_) => true,
+ TunnelState::Error(_) => true,
_ => false,
}
}
diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs
index fd26b20bc3..3ce80db030 100644
--- a/talpid-core/src/tunnel_state_machine/connected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connected_state.rs
@@ -1,5 +1,5 @@
use super::{
- AfterDisconnect, BlockedState, ConnectingState, DisconnectingState, EventConsequence,
+ AfterDisconnect, ConnectingState, DisconnectingState, ErrorState, EventConsequence,
SharedTunnelStateValues, TunnelCommand, TunnelState, TunnelStateTransition, TunnelStateWrapper,
};
use crate::{
@@ -12,7 +12,7 @@ use futures::{
};
use talpid_types::{
net::{Endpoint, TunnelParameters},
- tunnel::BlockReason,
+ tunnel::ErrorStateCause,
ErrorExt,
};
@@ -20,7 +20,7 @@ pub struct ConnectedStateBootstrap {
pub metadata: TunnelMetadata,
pub tunnel_events: mpsc::UnboundedReceiver<TunnelEvent>,
pub tunnel_parameters: TunnelParameters,
- pub tunnel_close_event: Option<oneshot::Receiver<Option<BlockReason>>>,
+ pub tunnel_close_event: Option<oneshot::Receiver<Option<ErrorStateCause>>>,
pub close_handle: Option<CloseHandle>,
}
@@ -29,7 +29,7 @@ pub struct ConnectedState {
metadata: TunnelMetadata,
tunnel_events: mpsc::UnboundedReceiver<TunnelEvent>,
tunnel_parameters: TunnelParameters,
- tunnel_close_event: Option<oneshot::Receiver<Option<BlockReason>>>,
+ tunnel_close_event: Option<oneshot::Receiver<Option<ErrorStateCause>>>,
close_handle: Option<CloseHandle>,
}
@@ -123,7 +123,7 @@ impl ConnectedState {
);
self.disconnect(
shared_values,
- AfterDisconnect::Block(BlockReason::SetFirewallPolicyError),
+ AfterDisconnect::Block(ErrorStateCause::SetFirewallPolicyError),
)
}
}
@@ -137,7 +137,7 @@ impl ConnectedState {
if is_offline {
self.disconnect(
shared_values,
- AfterDisconnect::Block(BlockReason::IsOffline),
+ AfterDisconnect::Block(ErrorStateCause::IsOffline),
)
} else {
SameState(self)
@@ -183,7 +183,7 @@ impl ConnectedState {
match poll_result {
Ok(Async::Ready(block_reason)) => {
if let Some(reason) = block_reason {
- return NewState(BlockedState::enter(shared_values, reason));
+ return NewState(ErrorState::enter(shared_values, reason));
}
}
Ok(Async::NotReady) => return NoEvents(self),
@@ -217,7 +217,7 @@ impl TunnelState for ConnectedState {
(
connected_state.close_handle,
connected_state.tunnel_close_event,
- AfterDisconnect::Block(BlockReason::SetFirewallPolicyError),
+ AfterDisconnect::Block(ErrorStateCause::SetFirewallPolicyError),
),
)
} else if let Err(error) = connected_state.set_dns(shared_values) {
@@ -230,7 +230,7 @@ impl TunnelState for ConnectedState {
(
connected_state.close_handle,
connected_state.tunnel_close_event,
- AfterDisconnect::Block(BlockReason::SetDnsError),
+ AfterDisconnect::Block(ErrorStateCause::SetDnsError),
),
)
} else {
diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs
index 67036ea98e..01e39b0ebc 100644
--- a/talpid-core/src/tunnel_state_machine/connecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs
@@ -1,5 +1,5 @@
use super::{
- AfterDisconnect, BlockedState, ConnectedState, ConnectedStateBootstrap, DisconnectingState,
+ AfterDisconnect, ConnectedState, ConnectedStateBootstrap, DisconnectingState, ErrorState,
EventConsequence, SharedTunnelStateValues, TunnelCommand, TunnelState, TunnelStateTransition,
TunnelStateWrapper,
};
@@ -22,7 +22,7 @@ use std::{
};
use talpid_types::{
net::{openvpn, TunnelParameters},
- tunnel::BlockReason,
+ tunnel::ErrorStateCause,
ErrorExt,
};
@@ -34,7 +34,7 @@ const MIN_TUNNEL_ALIVE_TIME: Duration = Duration::from_millis(1000);
pub struct ConnectingState {
tunnel_events: mpsc::UnboundedReceiver<TunnelEvent>,
tunnel_parameters: TunnelParameters,
- tunnel_close_event: Option<oneshot::Receiver<Option<BlockReason>>>,
+ tunnel_close_event: Option<oneshot::Receiver<Option<ErrorStateCause>>>,
close_handle: Option<CloseHandle>,
retry_attempt: u32,
}
@@ -92,7 +92,7 @@ impl ConnectingState {
fn spawn_tunnel_monitor_wait_thread(
tunnel_monitor: TunnelMonitor,
- ) -> Option<oneshot::Receiver<Option<BlockReason>>> {
+ ) -> Option<oneshot::Receiver<Option<ErrorStateCause>>> {
let (tunnel_close_event_tx, tunnel_close_event_rx) = oneshot::channel();
thread::spawn(move || {
@@ -120,7 +120,7 @@ impl ConnectingState {
Some(tunnel_close_event_rx)
}
- fn wait_for_tunnel_monitor(tunnel_monitor: TunnelMonitor) -> Option<BlockReason> {
+ fn wait_for_tunnel_monitor(tunnel_monitor: TunnelMonitor) -> Option<ErrorStateCause> {
match tunnel_monitor.wait() {
Ok(_) => None,
Err(error) => match error {
@@ -135,7 +135,7 @@ impl ConnectingState {
"{}",
error.display_chain_with_msg("TAP adapter problem detected")
);
- Some(BlockReason::TapAdapterProblem)
+ Some(ErrorStateCause::TapAdapterProblem)
}
error => {
warn!(
@@ -183,7 +183,7 @@ impl ConnectingState {
(
self.close_handle,
self.tunnel_close_event,
- AfterDisconnect::Block(BlockReason::SetFirewallPolicyError),
+ AfterDisconnect::Block(ErrorStateCause::SetFirewallPolicyError),
),
))
}
@@ -201,7 +201,7 @@ impl ConnectingState {
(
self.close_handle,
self.tunnel_close_event,
- AfterDisconnect::Block(BlockReason::IsOffline),
+ AfterDisconnect::Block(ErrorStateCause::IsOffline),
),
))
} else {
@@ -248,7 +248,7 @@ impl ConnectingState {
(
self.close_handle,
self.tunnel_close_event,
- AfterDisconnect::Block(BlockReason::AuthFailed(reason)),
+ AfterDisconnect::Block(ErrorStateCause::AuthFailed(reason)),
),
)),
Ok(TunnelEvent::Up(metadata)) => NewState(ConnectedState::enter(
@@ -282,7 +282,7 @@ impl ConnectingState {
match poll_result {
Ok(Async::Ready(block_reason)) => {
if let Some(reason) = block_reason {
- return EventConsequence::NewState(BlockedState::enter(shared_values, reason));
+ return EventConsequence::NewState(ErrorState::enter(shared_values, reason));
}
}
Ok(Async::NotReady) => return EventConsequence::NoEvents(self),
@@ -333,13 +333,15 @@ impl TunnelState for ConnectingState {
retry_attempt: u32,
) -> (TunnelStateWrapper, TunnelStateTransition) {
if shared_values.is_offline {
- return BlockedState::enter(shared_values, BlockReason::IsOffline);
+ return ErrorState::enter(shared_values, ErrorStateCause::IsOffline);
}
match shared_values
.tunnel_parameters_generator
.generate(retry_attempt)
{
- Err(err) => BlockedState::enter(shared_values, BlockReason::TunnelParameterError(err)),
+ Err(err) => {
+ ErrorState::enter(shared_values, ErrorStateCause::TunnelParameterError(err))
+ }
Ok(tunnel_parameters) => {
if let Err(error) = Self::set_firewall_policy(shared_values, &tunnel_parameters) {
error!(
@@ -348,7 +350,7 @@ impl TunnelState for ConnectingState {
"Failed to apply firewall policy for connecting state"
)
);
- BlockedState::enter(shared_values, BlockReason::StartTunnelError)
+ ErrorState::enter(shared_values, ErrorStateCause::StartTunnelError)
} else {
#[cfg(target_os = "android")]
{
@@ -394,10 +396,12 @@ impl TunnelState for ConnectingState {
error.display_chain_with_msg("Failed to start tunnel")
);
let block_reason = match error {
- tunnel::Error::EnableIpv6Error => BlockReason::Ipv6Unavailable,
- _ => BlockReason::StartTunnelError,
+ tunnel::Error::EnableIpv6Error => {
+ ErrorStateCause::Ipv6Unavailable
+ }
+ _ => ErrorStateCause::StartTunnelError,
};
- BlockedState::enter(shared_values, block_reason)
+ ErrorState::enter(shared_values, block_reason)
}
}
}
diff --git a/talpid-core/src/tunnel_state_machine/disconnected_state.rs b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
index 6b95548ddd..f183a7c78c 100644
--- a/talpid-core/src/tunnel_state_machine/disconnected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
@@ -1,5 +1,5 @@
use super::{
- BlockedState, ConnectingState, EventConsequence, SharedTunnelStateValues, TunnelCommand,
+ ConnectingState, ErrorState, EventConsequence, SharedTunnelStateValues, TunnelCommand,
TunnelState, TunnelStateTransition, TunnelStateWrapper,
};
use crate::firewall::FirewallPolicy;
@@ -76,9 +76,7 @@ impl TunnelState for DisconnectedState {
SameState(self)
}
Ok(TunnelCommand::Connect) => NewState(ConnectingState::enter(shared_values, 0)),
- Ok(TunnelCommand::Block(reason)) => {
- NewState(BlockedState::enter(shared_values, reason))
- }
+ Ok(TunnelCommand::Block(reason)) => NewState(ErrorState::enter(shared_values, reason)),
Ok(_) => SameState(self),
Err(_) => Finished,
}
diff --git a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
index 733a6e2448..d18fdeb6ee 100644
--- a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
@@ -1,5 +1,5 @@
use super::{
- BlockedState, ConnectingState, DisconnectedState, EventConsequence, SharedTunnelStateValues,
+ ConnectingState, DisconnectedState, ErrorState, EventConsequence, SharedTunnelStateValues,
TunnelCommand, TunnelState, TunnelStateTransition, TunnelStateWrapper,
};
use crate::tunnel::CloseHandle;
@@ -9,14 +9,14 @@ use futures::{
};
use std::thread;
use talpid_types::{
- tunnel::{ActionAfterDisconnect, BlockReason},
+ tunnel::{ActionAfterDisconnect, ErrorStateCause},
ErrorExt,
};
/// This state is active from when we manually trigger a tunnel kill until the tunnel wait
/// operation (TunnelExit) returned.
pub struct DisconnectingState {
- exited: Option<oneshot::Receiver<Option<BlockReason>>>,
+ exited: Option<oneshot::Receiver<Option<ErrorStateCause>>>,
after_disconnect: AfterDisconnect,
}
@@ -58,7 +58,7 @@ impl DisconnectingState {
}
Ok(TunnelCommand::IsOffline(is_offline)) => {
shared_values.is_offline = is_offline;
- if !is_offline && reason == BlockReason::IsOffline {
+ if !is_offline && reason == ErrorStateCause::IsOffline {
AfterDisconnect::Reconnect(0)
} else {
AfterDisconnect::Block(reason)
@@ -81,7 +81,7 @@ impl DisconnectingState {
Ok(TunnelCommand::IsOffline(is_offline)) => {
shared_values.is_offline = is_offline;
if is_offline {
- AfterDisconnect::Block(BlockReason::IsOffline)
+ AfterDisconnect::Block(ErrorStateCause::IsOffline)
} else {
AfterDisconnect::Reconnect(retry_attempt)
}
@@ -117,16 +117,16 @@ impl DisconnectingState {
fn after_disconnect(
self,
- block_reason: Option<BlockReason>,
+ block_reason: Option<ErrorStateCause>,
shared_values: &mut SharedTunnelStateValues,
) -> (TunnelStateWrapper, TunnelStateTransition) {
if let Some(reason) = block_reason {
- return BlockedState::enter(shared_values, reason);
+ return ErrorState::enter(shared_values, reason);
}
match self.after_disconnect {
AfterDisconnect::Nothing => DisconnectedState::enter(shared_values, ()),
- AfterDisconnect::Block(reason) => BlockedState::enter(shared_values, reason),
+ AfterDisconnect::Block(cause) => ErrorState::enter(shared_values, cause),
AfterDisconnect::Reconnect(retry_attempt) => {
ConnectingState::enter(shared_values, retry_attempt)
}
@@ -137,7 +137,7 @@ impl DisconnectingState {
impl TunnelState for DisconnectingState {
type Bootstrap = (
Option<CloseHandle>,
- Option<oneshot::Receiver<Option<BlockReason>>>,
+ Option<oneshot::Receiver<Option<ErrorStateCause>>>,
AfterDisconnect,
);
@@ -180,7 +180,7 @@ impl TunnelState for DisconnectingState {
/// Which state should be transitioned to after disconnection is complete.
pub enum AfterDisconnect {
Nothing,
- Block(BlockReason),
+ Block(ErrorStateCause),
Reconnect(u32),
}
diff --git a/talpid-core/src/tunnel_state_machine/blocked_state.rs b/talpid-core/src/tunnel_state_machine/error_state.rs
index bdf054ab2c..9d8402997d 100644
--- a/talpid-core/src/tunnel_state_machine/blocked_state.rs
+++ b/talpid-core/src/tunnel_state_machine/error_state.rs
@@ -4,21 +4,25 @@ use super::{
};
use crate::firewall::FirewallPolicy;
use futures::{sync::mpsc, Stream};
-use talpid_types::{tunnel::BlockReason, ErrorExt};
+use talpid_types::{
+ tunnel::{self as talpid_tunnel, ErrorStateCause},
+ ErrorExt,
+};
/// No tunnel is running and all network connections are blocked.
-pub struct BlockedState {
- block_reason: BlockReason,
+pub struct ErrorState {
+ block_reason: ErrorStateCause,
}
-impl BlockedState {
- fn set_firewall_policy(shared_values: &mut SharedTunnelStateValues) -> Option<BlockReason> {
+impl ErrorState {
+ /// Returns true if firewall policy was applied successfully
+ fn set_firewall_policy(shared_values: &mut SharedTunnelStateValues) -> bool {
let policy = FirewallPolicy::Blocked {
allow_lan: shared_values.allow_lan,
};
match shared_values.firewall.apply_policy(policy) {
- Ok(()) => None,
+ Ok(()) => true,
Err(error) => {
log::error!(
"{}",
@@ -26,15 +30,16 @@ impl BlockedState {
"Failed to apply firewall policy for blocked state"
)
);
- Some(BlockReason::SetFirewallPolicyError)
+ false
}
}
}
+ /// Returns true if a new tunnel device was successfully created.
#[cfg(target_os = "android")]
- fn create_blocking_tun(shared_values: &mut SharedTunnelStateValues) -> Option<BlockReason> {
+ fn create_blocking_tun(shared_values: &mut SharedTunnelStateValues) -> bool {
match shared_values.tun_provider.create_tun_if_closed() {
- Ok(()) => None,
+ Ok(()) => true,
Err(error) => {
log::error!(
"{}",
@@ -42,28 +47,28 @@ impl BlockedState {
"Failed to open tunnel adapter to drop packets for blocked state"
)
);
- Some(BlockReason::SetFirewallPolicyError)
+ false
}
}
}
}
-impl TunnelState for BlockedState {
- type Bootstrap = BlockReason;
+impl TunnelState for ErrorState {
+ type Bootstrap = ErrorStateCause;
fn enter(
shared_values: &mut SharedTunnelStateValues,
block_reason: Self::Bootstrap,
) -> (TunnelStateWrapper, TunnelStateTransition) {
- let block_reason = Self::set_firewall_policy(shared_values).unwrap_or_else(|| block_reason);
+ #[cfg(not(target_os = "android"))]
+ let is_blocking = Self::set_firewall_policy(shared_values);
#[cfg(target_os = "android")]
- let block_reason = Self::create_blocking_tun(shared_values).unwrap_or_else(|| block_reason);
-
+ let is_blocking = Self::create_blocking_tun(shared_values);
(
- TunnelStateWrapper::from(BlockedState {
+ TunnelStateWrapper::from(ErrorState {
block_reason: block_reason.clone(),
}),
- TunnelStateTransition::Blocked(block_reason),
+ TunnelStateTransition::Error(talpid_tunnel::ErrorState::new(block_reason, is_blocking)),
)
}
@@ -86,7 +91,7 @@ impl TunnelState for BlockedState {
}
Ok(TunnelCommand::IsOffline(is_offline)) => {
shared_values.is_offline = is_offline;
- if !is_offline && self.block_reason == BlockReason::IsOffline {
+ if !is_offline && self.block_reason == ErrorStateCause::IsOffline {
NewState(ConnectingState::enter(shared_values, 0))
} else {
SameState(self)
@@ -96,9 +101,7 @@ impl TunnelState for BlockedState {
Ok(TunnelCommand::Disconnect) | Err(_) => {
NewState(DisconnectedState::enter(shared_values, ()))
}
- Ok(TunnelCommand::Block(reason)) => {
- NewState(BlockedState::enter(shared_values, reason))
- }
+ Ok(TunnelCommand::Block(reason)) => NewState(ErrorState::enter(shared_values, reason)),
}
}
}
diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs
index b86795491d..76bd62a1d4 100644
--- a/talpid-core/src/tunnel_state_machine/mod.rs
+++ b/talpid-core/src/tunnel_state_machine/mod.rs
@@ -1,18 +1,18 @@
#[macro_use]
mod macros;
-mod blocked_state;
mod connected_state;
mod connecting_state;
mod disconnected_state;
mod disconnecting_state;
+mod error_state;
use self::{
- blocked_state::BlockedState,
connected_state::{ConnectedState, ConnectedStateBootstrap},
connecting_state::ConnectingState,
disconnected_state::DisconnectedState,
disconnecting_state::{AfterDisconnect, DisconnectingState},
+ error_state::ErrorState,
};
use crate::{
dns::DnsMonitor,
@@ -32,7 +32,7 @@ use std::{
use talpid_types::android::AndroidContext;
use talpid_types::{
net::TunnelParameters,
- tunnel::{BlockReason, ParameterGenerationError, TunnelStateTransition},
+ tunnel::{ErrorStateCause, ParameterGenerationError, TunnelStateTransition},
ErrorExt,
};
use tokio_core::reactor::Core;
@@ -182,7 +182,7 @@ pub enum TunnelCommand {
/// Close tunnel connection.
Disconnect,
/// Disconnect any open tunnel and block all network access
- Block(BlockReason),
+ Block(ErrorStateCause),
}
/// Asynchronous handling of the tunnel state machine.
@@ -297,7 +297,7 @@ impl<T: TunnelState> From<EventConsequence<T>> for TunnelStateMachineAction {
pub trait TunnelParametersGenerator: Send + 'static {
/// Given the number of consecutive failed retry attempts, it should yield a `TunnelParameters`
/// to establish a tunnel with.
- /// If this returns `None` then the state machine goes into the `Blocked` state.
+ /// If this returns `None` then the state machine goes into the `Error` state.
fn generate(
&mut self,
retry_attempt: u32,
@@ -427,6 +427,6 @@ state_wrapper! {
Connecting(ConnectingState),
Connected(ConnectedState),
Disconnecting(DisconnectingState),
- Blocked(BlockedState),
+ Error(ErrorState),
}
}
diff --git a/talpid-types/src/tunnel.rs b/talpid-types/src/tunnel.rs
index 9ab3ed6d36..fad6be14a4 100644
--- a/talpid-types/src/tunnel.rs
+++ b/talpid-types/src/tunnel.rs
@@ -18,7 +18,7 @@ pub enum TunnelStateTransition {
/// Disconnecting tunnel.
Disconnecting(ActionAfterDisconnect),
/// Tunnel is disconnected but secured by blocking all connections.
- Blocked(BlockReason),
+ Error(ErrorState),
}
/// Action that will be taken after disconnection is complete.
@@ -32,22 +32,43 @@ pub enum ActionAfterDisconnect {
Reconnect,
}
-impl TunnelStateTransition {
- pub fn is_blocked(&self) -> bool {
- match self {
- TunnelStateTransition::Blocked(_) => true,
- _ => false,
- }
+/// Error state
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "snake_case")]
+#[cfg_attr(target_os = "android", derive(IntoJava))]
+#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.talpid.tunnel"))]
+pub struct ErrorState {
+ /// Reason why the tunnel state machine ended up in the error state
+ cause: ErrorStateCause,
+ /// Indicates whether the daemon is currently blocking all traffic. This _should_ always be
+ /// true - in the case it is not, the user should be notified that no traffic is being blocked.
+ /// A false value means there was a serious error and the intended security properties are not
+ /// being upheld.
+ is_blocking: bool,
+}
+
+impl ErrorState {
+ pub fn new(cause: ErrorStateCause, is_blocking: bool) -> Self {
+ Self { cause, is_blocking }
+ }
+
+ pub fn is_blocking(&self) -> bool {
+ self.is_blocking
+ }
+
+ pub fn cause(&self) -> &ErrorStateCause {
+ &self.cause
}
}
+
/// Reason for entering the blocked state.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "reason", content = "details")]
#[cfg_attr(target_os = "android", derive(IntoJava))]
#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.talpid.tunnel"))]
-pub enum BlockReason {
+pub enum ErrorStateCause {
/// Authentication with remote server failed.
AuthFailed(Option<String>),
/// Failed to configure IPv6 because it's disabled in the platform.
@@ -86,9 +107,9 @@ pub enum ParameterGenerationError {
CustomTunnelHostResultionError,
}
-impl fmt::Display for BlockReason {
+impl fmt::Display for ErrorStateCause {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- use self::BlockReason::*;
+ use self::ErrorStateCause::*;
let description = match *self {
AuthFailed(ref reason) => {
return write!(