public void RasGetConnectionStatisticsAsExpected() { var hRasConn = new IntPtr(1); var lpStatistics = new RAS_STATS(); api.Setup(o => o.RasGetConnectionStatistics(hRasConn, ref It.Ref <RAS_STATS> .IsAny)).Returns(SUCCESS); eventLoggingPolicy.Setup(o => o.LogEvent(It.IsAny <EventLevel>(), It.IsAny <PInvokeInt32CallCompletedTraceEvent>())).Callback(new LogEventCallback( (level, o1) => { Assert.AreEqual(EventLevel.Verbose, level); var eventData = (PInvokeInt32CallCompletedTraceEvent)o1; Assert.True(eventData.Args.ContainsKey(nameof(hRasConn))); Assert.True(eventData.OutArgs.ContainsKey(nameof(lpStatistics))); Assert.True(eventData.Duration > TimeSpan.Zero); Assert.AreEqual(SUCCESS, eventData.Result); })).Verifiable(); var target = new RasApi32LoggingAdvice(api.Object, eventLoggingPolicy.Object); var result = target.RasGetConnectionStatistics(hRasConn, ref lpStatistics); eventLoggingPolicy.Verify(); Assert.AreEqual(SUCCESS, result); }
private RAS_STATS GetStatDelta(RAS_STATS stat, RAS_STATS prevStat) => new RAS_STATS { dwBytesXmited = GetUintDelta(stat.dwBytesXmited, prevStat.dwBytesXmited), dwBytesRcved = GetUintDelta(stat.dwBytesRcved, prevStat.dwBytesRcved), dwBufferOverrunErr = GetUintDelta(stat.dwBufferOverrunErr, prevStat.dwBufferOverrunErr), dwCrcErr = GetUintDelta(stat.dwCrcErr, prevStat.dwCrcErr), dwFramingErr = GetUintDelta(stat.dwFramingErr, prevStat.dwFramingErr), dwHardwareOverrunErr = GetUintDelta(stat.dwHardwareOverrunErr, prevStat.dwHardwareOverrunErr), dwTimeoutErr = GetUintDelta(stat.dwTimeoutErr, prevStat.dwTimeoutErr), dwAlignmentErr = GetUintDelta(stat.dwAlignmentErr, prevStat.dwAlignmentErr), };
public int RasGetConnectionStatistics(IntPtr hRasConn, ref RAS_STATS lpStatistics) { var stopwatch = Stopwatch.StartNew(); var result = AttachedObject.RasGetConnectionStatistics(hRasConn, ref lpStatistics); stopwatch.Stop(); var callEvent = new PInvokeInt32CallCompletedTraceEvent { DllName = RasApi32Dll, Duration = stopwatch.Elapsed, MethodName = nameof(RasGetConnectionStatistics), Result = result }; callEvent.Args.Add(nameof(hRasConn), hRasConn); callEvent.OutArgs.Add(nameof(lpStatistics), lpStatistics); LogVerbose(callEvent); return(result); }
public static extern int RasGetConnectionStatistics( IntPtr hRasConn, [In, Out] ref RAS_STATS lpStatistics);
public int RasGetConnectionStatistics(IntPtr hRasConn, ref RAS_STATS lpStatistics) { return(SafeNativeMethods.RasGetConnectionStatistics(hRasConn, ref lpStatistics)); }
private async Task MaintainConnection(VpnData vpnData, CancellationToken cancellationToken, TaskCompletionSource <bool> firstTime, Action <VpnRuntimeState> onStateChanged) { Task awaitConnectionChanged = null; IntPtr handle = IntPtr.Zero; bool statInitialized = false; RAS_STATS prevStat = new RAS_STATS(); string serverIpAddress = null; try { while (!_cts.IsCancellationRequested) { try { if (handle == IntPtr.Zero) { Log.Information("VPN Connecting"); handle = await ReconnectAsync(vpnData, _cts.Token); var info = VpnApi.GetProjectionInfoEx(handle); serverIpAddress = $"{info.ipv4ServerAddress.addr[0]}.{info.ipv4ServerAddress.addr[1]}.{info.ipv4ServerAddress.addr[2]}.{info.ipv4ServerAddress.addr[3]}"; firstTime?.TrySetResult(true); firstTime = null; statInitialized = false; var eventHandle = VpnApi.RegisterForTermination(handle); awaitConnectionChanged = TaskHelper.WaitOneAsync(eventHandle, "VPN state changed"); } if (handle != IntPtr.Zero) { var status = VpnApi.GetState(handle); var stat = VpnApi.GetStatisitcs(handle); if (status.connectionState != RasConnectionState.Connected) { if (status.errorCode == 0) { throw new VpnException($"VPN in wrong '{status.connectionState}' state"); } else { throw new VpnException($"VPN error '{VpnApi.RasErrorMessage(status.errorCode)}'"); } } if (!statInitialized) { statInitialized = true; prevStat = stat; } var delta = GetStatDelta(stat, prevStat); prevStat = stat; if (delta.dwTimeoutErr + delta.dwFramingErr + delta.dwCrcErr + delta.dwHardwareOverrunErr + delta.dwBufferOverrunErr + delta.dwAlignmentErr > 0) { Log.Warning($"VPN errors {delta.dwTimeoutErr},{delta.dwFramingErr},{delta.dwCrcErr},{delta.dwHardwareOverrunErr},{delta.dwBufferOverrunErr},{delta.dwAlignmentErr}"); } onStateChanged(new VpnRuntimeState { Connected = true, SentKbs = (int)delta.dwBytesXmited / (1024 / 8), ReceivedKbs = (int)delta.dwBytesRcved / (1024 / 8), ServerIpAddress = serverIpAddress }); } } catch (Exception e) when(TaskHelper.IsCancellation(e)) { Log.Error(e, "VPN cancellation"); throw; } catch (Exception e) { Log.Error(e, "VPN maintanance error"); firstTime?.TrySetException(e); firstTime = null; serverIpAddress = null; onStateChanged(new VpnRuntimeState { Connected = false, ErrorMessage = e.Message }); await HangUpAsync(handle); handle = IntPtr.Zero; awaitConnectionChanged = null; } var delay = Task.Delay(1000, cancellationToken); if (awaitConnectionChanged != null) { var result = await Task.WhenAny(delay, awaitConnectionChanged); if (result == awaitConnectionChanged) { Log.Information("VPN short wait"); awaitConnectionChanged = null; //it is raised once and not usable anymore } } else { await delay; } } } finally { Log.Information("VPN exiting maintainance"); await HangUpAsync(handle); onStateChanged(new VpnRuntimeState { Connected = false }); _disconnected?.TrySetResult(true); } }