Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port checker enhancements #294

Merged
merged 3 commits into from
Jun 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion SIT.Manager/Localization/en-US.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -554,5 +554,10 @@
<system:String x:Key="NetworkToolsViewNatPortLabelText">Nat Port: </system:String>
<system:String x:Key="NetworkToolsViewPortTestSuccessText">Port open!</system:String>
<system:String x:Key="NetworkToolsViewPortTestFailText">Port closed!</system:String>
<system:String x:Key="NetworkToolsViewUnknownIpAddressText">Unknown</system:String>
<system:String x:Key="NetworkToolsViewUnknownIpAddressText">Unknown</system:String>
<system:String x:Key="NetworkToolsViewServerLocationRadioGroupHeader">Where is the server you wish to check?</system:String>
<system:String x:Key="NetworkToolsViewServerLocationLocalServerOption">Local</system:String>
<system:String x:Key="NetworkToolsViewServerLocationExternalServerOption">External</system:String>
<system:String x:Key="NetworkToolsViewExternalIPAddressSelectionText">External IP to test:</system:String>
<system:String x:Key="NetworkToolsViewExternalIPAddressSelectionWatermark">External Server Address</system:String>
</ResourceDictionary>
5 changes: 5 additions & 0 deletions SIT.Manager/Localization/ru-RU.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -556,4 +556,9 @@
<system:String x:Key="NetworkToolsViewPortTestSuccessText">Port open!</system:String>
<system:String x:Key="NetworkToolsViewPortTestFailText">Port closed!</system:String>
<system:String x:Key="NetworkToolsViewUnknownIpAddressText">Unknown</system:String>
<system:String x:Key="NetworkToolsViewServerLocationRadioGroupHeader">Where is the server you wish to check?</system:String>
<system:String x:Key="NetworkToolsViewServerLocationLocalServerOption">Local</system:String>
<system:String x:Key="NetworkToolsViewServerLocationExternalServerOption">External</system:String>
<system:String x:Key="NetworkToolsViewExternalIPAddressSelectionText">External IP to test:</system:String>
<system:String x:Key="NetworkToolsViewExternalIPAddressSelectionWatermark">External Server Address</system:String>
</ResourceDictionary>
5 changes: 5 additions & 0 deletions SIT.Manager/Localization/uk-UA.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -557,4 +557,9 @@
<system:String x:Key="NetworkToolsViewPortTestSuccessText">Port open!</system:String>
<system:String x:Key="NetworkToolsViewPortTestFailText">Port closed!</system:String>
<system:String x:Key="NetworkToolsViewUnknownIpAddressText">Unknown</system:String>
<system:String x:Key="NetworkToolsViewServerLocationRadioGroupHeader">Where is the server you wish to check?</system:String>
<system:String x:Key="NetworkToolsViewServerLocationLocalServerOption">Local</system:String>
<system:String x:Key="NetworkToolsViewServerLocationExternalServerOption">External</system:String>
<system:String x:Key="NetworkToolsViewExternalIPAddressSelectionText">External IP to test:</system:String>
<system:String x:Key="NetworkToolsViewExternalIPAddressSelectionWatermark">External Server Address</system:String>
</ResourceDictionary>
5 changes: 5 additions & 0 deletions SIT.Manager/Localization/zh-CN.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -557,4 +557,9 @@
<system:String x:Key="NetworkToolsViewPortTestSuccessText">Port open!</system:String>
<system:String x:Key="NetworkToolsViewPortTestFailText">Port closed!</system:String>
<system:String x:Key="NetworkToolsViewUnknownIpAddressText">Unknown</system:String>
<system:String x:Key="NetworkToolsViewServerLocationRadioGroupHeader">Where is the server you wish to check?</system:String>
<system:String x:Key="NetworkToolsViewServerLocationLocalServerOption">Local</system:String>
<system:String x:Key="NetworkToolsViewServerLocationExternalServerOption">External</system:String>
<system:String x:Key="NetworkToolsViewExternalIPAddressSelectionText">External IP to test:</system:String>
<system:String x:Key="NetworkToolsViewExternalIPAddressSelectionWatermark">External Server Address</system:String>
</ResourceDictionary>
5 changes: 5 additions & 0 deletions SIT.Manager/Localization/zh-HK.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -556,4 +556,9 @@
<system:String x:Key="NetworkToolsViewPortTestSuccessText">Port open!</system:String>
<system:String x:Key="NetworkToolsViewPortTestFailText">Port closed!</system:String>
<system:String x:Key="NetworkToolsViewUnknownIpAddressText">Unknown</system:String>
<system:String x:Key="NetworkToolsViewServerLocationRadioGroupHeader">Where is the server you wish to check?</system:String>
<system:String x:Key="NetworkToolsViewServerLocationLocalServerOption">Local</system:String>
<system:String x:Key="NetworkToolsViewServerLocationExternalServerOption">External</system:String>
<system:String x:Key="NetworkToolsViewExternalIPAddressSelectionText">External IP to test:</system:String>
<system:String x:Key="NetworkToolsViewExternalIPAddressSelectionWatermark">External Server Address</system:String>
</ResourceDictionary>
5 changes: 5 additions & 0 deletions SIT.Manager/Localization/zh-TW.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -557,4 +557,9 @@
<system:String x:Key="NetworkToolsViewPortTestSuccessText">Port open!</system:String>
<system:String x:Key="NetworkToolsViewPortTestFailText">Port closed!</system:String>
<system:String x:Key="NetworkToolsViewUnknownIpAddressText">Unknown</system:String>
<system:String x:Key="NetworkToolsViewServerLocationRadioGroupHeader">Where is the server you wish to check?</system:String>
<system:String x:Key="NetworkToolsViewServerLocationLocalServerOption">Local</system:String>
<system:String x:Key="NetworkToolsViewServerLocationExternalServerOption">External</system:String>
<system:String x:Key="NetworkToolsViewExternalIPAddressSelectionText">External IP to test:</system:String>
<system:String x:Key="NetworkToolsViewExternalIPAddressSelectionWatermark">External Server Address</system:String>
</ResourceDictionary>
92 changes: 78 additions & 14 deletions SIT.Manager/ViewModels/Tools/NetworkToolsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,82 @@
using Polly;
using Polly.Registry;
using SIT.Manager.Models.Tools;
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Net.Sockets;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

namespace SIT.Manager.ViewModels.Tools;

public partial class NetworkToolsViewModel(HttpClient httpClient,
ResiliencePipelineProvider<string> pipelineProvider,
ILogger<NetworkToolsViewModel> logger) : ObservableRecipient
public partial class NetworkToolsViewModel : ObservableRecipient
{
private readonly ILogger<NetworkToolsViewModel> _logger = logger;
private readonly HttpClient _httpClient;
private readonly ILogger<NetworkToolsViewModel> _logger;
private readonly ResiliencePipelineProvider<string> _pipelineProvider;

private CancellationTokenSource _requestCancellationSource = new();

[ObservableProperty]
private bool _checkLocalServer = true;

[ObservableProperty]
private bool _hasRunPortCheck = false;

[ObservableProperty]
private string _externalServerIP = string.Empty;

[ObservableProperty]
private PortCheckerResponse _portResponse = new();

[RelayCommand]
private async Task CheckPorts()
public IAsyncRelayCommand CheckPortsCommand { get; }

public NetworkToolsViewModel(HttpClient httpClient,
ResiliencePipelineProvider<string> pipelineProvider,
ILogger<NetworkToolsViewModel> logger)
{
CancellationToken token = _requestCancellationSource.Token;
ResiliencePipeline<HttpResponseMessage> pipeline =
pipelineProvider.GetPipeline<HttpResponseMessage>("port-checker-pipeline");
_httpClient = httpClient;
_logger = logger;
_pipelineProvider = pipelineProvider;

CheckPortsCommand = new AsyncRelayCommand(CheckPorts);
}

private static async Task<bool> CheckPort(string host, ushort port, CancellationToken token)
{
using (TcpClient tcpClient = new())
{
try
{
await tcpClient.ConnectAsync(host, port, token);
}
catch (Exception)
{
return false;
}
}
return true;
}

private async Task ExternalServerPortCheck(CancellationToken token)
{
PortCheckerResponse response = new()
{
AkiSuccess = await CheckPort(ExternalServerIP, ushort.Parse(PortResponse.PortsUsed.AkiPort), token).ConfigureAwait(false),
NatSuccess = await CheckPort(ExternalServerIP, ushort.Parse(PortResponse.PortsUsed.NatPort), token).ConfigureAwait(false),
RelaySuccess = await CheckPort(ExternalServerIP, ushort.Parse(PortResponse.PortsUsed.RelayPort), token).ConfigureAwait(false),
PortsUsed = PortResponse.PortsUsed,
IpAddress = ExternalServerIP
};
await ProcessPortResponse(response);
}

private async Task LocalServerPortCheck(CancellationToken token)
{
ResiliencePipeline<HttpResponseMessage> pipeline = _pipelineProvider.GetPipeline<HttpResponseMessage>("port-checker-pipeline");

//This might be the wrong way to use polly pipelines
//TODO: Do further reading on polly to see if I can improve this
Expand All @@ -44,22 +91,22 @@ private async Task CheckPorts()
{
Content = JsonContent.Create(PortResponse.PortsUsed)
};
return await httpClient.SendAsync(req, ct);
return await _httpClient.SendAsync(req, ct).ConfigureAwait(false);
}, token);

switch (reqResp.StatusCode)
{
case HttpStatusCode.OK:
{
string response = await reqResp.Content.ReadAsStringAsync(token);
string response = await reqResp.Content.ReadAsStringAsync(token).ConfigureAwait(false);
PortCheckerResponse? respModel = JsonSerializer.Deserialize<PortCheckerResponse>(response);
if (respModel == null)
{
//TODO: Logging here
return;
}

ProcessPortResponse(respModel);
await ProcessPortResponse(respModel);
break;
}
case HttpStatusCode.ServiceUnavailable:
Expand All @@ -69,18 +116,35 @@ private async Task CheckPorts()
}
default:
{
//TODO: Logging here
_logger.LogWarning("Unknown http status response {statusCode}", reqResp.StatusCode);
return;
}
}
}
catch (TaskCanceledException) { }
}

private void ProcessPortResponse(PortCheckerResponse response)
private async Task CheckPorts()
{
CancellationToken token = _requestCancellationSource.Token;
if (CheckLocalServer)
{
await LocalServerPortCheck(token);
}
else
{
await ExternalServerPortCheck(token);
}
}

private async Task ProcessPortResponse(PortCheckerResponse response)
{
PortResponse = response;
HasRunPortCheck = true;

// We had a successfull check so just put an artificial wait here to
// force a slight delay on users spamming the button to check their ports
await Task.Delay(Random.Shared.Next(2500));
}

protected override void OnActivated()
Expand Down
Loading
Loading