public void Disconnect(VpnError error = VpnError.None) { _reconnectPending = false; _reconnecting = false; _disconnecting = true; _origin.Disconnect(error); }
public async Task DisconnectError_ShouldBe_None_WhenUnexpectedlyDisconnected_WithoutAnError() { // Arrange VpnError disconnectError = VpnError.None; SetupDisconnect(); SetupConnect(); SetupUnexpectedDisconnect(VpnError.None); HandlingRequestsWrapper subject = new(_logger, _taskQueue, _origin); subject.StateChanged += (s, e) => { if (e.Data.Status == VpnStatus.Disconnected) { disconnectError = e.Data.Error; } }; // Act subject.Connect(_endpoint, _credentials, _config); await _taskQueue.WaitForLastTask(); // Assert disconnectError.Should().Be(VpnError.None); }
private void InvokeStateChange(VpnStatus status, VpnError error = VpnError.None) { StateChanged?.Invoke(this, new EventArgs <VpnState>( new VpnState(status, error, _config.WireGuard.DefaultClientAddress, _endpoint?.Server.Ip ?? string.Empty, VpnProtocol.WireGuard, null, _endpoint?.Server.Label ?? string.Empty))); }
private async Task ShowModalAsync(VpnStateChangedEventArgs e) { VpnError error = e.Error; if (error == VpnError.AuthorizationError) { error = await _connectionErrorResolver.ResolveError(); } switch (error) { case VpnError.UserTierTooLowError: await ForceReconnectAsync(); break; case VpnError.Unpaid: await ShowDelinquencyPopupViewModelAsync(); break; case VpnError.SessionLimitReached: ShowMaximumDeviceLimitModalViewModel(); break; default: ShowDisconnectErrorModalViewModel(error, e.NetworkBlocked); break; } }
private async Task ConnectAction(CancellationToken cancellationToken) { _logger.Info("OpenVpnConnection: Connect action started"); OnStateChanged(VpnStatus.Connecting); var port = _managementPorts.Port(); var password = ManagementPassword(); var processParams = new OpenVpnProcessParams(_endpoint, port, password, _config.CustomDns, _config.SplitTunnelMode, _config.SplitTunnelIPs); cancellationToken.ThrowIfCancellationRequested(); if (!await _process.Start(processParams)) { _disconnectError = VpnError.Unknown; } else { await _managementClient.Connect(port, password); if (cancellationToken.IsCancellationRequested) { await _managementClient.CloseVpnConnection(); cancellationToken.ThrowIfCancellationRequested(); } await _managementClient.StartVpnConnection(_credentials, cancellationToken); } cancellationToken.ThrowIfCancellationRequested(); }
private void ManagementClient_StateChanged(object sender, EventArgs <VpnState> e) { _logger.Info($"ManagementClient: State changed to {e.Data.Status}"); VpnState state = new( e.Data.Status, e.Data.Error, e.Data.LocalIp, e.Data.RemoteIp, _endpoint.VpnProtocol, _config.OpenVpnAdapter, e.Data.Label); if ((state.Status == VpnStatus.Pinging || state.Status == VpnStatus.Connecting || state.Status == VpnStatus.Reconnecting) && string.IsNullOrEmpty(state.RemoteIp)) { state = new VpnState( state.Status, VpnError.None, string.Empty, _endpoint.Server.Ip, _endpoint.VpnProtocol, state.OpenVpnAdapter, _endpoint.Server.Label); } if (state.Status == VpnStatus.Disconnecting && !_disconnectAction.IsRunning) { _disconnectError = state.Error; } OnStateChanged(state); }
public void Disconnect(VpnError error) { _connectRequested = false; _disconnectedReceived = false; _origin.Disconnect(error); }
private void OnStateChanged(VpnState state) { _disconnected = state.Status == VpnStatus.Disconnected; if (_connectRequested) { InvokeConnecting(); if (_disconnected) { _logger.Info("HandlingRequestsWrapper: Already disconnected, queuing Connect"); Queued(Connect); } return; } if (_disconnectRequested || _disconnecting) { if (state.Status == VpnStatus.Disconnecting || state.Status == VpnStatus.Disconnected) { InvokeStateChanged(state.WithError(_disconnectError)); return; } InvokeDisconnecting(); return; } if (_connecting && state.Status == VpnStatus.Disconnecting) { // Force disconnect if disconnected while connecting _disconnectRequested = true; _disconnectError = state.Error == VpnError.None ? VpnError.Unknown : state.Error; _logger.Info("HandlingRequestsWrapper: Disconnecting unexpectedly, queuing Disconnect"); Queued(Disconnect); } if (state.Status == VpnStatus.Disconnecting || state.Status == VpnStatus.Disconnected) { var error = state.Error == VpnError.None ? VpnError.Unknown : state.Error; if (_connecting) { // Force disconnect if disconnected while connecting _disconnectRequested = true; _disconnectError = error; _logger.Info("HandlingRequestsWrapper: Disconnecting unexpectedly, queuing Disconnect"); Queued(Disconnect); return; } InvokeStateChanged(state.WithError(error)); return; } InvokeStateChanged(WithFallbackRemoteIp(state, _endpoint.Server.Ip)); }
private static VpnStateChangedEventArgs Map(VpnStateContract contract) { VpnStatus status = Map(contract.Status); VpnError error = Map(contract.Error); VpnProtocol protocol = Map(contract.VpnProtocol); return(new(status, error, contract.EndpointIp, contract.NetworkBlocked, protocol, contract.OpenVpnAdapterType, contract.Label)); }
private static VpnStateChangedEventArgs Map(VpnStateContract contract) { VpnStatus status = Map(contract.Status); VpnError error = Map(contract.Error); VpnProtocol protocol = Map(contract.Protocol); return(new VpnStateChangedEventArgs(status, error, contract.EndpointIp, contract.NetworkBlocked, protocol)); }
public VpnStateChangedEventArgs(VpnState state, VpnError error, bool networkBlocked) { Ensure.NotNull(state, nameof(state)); State = state; Error = error; NetworkBlocked = networkBlocked; }
public VpnState(VpnStatus status, VpnError error, string localIp, string remoteIp, VpnProtocol protocol = VpnProtocol.Auto) { Status = status; Error = error; LocalIp = localIp; RemoteIp = remoteIp; Protocol = protocol; }
public void Disconnect(VpnError error) { _connectRequested = false; _disconnectRequested = true; _disconnectError = error; _logger.Info("HandlingRequestsWrapper: Disconnect requested, queuing Disconnect"); Queued(Disconnect); }
private void ShowDisconnectErrorModalViewModel(VpnError error, bool networkBlocked) { dynamic options = new ExpandoObject(); options.Error = error; options.NetworkBlocked = networkBlocked; _modals.Show <DisconnectErrorModalViewModel>(options); }
public VpnStateChangedEventArgs(VpnState state, VpnError error, bool networkBlocked, VpnProtocol protocol = VpnProtocol.Auto) { Ensure.NotNull(state, nameof(state)); State = state; Error = error; NetworkBlocked = networkBlocked; Protocol = protocol; }
public static VpnState WithError(this VpnState state, VpnError error) { return(new VpnState( state.Status, error, state.LocalIp, state.RemoteIp, state.Protocol)); }
public VpnState(VpnStatus status, VpnError error, string localIp, string remoteIp, VpnProtocol vpnProtocol, OpenVpnAdapter?openVpnAdapter = null, string label = "") { Status = status; Error = error; LocalIp = localIp; RemoteIp = remoteIp; OpenVpnAdapter = openVpnAdapter; VpnProtocol = vpnProtocol; Label = label; }
public static VpnState WithError(this VpnState state, VpnError error) { return(new( state.Status, error, state.LocalIp, state.RemoteIp, state.VpnProtocol, state.OpenVpnAdapter, state.Label)); }
public void Disconnect(VpnError error) { if (VpnConnection == null) { OnStateChanged(this, new EventArgs <VpnState>(new VpnState(VpnStatus.Disconnected, VpnProtocol.Smart))); } else { VpnConnection.Disconnect(error); } }
public void VpnError_ShouldBe(VpnError expected, string message) { // Arrange var error = new ManagementError(message); // Act var result = error.VpnError(); // Assert result.Should().Be(expected); }
public void Connect(VpnEndpoint endpoint, VpnCredentials credentials, VpnConfig config) { _endpoint = endpoint; _credentials = credentials; _config = config; _connectRequested = true; _disconnectRequested = false; _disconnectError = VpnError.Unknown; _logger.Info("HandlingRequestsWrapper: Connect requested, queuing Connect"); Queued(Connect); }
private void SetupUnexpectedDisconnect(VpnError error) { _origin.StateChanged += (s, e) => { if (e.Data.Status == VpnStatus.Connected) { _taskQueue.Enqueue(() => RaiseStateChangedEvents( new [] { new VpnState(VpnStatus.Disconnecting, error), new VpnState(VpnStatus.Disconnected, error) })); } }; }
private async Task UpdateServersOrDisconnect(VpnError disconnectReason) { if (_state.Status == VpnStatus.Disconnecting || _state.Status == VpnStatus.Disconnected || _lastProfile == null) { return; } _lastServerCandidates = _profileConnector.ServerCandidates(_lastProfile); if (!await _profileConnector.UpdateServers(_lastServerCandidates, _lastProfile)) { await _vpnServiceManager.Disconnect(disconnectReason); } }
private async Task HandleStateMessage(ReceivedManagementMessage message) { ManagementState managementState = message.State(); if (managementState.HasError) { await TrySend(_managementChannel.Messages.Disconnect()); if (_lastError == VpnError.None) { _lastError = managementState.Error; } } else { if (managementState.HasStatus) { OnVpnStateChanged(new VpnState(managementState.Status, _lastError, managementState.LocalIpAddress, managementState.RemoteIpAddress, default, label: _endpoint.Server.Label));
private void ManagementClient_StateChanged(object sender, EventArgs <VpnState> e) { _logger.Info($"ManagementClient: State changed to {e.Data.Status}"); var state = e.Data; if ((state.Status == VpnStatus.Connecting || state.Status == VpnStatus.Reconnecting) && string.IsNullOrEmpty(state.RemoteIp)) { state = new VpnState(state.Status, VpnError.None, string.Empty, _endpoint.Server.Ip, _endpoint.Protocol); } if (state.Status == VpnStatus.Disconnecting && !_disconnectAction.IsRunning) { _disconnectError = state.Error; } OnStateChanged(state); }
public VpnException(VpnError error, Pack?pack = null) : base($"{ErrorToStr(error)}") { this.Error = error; this.Pack = pack?.Clone() ?? null; if (this.Pack != null) { if (error == VpnError.ERR_RECV_MSG) { // メッセージ付きエラー this.RecvMsg = this.Pack["Msg"].UniStrValueNonNull; } if (error == VpnError.ERR_RECV_URL) { // URL 付きエラー this.RecvUrl = this.Pack["Url"].StrValueNonNull; } } }
private void OnStateChanged(VpnState state) { _disconnected = state.Status == VpnStatus.Disconnected; if (_connectRequested) { InvokeConnecting(); if (_disconnected) { _logger.Info("HandlingRequestsWrapper: Already disconnected, queuing Connect"); Queued(Connect); } return; } if (_disconnectRequested || _disconnecting) { if (state.Status == VpnStatus.Disconnecting || state.Status == VpnStatus.Disconnected) { InvokeStateChanged(new VpnState(state.Status, _disconnectError)); return; } InvokeDisconnecting(); return; } if (_connecting && state.Status == VpnStatus.Disconnecting) { // Force disconnect if disconnected while connecting _disconnectRequested = true; _disconnectError = state.Error; _logger.Info("HandlingRequestsWrapper: Disconnecting unexpectedly, queuing Disconnect"); Queued(Disconnect); } InvokeStateChanged(state); }
/// <summary> /// Primary VPN connect method, doesn't finish until disconnect. /// This method will raise <see cref="TransportStatsChanged"/>, <see cref="VpnStateChanged"/> /// </summary> /// <param name="credentials"><see cref="VpnCredentials"/> (username and password) for authenticating to VPN server</param> /// <param name="endpoint"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task StartVpnConnection(VpnCredentials credentials, VpnEndpoint endpoint, CancellationToken cancellationToken) { _lastError = VpnError.None; _credentials = credentials; _endpoint = endpoint; _sendingFailed = false; _disconnectRequested = false; _disconnectAccepted = false; while (!cancellationToken.IsCancellationRequested && !_sendingFailed) { ReceivedManagementMessage message = await Receive(); if (message.IsChannelDisconnected) { if (!_disconnectRequested && _lastError == VpnError.None) { _lastError = VpnError.Unknown; } OnVpnStateChanged(VpnStatus.Disconnecting); return; } if (!cancellationToken.IsCancellationRequested) { HandleMessage(message); } } if (!_sendingFailed) { await SendExit(); } if (!cancellationToken.IsCancellationRequested && _sendingFailed) { OnVpnStateChanged(VpnStatus.Disconnecting); } }
private async Task ReceiveLogsAction(CancellationToken cancellationToken) { uint cursor = RingLogger.CursorAll; while (true) { List <string> lines = _ringLogger.FollowFromCursor(ref cursor); foreach (string line in lines) { _logger.Info(GetFormattedMessage(line)); if (line.Contains("Interface up")) { InvokeStateChange(VpnStatus.Connected); } else if (line.Contains("Shutting down")) { InvokeStateChange(VpnStatus.Disconnected, _lastError); _lastError = VpnError.None; } else if (line.Contains("Could not install driver")) { _lastError = VpnError.NoTapAdaptersError; } } try { Thread.Sleep(300); } catch { break; } cancellationToken.ThrowIfCancellationRequested(); } }
public WpcResult(VpnError errorCode, Pack?pack = null, string?additionalErrorStr = null, [CallerFilePath] string filename = "", [CallerLineNumber] int line = 0, [CallerMemberName] string?caller = null) { if (pack == null) { pack = new Pack(); } this.Pack = pack; this.ErrorCode = errorCode; this.Pack.AddInt("Error", (uint)this.ErrorCode); if (this.IsError) { this.AdditionalErrorStr = additionalErrorStr._NonNullTrim(); if (this.AdditionalErrorStr._IsEmpty()) { this.AdditionalErrorStr = null; } this.ErrorLocation = $"{filename}:{line} by {caller}"; } }