summaryrefslogtreecommitdiffhomepage
path: root/talpid-core/src
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2018-12-19 10:54:34 -0200
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-01-09 07:44:06 -0200
commit027a4c5260f31e4edfc3a3ddb70cbc1a146e6c40 (patch)
treec27fb186053f71296301d967a0d21ba714e6cb44 /talpid-core/src
parent8768f64ea9b8df2483735e4df92272cf2163deee (diff)
downloadmullvadvpn-027a4c5260f31e4edfc3a3ddb70cbc1a146e6c40.tar.xz
mullvadvpn-027a4c5260f31e4edfc3a3ddb70cbc1a146e6c40.zip
Block when TAP adapter problem is detected
Diffstat (limited to 'talpid-core/src')
-rw-r--r--talpid-core/src/tunnel_state_machine/connected_state.rs16
-rw-r--r--talpid-core/src/tunnel_state_machine/connecting_state.rs61
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnecting_state.rs18
3 files changed, 73 insertions, 22 deletions
diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs
index 961889d6c2..db28a200ef 100644
--- a/talpid-core/src/tunnel_state_machine/connected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connected_state.rs
@@ -9,9 +9,9 @@ use talpid_types::{
};
use super::{
- AfterDisconnect, ConnectingState, DisconnectingState, EventConsequence, Result, ResultExt,
- SharedTunnelStateValues, TunnelCommand, TunnelParameters, TunnelState, TunnelStateTransition,
- TunnelStateWrapper,
+ AfterDisconnect, BlockedState, ConnectingState, DisconnectingState, EventConsequence, Result,
+ ResultExt, SharedTunnelStateValues, TunnelCommand, TunnelParameters, TunnelState,
+ TunnelStateTransition, TunnelStateWrapper,
};
use crate::{
security::SecurityPolicy,
@@ -22,7 +22,7 @@ pub struct ConnectedStateBootstrap {
pub metadata: TunnelMetadata,
pub tunnel_events: mpsc::UnboundedReceiver<TunnelEvent>,
pub tunnel_parameters: TunnelParameters,
- pub tunnel_close_event: oneshot::Receiver<()>,
+ pub tunnel_close_event: oneshot::Receiver<Option<BlockReason>>,
pub close_handle: CloseHandle,
}
@@ -31,7 +31,7 @@ pub struct ConnectedState {
metadata: TunnelMetadata,
tunnel_events: mpsc::UnboundedReceiver<TunnelEvent>,
tunnel_parameters: TunnelParameters,
- tunnel_close_event: oneshot::Receiver<()>,
+ tunnel_close_event: oneshot::Receiver<Option<BlockReason>>,
close_handle: CloseHandle,
}
@@ -170,7 +170,11 @@ impl ConnectedState {
use self::EventConsequence::*;
match self.tunnel_close_event.poll() {
- Ok(Async::Ready(_)) => {}
+ Ok(Async::Ready(block_reason)) => {
+ if let Some(reason) = block_reason {
+ return NewState(BlockedState::enter(shared_values, reason));
+ }
+ }
Ok(Async::NotReady) => return NoEvents(self),
Err(_cancelled) => log::warn!("Tunnel monitor thread has stopped unexpectedly"),
}
diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs
index 6e7b88a212..a549145e90 100644
--- a/talpid-core/src/tunnel_state_machine/connecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs
@@ -54,7 +54,7 @@ error_chain! {
pub struct ConnectingState {
tunnel_events: mpsc::UnboundedReceiver<TunnelEvent>,
tunnel_parameters: TunnelParameters,
- tunnel_close_event: oneshot::Receiver<()>,
+ tunnel_close_event: oneshot::Receiver<Option<BlockReason>>,
close_handle: CloseHandle,
retry_attempt: u32,
}
@@ -147,25 +147,23 @@ impl ConnectingState {
}
}
- fn spawn_tunnel_monitor_wait_thread(tunnel_monitor: TunnelMonitor) -> oneshot::Receiver<()> {
+ fn spawn_tunnel_monitor_wait_thread(
+ tunnel_monitor: TunnelMonitor,
+ ) -> oneshot::Receiver<Option<BlockReason>> {
let (tunnel_close_event_tx, tunnel_close_event_rx) = oneshot::channel();
thread::spawn(move || {
let start = Instant::now();
- match tunnel_monitor.wait() {
- Ok(_) => debug!("Tunnel has finished without errors"),
- Err(error) => {
- let chained_error = error.chain_err(|| "Tunnel has stopped unexpectedly");
- warn!("{}", chained_error.display_chain());
- }
- }
+ let block_reason = Self::wait_for_tunnel_monitor(tunnel_monitor);
- if let Some(remaining_time) = MIN_TUNNEL_ALIVE_TIME.checked_sub(start.elapsed()) {
- thread::sleep(remaining_time);
+ if block_reason.is_none() {
+ if let Some(remaining_time) = MIN_TUNNEL_ALIVE_TIME.checked_sub(start.elapsed()) {
+ thread::sleep(remaining_time);
+ }
}
- if tunnel_close_event_tx.send(()).is_err() {
+ if tunnel_close_event_tx.send(block_reason).is_err() {
warn!("Tunnel state machine stopped before receiving tunnel closed event");
}
@@ -175,6 +173,39 @@ impl ConnectingState {
tunnel_close_event_rx
}
+ fn wait_for_tunnel_monitor(tunnel_monitor: TunnelMonitor) -> Option<BlockReason> {
+ match tunnel_monitor.wait() {
+ Ok(_) => {
+ debug!("Tunnel has finished without errors");
+ None
+ }
+ Err(error) => match error {
+ #[cfg(windows)]
+ error @ tunnel::Error(
+ tunnel::ErrorKind::OpenVpnTunnelMonitoringError(
+ tunnel::openvpn::ErrorKind::DisabledTapAdapter,
+ ),
+ _,
+ )
+ | error @ tunnel::Error(
+ tunnel::ErrorKind::OpenVpnTunnelMonitoringError(
+ tunnel::openvpn::ErrorKind::MissingTapAdapter,
+ ),
+ _,
+ ) => {
+ let chained_error = error.chain_err(|| "TAP adapter problem detected");
+ warn!("{}", chained_error.display_chain());
+ Some(BlockReason::TapAdapterProblem)
+ }
+ error => {
+ let chained_error = error.chain_err(|| "Tunnel has stopped unexpectedly");
+ warn!("{}", chained_error.display_chain());
+ None
+ }
+ },
+ }
+ }
+
fn into_connected_state_bootstrap(self, metadata: TunnelMetadata) -> ConnectedStateBootstrap {
ConnectedStateBootstrap {
metadata,
@@ -300,7 +331,11 @@ impl ConnectingState {
shared_values: &mut SharedTunnelStateValues,
) -> EventConsequence<Self> {
match self.tunnel_close_event.poll() {
- Ok(Async::Ready(_)) => {}
+ Ok(Async::Ready(block_reason)) => {
+ if let Some(reason) = block_reason {
+ return EventConsequence::NewState(BlockedState::enter(shared_values, reason));
+ }
+ }
Ok(Async::NotReady) => return EventConsequence::NoEvents(self),
Err(_cancelled) => warn!("Tunnel monitor thread has stopped unexpectedly"),
}
diff --git a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
index ec8be8cfe1..6f470fe370 100644
--- a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
@@ -16,7 +16,7 @@ use crate::tunnel::CloseHandle;
/// This state is active from when we manually trigger a tunnel kill until the tunnel wait
/// operation (TunnelExit) returned.
pub struct DisconnectingState {
- exited: oneshot::Receiver<()>,
+ exited: oneshot::Receiver<Option<BlockReason>>,
after_disconnect: AfterDisconnect,
}
@@ -103,14 +103,22 @@ impl DisconnectingState {
match self.exited.poll() {
Ok(Async::NotReady) => NoEvents(self),
- Ok(Async::Ready(_)) | Err(_) => NewState(self.after_disconnect(shared_values)),
+ Ok(Async::Ready(block_reason)) => {
+ NewState(self.after_disconnect(block_reason, shared_values))
+ }
+ Err(_) => NewState(self.after_disconnect(None, shared_values)),
}
}
fn after_disconnect(
self,
+ block_reason: Option<BlockReason>,
shared_values: &mut SharedTunnelStateValues,
) -> (TunnelStateWrapper, TunnelStateTransition) {
+ if let Some(reason) = block_reason {
+ return BlockedState::enter(shared_values, reason);
+ }
+
match self.after_disconnect {
AfterDisconnect::Nothing => DisconnectedState::enter(shared_values, ()),
AfterDisconnect::Block(reason) => BlockedState::enter(shared_values, reason),
@@ -122,7 +130,11 @@ impl DisconnectingState {
}
impl TunnelState for DisconnectingState {
- type Bootstrap = (CloseHandle, oneshot::Receiver<()>, AfterDisconnect);
+ type Bootstrap = (
+ CloseHandle,
+ oneshot::Receiver<Option<BlockReason>>,
+ AfterDisconnect,
+ );
fn enter(
_: &mut SharedTunnelStateValues,