重构中继,合并到隧道协议,不再单独配置

This commit is contained in:
snltty
2025-11-25 17:11:31 +08:00
parent 6b1dea777e
commit 1b61d67186
37 changed files with 245 additions and 550 deletions

View File

@@ -1,5 +1,5 @@
v1.9.6 v1.9.6
2025-11-25 09:52:47 2025-11-25 17:11:30
1. 一些累计更新一些BUG修复 1. 一些累计更新一些BUG修复
2. 优化客户端数据同步,减少服务器流量 2. 优化客户端数据同步,减少服务器流量
3. 去除cdkey改为发电解锁中继速度 3. 去除cdkey改为发电解锁中继速度

View File

@@ -2,7 +2,6 @@
using linker.libs.extends; using linker.libs.extends;
using linker.libs.timer; using linker.libs.timer;
using linker.messenger.pcp; using linker.messenger.pcp;
using linker.messenger.relay.client;
using linker.messenger.signin; using linker.messenger.signin;
using linker.tunnel; using linker.tunnel;
using linker.tunnel.connection; using linker.tunnel.connection;
@@ -73,17 +72,15 @@ namespace linker.messenger.channel
protected virtual string TransactionId { get; } protected virtual string TransactionId { get; }
private readonly TunnelTransfer tunnelTransfer; private readonly TunnelTransfer tunnelTransfer;
private readonly RelayClientTransfer relayTransfer;
private readonly PcpTransfer pcpTransfer; private readonly PcpTransfer pcpTransfer;
private readonly SignInClientTransfer signInClientTransfer; private readonly SignInClientTransfer signInClientTransfer;
private readonly ISignInClientStore signInClientStore; private readonly ISignInClientStore signInClientStore;
private readonly ChannelConnectionCaching channelConnectionCaching; private readonly ChannelConnectionCaching channelConnectionCaching;
public Channel(TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, public Channel(TunnelTransfer tunnelTransfer, PcpTransfer pcpTransfer,
SignInClientTransfer signInClientTransfer, ISignInClientStore signInClientStore, ChannelConnectionCaching channelConnectionCaching) SignInClientTransfer signInClientTransfer, ISignInClientStore signInClientStore, ChannelConnectionCaching channelConnectionCaching)
{ {
this.tunnelTransfer = tunnelTransfer; this.tunnelTransfer = tunnelTransfer;
this.relayTransfer = relayTransfer;
this.pcpTransfer = pcpTransfer; this.pcpTransfer = pcpTransfer;
this.signInClientTransfer = signInClientTransfer; this.signInClientTransfer = signInClientTransfer;
this.signInClientStore = signInClientStore; this.signInClientStore = signInClientStore;
@@ -91,8 +88,6 @@ namespace linker.messenger.channel
//监听打洞成功 //监听打洞成功
tunnelTransfer.SetConnectedCallback(TransactionId, OnConnected); tunnelTransfer.SetConnectedCallback(TransactionId, OnConnected);
//监听中继成功
relayTransfer.SetConnectedCallback(TransactionId, OnConnected);
//监听节点中继成功回调 //监听节点中继成功回调
pcpTransfer.SetConnectedCallback(TransactionId, OnConnected); pcpTransfer.SetConnectedCallback(TransactionId, OnConnected);
@@ -167,7 +162,6 @@ namespace linker.messenger.channel
{ {
channelConnectionCaching.Add(connection); channelConnectionCaching.Add(connection);
} }
} }
catch (Exception) catch (Exception)
{ {
@@ -181,55 +175,29 @@ namespace linker.messenger.channel
} }
private async Task<ITunnelConnection> RelayAndP2P(string machineId, TunnelProtocolType denyProtocols) private async Task<ITunnelConnection> RelayAndP2P(string machineId, TunnelProtocolType denyProtocols)
{ {
//中继 ITunnelConnection connection = null;
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"{TransactionId} relay to {machineId}");
ITunnelConnection connection = await relayTransfer.ConnectAsync(signInClientStore.Id, machineId, TransactionId, denyProtocols).ConfigureAwait(false);
if (connection != null)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"{TransactionId} relay success,{connection.ToString()}");
}
//正在后台打洞 //正在后台打洞
if (tunnelTransfer.IsBackground(machineId, TransactionId)) if (tunnelTransfer.IsBackground(machineId, TransactionId))
{ {
return connection; return connection;
} }
//隧道连接
connection = await tunnelTransfer.ConnectAsync(machineId, TransactionId, denyProtocols).ConfigureAwait(false);
if (connection != null) if (connection != null)
{ {
//后台打洞 return connection;
tunnelTransfer.StartBackground(machineId, TransactionId, denyProtocols, () =>
{
return channelConnectionCaching.TryGetValue(machineId, TransactionId, out ITunnelConnection connection) && connection.Connected && connection.Type == TunnelType.P2P;
}, async (_connection) =>
{
//后台打洞失败pcp
if (_connection == null)
{
await pcpTransfer.ConnectAsync(machineId, TransactionId, denyProtocols).ConfigureAwait(false);
}
}, 3, 10000);
} }
else
//后台打洞
tunnelTransfer.StartBackground(machineId, TransactionId, denyProtocols, () =>
{ {
//打洞 return channelConnectionCaching.TryGetValue(machineId, TransactionId, out ITunnelConnection connection) && connection.Connected;
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"{TransactionId} p2p to {machineId}"); }, async (_connection) =>
connection = await tunnelTransfer.ConnectAsync(machineId, TransactionId, denyProtocols).ConfigureAwait(false); {
if (connection != null) await Task.CompletedTask;
{ }, 3, 10000);
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"{TransactionId} p2p success,{connection.ToString()}");
}
if (connection == null)
{
//pcp
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"{TransactionId} pcp to {machineId}");
connection = await pcpTransfer.ConnectAsync(machineId, TransactionId, denyProtocols).ConfigureAwait(false);
}
if (connection != null)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"{TransactionId} pcp success,{connection.ToString()}");
}
}
return connection; return connection;
} }

View File

@@ -4,7 +4,6 @@ using linker.libs.timer;
using linker.messenger.channel; using linker.messenger.channel;
using linker.messenger.forward.proxy; using linker.messenger.forward.proxy;
using linker.messenger.pcp; using linker.messenger.pcp;
using linker.messenger.relay.client;
using linker.messenger.signin; using linker.messenger.signin;
using linker.tunnel; using linker.tunnel;
using linker.tunnel.connection; using linker.tunnel.connection;
@@ -18,9 +17,9 @@ namespace linker.messenger.flow
{ {
private readonly FlowForward forwardFlow; private readonly FlowForward forwardFlow;
private readonly FlowTunnel flowTunnel; private readonly FlowTunnel flowTunnel;
public FlowForwardProxy(FlowForward forwardFlow, FlowTunnel flowTunnel, ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, public FlowForwardProxy(FlowForward forwardFlow, FlowTunnel flowTunnel, ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, PcpTransfer pcpTransfer,
SignInClientTransfer signInClientTransfer, ChannelConnectionCaching channelConnectionCaching) SignInClientTransfer signInClientTransfer, ChannelConnectionCaching channelConnectionCaching)
: base(signInClientStore, tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, channelConnectionCaching) : base(signInClientStore, tunnelTransfer, pcpTransfer, signInClientTransfer, channelConnectionCaching)
{ {
this.forwardFlow = forwardFlow; this.forwardFlow = forwardFlow;
this.flowTunnel = flowTunnel; this.flowTunnel = flowTunnel;

View File

@@ -3,7 +3,6 @@ using linker.libs.extends;
using linker.libs.timer; using linker.libs.timer;
using linker.messenger.channel; using linker.messenger.channel;
using linker.messenger.pcp; using linker.messenger.pcp;
using linker.messenger.relay.client;
using linker.messenger.signin; using linker.messenger.signin;
using linker.messenger.socks5; using linker.messenger.socks5;
using linker.tunnel; using linker.tunnel;
@@ -19,9 +18,9 @@ namespace linker.messenger.flow
private readonly FlowSocks5 flowSocks5; private readonly FlowSocks5 flowSocks5;
private readonly FlowTunnel flowTunnel; private readonly FlowTunnel flowTunnel;
public FlowSocks5Proxy(FlowSocks5 flowSocks5, FlowTunnel flowTunnel, ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, public FlowSocks5Proxy(FlowSocks5 flowSocks5, FlowTunnel flowTunnel, ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, PcpTransfer pcpTransfer,
SignInClientTransfer signInClientTransfer, Socks5CidrDecenterManager socks5CidrDecenterManager, ChannelConnectionCaching channelConnectionCaching) SignInClientTransfer signInClientTransfer, Socks5CidrDecenterManager socks5CidrDecenterManager, ChannelConnectionCaching channelConnectionCaching)
: base(signInClientStore, tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, socks5CidrDecenterManager, channelConnectionCaching) : base(signInClientStore, tunnelTransfer, pcpTransfer, signInClientTransfer, socks5CidrDecenterManager, channelConnectionCaching)
{ {
this.flowSocks5 = flowSocks5; this.flowSocks5 = flowSocks5;
this.flowTunnel = flowTunnel; this.flowTunnel = flowTunnel;

View File

@@ -2,11 +2,9 @@
using linker.libs.extends; using linker.libs.extends;
using linker.messenger.channel; using linker.messenger.channel;
using linker.messenger.pcp; using linker.messenger.pcp;
using linker.messenger.relay.client;
using linker.messenger.signin; using linker.messenger.signin;
using linker.messenger.tuntap; using linker.messenger.tuntap;
using linker.messenger.tuntap.cidr; using linker.messenger.tuntap.cidr;
using linker.nat;
using linker.tunnel; using linker.tunnel;
using linker.tunnel.connection; using linker.tunnel.connection;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@@ -18,11 +16,11 @@ namespace linker.messenger.flow
{ {
private readonly FlowTunnel flowTunnel; private readonly FlowTunnel flowTunnel;
public FlowTuntapProxy(FlowTunnel flowTunnel, ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, public FlowTuntapProxy(FlowTunnel flowTunnel, ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, PcpTransfer pcpTransfer,
SignInClientTransfer signInClientTransfer, TuntapConfigTransfer tuntapConfigTransfer, SignInClientTransfer signInClientTransfer, TuntapConfigTransfer tuntapConfigTransfer,
TuntapCidrConnectionManager tuntapCidrConnectionManager, TuntapCidrDecenterManager tuntapCidrDecenterManager, TuntapCidrConnectionManager tuntapCidrConnectionManager, TuntapCidrDecenterManager tuntapCidrDecenterManager,
TuntapCidrMapfileManager tuntapCidrMapfileManager,TuntapDecenter tuntapDecenter, ChannelConnectionCaching channelConnectionCaching) TuntapCidrMapfileManager tuntapCidrMapfileManager,TuntapDecenter tuntapDecenter, ChannelConnectionCaching channelConnectionCaching)
: base(signInClientStore, tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, : base(signInClientStore, tunnelTransfer, pcpTransfer, signInClientTransfer,
tuntapConfigTransfer, tuntapCidrConnectionManager, tuntapCidrDecenterManager, tuntapCidrMapfileManager, tuntapDecenter, channelConnectionCaching) tuntapConfigTransfer, tuntapCidrConnectionManager, tuntapCidrDecenterManager, tuntapCidrMapfileManager, tuntapDecenter, channelConnectionCaching)
{ {
this.flowTunnel = flowTunnel; this.flowTunnel = flowTunnel;

View File

@@ -2,12 +2,10 @@
using linker.tunnel.connection; using linker.tunnel.connection;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Net; using System.Net;
using linker.messenger.relay.client;
using linker.messenger.signin; using linker.messenger.signin;
using linker.messenger.channel; using linker.messenger.channel;
using linker.messenger.pcp; using linker.messenger.pcp;
using linker.libs; using linker.libs;
using System.Net.Sockets;
namespace linker.messenger.forward.proxy namespace linker.messenger.forward.proxy
{ {
@@ -22,9 +20,9 @@ namespace linker.messenger.forward.proxy
protected override string TransactionId => "forward"; protected override string TransactionId => "forward";
public ForwardProxy(ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, public ForwardProxy(ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, PcpTransfer pcpTransfer,
SignInClientTransfer signInClientTransfer, ChannelConnectionCaching channelConnectionCaching) SignInClientTransfer signInClientTransfer, ChannelConnectionCaching channelConnectionCaching)
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching) : base(tunnelTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching)
{ {
TaskUdp(); TaskUdp();
} }
@@ -107,7 +105,7 @@ namespace linker.messenger.forward.proxy
Add(token.Connection.RemoteMachineId, token.IPEndPoint, token.ReadPacket.Length, 0); Add(token.Connection.RemoteMachineId, token.IPEndPoint, token.ReadPacket.Length, 0);
return true; return true;
} }
private async Task<bool> SendToConnection(ITunnelConnection connection,ForwardReadPacket packet,IPEndPoint ep) private async Task<bool> SendToConnection(ITunnelConnection connection, ForwardReadPacket packet, IPEndPoint ep)
{ {
if (connection == null) if (connection == null)
{ {

View File

@@ -3,8 +3,12 @@ using linker.messenger.relay.client;
using linker.messenger.relay.messenger; using linker.messenger.relay.messenger;
using linker.messenger.relay.server; using linker.messenger.relay.server;
using linker.messenger.relay.server.validator; using linker.messenger.relay.server.validator;
using linker.messenger.relay.transport;
using linker.messenger.relay.webapi; using linker.messenger.relay.webapi;
using linker.messenger.sync; using linker.messenger.sync;
using linker.tunnel;
using linker.tunnel.transport;
using linker.tunnel.wanport;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace linker.messenger.relay namespace linker.messenger.relay
{ {
@@ -12,7 +16,9 @@ namespace linker.messenger.relay
{ {
public static ServiceCollection AddRelayClient(this ServiceCollection serviceCollection) public static ServiceCollection AddRelayClient(this ServiceCollection serviceCollection)
{ {
serviceCollection.AddSingleton<RelayClientTransfer>(); serviceCollection.AddSingleton<TransportRelay>();
serviceCollection.AddSingleton<TunnelWanPortProtocolRelay>();
serviceCollection.AddSingleton<RelayClientMessenger>(); serviceCollection.AddSingleton<RelayClientMessenger>();
serviceCollection.AddSingleton<RelaySyncDefault>(); serviceCollection.AddSingleton<RelaySyncDefault>();
@@ -25,11 +31,17 @@ namespace linker.messenger.relay
} }
public static ServiceProvider UseRelayClient(this ServiceProvider serviceProvider) public static ServiceProvider UseRelayClient(this ServiceProvider serviceProvider)
{ {
TunnelTransfer tunnelTransfer = serviceProvider.GetService<TunnelTransfer>();
tunnelTransfer.AddTransport(serviceProvider.GetService<TransportRelay>());
tunnelTransfer.AddProtocol(serviceProvider.GetService<TunnelWanPortProtocolRelay>());
IMessengerResolver messengerResolver = serviceProvider.GetService<IMessengerResolver>(); IMessengerResolver messengerResolver = serviceProvider.GetService<IMessengerResolver>();
messengerResolver.AddMessenger(new List<IMessenger> { serviceProvider.GetService<RelayClientMessenger>() }); messengerResolver.AddMessenger(new List<IMessenger> { serviceProvider.GetService<RelayClientMessenger>() });
SyncTreansfer syncTreansfer = serviceProvider.GetService<SyncTreansfer>(); SyncTreansfer syncTreansfer = serviceProvider.GetService<SyncTreansfer>();
syncTreansfer.AddSyncs(new List<ISync> { serviceProvider.GetService<RelaySyncDefault>() }); syncTreansfer.AddSyncs(new List<ISync> { serviceProvider.GetService<RelaySyncDefault>() });
linker.messenger.api.IWebServer apiServer = serviceProvider.GetService<linker.messenger.api.IWebServer>(); linker.messenger.api.IWebServer apiServer = serviceProvider.GetService<linker.messenger.api.IWebServer>();
apiServer.AddPlugins(new List<IApiController> { serviceProvider.GetService<RelayApiController>() }); apiServer.AddPlugins(new List<IApiController> { serviceProvider.GetService<RelayApiController>() });

View File

@@ -1,5 +1,4 @@
using linker.messenger.relay.client.transport; using linker.tunnel.connection;
using linker.tunnel.connection;
namespace linker.messenger.relay.client namespace linker.messenger.relay.client
{ {
@@ -17,11 +16,6 @@ namespace linker.messenger.relay.client
/// </summary> /// </summary>
public TunnelProtocolType DefaultProtocol { get; } public TunnelProtocolType DefaultProtocol { get; }
/// <summary>
/// 服务器配置
/// </summary>
public RelayServerInfo Server { get; }
/// <summary> /// <summary>
/// 设置默认节点id /// 设置默认节点id
/// </summary> /// </summary>
@@ -32,11 +26,6 @@ namespace linker.messenger.relay.client
/// </summary> /// </summary>
/// <param name="protocol"></param> /// <param name="protocol"></param>
public void SetDefaultProtocol(TunnelProtocolType protocol); public void SetDefaultProtocol(TunnelProtocolType protocol);
/// <summary>
/// 设置中继服务器
/// </summary>
/// <param name="server"></param>
public void SetServer(RelayServerInfo server);
/// <summary> /// <summary>
/// 提交 /// 提交

View File

@@ -7,7 +7,6 @@ using linker.messenger.relay.messenger;
using linker.messenger.relay.server; using linker.messenger.relay.server;
using linker.messenger.signin; using linker.messenger.signin;
using linker.messenger.sync; using linker.messenger.sync;
using linker.tunnel;
using linker.tunnel.connection; using linker.tunnel.connection;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@@ -19,7 +18,6 @@ namespace linker.messenger.relay.client
public sealed class RelayApiController : IApiController public sealed class RelayApiController : IApiController
{ {
private readonly RelayClientTestTransfer relayTestTransfer; private readonly RelayClientTestTransfer relayTestTransfer;
private readonly RelayClientTransfer relayTransfer;
private readonly IRelayClientStore relayClientStore; private readonly IRelayClientStore relayClientStore;
private readonly SignInClientState signInClientState; private readonly SignInClientState signInClientState;
private readonly IMessengerSender messengerSender; private readonly IMessengerSender messengerSender;
@@ -27,11 +25,10 @@ namespace linker.messenger.relay.client
private readonly ISignInClientStore signInClientStore; private readonly ISignInClientStore signInClientStore;
private readonly SyncTreansfer syncTreansfer; private readonly SyncTreansfer syncTreansfer;
public RelayApiController(RelayClientTestTransfer relayTestTransfer, RelayClientTransfer relayTransfer, IRelayClientStore relayClientStore, public RelayApiController(RelayClientTestTransfer relayTestTransfer, IRelayClientStore relayClientStore,
SignInClientState signInClientState, IMessengerSender messengerSender, ISerializer serializer, ISignInClientStore signInClientStore, SyncTreansfer syncTreansfer) SignInClientState signInClientState, IMessengerSender messengerSender, ISerializer serializer, ISignInClientStore signInClientStore, SyncTreansfer syncTreansfer)
{ {
this.relayTestTransfer = relayTestTransfer; this.relayTestTransfer = relayTestTransfer;
this.relayTransfer = relayTransfer;
this.relayClientStore = relayClientStore; this.relayClientStore = relayClientStore;
this.signInClientState = signInClientState; this.signInClientState = signInClientState;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
@@ -40,13 +37,6 @@ namespace linker.messenger.relay.client
this.syncTreansfer = syncTreansfer; this.syncTreansfer = syncTreansfer;
} }
[Access(AccessValue.Config)]
public bool SetServers(ApiControllerParamsInfo param)
{
RelayServerInfo info = param.Content.DeJson<RelayServerInfo>();
relayClientStore.SetServer(info);
return true;
}
public List<RelayServerNodeReportInfo> Subscribe(ApiControllerParamsInfo param) public List<RelayServerNodeReportInfo> Subscribe(ApiControllerParamsInfo param)
{ {
relayTestTransfer.Subscribe(); relayTestTransfer.Subscribe();
@@ -68,25 +58,6 @@ namespace linker.messenger.relay.client
} }
} }
/// <summary>
/// 正在操作列表
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public RelayOperatingInfo Operating(ApiControllerParamsInfo param)
{
ulong hashCode = ulong.Parse(param.Content);
if (relayTransfer.OperatingVersion.Eq(hashCode, out ulong version) == false)
{
return new RelayOperatingInfo
{
List = relayTransfer.Operating,
HashCode = version
};
}
return new RelayOperatingInfo { HashCode = version };
}
/// <summary> /// <summary>
/// 连接 /// 连接
/// </summary> /// </summary>
@@ -99,9 +70,7 @@ namespace linker.messenger.relay.client
{ {
relayConnectInfo.Protocol = TunnelProtocolType.Tcp; relayConnectInfo.Protocol = TunnelProtocolType.Tcp;
} }
//relayClientStore.SetDefaultNodeId(relayConnectInfo.NodeId); //_ = relayTransfer.ConnectAsync(relayConnectInfo.FromMachineId, relayConnectInfo.ToMachineId, relayConnectInfo.TransactionId, relayConnectInfo.NodeId, relayConnectInfo.Protocol);
//relayClientStore.SetDefaultProtocol(relayConnectInfo.Protocol);
_ = relayTransfer.ConnectAsync(relayConnectInfo.FromMachineId, relayConnectInfo.ToMachineId, relayConnectInfo.TransactionId, relayConnectInfo.NodeId, relayConnectInfo.Protocol);
return true; return true;
} }

View File

@@ -1,8 +1,8 @@
using linker.libs; using linker.libs;
using linker.libs.timer; using linker.libs.timer;
using linker.messenger.relay.client.transport;
using linker.messenger.relay.server; using linker.messenger.relay.server;
using linker.messenger.signin; using linker.messenger.signin;
using linker.tunnel.transport;
using System.Net; using System.Net;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
@@ -13,18 +13,16 @@ namespace linker.messenger.relay.client
/// </summary> /// </summary>
public sealed class RelayClientTestTransfer public sealed class RelayClientTestTransfer
{ {
private readonly RelayClientTransfer relayTransfer; private readonly TransportRelay transportRelay;
private readonly SignInClientState signInClientState; private readonly SignInClientState signInClientState;
private readonly ISignInClientStore signInClientStore;
private readonly IRelayClientStore relayClientStore; private readonly IRelayClientStore relayClientStore;
public List<RelayServerNodeReportInfo> Nodes { get; private set; } = new List<RelayServerNodeReportInfo>(); public List<RelayServerNodeReportInfo> Nodes { get; private set; } = new List<RelayServerNodeReportInfo>();
public RelayClientTestTransfer(RelayClientTransfer relayTransfer, SignInClientState signInClientState, ISignInClientStore signInClientStore, IRelayClientStore relayClientStore) public RelayClientTestTransfer(TransportRelay transportRelay, SignInClientState signInClientState, IRelayClientStore relayClientStore)
{ {
this.relayTransfer = relayTransfer; this.transportRelay = transportRelay;
this.signInClientState = signInClientState; this.signInClientState = signInClientState;
this.signInClientStore = signInClientStore;
this.relayClientStore = relayClientStore; this.relayClientStore = relayClientStore;
TestTask(); TestTask();
@@ -40,20 +38,16 @@ namespace linker.messenger.relay.client
{ {
try try
{ {
IRelayClientTransport transport = relayTransfer.Transports.FirstOrDefault(d => d.Type == relayClientStore.Server.RelayType); Nodes = await transportRelay.RelayTestAsync().ConfigureAwait(false);
if (transport != null) var tasks = Nodes.Select(async (c) =>
{ {
Nodes = await transport.RelayTestAsync().ConfigureAwait(false); c.EndPoint = c.EndPoint == null || c.EndPoint.Address.Equals(IPAddress.Any) ? signInClientState.Connection.Address : c.EndPoint;
var tasks = Nodes.Select(async (c) =>
{
c.EndPoint = c.EndPoint == null || c.EndPoint.Address.Equals(IPAddress.Any) ? signInClientState.Connection.Address : c.EndPoint;
using Ping ping = new Ping(); using Ping ping = new Ping();
var resp = await ping.SendPingAsync(c.EndPoint.Address, 1000); var resp = await ping.SendPingAsync(c.EndPoint.Address, 1000);
c.Delay = resp.Status == IPStatus.Success ? (int)resp.RoundtripTime : -1; c.Delay = resp.Status == IPStatus.Success ? (int)resp.RoundtripTime : -1;
}); });
await Task.WhenAll(tasks).ConfigureAwait(false); await Task.WhenAll(tasks).ConfigureAwait(false);
}
} }
catch (Exception) catch (Exception)
{ {

View File

@@ -1,224 +0,0 @@
using linker.messenger.relay.client.transport;
using linker.tunnel.connection;
using linker.libs;
using linker.libs.extends;
using linker.messenger.signin;
using System.Collections.Concurrent;
namespace linker.messenger.relay.client
{
/// <summary>
/// 中继
/// </summary>
public sealed class RelayClientTransfer
{
public List<IRelayClientTransport> Transports { get; private set; }
public VersionManager OperatingVersion => operating.DataVersion;
public ConcurrentDictionary<string, bool> Operating => operating.StringKeyValue;
private readonly OperatingMultipleManager operating = new OperatingMultipleManager();
private Dictionary<string, List<Action<ITunnelConnection>>> OnConnected { get; } = new Dictionary<string, List<Action<ITunnelConnection>>>();
private readonly IRelayClientStore relayClientStore;
private readonly ISignInClientStore signInClientStore;
public RelayClientTransfer(IMessengerSender messengerSender, ISerializer serializer, IRelayClientStore relayClientStore, SignInClientState signInClientState, IMessengerStore messengerStore, ISignInClientStore signInClientStore)
{
this.relayClientStore = relayClientStore;
this.signInClientStore = signInClientStore;
Transports = new List<IRelayClientTransport> {
new RelayClientTransportSelfHost(messengerSender,serializer,relayClientStore,signInClientState,messengerStore),
new RelayClientTransportSelfHostUdp(messengerSender,serializer,relayClientStore,signInClientState,messengerStore),
};
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Info($"load relay transport:{string.Join(",", Transports.Select(c => c.GetType().Name))}");
}
/// <summary>
/// 设置中继成功回调
/// </summary>
/// <param name="transactionId">事务</param>
/// <param name="callback"></param>
public void SetConnectedCallback(string transactionId, Action<ITunnelConnection> callback)
{
if (OnConnected.TryGetValue(transactionId, out List<Action<ITunnelConnection>> callbacks) == false)
{
callbacks = new List<Action<ITunnelConnection>>();
OnConnected[transactionId] = callbacks;
}
callbacks.Add(callback);
}
/// <summary>
/// 一处中继成功回调
/// </summary>
/// <param name="transactionId">事务</param>
/// <param name="callback"></param>
public void RemoveConnectedCallback(string transactionId, Action<ITunnelConnection> callback)
{
if (OnConnected.TryGetValue(transactionId, out List<Action<ITunnelConnection>> callbacks))
{
callbacks.Remove(callback);
}
}
public async Task<ITunnelConnection> ConnectAsync(string fromMachineId, string remoteMachineId, string transactionId, string nodeId, TunnelProtocolType protocol)
{
return await ConnectAsync(fromMachineId, remoteMachineId, transactionId, TunnelProtocolType.All & (~protocol), nodeId, protocol).ConfigureAwait(false);
}
/// <summary>
/// 中继连接对方
/// </summary>
/// <param name="fromMachineId">自己的id</param>
/// <param name="remoteMachineId">对方id</param>
/// <param name="transactionId">事务</param>
/// <returns></returns>
public async Task<ITunnelConnection> ConnectAsync(string fromMachineId, string remoteMachineId, string transactionId, TunnelProtocolType denyProtocols, string nodeId = "", TunnelProtocolType protocol = TunnelProtocolType.None)
{
if (string.IsNullOrWhiteSpace(nodeId)) nodeId = relayClientStore.DefaultNodeId;
if(protocol == TunnelProtocolType.None) protocol = relayClientStore.DefaultProtocol;
if (operating.StartOperation(BuildKey(remoteMachineId, transactionId)) == false)
{
return null;
}
try
{
if (relayClientStore.Server.Disabled)
{
return null;
}
IEnumerable<IRelayClientTransport> transports = Transports
//优先的
.Where(c => c.ProtocolType == protocol)
//其次的
.Concat(Transports.Where(c => c.ProtocolType != protocol))
//不包含在禁用列表里的
.Where(c => (denyProtocols & c.ProtocolType)!= c.ProtocolType);
foreach (IRelayClientTransport transport in transports)
{
if (transport == null)
{
continue;
}
RelayInfo relayInfo = new RelayInfo
{
FlowingId = 0,
FromMachineId = fromMachineId,
FromMachineName = string.Empty,
RemoteMachineId = remoteMachineId,
RemoteMachineName = string.Empty,
TransactionId = transactionId,
TransportName = transport.Name,
SSL = relayClientStore.Server.SSL,
NodeId = nodeId,
UserId = signInClientStore.Server.UserId,
};
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Info($"relay {transport.Name} to {relayInfo.RemoteMachineId}->{relayInfo.RemoteMachineName} {relayInfo.ToJson()}");
ITunnelConnection connection = await transport.RelayAsync(relayInfo).ConfigureAwait(false);
if (connection != null)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Debug($"relay {transport.Name} to {relayInfo.RemoteMachineId}->{relayInfo.RemoteMachineName} success,{relayInfo.ToJson()}");
ConnectedCallback(relayInfo, connection);
return connection;
}
else
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error($"relay {transport.Name} to {relayInfo.RemoteMachineId}->{relayInfo.RemoteMachineName} fail,{relayInfo.ToJson()}");
}
}
}
catch (Exception ex)
{
LoggerHelper.Instance.Error(ex);
}
finally
{
operating.StopOperation(BuildKey(remoteMachineId, transactionId));
}
return null;
}
/// <summary>
/// 收到对方的中继请求
/// </summary>
/// <param name="relayInfo"></param>
/// <returns></returns>
public async Task<bool> OnBeginAsync(transport.RelayInfo relayInfo)
{
if (operating.StartOperation(BuildKey(relayInfo.FromMachineId, relayInfo.TransactionId)) == false)
{
return false;
}
try
{
IRelayClientTransport _transports = Transports.FirstOrDefault(c => c.Name == relayInfo.TransportName);
if (_transports == null) return false;
await _transports.OnBeginAsync(relayInfo, (connection) =>
{
if (connection != null)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Debug($"relay from {relayInfo.RemoteMachineId}->{relayInfo.RemoteMachineName} success,{relayInfo.ToJson()}");
ConnectedCallback(relayInfo, connection);
}
else
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error($"relay from {relayInfo.RemoteMachineId}->{relayInfo.RemoteMachineName} error,{relayInfo.ToJson()}");
}
}).ConfigureAwait(false);
return true;
}
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{
LoggerHelper.Instance.Error(ex);
}
}
finally
{
operating.StopOperation(BuildKey(relayInfo.FromMachineId, relayInfo.TransactionId));
}
return false;
}
/// <summary>
/// 回调
/// </summary>
/// <param name="relayInfo"></param>
/// <param name="connection"></param>
private void ConnectedCallback(transport.RelayInfo relayInfo, ITunnelConnection connection)
{
if (OnConnected.TryGetValue(Helper.GlobalString, out List<Action<ITunnelConnection>> callbacks))
{
foreach (var item in callbacks)
{
item(connection);
}
}
if (OnConnected.TryGetValue(connection.TransactionId, out callbacks))
{
foreach (var callabck in callbacks)
{
callabck(connection);
}
}
}
private string BuildKey(string remoteMachineId, string transactionId)
{
return $"{remoteMachineId}@{transactionId}";
}
}
}

View File

@@ -112,19 +112,4 @@ namespace linker.messenger.relay.client.transport
public string UserId { get; set; } public string UserId { get; set; }
} }
public sealed partial class RelayServerInfo
{
public RelayServerInfo() { }
/// <summary>
/// 禁用
/// </summary>
public bool Disabled { get; set; }
/// <summary>
/// 开启ssl
/// </summary>
public bool SSL { get; set; } = true;
public RelayClientType RelayType { get; set; } = RelayClientType.Linker;
}
} }

View File

@@ -26,15 +26,13 @@ namespace linker.messenger.relay.client.transport
private readonly IMessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly ISerializer serializer; private readonly ISerializer serializer;
private readonly IRelayClientStore relayClientStore;
private readonly SignInClientState signInClientState; private readonly SignInClientState signInClientState;
private readonly IMessengerStore messengerStore; private readonly IMessengerStore messengerStore;
public RelayClientTransportSelfHost(IMessengerSender messengerSender, ISerializer serializer, IRelayClientStore relayClientStore, SignInClientState signInClientState, IMessengerStore messengerStore) public RelayClientTransportSelfHost(IMessengerSender messengerSender, ISerializer serializer, SignInClientState signInClientState, IMessengerStore messengerStore)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.serializer = serializer; this.serializer = serializer;
this.relayClientStore = relayClientStore;
this.signInClientState = signInClientState; this.signInClientState = signInClientState;
this.messengerStore = messengerStore; this.messengerStore = messengerStore;
} }

View File

@@ -1,11 +1,9 @@
 
using linker.messenger.relay.client.transport; using linker.messenger.relay.client.transport;
using linker.libs; using linker.libs;
using linker.messenger.relay.client;
using linker.messenger.relay.server; using linker.messenger.relay.server;
using linker.messenger.signin; using linker.messenger.signin;
using linker.messenger.relay.server.validator; using linker.messenger.relay.server.validator;
using linker.libs.extends;
namespace linker.messenger.relay.messenger namespace linker.messenger.relay.messenger
{ {
@@ -14,25 +12,8 @@ namespace linker.messenger.relay.messenger
/// </summary> /// </summary>
public class RelayClientMessenger : IMessenger public class RelayClientMessenger : IMessenger
{ {
private readonly RelayClientTransfer relayTransfer; public RelayClientMessenger()
private readonly ISerializer serializer;
public RelayClientMessenger(RelayClientTransfer relayTransfer, ISerializer serializer)
{ {
this.relayTransfer = relayTransfer;
this.serializer = serializer;
}
/// <summary>
/// 收到中继请求
/// </summary>
/// <param name="connection"></param>
/// <returns></returns>
[MessengerId((ushort)RelayMessengerIds.Relay)]
public async Task Relay(IConnection connection)
{
client.transport.RelayInfo info = serializer.Deserialize<client.transport.RelayInfo>(connection.ReceiveRequestWrap.Payload.Span);
bool res = await relayTransfer.OnBeginAsync(info).ConfigureAwait(false);
connection.Write(res ? Helper.TrueArray : Helper.FalseArray);
} }
} }
@@ -128,7 +109,6 @@ namespace linker.messenger.relay.messenger
} }
connection.Write(serializer.Serialize(result)); connection.Write(serializer.Serialize(result));
} }
private async Task<List<RelayServerNodeReportInfo>> GetNodes(SignCacheInfo from) private async Task<List<RelayServerNodeReportInfo>> GetNodes(SignCacheInfo from)
{ {
return await relayServerTransfer.GetNodes(from.Super, from.UserId, from.MachineId); return await relayServerTransfer.GetNodes(from.Super, from.UserId, from.MachineId);

View File

@@ -0,0 +1,93 @@
using linker.libs;
using linker.messenger;
using linker.messenger.relay.messenger;
using linker.messenger.relay.server;
using linker.messenger.signin;
using linker.tunnel.connection;
using linker.tunnel.wanport;
using System.Security.Cryptography.X509Certificates;
namespace linker.tunnel.transport
{
public class TransportRelay : ITunnelTransport
{
public string Name => "TcpRelay";
public string Label => "TCP、服务器中继";
public TunnelProtocolType ProtocolType => TunnelProtocolType.Tcp;
public TunnelWanPortProtocolType AllowWanPortProtocolType => TunnelWanPortProtocolType.Other;
public bool Reverse => true;
public bool DisableReverse => false;
public bool SSL => true;
public bool DisableSSL => false;
public byte Order => 0;
public Action<ITunnelConnection> OnConnected { get; set; } = (state) => { };
private readonly IMessengerSender messengerSender;
private readonly ISerializer serializer;
private readonly SignInClientState signInClientState;
private readonly IMessengerStore messengerStore;
public TransportRelay(IMessengerSender messengerSender, ISerializer serializer, SignInClientState signInClientState, IMessengerStore messengerStore)
{
this.messengerSender = messengerSender;
this.serializer = serializer;
this.signInClientState = signInClientState;
this.messengerStore = messengerStore;
}
public virtual async Task<ITunnelConnection> ConnectAsync(TunnelTransportInfo tunnelTransportInfo)
{
return null;
}
public virtual async Task OnBegin(TunnelTransportInfo tunnelTransportInfo)
{
}
public virtual void OnFail(TunnelTransportInfo tunnelTransportInfo)
{
}
public virtual void OnSuccess(TunnelTransportInfo tunnelTransportInfo)
{
}
public virtual void SetSSL(X509Certificate certificate)
{
}
public async Task<List<RelayServerNodeReportInfo>> RelayTestAsync()
{
try
{
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = signInClientState.Connection,
MessengerId = (ushort)RelayMessengerIds.Nodes188,
Timeout = 2000
}).ConfigureAwait(false);
if (resp.Code == MessageResponeCodes.OK)
{
return serializer.Deserialize<List<RelayServerNodeReportInfo>>(resp.Data.Span);
}
}
catch (Exception)
{
}
return new List<RelayServerNodeReportInfo>();
}
}
}

View File

@@ -0,0 +1,23 @@
using linker.tunnel.wanport;
using System.Net;
namespace linker.messenger.relay.transport
{
public sealed class TunnelWanPortProtocolRelay : ITunnelWanPortProtocol
{
public string Name => "relay";
public TunnelWanPortProtocolType ProtocolType => TunnelWanPortProtocolType.Other;
public TunnelWanPortProtocolRelay() { }
public async Task<TunnelWanPortEndPoint> GetAsync(IPEndPoint server)
{
return new TunnelWanPortEndPoint
{
Local = new IPEndPoint(IPAddress.Loopback, 0),
Remote = server
};
}
}
}

View File

@@ -3,7 +3,6 @@ using linker.tunnel.connection;
using linker.libs; using linker.libs;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using linker.messenger.relay.client;
using linker.messenger.channel; using linker.messenger.channel;
using linker.messenger.signin; using linker.messenger.signin;
using linker.messenger.pcp; using linker.messenger.pcp;
@@ -21,9 +20,9 @@ namespace linker.messenger.socks5
private readonly Socks5CidrDecenterManager socks5CidrDecenterManager; private readonly Socks5CidrDecenterManager socks5CidrDecenterManager;
public Socks5Proxy(ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, public Socks5Proxy(ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, PcpTransfer pcpTransfer,
SignInClientTransfer signInClientTransfer, Socks5CidrDecenterManager socks5CidrDecenterManager, ChannelConnectionCaching channelConnectionCaching) SignInClientTransfer signInClientTransfer, Socks5CidrDecenterManager socks5CidrDecenterManager, ChannelConnectionCaching channelConnectionCaching)
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching) : base(tunnelTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching)
{ {
this.socks5CidrDecenterManager = socks5CidrDecenterManager; this.socks5CidrDecenterManager = socks5CidrDecenterManager;
TaskUdp(); TaskUdp();

View File

@@ -4,7 +4,6 @@ using linker.libs;
using linker.messenger.signin; using linker.messenger.signin;
using linker.messenger.api; using linker.messenger.api;
using System.Text; using System.Text;
using linker.messenger.relay.client.transport;
using System.Text.Json; using System.Text.Json;
using System.Collections; using System.Collections;
using linker.libs.web; using linker.libs.web;
@@ -263,9 +262,6 @@ namespace linker.messenger.store.file
client.AccessBits = accessStore.AssignAccess(configExportInfo.Access); client.AccessBits = accessStore.AssignAccess(configExportInfo.Access);
client.FullAccess = configExportInfo.FullAccess && config.Data.Client.FullAccess; client.FullAccess = configExportInfo.FullAccess && config.Data.Client.FullAccess;
if (configExportInfo.Relay) client.Relay = new RelayClientInfo { Servers = [client.Relay.Servers[0]] };
else client.Relay = new RelayClientInfo { Servers = [new RelayServerInfo { }] };
if (configExportInfo.Server) if (configExportInfo.Server)
{ {
client.Server.Host = config.Data.Client.Server.Host; client.Server.Host = config.Data.Client.Server.Host;
@@ -304,7 +300,6 @@ namespace linker.messenger.store.file
Groups = new SignInClientGroupInfo[] { client.Group }, Groups = new SignInClientGroupInfo[] { client.Group },
Servers = new SignInClientServerInfo[] { client.Server }, Servers = new SignInClientServerInfo[] { client.Server },
client.Updater, client.Updater,
Relay = new { Servers = new RelayServerInfo[] { client.Relay.Server } },
client.Tunnel, client.Tunnel,
}, common, new { Install = true, Modes = new string[] { "client" } }); }, common, new { Install = true, Modes = new string[] { "client" } });
} }

View File

@@ -1,6 +1,4 @@
using linker.libs; using linker.messenger.relay.server;
using linker.messenger.relay.client.transport;
using linker.messenger.relay.server;
using linker.tunnel.connection; using linker.tunnel.connection;
@@ -18,22 +16,6 @@ namespace linker.messenger.store.file
public TunnelProtocolType DefaultProtocol { get; set; } = TunnelProtocolType.None; public TunnelProtocolType DefaultProtocol { get; set; } = TunnelProtocolType.None;
} }
public sealed partial class ConfigClientInfo
{
public RelayClientInfo Relay { get; set; } = new RelayClientInfo();
}
public sealed class RelayClientInfo
{
/// <summary>
/// 中继服务器列表
/// </summary>
public RelayServerInfo[] Servers { get; set; } = new RelayServerInfo[] { new RelayServerInfo { } };
[SaveJsonIgnore]
public RelayServerInfo Server => Servers[0];
}
public partial class ConfigServerInfo public partial class ConfigServerInfo
{ {
/// <summary> /// <summary>
@@ -52,12 +34,4 @@ namespace linker.messenger.store.file
public RelayServerMasterInfo Master { get; set; } = new RelayServerMasterInfo { }; public RelayServerMasterInfo Master { get; set; } = new RelayServerMasterInfo { };
} }
public sealed class CdkeyConfigInfo
{
#if DEBUG
public string SecretKey { get; set; } = Helper.GlobalString;
#else
public string SecretKey { get; set; } = Guid.NewGuid().ToString().ToUpper();
#endif
}
} }

View File

@@ -1,6 +1,4 @@
using linker.messenger.relay.client; using linker.messenger.relay.client;
using linker.messenger.relay.client.transport;
using linker.messenger.signin;
using linker.tunnel.connection; using linker.tunnel.connection;
namespace linker.messenger.store.file.relay namespace linker.messenger.store.file.relay
@@ -9,21 +7,13 @@ namespace linker.messenger.store.file.relay
{ {
public string DefaultNodeId => runningConfig.Data.Relay.DefaultNodeId; public string DefaultNodeId => runningConfig.Data.Relay.DefaultNodeId;
public TunnelProtocolType DefaultProtocol => runningConfig.Data.Relay.DefaultProtocol; public TunnelProtocolType DefaultProtocol => runningConfig.Data.Relay.DefaultProtocol;
public RelayServerInfo Server => config.Data.Client.Relay.Server;
private readonly SignInClientState signInClientState;
private readonly ISignInClientStore signInClientStore;
private readonly FileConfig config; private readonly FileConfig config;
private readonly RunningConfig runningConfig; private readonly RunningConfig runningConfig;
public RelayClientStore(SignInClientState signInClientState, ISignInClientStore signInClientStore, FileConfig config, RunningConfig runningConfig) public RelayClientStore(FileConfig config, RunningConfig runningConfig)
{ {
this.signInClientState = signInClientState;
this.signInClientStore = signInClientStore;
this.config = config; this.config = config;
this.runningConfig = runningConfig; this.runningConfig = runningConfig;
} }
@@ -39,11 +29,6 @@ namespace linker.messenger.store.file.relay
runningConfig.Data.Update(); runningConfig.Data.Update();
} }
public void SetServer(RelayServerInfo server)
{
config.Data.Client.Relay.Servers = [server];
config.Data.Update();
}
public bool Confirm() public bool Confirm()
{ {
config.Data.Update(); config.Data.Update();

View File

@@ -1,7 +1,6 @@
using linker.libs; using linker.libs;
using linker.messenger.channel; using linker.messenger.channel;
using linker.messenger.pcp; using linker.messenger.pcp;
using linker.messenger.relay.client;
using linker.messenger.signin; using linker.messenger.signin;
using linker.messenger.tuntap.cidr; using linker.messenger.tuntap.cidr;
using linker.nat; using linker.nat;
@@ -31,11 +30,11 @@ namespace linker.messenger.tuntap
private readonly TuntapDecenter tuntapDecenter; private readonly TuntapDecenter tuntapDecenter;
public TuntapProxy(ISignInClientStore signInClientStore, public TuntapProxy(ISignInClientStore signInClientStore,
TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, TunnelTransfer tunnelTransfer, PcpTransfer pcpTransfer,
SignInClientTransfer signInClientTransfer, TuntapConfigTransfer tuntapConfigTransfer, SignInClientTransfer signInClientTransfer, TuntapConfigTransfer tuntapConfigTransfer,
TuntapCidrConnectionManager tuntapCidrConnectionManager, TuntapCidrDecenterManager tuntapCidrDecenterManager, TuntapCidrConnectionManager tuntapCidrConnectionManager, TuntapCidrDecenterManager tuntapCidrDecenterManager,
TuntapCidrMapfileManager tuntapCidrMapfileManager, TuntapDecenter tuntapDecenter, ChannelConnectionCaching channelConnectionCaching) TuntapCidrMapfileManager tuntapCidrMapfileManager, TuntapDecenter tuntapDecenter, ChannelConnectionCaching channelConnectionCaching)
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching) : base(tunnelTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching)
{ {
this.tuntapConfigTransfer = tuntapConfigTransfer; this.tuntapConfigTransfer = tuntapConfigTransfer;
this.tuntapCidrConnectionManager = tuntapCidrConnectionManager; this.tuntapCidrConnectionManager = tuntapCidrConnectionManager;

View File

@@ -58,6 +58,21 @@ namespace linker.tunnel
LoggerHelper.Instance.Info($"load tunnel transport:{string.Join(",", transports.Select(c => c.GetType().Name))}"); LoggerHelper.Instance.Info($"load tunnel transport:{string.Join(",", transports.Select(c => c.GetType().Name))}");
} }
public void AddTransport(ITunnelTransport transport)
{
if (transports.Any(c => c.Name == transport.Name) == false)
{
transport.OnConnected = OnConnected;
transports.Add(transport);
_ = RebuildTransports();
}
}
public void AddProtocol(ITunnelWanPortProtocol protocol)
{
tunnelWanPortTransfer.AddProtocol(protocol);
}
/// <summary> /// <summary>
/// 刷新一下网络信息比如路由级别本机IP等 /// 刷新一下网络信息比如路由级别本机IP等
/// </summary> /// </summary>
@@ -423,6 +438,8 @@ namespace linker.tunnel
private void ParseRemoteEndPoint(TunnelTransportInfo tunnelTransportInfo) private void ParseRemoteEndPoint(TunnelTransportInfo tunnelTransportInfo)
{ {
if (tunnelTransportInfo.Local == null || tunnelTransportInfo.Remote == null) return;
//要连接哪些IP //要连接哪些IP
List<IPEndPoint> eps = new List<IPEndPoint>(); List<IPEndPoint> eps = new List<IPEndPoint>();
var excludeips = tunnelMessengerAdapter.GetExcludeIps(); var excludeips = tunnelMessengerAdapter.GetExcludeIps();

View File

@@ -62,7 +62,7 @@ namespace linker.tunnel
{ {
if (await HasMap(device, Protocol.Tcp, MapInfo.PublicPort).ConfigureAwait(false) == false) if (await HasMap(device, Protocol.Tcp, MapInfo.PublicPort).ConfigureAwait(false) == false)
{ {
Mapping mapping = new Mapping(Protocol.Tcp, MapInfo.PrivatePort, MapInfo.PublicPort, 86400, $"linker-tcp-{MapInfo.PublicPort}-{MapInfo.PrivatePort}"); Mapping mapping = new Mapping(Protocol.Tcp, MapInfo.PrivatePort, MapInfo.PublicPort, 7 * 24 * 60 * 60, $"linker-tcp-{MapInfo.PublicPort}-{MapInfo.PrivatePort}");
await device.CreatePortMapAsync(mapping).ConfigureAwait(false); await device.CreatePortMapAsync(mapping).ConfigureAwait(false);
Mapping m = await device.GetSpecificMappingAsync(Protocol.Tcp, mapping.PublicPort).ConfigureAwait(false); Mapping m = await device.GetSpecificMappingAsync(Protocol.Tcp, mapping.PublicPort).ConfigureAwait(false);
} }
@@ -75,7 +75,7 @@ namespace linker.tunnel
{ {
if (await HasMap(device, Protocol.Udp, MapInfo.PublicPort).ConfigureAwait(false) == false) if (await HasMap(device, Protocol.Udp, MapInfo.PublicPort).ConfigureAwait(false) == false)
{ {
Mapping mapping = new Mapping(Protocol.Udp, MapInfo.PrivatePort, MapInfo.PublicPort, 86400, $"linker-udp-{MapInfo.PublicPort}-{MapInfo.PrivatePort}"); Mapping mapping = new Mapping(Protocol.Udp, MapInfo.PrivatePort, MapInfo.PublicPort, 7 * 24 * 60 * 60, $"linker-udp-{MapInfo.PublicPort}-{MapInfo.PrivatePort}");
await device.CreatePortMapAsync(mapping).ConfigureAwait(false); await device.CreatePortMapAsync(mapping).ConfigureAwait(false);
Mapping m = await device.GetSpecificMappingAsync(Protocol.Udp, mapping.PublicPort).ConfigureAwait(false); Mapping m = await device.GetSpecificMappingAsync(Protocol.Udp, mapping.PublicPort).ConfigureAwait(false);
} }

View File

@@ -21,7 +21,7 @@ namespace linker.tunnel.transport
/// </summary> /// </summary>
public sealed class TransportMsQuic : ITunnelTransport public sealed class TransportMsQuic : ITunnelTransport
{ {
public string Name => "msquic"; public string Name => "MsQuic";
public string Label => "MsQuicwin10+、linux"; public string Label => "MsQuicwin10+、linux";

View File

@@ -25,7 +25,7 @@ namespace linker.tunnel.transport
/// </summary> /// </summary>
public sealed class TransportUdp : ITunnelTransport public sealed class TransportUdp : ITunnelTransport
{ {
public string Name => "udp"; public string Name => "Udp";
public string Label => "UDP、非常纯"; public string Label => "UDP、非常纯";

View File

@@ -35,5 +35,6 @@ namespace linker.tunnel.wanport
{ {
Tcp = 1, Tcp = 1,
Udp = 2, Udp = 2,
Other = 4,
} }
} }

View File

@@ -20,6 +20,14 @@ namespace linker.tunnel.wanport
{ {
} }
public void AddProtocol(ITunnelWanPortProtocol protocol)
{
if (!tunnelWanPorts.Any(c => c.ProtocolType == protocol.ProtocolType))
{
tunnelWanPorts.Add(protocol);
}
}
/// <summary> /// <summary>
/// 获取外网端口 /// 获取外网端口
/// </summary> /// </summary>

View File

@@ -6,15 +6,9 @@ export const getDefault = () => {
export const syncDefault = (data) => { export const syncDefault = (data) => {
return sendWebsocketMsg('relay/SyncDefault', data); return sendWebsocketMsg('relay/SyncDefault', data);
} }
export const setRelayServers = (servers) => {
return sendWebsocketMsg('relay/SetServers', servers);
}
export const setRelaySubscribe = () => { export const setRelaySubscribe = () => {
return sendWebsocketMsg('relay/Subscribe'); return sendWebsocketMsg('relay/Subscribe');
} }
export const relayOperating = (data) => {
return sendWebsocketMsg('relay/Operating',data);
}
export const relayConnect = (data) => { export const relayConnect = (data) => {
return sendWebsocketMsg('relay/Connect', data); return sendWebsocketMsg('relay/Connect', data);
} }

View File

@@ -179,6 +179,11 @@ html.dark .el-switch__core .el-switch__action{
background-color: #ccc; background-color: #ccc;
} }
html.dark .el-dialog{border: 1px solid #575c61;} html.dark .el-dialog{border: 1px solid #575c61;}
html .el-overlay {
border-radius: 4px;
}
body { body {
overflow: hidden; overflow: hidden;

View File

@@ -15,7 +15,7 @@ export default {
'head.home': '首页', 'head.home': '首页',
'head.server': '服务器', 'head.server': '服务器',
'head.group': '分组', 'head.group': '分组',
'head.protocol': '打洞协议', 'head.protocol': '隧道协议',
'head.action': '验证', 'head.action': '验证',
'head.firewall': '防火墙', 'head.firewall': '防火墙',
'head.wakeup': '唤醒', 'head.wakeup': '唤醒',
@@ -47,7 +47,7 @@ export default {
'home.tuntapRoute':'网卡路由', 'home.tuntapRoute':'网卡路由',
'home.firewall':'防火墙', 'home.firewall':'防火墙',
'home.wakeup':'唤醒', 'home.wakeup':'唤醒',
'home.protocol':'打洞协议', 'home.protocol':'隧道协议',
'home.action':'验证', 'home.action':'验证',
'home.flowStatis':'流量统计', 'home.flowStatis':'流量统计',
'home.delete':'删除', 'home.delete':'删除',
@@ -116,7 +116,7 @@ export default {
'status.exportServer': '服务器配置', 'status.exportServer': '服务器配置',
'status.exportSuper': '服务器密码', 'status.exportSuper': '服务器密码',
'status.exportGroup': '当前分组', 'status.exportGroup': '当前分组',
'status.exportTunnel': '打洞协议', 'status.exportTunnel': '隧道协议',
'status.exportCdkey': 'cdkey密钥', 'status.exportCdkey': 'cdkey密钥',
'status.exportWhiteList': '白名单密钥', 'status.exportWhiteList': '白名单密钥',
@@ -448,7 +448,7 @@ export default {
'server.asyncRelaySecretKey': '中继密钥', 'server.asyncRelaySecretKey': '中继密钥',
'server.asyncSForwardSecretKey': '服务器穿透密钥', 'server.asyncSForwardSecretKey': '服务器穿透密钥',
'server.asyncUpdaterSecretKey': '更新配置', 'server.asyncUpdaterSecretKey': '更新配置',
'server.asyncTunnelTransports': '打洞协议', 'server.asyncTunnelTransports': '隧道协议',
'server.asyncSignInUserId': '用户唯一标识', 'server.asyncSignInUserId': '用户唯一标识',
'server.asyncActionStatic': '自定义验证参数', 'server.asyncActionStatic': '自定义验证参数',
'server.asyncFirewall': '防火墙选中项', 'server.asyncFirewall': '防火墙选中项',

View File

@@ -53,6 +53,9 @@ export default {
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
html.dark .adv-wrap .inner{
border-color:#333;
}
.adv-wrap{ .adv-wrap{
padding:1rem 1rem 0 1rem; padding:1rem 1rem 0 1rem;

View File

@@ -1,16 +1,14 @@
<template> <template>
<el-form-item :label="$t('server.sforward')"> <el-form-item :label="$t('server.sforward')">
<div> <div class="flex">
<div class="flex"> <a href="javascript:;" @click="state.showModes = true" class="mgr-1 delay a-line" :class="{red:state.nodes.length==0,green:state.nodes.length>0}">
<a href="javascript:;" @click="state.showModes = true" class="mgr-1 delay a-line" :class="{red:state.nodes.length==0,green:state.nodes.length>0}"> {{$t('server.sforwardNodes')}} : {{state.nodes.length}}
{{$t('server.sforwardNodes')}} : {{state.nodes.length}} </a>
</a> <AccessShow value="WhiteList">
<AccessShow value="WhiteList"> <WhiteList type="SForward" prefix="sfp->" v-if="state.super"></WhiteList>
<WhiteList type="SForward" prefix="sfp->" v-if="state.super"></WhiteList> </AccessShow>
</AccessShow> <Nodes v-if="state.showModes" v-model="state.showModes" :data="state.nodes"></Nodes>
<Nodes v-if="state.showModes" v-model="state.showModes" :data="state.nodes"></Nodes> <!-- <Status type="SForward"></Status> -->
<!-- <Status type="SForward"></Status> -->
</div>
</div> </div>
</el-form-item> </el-form-item>
</template> </template>

View File

@@ -1,30 +1,19 @@
<template> <template>
<el-form-item :label="$t('server.relay')"> <el-form-item :label="$t('server.relay')">
<div> <div class="flex">
<div class="flex"> <a href="javascript:;" @click="state.showModes=true" class="mgr-1 delay a-line" :class="{red:state.nodes.length==0,green:state.nodes.length>0}">
<div class="mgr-1"> {{$t('server.relayNodes')}} : {{state.nodes.length}}
<el-checkbox class="mgr-1" v-model="state.list.Disabled" :label="$t('server.relayDisable')" @change="handleSave" /> </a>
<el-checkbox v-model="state.list.SSL" :label="$t('server.relaySSL')" @change="handleSave" /> <WhiteList type="Relay"></WhiteList>
</div> <Nodes v-if="state.showModes" v-model="state.showModes" :data="state.nodes"></Nodes>
<Sync class="mgl-1" name="RelaySecretKey"></Sync> <Status type="Relay"></Status>
</div>
<div class="flex">
<a href="javascript:;" @click="state.showModes=true" class="mgr-1 delay a-line" :class="{red:state.nodes.length==0,green:state.nodes.length>0}">
{{$t('server.relayNodes')}} : {{state.nodes.length}}
</a>
<WhiteList type="Relay"></WhiteList>
<Nodes v-if="state.showModes" v-model="state.showModes" :data="state.nodes"></Nodes>
<Status type="Relay"></Status>
</div>
</div> </div>
</el-form-item> </el-form-item>
</template> </template>
<script> <script>
import { setRelayServers, setRelaySubscribe } from '@/apis/relay'; import { setRelaySubscribe } from '@/apis/relay';
import { injectGlobalData } from '@/provide'; import { injectGlobalData } from '@/provide';
import { ElMessage } from 'element-plus';
import { onMounted, onUnmounted, provide, reactive, ref } from 'vue' import { onMounted, onUnmounted, provide, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n';
import Sync from '../sync/Index.vue' import Sync from '../sync/Index.vue'
import Nodes from './Nodes.vue'; import Nodes from './Nodes.vue';
import WhiteList from '../wlist/Index.vue'; import WhiteList from '../wlist/Index.vue';
@@ -33,22 +22,12 @@ import Status from '../wlist/Status.vue';
export default { export default {
components:{Sync,Nodes,WhiteList,Status}, components:{Sync,Nodes,WhiteList,Status},
setup(props) { setup(props) {
const {t} = useI18n();
const globalData = injectGlobalData(); const globalData = injectGlobalData();
const state = reactive({ const state = reactive({
list:globalData.value.config.Client.Relay.Server,
showModes:false, showModes:false,
nodes:[], nodes:[],
timer:0 timer:0
}); });
const handleSave = ()=>{
setRelayServers(state.list).then(()=>{
ElMessage.success(t('common.oper'));
}).catch((err)=>{
console.log(err);
ElMessage.error(t('common.operFail'));
});
}
const nodes = ref([]); const nodes = ref([]);
provide('nodes',nodes); provide('nodes',nodes);
@@ -70,7 +49,7 @@ export default {
clearTimeout(state.timer); clearTimeout(state.timer);
}); });
return {globalData,state,handleSave} return {globalData,state}
} }
} }
</script> </script>

View File

@@ -42,7 +42,6 @@
</div> </div>
<div> <div>
<el-row> <el-row>
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.relay" :label="$t('status.exportRelay')" /></el-col>
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.updater" :label="$t('status.exportUpdater')" /></el-col> <el-col :xs="12" :sm="8"><el-checkbox v-model="state.updater" :label="$t('status.exportUpdater')" /></el-col>
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.group" :label="$t('status.exportGroup')" /></el-col> <el-col :xs="12" :sm="8"><el-checkbox v-model="state.group" :label="$t('status.exportGroup')" /></el-col>
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.server" :label="$t('status.exportServer')" /></el-col> <el-col :xs="12" :sm="8"><el-checkbox v-model="state.server" :label="$t('status.exportServer')" /></el-col>
@@ -112,7 +111,6 @@ export default {
apipassword:onlyNode.value? globalData.value.config.Client.CApi.ApiPassword :'', apipassword:onlyNode.value? globalData.value.config.Client.CApi.ApiPassword :'',
webport: globalData.value.config.Client.CApi.WebPort, webport: globalData.value.config.Client.CApi.WebPort,
relay:true,
updater:true, updater:true,
server:true, server:true,
super:false, super:false,
@@ -140,7 +138,6 @@ export default {
name:state.name, name:state.name,
apipassword:state.apipassword, apipassword:state.apipassword,
webport:+state.webport, webport:+state.webport,
relay:state.relay,
updater:state.updater, updater:state.updater,
server:state.server, server:state.server,
super:state.super, super:state.super,

View File

@@ -33,7 +33,7 @@ html.dark .flow-wrap{
} }
.flow-wrap{ .flow-wrap{
padding:.4rem; padding:.4rem;
font-weight:bold;position:absolute;right:1rem;bottom:80%; font-weight:bold;position:absolute;right:0.5rem;bottom:80%;
border:1px solid #ddd; border:1px solid #ddd;
background-color:#fff; background-color:#fff;
z-index :9 z-index :9

View File

@@ -26,7 +26,7 @@ export default {
const state = reactive({ const state = reactive({
show: true, show: true,
machineId: transport.value.device.id, machineId: transport.value.device.id,
title:isSelf? `[${transport.value.device.name}]上的打洞协议` : `本机与[${transport.value.device.name}]之间的打洞协议`, title:isSelf? `[${transport.value.device.name}]上的隧道协议` : `本机与[${transport.value.device.name}]之间的隧道协议`,
}); });
watch(() => state.show, (val) => { watch(() => state.show, (val) => {
if (!val) { if (!val) {

View File

@@ -1,4 +1,3 @@
import { relayOperating } from "@/apis/relay";
import { getTunnelInfo, tunnelRefresh,tunnelOperating } from "@/apis/tunnel"; import { getTunnelInfo, tunnelRefresh,tunnelOperating } from "@/apis/tunnel";
import { inject, provide, ref } from "vue"; import { inject, provide, ref } from "vue";
@@ -6,20 +5,12 @@ const tunnelSymbol = Symbol();
export const provideTunnel = () => { export const provideTunnel = () => {
const tunnel = ref({ const tunnel = ref({
timer: 0,
list: null, list: null,
hashcode: 0, hashcode: 0,
operatings:null, operatings:{},
timer1: 0,
p2pOperatings:{},
hashcode1: 0, hashcode1: 0,
timer2: 0,
relayOperatings:{},
hashcode2: 0,
showEdit: false, showEdit: false,
current: null, current: null,
@@ -47,7 +38,7 @@ export const provideTunnel = () => {
let arr = key.split('@'); let arr = key.split('@');
json[arr[0]] = json[arr[0]] ||{}; json[arr[0]] = json[arr[0]] ||{};
json[arr[0]][arr[1]] = operatings[key]; json[arr[0]][arr[1]] = operatings[key];
} }
return json; return json;
} }
const getTunnelOperating = () => { const getTunnelOperating = () => {
@@ -56,23 +47,7 @@ export const provideTunnel = () => {
tunnel.value.hashcode1 = res.HashCode; tunnel.value.hashcode1 = res.HashCode;
if (res.List) if (res.List)
{ {
tunnel.value.p2pOperatings = parseOperating(res.List); tunnel.value.operatings = parseOperating(res.List);
resolve(true);
return;
}
resolve(false);
}).catch(() => {
resolve(false);
});
});
}
const getRelayOperating = () => {
return new Promise((resolve, reject) => {
relayOperating(tunnel.value.hashcode2.toString()).then((res) => {
tunnel.value.hashcode2 = res.HashCode;
if (res.List)
{
tunnel.value.relayOperatings = parseOperating(res.List);
resolve(true); resolve(true);
return; return;
} }
@@ -84,23 +59,8 @@ export const provideTunnel = () => {
} }
const tunnelDataFn = () => { const tunnelDataFn = () => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
Promise.all([_getTunnelInfo(), getTunnelOperating(), getRelayOperating()]).then((res) => { Promise.all([_getTunnelInfo(), getTunnelOperating()]).then((res) => {
resolve(res.filter(c=>c == true).length > 0);
const result = res.filter(c=>c == true).length > 0;
if(result){
const p2p = tunnel.value.p2pOperatings;
const relay = tunnel.value.relayOperatings;
if(p2p && relay){
const keys = [...new Set(Object.keys(p2p).concat(Object.keys(relay)))];
const json = {};
for(let key of keys) {
json[key] = json[key] || {};
Object.assign(json[key],p2p[key]||{},relay[key]||{});
}
tunnel.value.operatings = json;
}
}
resolve(result);
}).catch(() => { }).catch(() => {
resolve(false); resolve(false);
}); });