LumaTunnel
【WinUI】LumaTunnel 是一个面向个人多设备的 Windows 代理系统。客户端在本机提供 HTTP/HTTPS CONNECT 与 SOCKS5 TCP 代理,并通过一个受信任 TLS 证书保护的 WSS 会话,将多个 TCP 流复用到自建 Windows Server 节点。
关注
0
Fork
0
Star
0
using LumaTunnel.Server.Core.Configuration;
using LumaTunnel.Server.Core.Persistence;
using LumaTunnel.Server.Core.Security;
namespace LumaTunnel.Server.Core.Runtime;
public sealed class ServerRuntime
{
private static ServerRuntime? s_current;
private readonly AtomicJsonStore<TrafficDatabase> _trafficStore;
private ServerRuntime(ServerPaths paths, ServerSettings settings, DeviceRegistry devices, PairingCodeService pairingCodes, AtomicJsonStore<TrafficDatabase> trafficStore, TrafficCounters traffic)
{
Paths = paths;
Settings = settings;
Devices = devices;
PairingCodes = pairingCodes;
_trafficStore = trafficStore;
Traffic = traffic;
TargetPolicy = new TargetPolicy(settings);
}
public static ServerRuntime Current => s_current ?? throw new InvalidOperationException("Server runtime has not been initialized.");
public ServerPaths Paths { get; }
public ServerSettings Settings { get; }
public DeviceRegistry Devices { get; }
public PairingCodeService PairingCodes { get; }
public TargetPolicy TargetPolicy { get; }
public TrafficCounters Traffic { get; }
public TunnelConnectionManager? TunnelConnections { get; set; }
public static async Task<ServerRuntime> InitializeAsync(ServerPaths? paths = null, CancellationToken cancellationToken = default)
{
paths ??= ServerPaths.CreateDefault();
paths.EnsureDirectories();
var settingsStore = new AtomicJsonStore<ServerSettings>(paths.SettingsFile);
var settings = await settingsStore.LoadOrCreateAsync(static () => new ServerSettings(), cancellationToken).ConfigureAwait(false);
settings.Validate();
var devices = new DeviceRegistry(new AtomicJsonStore<DeviceDatabase>(paths.DevicesFile));
var pairingCodes = new PairingCodeService(new AtomicJsonStore<PairingCodeDatabase>(paths.PairingCodesFile));
var trafficStore = new AtomicJsonStore<TrafficDatabase>(paths.TrafficFile);
await devices.InitializeAsync(cancellationToken).ConfigureAwait(false);
await pairingCodes.InitializeAsync(cancellationToken).ConfigureAwait(false);
var traffic = await trafficStore.LoadOrCreateAsync(static () => new TrafficDatabase(), cancellationToken).ConfigureAwait(false);
s_current = new ServerRuntime(paths, settings, devices, pairingCodes, trafficStore, new TrafficCounters(traffic.Devices));
return s_current;
}
public async Task FlushAsync(CancellationToken cancellationToken = default)
{
await Devices.SaveAsync(cancellationToken).ConfigureAwait(false);
await _trafficStore.SaveAsync(Traffic.Snapshot(), cancellationToken).ConfigureAwait(false);
}
}
using LumaTunnel.Server.Core.Configuration;
using LumaTunnel.Server.Core.Persistence;
using LumaTunnel.Server.Core.Security;
namespace LumaTunnel.Server.Core.Runtime;
public sealed class ServerRuntime
{
private static ServerRuntime? s_current;
private readonly AtomicJsonStore<TrafficDatabase> _trafficStore;
private ServerRuntime(ServerPaths paths, ServerSettings settings, DeviceRegistry devices, PairingCodeService pairingCodes, AtomicJsonStore<TrafficDatabase> trafficStore, TrafficCounters traffic)
{
Paths = paths;
Settings = settings;
Devices = devices;
PairingCodes = pairingCodes;
_trafficStore = trafficStore;
Traffic = traffic;
TargetPolicy = new TargetPolicy(settings);
}
public static ServerRuntime Current => s_current ?? throw new InvalidOperationException("Server runtime has not been initialized.");
public ServerPaths Paths { get; }
public ServerSettings Settings { get; }
public DeviceRegistry Devices { get; }
public PairingCodeService PairingCodes { get; }
public TargetPolicy TargetPolicy { get; }
public TrafficCounters Traffic { get; }
public TunnelConnectionManager? TunnelConnections { get; set; }
public static async Task<ServerRuntime> InitializeAsync(ServerPaths? paths = null, CancellationToken cancellationToken = default)
{
paths ??= ServerPaths.CreateDefault();
paths.EnsureDirectories();
var settingsStore = new AtomicJsonStore<ServerSettings>(paths.SettingsFile);
var settings = await settingsStore.LoadOrCreateAsync(static () => new ServerSettings(), cancellationToken).ConfigureAwait(false);
settings.Validate();
var devices = new DeviceRegistry(new AtomicJsonStore<DeviceDatabase>(paths.DevicesFile));
var pairingCodes = new PairingCodeService(new AtomicJsonStore<PairingCodeDatabase>(paths.PairingCodesFile));
var trafficStore = new AtomicJsonStore<TrafficDatabase>(paths.TrafficFile);
await devices.InitializeAsync(cancellationToken).ConfigureAwait(false);
await pairingCodes.InitializeAsync(cancellationToken).ConfigureAwait(false);
var traffic = await trafficStore.LoadOrCreateAsync(static () => new TrafficDatabase(), cancellationToken).ConfigureAwait(false);
s_current = new ServerRuntime(paths, settings, devices, pairingCodes, trafficStore, new TrafficCounters(traffic.Devices));
return s_current;
}
public async Task FlushAsync(CancellationToken cancellationToken = default)
{
await Devices.SaveAsync(cancellationToken).ConfigureAwait(false);
await _trafficStore.SaveAsync(Traffic.Snapshot(), cancellationToken).ConfigureAwait(false);
}
}