LumaTunnel
【WinUI】LumaTunnel 是一个面向个人多设备的 Windows 代理系统。客户端在本机提供 HTTP/HTTPS CONNECT 与 SOCKS5 TCP 代理,并通过一个受信任 TLS 证书保护的 WSS 会话,将多个 TCP 流复用到自建 Windows Server 节点。
关注
0
Fork
0
Star
0
using System.Diagnostics;
using System.IO.Pipes;
using LumaTunnel.Shared.Windows;
var options = WatchdogOptions.Parse(args);
if (options is null)
return 2;
try
{
using var parent = Process.GetProcessById(options.ParentProcessId);
using var pipe = new NamedPipeClientStream(".", options.PipeName, PipeDirection.In, PipeOptions.Asynchronous);
try
{
using var connectTimeout = new CancellationTokenSource(TimeSpan.FromSeconds(5));
await pipe.ConnectAsync(connectTimeout.Token).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
}
var parentExit = parent.WaitForExitAsync();
var buffer = new byte[16];
var pipeSignal = pipe.IsConnected ? pipe.ReadAsync(buffer).AsTask() : Task.FromResult(0);
var completed = await Task.WhenAny(parentExit, pipeSignal).ConfigureAwait(false);
if (completed == pipeSignal && await pipeSignal.ConfigureAwait(false) > 0)
return 0;
var snapshot = await SystemProxyRegistry.LoadSnapshotAsync(options.SnapshotPath).ConfigureAwait(false);
if (snapshot is not null && snapshot.OwnerId == options.OwnerId)
SystemProxyRegistry.RestoreIfOwned(snapshot, options.HttpPort);
return 0;
}
catch (ArgumentException)
{
var snapshot = await SystemProxyRegistry.LoadSnapshotAsync(options.SnapshotPath).ConfigureAwait(false);
if (snapshot is not null && snapshot.OwnerId == options.OwnerId)
SystemProxyRegistry.RestoreIfOwned(snapshot, options.HttpPort);
return 0;
}
internal sealed record WatchdogOptions(int ParentProcessId, string PipeName, string SnapshotPath, string OwnerId, int HttpPort)
{
public static WatchdogOptions? Parse(string[] args)
{
string? Read(string name)
{
var index = Array.FindIndex(args, item => item.Equals(name, StringComparison.OrdinalIgnoreCase));
return index >= 0 && index + 1 < args.Length ? args[index + 1] : null;
}
return int.TryParse(Read("--parent"), out var parent)
&& int.TryParse(Read("--port"), out var port)
&& Read("--pipe") is { Length: > 0 } pipe
&& Read("--snapshot") is { Length: > 0 } snapshot
&& Read("--owner") is { Length: > 0 } owner
? new WatchdogOptions(parent, pipe, snapshot, owner, port)
: null;
}
}
using System.Diagnostics;
using System.IO.Pipes;
using LumaTunnel.Shared.Windows;
var options = WatchdogOptions.Parse(args);
if (options is null)
return 2;
try
{
using var parent = Process.GetProcessById(options.ParentProcessId);
using var pipe = new NamedPipeClientStream(".", options.PipeName, PipeDirection.In, PipeOptions.Asynchronous);
try
{
using var connectTimeout = new CancellationTokenSource(TimeSpan.FromSeconds(5));
await pipe.ConnectAsync(connectTimeout.Token).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
}
var parentExit = parent.WaitForExitAsync();
var buffer = new byte[16];
var pipeSignal = pipe.IsConnected ? pipe.ReadAsync(buffer).AsTask() : Task.FromResult(0);
var completed = await Task.WhenAny(parentExit, pipeSignal).ConfigureAwait(false);
if (completed == pipeSignal && await pipeSignal.ConfigureAwait(false) > 0)
return 0;
var snapshot = await SystemProxyRegistry.LoadSnapshotAsync(options.SnapshotPath).ConfigureAwait(false);
if (snapshot is not null && snapshot.OwnerId == options.OwnerId)
SystemProxyRegistry.RestoreIfOwned(snapshot, options.HttpPort);
return 0;
}
catch (ArgumentException)
{
var snapshot = await SystemProxyRegistry.LoadSnapshotAsync(options.SnapshotPath).ConfigureAwait(false);
if (snapshot is not null && snapshot.OwnerId == options.OwnerId)
SystemProxyRegistry.RestoreIfOwned(snapshot, options.HttpPort);
return 0;
}
internal sealed record WatchdogOptions(int ParentProcessId, string PipeName, string SnapshotPath, string OwnerId, int HttpPort)
{
public static WatchdogOptions? Parse(string[] args)
{
string? Read(string name)
{
var index = Array.FindIndex(args, item => item.Equals(name, StringComparison.OrdinalIgnoreCase));
return index >= 0 && index + 1 < args.Length ? args[index + 1] : null;
}
return int.TryParse(Read("--parent"), out var parent)
&& int.TryParse(Read("--port"), out var port)
&& Read("--pipe") is { Length: > 0 } pipe
&& Read("--snapshot") is { Length: > 0 } snapshot
&& Read("--owner") is { Length: > 0 } owner
? new WatchdogOptions(parent, pipe, snapshot, owner, port)
: null;
}
}