release: bump version to 0.57.0
This commit is contained in:
103
scripts/windows-lan-relay.ps1
Normal file
103
scripts/windows-lan-relay.ps1
Normal file
@@ -0,0 +1,103 @@
|
||||
param(
|
||||
[string]$ListenAddress = "0.0.0.0",
|
||||
[Parameter(Mandatory = $true)][int]$ListenPort,
|
||||
[Parameter(Mandatory = $true)][string]$TargetHost,
|
||||
[Parameter(Mandatory = $true)][int]$TargetPort,
|
||||
[int]$IdleExitSeconds = 8
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
Add-Type -TypeDefinition @"
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public static class PlanetTcpRelay
|
||||
{
|
||||
public static async Task RunAsync(string listenAddress, int listenPort, string targetHost, int targetPort, int idleExitSeconds)
|
||||
{
|
||||
IPAddress address;
|
||||
if (!IPAddress.TryParse(listenAddress, out address))
|
||||
{
|
||||
address = IPAddress.Any;
|
||||
}
|
||||
var listener = new TcpListener(address, listenPort);
|
||||
listener.Start();
|
||||
var lastHealthyAt = DateTime.UtcNow;
|
||||
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (await CanConnectAsync(targetHost, targetPort))
|
||||
{
|
||||
lastHealthyAt = DateTime.UtcNow;
|
||||
}
|
||||
else if ((DateTime.UtcNow - lastHealthyAt).TotalSeconds >= idleExitSeconds)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
while (listener.Pending())
|
||||
{
|
||||
var client = await listener.AcceptTcpClientAsync();
|
||||
_ = Task.Run(() => HandleClientAsync(client, targetHost, targetPort));
|
||||
}
|
||||
|
||||
await Task.Delay(200);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
listener.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<bool> CanConnectAsync(string host, int port)
|
||||
{
|
||||
using (var client = new TcpClient())
|
||||
{
|
||||
var connectTask = client.ConnectAsync(host, port);
|
||||
var completed = await Task.WhenAny(connectTask, Task.Delay(500));
|
||||
if (completed != connectTask)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await connectTask;
|
||||
return client.Connected;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task HandleClientAsync(TcpClient client, string targetHost, int targetPort)
|
||||
{
|
||||
using (client)
|
||||
using (var upstream = new TcpClient())
|
||||
{
|
||||
try
|
||||
{
|
||||
await upstream.ConnectAsync(targetHost, targetPort);
|
||||
var clientStream = client.GetStream();
|
||||
var upstreamStream = upstream.GetStream();
|
||||
var toUpstream = clientStream.CopyToAsync(upstreamStream);
|
||||
var toClient = upstreamStream.CopyToAsync(clientStream);
|
||||
await Task.WhenAny(toUpstream, toClient);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"@
|
||||
|
||||
[PlanetTcpRelay]::RunAsync($ListenAddress, $ListenPort, $TargetHost, $TargetPort, $IdleExitSeconds).GetAwaiter().GetResult()
|
||||
Reference in New Issue
Block a user