diff --git a/CHANGELOG.md b/CHANGELOG.md index b653c6d79..ec24c8c5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v2.8.360 +### Client +* Fix: Used traffic was not displayed correctly + +### Server +* Fix: Used traffic was not reported correctly + # v2.7.357 ### Client * Fix: Windows: Too long filter expression error diff --git a/Pub/Version.json b/Pub/Version.json index 636474647..465cda7c9 100644 --- a/Pub/Version.json +++ b/Pub/Version.json @@ -1,6 +1,6 @@ { - "Version": "2.7.357", - "BumpTime": "2023-03-10T02:50:07.6445704Z", + "Version": "2.8.360", + "BumpTime": "2023-03-12T01:19:57.7771871Z", "Prerelease": false, "DeprecatedVersion": "2.0.0" } diff --git a/Samples/VpnHood.Samples.SimpleClient.Droid/Resources/Resource.designer.cs b/Samples/VpnHood.Samples.SimpleClient.Droid/Resources/Resource.designer.cs index b8fb6c548..30bb4a204 100644 --- a/Samples/VpnHood.Samples.SimpleClient.Droid/Resources/Resource.designer.cs +++ b/Samples/VpnHood.Samples.SimpleClient.Droid/Resources/Resource.designer.cs @@ -14,7 +14,7 @@ namespace VpnHood.Samples.SimpleClient.Droid { - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "13.1.0.5")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "13.2.0.93")] public partial class Resource { diff --git a/VpnHood.Client.App.Android/Assets/SPA.zip b/VpnHood.Client.App.Android/Assets/SPA.zip index 5b2ee24b2..80ee0f7f9 100644 Binary files a/VpnHood.Client.App.Android/Assets/SPA.zip and b/VpnHood.Client.App.Android/Assets/SPA.zip differ diff --git a/VpnHood.Client.App.Android/Properties/AndroidManifest.xml b/VpnHood.Client.App.Android/Properties/AndroidManifest.xml index b3329fc9d..3a5fe79c1 100644 --- a/VpnHood.Client.App.Android/Properties/AndroidManifest.xml +++ b/VpnHood.Client.App.Android/Properties/AndroidManifest.xml @@ -1,5 +1,5 @@  - + diff --git a/VpnHood.Client.App.UI/VpnHood.Client.App.UI.csproj b/VpnHood.Client.App.UI/VpnHood.Client.App.UI.csproj index 0d864283b..72ad62637 100644 --- a/VpnHood.Client.App.UI/VpnHood.Client.App.UI.csproj +++ b/VpnHood.Client.App.UI/VpnHood.Client.App.UI.csproj @@ -12,8 +12,8 @@ VpnHood.png Tiny internal webserver to server your single-page application (SPA). You need this only if you want to create a UI for your VpnHood client by single-page application (SPA). VpnHood.Client.App.UI - 2.7.357 - 2.7.357 + 2.8.360 + 2.8.360 $([System.DateTime]::Now.ToString("yyyy.M.d.HHmm")) enable latest diff --git a/VpnHood.Client.App.UI/VpnHoodAppUI.cs b/VpnHood.Client.App.UI/VpnHoodAppUI.cs index 7902465fa..e86f69be8 100644 --- a/VpnHood.Client.App.UI/VpnHoodAppUI.cs +++ b/VpnHood.Client.App.UI/VpnHoodAppUI.cs @@ -61,7 +61,7 @@ public static VpnHoodAppUi Init(Stream zipStream, int defaultPort = 9090, Uri? u private void Start() { - _url1 = new Uri($"http://{Util.GetFreeTcpEndPoint(IPAddress.Loopback, DefaultPort)}"); + _url1 = new Uri($"http://{VhUtil.GetFreeTcpEndPoint(IPAddress.Loopback, DefaultPort)}"); _server = CreateWebServer(Url1, Url2, GetSpaPath()); try { @@ -117,7 +117,7 @@ private WebServer CreateWebServer(Uri url1, Uri? url2, string spaPath) { // read index.html for fallback _indexHtml = File.ReadAllText(Path.Combine(spaPath, "index.html")); - var urlPrefixes = new string[] { url1.AbsoluteUri }; + var urlPrefixes = new[] { url1.AbsoluteUri }; if (url2 != null) urlPrefixes = urlPrefixes.Concat(new[] { url2.AbsoluteUri }).ToArray(); // create the server diff --git a/VpnHood.Client.App.Win/Resources/SPA.zip b/VpnHood.Client.App.Win/Resources/SPA.zip index 5b2ee24b2..80ee0f7f9 100644 Binary files a/VpnHood.Client.App.Win/Resources/SPA.zip and b/VpnHood.Client.App.Win/Resources/SPA.zip differ diff --git a/VpnHood.Client.App.Win/VpnHood.Client.App.Win.csproj b/VpnHood.Client.App.Win/VpnHood.Client.App.Win.csproj index 756a5c415..832962a19 100644 --- a/VpnHood.Client.App.Win/VpnHood.Client.App.Win.csproj +++ b/VpnHood.Client.App.Win/VpnHood.Client.App.Win.csproj @@ -19,8 +19,8 @@ VpnHood.png VpnHood.Client.App.Win - 2.7.357 - 2.7.357 + 2.8.360 + 2.8.360 $([System.DateTime]::Now.ToString("yyyy.M.d.HHmm")) enable 11 diff --git a/VpnHood.Client.App.Win/WinApp.cs b/VpnHood.Client.App.Win/WinApp.cs index 6b1bf583f..66dab1cf9 100644 --- a/VpnHood.Client.App.Win/WinApp.cs +++ b/VpnHood.Client.App.Win/WinApp.cs @@ -29,7 +29,7 @@ public class WinApp : IDisposable private bool _disposed; private bool _showWindowAfterStart; private string AppLocalDataPath { get; } - public Uri LocalHostUrl = new($"http://myvpnhood"); + public Uri LocalHostUrl = new("http://myvpnhood"); public WinApp() { @@ -94,6 +94,7 @@ public void Start(string[] args) } catch { + // ignored } // configuring Windows Firewall @@ -242,7 +243,7 @@ private void CheckForUpdate() public void OpenMainWindow() { - if (_webViewWindow != null && _webViewWindow.IsInitCompleted) + if (_webViewWindow is { IsInitCompleted: true }) _webViewWindow.Show(); else OpenMainWindowInBrowser(); @@ -321,7 +322,7 @@ private void Menu_Opening(object? sender, CancelEventArgs e) var menu = (ContextMenuStrip)sender!; menu.Items["connect"].Enabled = VhApp.IsIdle; menu.Items["disconnect"].Enabled = !VhApp.IsIdle && VhApp.State.ConnectionState != AppConnectionState.Disconnecting; - menu.Items["open"].Visible = _webViewWindow != null && _webViewWindow.IsInitCompleted; + menu.Items["open"].Visible = _webViewWindow is { IsInitCompleted: true }; menu.Items["openInBrowser"].Visible = true; } @@ -400,11 +401,12 @@ public void Dispose() private void RegisterLocalDomain() { var hostsFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "drivers", "etc", "hosts"); - var hosts = File.ReadLines(hostsFilePath); + var hosts = File.ReadLines(hostsFilePath).ToList(); var hostItem = $"{LocalHostIpAddress} {LocalHostUrl.Host}"; + if (!hosts.Contains(hostItem)) { - hosts = hosts.Concat(new[] { hostItem }); + hosts.Add(hostItem); File.WriteAllLines(hostsFilePath, hosts.ToArray()); } } diff --git a/VpnHood.Client.App/AppState.cs b/VpnHood.Client.App/AppState.cs index 601400c9f..b5f474faf 100644 --- a/VpnHood.Client.App/AppState.cs +++ b/VpnHood.Client.App/AppState.cs @@ -1,4 +1,5 @@ using System; +using VpnHood.Common.Messaging; namespace VpnHood.Client.App; @@ -15,10 +16,9 @@ public class AppState public bool HasDisconnectedByUser { get; internal set; } public bool HasProblemDetected { get; internal set; } public SessionStatus? SessionStatus { get; internal set; } - public long SendSpeed { get; internal set; } - public long SentTraffic { get; internal set; } - public long ReceiveSpeed { get; internal set; } - public long ReceivedTraffic { get; internal set; } + public Traffic Speed { get; internal set; } = new (); + public Traffic SessionTraffic { get; internal set; } = new (); + public Traffic AccountTraffic { get; internal set; } = new (); public IpGroup? ClientIpGroup { get; internal set; } public bool IsWaitingForAd { get; internal set; } public VersionStatus VersionStatus { get; internal set; } diff --git a/VpnHood.Client.App/ClientProfileStore.cs b/VpnHood.Client.App/ClientProfileStore.cs index 325717137..62a704d5d 100644 --- a/VpnHood.Client.App/ClientProfileStore.cs +++ b/VpnHood.Client.App/ClientProfileStore.cs @@ -79,7 +79,7 @@ public async Task UpdateTokenFromUrl(Token token) try { using var client = new HttpClient(); - var accessKey = await Util.RunTask(client.GetStringAsync(token.Url), TimeSpan.FromSeconds(20)); + var accessKey = await VhUtil.RunTask(client.GetStringAsync(token.Url), TimeSpan.FromSeconds(20)); var newToken = Token.FromAccessKey(accessKey); if (newToken.TokenId != token.TokenId) throw new InvalidOperationException($"Could not updated Token because {nameof(token.TokenId)} has been changed! TokenId: {VhLogger.FormatId(token.TokenId)}"); diff --git a/VpnHood.Client.App/VpnHood.Client.App.csproj b/VpnHood.Client.App/VpnHood.Client.App.csproj index e69bba2bf..14e9bd882 100644 --- a/VpnHood.Client.App/VpnHood.Client.App.csproj +++ b/VpnHood.Client.App/VpnHood.Client.App.csproj @@ -11,8 +11,8 @@ https://github.com/vpnhood/vpnhood Readymade Vpn App skeleton for VpnHood clients. You just need to create a UI on it. VpnHood.Client.App - 2.7.357 - 2.7.357 + 2.8.360 + 2.8.360 $([System.DateTime]::Now.ToString("yyyy.M.d.HHmm")) enable latest diff --git a/VpnHood.Client.App/VpnHoodApp.cs b/VpnHood.Client.App/VpnHoodApp.cs index e8f2447eb..d69a8238f 100644 --- a/VpnHood.Client.App/VpnHoodApp.cs +++ b/VpnHood.Client.App/VpnHoodApp.cs @@ -14,6 +14,7 @@ using VpnHood.Common; using VpnHood.Common.JobController; using VpnHood.Common.Logging; +using VpnHood.Common.Messaging; using VpnHood.Common.Net; using VpnHood.Common.Utils; using VpnHood.Tunneling; @@ -128,10 +129,9 @@ private VpnHoodApp(IAppProvider clientAppProvider, AppOptions? options = default HasDisconnectedByUser = _hasDisconnectedByUser, HasProblemDetected = _hasConnectRequested && IsIdle && (_hasDiagnoseStarted || LastError != null), SessionStatus = LastSessionStatus, - ReceiveSpeed = Client?.ReceiveSpeed ?? 0, - ReceivedTraffic = Client?.ReceivedByteCount ?? 0, - SendSpeed = Client?.SendSpeed ?? 0, - SentTraffic = Client?.SentByteCount ?? 0, + Speed = Client?.Speed ?? new Traffic(), + AccountTraffic = Client?.AccountTraffic ?? new Traffic(), + SessionTraffic = Client?.SessionTraffic ?? new Traffic(), ClientIpGroup = _lastClientIpGroup, IsWaitingForAd = IsWaitingForAd, VersionStatus = VersionStatus, @@ -389,9 +389,9 @@ private async Task ConnectInternal(IPacketCapture packetCapture, Guid tokenId, s // calculate packetCaptureIpRanges var packetCaptureIpRanges = IpNetwork.All.ToIpRanges(); - if (!Util.IsNullOrEmpty(UserSettings.PacketCaptureIncludeIpRanges)) + if (!VhUtil.IsNullOrEmpty(UserSettings.PacketCaptureIncludeIpRanges)) packetCaptureIpRanges = packetCaptureIpRanges.Intersect(UserSettings.PacketCaptureIncludeIpRanges); - if (!Util.IsNullOrEmpty(UserSettings.PacketCaptureExcludeIpRanges)) + if (!VhUtil.IsNullOrEmpty(UserSettings.PacketCaptureExcludeIpRanges)) packetCaptureIpRanges = packetCaptureIpRanges.Exclude(UserSettings.PacketCaptureExcludeIpRanges); // create clientOptions @@ -446,7 +446,7 @@ private void ClientConnect_StateChanged(object sender, EventArgs e) private async Task GetIncludeIpRanges(FilterMode filterMode, string[]? ipGroupIds) { - if (filterMode == FilterMode.All || Util.IsNullOrEmpty(ipGroupIds)) + if (filterMode == FilterMode.All || VhUtil.IsNullOrEmpty(ipGroupIds)) return null; if (filterMode == FilterMode.Include) @@ -501,7 +501,7 @@ public async Task Disconnect(bool byUser = false) // check for any success if (Client != null) { - _hasAnyDataArrived = Client.ReceivedByteCount > 1000; + _hasAnyDataArrived = Client.SessionTraffic.Received > 1000; if (LastError == null && !_hasAnyDataArrived && UserSettings is { IpGroupFiltersMode: FilterMode.All, TunnelClientCountry: true }) _lastException = new Exception("No data has arrived!"); } @@ -591,7 +591,7 @@ public async Task CheckNewVersion() using var httpClient = new HttpClient(); var publishInfoJson = await httpClient.GetStringAsync(Features.UpdateInfoUrl); - LatestPublishInfo = Util.JsonDeserialize(publishInfoJson); + LatestPublishInfo = VhUtil.JsonDeserialize(publishInfoJson); // Check version if (LatestPublishInfo.Version == null) diff --git a/VpnHood.Client.Device.Android/AndroidPacketCapture.cs b/VpnHood.Client.Device.Android/AndroidPacketCapture.cs index 8a31ced94..f59375bf4 100644 --- a/VpnHood.Client.Device.Android/AndroidPacketCapture.cs +++ b/VpnHood.Client.Device.Android/AndroidPacketCapture.cs @@ -236,7 +236,7 @@ private Task ReadingPacketTask() } catch (Exception ex) { - if (!Util.IsSocketClosedException(ex)) + if (!VhUtil.IsSocketClosedException(ex)) VhLogger.Instance.LogError($"ReadingPacketTask: {ex}"); } diff --git a/VpnHood.Client.Device.WinDivert/VpnHood.Client.Device.WinDivert.csproj b/VpnHood.Client.Device.WinDivert/VpnHood.Client.Device.WinDivert.csproj index c1dd004f5..68eec63c0 100644 --- a/VpnHood.Client.Device.WinDivert/VpnHood.Client.Device.WinDivert.csproj +++ b/VpnHood.Client.Device.WinDivert/VpnHood.Client.Device.WinDivert.csproj @@ -9,10 +9,10 @@ https://github.com/vpnhood/vpnhood VpnHood.png VpnHood client device provider for Windows using WinDivert. - 2.7.357 + 2.8.360 VpnHood.Client.Device.WinDivert 1.1.226 - 2.7.357 + 2.8.360 $([System.DateTime]::Now.ToString("yyyy.M.d.HHmm")) enable latest diff --git a/VpnHood.Client.Device/VpnHood.Client.Device.csproj b/VpnHood.Client.Device/VpnHood.Client.Device.csproj index 521b0e305..4a95f31f7 100644 --- a/VpnHood.Client.Device/VpnHood.Client.Device.csproj +++ b/VpnHood.Client.Device/VpnHood.Client.Device.csproj @@ -14,8 +14,8 @@ VpnHood.Client.Device VpnHood.Client.Device - 2.7.357 - 2.7.357 + 2.8.360 + 2.8.360 $([System.DateTime]::Now.ToString("yyyy.M.d.HHmm")) enable latest diff --git a/VpnHood.Client/Diagnosing/DiagnoseUtil.cs b/VpnHood.Client/Diagnosing/DiagnoseUtil.cs index 29926cc0a..0816a8f0c 100644 --- a/VpnHood.Client/Diagnosing/DiagnoseUtil.cs +++ b/VpnHood.Client/Diagnosing/DiagnoseUtil.cs @@ -187,7 +187,7 @@ public static async Task GetHostEntry(string host, IPEndPoint dnsEn udpClient.Client.SendTimeout = timeout; udpClient.Client.ReceiveTimeout = timeout; await udpClient.SendAsync(buffer, buffer.Length, dnsEndPoint); - var receiveTask = await Util.RunTask(udpClient.ReceiveAsync(), TimeSpan.FromMilliseconds(timeout)); + var receiveTask = await VhUtil.RunTask(udpClient.ReceiveAsync(), TimeSpan.FromMilliseconds(timeout)); buffer = receiveTask.Buffer; //The response message has the same header and question structure, so we move index to the answer part directly. diff --git a/VpnHood.Client/TcpProxyHost.cs b/VpnHood.Client/TcpProxyHost.cs index c11fa55be..90fc4e1c9 100644 --- a/VpnHood.Client/TcpProxyHost.cs +++ b/VpnHood.Client/TcpProxyHost.cs @@ -83,7 +83,7 @@ private async Task AcceptTcpClientLoop(TcpListener tcpListener) { while (!cancellationToken.IsCancellationRequested) { - var tcpClient = await Util.RunTask(tcpListener.AcceptTcpClientAsync(), default, cancellationToken); + var tcpClient = await VhUtil.RunTask(tcpListener.AcceptTcpClientAsync(), default, cancellationToken); _ = ProcessClient(tcpClient, cancellationToken); } } @@ -246,7 +246,7 @@ await Client.AddPassthruTcpStream( Client.SessionId, Client.SessionKey, new IPEndPoint(natItem.DestinationAddress, natItem.DestinationPort), - Util.GenerateSessionKey(), + VhUtil.GenerateSessionKey(), natItem.DestinationPort == 443 ? TunnelUtil.TlsHandshakeLength : -1); tcpProxyClientStream = await Client.GetTlsConnectionToServer(GeneralEventId.TcpProxyChannel, cancellationToken); diff --git a/VpnHood.Client/VpnHood.Client.csproj b/VpnHood.Client/VpnHood.Client.csproj index 1d7e3164c..9a816eec7 100644 --- a/VpnHood.Client/VpnHood.Client.csproj +++ b/VpnHood.Client/VpnHood.Client.csproj @@ -13,8 +13,8 @@ 2022 VpnHood VpnHood.Client VPN VpnClient Proxy - 2.7.357 - 2.7.357 + 2.8.360 + 2.8.360 $([System.DateTime]::Now.ToString("yyyy.M.d.HHmm")) enable latest diff --git a/VpnHood.Client/VpnHoodClient.cs b/VpnHood.Client/VpnHoodClient.cs index 527c1eb77..f6a6b2a3f 100644 --- a/VpnHood.Client/VpnHoodClient.cs +++ b/VpnHood.Client/VpnHoodClient.cs @@ -47,6 +47,7 @@ public void Clear() } } + private bool _disposed; private readonly bool _autoDisposePacketCapture; private readonly CancellationTokenSource _cancellationTokenSource; private readonly CancellationToken _cancellationToken; @@ -56,7 +57,6 @@ public void Clear() private readonly IPacketCapture _packetCapture; private readonly SendingPackets _sendingPacket = new(); private readonly TcpProxyHost _tcpProxyHost; - private bool _disposed; private readonly SemaphoreSlim _datagramChannelsSemaphore = new(1, 1); private DateTime? _lastConnectionErrorTime; private byte[]? _sessionKey; @@ -68,6 +68,7 @@ public void Clear() private readonly TimeSpan _maxTcpDatagramLifespan; private bool _udpChannelAdded; private DateTime _lastReceivedPacketTime = DateTime.MinValue; + private Traffic _helloTraffic = new (); private int ProtocolVersion { get; } private bool IsTcpDatagramLifespanSupported => ServerVersion?.Build >= 345; //will be deprecated @@ -88,10 +89,9 @@ public void Clear() public SessionStatus SessionStatus { get; private set; } = new(); public Version Version { get; } public bool ExcludeLocalNetwork { get; } - public long ReceiveSpeed => Tunnel.ReceiveSpeed; - public long ReceivedByteCount => Tunnel.ReceivedByteCount; - public long SendSpeed => Tunnel.SendSpeed; - public long SentByteCount => Tunnel.SentByteCount; + public Traffic Speed => Tunnel.Speed; + public Traffic SessionTraffic => Tunnel.Traffic; + public Traffic AccountTraffic => _helloTraffic + SessionTraffic; public bool UseUdpChannel { get; set; } public IpRange[] IncludeIpRanges { get; private set; } = IpNetwork.All.ToIpRanges().ToArray(); public IpRange[] PacketCaptureIncludeIpRanges { get; private set; } @@ -107,7 +107,7 @@ public VpnHoodClient(IPacketCapture packetCapture, Guid clientId, Token token, C if (options.TcpProxyCatcherAddressIpV6 == null) throw new ArgumentNullException(nameof(options.TcpProxyCatcherAddressIpV6)); - if (!Util.IsInfinite(_maxTcpDatagramLifespan) && _maxTcpDatagramLifespan < _minTcpDatagramLifespan) + if (!VhUtil.IsInfinite(_maxTcpDatagramLifespan) && _maxTcpDatagramLifespan < _minTcpDatagramLifespan) throw new ArgumentNullException(nameof(options.MaxTcpDatagramTimespan), $"{nameof(options.MaxTcpDatagramTimespan)} must be bigger or equal than {nameof(options.MinTcpDatagramTimespan)}."); DnsServers = options.DnsServers ?? throw new ArgumentNullException(nameof(options.DnsServers)); @@ -154,8 +154,8 @@ public VpnHoodClient(IPacketCapture packetCapture, Guid clientId, Token token, C #endif } - public byte[] SessionKey => _sessionKey ?? - throw new InvalidOperationException($"{nameof(SessionKey)} has not been initialized!"); + public byte[] SessionKey => _sessionKey + ?? throw new InvalidOperationException($"{nameof(SessionKey)} has not been initialized!"); public ClientState State { @@ -186,7 +186,7 @@ internal async Task AddPassthruTcpStream(TcpClientStream orgTcpClientStream, IPE // connect to host _packetCapture.ProtectSocket(tcpClient.Client); - await Util.RunTask(tcpClient.ConnectAsync(hostEndPoint.Address, hostEndPoint.Port), cancellationToken: cancellationToken); + await VhUtil.RunTask(tcpClient.ConnectAsync(hostEndPoint.Address, hostEndPoint.Port), cancellationToken: cancellationToken); // create add add channel var bypassChannel = new TcpProxyChannel(orgTcpClientStream, new TcpClientStream(tcpClient, tcpClient.GetStream()), TunnelUtil.TcpTimeout); @@ -279,7 +279,7 @@ private void ConfigPacketFilter(IPEndPoint hostEndPoint) private void Tunnel_OnChannelRemoved(object sender, ChannelEventArgs e) { // device is sleep. Don't wake it up - if (!Util.IsInfinite(_maxTcpDatagramLifespan) && FastDateTime.Now - _lastReceivedPacketTime > _maxTcpDatagramLifespan) + if (!VhUtil.IsInfinite(_maxTcpDatagramLifespan) && FastDateTime.Now - _lastReceivedPacketTime > _maxTcpDatagramLifespan) return; if (e.Channel is IDatagramChannel) @@ -433,7 +433,7 @@ private static bool IsIcmpControlMessage(IPPacket ipPacket) public bool IsInIpRange(IPAddress ipAddress) { // all IPs are included if there is no filter - if (Util.IsNullOrEmpty(IncludeIpRanges)) + if (VhUtil.IsNullOrEmpty(IncludeIpRanges)) return true; // check tcp-loopback @@ -620,7 +620,7 @@ internal async Task GetTlsConnectionToServer(EventId eventId, C // Client.SessionTimeout does not affect in ConnectAsync VhLogger.Instance.LogTrace(eventId, $"Connecting to Server: {VhLogger.Format(HostEndPoint)}..."); - await Util.RunTask(tcpClient.ConnectAsync(HostEndPoint.Address, HostEndPoint.Port), TcpTimeout, cancellationToken); + await VhUtil.RunTask(tcpClient.ConnectAsync(HostEndPoint.Address, HostEndPoint.Port), TcpTimeout, cancellationToken); // start TLS var stream = new SslStream(tcpClient.GetStream(), true, UserCertificateValidationCallback); @@ -689,7 +689,7 @@ private async Task ConnectInternal(CancellationToken cancellationToken, bool red // Create the hello Message var request = new HelloRequest(Token.TokenId, clientInfo, - Util.EncryptClientId(clientInfo.ClientId, Token.Secret)) + VhUtil.EncryptClientId(clientInfo.ClientId, Token.Secret)) { UseUdpChannel = UseUdpChannel }; @@ -712,22 +712,23 @@ private async Task ConnectInternal(CancellationToken cancellationToken, bool red // get session id SessionId = sessionResponse.SessionId != 0 ? sessionResponse.SessionId : throw new Exception("Invalid SessionId!"); _sessionKey = sessionResponse.SessionKey; + _helloTraffic = sessionResponse.AccessUsage?.Traffic ?? new Traffic(); SessionStatus.SuppressedTo = sessionResponse.SuppressedTo; PublicAddress = sessionResponse.ClientPublicAddress; IsIpV6Supported = sessionResponse.IsIpV6Supported; ServerVersion = Version.Parse(sessionResponse.ServerVersion); // PacketCaptureIpRanges - if (!Util.IsNullOrEmpty(sessionResponse.PacketCaptureIncludeIpRanges)) + if (!VhUtil.IsNullOrEmpty(sessionResponse.PacketCaptureIncludeIpRanges)) PacketCaptureIncludeIpRanges = PacketCaptureIncludeIpRanges.Intersect(sessionResponse.PacketCaptureIncludeIpRanges).ToArray(); // IncludeIpRanges - if (!Util.IsNullOrEmpty(sessionResponse.IncludeIpRanges) && !sessionResponse.IncludeIpRanges.ToIpNetworks().IsAll()) + if (!VhUtil.IsNullOrEmpty(sessionResponse.IncludeIpRanges) && !sessionResponse.IncludeIpRanges.ToIpNetworks().IsAll()) IncludeIpRanges = IncludeIpRanges.Intersect(sessionResponse.IncludeIpRanges).ToArray(); // Get IncludeIpRange for clientIp var filterIpRanges = _ipRangeProvider != null ? await _ipRangeProvider.GetIncludeIpRanges(sessionResponse.ClientPublicAddress) : null; - if (!Util.IsNullOrEmpty(filterIpRanges)) + if (!VhUtil.IsNullOrEmpty(filterIpRanges)) IncludeIpRanges = IncludeIpRanges.Intersect(filterIpRanges).ToArray(); // Preparing tunnel @@ -768,7 +769,7 @@ await SendRequest(tcpClientStream.Stream, RequestCode.TcpDa request, cancellationToken); // find timespan - var lifespan = !Util.IsInfinite(_maxTcpDatagramLifespan) && IsTcpDatagramLifespanSupported + var lifespan = !VhUtil.IsInfinite(_maxTcpDatagramLifespan) && IsTcpDatagramLifespanSupported ? TimeSpan.FromSeconds(new Random().Next((int)_minTcpDatagramLifespan.TotalSeconds, (int)_maxTcpDatagramLifespan.TotalSeconds)) : Timeout.InfiniteTimeSpan; @@ -883,7 +884,10 @@ private void Dispose(Exception ex) SessionStatus.ErrorMessage = sessionException.SessionResponseBase.ErrorMessage; SessionStatus.SuppressedBy = sessionException.SessionResponseBase.SuppressedBy; if (sessionException.SessionResponseBase.AccessUsage != null) //update AccessUsage if exists - SessionStatus.AccessUsage = sessionException.SessionResponseBase.AccessUsage; + { + SessionStatus.AccessUsage = sessionException.SessionResponseBase.AccessUsage; + SessionStatus.AccessUsage.Traffic = _helloTraffic; // let calculate it on client + } } else { diff --git a/VpnHood.Common/CommandListener.cs b/VpnHood.Common/CommandListener.cs index 8a0f98883..7a3071e2a 100644 --- a/VpnHood.Common/CommandListener.cs +++ b/VpnHood.Common/CommandListener.cs @@ -48,7 +48,7 @@ public void Start() _fileSystemWatcher.Changed += (_, e) => { var command = ReadAllTextAndWait(e.FullPath); - OnCommand(Util.ParseArguments(command).ToArray()); + OnCommand(VhUtil.ParseArguments(command).ToArray()); }; } catch (Exception ex) diff --git a/VpnHood.Common/JobController/JobSection.cs b/VpnHood.Common/JobController/JobSection.cs index 857c80dba..4ced6ede2 100644 --- a/VpnHood.Common/JobController/JobSection.cs +++ b/VpnHood.Common/JobController/JobSection.cs @@ -8,12 +8,13 @@ public class JobSection private readonly object _lockObject = new(); private bool _runnerEntered; private bool _normalEntered; - + private bool ShouldEnter => Elapsed > Interval && !_normalEntered; private bool ShouldRunnerEnter => Elapsed > Interval && !_normalEntered && !_runnerEntered; + public static TimeSpan DefaultInterval { get; set; } = TimeSpan.FromSeconds(30); public TimeSpan Elapsed => FastDateTime.Now - LastDoneTime; - public TimeSpan Interval { get; set; } = TimeSpan.FromSeconds(30); + public TimeSpan Interval { get; set; } = DefaultInterval; public DateTime LastDoneTime { get; private set; } = FastDateTime.Now; public JobSection() diff --git a/VpnHood.Common/Logging/VhLogger.cs b/VpnHood.Common/Logging/VhLogger.cs index 5d73347be..c329a523e 100644 --- a/VpnHood.Common/Logging/VhLogger.cs +++ b/VpnHood.Common/Logging/VhLogger.cs @@ -65,7 +65,7 @@ public static string Format(IPEndPoint? endPoint) public static string Format(IPAddress? ipAddress) { if (ipAddress == null) return ""; - return IsAnonymousMode ? Util.RedactIpAddress(ipAddress) : ipAddress.ToString(); + return IsAnonymousMode ? VhUtil.RedactIpAddress(ipAddress) : ipAddress.ToString(); } public static string FormatType(object? obj) diff --git a/VpnHood.Common/Messaging/AccessUsage.cs b/VpnHood.Common/Messaging/AccessUsage.cs index 80349ee08..a0081fef1 100644 --- a/VpnHood.Common/Messaging/AccessUsage.cs +++ b/VpnHood.Common/Messaging/AccessUsage.cs @@ -4,8 +4,7 @@ namespace VpnHood.Common.Messaging; public class AccessUsage { - public long SentTraffic { get; set; } - public long ReceivedTraffic { get; set; } + public Traffic Traffic { get; set; } = new (); public long MaxTraffic { get; set; } public DateTime? ExpirationTime { get; set; } public int MaxClientCount { get; set; } diff --git a/VpnHood.Common/Messaging/Traffic.cs b/VpnHood.Common/Messaging/Traffic.cs new file mode 100644 index 000000000..23b97290d --- /dev/null +++ b/VpnHood.Common/Messaging/Traffic.cs @@ -0,0 +1,96 @@ +using System; +using System.Text.Json.Serialization; + +namespace VpnHood.Common.Messaging; + +public class Traffic : IEquatable, ICloneable +{ + [Obsolete("Version 2.7.360 or upper")] + public long SentTraffic { set => Sent = value; } + [Obsolete("Version 2.7.360 or upper")] + public long ReceivedTraffic { set => Received = value; } + + public long Sent { get; set; } + public long Received { get; set; } + + [JsonIgnore] + public long Total => Sent + Received; + + public Traffic() + { + } + + public Traffic(long sent, long received) + { + Sent = sent; + Received = received; + } + + public void Add(Traffic traffic) + { + Sent += traffic.Sent; + Received += traffic.Received; + } + + public static Traffic operator +(Traffic traffic1, Traffic traffic2) + { + return new Traffic + { + Sent = traffic1.Sent + traffic2.Sent, + Received = traffic1.Received + traffic2.Received + }; + } + + public static Traffic operator -(Traffic traffic1, Traffic traffic2) + { + return new Traffic + { + Sent = traffic1.Sent - traffic2.Sent, + Received = traffic1.Received - traffic2.Received + }; + } + + public bool Equals(Traffic? other) + { + if (other == null) return false; + return Sent == other.Sent && Received == other.Received; + } + + public override bool Equals(object obj) + { + return Equals(obj as Traffic); + } + + public override int GetHashCode() + { + // ReSharper disable NonReadonlyMemberInGetHashCode + return HashCode.Combine(Sent, Received); + // ReSharper restore NonReadonlyMemberInGetHashCode + } + + public Traffic Clone() + { + return new Traffic + { + Sent = Sent, + Received = Received + }; + } + + object ICloneable.Clone() + { + return Clone(); + } + + public static bool operator ==(Traffic? traffic1, Traffic? traffic2) + { + if (ReferenceEquals(traffic1, traffic2)) return true; + if (traffic1 is null || traffic2 is null) return false; + return traffic1.Equals(traffic2); + } + + public static bool operator !=(Traffic traffic1, Traffic traffic2) + { + return !(traffic1 == traffic2); + } +} \ No newline at end of file diff --git a/VpnHood.Common/Token.cs b/VpnHood.Common/Token.cs index 64e1aef35..1653870e1 100644 --- a/VpnHood.Common/Token.cs +++ b/VpnHood.Common/Token.cs @@ -20,8 +20,8 @@ public class Token : ICloneable { public Token(byte[] secret, byte[] certificateHash, string hostName) { - if (Util.IsNullOrEmpty(secret)) throw new ArgumentException($"'{nameof(secret)}' cannot be null or empty.", nameof(secret)); - if (Util.IsNullOrEmpty(certificateHash)) throw new ArgumentException($"'{nameof(certificateHash)}' cannot be null or empty.", nameof(certificateHash)); + if (VhUtil.IsNullOrEmpty(secret)) throw new ArgumentException($"'{nameof(secret)}' cannot be null or empty.", nameof(secret)); + if (VhUtil.IsNullOrEmpty(certificateHash)) throw new ArgumentException($"'{nameof(certificateHash)}' cannot be null or empty.", nameof(certificateHash)); // after 2.2.276, hostName must exists; //remark for compatibility // if (string.IsNullOrEmpty(hostName)) throw new ArgumentException($"'{nameof(hostName)}' cannot be null or empty.", nameof(hostName)); @@ -69,7 +69,7 @@ public Token(byte[] secret, byte[] certificateHash, string hostName) public object Clone() { - return Util.JsonDeserialize(JsonSerializer.Serialize(this)); + return VhUtil.JsonDeserialize(JsonSerializer.Serialize(this)); } public string ToAccessKey() @@ -97,7 +97,7 @@ private async Task ResolveHostEndPointsInternalAsync() { VhLogger.Instance.LogInformation($"Resolving IP from host name: {VhLogger.FormatDns(HostName)}..."); var hostEntities = await Dns.GetHostEntryAsync(HostName); - if (!Util.IsNullOrEmpty(hostEntities.AddressList)) + if (!VhUtil.IsNullOrEmpty(hostEntities.AddressList)) { return hostEntities.AddressList .Select(x => new IPEndPoint(x, HostPort)) @@ -110,7 +110,7 @@ private async Task ResolveHostEndPointsInternalAsync() } } - if (!Util.IsNullOrEmpty(HostEndPoints)) + if (!VhUtil.IsNullOrEmpty(HostEndPoints)) return HostEndPoints; throw new Exception($"Could not resolve {nameof(HostEndPoints)} from token!"); @@ -119,7 +119,7 @@ private async Task ResolveHostEndPointsInternalAsync() public async Task ResolveHostEndPointsAsync() { var endPoints = await ResolveHostEndPointsInternalAsync(); - if (Util.IsNullOrEmpty(endPoints)) + if (VhUtil.IsNullOrEmpty(endPoints)) throw new Exception("Could not resolve any host endpoint from AccessToken!"); var ipV4EndPoints = endPoints.Where(x => x.AddressFamily == AddressFamily.InterNetwork).ToArray(); @@ -134,7 +134,7 @@ public async Task ResolveHostEndPointsAsync() public async Task ResolveHostEndPointAsync() { var endPoints = await ResolveHostEndPointsAsync(); - if (Util.IsNullOrEmpty(endPoints)) + if (VhUtil.IsNullOrEmpty(endPoints)) throw new Exception("Could not resolve any host endpoint!"); var rand = new Random(); diff --git a/VpnHood.Common/Utils/Util.cs b/VpnHood.Common/Utils/VhUtil.cs similarity index 92% rename from VpnHood.Common/Utils/Util.cs rename to VpnHood.Common/Utils/VhUtil.cs index e2cd217ee..4c2a5c20f 100644 --- a/VpnHood.Common/Utils/Util.cs +++ b/VpnHood.Common/Utils/VhUtil.cs @@ -13,7 +13,7 @@ namespace VpnHood.Common.Utils; -public static class Util +public static class VhUtil { public static bool IsConnectionRefusedException(Exception ex) { @@ -198,20 +198,24 @@ public static string RedactIpAddress(IPAddress ipAddress) return ipAddress.ToString(); } - public static string FormatBytes(long size) + public static string FormatBytes(long size, bool use1024 = true) { - // Get absolute value - if (size >= 0x10000000000) // Terabyte - return ((double)(size >> 30) / 1024).ToString("0.## ") + "TB"; + var kb = use1024 ? (long)1024 : 1000; + var mb = kb * kb; + var gb = mb * kb; + var tb = gb * kb; + + if (size >= tb) // Terabyte + return (size / tb).ToString("0.## ") + "TB"; - if (size >= 0x40000000) // Gigabyte - return ((double)(size >> 20) / 1024).ToString("0.# ") + "GB"; + if (size >= gb) // Gigabyte + return (size / gb).ToString("0.# ") + "GB"; - if (size >= 0x100000) // Megabyte - return ((double)(size >> 10) / 1024).ToString("0 ") + "MB"; + if (size >= mb) // Megabyte + return (size / mb).ToString("0 ") + "MB"; - if (size >= 1024) // Kilobyte - return ((double)size / 1024).ToString("0 ") + "KB"; + if (size >= kb) // Kilobyte + return (size / kb).ToString("0 ") + "KB"; if (size > 0) // Kilobyte return size.ToString("0 ") + "B"; diff --git a/VpnHood.Common/VpnHood.Common.csproj b/VpnHood.Common/VpnHood.Common.csproj index 5219157d7..412f6571b 100644 --- a/VpnHood.Common/VpnHood.Common.csproj +++ b/VpnHood.Common/VpnHood.Common.csproj @@ -12,8 +12,8 @@ VpnHood.Common VpnHood.png VpnHood Common Library is shared among all other VpnHood modules. - 2.7.357 - 2.7.357 + 2.8.360 + 2.8.360 $([System.DateTime]::Now.ToString("yyyy.M.d.HHmm")) enable latest diff --git a/VpnHood.Server.Access/IAccessServer.cs b/VpnHood.Server.Access/IAccessServer.cs index d02f5a450..0c449bc6e 100644 --- a/VpnHood.Server.Access/IAccessServer.cs +++ b/VpnHood.Server.Access/IAccessServer.cs @@ -12,8 +12,8 @@ public interface IAccessServer : IDisposable bool IsMaintenanceMode { get; } Task Session_Create(SessionRequestEx sessionRequestEx); Task Session_Get(uint sessionId, IPEndPoint hostEndPoint, IPAddress? clientIp); - Task Session_AddUsage(uint sessionId, UsageInfo usageInfo); - Task Session_Close(uint sessionId, UsageInfo usageInfo); + Task Session_AddUsage(uint sessionId, Traffic traffic); + Task Session_Close(uint sessionId, Traffic traffic); Task Server_UpdateStatus(ServerStatus serverStatus); Task Server_Configure(ServerInfo serverInfo); Task GetSslCertificateData(IPEndPoint hostEndPoint); diff --git a/VpnHood.Server.Access/Providers/FileAccessServerProvider/FileAccessServer.cs b/VpnHood.Server.Access/Providers/FileAccessServerProvider/FileAccessServer.cs index 86a6ec719..c142b57d0 100644 --- a/VpnHood.Server.Access/Providers/FileAccessServerProvider/FileAccessServer.cs +++ b/VpnHood.Server.Access/Providers/FileAccessServerProvider/FileAccessServer.cs @@ -107,17 +107,17 @@ public async Task Session_Get(uint sessionId, IPEndPoint host return SessionManager.GetSession(sessionId, accessItem, hostEndPoint); } - public Task Session_AddUsage(uint sessionId, UsageInfo usageInfo) + public Task Session_AddUsage(uint sessionId, Traffic traffic) { - return Session_AddUsage(sessionId, usageInfo, false); + return Session_AddUsage(sessionId, traffic, false); } - public Task Session_Close(uint sessionId, UsageInfo usageInfo) + public Task Session_Close(uint sessionId, Traffic traffic) { - return Session_AddUsage(sessionId, usageInfo, true); + return Session_AddUsage(sessionId, traffic, true); } - private async Task Session_AddUsage(uint sessionId, UsageInfo usageInfo, bool closeSession) + private async Task Session_AddUsage(uint sessionId, Traffic traffic, bool closeSession) { // find token var tokenId = SessionManager.TokenIdFromSessionId(sessionId); @@ -129,8 +129,7 @@ private async Task Session_AddUsage(uint sessionId, UsageIn if (accessItem == null) return new SessionResponseBase(SessionErrorCode.AccessError) { ErrorMessage = "Token does not exist." }; - accessItem.AccessUsage.SentTraffic += usageInfo.SentTraffic; - accessItem.AccessUsage.ReceivedTraffic += usageInfo.ReceivedTraffic; + accessItem.AccessUsage.Traffic += traffic; await WriteAccessItemUsage(accessItem); if (closeSession) @@ -256,7 +255,7 @@ public async Task AccessItem_Delete(Guid tokenId) return null; var json = await File.ReadAllTextAsync(fileName); - var accessItem = Util.JsonDeserialize(json); + var accessItem = VhUtil.JsonDeserialize(json); await ReadAccessItemUsage(accessItem); return accessItem; } @@ -281,8 +280,7 @@ private async Task ReadAccessItemUsage(AccessItem accessItem) { var json = await File.ReadAllTextAsync(fileName); var accessItemUsage = JsonSerializer.Deserialize(json) ?? new AccessItemUsage(); - accessItem.AccessUsage.ReceivedTraffic = accessItemUsage.ReceivedTraffic; - accessItem.AccessUsage.SentTraffic = accessItemUsage.SentTraffic; + accessItem.AccessUsage.Traffic = new Traffic { Sent = accessItemUsage.SentTraffic, Received = accessItemUsage.ReceivedTraffic }; } } catch (Exception ex) @@ -297,8 +295,8 @@ private async Task WriteAccessItemUsage(AccessItem accessItem) // write token info var accessItemUsage = new AccessItemUsage { - ReceivedTraffic = accessItem.AccessUsage.ReceivedTraffic, - SentTraffic = accessItem.AccessUsage.SentTraffic + ReceivedTraffic = accessItem.AccessUsage.Traffic.Received, + SentTraffic = accessItem.AccessUsage.Traffic.Sent }; var json = JsonSerializer.Serialize(accessItemUsage); diff --git a/VpnHood.Server.Access/Providers/FileAccessServerProvider/FileAccessServerSessionManager.cs b/VpnHood.Server.Access/Providers/FileAccessServerProvider/FileAccessServerSessionManager.cs index dcf515093..ccb33f456 100644 --- a/VpnHood.Server.Access/Providers/FileAccessServerProvider/FileAccessServerSessionManager.cs +++ b/VpnHood.Server.Access/Providers/FileAccessServerProvider/FileAccessServerSessionManager.cs @@ -52,7 +52,7 @@ private void CleanupSessions() private static bool ValidateRequest(SessionRequest sessionRequest, FileAccessServer.AccessItem accessItem) { - var encryptClientId = Util.EncryptClientId(sessionRequest.ClientInfo.ClientId, accessItem.Token.Secret); + var encryptClientId = VhUtil.EncryptClientId(sessionRequest.ClientInfo.ClientId, accessItem.Token.Secret); return encryptClientId.SequenceEqual(sessionRequest.EncryptedClientId); } @@ -71,7 +71,7 @@ public SessionResponseEx CreateSession(SessionRequestEx sessionRequestEx, ClientInfo = sessionRequestEx.ClientInfo, CreatedTime = FastDateTime.Now, LastUsedTime = FastDateTime.Now, - SessionKey = Util.GenerateSessionKey(), + SessionKey = VhUtil.GenerateSessionKey(), ErrorCode = SessionErrorCode.Ok, HostEndPoint = sessionRequestEx.HostEndPoint, ClientIp = sessionRequestEx.ClientIp @@ -119,7 +119,7 @@ private SessionResponseEx BuildSessionResponse(Session session, FileAccessServer // check traffic if (accessUsage.MaxTraffic != 0 && - accessUsage.SentTraffic + accessUsage.ReceivedTraffic > accessUsage.MaxTraffic) + accessUsage.Traffic.Total > accessUsage.MaxTraffic) return new SessionResponseEx(SessionErrorCode.AccessTrafficOverflow) { AccessUsage = accessUsage, ErrorMessage = "All traffic quota has been consumed!" }; diff --git a/VpnHood.Server.Access/Providers/HttpAccessServerProvider/HttpAccessServer.cs b/VpnHood.Server.Access/Providers/HttpAccessServerProvider/HttpAccessServer.cs index 55549b3ed..3e7071ba2 100644 --- a/VpnHood.Server.Access/Providers/HttpAccessServerProvider/HttpAccessServer.cs +++ b/VpnHood.Server.Access/Providers/HttpAccessServerProvider/HttpAccessServer.cs @@ -55,7 +55,7 @@ protected override async Task> HttpSendAsync(string urlPart, Di { return await base.HttpSendAsync(urlPart, parameters, request, cancellationToken); } - catch (Exception ex) when (Util.IsConnectionRefusedException(ex)) + catch (Exception ex) when (VhUtil.IsConnectionRefusedException(ex)) { IsMaintenanceMode = true; throw new MaintenanceException(); @@ -86,7 +86,7 @@ public Task Session_Get(uint sessionId, IPEndPoint hostEndPoi return HttpGetAsync($"sessions/{sessionId}", parameters); } - public Task Session_AddUsage(uint sessionId, UsageInfo usageInfo) + public Task Session_AddUsage(uint sessionId, Traffic traffic) { var parameters = new Dictionary { @@ -94,10 +94,10 @@ public Task Session_AddUsage(uint sessionId, UsageInfo usag { "closeSession", false} }; - return HttpPostAsync($"sessions/{sessionId}/usage", parameters, usageInfo); + return HttpPostAsync($"sessions/{sessionId}/usage", parameters, traffic); } - public Task Session_Close(uint sessionId, UsageInfo usageInfo) + public Task Session_Close(uint sessionId, Traffic traffic) { var parameters = new Dictionary { @@ -105,7 +105,7 @@ public Task Session_Close(uint sessionId, UsageInfo usageIn { "closeSession", true} }; - return HttpPostAsync($"sessions/{sessionId}/usage", parameters, usageInfo); + return HttpPostAsync($"sessions/{sessionId}/usage", parameters, traffic); } diff --git a/VpnHood.Server.Access/ServerStatus.cs b/VpnHood.Server.Access/ServerStatus.cs index cae71cf24..0ce189cde 100644 --- a/VpnHood.Server.Access/ServerStatus.cs +++ b/VpnHood.Server.Access/ServerStatus.cs @@ -1,4 +1,6 @@ -namespace VpnHood.Server; +using VpnHood.Common.Messaging; + +namespace VpnHood.Server; public class ServerStatus { @@ -9,7 +11,6 @@ public class ServerStatus public int? CpuUsage { get; set; } public long UsedMemory { get; set; } public int ThreadCount { get; set; } - public long TunnelSendSpeed { get; set; } - public long TunnelReceiveSpeed { get; set; } + public Traffic TunnelSpeed { get; set; } = new(); public string? ConfigCode { get; set; } } \ No newline at end of file diff --git a/VpnHood.Server.Access/UsageInfo.cs b/VpnHood.Server.Access/UsageInfo.cs deleted file mode 100644 index d67a7d06d..000000000 --- a/VpnHood.Server.Access/UsageInfo.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace VpnHood.Server; - -public class UsageInfo -{ - public long SentTraffic { get; set; } - public long ReceivedTraffic { get; set; } -} diff --git a/VpnHood.Server.Access/VpnHood.Server.Access.csproj b/VpnHood.Server.Access/VpnHood.Server.Access.csproj index 86deeef44..32fde8fc1 100644 --- a/VpnHood.Server.Access/VpnHood.Server.Access.csproj +++ b/VpnHood.Server.Access/VpnHood.Server.Access.csproj @@ -12,8 +12,8 @@ VpnHood.Server.Access VpnHood.png Stores, and retrieves end users' access and usage. Provides required interfaces and classes to use or create an access server and accounting. - 2.7.357 - 2.7.357 + 2.8.360 + 2.8.360 $([System.DateTime]::Now.ToString("yyyy.M.d.HHmm")) enable latest diff --git a/VpnHood.Server.App.Net/ServerApp.cs b/VpnHood.Server.App.Net/ServerApp.cs index 34be4c954..62ff7c26a 100644 --- a/VpnHood.Server.App.Net/ServerApp.cs +++ b/VpnHood.Server.App.Net/ServerApp.cs @@ -70,7 +70,7 @@ public ServerApp() } if (!File.Exists(appSettingsFilePath)) appSettingsFilePath = Path.Combine(AppFolderPath, "appsettings.json"); AppSettings = File.Exists(appSettingsFilePath) - ? Util.JsonDeserialize(File.ReadAllText(appSettingsFilePath)) + ? VhUtil.JsonDeserialize(File.ReadAllText(appSettingsFilePath)) : new AppSettings(); VhLogger.IsDiagnoseMode = AppSettings.IsDiagnoseMode; @@ -161,7 +161,7 @@ private static HttpAccessServer CreateHttpAccessServer(HttpAccessServerOptions o private void CommandListener_CommandReceived(object? sender, CommandReceivedEventArgs e) { - if (!Util.IsNullOrEmpty(e.Arguments) && e.Arguments[0] == "stop") + if (!VhUtil.IsNullOrEmpty(e.Arguments) && e.Arguments[0] == "stop") { VhLogger.Instance.LogInformation("I have received the stop command!"); _vpnHoodServer?.SessionManager.SyncSessions().Wait(); diff --git a/VpnHood.Server.App.Net/VpnHood.Server.App.Net.csproj b/VpnHood.Server.App.Net/VpnHood.Server.App.Net.csproj index fd8ffb8c9..d08f9d8a6 100644 --- a/VpnHood.Server.App.Net/VpnHood.Server.App.Net.csproj +++ b/VpnHood.Server.App.Net/VpnHood.Server.App.Net.csproj @@ -12,8 +12,8 @@ https://github.com/vpnhood/vpnhood LGPL-2.1-only VpnHood.png - 2.7.356 - 2.7.356 + 2.8.360 + 2.8.360 $([System.DateTime]::Now.ToString("yyyy.M.d.HHmm")) enable latest diff --git a/VpnHood.Server/Session.cs b/VpnHood.Server/Session.cs index e0181fa19..f57dfd568 100644 --- a/VpnHood.Server/Session.cs +++ b/VpnHood.Server/Session.cs @@ -17,7 +17,6 @@ using VpnHood.Tunneling; using VpnHood.Tunneling.Factory; using VpnHood.Tunneling.Messaging; -using static VpnHood.Server.Providers.FileAccessServerProvider.FileAccessServerSessionManager; using ProtocolType = PacketDotNet.ProtocolType; namespace VpnHood.Server; @@ -45,9 +44,9 @@ public class Session : IAsyncDisposable, IJob private readonly EventReporter _maxTcpConnectWaitExceptionReporter = new(VhLogger.Instance, "Maximum TcpConnectWait has been reached.", GeneralEventId.NetProtect); private readonly EventReporter _filterReporter = new(VhLogger.Instance, "Some requests has been blocked.", GeneralEventId.NetProtect); private bool _isSyncing; - private long _syncReceivedTraffic; - private long _syncSentTraffic; + private readonly Traffic _syncTraffic = new (); private int _tcpConnectWaitCount; + private readonly JobSection _syncJobSection; public Tunnel Tunnel { get; } public uint SessionId { get; } @@ -56,7 +55,7 @@ public class Session : IAsyncDisposable, IJob public UdpChannel? UdpChannel { get; private set; } public bool IsDisposed { get; private set; } public NetScanDetector? NetScanDetector { get; } - public JobSection JobSection { get; } + public JobSection JobSection { get; } = new(); public HelloRequest? HelloRequest { get; } public int TcpConnectWaitCount => _tcpConnectWaitCount; public int TcpChannelCount => Tunnel.TcpProxyChannelCount + (UseUdpChannel ? 0 : Tunnel.DatagramChannels.Length); @@ -97,12 +96,11 @@ internal Session(IAccessServer accessServer, SessionResponse sessionResponse, _netScanExceptionReporter.LogScope.Data.AddRange(logScope.Data); _maxTcpConnectWaitExceptionReporter.LogScope.Data.AddRange(logScope.Data); _maxTcpChannelExceptionReporter.LogScope.Data.AddRange(logScope.Data); + _syncJobSection = new JobSection(options.SyncIntervalValue); HelloRequest = helloRequest; SessionResponse = new SessionResponseBase(sessionResponse); SessionId = sessionResponse.SessionId; SessionKey = sessionResponse.SessionKey ?? throw new InvalidOperationException($"{nameof(sessionResponse)} does not have {nameof(sessionResponse.SessionKey)}!"); - JobSection = new JobSection(options.SyncIntervalValue); - var tunnelOptions = new TunnelOptions { MaxDatagramChannelCount = options.MaxDatagramChannelCountValue @@ -120,7 +118,8 @@ internal Session(IAccessServer accessServer, SessionResponse sessionResponse, public Task RunJob() { - return Sync(true, false); + using var jobLock = _syncJobSection.Enter(); + return Sync(jobLock.IsEntered, false); } public bool UseUdpChannel @@ -193,34 +192,32 @@ private async Task Sync(bool force, bool closeSession) using var scope = VhLogger.Instance.BeginScope( $"Server => SessionId: {VhLogger.FormatSessionId(SessionId)}, TokenId: {VhLogger.FormatId(HelloRequest?.TokenId)}"); - UsageInfo usageParam; + Traffic traffic; lock (_syncLock) { if (_isSyncing) return; - usageParam = new UsageInfo + traffic = new Traffic { - SentTraffic = Tunnel.ReceivedByteCount - _syncSentTraffic, // Intentionally Reversed: sending to tunnel means receiving form client, - ReceivedTraffic = Tunnel.SentByteCount - _syncReceivedTraffic // Intentionally Reversed: receiving from tunnel means sending for client + Sent = Tunnel.Traffic.Received - _syncTraffic.Sent, // Intentionally Reversed: sending to tunnel means receiving form client, + Received = Tunnel.Traffic.Sent - _syncTraffic.Received // Intentionally Reversed: receiving from tunnel means sending for client }; - var usedTraffic = usageParam.ReceivedTraffic + usageParam.SentTraffic; - var shouldSync = closeSession || (force && usedTraffic > 0) || usedTraffic >= _syncCacheSize; + var shouldSync = closeSession || (force && traffic.Total > 0) || traffic.Total >= _syncCacheSize; if (!shouldSync) return; // reset usage and sync time; no matter it is successful or not to prevent frequent call - _syncSentTraffic += usageParam.SentTraffic; - _syncReceivedTraffic += usageParam.ReceivedTraffic; + _syncTraffic.Add(traffic); _isSyncing = true; } try { SessionResponse = closeSession - ? await _accessServer.Session_Close(SessionId, usageParam) - : await _accessServer.Session_AddUsage(SessionId, usageParam); + ? await _accessServer.Session_Close(SessionId, traffic) + : await _accessServer.Session_AddUsage(SessionId, traffic); // dispose for any error if (SessionResponse.ErrorCode != SessionErrorCode.Ok) @@ -270,7 +267,7 @@ public void LogTrack(string protocol, IPEndPoint? localEndPoint, IPEndPoint? des if (destinationEndPoint != null) { - destinationIpStr = _trackingOptions.TrackDestinationIpValue ? Util.RedactIpAddress(destinationEndPoint.Address) : "*"; + destinationIpStr = _trackingOptions.TrackDestinationIpValue ? VhUtil.RedactIpAddress(destinationEndPoint.Address) : "*"; destinationPortStr = _trackingOptions.TrackDestinationPortValue ? destinationEndPoint.Port.ToString() : "*"; netScanCount = NetScanDetector?.GetBurstCount(destinationEndPoint).ToString() ?? "*"; } @@ -348,7 +345,7 @@ public async Task ProcessTcpChannelRequest(TcpClientStream tcpClientStream, TcpP // connect to requested destination isRequestedEpException = true; - await Util.RunTask( + await VhUtil.RunTask( tcpClientHost.ConnectAsync(request.DestinationEndPoint.Address, request.DestinationEndPoint.Port), _tcpConnectTimeout, cancellationToken); isRequestedEpException = false; diff --git a/VpnHood.Server/SystemInformation/SystemInfo.cs b/VpnHood.Server/SystemInformation/SystemInfo.cs index 9a6ce48f8..53c82f23d 100644 --- a/VpnHood.Server/SystemInformation/SystemInfo.cs +++ b/VpnHood.Server/SystemInformation/SystemInfo.cs @@ -21,7 +21,7 @@ public SystemInfo(string osInfo, long? totalMemory, long? availableMemory, int? public override string ToString() { - var totalMemory = TotalMemory != null ? Util.FormatBytes(TotalMemory.Value) : "*"; + var totalMemory = TotalMemory != null ? VhUtil.FormatBytes(TotalMemory.Value) : "*"; return $"{OsInfo}, TotalMemory: {totalMemory}, Logical Cores: {LogicalCoreCount}"; } diff --git a/VpnHood.Server/VpnHood.Server.csproj b/VpnHood.Server/VpnHood.Server.csproj index ec82a99ad..bb5f09191 100644 --- a/VpnHood.Server/VpnHood.Server.csproj +++ b/VpnHood.Server/VpnHood.Server.csproj @@ -13,8 +13,8 @@ VpnHood.png The core of VpnHood server. It can listen and accept connections from VpnHood clients. VpnHood.Server - 2.7.357 - 2.7.357 + 2.8.360 + 2.8.360 $([System.DateTime]::Now.ToString("yyyy.M.d.HHmm")) enable latest diff --git a/VpnHood.Server/VpnHoodServer.cs b/VpnHood.Server/VpnHoodServer.cs index 889fe0e83..f1a503b99 100644 --- a/VpnHood.Server/VpnHoodServer.cs +++ b/VpnHood.Server/VpnHoodServer.cs @@ -11,6 +11,7 @@ using VpnHood.Common.Exceptions; using VpnHood.Common.JobController; using VpnHood.Common.Logging; +using VpnHood.Common.Messaging; using VpnHood.Common.Net; using VpnHood.Common.Utils; using VpnHood.Server.Configurations; @@ -195,10 +196,10 @@ private static void ConfigNetFilter(INetFilter netFilter, TcpHost tcpHost, NetFi // net filters var includeIpRanges = IpNetwork.All.ToIpRanges(); - if (!Util.IsNullOrEmpty(netFilterOptions.IncludeIpRanges)) + if (!VhUtil.IsNullOrEmpty(netFilterOptions.IncludeIpRanges)) includeIpRanges = includeIpRanges.Intersect(netFilterOptions.IncludeIpRanges); - if (!Util.IsNullOrEmpty(netFilterOptions.ExcludeIpRanges)) + if (!VhUtil.IsNullOrEmpty(netFilterOptions.ExcludeIpRanges)) includeIpRanges = includeIpRanges.Exclude(netFilterOptions.ExcludeIpRanges); // packet capture @@ -206,10 +207,10 @@ private static void ConfigNetFilter(INetFilter netFilter, TcpHost tcpHost, NetFi if (netFilterOptions.ExcludeLocalNetworkValue) packetCaptureIncludeIpRanges = packetCaptureIncludeIpRanges.Exclude(IpNetwork.LocalNetworks.ToIpRanges()); - if (!Util.IsNullOrEmpty(netFilterOptions.PacketCaptureIncludeIpRanges)) + if (!VhUtil.IsNullOrEmpty(netFilterOptions.PacketCaptureIncludeIpRanges)) packetCaptureIncludeIpRanges = packetCaptureIncludeIpRanges.Intersect(netFilterOptions.PacketCaptureIncludeIpRanges); - if (!Util.IsNullOrEmpty(netFilterOptions.PacketCaptureExcludeIpRanges)) + if (!VhUtil.IsNullOrEmpty(netFilterOptions.PacketCaptureExcludeIpRanges)) packetCaptureIncludeIpRanges = packetCaptureIncludeIpRanges.Exclude(netFilterOptions.PacketCaptureExcludeIpRanges); // assign to workers @@ -270,7 +271,7 @@ private async Task ReadConfigImpl(ServerInfo serverInfo) { if (File.Exists(_lastConfigFilePath)) { - var ret = Util.JsonDeserialize(await File.ReadAllTextAsync(_lastConfigFilePath)); + var ret = VhUtil.JsonDeserialize(await File.ReadAllTextAsync(_lastConfigFilePath)); VhLogger.Instance.LogWarning("Last configuration has been loaded to report Maintenance mode."); return ret; } @@ -298,8 +299,11 @@ public ServerStatus Status AvailableMemory = systemInfo.AvailableMemory, CpuUsage = systemInfo.CpuUsage, UsedMemory = Process.GetCurrentProcess().WorkingSet64, - TunnelSendSpeed = SessionManager.Sessions.Sum(x => x.Value.Tunnel.SendSpeed), - TunnelReceiveSpeed = SessionManager.Sessions.Sum(x => x.Value.Tunnel.ReceiveSpeed), + TunnelSpeed = new Traffic + { + Sent = SessionManager.Sessions.Sum(x => x.Value.Tunnel.Speed.Sent), + Received = SessionManager.Sessions.Sum(x => x.Value.Tunnel.Speed.Received), + }, ConfigCode = _lastConfigCode }; return serverStatus; diff --git a/VpnHood.Tunneling/IChannel.cs b/VpnHood.Tunneling/IChannel.cs index e930750d2..dcf08636e 100644 --- a/VpnHood.Tunneling/IChannel.cs +++ b/VpnHood.Tunneling/IChannel.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using VpnHood.Common.Messaging; namespace VpnHood.Tunneling; @@ -8,8 +9,7 @@ public interface IChannel : IDisposable bool IsClosePending { get; } bool Connected { get; } DateTime LastActivityTime { get; } - long SentByteCount { get; } - long ReceivedByteCount { get; } + Traffic Traffic { get; } Task Start(); event EventHandler OnFinished; } \ No newline at end of file diff --git a/VpnHood.Tunneling/TcpDatagramChannel.cs b/VpnHood.Tunneling/TcpDatagramChannel.cs index 78c95d172..084542628 100644 --- a/VpnHood.Tunneling/TcpDatagramChannel.cs +++ b/VpnHood.Tunneling/TcpDatagramChannel.cs @@ -7,6 +7,7 @@ using PacketDotNet; using VpnHood.Common.JobController; using VpnHood.Common.Logging; +using VpnHood.Common.Messaging; using VpnHood.Common.Utils; using VpnHood.Tunneling.DatagramMessaging; @@ -26,8 +27,7 @@ public class TcpDatagramChannel : IDatagramChannel, IJob public JobSection? JobSection => null; public bool IsClosePending { get; private set; } public bool Connected { get; private set; } - public long SentByteCount { get; private set; } - public long ReceivedByteCount { get; private set; } + public Traffic Traffic { get; } = new(); public DateTime LastActivityTime { get; private set; } = FastDateTime.Now; public TcpDatagramChannel(TcpClientStream tcpClientStream) @@ -39,7 +39,7 @@ public TcpDatagramChannel(TcpClientStream tcpClientStream, TimeSpan lifespan) { _tcpClientStream = tcpClientStream ?? throw new ArgumentNullException(nameof(tcpClientStream)); tcpClientStream.TcpClient.NoDelay = true; - if (!Util.IsInfinite(lifespan)) + if (!VhUtil.IsInfinite(lifespan)) { _lifeTime = FastDateTime.Now + lifespan; JobRunner.Default.Add(this); @@ -84,7 +84,7 @@ public async Task SendPacketAsync(IPPacket[] ipPackets) await _tcpClientStream.Stream.WriteAsync(buffer, 0, bufferIndex); LastActivityTime = FastDateTime.Now; - SentByteCount += bufferIndex; + Traffic.Sent += bufferIndex; } finally { @@ -107,7 +107,7 @@ private async Task ReadTask() break; LastActivityTime = FastDateTime.Now; - ReceivedByteCount += ipPackets.Sum(x => x.TotalPacketLength); + Traffic.Received += ipPackets.Sum(x => x.TotalPacketLength); // check datagram message List? processedPackets = null; diff --git a/VpnHood.Tunneling/TcpProxyChannel.cs b/VpnHood.Tunneling/TcpProxyChannel.cs index 0534dc8a0..022e47a28 100644 --- a/VpnHood.Tunneling/TcpProxyChannel.cs +++ b/VpnHood.Tunneling/TcpProxyChannel.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging; using VpnHood.Common.JobController; using VpnHood.Common.Logging; +using VpnHood.Common.Messaging; using VpnHood.Common.Utils; namespace VpnHood.Tunneling; @@ -25,8 +26,7 @@ public class TcpProxyChannel : IChannel, IJob public event EventHandler? OnFinished; public bool IsClosePending => false; public bool Connected { get; private set; } - public long SentByteCount { get; private set; } - public long ReceivedByteCount { get; private set; } + public Traffic Traffic { get; } = new (); public DateTime LastActivityTime { get; private set; } = FastDateTime.Now; public TcpProxyChannel(TcpClientStream orgTcpClientStream, TcpClientStream tunnelTcpClientStream, @@ -174,9 +174,9 @@ private async Task CopyToInternalAsync(Stream source, Stream destination, bool i // calculate transferred bytes if (!isSendingOut) - ReceivedByteCount += bytesRead; + Traffic.Received += bytesRead; else - SentByteCount += bytesRead; + Traffic.Sent += bytesRead; // set LastActivityTime as some data delegated LastActivityTime = FastDateTime.Now; diff --git a/VpnHood.Tunneling/Tunnel.cs b/VpnHood.Tunneling/Tunnel.cs index 75033e988..4b9691aa8 100644 --- a/VpnHood.Tunneling/Tunnel.cs +++ b/VpnHood.Tunneling/Tunnel.cs @@ -7,6 +7,7 @@ using PacketDotNet; using VpnHood.Common.Collections; using VpnHood.Common.Logging; +using VpnHood.Common.Messaging; using VpnHood.Common.Utils; using VpnHood.Tunneling.DatagramMessaging; @@ -24,21 +25,17 @@ public class Tunnel : IDisposable private readonly HashSet _tcpProxyChannels = new(); private readonly Timer _speedMonitorTimer; private bool _disposed; - private long _lastReceivedByteCount; - private long _lastSentByteCount; private int _maxDatagramChannelCount; - private long _receivedByteCount; - private long _sentByteCount; + private Traffic _lastTraffic = new(); + private readonly Traffic _trafficUsage = new(); private readonly TimeSpan _datagramPacketTimeout = TimeSpan.FromSeconds(100); private DateTime _lastSpeedUpdateTime = FastDateTime.Now; private readonly TimeSpan _speedTestThreshold = TimeSpan.FromSeconds(2); private readonly TimeoutDictionary> _closePendingChannels = new(TimeSpan.FromSeconds(30)); - public event EventHandler? OnPacketReceived; public event EventHandler? OnChannelAdded; public event EventHandler? OnChannelRemoved; - public long SendSpeed { get; private set; } - public long ReceiveSpeed { get; private set; } + public Traffic Speed { get; } = new(); public DateTime LastActivityTime { get; private set; } = FastDateTime.Now; public IDatagramChannel[] DatagramChannels { get; private set; } = Array.Empty(); @@ -58,26 +55,17 @@ public int TcpProxyChannelCount } } - public long ReceivedByteCount - { - get - { - lock (_channelListLock) - { - return _receivedByteCount + _tcpProxyChannels.Sum(x => x.ReceivedByteCount) + - DatagramChannels.Sum(x => x.ReceivedByteCount); - } - } - } - - public long SentByteCount + public Traffic Traffic { get { lock (_channelListLock) { - return _sentByteCount + _tcpProxyChannels.Sum(x => x.SentByteCount) + - DatagramChannels.Sum(x => x.SentByteCount); + return new Traffic + { + Sent = _trafficUsage.Sent + _tcpProxyChannels.Sum(x => x.Traffic.Sent) + DatagramChannels.Sum(x => x.Traffic.Sent), + Received = _trafficUsage.Received + _tcpProxyChannels.Sum(x => x.Traffic.Received) + DatagramChannels.Sum(x => x.Traffic.Received) + }; } } } @@ -101,17 +89,14 @@ private void UpdateSpeed() if (FastDateTime.Now - _lastSpeedUpdateTime < _speedTestThreshold) return; - var sentByteCount = SentByteCount; - var receivedByteCount = ReceivedByteCount; - var trafficChanged = _lastSentByteCount != sentByteCount || _lastReceivedByteCount != receivedByteCount; + var traffic = Traffic; + var trafficChanged = _lastTraffic != traffic; var duration = (FastDateTime.Now - _lastSpeedUpdateTime).TotalSeconds; - SendSpeed = (int)((sentByteCount - _lastSentByteCount) / duration); - ReceiveSpeed = (int)((receivedByteCount - _lastReceivedByteCount) / duration); - + Speed.Sent = (long)((traffic.Sent - _lastTraffic.Sent) / duration); + Speed.Received = (long)((traffic.Received - _lastTraffic.Received) / duration); _lastSpeedUpdateTime = FastDateTime.Now; - _lastSentByteCount = sentByteCount; - _lastReceivedByteCount = receivedByteCount; + _lastTraffic = traffic.Clone(); if (trafficChanged) LastActivityTime = FastDateTime.Now; } @@ -145,7 +130,7 @@ public void AddChannel(IDatagramChannel datagramChannel) // remove additional Datagram channels while (DatagramChannels.Length > MaxDatagramChannelCount) { - VhLogger.Instance.LogInformation(GeneralEventId.DatagramChannel, + VhLogger.Instance.LogInformation(GeneralEventId.DatagramChannel, "Removing an exceeded DatagramChannel. ChannelCount: {ChannelCount}", DatagramChannels.Length); RemoveChannel(DatagramChannels[0]); @@ -223,9 +208,8 @@ public void RemoveChannel(IChannel channel) else channel.Dispose(); - // clean up tunnel - _sentByteCount += channel.SentByteCount; - _receivedByteCount += channel.ReceivedByteCount; + // clean up channel + _trafficUsage.Add(channel.Traffic); channel.OnFinished -= Channel_OnFinished; // notify channel has been removed @@ -273,7 +257,7 @@ public async Task SendPackets(IEnumerable ipPackets) { var dateTime = FastDateTime.Now; if (_disposed) throw new ObjectDisposedException(nameof(Tunnel)); - + // waiting for a space in the packetQueue; the Inconsistently is not important. synchronization may lead to dead-lock // ReSharper disable once InconsistentlySynchronizedField while (_packetQueue.Count > _maxQueueLength) @@ -419,8 +403,8 @@ public void Dispose() _packetQueue.Clear(); _speedMonitorTimer.Dispose(); - SendSpeed = 0; - ReceiveSpeed = 0; + Speed.Sent = 0; + Speed.Received = 0; // release worker threads _packetSenderSemaphore.Release(MaxDatagramChannelCount * 10); //make sure to release all semaphores diff --git a/VpnHood.Tunneling/UdpChannel.cs b/VpnHood.Tunneling/UdpChannel.cs index d30aabab5..46f5c6b51 100644 --- a/VpnHood.Tunneling/UdpChannel.cs +++ b/VpnHood.Tunneling/UdpChannel.cs @@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging; using PacketDotNet; using VpnHood.Common.Logging; +using VpnHood.Common.Messaging; using VpnHood.Common.Utils; namespace VpnHood.Tunneling; @@ -27,7 +28,14 @@ public class UdpChannel : IDatagramChannel private IPEndPoint? _lastRemoteEp; public bool IsClosePending => false; - + public byte[] Key { get; } + public int LocalPort => ((IPEndPoint)_udpClient.Client.LocalEndPoint).Port; + public bool Connected { get; private set; } + public Traffic Traffic { get; } = new(); + public DateTime LastActivityTime { get; private set; } + public event EventHandler? OnFinished; + public event EventHandler? OnPacketReceived; + public UdpChannel(bool isClient, UdpClient udpClient, uint sessionId, byte[] key) { VhLogger.Instance.LogInformation(GeneralEventId.Udp, $"Creating a {nameof(UdpChannel)}. SessionId: {VhLogger.FormatId(_sessionId)} ..."); @@ -48,16 +56,6 @@ public UdpChannel(bool isClient, UdpClient udpClient, uint sessionId, byte[] key } - public byte[] Key { get; } - public int LocalPort => ((IPEndPoint)_udpClient.Client.LocalEndPoint).Port; - - public event EventHandler? OnFinished; - public event EventHandler? OnPacketReceived; - public bool Connected { get; private set; } - public long SentByteCount { get; private set; } - public long ReceivedByteCount { get; private set; } - public DateTime LastActivityTime { get; private set; } - public Task Start() { if (_disposed) @@ -143,7 +141,7 @@ private async Task ReadTask() while (bufferIndex < buffer.Length) { var ipPacket = PacketUtil.ReadNextPacket(buffer, ref bufferIndex); - ReceivedByteCount += ipPacket.TotalPacketLength; + Traffic.Received += ipPacket.TotalPacketLength; ipPackets.Add(ipPacket); } } @@ -193,7 +191,7 @@ private async Task Send(byte[] buffer, int bufferCount) VhLogger.Instance.Log(LogLevel.Information, GeneralEventId.Udp, $"{VhLogger.FormatType(this)} is sending {bufferCount} bytes..."); - var cryptoPos = _cryptorPosBase + SentByteCount; + var cryptoPos = _cryptorPosBase + Traffic.Sent; _bufferCryptor.Cipher(buffer, _bufferHeaderLength, bufferCount, cryptoPos); if (_isClient) { @@ -211,7 +209,7 @@ private async Task Send(byte[] buffer, int bufferCount) throw new Exception( $"{VhLogger.FormatType(this)}: Send {ret} bytes instead {bufferCount} bytes! "); - SentByteCount += ret; + Traffic.Sent += ret; LastActivityTime = FastDateTime.Now; } catch (Exception ex) diff --git a/VpnHood.Tunneling/VpnHood.Tunneling.csproj b/VpnHood.Tunneling/VpnHood.Tunneling.csproj index 2c6178543..013669b9e 100644 --- a/VpnHood.Tunneling/VpnHood.Tunneling.csproj +++ b/VpnHood.Tunneling/VpnHood.Tunneling.csproj @@ -15,8 +15,8 @@ VpnHood.png VpnHood.Tunneling Provides tunnelling classes and protocols shared between VpnHood.Client and VpnHood.Server. - 2.7.357 - 2.7.357 + 2.8.360 + 2.8.360 $([System.DateTime]::Now.ToString("yyyy.M.d.HHmm")) enable latest diff --git a/VpnHood.ZTest/TestAccessServer.cs b/VpnHood.ZTest/TestAccessServer.cs index 089fb0a2a..9d69ca60f 100644 --- a/VpnHood.ZTest/TestAccessServer.cs +++ b/VpnHood.ZTest/TestAccessServer.cs @@ -64,14 +64,14 @@ public Task Session_Create(SessionRequestEx sessionRequestEx) return _httpAccessServer.Session_Create(sessionRequestEx); } - public Task Session_AddUsage(uint sessionId, UsageInfo usageInfo) + public Task Session_AddUsage(uint sessionId, Traffic traffic) { - return _httpAccessServer.Session_AddUsage(sessionId, usageInfo); + return _httpAccessServer.Session_AddUsage(sessionId, traffic); } - public Task Session_Close(uint sessionId, UsageInfo usageInfo) + public Task Session_Close(uint sessionId, Traffic traffic) { - return _httpAccessServer.Session_Close(sessionId, usageInfo); + return _httpAccessServer.Session_Close(sessionId, traffic); } public Task GetSslCertificateData(IPEndPoint hostEndPoint) diff --git a/VpnHood.ZTest/TestEmbedIoAccessServer.cs b/VpnHood.ZTest/TestEmbedIoAccessServer.cs index 3ae8b2545..caa0e7388 100644 --- a/VpnHood.ZTest/TestEmbedIoAccessServer.cs +++ b/VpnHood.ZTest/TestEmbedIoAccessServer.cs @@ -30,7 +30,7 @@ public TestEmbedIoAccessServer(IAccessServer fileFileAccessServer, bool autoStar try { Logger.UnregisterLogger(); } catch { /* ignored */} FileAccessServer = fileFileAccessServer; - BaseUri = new Uri($"http://{Util.GetFreeTcpEndPoint(IPAddress.Loopback)}"); + BaseUri = new Uri($"http://{VhUtil.GetFreeTcpEndPoint(IPAddress.Loopback)}"); _webServer = CreateServer(BaseUri); if (autoStart) _webServer.Start(); @@ -133,10 +133,10 @@ public async Task Session_Create([QueryField] Guid serverId) public async Task Session_AddUsage([QueryField] Guid serverId, uint sessionId, [QueryField] bool closeSession) { _ = serverId; - var usageInfo = await GetRequestDataAsync(); + var traffic = await GetRequestDataAsync(); var res = closeSession - ? await AccessServer.Session_Close(sessionId, usageInfo) - : await AccessServer.Session_AddUsage(sessionId, usageInfo); + ? await AccessServer.Session_Close(sessionId, traffic) + : await AccessServer.Session_AddUsage(sessionId, traffic); return res; } diff --git a/VpnHood.ZTest/TestHelper.cs b/VpnHood.ZTest/TestHelper.cs index 573c5d372..eee644514 100644 --- a/VpnHood.ZTest/TestHelper.cs +++ b/VpnHood.ZTest/TestHelper.cs @@ -260,7 +260,7 @@ public static FileAccessServerOptions CreateFileAccessServerOptions() { var options = new FileAccessServerOptions { - TcpEndPoints = new[] { Util.GetFreeTcpEndPoint(IPAddress.Loopback) }, + TcpEndPoints = new[] { VhUtil.GetFreeTcpEndPoint(IPAddress.Loopback) }, TrackingOptions = new TrackingOptions { TrackClientIp = true, @@ -279,12 +279,12 @@ public static FileAccessServerOptions CreateFileAccessServerOptions() public static VpnHoodServer CreateServer(IAccessServer? accessServer = null, bool autoStart = true, TimeSpan? configureInterval = null) { - return CreateServer(accessServer, null, autoStart); + return CreateServer(accessServer, null, autoStart, configureInterval); } public static VpnHoodServer CreateServer(FileAccessServerOptions? options, bool autoStart = true, TimeSpan? configureInterval = null) { - return CreateServer(null, options, autoStart); + return CreateServer(null, options, autoStart, configureInterval); } private static VpnHoodServer CreateServer(IAccessServer? accessServer, FileAccessServerOptions? fileAccessServerOptions, bool autoStart, @@ -426,7 +426,7 @@ public static SessionRequestEx CreateSessionRequestEx(Token token, Guid? clientI return new SessionRequestEx(token.TokenId, new ClientInfo { ClientId = clientId.Value }, hostEndPoint: token.HostEndPoints!.First(), - encryptedClientId: Util.EncryptClientId(clientId.Value, token.Secret)); + encryptedClientId: VhUtil.EncryptClientId(clientId.Value, token.Secret)); } public static async Task WaitForValue(object? expectedValue, Func valueFactory, int timeout = 5000) @@ -513,5 +513,6 @@ internal static void Init() }); FastDateTime.Precision = TimeSpan.FromMilliseconds(1); JobRunner.Default.Interval = TimeSpan.FromMilliseconds(200); + JobSection.DefaultInterval = TimeSpan.FromMilliseconds(200); } } \ No newline at end of file diff --git a/VpnHood.ZTest/Tests/AccessTest.cs b/VpnHood.ZTest/Tests/AccessTest.cs index 0e8ba31b7..4d057fea0 100644 --- a/VpnHood.ZTest/Tests/AccessTest.cs +++ b/VpnHood.ZTest/Tests/AccessTest.cs @@ -1,12 +1,10 @@ using System; -using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using VpnHood.Client; using VpnHood.Common.Logging; using VpnHood.Common.Messaging; -using VpnHood.Server.Configurations; namespace VpnHood.Test.Tests; diff --git a/VpnHood.ZTest/Tests/ClientAppTest.cs b/VpnHood.ZTest/Tests/ClientAppTest.cs index 7d0e8c357..624f0c3a4 100644 --- a/VpnHood.ZTest/Tests/ClientAppTest.cs +++ b/VpnHood.ZTest/Tests/ClientAppTest.cs @@ -152,12 +152,12 @@ public async Task Token_secret_should_not_be_extracted() // ************ // *** TEST ***: GetToken should not return then secret var token2 = app.ClientProfileStore.GetToken(clientProfile.TokenId); - Assert.IsTrue(Util.IsNullOrEmpty(token2.Secret), "token should not have secret"); + Assert.IsTrue(VhUtil.IsNullOrEmpty(token2.Secret), "token should not have secret"); // ************ // *** TEST ***: ClientProfileItems should not return then secret var clientProfiles = app.ClientProfileStore.ClientProfileItems; - Assert.IsTrue(clientProfiles.All(x => Util.IsNullOrEmpty(x.Token.Secret)), "token should not have secret"); + Assert.IsTrue(clientProfiles.All(x => VhUtil.IsNullOrEmpty(x.Token.Secret)), "token should not have secret"); } [TestMethod] @@ -335,24 +335,24 @@ public async Task IpFilters(bool usePassthru, bool isDnsServerSupported) public static async Task IpFilters_TestInclude(VpnHoodApp app, bool testUdp, bool testPing, bool testDns) { // TCP - var oldReceivedByteCount = app.State.ReceivedTraffic; + var oldReceivedByteCount = app.State.SessionTraffic.Received; await TestHelper.Test_HttpsAsync(uri: TestHelper.TEST_HttpsUri1); - Assert.AreNotEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreNotEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); // TCP - oldReceivedByteCount = app.State.ReceivedTraffic; + oldReceivedByteCount = app.State.SessionTraffic.Received; await TestHelper.Test_HttpsAsync(uri: TestHelper.TEST_HttpsUri2); - Assert.AreEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); if (testPing) { // ping - oldReceivedByteCount = app.State.ReceivedTraffic; + oldReceivedByteCount = app.State.SessionTraffic.Received; await TestHelper.Test_Ping(ipAddress: TestHelper.TEST_PingV4Address1); - Assert.AreNotEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreNotEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); // ping - oldReceivedByteCount = app.State.ReceivedTraffic; + oldReceivedByteCount = app.State.SessionTraffic.Received; try { await TestHelper.Test_Ping(ipAddress: TestHelper.TEST_PingV4Address2, timeout: 1000); @@ -363,18 +363,18 @@ public static async Task IpFilters_TestInclude(VpnHoodApp app, bool testUdp, boo Assert.AreEqual(nameof(PingException), ex.GetType().Name); } - Assert.AreEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); } if (testUdp) { // UDP - oldReceivedByteCount = app.State.ReceivedTraffic; + oldReceivedByteCount = app.State.SessionTraffic.Received; await TestHelper.Test_Udp(TestHelper.TEST_UdpV4EndPoint1); - Assert.AreNotEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreNotEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); // UDP - oldReceivedByteCount = app.State.ReceivedTraffic; + oldReceivedByteCount = app.State.SessionTraffic.Received; try { await TestHelper.Test_Udp(TestHelper.TEST_UdpV4EndPoint2, timeout: 1000); @@ -385,39 +385,39 @@ public static async Task IpFilters_TestInclude(VpnHoodApp app, bool testUdp, boo Assert.AreEqual(nameof(OperationCanceledException), ex.GetType().Name); } - Assert.AreEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); } // DNS should always use tunnel regarding of any exclude or include option if (testDns) { - oldReceivedByteCount = app.State.ReceivedTraffic; + oldReceivedByteCount = app.State.SessionTraffic.Received; TestHelper.Test_Dns(nsEndPoint: TestHelper.TEST_NsEndPoint1); - Assert.AreNotEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreNotEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); - oldReceivedByteCount = app.State.ReceivedTraffic; + oldReceivedByteCount = app.State.SessionTraffic.Received; TestHelper.Test_Dns(nsEndPoint: TestHelper.TEST_NsEndPoint2); - Assert.AreNotEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreNotEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); } } public static async Task IpFilters_TestExclude(VpnHoodApp app, bool testUdp, bool testPing, bool testDns) { // TCP - var oldReceivedByteCount = app.State.ReceivedTraffic; + var oldReceivedByteCount = app.State.SessionTraffic.Received; await TestHelper.Test_HttpsAsync(uri: TestHelper.TEST_HttpsUri1); - Assert.AreEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); // TCP - oldReceivedByteCount = app.State.ReceivedTraffic; + oldReceivedByteCount = app.State.SessionTraffic.Received; await TestHelper.Test_HttpsAsync(uri: TestHelper.TEST_HttpsUri2); - Assert.AreNotEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreNotEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); if (testPing) { // ping - oldReceivedByteCount = app.State.ReceivedTraffic; + oldReceivedByteCount = app.State.SessionTraffic.Received; try { await TestHelper.Test_Ping(ipAddress: TestHelper.TEST_PingV4Address1, timeout: 1000); @@ -427,19 +427,19 @@ public static async Task IpFilters_TestExclude(VpnHoodApp app, bool testUdp, boo { Assert.AreEqual(nameof(PingException), ex.GetType().Name); } - Assert.AreEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); // ping - oldReceivedByteCount = app.State.ReceivedTraffic; + oldReceivedByteCount = app.State.SessionTraffic.Received; await TestHelper.Test_Ping(ipAddress: TestHelper.TEST_PingV4Address2); - Assert.AreNotEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreNotEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); } if (testUdp) { // UDP VhLogger.Instance.LogTrace("Testing UDP include..."); - oldReceivedByteCount = app.State.ReceivedTraffic; + oldReceivedByteCount = app.State.SessionTraffic.Received; try { await TestHelper.Test_Udp(udpEndPoint: TestHelper.TEST_UdpV4EndPoint1, timeout: 1000); @@ -449,25 +449,25 @@ public static async Task IpFilters_TestExclude(VpnHoodApp app, bool testUdp, boo { Assert.AreEqual(nameof(OperationCanceledException), ex.GetType().Name); } - Assert.AreEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); // UDP VhLogger.Instance.LogTrace("Testing UDP exclude..."); - oldReceivedByteCount = app.State.ReceivedTraffic; + oldReceivedByteCount = app.State.SessionTraffic.Received; await TestHelper.Test_Udp(TestHelper.TEST_UdpV4EndPoint2); - Assert.AreNotEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreNotEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); } // DNS should always use tunnel regarding of any exclude or include option if (testDns) { - oldReceivedByteCount = app.State.ReceivedTraffic; + oldReceivedByteCount = app.State.SessionTraffic.Received; TestHelper.Test_Dns(nsEndPoint: TestHelper.TEST_NsEndPoint1); - Assert.AreNotEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreNotEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); - oldReceivedByteCount = app.State.ReceivedTraffic; + oldReceivedByteCount = app.State.SessionTraffic.Received; TestHelper.Test_Dns(nsEndPoint: TestHelper.TEST_NsEndPoint2); - Assert.AreNotEqual(oldReceivedByteCount, app.State.ReceivedTraffic); + Assert.AreNotEqual(oldReceivedByteCount, app.State.SessionTraffic.Received); } } @@ -511,7 +511,7 @@ public async Task Get_token_from_tokenLink() var token2 = TestHelper.CreateAccessToken(server); //create web server and set token url to it - var endPoint = Util.GetFreeTcpEndPoint(IPAddress.Loopback); + var endPoint = VhUtil.GetFreeTcpEndPoint(IPAddress.Loopback); using var webServer = new WebServer(endPoint.Port); token1.Url = $"http://{endPoint}/accesskey"; diff --git a/VpnHood.ZTest/Tests/ClientServerTest.cs b/VpnHood.ZTest/Tests/ClientServerTest.cs index 10af2ba66..54fbb042d 100644 --- a/VpnHood.ZTest/Tests/ClientServerTest.cs +++ b/VpnHood.ZTest/Tests/ClientServerTest.cs @@ -30,14 +30,14 @@ public void Initialize() [TestMethod] public void Redirect_Server() { - var serverEndPoint1 = Util.GetFreeTcpEndPoint(IPAddress.Loopback); + var serverEndPoint1 = VhUtil.GetFreeTcpEndPoint(IPAddress.Loopback); var fileAccessServerOptions1 = new FileAccessServerOptions { TcpEndPoints = new[] { serverEndPoint1 } }; using var fileAccessServer1 = TestHelper.CreateFileAccessServer(fileAccessServerOptions1); using var testAccessServer1 = new TestAccessServer(fileAccessServer1); using var server1 = TestHelper.CreateServer(testAccessServer1); // Create Server 2 - var serverEndPoint2 = Util.GetFreeTcpEndPoint(IPAddress.Loopback); + var serverEndPoint2 = VhUtil.GetFreeTcpEndPoint(IPAddress.Loopback); var fileAccessServerOptions2 = new FileAccessServerOptions { TcpEndPoints = new[] { serverEndPoint2 } }; using var fileAccessServer2 = TestHelper.CreateFileAccessServer(fileAccessServerOptions2, fileAccessServer1.StoragePath); @@ -59,7 +59,7 @@ public void Redirect_Server() public async Task TcpChannel() { // Create Server - var serverEp = Util.GetFreeTcpEndPoint(IPAddress.IPv6Loopback); + var serverEp = VhUtil.GetFreeTcpEndPoint(IPAddress.IPv6Loopback); var fileAccessServerOptions = TestHelper.CreateFileAccessServerOptions(); fileAccessServerOptions.TcpEndPoints = new[] { serverEp }; using var fileAccessServer = TestHelper.CreateFileAccessServer(fileAccessServerOptions); @@ -165,10 +165,10 @@ private static async Task TestTunnel(VpnHoodServer server, VpnHoodClient client) // ************ // *** TEST ***: TCP invalid request should not close the vpn connection - var oldClientSentByteCount = client.SentByteCount; - var oldClientReceivedByteCount = client.ReceivedByteCount; - var oldServerSentByteCount = serverSession.Tunnel.SentByteCount; - var oldServerReceivedByteCount = serverSession.Tunnel.ReceivedByteCount; + var oldClientSentByteCount = client.SessionTraffic.Sent; + var oldClientReceivedByteCount = client.SessionTraffic.Received; + var oldServerSentByteCount = serverSession.Tunnel.Traffic.Sent; + var oldServerReceivedByteCount = serverSession.Tunnel.Traffic.Received; using var httpClient = new HttpClient(); try @@ -189,49 +189,49 @@ await httpClient.GetStringAsync($"http://{TestHelper.TEST_NsEndPoint1}", await TestHelper.Test_HttpsAsync(); // check there is send data - Assert.IsTrue(client.SentByteCount > oldClientSentByteCount + 100, + Assert.IsTrue(client.SessionTraffic.Sent > oldClientSentByteCount + 100, "Not enough data has been sent through the client!"); - Assert.IsTrue(client.ReceivedByteCount > oldClientReceivedByteCount + 2000, + Assert.IsTrue(client.SessionTraffic.Received > oldClientReceivedByteCount + 2000, "Not enough data has been sent through the client!"); - Assert.IsTrue(serverSession.Tunnel.SentByteCount > oldServerSentByteCount + 2000, + Assert.IsTrue(serverSession.Tunnel.Traffic.Sent > oldServerSentByteCount + 2000, "Not enough data has been sent through the client!"); - Assert.IsTrue(serverSession.Tunnel.ReceivedByteCount > oldServerReceivedByteCount + 100, + Assert.IsTrue(serverSession.Tunnel.Traffic.Received> oldServerReceivedByteCount + 100, "Not enough data has been sent through the client!"); // ************ // *** TEST ***: UDP v4 - oldClientSentByteCount = client.SentByteCount; - oldClientReceivedByteCount = client.ReceivedByteCount; - oldServerSentByteCount = serverSession.Tunnel.SentByteCount; - oldServerReceivedByteCount = serverSession.Tunnel.ReceivedByteCount; + oldClientSentByteCount = client.SessionTraffic.Sent; + oldClientReceivedByteCount = client.SessionTraffic.Received; + oldServerSentByteCount = serverSession.Tunnel.Traffic.Sent; + oldServerReceivedByteCount = serverSession.Tunnel.Traffic.Received; await TestHelper.Test_Udp(); - Assert.IsTrue(client.SentByteCount > oldClientSentByteCount + 500, + Assert.IsTrue(client.SessionTraffic.Sent > oldClientSentByteCount + 500, "Not enough data has been sent through the client!"); - Assert.IsTrue(client.ReceivedByteCount > oldClientReceivedByteCount + 500, + Assert.IsTrue(client.SessionTraffic.Received > oldClientReceivedByteCount + 500, "Not enough data has been sent through the client!"); - Assert.IsTrue(serverSession.Tunnel.SentByteCount > oldServerSentByteCount + 500, + Assert.IsTrue(serverSession.Tunnel.Traffic.Sent > oldServerSentByteCount + 500, "Not enough data has been sent through the client!"); - Assert.IsTrue(serverSession.Tunnel.ReceivedByteCount > oldServerReceivedByteCount + 500, + Assert.IsTrue(serverSession.Tunnel.Traffic.Received > oldServerReceivedByteCount + 500, "Not enough data has been sent through the client!"); // ************ // *** TEST ***: IcmpV4 - oldClientSentByteCount = client.SentByteCount; - oldClientReceivedByteCount = client.ReceivedByteCount; - oldServerSentByteCount = serverSession.Tunnel.SentByteCount; - oldServerReceivedByteCount = serverSession.Tunnel.ReceivedByteCount; + oldClientSentByteCount = client.SessionTraffic.Sent; + oldClientReceivedByteCount = client.SessionTraffic.Received; + oldServerSentByteCount = serverSession.Tunnel.Traffic.Sent; + oldServerReceivedByteCount = serverSession.Tunnel.Traffic.Received; await TestHelper.Test_Ping(ipAddress: TestHelper.TEST_PingV4Address1); - Assert.IsTrue(client.SentByteCount > oldClientSentByteCount + 500, + Assert.IsTrue(client.SessionTraffic.Sent > oldClientSentByteCount + 500, "Not enough data has been sent through the client!"); - Assert.IsTrue(client.ReceivedByteCount > oldClientReceivedByteCount + 500, + Assert.IsTrue(client.SessionTraffic.Received > oldClientReceivedByteCount + 500, "Not enough data has been sent through the client!"); - Assert.IsTrue(serverSession.Tunnel.SentByteCount > oldServerSentByteCount + 500, + Assert.IsTrue(serverSession.Tunnel.Traffic.Sent > oldServerSentByteCount + 500, "Not enough data has been sent through the client!"); - Assert.IsTrue(serverSession.Tunnel.ReceivedByteCount > oldServerReceivedByteCount + 500, + Assert.IsTrue(serverSession.Tunnel.Traffic.Received > oldServerReceivedByteCount + 500, "Not enough data has been sent through the client!"); } diff --git a/VpnHood.ZTest/Tests/FileAccessServerTest.cs b/VpnHood.ZTest/Tests/FileAccessServerTest.cs index 03e18f3ea..23f82f091 100644 --- a/VpnHood.ZTest/Tests/FileAccessServerTest.cs +++ b/VpnHood.ZTest/Tests/FileAccessServerTest.cs @@ -5,7 +5,6 @@ using System.Security.Cryptography.X509Certificates; using Microsoft.VisualStudio.TestTools.UnitTesting; using VpnHood.Common.Messaging; -using VpnHood.Server; using VpnHood.Server.Providers.FileAccessServerProvider; using VpnHood.Server.Providers.HttpAccessServerProvider; @@ -117,42 +116,42 @@ public void AddUsage() // ************ // *** TEST ***: add sent and receive bytes var response = accessServer1.Session_AddUsage(sessionResponse.SessionId, - new UsageInfo { SentTraffic = 20, ReceivedTraffic = 10 }).Result; + new Traffic { Sent = 20, Received = 10 }).Result; Assert.AreEqual(SessionErrorCode.Ok, response.ErrorCode, response.ErrorMessage); - Assert.AreEqual(20, response.AccessUsage?.SentTraffic); - Assert.AreEqual(10, response.AccessUsage?.ReceivedTraffic); + Assert.AreEqual(20, response.AccessUsage?.Traffic.Sent); + Assert.AreEqual(10, response.AccessUsage?.Traffic.Received); response = accessServer1.Session_AddUsage(sessionResponse.SessionId, - new UsageInfo { SentTraffic = 20, ReceivedTraffic = 10 }).Result; + new Traffic { Sent = 20, Received = 10 }).Result; Assert.AreEqual(SessionErrorCode.Ok, response.ErrorCode, response.ErrorMessage); - Assert.AreEqual(40, response.AccessUsage?.SentTraffic); - Assert.AreEqual(20, response.AccessUsage?.ReceivedTraffic); + Assert.AreEqual(40, response.AccessUsage?.Traffic.Sent); + Assert.AreEqual(20, response.AccessUsage?.Traffic.Received); response = accessServer1.Session_Get(sessionResponse.SessionId, sessionRequestEx1.HostEndPoint, sessionRequestEx1.ClientIp).Result; Assert.AreEqual(SessionErrorCode.Ok, response.ErrorCode, response.ErrorMessage); - Assert.AreEqual(40, response.AccessUsage?.SentTraffic); - Assert.AreEqual(20, response.AccessUsage?.ReceivedTraffic); + Assert.AreEqual(40, response.AccessUsage?.Traffic.Sent); + Assert.AreEqual(20, response.AccessUsage?.Traffic.Received); // close session response = accessServer1.Session_Close(sessionResponse.SessionId, - new UsageInfo { SentTraffic = 20, ReceivedTraffic = 10 }).Result; + new Traffic {Sent = 20, Received = 10 }).Result; Assert.AreEqual(SessionErrorCode.SessionClosed, response.ErrorCode, response.ErrorMessage); - Assert.AreEqual(60, response.AccessUsage?.SentTraffic); - Assert.AreEqual(30, response.AccessUsage?.ReceivedTraffic); + Assert.AreEqual(60, response.AccessUsage?.Traffic.Sent); + Assert.AreEqual(30, response.AccessUsage?.Traffic.Received); // check is session closed response = accessServer1.Session_Get(sessionResponse.SessionId, sessionRequestEx1.HostEndPoint, sessionRequestEx1.ClientIp).Result; Assert.AreEqual(SessionErrorCode.SessionClosed, response.ErrorCode); - Assert.AreEqual(60, response.AccessUsage?.SentTraffic); - Assert.AreEqual(30, response.AccessUsage?.ReceivedTraffic); + Assert.AreEqual(60, response.AccessUsage?.Traffic.Sent); + Assert.AreEqual(30, response.AccessUsage?.Traffic.Received); // check restore var accessServer2 = TestHelper.CreateFileAccessServer(storagePath : storagePath); response = accessServer2.Session_Create(sessionRequestEx1).Result; Assert.AreEqual(SessionErrorCode.Ok, response.ErrorCode); - Assert.AreEqual(60, response.AccessUsage?.SentTraffic); - Assert.AreEqual(30, response.AccessUsage?.ReceivedTraffic); + Assert.AreEqual(60, response.AccessUsage?.Traffic.Sent); + Assert.AreEqual(30, response.AccessUsage?.Traffic.Received); } } \ No newline at end of file diff --git a/VpnHood.ZTest/Tests/NetScanTest.cs b/VpnHood.ZTest/Tests/NetScanTest.cs index 437f0fe04..ba6a695ee 100644 --- a/VpnHood.ZTest/Tests/NetScanTest.cs +++ b/VpnHood.ZTest/Tests/NetScanTest.cs @@ -29,7 +29,7 @@ public async Task Reject_by_server() await tcpClient1.ConnectAsync(TestHelper.TEST_TcpEndPoint1); try { - await Util.RunTask(tcpClient1.GetStream().ReadAsync(new byte[100]).AsTask(), TimeSpan.FromSeconds(2)); + await VhUtil.RunTask(tcpClient1.GetStream().ReadAsync(new byte[100]).AsTask(), TimeSpan.FromSeconds(2)); } catch (Exception ex) { diff --git a/VpnHood.ZTest/Tests/ServerTest.cs b/VpnHood.ZTest/Tests/ServerTest.cs index d42bdebed..f584987d0 100644 --- a/VpnHood.ZTest/Tests/ServerTest.cs +++ b/VpnHood.ZTest/Tests/ServerTest.cs @@ -40,7 +40,7 @@ public async Task Auto_sync_sessions_by_interval() // check usage when usage should be 0 var sessionResponseEx = await testAccessServer.Session_Get(client.SessionId, client.HostEndPoint!, null); - Assert.IsTrue(sessionResponseEx.AccessUsage!.ReceivedTraffic == 0); + Assert.IsTrue(sessionResponseEx.AccessUsage!.Traffic.Received == 0); // lets do transfer await TestHelper.Test_HttpsAsync(); @@ -48,13 +48,13 @@ public async Task Auto_sync_sessions_by_interval() // check usage should still not be 0 after interval await Task.Delay(1000); sessionResponseEx = await testAccessServer.Session_Get(client.SessionId, client.HostEndPoint!, null); - Assert.IsTrue(sessionResponseEx.AccessUsage!.ReceivedTraffic > 0); + Assert.IsTrue(sessionResponseEx.AccessUsage!.Traffic.Received > 0); } [TestMethod] public async Task Reconfigure() { - var serverEndPoint = Util.GetFreeTcpEndPoint(IPAddress.Loopback); + var serverEndPoint = VhUtil.GetFreeTcpEndPoint(IPAddress.Loopback); var fileAccessServerOptions = new FileAccessServerOptions { TcpEndPoints = new[] { serverEndPoint } }; using var fileAccessServer = TestHelper.CreateFileAccessServer(fileAccessServerOptions); var serverConfig = fileAccessServer.ServerConfig; diff --git a/VpnHood.ZTest/Tests/TcpDatagramTest.cs b/VpnHood.ZTest/Tests/TcpDatagramTest.cs index b3600b228..506ca649c 100644 --- a/VpnHood.ZTest/Tests/TcpDatagramTest.cs +++ b/VpnHood.ZTest/Tests/TcpDatagramTest.cs @@ -28,7 +28,7 @@ public void DatagramMessages() public async Task AutoCloseChannel() { // create server tcp listener - var tcpEndPoint = Util.GetFreeTcpEndPoint(IPAddress.Loopback); + var tcpEndPoint = VhUtil.GetFreeTcpEndPoint(IPAddress.Loopback); var tcpListener = new TcpListener(tcpEndPoint); tcpListener.Start(); var listenerTask = tcpListener.AcceptTcpClientAsync();