mirror of
https://github.com/snltty/linker.git
synced 2025-12-18 01:16:46 +08:00
重构中继,合并到隧道协议,不再单独配置
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
v1.9.6
|
||||
2025-11-25 09:52:47
|
||||
2025-11-25 17:11:30
|
||||
1. 一些累计更新,一些BUG修复
|
||||
2. 优化客户端数据同步,减少服务器流量
|
||||
3. 去除cdkey,改为发电解锁中继速度
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using linker.libs.extends;
|
||||
using linker.libs.timer;
|
||||
using linker.messenger.pcp;
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.signin;
|
||||
using linker.tunnel;
|
||||
using linker.tunnel.connection;
|
||||
@@ -73,17 +72,15 @@ namespace linker.messenger.channel
|
||||
protected virtual string TransactionId { get; }
|
||||
|
||||
private readonly TunnelTransfer tunnelTransfer;
|
||||
private readonly RelayClientTransfer relayTransfer;
|
||||
private readonly PcpTransfer pcpTransfer;
|
||||
private readonly SignInClientTransfer signInClientTransfer;
|
||||
private readonly ISignInClientStore signInClientStore;
|
||||
private readonly ChannelConnectionCaching channelConnectionCaching;
|
||||
|
||||
public Channel(TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer,
|
||||
public Channel(TunnelTransfer tunnelTransfer, PcpTransfer pcpTransfer,
|
||||
SignInClientTransfer signInClientTransfer, ISignInClientStore signInClientStore, ChannelConnectionCaching channelConnectionCaching)
|
||||
{
|
||||
this.tunnelTransfer = tunnelTransfer;
|
||||
this.relayTransfer = relayTransfer;
|
||||
this.pcpTransfer = pcpTransfer;
|
||||
this.signInClientTransfer = signInClientTransfer;
|
||||
this.signInClientStore = signInClientStore;
|
||||
@@ -91,8 +88,6 @@ namespace linker.messenger.channel
|
||||
|
||||
//监听打洞成功
|
||||
tunnelTransfer.SetConnectedCallback(TransactionId, OnConnected);
|
||||
//监听中继成功
|
||||
relayTransfer.SetConnectedCallback(TransactionId, OnConnected);
|
||||
//监听节点中继成功回调
|
||||
pcpTransfer.SetConnectedCallback(TransactionId, OnConnected);
|
||||
|
||||
@@ -167,7 +162,6 @@ namespace linker.messenger.channel
|
||||
{
|
||||
channelConnectionCaching.Add(connection);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -181,55 +175,29 @@ namespace linker.messenger.channel
|
||||
}
|
||||
private async Task<ITunnelConnection> RelayAndP2P(string machineId, TunnelProtocolType denyProtocols)
|
||||
{
|
||||
//中继
|
||||
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()}");
|
||||
}
|
||||
|
||||
ITunnelConnection connection = null;
|
||||
//正在后台打洞
|
||||
if (tunnelTransfer.IsBackground(machineId, TransactionId))
|
||||
{
|
||||
return connection;
|
||||
}
|
||||
|
||||
//隧道连接
|
||||
connection = await tunnelTransfer.ConnectAsync(machineId, TransactionId, denyProtocols).ConfigureAwait(false);
|
||||
if (connection != null)
|
||||
{
|
||||
//后台打洞
|
||||
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);
|
||||
return connection;
|
||||
}
|
||||
else
|
||||
|
||||
//后台打洞
|
||||
tunnelTransfer.StartBackground(machineId, TransactionId, denyProtocols, () =>
|
||||
{
|
||||
//打洞
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"{TransactionId} p2p to {machineId}");
|
||||
connection = await tunnelTransfer.ConnectAsync(machineId, TransactionId, denyProtocols).ConfigureAwait(false);
|
||||
if (connection != null)
|
||||
{
|
||||
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 channelConnectionCaching.TryGetValue(machineId, TransactionId, out ITunnelConnection connection) && connection.Connected;
|
||||
}, async (_connection) =>
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
}, 3, 10000);
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ using linker.libs.timer;
|
||||
using linker.messenger.channel;
|
||||
using linker.messenger.forward.proxy;
|
||||
using linker.messenger.pcp;
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.signin;
|
||||
using linker.tunnel;
|
||||
using linker.tunnel.connection;
|
||||
@@ -18,9 +17,9 @@ namespace linker.messenger.flow
|
||||
{
|
||||
private readonly FlowForward forwardFlow;
|
||||
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)
|
||||
: base(signInClientStore, tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, channelConnectionCaching)
|
||||
: base(signInClientStore, tunnelTransfer, pcpTransfer, signInClientTransfer, channelConnectionCaching)
|
||||
{
|
||||
this.forwardFlow = forwardFlow;
|
||||
this.flowTunnel = flowTunnel;
|
||||
|
||||
@@ -3,7 +3,6 @@ using linker.libs.extends;
|
||||
using linker.libs.timer;
|
||||
using linker.messenger.channel;
|
||||
using linker.messenger.pcp;
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.signin;
|
||||
using linker.messenger.socks5;
|
||||
using linker.tunnel;
|
||||
@@ -19,9 +18,9 @@ namespace linker.messenger.flow
|
||||
private readonly FlowSocks5 flowSocks5;
|
||||
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)
|
||||
: base(signInClientStore, tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, socks5CidrDecenterManager, channelConnectionCaching)
|
||||
: base(signInClientStore, tunnelTransfer, pcpTransfer, signInClientTransfer, socks5CidrDecenterManager, channelConnectionCaching)
|
||||
{
|
||||
this.flowSocks5 = flowSocks5;
|
||||
this.flowTunnel = flowTunnel;
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
using linker.libs.extends;
|
||||
using linker.messenger.channel;
|
||||
using linker.messenger.pcp;
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.signin;
|
||||
using linker.messenger.tuntap;
|
||||
using linker.messenger.tuntap.cidr;
|
||||
using linker.nat;
|
||||
using linker.tunnel;
|
||||
using linker.tunnel.connection;
|
||||
using System.Collections.Concurrent;
|
||||
@@ -18,11 +16,11 @@ namespace linker.messenger.flow
|
||||
{
|
||||
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,
|
||||
TuntapCidrConnectionManager tuntapCidrConnectionManager, TuntapCidrDecenterManager tuntapCidrDecenterManager,
|
||||
TuntapCidrMapfileManager tuntapCidrMapfileManager,TuntapDecenter tuntapDecenter, ChannelConnectionCaching channelConnectionCaching)
|
||||
: base(signInClientStore, tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer,
|
||||
: base(signInClientStore, tunnelTransfer, pcpTransfer, signInClientTransfer,
|
||||
tuntapConfigTransfer, tuntapCidrConnectionManager, tuntapCidrDecenterManager, tuntapCidrMapfileManager, tuntapDecenter, channelConnectionCaching)
|
||||
{
|
||||
this.flowTunnel = flowTunnel;
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
using linker.tunnel.connection;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net;
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.signin;
|
||||
using linker.messenger.channel;
|
||||
using linker.messenger.pcp;
|
||||
using linker.libs;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace linker.messenger.forward.proxy
|
||||
{
|
||||
@@ -22,9 +20,9 @@ namespace linker.messenger.forward.proxy
|
||||
|
||||
protected override string TransactionId => "forward";
|
||||
|
||||
public ForwardProxy(ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer,
|
||||
SignInClientTransfer signInClientTransfer, ChannelConnectionCaching channelConnectionCaching)
|
||||
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching)
|
||||
public ForwardProxy(ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, PcpTransfer pcpTransfer,
|
||||
SignInClientTransfer signInClientTransfer, ChannelConnectionCaching channelConnectionCaching)
|
||||
: base(tunnelTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching)
|
||||
{
|
||||
TaskUdp();
|
||||
}
|
||||
@@ -107,7 +105,7 @@ namespace linker.messenger.forward.proxy
|
||||
Add(token.Connection.RemoteMachineId, token.IPEndPoint, token.ReadPacket.Length, 0);
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -3,8 +3,12 @@ using linker.messenger.relay.client;
|
||||
using linker.messenger.relay.messenger;
|
||||
using linker.messenger.relay.server;
|
||||
using linker.messenger.relay.server.validator;
|
||||
using linker.messenger.relay.transport;
|
||||
using linker.messenger.relay.webapi;
|
||||
using linker.messenger.sync;
|
||||
using linker.tunnel;
|
||||
using linker.tunnel.transport;
|
||||
using linker.tunnel.wanport;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
namespace linker.messenger.relay
|
||||
{
|
||||
@@ -12,7 +16,9 @@ namespace linker.messenger.relay
|
||||
{
|
||||
public static ServiceCollection AddRelayClient(this ServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddSingleton<RelayClientTransfer>();
|
||||
serviceCollection.AddSingleton<TransportRelay>();
|
||||
serviceCollection.AddSingleton<TunnelWanPortProtocolRelay>();
|
||||
|
||||
serviceCollection.AddSingleton<RelayClientMessenger>();
|
||||
|
||||
serviceCollection.AddSingleton<RelaySyncDefault>();
|
||||
@@ -25,11 +31,17 @@ namespace linker.messenger.relay
|
||||
}
|
||||
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>();
|
||||
messengerResolver.AddMessenger(new List<IMessenger> { serviceProvider.GetService<RelayClientMessenger>() });
|
||||
|
||||
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>();
|
||||
apiServer.AddPlugins(new List<IApiController> { serviceProvider.GetService<RelayApiController>() });
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using linker.messenger.relay.client.transport;
|
||||
using linker.tunnel.connection;
|
||||
using linker.tunnel.connection;
|
||||
|
||||
namespace linker.messenger.relay.client
|
||||
{
|
||||
@@ -17,11 +16,6 @@ namespace linker.messenger.relay.client
|
||||
/// </summary>
|
||||
public TunnelProtocolType DefaultProtocol { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 服务器配置
|
||||
/// </summary>
|
||||
public RelayServerInfo Server { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 设置默认节点id
|
||||
/// </summary>
|
||||
@@ -32,11 +26,6 @@ namespace linker.messenger.relay.client
|
||||
/// </summary>
|
||||
/// <param name="protocol"></param>
|
||||
public void SetDefaultProtocol(TunnelProtocolType protocol);
|
||||
/// <summary>
|
||||
/// 设置中继服务器
|
||||
/// </summary>
|
||||
/// <param name="server"></param>
|
||||
public void SetServer(RelayServerInfo server);
|
||||
|
||||
/// <summary>
|
||||
/// 提交
|
||||
|
||||
@@ -7,7 +7,6 @@ using linker.messenger.relay.messenger;
|
||||
using linker.messenger.relay.server;
|
||||
using linker.messenger.signin;
|
||||
using linker.messenger.sync;
|
||||
using linker.tunnel;
|
||||
using linker.tunnel.connection;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
@@ -19,7 +18,6 @@ namespace linker.messenger.relay.client
|
||||
public sealed class RelayApiController : IApiController
|
||||
{
|
||||
private readonly RelayClientTestTransfer relayTestTransfer;
|
||||
private readonly RelayClientTransfer relayTransfer;
|
||||
private readonly IRelayClientStore relayClientStore;
|
||||
private readonly SignInClientState signInClientState;
|
||||
private readonly IMessengerSender messengerSender;
|
||||
@@ -27,11 +25,10 @@ namespace linker.messenger.relay.client
|
||||
private readonly ISignInClientStore signInClientStore;
|
||||
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)
|
||||
{
|
||||
this.relayTestTransfer = relayTestTransfer;
|
||||
this.relayTransfer = relayTransfer;
|
||||
this.relayClientStore = relayClientStore;
|
||||
this.signInClientState = signInClientState;
|
||||
this.messengerSender = messengerSender;
|
||||
@@ -40,13 +37,6 @@ namespace linker.messenger.relay.client
|
||||
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)
|
||||
{
|
||||
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>
|
||||
@@ -99,9 +70,7 @@ namespace linker.messenger.relay.client
|
||||
{
|
||||
relayConnectInfo.Protocol = TunnelProtocolType.Tcp;
|
||||
}
|
||||
//relayClientStore.SetDefaultNodeId(relayConnectInfo.NodeId);
|
||||
//relayClientStore.SetDefaultProtocol(relayConnectInfo.Protocol);
|
||||
_ = relayTransfer.ConnectAsync(relayConnectInfo.FromMachineId, relayConnectInfo.ToMachineId, relayConnectInfo.TransactionId, relayConnectInfo.NodeId, relayConnectInfo.Protocol);
|
||||
//_ = relayTransfer.ConnectAsync(relayConnectInfo.FromMachineId, relayConnectInfo.ToMachineId, relayConnectInfo.TransactionId, relayConnectInfo.NodeId, relayConnectInfo.Protocol);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using linker.libs;
|
||||
using linker.libs.timer;
|
||||
using linker.messenger.relay.client.transport;
|
||||
using linker.messenger.relay.server;
|
||||
using linker.messenger.signin;
|
||||
using linker.tunnel.transport;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
@@ -13,18 +13,16 @@ namespace linker.messenger.relay.client
|
||||
/// </summary>
|
||||
public sealed class RelayClientTestTransfer
|
||||
{
|
||||
private readonly RelayClientTransfer relayTransfer;
|
||||
private readonly TransportRelay transportRelay;
|
||||
private readonly SignInClientState signInClientState;
|
||||
private readonly ISignInClientStore signInClientStore;
|
||||
private readonly IRelayClientStore relayClientStore;
|
||||
|
||||
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.signInClientStore = signInClientStore;
|
||||
this.relayClientStore = relayClientStore;
|
||||
|
||||
TestTask();
|
||||
@@ -40,20 +38,16 @@ namespace linker.messenger.relay.client
|
||||
{
|
||||
try
|
||||
{
|
||||
IRelayClientTransport transport = relayTransfer.Transports.FirstOrDefault(d => d.Type == relayClientStore.Server.RelayType);
|
||||
if (transport != null)
|
||||
Nodes = await transportRelay.RelayTestAsync().ConfigureAwait(false);
|
||||
var tasks = Nodes.Select(async (c) =>
|
||||
{
|
||||
Nodes = await transport.RelayTestAsync().ConfigureAwait(false);
|
||||
var tasks = Nodes.Select(async (c) =>
|
||||
{
|
||||
c.EndPoint = c.EndPoint == null || c.EndPoint.Address.Equals(IPAddress.Any) ? signInClientState.Connection.Address : c.EndPoint;
|
||||
c.EndPoint = c.EndPoint == null || c.EndPoint.Address.Equals(IPAddress.Any) ? signInClientState.Connection.Address : c.EndPoint;
|
||||
|
||||
using Ping ping = new Ping();
|
||||
var resp = await ping.SendPingAsync(c.EndPoint.Address, 1000);
|
||||
c.Delay = resp.Status == IPStatus.Success ? (int)resp.RoundtripTime : -1;
|
||||
});
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
}
|
||||
using Ping ping = new Ping();
|
||||
var resp = await ping.SendPingAsync(c.EndPoint.Address, 1000);
|
||||
c.Delay = resp.Status == IPStatus.Success ? (int)resp.RoundtripTime : -1;
|
||||
});
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
@@ -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}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,19 +112,4 @@ namespace linker.messenger.relay.client.transport
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,15 +26,13 @@ namespace linker.messenger.relay.client.transport
|
||||
|
||||
private readonly IMessengerSender messengerSender;
|
||||
private readonly ISerializer serializer;
|
||||
private readonly IRelayClientStore relayClientStore;
|
||||
private readonly SignInClientState signInClientState;
|
||||
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.serializer = serializer;
|
||||
this.relayClientStore = relayClientStore;
|
||||
this.signInClientState = signInClientState;
|
||||
this.messengerStore = messengerStore;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
|
||||
using linker.messenger.relay.client.transport;
|
||||
using linker.libs;
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.relay.server;
|
||||
using linker.messenger.signin;
|
||||
using linker.messenger.relay.server.validator;
|
||||
using linker.libs.extends;
|
||||
|
||||
namespace linker.messenger.relay.messenger
|
||||
{
|
||||
@@ -14,25 +12,8 @@ namespace linker.messenger.relay.messenger
|
||||
/// </summary>
|
||||
public class RelayClientMessenger : IMessenger
|
||||
{
|
||||
private readonly RelayClientTransfer relayTransfer;
|
||||
private readonly ISerializer serializer;
|
||||
public RelayClientMessenger(RelayClientTransfer relayTransfer, ISerializer serializer)
|
||||
public RelayClientMessenger()
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
private async Task<List<RelayServerNodeReportInfo>> GetNodes(SignCacheInfo from)
|
||||
{
|
||||
return await relayServerTransfer.GetNodes(from.Super, from.UserId, from.MachineId);
|
||||
|
||||
93
src/linker.messenger.relay/transport/TransportRelay.cs
Normal file
93
src/linker.messenger.relay/transport/TransportRelay.cs
Normal 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>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using linker.tunnel.connection;
|
||||
using linker.libs;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.channel;
|
||||
using linker.messenger.signin;
|
||||
using linker.messenger.pcp;
|
||||
@@ -21,9 +20,9 @@ namespace linker.messenger.socks5
|
||||
|
||||
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)
|
||||
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching)
|
||||
: base(tunnelTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching)
|
||||
{
|
||||
this.socks5CidrDecenterManager = socks5CidrDecenterManager;
|
||||
TaskUdp();
|
||||
|
||||
@@ -4,7 +4,6 @@ using linker.libs;
|
||||
using linker.messenger.signin;
|
||||
using linker.messenger.api;
|
||||
using System.Text;
|
||||
using linker.messenger.relay.client.transport;
|
||||
using System.Text.Json;
|
||||
using System.Collections;
|
||||
using linker.libs.web;
|
||||
@@ -263,9 +262,6 @@ namespace linker.messenger.store.file
|
||||
client.AccessBits = accessStore.AssignAccess(configExportInfo.Access);
|
||||
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)
|
||||
{
|
||||
client.Server.Host = config.Data.Client.Server.Host;
|
||||
@@ -304,7 +300,6 @@ namespace linker.messenger.store.file
|
||||
Groups = new SignInClientGroupInfo[] { client.Group },
|
||||
Servers = new SignInClientServerInfo[] { client.Server },
|
||||
client.Updater,
|
||||
Relay = new { Servers = new RelayServerInfo[] { client.Relay.Server } },
|
||||
client.Tunnel,
|
||||
}, common, new { Install = true, Modes = new string[] { "client" } });
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using linker.libs;
|
||||
using linker.messenger.relay.client.transport;
|
||||
using linker.messenger.relay.server;
|
||||
using linker.messenger.relay.server;
|
||||
using linker.tunnel.connection;
|
||||
|
||||
|
||||
@@ -18,22 +16,6 @@ namespace linker.messenger.store.file
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
@@ -52,12 +34,4 @@ namespace linker.messenger.store.file
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.relay.client.transport;
|
||||
using linker.messenger.signin;
|
||||
using linker.tunnel.connection;
|
||||
|
||||
namespace linker.messenger.store.file.relay
|
||||
@@ -9,21 +7,13 @@ namespace linker.messenger.store.file.relay
|
||||
{
|
||||
public string DefaultNodeId => runningConfig.Data.Relay.DefaultNodeId;
|
||||
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 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.runningConfig = runningConfig;
|
||||
}
|
||||
@@ -39,11 +29,6 @@ namespace linker.messenger.store.file.relay
|
||||
runningConfig.Data.Update();
|
||||
}
|
||||
|
||||
public void SetServer(RelayServerInfo server)
|
||||
{
|
||||
config.Data.Client.Relay.Servers = [server];
|
||||
config.Data.Update();
|
||||
}
|
||||
public bool Confirm()
|
||||
{
|
||||
config.Data.Update();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using linker.libs;
|
||||
using linker.messenger.channel;
|
||||
using linker.messenger.pcp;
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.signin;
|
||||
using linker.messenger.tuntap.cidr;
|
||||
using linker.nat;
|
||||
@@ -31,11 +30,11 @@ namespace linker.messenger.tuntap
|
||||
private readonly TuntapDecenter tuntapDecenter;
|
||||
|
||||
public TuntapProxy(ISignInClientStore signInClientStore,
|
||||
TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer,
|
||||
TunnelTransfer tunnelTransfer, PcpTransfer pcpTransfer,
|
||||
SignInClientTransfer signInClientTransfer, TuntapConfigTransfer tuntapConfigTransfer,
|
||||
TuntapCidrConnectionManager tuntapCidrConnectionManager, TuntapCidrDecenterManager tuntapCidrDecenterManager,
|
||||
TuntapCidrMapfileManager tuntapCidrMapfileManager, TuntapDecenter tuntapDecenter, ChannelConnectionCaching channelConnectionCaching)
|
||||
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching)
|
||||
: base(tunnelTransfer, pcpTransfer, signInClientTransfer, signInClientStore, channelConnectionCaching)
|
||||
{
|
||||
this.tuntapConfigTransfer = tuntapConfigTransfer;
|
||||
this.tuntapCidrConnectionManager = tuntapCidrConnectionManager;
|
||||
|
||||
@@ -58,6 +58,21 @@ namespace linker.tunnel
|
||||
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>
|
||||
/// 刷新一下网络信息,比如路由级别,本机IP等
|
||||
/// </summary>
|
||||
@@ -423,6 +438,8 @@ namespace linker.tunnel
|
||||
|
||||
private void ParseRemoteEndPoint(TunnelTransportInfo tunnelTransportInfo)
|
||||
{
|
||||
if (tunnelTransportInfo.Local == null || tunnelTransportInfo.Remote == null) return;
|
||||
|
||||
//要连接哪些IP
|
||||
List<IPEndPoint> eps = new List<IPEndPoint>();
|
||||
var excludeips = tunnelMessengerAdapter.GetExcludeIps();
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace linker.tunnel
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
Mapping m = await device.GetSpecificMappingAsync(Protocol.Udp, mapping.PublicPort).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace linker.tunnel.transport
|
||||
/// </summary>
|
||||
public sealed class TransportMsQuic : ITunnelTransport
|
||||
{
|
||||
public string Name => "msquic";
|
||||
public string Name => "MsQuic";
|
||||
|
||||
public string Label => "MsQuic,win10+、linux";
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace linker.tunnel.transport
|
||||
/// </summary>
|
||||
public sealed class TransportUdp : ITunnelTransport
|
||||
{
|
||||
public string Name => "udp";
|
||||
public string Name => "Udp";
|
||||
|
||||
public string Label => "UDP、非常纯";
|
||||
|
||||
|
||||
@@ -35,5 +35,6 @@ namespace linker.tunnel.wanport
|
||||
{
|
||||
Tcp = 1,
|
||||
Udp = 2,
|
||||
Other = 4,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -6,15 +6,9 @@ export const getDefault = () => {
|
||||
export const syncDefault = (data) => {
|
||||
return sendWebsocketMsg('relay/SyncDefault', data);
|
||||
}
|
||||
export const setRelayServers = (servers) => {
|
||||
return sendWebsocketMsg('relay/SetServers', servers);
|
||||
}
|
||||
export const setRelaySubscribe = () => {
|
||||
return sendWebsocketMsg('relay/Subscribe');
|
||||
}
|
||||
export const relayOperating = (data) => {
|
||||
return sendWebsocketMsg('relay/Operating',data);
|
||||
}
|
||||
export const relayConnect = (data) => {
|
||||
return sendWebsocketMsg('relay/Connect', data);
|
||||
}
|
||||
|
||||
@@ -179,6 +179,11 @@ html.dark .el-switch__core .el-switch__action{
|
||||
background-color: #ccc;
|
||||
}
|
||||
html.dark .el-dialog{border: 1px solid #575c61;}
|
||||
html .el-overlay {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
|
||||
@@ -15,7 +15,7 @@ export default {
|
||||
'head.home': '首页',
|
||||
'head.server': '服务器',
|
||||
'head.group': '分组',
|
||||
'head.protocol': '打洞协议',
|
||||
'head.protocol': '隧道协议',
|
||||
'head.action': '验证',
|
||||
'head.firewall': '防火墙',
|
||||
'head.wakeup': '唤醒',
|
||||
@@ -47,7 +47,7 @@ export default {
|
||||
'home.tuntapRoute':'网卡路由',
|
||||
'home.firewall':'防火墙',
|
||||
'home.wakeup':'唤醒',
|
||||
'home.protocol':'打洞协议',
|
||||
'home.protocol':'隧道协议',
|
||||
'home.action':'验证',
|
||||
'home.flowStatis':'流量统计',
|
||||
'home.delete':'删除',
|
||||
@@ -116,7 +116,7 @@ export default {
|
||||
'status.exportServer': '服务器配置',
|
||||
'status.exportSuper': '服务器密码',
|
||||
'status.exportGroup': '当前分组',
|
||||
'status.exportTunnel': '打洞协议',
|
||||
'status.exportTunnel': '隧道协议',
|
||||
'status.exportCdkey': 'cdkey密钥',
|
||||
'status.exportWhiteList': '白名单密钥',
|
||||
|
||||
@@ -448,7 +448,7 @@ export default {
|
||||
'server.asyncRelaySecretKey': '中继密钥',
|
||||
'server.asyncSForwardSecretKey': '服务器穿透密钥',
|
||||
'server.asyncUpdaterSecretKey': '更新配置',
|
||||
'server.asyncTunnelTransports': '打洞协议',
|
||||
'server.asyncTunnelTransports': '隧道协议',
|
||||
'server.asyncSignInUserId': '用户唯一标识',
|
||||
'server.asyncActionStatic': '自定义验证参数',
|
||||
'server.asyncFirewall': '防火墙选中项',
|
||||
|
||||
@@ -53,6 +53,9 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
html.dark .adv-wrap .inner{
|
||||
border-color:#333;
|
||||
}
|
||||
.adv-wrap{
|
||||
padding:1rem 1rem 0 1rem;
|
||||
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
<template>
|
||||
<el-form-item :label="$t('server.sforward')">
|
||||
<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.sforwardNodes')}} : {{state.nodes.length}}
|
||||
</a>
|
||||
<AccessShow value="WhiteList">
|
||||
<WhiteList type="SForward" prefix="sfp->" v-if="state.super"></WhiteList>
|
||||
</AccessShow>
|
||||
<Nodes v-if="state.showModes" v-model="state.showModes" :data="state.nodes"></Nodes>
|
||||
<!-- <Status type="SForward"></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.sforwardNodes')}} : {{state.nodes.length}}
|
||||
</a>
|
||||
<AccessShow value="WhiteList">
|
||||
<WhiteList type="SForward" prefix="sfp->" v-if="state.super"></WhiteList>
|
||||
</AccessShow>
|
||||
<Nodes v-if="state.showModes" v-model="state.showModes" :data="state.nodes"></Nodes>
|
||||
<!-- <Status type="SForward"></Status> -->
|
||||
</div>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
@@ -1,30 +1,19 @@
|
||||
<template>
|
||||
<el-form-item :label="$t('server.relay')">
|
||||
<div>
|
||||
<div class="flex">
|
||||
<div class="mgr-1">
|
||||
<el-checkbox class="mgr-1" v-model="state.list.Disabled" :label="$t('server.relayDisable')" @change="handleSave" />
|
||||
<el-checkbox v-model="state.list.SSL" :label="$t('server.relaySSL')" @change="handleSave" />
|
||||
</div>
|
||||
<Sync class="mgl-1" name="RelaySecretKey"></Sync>
|
||||
</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 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>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<script>
|
||||
import { setRelayServers, setRelaySubscribe } from '@/apis/relay';
|
||||
import { setRelaySubscribe } from '@/apis/relay';
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { onMounted, onUnmounted, provide, reactive, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import Sync from '../sync/Index.vue'
|
||||
import Nodes from './Nodes.vue';
|
||||
import WhiteList from '../wlist/Index.vue';
|
||||
@@ -33,22 +22,12 @@ import Status from '../wlist/Status.vue';
|
||||
export default {
|
||||
components:{Sync,Nodes,WhiteList,Status},
|
||||
setup(props) {
|
||||
const {t} = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
const state = reactive({
|
||||
list:globalData.value.config.Client.Relay.Server,
|
||||
showModes:false,
|
||||
nodes:[],
|
||||
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([]);
|
||||
provide('nodes',nodes);
|
||||
@@ -70,7 +49,7 @@ export default {
|
||||
clearTimeout(state.timer);
|
||||
});
|
||||
|
||||
return {globalData,state,handleSave}
|
||||
return {globalData,state}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
</div>
|
||||
<div>
|
||||
<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.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>
|
||||
@@ -112,7 +111,6 @@ export default {
|
||||
apipassword:onlyNode.value? globalData.value.config.Client.CApi.ApiPassword :'',
|
||||
webport: globalData.value.config.Client.CApi.WebPort,
|
||||
|
||||
relay:true,
|
||||
updater:true,
|
||||
server:true,
|
||||
super:false,
|
||||
@@ -140,7 +138,6 @@ export default {
|
||||
name:state.name,
|
||||
apipassword:state.apipassword,
|
||||
webport:+state.webport,
|
||||
relay:state.relay,
|
||||
updater:state.updater,
|
||||
server:state.server,
|
||||
super:state.super,
|
||||
|
||||
@@ -33,7 +33,7 @@ html.dark .flow-wrap{
|
||||
}
|
||||
.flow-wrap{
|
||||
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;
|
||||
background-color:#fff;
|
||||
z-index :9
|
||||
|
||||
@@ -26,7 +26,7 @@ export default {
|
||||
const state = reactive({
|
||||
show: true,
|
||||
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) => {
|
||||
if (!val) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { relayOperating } from "@/apis/relay";
|
||||
import { getTunnelInfo, tunnelRefresh,tunnelOperating } from "@/apis/tunnel";
|
||||
import { inject, provide, ref } from "vue";
|
||||
|
||||
@@ -6,20 +5,12 @@ const tunnelSymbol = Symbol();
|
||||
export const provideTunnel = () => {
|
||||
const tunnel = ref({
|
||||
|
||||
timer: 0,
|
||||
list: null,
|
||||
hashcode: 0,
|
||||
|
||||
operatings:null,
|
||||
|
||||
timer1: 0,
|
||||
p2pOperatings:{},
|
||||
operatings:{},
|
||||
hashcode1: 0,
|
||||
|
||||
timer2: 0,
|
||||
relayOperatings:{},
|
||||
hashcode2: 0,
|
||||
|
||||
showEdit: false,
|
||||
current: null,
|
||||
|
||||
@@ -47,7 +38,7 @@ export const provideTunnel = () => {
|
||||
let arr = key.split('@');
|
||||
json[arr[0]] = json[arr[0]] ||{};
|
||||
json[arr[0]][arr[1]] = operatings[key];
|
||||
}
|
||||
}
|
||||
return json;
|
||||
}
|
||||
const getTunnelOperating = () => {
|
||||
@@ -56,23 +47,7 @@ export const provideTunnel = () => {
|
||||
tunnel.value.hashcode1 = res.HashCode;
|
||||
if (res.List)
|
||||
{
|
||||
tunnel.value.p2pOperatings = 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);
|
||||
tunnel.value.operatings = parseOperating(res.List);
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
@@ -84,23 +59,8 @@ export const provideTunnel = () => {
|
||||
}
|
||||
const tunnelDataFn = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
Promise.all([_getTunnelInfo(), getTunnelOperating(), getRelayOperating()]).then((res) => {
|
||||
|
||||
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);
|
||||
Promise.all([_getTunnelInfo(), getTunnelOperating()]).then((res) => {
|
||||
resolve(res.filter(c=>c == true).length > 0);
|
||||
}).catch(() => {
|
||||
resolve(false);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user