整理代码

This commit is contained in:
snltty
2024-12-19 17:21:14 +08:00
parent 3bb5ff9dd4
commit 0b53cb5d16
55 changed files with 1284 additions and 677 deletions

View File

@@ -14,8 +14,8 @@ namespace linker.gen
{
private List<GeneratorInfo> generators = new List<GeneratorInfo> {
new GeneratorInfo{ ClassName="linker.plugins.flow.FlowTypesLoader", InterfaceName="linker.plugins.flow.IFlow" },
new GeneratorInfo{ ClassName="linker.plugins.relay.client.RelayTypesLoader", InterfaceName="linker.plugins.relay.client.transport.ITransport" },
new GeneratorInfo{ ClassName="linker.plugins.relay.server.validator.RelayValidatorTypeLoader", InterfaceName="linker.plugins.relay.server.validator.IRelayValidator" },
new GeneratorInfo{ ClassName="linker.plugins.relay.client.RelayClientTypesLoader", InterfaceName="linker.messenger.relay.client.transport.IRelayClientTransport" },
new GeneratorInfo{ ClassName="linker.plugins.relay.server.validator.RelayServerValidatorTypeLoader", InterfaceName="linker.messenger.relay.server.validator.IRelayServerValidator" },
new GeneratorInfo{ ClassName="linker.plugins.signIn.args.SignInArgsTypesLoader", InterfaceName="linker.messenger.signin.ISignInArgs" },
new GeneratorInfo{ ClassName="linker.plugins.resolver.ResolverTypesLoader", InterfaceName="linker.plugins.resolver.IResolver" },
new GeneratorInfo{ ClassName="linker.plugins.tunnel.TunnelExcludeIPTypesLoader", InterfaceName="linker.messenger.tunnel.ITunnelExcludeIP" },

View File

@@ -0,0 +1,39 @@
using linker.messenger.relay.client.transport;
using System.Security.Cryptography.X509Certificates;
namespace linker.messenger.relay.client
{
public interface IRelayClientStore
{
/// <summary>
/// 标志当所有业务使用同一端口时flag区分0则不发送
/// </summary>
public byte Flag { get; }
/// <summary>
/// 加密证书
/// </summary>
public X509Certificate2 Certificate { get; }
/// <summary>
/// 登录连接
/// </summary>
public IConnection SigninConnection { get; }
/// <summary>
/// 密钥
/// </summary>
public string SecretKey { get; }
/// <summary>
/// 禁用
/// </summary>
public bool Disabled { get; }
/// <summary>
/// 开启ssl
/// </summary>
public bool SSL { get;}
/// <summary>
/// 中继类型
/// </summary>
public RelayClientType RelayType { get; }
}
}

View File

@@ -1,29 +1,28 @@
using linker.config;
using linker.plugins.relay.client.transport;
using linker.messenger.relay.client.transport;
using linker.tunnel.connection;
using linker.libs;
using linker.libs.extends;
using System.Collections.Concurrent;
namespace linker.plugins.relay.client
namespace linker.messenger.relay.client
{
/// <summary>
/// 中继
/// </summary>
public sealed class RelayTransfer
public sealed class RelayClientTransfer
{
public List<ITransport> Transports { get; private set; }
public List<IRelayClientTransport> Transports { get; private set; }
private ConcurrentDictionary<string, bool> connectingDic = new ConcurrentDictionary<string, bool>();
private Dictionary<string, List<Action<ITunnelConnection>>> OnConnected { get; } = new Dictionary<string, List<Action<ITunnelConnection>>>();
private readonly RelayClientConfigTransfer relayClientConfigTransfer;
public RelayTransfer(RelayClientConfigTransfer relayClientConfigTransfer)
private readonly IRelayClientStore relayClientStore;
public RelayClientTransfer(IRelayClientStore relayClientStore)
{
this.relayClientConfigTransfer = relayClientConfigTransfer;
this.relayClientStore = relayClientStore;
}
public void LoadTransports(List<ITransport> list)
public void LoadTransports(List<IRelayClientTransport> list)
{
Transports = list;
}
@@ -69,7 +68,7 @@ namespace linker.plugins.relay.client
}
try
{
ITransport transport = Transports.FirstOrDefault(c => c.Type == relayClientConfigTransfer.Server.RelayType && relayClientConfigTransfer.Server.Disabled == false);
IRelayClientTransport transport = Transports.FirstOrDefault(c => c.Type == relayClientStore.RelayType && relayClientStore.Disabled == false);
if (transport == null)
{
return null;
@@ -82,10 +81,10 @@ namespace linker.plugins.relay.client
FromMachineName = string.Empty,
RemoteMachineId = remoteMachineId,
RemoteMachineName = string.Empty,
SecretKey = relayClientConfigTransfer.Server.SecretKey,
SecretKey = relayClientStore.SecretKey,
TransactionId = transactionId,
TransportName = transport.Name,
SSL = relayClientConfigTransfer.Server.SSL,
SSL = relayClientStore.SSL,
NodeId = nodeId
};
@@ -131,7 +130,7 @@ namespace linker.plugins.relay.client
try
{
ITransport _transports = Transports.FirstOrDefault(c => c.Name == relayInfo.TransportName);
IRelayClientTransport _transports = Transports.FirstOrDefault(c => c.Name == relayInfo.TransportName);
if (_transports == null) return false;
await _transports.OnBeginAsync(relayInfo, (connection) =>

View File

@@ -1,18 +1,17 @@
using linker.config;
using linker.messenger.relay.server;
using linker.tunnel.connection;
using MemoryPack;
using System.Net;
namespace linker.plugins.relay.client.transport
namespace linker.messenger.relay.client.transport
{
public enum RelayType : byte
public enum RelayClientType : byte
{
Linker = 0,
}
/// <summary>
/// 中继接口
/// </summary>
public interface ITransport
public interface IRelayClientTransport
{
/// <summary>
/// 接口名
@@ -21,7 +20,7 @@ namespace linker.plugins.relay.client.transport
/// <summary>
/// 中继类型
/// </summary>
public RelayType Type { get; }
public RelayClientType Type { get; }
/// <summary>
/// 协议
/// </summary>
@@ -44,26 +43,22 @@ namespace linker.plugins.relay.client.transport
/// </summary>
/// <param name="relayTestInfo"></param>
/// <returns></returns>
public Task<List<RelayNodeReportInfo>> RelayTestAsync(RelayTestInfo relayTestInfo);
public Task<List<RelayServerNodeReportInfo>> RelayTestAsync(RelayTestInfo relayTestInfo);
}
/// <summary>
/// 中继测试
/// </summary>
[MemoryPackable]
public sealed partial class RelayTestInfo
{
public string MachineId { get; set; }
public string SecretKey { get; set; }
[MemoryPackAllowSerialize]
public IPEndPoint Server { get; set; }
}
/// <summary>
/// 中继交换数据
/// </summary>
[MemoryPackable]
public sealed partial class RelayInfo
{
/// <summary>
@@ -107,7 +102,6 @@ namespace linker.plugins.relay.client.transport
/// <summary>
/// 服务器a端选择用什么服务器就带给bb直接用不需要再做复杂的选择
/// </summary>
[MemoryPackAllowSerialize]
public IPEndPoint Server { get; set; }
/// <summary>
@@ -115,4 +109,5 @@ namespace linker.plugins.relay.client.transport
/// </summary>
public bool SSL { get; set; } = true;
}
}

View File

@@ -1,46 +1,32 @@
using linker.config;
using linker.plugins.relay.messenger;

using linker.messenger.relay.messenger;
using linker.tunnel.connection;
using linker.libs;
using linker.libs.extends;
using MemoryPack;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using linker.plugins.messenger;
using linker.plugins.client;
using System.Buffers;
using linker.plugins.relay.server;
using linker.plugins.resolver;
using System.Net.NetworkInformation;
using linker.messenger;
using linker.messenger.relay.server;
namespace linker.plugins.relay.client.transport
namespace linker.messenger.relay.client.transport
{
public sealed class TransportSelfHost : ITransport
public sealed class RelayClientTransportSelfHost : IRelayClientTransport
{
public string Name => "Linker";
public RelayType Type => RelayType.Linker;
public RelayClientType Type => RelayClientType.Linker;
public TunnelProtocolType ProtocolType => TunnelProtocolType.Tcp;
private readonly IMessengerSender messengerSender;
private readonly ClientSignInState clientSignInState;
private X509Certificate2 certificate;
public TransportSelfHost(IMessengerSender messengerSender, ClientSignInState clientSignInState, ClientConfigTransfer clientConfigTransfer)
private readonly ISerializer serializer;
private readonly IRelayClientStore relayClientStore;
public RelayClientTransportSelfHost(IMessengerSender messengerSender, ISerializer serializer, IRelayClientStore relayClientStore)
{
this.messengerSender = messengerSender;
this.clientSignInState = clientSignInState;
string path = Path.GetFullPath(clientConfigTransfer.SSL.File);
if (File.Exists(path))
{
certificate = new X509Certificate2(path, clientConfigTransfer.SSL.Password, X509KeyStorageFlags.Exportable);
}
this.serializer = serializer;
this.relayClientStore = relayClientStore;
}
public async Task<ITunnelConnection> RelayAsync(RelayInfo relayInfo)
@@ -128,9 +114,9 @@ namespace linker.plugins.relay.client.transport
{
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = clientSignInState.Connection,
Connection = relayClientStore.SigninConnection,
MessengerId = (ushort)RelayMessengerIds.RelayAsk,
Payload = MemoryPackSerializer.Serialize(relayInfo),
Payload = serializer.Serialize(relayInfo),
Timeout = 2000
}).ConfigureAwait(false);
if (resp.Code != MessageResponeCodes.OK)
@@ -138,66 +124,12 @@ namespace linker.plugins.relay.client.transport
return new RelayAskResultInfo();
}
RelayAskResultInfo result = MemoryPackSerializer.Deserialize<RelayAskResultInfo>(resp.Data.Span);
RelayAskResultInfo result = serializer.Deserialize<RelayAskResultInfo>(resp.Data.Span);
return result;
}
private async Task<List<RelayNodeReportInfo>> TestDelay(List<RelayNodeReportInfo> list)
{
//测试前几个就行了
List<RelayNodeReportInfo> result = list.Take(10).ToList();
Dictionary<string, RelayNodeDelayInfo> delays = result.ToDictionary(c => c.Id, d => new RelayNodeDelayInfo
{
Delay = 65535,
Id = d.Id,
IP = d.EndPoint == null || d.EndPoint.Address.Equals(IPAddress.Any) ? clientSignInState.Connection.Address.Address : d.EndPoint.Address
});
//让对面测一测
Task<MessageResponeInfo> respTask = messengerSender.SendReply(new MessageRequestWrap
{
Connection = clientSignInState.Connection,
MessengerId = (ushort)RelayMessengerIds.NodeDelayForward,
Payload = MemoryPackSerializer.Serialize(delays),
Timeout = 5000
});
//自己测一测
var tasks = delays.Select(async (c) =>
{
using Ping ping = new Ping();
var resp = await ping.SendPingAsync(c.Value.IP, 1000);
c.Value.Delay = resp.Status == IPStatus.Success ? (int)resp.RoundtripTime : 65535;
});
await Task.WhenAll(tasks);
MessageResponeInfo resp = await respTask;
//两边的延迟加起来,看哪个服务器更快
if (resp.Code == MessageResponeCodes.OK && resp.Data.Length > 0)
{
Dictionary<string, RelayNodeDelayInfo> remotes = MemoryPackSerializer.Deserialize<Dictionary<string, RelayNodeDelayInfo>>(resp.Data.Span);
foreach (var item in result)
{
if (delays.TryGetValue(item.Id, out RelayNodeDelayInfo local) && remotes.TryGetValue(item.Id, out RelayNodeDelayInfo remote))
{
item.Delay = local.Delay + remote.Delay;
}
}
return result.OrderByDescending(c => c.LastTicks)
//带宽倒序
.OrderByDescending(c => c.MaxBandwidth)
//最大连接数倒序
.OrderByDescending(c => c.MaxConnection)
//连接数比例升序
.OrderBy(c => c.ConnectionRatio)
//延迟升序
.OrderBy(c => c.Delay).ToList();
}
return result;
}
private async Task<Socket> ConnectNodeServer(RelayInfo relayInfo, List<RelayNodeReportInfo> nodes)
private async Task<Socket> ConnectNodeServer(RelayInfo relayInfo, List<RelayServerNodeReportInfo> nodes)
{
byte[] buffer = ArrayPool<byte>.Shared.Rent(1 * 1024);
@@ -210,7 +142,7 @@ namespace linker.plugins.relay.client.transport
IPEndPoint ep = node.EndPoint;
if (ep == null || ep.Address.Equals(IPAddress.Any))
{
ep = clientSignInState.Connection.Address;
ep = relayClientStore.SigninConnection.Address;
}
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
@@ -222,7 +154,7 @@ namespace linker.plugins.relay.client.transport
await socket.ConnectAsync(ep).WaitAsync(TimeSpan.FromMilliseconds(5000)).ConfigureAwait(false);
//建立关联
RelayMessage relayMessage = new RelayMessage
RelayMessageInfo relayMessage = new RelayMessageInfo
{
FlowId = relayInfo.FlowingId,
Type = RelayMessengerType.Ask,
@@ -230,8 +162,9 @@ namespace linker.plugins.relay.client.transport
ToId = relayInfo.RemoteMachineId,
NodeId = node.Id,
};
await socket.SendAsync(new byte[] { (byte)ResolverType.Relay });
await socket.SendAsync(MemoryPackSerializer.Serialize(relayMessage));
if (relayClientStore.Flag > 0)
await socket.SendAsync(new byte[] { relayClientStore.Flag });
await socket.SendAsync(serializer.Serialize(relayMessage));
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"relay connected {ep}");
@@ -275,9 +208,9 @@ namespace linker.plugins.relay.client.transport
//通知对方去确认中继
var resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = clientSignInState.Connection,
Connection = relayClientStore.SigninConnection,
MessengerId = (ushort)RelayMessengerIds.RelayForward,
Payload = MemoryPackSerializer.Serialize(relayInfo),
Payload = serializer.Serialize(relayInfo),
});
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
}
@@ -291,13 +224,13 @@ namespace linker.plugins.relay.client.transport
{
try
{
IPEndPoint ep = relayInfo.Server == null || relayInfo.Server.Address.Equals(IPAddress.Any) ? clientSignInState.Connection.Address : relayInfo.Server;
IPEndPoint ep = relayInfo.Server == null || relayInfo.Server.Address.Equals(IPAddress.Any) ? relayClientStore.SigninConnection.Address : relayInfo.Server;
Socket socket = new Socket(ep.AddressFamily, SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
socket.KeepAlive();
await socket.ConnectAsync(ep).WaitAsync(TimeSpan.FromMilliseconds(5000)).ConfigureAwait(false);
RelayMessage relayMessage = new RelayMessage
RelayMessageInfo relayMessage = new RelayMessageInfo
{
FlowId = relayInfo.FlowingId,
Type = RelayMessengerType.Answer,
@@ -305,8 +238,9 @@ namespace linker.plugins.relay.client.transport
ToId = relayInfo.RemoteMachineId,
NodeId = relayInfo.NodeId,
};
await socket.SendAsync(new byte[] { (byte)ResolverType.Relay });
await socket.SendAsync(MemoryPackSerializer.Serialize(relayMessage));
if (relayClientStore.Flag > 0)
await socket.SendAsync(new byte[] { relayClientStore.Flag });
await socket.SendAsync(serializer.Serialize(relayMessage));
_ = WaitSSL(socket, relayInfo).ContinueWith((result) =>
{
@@ -333,14 +267,8 @@ namespace linker.plugins.relay.client.transport
SslStream sslStream = null;
if (relayInfo.SSL)
{
if (certificate == null)
{
LoggerHelper.Instance.Error($"need ssl");
socket.SafeClose();
return null;
}
sslStream = new SslStream(new NetworkStream(socket, false), false);
await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false).ConfigureAwait(false);
await sslStream.AuthenticateAsServerAsync(relayClientStore.Certificate, false, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false).ConfigureAwait(false);
}
return new TunnelConnectionTcp
{
@@ -371,27 +299,27 @@ namespace linker.plugins.relay.client.transport
return null;
}
public async Task<List<RelayNodeReportInfo>> RelayTestAsync(RelayTestInfo relayTestInfo)
public async Task<List<RelayServerNodeReportInfo>> RelayTestAsync(RelayTestInfo relayTestInfo)
{
try
{
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = clientSignInState.Connection,
Connection = relayClientStore.SigninConnection,
MessengerId = (ushort)RelayMessengerIds.RelayTest,
Payload = MemoryPackSerializer.Serialize(relayTestInfo),
Payload = serializer.Serialize(relayTestInfo),
Timeout = 2000
}).ConfigureAwait(false);
if (resp.Code == MessageResponeCodes.OK)
{
return MemoryPackSerializer.Deserialize<List<RelayNodeReportInfo>>(resp.Data.Span);
return serializer.Deserialize<List<RelayServerNodeReportInfo>>(resp.Data.Span);
}
}
catch (Exception)
{
}
return new List<RelayNodeReportInfo>();
return new List<RelayServerNodeReportInfo>();
}
}
}

View File

@@ -0,0 +1,45 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PublishAot>false</PublishAot>
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
<EnablePreviewFeatures>True</EnablePreviewFeatures>
<Title>linker relay</Title>
<Authors>snltty</Authors>
<Company>snltty</Company>
<Description>linker messenger relay</Description>
<Copyright>snltty</Copyright>
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker messenger relay</PackageReleaseNotes>
<Version>1.6.4</Version>
<AssemblyVersion>1.6.4</AssemblyVersion>
<FileVersion>1.6.4</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\linker.libs\linker.libs.csproj" />
<ProjectReference Include="..\linker.messenger\linker.messenger.csproj" />
<ProjectReference Include="..\linker.signin\linker.messenger.signin.csproj" />
<ProjectReference Include="..\linker.tunnel\linker.tunnel.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,25 +1,24 @@
using linker.config;
using linker.plugins.relay.client.transport;

using linker.messenger.relay.client.transport;
using linker.libs;
using MemoryPack;
using linker.plugins.relay.client;
using linker.plugins.relay.server.validator;
using linker.plugins.relay.server;
using System.Net.NetworkInformation;
using linker.messenger;
using linker.messenger.relay.client;
using linker.messenger.relay.server;
using linker.messenger.signin;
using linker.messenger.relay.server.validator;
namespace linker.plugins.relay.messenger
namespace linker.messenger.relay.messenger
{
/// <summary>
/// 中继客户端
/// </summary>
public sealed class RelayClientMessenger : IMessenger
public class RelayClientMessenger : IMessenger
{
private readonly RelayTransfer relayTransfer;
public RelayClientMessenger(RelayTransfer relayTransfer)
private readonly RelayClientTransfer relayTransfer;
private readonly ISerializer serializer;
public RelayClientMessenger(RelayClientTransfer relayTransfer, ISerializer serializer)
{
this.relayTransfer = relayTransfer;
this.serializer = serializer;
}
/// <summary>
@@ -30,52 +29,30 @@ namespace linker.plugins.relay.messenger
[MessengerId((ushort)RelayMessengerIds.Relay)]
public async Task Relay(IConnection connection)
{
client.transport.RelayInfo info = MemoryPackSerializer.Deserialize<client.transport.RelayInfo>(connection.ReceiveRequestWrap.Payload.Span);
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);
}
/// <summary>
/// 测试延迟
/// </summary>
/// <param name="connection"></param>
[MessengerId((ushort)RelayMessengerIds.NodeDelay)]
public void NodeDelay(IConnection connection)
{
Dictionary<string, RelayNodeDelayInfo> nodes = MemoryPackSerializer.Deserialize<Dictionary<string, RelayNodeDelayInfo>>(connection.ReceiveRequestWrap.Payload.Span);
var tasks = nodes.Select(async (c) =>
{
using Ping ping = new Ping();
var resp = await ping.SendPingAsync(c.Value.IP, 1000);
c.Value.Delay = resp.Status == IPStatus.Success ? (int)resp.RoundtripTime : 65535;
});
Task.WhenAll(tasks).ContinueWith((result) =>
{
connection.Write(MemoryPackSerializer.Serialize(nodes));
});
}
}
/// <summary>
/// 中继服务端
/// </summary>
public sealed class RelayServerMessenger : IMessenger
public class RelayServerMessenger : IMessenger
{
private readonly FileConfig config;
private readonly IMessengerSender messengerSender;
private readonly SignCaching signCaching;
private readonly RelayServerMasterTransfer relayServerTransfer;
private readonly RelayValidatorTransfer relayValidatorTransfer;
private readonly RelayServerValidatorTransfer relayValidatorTransfer;
private readonly ISerializer serializer;
public RelayServerMessenger(FileConfig config, IMessengerSender messengerSender, SignCaching signCaching, RelayServerMasterTransfer relayServerTransfer, RelayValidatorTransfer relayValidatorTransfer)
public RelayServerMessenger(IMessengerSender messengerSender, SignCaching signCaching, RelayServerMasterTransfer relayServerTransfer, RelayServerValidatorTransfer relayValidatorTransfer, ISerializer serializer)
{
this.config = config;
this.messengerSender = messengerSender;
this.signCaching = signCaching;
this.relayServerTransfer = relayServerTransfer;
this.relayValidatorTransfer = relayValidatorTransfer;
this.serializer = serializer;
}
/// <summary>
@@ -85,7 +62,7 @@ namespace linker.plugins.relay.messenger
[MessengerId((ushort)RelayMessengerIds.RelayTest)]
public async Task RelayTest(IConnection connection)
{
RelayTestInfo info = MemoryPackSerializer.Deserialize<RelayTestInfo>(connection.ReceiveRequestWrap.Payload.Span);
RelayTestInfo info = serializer.Deserialize<RelayTestInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false)
{
connection.Write(Helper.FalseArray);
@@ -101,7 +78,7 @@ namespace linker.plugins.relay.messenger
}, cache, null);
var nodes = relayServerTransfer.GetNodes(string.IsNullOrWhiteSpace(result));
connection.Write(MemoryPackSerializer.Serialize(nodes));
connection.Write(serializer.Serialize(nodes));
}
@@ -112,10 +89,10 @@ namespace linker.plugins.relay.messenger
[MessengerId((ushort)RelayMessengerIds.RelayAsk)]
public async Task RelayAsk(IConnection connection)
{
client.transport.RelayInfo info = MemoryPackSerializer.Deserialize<client.transport.RelayInfo>(connection.ReceiveRequestWrap.Payload.Span);
client.transport.RelayInfo info = serializer.Deserialize<client.transport.RelayInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(connection.Id, out SignCacheInfo cacheFrom) == false || signCaching.TryGet(info.RemoteMachineId, out SignCacheInfo cacheTo) == false || cacheFrom.GroupId != cacheTo.GroupId)
{
connection.Write(MemoryPackSerializer.Serialize(new RelayAskResultInfo { }));
connection.Write(serializer.Serialize(new RelayAskResultInfo { }));
return;
}
@@ -133,7 +110,7 @@ namespace linker.plugins.relay.messenger
result.FlowingId = relayServerTransfer.AddRelay(cacheFrom.MachineId, cacheFrom.MachineName, cacheTo.MachineId, cacheTo.MachineName, cacheFrom.GroupId);
}
connection.Write(MemoryPackSerializer.Serialize(result));
connection.Write(serializer.Serialize(result));
}
/// <summary>
@@ -144,7 +121,7 @@ namespace linker.plugins.relay.messenger
[MessengerId((ushort)RelayMessengerIds.RelayForward)]
public async Task RelayForward(IConnection connection)
{
client.transport.RelayInfo info = MemoryPackSerializer.Deserialize<client.transport.RelayInfo>(connection.ReceiveRequestWrap.Payload.Span);
client.transport.RelayInfo info = serializer.Deserialize<client.transport.RelayInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(connection.Id, out SignCacheInfo cacheFrom) == false || signCaching.TryGet(info.RemoteMachineId, out SignCacheInfo cacheTo) == false || cacheFrom.GroupId != cacheTo.GroupId)
{
connection.Write(Helper.FalseArray);
@@ -176,7 +153,7 @@ namespace linker.plugins.relay.messenger
{
Connection = cacheTo.Connection,
MessengerId = (ushort)RelayMessengerIds.Relay,
Payload = MemoryPackSerializer.Serialize(info)
Payload = serializer.Serialize(info)
}).ConfigureAwait(false);
if (resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray))
{
@@ -190,59 +167,5 @@ namespace linker.plugins.relay.messenger
connection.Write(Helper.FalseArray);
}
}
/// <summary>
/// 测试延迟
/// </summary>
/// <param name="connection"></param>
/// <returns></returns>
[MessengerId((ushort)RelayMessengerIds.NodeDelayForward)]
public void NodeDelayForward(IConnection connection)
{
RelayNodeDelayWrapInfo info = MemoryPackSerializer.Deserialize<RelayNodeDelayWrapInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(connection.Id, out SignCacheInfo cacheFrom) == false || signCaching.TryGet(info.MachineId, out SignCacheInfo cacheTo) == false || cacheFrom.GroupId != cacheTo.GroupId)
{
connection.Write(Helper.FalseArray);
return;
}
uint requiestid = connection.ReceiveRequestWrap.RequestId;
messengerSender.SendReply(new MessageRequestWrap
{
Connection = cacheTo.Connection,
MessengerId = (ushort)RelayMessengerIds.NodeDelay,
Payload = MemoryPackSerializer.Serialize(info.Nodes)
}).ContinueWith(async (result) =>
{
if (result.Result.Code == MessageResponeCodes.OK)
{
await messengerSender.ReplyOnly(new MessageResponseWrap
{
RequestId = requiestid,
Connection = connection,
Payload = MemoryPackSerializer.Serialize(MemoryPackSerializer.Deserialize<Dictionary<string, RelayNodeDelayInfo>>(result.Result.Data.Span))
}, (ushort)RelayMessengerIds.NodeDelayForward).ConfigureAwait(false);
return;
}
await messengerSender.ReplyOnly(new MessageResponseWrap
{
RequestId = requiestid,
Connection = connection,
Payload = Helper.EmptyArray
}, (ushort)RelayMessengerIds.NodeDelayForward).ConfigureAwait(false);
});
}
}
[MemoryPackable]
public sealed partial class RelayAskResultInfo
{
public ulong FlowingId { get; set; }
[MemoryPackAllowSerialize]
public List<RelayNodeReportInfo> Nodes { get; set; } = new List<RelayNodeReportInfo>();
}
}

View File

@@ -1,4 +1,4 @@
namespace linker.plugins.relay.messenger
namespace linker.messenger.relay.messenger
{
public enum RelayMessengerIds : ushort
{

View File

@@ -0,0 +1,22 @@
using linker.libs;
namespace linker.messenger.relay.server
{
public interface IRelayServerMasterStore
{
/// <summary>
/// 主服务器信息
/// </summary>
public RelayServerMasterInfo Master { get; }
}
public sealed class RelayServerMasterInfo
{
#if DEBUG
public string SecretKey { get; set; } = Helper.GlobalString;
#else
public string SecretKey { get; set; } = Guid.NewGuid().ToString().ToUpper();
#endif
}
}

View File

@@ -0,0 +1,110 @@
using linker.libs;
using System.Net;
using linker.libs.extends;
namespace linker.messenger.relay.server
{
public interface IRelayServerNodeStore
{
/// <summary>
/// 标志0不发送大于0发送当一个端口用于多个服务时使用用于区分不同业务
/// </summary>
public byte Flag { get; }
/// <summary>
/// 服务端端口
/// </summary>
public int ServicePort { get; }
/// <summary>
/// 节点信息
/// </summary>
public RelayServerNodeInfo Node { get; }
/// <summary>
/// 设置月份
/// </summary>
/// <param name="month"></param>
public void SetMaxGbTotalMonth(int month);
/// <summary>
/// 设置剩余流量
/// </summary>
/// <param name="value"></param>
public void SetMaxGbTotalLastBytes(ulong value);
/// <summary>
/// 提交保存
/// </summary>
public void Confirm();
}
public sealed class RelayServerNodeInfo
{
public const string MASTER_NODE_ID = "824777CF-2804-83FE-DE71-69B7B7D3BBA7";
private string id = Guid.NewGuid().ToString().ToUpper();
public string Id
{
get => id; set
{
id = value.SubStr(0, 36);
}
}
private string name = Dns.GetHostName().SubStr(0, 12);
public string Name
{
get => name; set
{
name = value.SubStr(0, 12);
}
}
public string Host { get; set; } = string.Empty;
public int MaxConnection { get; set; } = 100;
public double MaxBandwidth { get; set; } = 1;
public double MaxBandwidthTotal { get; set; }
public double MaxGbTotal { get; set; }
public ulong MaxGbTotalLastBytes { get; set; }
public int MaxGbTotalMonth { get; set; }
public bool Public { get; set; }
public string MasterHost { get; set; } = string.Empty;
#if DEBUG
public string MasterSecretKey { get; set; } = Helper.GlobalString;
#else
public string MasterSecretKey { get; set; } = string.Empty;
#endif
}
public sealed partial class RelayServerNodeReportInfo
{
public string Id { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public int MaxConnection { get; set; }
public double MaxBandwidth { get; set; }
public double MaxBandwidthTotal { get; set; }
public double MaxGbTotal { get; set; }
public ulong MaxGbTotalLastBytes { get; set; }
public double ConnectionRatio { get; set; }
public double BandwidthRatio { get; set; }
public bool Public { get; set; }
public int Delay { get; set; }
public IPEndPoint EndPoint { get; set; }
public long LastTicks { get; set; }
}
public sealed partial class RelayAskResultInfo
{
public ulong FlowingId { get; set; }
public List<RelayServerNodeReportInfo> Nodes { get; set; } = new List<RelayServerNodeReportInfo>();
}
}

View File

@@ -1,27 +1,25 @@
using linker.config;
using linker.libs;
using linker.plugins.relay.server.caching;
using MemoryPack;
using linker.libs;
using linker.messenger.relay.server.caching;
using System.Collections.Concurrent;
using System.Net;
namespace linker.plugins.relay.server
namespace linker.messenger.relay.server
{
public class RelayServerMasterTransfer
{
private ulong relayFlowingId = 0;
private readonly IRelayCaching relayCaching;
private readonly ICrypto crypto;
private readonly ConcurrentDictionary<string, RelayNodeReportInfo> reports = new ConcurrentDictionary<string, RelayNodeReportInfo>();
private readonly ConcurrentDictionary<string, RelayServerNodeReportInfo> reports = new ConcurrentDictionary<string, RelayServerNodeReportInfo>();
public RelayServerMasterTransfer(IRelayCaching relayCaching, RelayServerConfigTransfer relayServerConfigTransfer)
private readonly IRelayServerCaching relayCaching;
private readonly ISerializer serializer;
public RelayServerMasterTransfer(IRelayServerCaching relayCaching, ISerializer serializer, IRelayServerMasterStore relayServerMasterStore)
{
this.relayCaching = relayCaching;
crypto = CryptoFactory.CreateSymmetric(relayServerConfigTransfer.Master.SecretKey);
this.serializer = serializer;
crypto = CryptoFactory.CreateSymmetric(relayServerMasterStore.Master.SecretKey);
}
@@ -29,7 +27,7 @@ namespace linker.plugins.relay.server
{
ulong flowingId = Interlocked.Increment(ref relayFlowingId);
RelayCache cache = new RelayCache
RelayCacheInfo cache = new RelayCacheInfo
{
FlowId = flowingId,
FromId = fromid,
@@ -46,9 +44,9 @@ namespace linker.plugins.relay.server
public Memory<byte> TryGetRelayCache(string key)
{
if (relayCaching.TryGetValue(key, out RelayCache value))
if (relayCaching.TryGetValue(key, out RelayCacheInfo value))
{
byte[] bytes = crypto.Encode(MemoryPackSerializer.Serialize(value));
byte[] bytes = crypto.Encode(serializer.Serialize(value));
return bytes;
}
return Helper.EmptyArray;
@@ -66,9 +64,9 @@ namespace linker.plugins.relay.server
if (crypto == null) return;
data = crypto.Decode(data.ToArray());
RelayNodeReportInfo relayNodeReportInfo = MemoryPackSerializer.Deserialize<RelayNodeReportInfo>(data.Span);
RelayServerNodeReportInfo relayNodeReportInfo = serializer.Deserialize<RelayServerNodeReportInfo>(data.Span);
if (relayNodeReportInfo.Id == RelayNodeInfo.MASTER_NODE_ID)
if (relayNodeReportInfo.Id == RelayServerNodeInfo.MASTER_NODE_ID)
{
relayNodeReportInfo.EndPoint = new IPEndPoint(IPAddress.Any, 0);
}
@@ -88,7 +86,7 @@ namespace linker.plugins.relay.server
/// </summary>
/// <param name="validated">是否已认证</param>
/// <returns></returns>
public List<RelayNodeReportInfo> GetNodes(bool validated)
public List<RelayServerNodeReportInfo> GetNodes(bool validated)
{
var result = reports.Values
.Where(c => c.Public || (c.Public == false && validated))
@@ -113,7 +111,7 @@ namespace linker.plugins.relay.server
/// <returns></returns>
public bool NodeValidate(string nodeId)
{
return reports.TryGetValue(nodeId, out RelayNodeReportInfo relayNodeReportInfo) && relayNodeReportInfo.Public == false;
return reports.TryGetValue(nodeId, out RelayServerNodeReportInfo relayNodeReportInfo) && relayNodeReportInfo.Public == false;
}
}

View File

@@ -1,68 +1,63 @@
using linker.config;
using linker.libs;
using linker.libs;
using linker.libs.extends;
using linker.plugins.relay.server.caching;
using linker.plugins.resolver;
using linker.plugins.server;
using MemoryPack;
using linker.messenger.relay.server.caching;
using System.Buffers;
using System.Net;
using System.Net.Sockets;
namespace linker.plugins.relay.server
namespace linker.messenger.relay.server
{
public class RelayServerNodeTransfer
{
private uint connectionNum = 0;
private readonly IRelayCaching relayCaching;
private readonly FileConfig fileConfig;
private readonly RelayServerConfigTransfer relayServerConfigTransfer;
private readonly ServerConfigTransfer serverConfigTransfer;
private readonly ICrypto cryptoNode;
private readonly ICrypto cryptoMaster;
private ulong bytes = 0;
private ulong lastBytes = 0;
RelaySpeedLimit limitTotal = new RelaySpeedLimit();
public RelayServerNodeTransfer(IRelayCaching relayCaching, FileConfig fileConfig, RelayServerConfigTransfer relayServerConfigTransfer, ServerConfigTransfer serverConfigTransfer)
private readonly ISerializer serializer;
private readonly IRelayServerCaching relayCaching;
private readonly IRelayServerNodeStore relayServerNodeStore;
private readonly IRelayServerMasterStore relayServerMasterStore;
public RelayServerNodeTransfer(ISerializer serializer, IRelayServerCaching relayCaching, IRelayServerNodeStore relayServerNodeStore, IRelayServerMasterStore relayServerMasterStore)
{
this.serializer = serializer;
this.relayCaching = relayCaching;
this.fileConfig = fileConfig;
this.relayServerConfigTransfer = relayServerConfigTransfer;
this.serverConfigTransfer = serverConfigTransfer;
this.relayServerNodeStore = relayServerNodeStore;
this.relayServerMasterStore = relayServerMasterStore;
limitTotal.SetLimit((uint)Math.Ceiling((relayServerConfigTransfer.Node.MaxBandwidthTotal * 1024 * 1024) / 8.0));
limitTotal.SetLimit((uint)Math.Ceiling((relayServerNodeStore.Node.MaxBandwidthTotal * 1024 * 1024) / 8.0));
cryptoNode = CryptoFactory.CreateSymmetric(relayServerConfigTransfer.Node.MasterSecretKey);
cryptoMaster = CryptoFactory.CreateSymmetric(relayServerConfigTransfer.Master.SecretKey);
cryptoNode = CryptoFactory.CreateSymmetric(relayServerNodeStore.Node.MasterSecretKey);
cryptoMaster = CryptoFactory.CreateSymmetric(relayServerMasterStore.Master.SecretKey);
ReportTask();
}
public async ValueTask<RelayCache> TryGetRelayCache(string key, string nodeid)
public async ValueTask<RelayCacheInfo> TryGetRelayCache(string key, string nodeid)
{
byte[] buffer = ArrayPool<byte>.Shared.Rent(2 * 1024);
try
{
IPEndPoint server = nodeid == RelayNodeInfo.MASTER_NODE_ID
? new IPEndPoint(IPAddress.Loopback, serverConfigTransfer.Port)
: await NetworkHelper.GetEndPointAsync(relayServerConfigTransfer.Node.MasterHost, 1802);
ICrypto crypto = nodeid == RelayNodeInfo.MASTER_NODE_ID ? cryptoMaster : cryptoNode;
IPEndPoint server = nodeid == RelayServerNodeInfo.MASTER_NODE_ID
? new IPEndPoint(IPAddress.Loopback, relayServerNodeStore.ServicePort)
: await NetworkHelper.GetEndPointAsync(relayServerNodeStore.Node.MasterHost, 1802);
ICrypto crypto = nodeid == RelayServerNodeInfo.MASTER_NODE_ID ? cryptoMaster : cryptoNode;
Socket socket = new Socket(server.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
long start = Environment.TickCount64;
await socket.ConnectAsync(server).ConfigureAwait(false);
long time = Environment.TickCount64 - start;
await socket.SendAsync(new byte[] { (byte)ResolverType.RelayReport });
if (relayServerNodeStore.Flag > 0)
await socket.SendAsync(new byte[] { relayServerNodeStore.Flag });
await socket.SendAsync(key.ToBytes());
int length = await socket.ReceiveAsync(buffer.AsMemory(), SocketFlags.None).AsTask().WaitAsync(TimeSpan.FromMilliseconds(Math.Max(time * 2, 5000))).ConfigureAwait(false);
socket.SafeClose();
RelayCache result = MemoryPackSerializer.Deserialize<RelayCache>(crypto.Decode(buffer.AsMemory(0, length).ToArray()).Span);
RelayCacheInfo result = serializer.Deserialize<RelayCacheInfo>(crypto.Decode(buffer.AsMemory(0, length).ToArray()).Span);
return result;
}
catch (Exception ex)
@@ -106,9 +101,9 @@ namespace linker.plugins.relay.server
/// <returns></returns>
public bool ValidateConnection()
{
bool res = relayServerConfigTransfer.Node.MaxConnection == 0 || relayServerConfigTransfer.Node.MaxConnection * 2 > connectionNum;
bool res = relayServerNodeStore.Node.MaxConnection == 0 || relayServerNodeStore.Node.MaxConnection * 2 > connectionNum;
if (res == false && LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Debug($"relay ValidateConnection false,{connectionNum}/{relayServerConfigTransfer.Node.MaxConnection * 2}");
LoggerHelper.Instance.Debug($"relay ValidateConnection false,{connectionNum}/{relayServerNodeStore.Node.MaxConnection * 2}");
return res;
}
@@ -119,11 +114,11 @@ namespace linker.plugins.relay.server
/// <returns></returns>
public bool ValidateBytes()
{
bool res = relayServerConfigTransfer.Node.MaxGbTotal == 0
|| (relayServerConfigTransfer.Node.MaxGbTotal > 0 && relayServerConfigTransfer.Node.MaxGbTotalLastBytes > 0);
bool res = relayServerNodeStore.Node.MaxGbTotal == 0
|| (relayServerNodeStore.Node.MaxGbTotal > 0 && relayServerNodeStore.Node.MaxGbTotalLastBytes > 0);
if (res == false && LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Debug($"relay ValidateBytes false,{relayServerConfigTransfer.Node.MaxGbTotalLastBytes}bytes/{relayServerConfigTransfer.Node.MaxGbTotal}gb");
LoggerHelper.Instance.Debug($"relay ValidateBytes false,{relayServerNodeStore.Node.MaxGbTotalLastBytes}bytes/{relayServerNodeStore.Node.MaxGbTotal}gb");
return res;
}
@@ -135,15 +130,15 @@ namespace linker.plugins.relay.server
public bool AddBytes(ulong length)
{
bytes += length;
if (relayServerConfigTransfer.Node.MaxGbTotal == 0)
if (relayServerNodeStore.Node.MaxGbTotal == 0)
{
return true;
}
if (relayServerConfigTransfer.Node.MaxGbTotalLastBytes >= length)
relayServerConfigTransfer.SetMaxGbTotalLastBytes(relayServerConfigTransfer.Node.MaxGbTotalLastBytes - length);
else relayServerConfigTransfer.SetMaxGbTotalLastBytes(0);
return relayServerConfigTransfer.Node.MaxGbTotalLastBytes > 0;
if (relayServerNodeStore.Node.MaxGbTotalLastBytes >= length)
relayServerNodeStore.SetMaxGbTotalLastBytes(relayServerNodeStore.Node.MaxGbTotalLastBytes - length);
else relayServerNodeStore.SetMaxGbTotalLastBytes(0);
return relayServerNodeStore.Node.MaxGbTotalLastBytes > 0;
}
/// <summary>
@@ -152,7 +147,7 @@ namespace linker.plugins.relay.server
/// <returns></returns>
public uint GetBandwidthLimit()
{
return (uint)Math.Ceiling((relayServerConfigTransfer.Node.MaxBandwidth * 1024 * 1024) / 8.0);
return (uint)Math.Ceiling((relayServerNodeStore.Node.MaxBandwidth * 1024 * 1024) / 8.0);
}
/// <summary>
/// 是否需要总限速
@@ -175,12 +170,12 @@ namespace linker.plugins.relay.server
private void ResetBytes()
{
if (relayServerConfigTransfer.Node.MaxGbTotalMonth != DateTime.Now.Month)
if (relayServerNodeStore.Node.MaxGbTotalMonth != DateTime.Now.Month)
{
relayServerConfigTransfer.SetMaxGbTotalMonth(DateTime.Now.Month);
relayServerConfigTransfer.SetMaxGbTotalLastBytes((ulong)(relayServerConfigTransfer.Node.MaxGbTotal * 1024 * 1024 * 1024));
relayServerNodeStore.SetMaxGbTotalMonth(DateTime.Now.Month);
relayServerNodeStore.SetMaxGbTotalLastBytes((ulong)(relayServerNodeStore.Node.MaxGbTotal * 1024 * 1024 * 1024));
}
relayServerConfigTransfer.Update();
relayServerNodeStore.Confirm();
}
private void ReportTask()
@@ -188,14 +183,14 @@ namespace linker.plugins.relay.server
TimerHelper.SetInterval(async () =>
{
ResetBytes();
IEnumerable<RelayNodeInfo> nodes = new List<RelayNodeInfo>
IEnumerable<RelayServerNodeInfo> nodes = new List<RelayServerNodeInfo>
{
//默认报告给自己,作为本服务器的一个默认中继节点
new RelayNodeInfo{
Id = RelayNodeInfo.MASTER_NODE_ID,
Host = new IPEndPoint(IPAddress.Any,serverConfigTransfer.Port).ToString(),
MasterHost = new IPEndPoint(IPAddress.Loopback,serverConfigTransfer.Port).ToString(),
MasterSecretKey = relayServerConfigTransfer.Master.SecretKey,
new RelayServerNodeInfo{
Id = RelayServerNodeInfo.MASTER_NODE_ID,
Host = new IPEndPoint(IPAddress.Any, relayServerNodeStore.ServicePort).ToString(),
MasterHost = new IPEndPoint(IPAddress.Loopback, relayServerNodeStore.ServicePort).ToString(),
MasterSecretKey = relayServerMasterStore.Master.SecretKey,
MaxBandwidth = 0,
MaxConnection = 0,
MaxBandwidthTotal=0,
@@ -206,7 +201,7 @@ namespace linker.plugins.relay.server
Public = false
},
//配置的中继节点
relayServerConfigTransfer.Node
relayServerNodeStore.Node
}.Where(c => string.IsNullOrWhiteSpace(c.MasterHost) == false && string.IsNullOrWhiteSpace(c.MasterSecretKey) == false)
.Where(c => string.IsNullOrWhiteSpace(c.Name) == false && string.IsNullOrWhiteSpace(c.Id) == false);
@@ -217,10 +212,10 @@ namespace linker.plugins.relay.server
{
try
{
ICrypto crypto = node.Id == RelayNodeInfo.MASTER_NODE_ID ? cryptoMaster : cryptoNode;
IPEndPoint endPoint = await NetworkHelper.GetEndPointAsync(node.Host, serverConfigTransfer.Port) ?? new IPEndPoint(IPAddress.Any, serverConfigTransfer.Port);
ICrypto crypto = node.Id == RelayServerNodeInfo.MASTER_NODE_ID ? cryptoMaster : cryptoNode;
IPEndPoint endPoint = await NetworkHelper.GetEndPointAsync(node.Host, relayServerNodeStore.ServicePort) ?? new IPEndPoint(IPAddress.Any, relayServerNodeStore.ServicePort);
RelayNodeReportInfo relayNodeReportInfo = new RelayNodeReportInfo
RelayServerNodeReportInfo relayNodeReportInfo = new RelayServerNodeReportInfo
{
Id = node.Id,
Name = node.Name,
@@ -235,11 +230,11 @@ namespace linker.plugins.relay.server
EndPoint = endPoint,
};
IPEndPoint ep = await NetworkHelper.GetEndPointAsync(node.MasterHost, serverConfigTransfer.Port);
IPEndPoint ep = await NetworkHelper.GetEndPointAsync(node.MasterHost, relayServerNodeStore.ServicePort);
byte[] content = crypto.Encode(MemoryPackSerializer.Serialize(relayNodeReportInfo));
byte[] content = crypto.Encode(serializer.Serialize(relayNodeReportInfo));
byte[] data = new byte[content.Length + 1];
data[0] = (byte)ResolverType.RelayReport;
data[0] = relayServerNodeStore.Flag;
content.AsMemory().CopyTo(data.AsMemory(1));
using UdpClient udpClient = new UdpClient(AddressFamily.InterNetwork);

View File

@@ -1,17 +1,14 @@
using linker.libs.extends;
using linker.plugins.resolver;
using System.Buffers;
using System.Net;
using System.Net.Sockets;
namespace linker.plugins.relay.server
namespace linker.messenger.relay.server
{
public class RelayReportResolver : IResolver
public class RelayServerReportResolver
{
public ResolverType Type => ResolverType.RelayReport;
private readonly RelayServerMasterTransfer relayServerTransfer;
public RelayReportResolver(RelayServerMasterTransfer relayServerTransfer)
public RelayServerReportResolver(RelayServerMasterTransfer relayServerTransfer)
{
this.relayServerTransfer = relayServerTransfer;
}

View File

@@ -2,29 +2,25 @@
using System.Buffers;
using linker.libs.extends;
using System.Collections.Concurrent;
using linker.plugins.resolver;
using System.Net;
using MemoryPack;
using linker.config;
using linker.libs;
namespace linker.plugins.relay.server
namespace linker.messenger.relay.server
{
/// <summary>
/// 中继连接处理
/// </summary>
public class RelayResolver : IResolver
public class RelayServerResolver
{
public ResolverType Type => ResolverType.Relay;
private readonly RelayServerNodeTransfer relayServerNodeTransfer;
public RelayResolver(RelayServerNodeTransfer relayServerNodeTransfer)
private readonly ISerializer serializer;
public RelayServerResolver(RelayServerNodeTransfer relayServerNodeTransfer, ISerializer serializer)
{
this.relayServerNodeTransfer = relayServerNodeTransfer;
this.serializer = serializer;
}
private readonly ConcurrentDictionary<ulong, RelayWrap> relayDic = new ConcurrentDictionary<ulong, RelayWrap>();
private readonly ConcurrentDictionary<ulong, RelayWrapInfo> relayDic = new ConcurrentDictionary<ulong, RelayWrapInfo>();
public virtual void AddReceive(string key, string from, string to, string groupid, ulong bytes)
@@ -51,9 +47,9 @@ namespace linker.plugins.relay.server
try
{
int length = await socket.ReceiveAsync(buffer.AsMemory(), SocketFlags.None).ConfigureAwait(false);
RelayMessage relayMessage = MemoryPackSerializer.Deserialize<RelayMessage>(buffer.AsMemory(0, length).Span);
RelayMessageInfo relayMessage = serializer.Deserialize<RelayMessageInfo>(buffer.AsMemory(0, length).Span);
if (relayMessage.Type == RelayMessengerType.Ask && relayMessage.NodeId != RelayNodeInfo.MASTER_NODE_ID)
if (relayMessage.Type == RelayMessengerType.Ask && relayMessage.NodeId != RelayServerNodeInfo.MASTER_NODE_ID)
{
if (relayServerNodeTransfer.Validate() == false)
{
@@ -67,7 +63,7 @@ namespace linker.plugins.relay.server
//ask 是发起端来的那key就是 发起端->目标端, answer的目标和来源会交换所以转换一下
string key = relayMessage.Type == RelayMessengerType.Ask ? $"{relayMessage.FromId}->{relayMessage.ToId}->{relayMessage.FlowId}" : $"{relayMessage.ToId}->{relayMessage.FromId}->{relayMessage.FlowId}";
//获取缓存
RelayCache relayCache = await relayServerNodeTransfer.TryGetRelayCache(key, relayMessage.NodeId);
RelayCacheInfo relayCache = await relayServerNodeTransfer.TryGetRelayCache(key, relayMessage.NodeId);
if (relayCache == null)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
@@ -84,7 +80,7 @@ namespace linker.plugins.relay.server
case RelayMessengerType.Ask:
{
//添加本地缓存
RelayWrap relayWrap = new RelayWrap { Socket = socket, Tcs = new TaskCompletionSource<Socket>() };
RelayWrapInfo relayWrap = new RelayWrapInfo { Socket = socket, Tcs = new TaskCompletionSource<Socket>() };
relayWrap.Limit.SetLimit(relayServerNodeTransfer.GetBandwidthLimit());
relayDic.TryAdd(relayCache.FlowId, relayWrap);
@@ -99,7 +95,7 @@ namespace linker.plugins.relay.server
case RelayMessengerType.Answer:
{
//看发起端缓存
if (relayDic.TryRemove(relayCache.FlowId, out RelayWrap relayWrap) == false || relayWrap.Socket == null)
if (relayDic.TryRemove(relayCache.FlowId, out RelayWrapInfo relayWrap) == false || relayWrap.Socket == null)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error($"relay {relayMessage.Type} get cache fail,flowid:{relayMessage.FlowId}");
@@ -124,7 +120,7 @@ namespace linker.plugins.relay.server
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error($"{ex},flowid:{relayMessage.FlowId}");
if (relayDic.TryRemove(relayCache.FlowId, out RelayWrap remove))
if (relayDic.TryRemove(relayCache.FlowId, out RelayWrapInfo remove))
{
remove.Socket?.SafeClose();
}
@@ -141,7 +137,7 @@ namespace linker.plugins.relay.server
ArrayPool<byte>.Shared.Return(buffer);
}
}
private async Task CopyToAsync(RelayCache cache, RelaySpeedLimit limit, Socket source, Socket destination)
private async Task CopyToAsync(RelayCacheInfo cache, RelaySpeedLimit limit, Socket source, Socket destination)
{
byte[] buffer = new byte[4 * 1024];
try
@@ -202,7 +198,6 @@ namespace linker.plugins.relay.server
Ask = 0,
Answer = 1,
}
public class RelaySpeedLimit
{
private uint relayLimit = 0;
@@ -247,8 +242,7 @@ namespace linker.plugins.relay.server
}
}
[MemoryPackable]
public sealed partial class RelayCache
public sealed partial class RelayCacheInfo
{
public ulong FlowId { get; set; }
public string FromId { get; set; }
@@ -258,17 +252,14 @@ namespace linker.plugins.relay.server
public string GroupId { get; set; }
}
public sealed class RelayWrap
public sealed class RelayWrapInfo
{
public TaskCompletionSource<Socket> Tcs { get; set; }
public Socket Socket { get; set; }
[MemoryPackIgnore]
public RelaySpeedLimit Limit { get; set; } = new RelaySpeedLimit();
}
[MemoryPackable]
public sealed partial class RelayMessage
public sealed partial class RelayMessageInfo
{
public RelayMessengerType Type { get; set; }
public ulong FlowId { get; set; }

View File

@@ -1,6 +1,6 @@
namespace linker.plugins.relay.server.caching
namespace linker.messenger.relay.server.caching
{
public interface IRelayCaching
public interface IRelayServerCaching
{
public string Name { get; }

View File

@@ -1,19 +1,22 @@
using MemoryPack;
using linker.libs;
using Microsoft.Extensions.Caching.Memory;
namespace linker.plugins.relay.server.caching
namespace linker.messenger.relay.server.caching
{
public sealed class RelayCachingMemory : IRelayCaching
public sealed class RelayServerCachingMemory : IRelayServerCaching
{
public string Name => "memory";
private readonly IMemoryCache cache = new MemoryCache(new MemoryCacheOptions { });
public RelayCachingMemory()
private readonly ISerializer serializer;
public RelayServerCachingMemory(ISerializer serializer)
{
this.serializer = serializer;
}
public bool TryAdd<T>(string key, T value, int expired)
{
cache.Set(key, MemoryPackSerializer.Serialize(value), TimeSpan.FromMilliseconds(expired));
cache.Set(key, serializer.Serialize(value), TimeSpan.FromMilliseconds(expired));
return true;
}
@@ -22,7 +25,7 @@ namespace linker.plugins.relay.server.caching
bool result = cache.TryGetValue(key, out byte[] bytes);
if (result)
value = MemoryPackSerializer.Deserialize<T>(bytes);
value = serializer.Deserialize<T>(bytes);
else value = default;
return true;

View File

@@ -0,0 +1,17 @@
using linker.messenger.signin;
using RelayInfo = linker.messenger.relay.client.transport.RelayInfo;
namespace linker.messenger.relay.server.validator
{
public interface IRelayServerValidator
{
/// <summary>
/// 验证
/// </summary>
/// <param name="relayInfo">中继信息</param>
/// <param name="fromMachine">来源客户端</param>
/// <param name="toMachine">目标客户端可能为null</param>
/// <returns></returns>
public Task<string> Validate(RelayInfo relayInfo, SignCacheInfo fromMachine, SignCacheInfo toMachine);
}
}

View File

@@ -1,17 +1,17 @@
using linker.messenger.signin;
using linker.plugins.relay.client.transport;
using linker.messenger.relay.client.transport;
namespace linker.plugins.relay.server.validator
namespace linker.messenger.relay.server.validator
{
public sealed partial class RelayValidatorTransfer
public sealed partial class RelayServerValidatorTransfer
{
private List<IRelayValidator> validators;
private List<IRelayServerValidator> validators;
public RelayValidatorTransfer()
public RelayServerValidatorTransfer()
{
}
public void LoadValidators(List<IRelayValidator> list)
public void LoadValidators(List<IRelayServerValidator> list)
{
validators = list;
}

View File

@@ -27,7 +27,7 @@ namespace linker.messenger.tunnel
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"{ep} get udp external port");
AddReceive((ulong)memory.Length);
byte[] sendData = ArrayPool<byte>.Shared.Rent(20);
byte[] sendData = ArrayPool<byte>.Shared.Rent(1024);
try
{
var send = BuildSendData(sendData, ep);

View File

@@ -9,33 +9,37 @@ using System.Security.Cryptography.X509Certificates;
namespace linker.plugins.tunnel
{
public interface ITunnelMessengerAdapterStore
{
/// <summary>
/// 获取信标连接
/// </summary>
public IConnection SignConnection { get; }
/// <summary>
/// 获取本地网信息
/// </summary>
public NetworkInfo Network { get; }
/// <summary>
/// ssl
/// </summary>
public X509Certificate2 Certificate { get; }
/// <summary>
/// 打洞协议列表,按照这个列表去打洞
/// </summary>
public List<TunnelTransportItemInfo> TunnelTransports { get; }
/// <summary>
/// 保存打洞协议列表,因为可能会有新的打洞协议
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
public bool SetTunnelTransports(List<TunnelTransportItemInfo> list);
}
/// <summary>
/// 打洞信标适配
/// </summary>
public class TunnelMessengerAdapter
{
/// <summary>
/// 获取信标连接
/// </summary>
public Func<IConnection> GetSignConnection { get; set; } = () => { return null; };
/// <summary>
/// 获取本地网信息
/// </summary>
public Func<NetworkInfo> GetNetwork { get; set; } = () => { return new NetworkInfo(); };
/// <summary>
/// ssl
/// </summary>
public Func<X509Certificate2> Certificate { get; set; } = () => null;
/// <summary>
/// 打洞协议列表,按照这个列表去打洞
/// </summary>
public Func<List<TunnelTransportItemInfo>> GetTunnelTransports { get; set; } = () => new List<TunnelTransportItemInfo>();
/// <summary>
/// 保存打洞协议列表,因为可能会有新的打洞协议
/// </summary>
public Action<List<TunnelTransportItemInfo>, bool> SetTunnelTransports { get; set; } = (list, update) => { };
private readonly IMessengerSender messengerSender;
private readonly TunnelExcludeIPTransfer excludeIPTransfer;
@@ -50,7 +54,9 @@ namespace linker.plugins.tunnel
private readonly ISerializer serializer;
public TunnelMessengerAdapter(IMessengerSender messengerSender, TunnelExcludeIPTransfer excludeIPTransfer, TunnelWanPortTransfer tunnelWanPortTransfer, TunnelUpnpTransfer tunnelUpnpTransfer, TunnelTransfer tunnelTransfer, ISerializer serializer)
private readonly ITunnelMessengerAdapterStore tunnelMessengerAdapterStore;
public TunnelMessengerAdapter(IMessengerSender messengerSender, TunnelExcludeIPTransfer excludeIPTransfer, TunnelWanPortTransfer tunnelWanPortTransfer, TunnelUpnpTransfer tunnelUpnpTransfer, TunnelTransfer tunnelTransfer, ISerializer serializer,ITunnelMessengerAdapterStore tunnelMessengerAdapterStore)
{
this.messengerSender = messengerSender;
this.excludeIPTransfer = excludeIPTransfer;
@@ -61,6 +67,8 @@ namespace linker.plugins.tunnel
this.serializer = serializer;
this.tunnelMessengerAdapterStore = tunnelMessengerAdapterStore;
//加载外网端口
tunnelWanPortTransfer.LoadTransports(new List<ITunnelWanPortProtocol>
{
@@ -68,11 +76,11 @@ namespace linker.plugins.tunnel
new TunnelWanPortProtocolLinkerTcp(),
});
tunnelTransfer.LocalIP = () => { IConnection connection = GetSignConnection(); return connection?.LocalAddress.Address ?? IPAddress.Any; };
tunnelTransfer.ServerHost = () => { IConnection connection = GetSignConnection(); return connection?.Address ?? null; };
tunnelTransfer.Certificate = () => Certificate();
tunnelTransfer.GetTunnelTransports = () => GetTunnelTransports();
tunnelTransfer.SetTunnelTransports = (transports, update) => SetTunnelTransports(transports, update);
tunnelTransfer.LocalIP = () => tunnelMessengerAdapterStore.SignConnection?.LocalAddress.Address ?? IPAddress.Any; ;
tunnelTransfer.ServerHost = () => tunnelMessengerAdapterStore.SignConnection?.Address ?? null;
tunnelTransfer.Certificate = () => tunnelMessengerAdapterStore.Certificate;
tunnelTransfer.GetTunnelTransports = () => tunnelMessengerAdapterStore.TunnelTransports;
tunnelTransfer.SetTunnelTransports = (transports, update) => tunnelMessengerAdapterStore.SetTunnelTransports(transports);
tunnelTransfer.GetLocalConfig = GetLocalConfig;
tunnelTransfer.GetRemoteWanPort = GetRemoteWanPort;
tunnelTransfer.SendConnectBegin = SendConnectBegin;
@@ -96,7 +104,7 @@ namespace linker.plugins.tunnel
{
var excludeips = excludeIPTransfer.Get();
NetworkInfo networkInfo = GetNetwork();
NetworkInfo networkInfo = tunnelMessengerAdapterStore.Network;
networkInfo.LocalIps = networkInfo.LocalIps.Where(c =>
{
if (c.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
@@ -122,7 +130,7 @@ namespace linker.plugins.tunnel
{
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = GetSignConnection(),
Connection = tunnelMessengerAdapterStore.SignConnection,
MessengerId = (ushort)TunnelMessengerIds.InfoForward,
Payload = serializer.Serialize(info)
}).ConfigureAwait(false);
@@ -136,7 +144,7 @@ namespace linker.plugins.tunnel
{
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = GetSignConnection(),
Connection = tunnelMessengerAdapterStore.SignConnection,
MessengerId = (ushort)TunnelMessengerIds.BeginForward,
Payload = serializer.Serialize(tunnelTransportInfo)
}).ConfigureAwait(false);
@@ -146,7 +154,7 @@ namespace linker.plugins.tunnel
{
await messengerSender.SendOnly(new MessageRequestWrap
{
Connection = GetSignConnection(),
Connection = tunnelMessengerAdapterStore.SignConnection,
MessengerId = (ushort)TunnelMessengerIds.FailForward,
Payload = serializer.Serialize(tunnelTransportInfo)
}).ConfigureAwait(false);
@@ -156,7 +164,7 @@ namespace linker.plugins.tunnel
{
await messengerSender.SendOnly(new MessageRequestWrap
{
Connection = GetSignConnection(),
Connection = tunnelMessengerAdapterStore.SignConnection,
MessengerId = (ushort)TunnelMessengerIds.SuccessForward,
Payload = serializer.Serialize(tunnelTransportInfo)
}).ConfigureAwait(false);
@@ -178,10 +186,9 @@ namespace linker.plugins.tunnel
}
else
{
IConnection connection = GetSignConnection();
if (connection != null && connection.Connected)
if (tunnelMessengerAdapterStore.SignConnection != null && tunnelMessengerAdapterStore.SignConnection.Connected)
{
int ip = connection.LocalAddress.Address.GetAddressBytes()[3];
int ip = tunnelMessengerAdapterStore.SignConnection.LocalAddress.Address.GetAddressBytes()[3];
tunnelUpnpTransfer.SetMap(18180 + ip);
_ = transportTcpPortMap.Listen(18180 + ip);

View File

@@ -1,7 +1,6 @@
using linker.libs;
using System.Collections.Concurrent;
using System.Net;
using linker.messenger;
namespace linker.messenger.signin
{

View File

@@ -17,7 +17,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.messenger", "linker.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.messenger.signin", "linker.signin\linker.messenger.signin.csproj", "{5B1F4754-D1B6-426B-B310-8C21F26879D2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linker.messenger.tunnel", "linker.messenger.tunnel\linker.messenger.tunnel.csproj", "{92582A55-8BBF-4B82-892D-75CEC8969EAF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.messenger.tunnel", "linker.messenger.tunnel\linker.messenger.tunnel.csproj", "{92582A55-8BBF-4B82-892D-75CEC8969EAF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linker.messenger.relay", "linker.messenger.relay\linker.messenger.relay.csproj", "{90E99334-FBF6-423F-A636-89B1E71D8FEE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -125,6 +127,18 @@ Global
{92582A55-8BBF-4B82-892D-75CEC8969EAF}.Release|x64.Build.0 = Release|Any CPU
{92582A55-8BBF-4B82-892D-75CEC8969EAF}.Release|x86.ActiveCfg = Release|Any CPU
{92582A55-8BBF-4B82-892D-75CEC8969EAF}.Release|x86.Build.0 = Release|Any CPU
{90E99334-FBF6-423F-A636-89B1E71D8FEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{90E99334-FBF6-423F-A636-89B1E71D8FEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{90E99334-FBF6-423F-A636-89B1E71D8FEE}.Debug|x64.ActiveCfg = Debug|Any CPU
{90E99334-FBF6-423F-A636-89B1E71D8FEE}.Debug|x64.Build.0 = Debug|Any CPU
{90E99334-FBF6-423F-A636-89B1E71D8FEE}.Debug|x86.ActiveCfg = Debug|Any CPU
{90E99334-FBF6-423F-A636-89B1E71D8FEE}.Debug|x86.Build.0 = Debug|Any CPU
{90E99334-FBF6-423F-A636-89B1E71D8FEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{90E99334-FBF6-423F-A636-89B1E71D8FEE}.Release|Any CPU.Build.0 = Release|Any CPU
{90E99334-FBF6-423F-A636-89B1E71D8FEE}.Release|x64.ActiveCfg = Release|Any CPU
{90E99334-FBF6-423F-A636-89B1E71D8FEE}.Release|x64.Build.0 = Release|Any CPU
{90E99334-FBF6-423F-A636-89B1E71D8FEE}.Release|x86.ActiveCfg = Release|Any CPU
{90E99334-FBF6-423F-A636-89B1E71D8FEE}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -85,6 +85,7 @@ export default {
'Relay':{text:'中继',detail:hasRelayFlow.value},
'Messenger':{text:'信标',detail:hasSigninFlow.value},
'SForward':{text:'内网穿透',detail:hasSForwardFlow.value},
'flow':{text:'在线报告',detail:false},
};
const _getFlows = ()=>{
getFlows().then(res => {
@@ -119,7 +120,7 @@ export default {
for(let j in res.Items){
const item = res.Items[j];
const itemOld = old.Items[j];
const text = id2text[`${j}`] || {text:'未知',detail:false};
const text = id2text[`${j}`] || {text:`未知${j}`,detail:false};
list.push({
id:j,
text:text.text,

View File

@@ -66,6 +66,7 @@
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<IsTrimmable>false</IsTrimmable>
</ProjectReference>
<ProjectReference Include="..\linker.messenger.relay\linker.messenger.relay.csproj" />
<ProjectReference Include="..\linker.messenger.tunnel\linker.messenger.tunnel.csproj" />
<ProjectReference Include="..\linker.messenger\linker.messenger.csproj" />
<ProjectReference Include="..\linker.signin\linker.messenger.signin.csproj" />
@@ -76,7 +77,6 @@
<ItemGroup>
<PackageReference Include="LiteDB" Version="5.0.17" />
<PackageReference Include="MemoryPack" Version="1.21.3" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="8.0.1" />
</ItemGroup>

View File

@@ -1,9 +1,9 @@
using linker.config;
using linker.libs.extends;
using linker.messenger.signin;
using linker.plugins.relay.server.validator;
using linker.plugins.sforward.config;
using linker.plugins.sforward.validator;
using linker.messenger.relay.server.validator;
using System.Net;
using System.Text.Json.Nodes;
@@ -146,7 +146,7 @@ namespace linker.plugins.action
}
}
public sealed class RelayValidatorAction : JsonArgReplace, IRelayValidator
public sealed class RelayValidatorAction : JsonArgReplace, IRelayServerValidator
{
private readonly ActionTransfer actionTransfer;
private readonly FileConfig fileConfig;
@@ -157,7 +157,7 @@ namespace linker.plugins.action
this.fileConfig = fileConfig;
}
public async Task<string> Validate(linker.plugins.relay.client.transport.RelayInfo relayInfo, SignCacheInfo fromMachine, SignCacheInfo toMachine)
public async Task<string> Validate(linker.messenger.relay.client.transport.RelayInfo relayInfo, SignCacheInfo fromMachine, SignCacheInfo toMachine)
{
if (string.IsNullOrWhiteSpace(actionTransfer.RelayActionUrl) == false)
{

View File

@@ -22,7 +22,7 @@ namespace linker.plugins.flow
public sealed class ExternalResolverFlow : PlusTunnelExternalResolver
{
private readonly ExternalFlow externalFlow;
public ExternalResolverFlow(ExternalFlow externalFlow, TunnelExternalResolver tunnelExternalResolver) :base(tunnelExternalResolver)
public ExternalResolverFlow(ExternalFlow externalFlow)
{
this.externalFlow = externalFlow;
}

View File

@@ -42,9 +42,9 @@ namespace linker.plugins.flow
serviceCollection.AddSingleton<IMessengerSender, MessengerSenderFlow>();
serviceCollection.AddSingleton<RelayFlow>();
serviceCollection.AddSingleton<RelayResolver, RelayResolverFlow>();
serviceCollection.AddSingleton<PlusRelayServerResolver, RelayResolverFlow>();
serviceCollection.AddSingleton<RelayReportFlow>();
serviceCollection.AddSingleton<RelayReportResolver, RelayReportResolverFlow>();
serviceCollection.AddSingleton<PlusRelayServerReportResolver, RelayReportResolverFlow>();
serviceCollection.AddSingleton<ExternalFlow>();
serviceCollection.AddSingleton<PlusTunnelExternalResolver, ExternalResolverFlow>();

View File

@@ -1,4 +1,5 @@
using linker.libs;
using linker.messenger.relay.server;
using linker.plugins.relay.server;
using MemoryPack;
using System.Text.Json.Serialization;
@@ -19,7 +20,7 @@ namespace linker.plugins.flow
}
public sealed class RelayReportResolverFlow : RelayReportResolver
public sealed class RelayReportResolverFlow : PlusRelayServerReportResolver
{
private readonly RelayReportFlow relayReportFlow;
public RelayReportResolverFlow(RelayReportFlow relayReportFlow, RelayServerMasterTransfer relayServerTransfer) : base(relayServerTransfer)
@@ -34,10 +35,10 @@ namespace linker.plugins.flow
public sealed class RelayResolverFlow : RelayResolver
public sealed class RelayResolverFlow : PlusRelayServerResolver
{
private readonly RelayFlow relayFlow;
public RelayResolverFlow(RelayFlow relayFlow, RelayServerNodeTransfer relayServerNodeTransfer) : base(relayServerNodeTransfer)
public RelayResolverFlow(RelayFlow relayFlow, RelayServerNodeTransfer relayServerNodeTransfer,ISerializer serializer) : base(relayServerNodeTransfer, serializer)
{
this.relayFlow = relayFlow;
}

View File

@@ -1,14 +1,12 @@
using linker.config;
using linker.tunnel;
using linker.tunnel;
using linker.tunnel.connection;
using System.Collections.Concurrent;
using System.Net;
using linker.plugins.client;
using linker.plugins.tunnel;
using linker.plugins.messenger;
using linker.plugins.relay.client;
using linker.client.config;
using linker.plugins.pcp;
using linker.messenger.relay.client;
namespace linker.plugins.forward.proxy
{
@@ -20,7 +18,7 @@ namespace linker.plugins.forward.proxy
protected override string TransactionId => "forward";
public ForwardProxy(ClientConfigTransfer clientConfigTransfer, TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, PcpTransfer pcpTransfer, ClientSignInTransfer clientSignInTransfer, ClientSignInState clientSignInState, RelayClientConfigTransfer relayClientConfigTransfer)
public ForwardProxy(ClientConfigTransfer clientConfigTransfer, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, ClientSignInTransfer clientSignInTransfer, ClientSignInState clientSignInState, RelayClientConfigTransfer relayClientConfigTransfer)
: base(tunnelTransfer, relayTransfer, pcpTransfer, clientSignInTransfer, clientSignInState, clientConfigTransfer, relayClientConfigTransfer)
{
TaskUdp();

View File

@@ -0,0 +1,430 @@
using linker.messenger.relay.client.transport;
using linker.messenger.relay.server;
using MemoryPack;
using System.Net;
namespace linker.plugins.relay
{
[MemoryPackable]
public readonly partial struct SerializableRelayTestInfo
{
[MemoryPackIgnore]
public readonly RelayTestInfo info;
[MemoryPackInclude]
string MachineId => info.MachineId;
[MemoryPackInclude]
string SecretKey => info.SecretKey;
[MemoryPackInclude, MemoryPackAllowSerialize]
IPEndPoint Server => info.Server;
[MemoryPackConstructor]
SerializableRelayTestInfo(string machineId, string secretKey, IPEndPoint server)
{
var info = new RelayTestInfo { MachineId = machineId, SecretKey = secretKey, Server = server };
this.info = info;
}
public SerializableRelayTestInfo(RelayTestInfo info)
{
this.info = info;
}
}
public class RelayTestInfoFormatter : MemoryPackFormatter<RelayTestInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayTestInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayTestInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayTestInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableRelayTestInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableRelayInfo
{
[MemoryPackIgnore]
public readonly RelayInfo info;
[MemoryPackInclude]
string FromMachineId => info.FromMachineId;
[MemoryPackInclude]
string FromMachineName => info.FromMachineName;
[MemoryPackInclude]
string RemoteMachineId => info.RemoteMachineId;
[MemoryPackInclude]
string RemoteMachineName => info.RemoteMachineName;
[MemoryPackInclude]
string TransactionId => info.TransactionId;
[MemoryPackInclude]
string SecretKey => info.SecretKey;
[MemoryPackInclude]
string TransportName => info.TransportName;
[MemoryPackInclude]
ulong FlowingId => info.FlowingId;
[MemoryPackInclude]
string NodeId => info.NodeId;
[MemoryPackInclude, MemoryPackAllowSerialize]
IPEndPoint Server => info.Server;
[MemoryPackInclude]
bool SSL => info.SSL;
[MemoryPackConstructor]
SerializableRelayInfo(string fromMachineId, string fromMachineName,
string remoteMachineId, string remoteMachineName,
string transactionId, string secretKey, string transportName, ulong flowingId,
string nodeId, IPEndPoint server, bool ssl)
{
var info = new RelayInfo
{
FlowingId = flowingId,
FromMachineId = fromMachineId,
FromMachineName = fromMachineName,
NodeId = nodeId,
RemoteMachineId = remoteMachineId,
RemoteMachineName = remoteMachineName,
SSL = ssl,
TransactionId = transactionId,
TransportName = transportName,
SecretKey = secretKey,
Server = server
};
this.info = info;
}
public SerializableRelayInfo(RelayInfo relayInfo)
{
this.info = relayInfo;
}
}
public class RelayInfoFormatter : MemoryPackFormatter<RelayInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableRelayInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableRelayServerNodeReportInfo
{
[MemoryPackIgnore]
public readonly RelayServerNodeReportInfo info;
[MemoryPackInclude]
string Id => info.Id;
[MemoryPackInclude]
string Name => info.Name;
[MemoryPackInclude]
int MaxConnection => info.MaxConnection;
[MemoryPackInclude]
double MaxBandwidth => info.MaxBandwidth;
[MemoryPackInclude]
double MaxBandwidthTotal => info.MaxBandwidthTotal;
[MemoryPackInclude]
double MaxGbTotal => info.MaxGbTotal;
[MemoryPackInclude]
ulong MaxGbTotalLastBytes => info.MaxGbTotalLastBytes;
[MemoryPackInclude]
double ConnectionRatio => info.ConnectionRatio;
[MemoryPackInclude]
double BandwidthRatio => info.BandwidthRatio;
[MemoryPackInclude]
bool Public => info.Public;
[MemoryPackInclude]
int Delay => info.Delay;
[MemoryPackInclude, MemoryPackAllowSerialize]
IPEndPoint EndPoint => info.EndPoint;
[MemoryPackInclude]
long LastTicks => info.LastTicks;
[MemoryPackConstructor]
SerializableRelayServerNodeReportInfo(
string id, string name,
int maxConnection, double maxBandwidth, double maxBandwidthTotal,
double maxGbTotal, ulong maxGbTotalLastBytes,
double connectionRatio, double bandwidthRatio,
bool Public, int delay,
IPEndPoint endPoint, long lastTicks)
{
var info = new RelayServerNodeReportInfo
{
BandwidthRatio = bandwidthRatio,
ConnectionRatio = connectionRatio,
Delay = delay,
EndPoint = endPoint,
Id = id,
LastTicks = lastTicks,
MaxBandwidth = maxBandwidth,
MaxBandwidthTotal = maxBandwidthTotal,
MaxConnection = maxConnection,
MaxGbTotal = maxGbTotal,
MaxGbTotalLastBytes = maxGbTotalLastBytes,
Name = name,
Public = Public,
};
this.info = info;
}
public SerializableRelayServerNodeReportInfo(RelayServerNodeReportInfo info)
{
this.info = info;
}
}
public class RelayServerNodeReportInfoFormatter : MemoryPackFormatter<RelayServerNodeReportInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerNodeReportInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayServerNodeReportInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerNodeReportInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableRelayServerNodeReportInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableRelayAskResultInfo
{
[MemoryPackIgnore]
public readonly RelayAskResultInfo info;
[MemoryPackInclude]
ulong FlowingId => info.FlowingId;
[MemoryPackInclude]
List<RelayServerNodeReportInfo> Nodes => info.Nodes;
[MemoryPackConstructor]
SerializableRelayAskResultInfo(ulong flowingId, List<RelayServerNodeReportInfo> nodes)
{
var info = new RelayAskResultInfo { FlowingId = flowingId, Nodes = nodes };
this.info = info;
}
public SerializableRelayAskResultInfo(RelayAskResultInfo info)
{
this.info = info;
}
}
public class RelayAskResultInfoFormatter : MemoryPackFormatter<RelayAskResultInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayAskResultInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayAskResultInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayAskResultInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableRelayAskResultInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableRelayCacheInfo
{
[MemoryPackIgnore]
public readonly RelayCacheInfo info;
[MemoryPackInclude]
ulong FlowId => info.FlowId;
[MemoryPackInclude]
string FromId => info.FromId;
[MemoryPackInclude]
string FromName => info.FromName;
[MemoryPackInclude]
string ToId => info.ToId;
[MemoryPackInclude]
string ToName => info.ToName;
[MemoryPackInclude]
string GroupId => info.GroupId;
[MemoryPackConstructor]
SerializableRelayCacheInfo(ulong flowId, string fromId, string fromName, string toId, string toName, string groupId)
{
var info = new RelayCacheInfo
{
FlowId = flowId,
FromId = fromId,
FromName = fromName,
GroupId = groupId,
ToId = toId,
ToName = toName,
};
this.info = info;
}
public SerializableRelayCacheInfo(RelayCacheInfo info)
{
this.info = info;
}
}
public class RelayCacheInfoFormatter : MemoryPackFormatter<RelayCacheInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayCacheInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayCacheInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayCacheInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableRelayCacheInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableRelayMessageInfo
{
[MemoryPackIgnore]
public readonly RelayMessageInfo info;
[MemoryPackInclude]
RelayMessengerType Type => info.Type;
[MemoryPackInclude]
ulong FlowId => info.FlowId;
[MemoryPackInclude]
string FromId => info.FromId;
[MemoryPackInclude]
string ToId => info.ToId;
[MemoryPackInclude]
string NodeId => info.NodeId;
[MemoryPackConstructor]
SerializableRelayMessageInfo(RelayMessengerType type, ulong flowId, string fromId, string toId, string nodeId)
{
var info = new RelayMessageInfo
{
Type = type,
FlowId = flowId,
FromId = fromId,
ToId = toId,
NodeId = nodeId
};
this.info = info;
}
public SerializableRelayMessageInfo(RelayMessageInfo info)
{
this.info = info;
}
}
public class RelayMessageInfoFormatter : MemoryPackFormatter<RelayMessageInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayMessageInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayMessageInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayMessageInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableRelayMessageInfo>();
value = wrapped.info;
}
}
}

View File

@@ -1,11 +1,15 @@
using linker.config;
using linker.messenger.relay.client;
using linker.messenger.relay.client.transport;
using linker.messenger.relay.server;
using linker.messenger.relay.server.caching;
using linker.messenger.relay.server.validator;
using linker.plugins.relay.client;
using linker.plugins.relay.client.transport;
using linker.plugins.relay.messenger;
using linker.plugins.relay.server;
using linker.plugins.relay.server.caching;
using linker.plugins.relay.server.validator;
using linker.startup;
using MemoryPack;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.relay
@@ -26,50 +30,68 @@ namespace linker.plugins.relay
public void AddClient(ServiceCollection serviceCollection, FileConfig config)
{
serviceCollection.AddSingleton<RelayClientTransportSelfHost>();
serviceCollection.AddSingleton<RelayClientTransfer>();
serviceCollection.AddSingleton<PlusRelayClientMessenger>();
serviceCollection.AddSingleton<IRelayClientStore, PlusRelayClientStore>();
MemoryPackFormatterProvider.Register(new RelayTestInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerNodeReportInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayAskResultInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayCacheInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayMessageInfoFormatter());
serviceCollection.AddSingleton<RelayApiController>();
serviceCollection.AddSingleton<RelayClientMessenger>();
serviceCollection.AddSingleton<TransportSelfHost>();
serviceCollection.AddSingleton<RelayTransfer>();
serviceCollection.AddSingleton<RelayTestTransfer>();
serviceCollection.AddSingleton<RelayClientTestTransfer>();
serviceCollection.AddSingleton<RelayClientTypesLoader>();
serviceCollection.AddSingleton<RelaConfigSyncSecretKey>();
serviceCollection.AddSingleton<RelayTypesLoader>();
serviceCollection.AddSingleton<RelayClientConfigTransfer>();
}
public void AddServer(ServiceCollection serviceCollection, FileConfig config)
{
serviceCollection.AddSingleton<RelayServerMessenger>();
serviceCollection.AddSingleton<RelayResolver>();
serviceCollection.AddSingleton<RelayReportResolver>();
serviceCollection.AddSingleton<RelayServerMasterTransfer>();
serviceCollection.AddSingleton<RelayServerNodeTransfer>();
serviceCollection.AddSingleton<IRelayCaching, RelayCachingMemory>();
serviceCollection.AddSingleton<IRelayServerCaching, RelayServerCachingMemory>();
serviceCollection.AddSingleton<RelayServerValidatorTransfer>();
serviceCollection.AddSingleton<IRelayServerNodeStore, PlusRelayServerNodeStore>();
serviceCollection.AddSingleton<IRelayServerMasterStore, PlusRelayServerMasterStore>();
serviceCollection.AddSingleton<RelayValidatorTransfer>();
serviceCollection.AddSingleton<RelayValidatorTypeLoader>();
serviceCollection.AddSingleton<PlusRelayServerMessenger>();
serviceCollection.AddSingleton<PlusRelayServerResolver>();
serviceCollection.AddSingleton<PlusRelayServerReportResolver>();
serviceCollection.AddSingleton<RelayValidatorSecretKey>();
MemoryPackFormatterProvider.Register(new RelayTestInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerNodeReportInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayAskResultInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayCacheInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayMessageInfoFormatter());
serviceCollection.AddSingleton<RelayServerValidatorTypeLoader>();
serviceCollection.AddSingleton<RelayServerValidatorSecretKey>();
serviceCollection.AddSingleton<RelayServerConfigTransfer>();
}
public void UseClient(ServiceProvider serviceProvider, FileConfig config)
{
RelayTransfer relayTransfer = serviceProvider.GetService<RelayTransfer>();
RelayTypesLoader relayTypesLoader = serviceProvider.GetService<RelayTypesLoader>();
RelayClientTransfer relayTransfer = serviceProvider.GetService<RelayClientTransfer>();
RelayClientTypesLoader relayTypesLoader = serviceProvider.GetService<RelayClientTypesLoader>();
}
public void UseServer(ServiceProvider serviceProvider, FileConfig config)
{
RelayValidatorTypeLoader relayValidatorTypeLoader = serviceProvider.GetService<RelayValidatorTypeLoader>();
IRelayCaching relayCaching = serviceProvider.GetService<IRelayCaching>();
RelayServerValidatorTypeLoader relayValidatorTypeLoader = serviceProvider.GetService<RelayServerValidatorTypeLoader>();
IRelayServerCaching relayCaching = serviceProvider.GetService<IRelayServerCaching>();
RelayReportResolver relayReportResolver = serviceProvider.GetService<RelayReportResolver>();
PlusRelayServerReportResolver relayReportResolver = serviceProvider.GetService<PlusRelayServerReportResolver>();
RelayServerMasterTransfer relayServerMasterTransfer = serviceProvider.GetService<RelayServerMasterTransfer>();

View File

@@ -0,0 +1,42 @@
using linker.messenger;
using linker.messenger.relay.client;
using linker.messenger.relay.client.transport;
using linker.plugins.client;
using linker.plugins.resolver;
using System.Security.Cryptography.X509Certificates;
namespace linker.plugins.relay.client
{
public class PlusRelayClientStore : IRelayClientStore
{
public byte Flag => (byte)(ResolverType.Relay);
public X509Certificate2 Certificate => certificate;
public IConnection SigninConnection => clientSignInState.Connection;
public string SecretKey => relayClientConfigTransfer.Server.SecretKey;
public bool Disabled => relayClientConfigTransfer.Server.Disabled;
public bool SSL => relayClientConfigTransfer.Server.SSL;
public RelayClientType RelayType => relayClientConfigTransfer.Server.RelayType;
private readonly X509Certificate2 certificate = null;
private readonly RelayClientConfigTransfer relayClientConfigTransfer;
private readonly ClientSignInState clientSignInState;
public PlusRelayClientStore(RelayClientConfigTransfer relayClientConfigTransfer, ClientSignInState clientSignInState, ClientConfigTransfer clientConfigTransfer)
{
this.relayClientConfigTransfer = relayClientConfigTransfer;
this.clientSignInState = clientSignInState;
string path = Path.GetFullPath(clientConfigTransfer.SSL.File);
if (File.Exists(path))
{
certificate = new X509Certificate2(path, clientConfigTransfer.SSL.Password, X509KeyStorageFlags.Exportable);
}
}
}
}

View File

@@ -1,6 +1,8 @@
using linker.config;
using linker.libs.api;
using linker.libs.extends;
using linker.messenger.relay.client;
using linker.messenger.relay.server;
using linker.plugins.capi;
namespace linker.plugins.relay.client
@@ -10,11 +12,11 @@ namespace linker.plugins.relay.client
/// </summary>
public sealed class RelayApiController : IApiClientController
{
private readonly RelayTestTransfer relayTestTransfer;
private readonly RelayTransfer relayTransfer;
private readonly RelayClientTestTransfer relayTestTransfer;
private readonly RelayClientTransfer relayTransfer;
private readonly RelayClientConfigTransfer relayClientConfigTransfer;
public RelayApiController(RelayTestTransfer relayTestTransfer, RelayTransfer relayTransfer, RelayClientConfigTransfer relayClientConfigTransfer)
public RelayApiController(RelayClientTestTransfer relayTestTransfer, RelayClientTransfer relayTransfer, RelayClientConfigTransfer relayClientConfigTransfer)
{
this.relayTestTransfer = relayTestTransfer;
this.relayTransfer = relayTransfer;
@@ -34,7 +36,7 @@ namespace linker.plugins.relay.client
return true;
}
public List<RelayNodeReportInfo> Subscribe(ApiControllerParamsInfo param)
public List<RelayServerNodeReportInfo> Subscribe(ApiControllerParamsInfo param)
{
relayTestTransfer.Subscribe();
return relayTestTransfer.Nodes;

View File

@@ -1,7 +1,8 @@
using linker.config;
using linker.libs;
using linker.libs;
using linker.messenger.relay.client;
using linker.messenger.relay.client.transport;
using linker.messenger.relay.server;
using linker.plugins.client;
using linker.plugins.relay.client.transport;
using System.Net;
using System.Net.NetworkInformation;
@@ -10,16 +11,16 @@ namespace linker.plugins.relay.client
/// <summary>
/// 中继
/// </summary>
public sealed class RelayTestTransfer
public sealed class RelayClientTestTransfer
{
private readonly RelayTransfer relayTransfer;
private readonly RelayClientTransfer relayTransfer;
private readonly ClientSignInState clientSignInState;
private readonly ClientConfigTransfer clientConfigTransfer;
private readonly RelayClientConfigTransfer relayClientConfigTransfer;
public List<RelayNodeReportInfo> Nodes { get; private set; } = new List<RelayNodeReportInfo>();
public List<RelayServerNodeReportInfo> Nodes { get; private set; } = new List<RelayServerNodeReportInfo>();
public RelayTestTransfer( RelayTransfer relayTransfer, ClientSignInState clientSignInState, ClientConfigTransfer clientConfigTransfer, RelayClientConfigTransfer relayClientConfigTransfer)
public RelayClientTestTransfer(RelayClientTransfer relayTransfer, ClientSignInState clientSignInState, ClientConfigTransfer clientConfigTransfer, RelayClientConfigTransfer relayClientConfigTransfer)
{
this.relayTransfer = relayTransfer;
this.clientSignInState = clientSignInState;
@@ -39,7 +40,7 @@ namespace linker.plugins.relay.client
{
try
{
ITransport transport = relayTransfer.Transports.FirstOrDefault(d => d.Type == relayClientConfigTransfer.Server.RelayType);
IRelayClientTransport transport = relayTransfer.Transports.FirstOrDefault(d => d.Type == relayClientConfigTransfer.Server.RelayType);
if (transport != null)
{
Nodes = await transport.RelayTestAsync(new RelayTestInfo

View File

@@ -0,0 +1,18 @@
using linker.libs;
using linker.messenger.relay.client;
using linker.messenger.relay.client.transport;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.relay.client
{
public sealed partial class RelayClientTypesLoader
{
public RelayClientTypesLoader(RelayClientTransfer relayTransfer, ServiceProvider serviceProvider)
{
var types = GetSourceGeneratorTypes();
var transports = types.Select(c => (IRelayClientTransport)serviceProvider.GetService(c)).Where(c => c != null).ToList();
relayTransfer.LoadTransports(transports);
LoggerHelper.Instance.Info($"load relay transport:{string.Join(",", transports.Select(c => c.GetType().Name))}");
}
}
}

View File

@@ -1,17 +0,0 @@
using linker.libs;
using linker.plugins.relay.client.transport;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.relay.client
{
public sealed partial class RelayTypesLoader
{
public RelayTypesLoader(RelayTransfer relayTransfer, ServiceProvider serviceProvider)
{
var types = GetSourceGeneratorTypes();
var transports = types.Select(c => (ITransport)serviceProvider.GetService(c)).Where(c => c != null).ToList();
relayTransfer.LoadTransports(transports);
LoggerHelper.Instance.Info($"load relay transport:{string.Join(",", transports.Select(c => c.GetType().Name))}");
}
}
}

View File

@@ -1,6 +1,7 @@
using linker.libs;
using linker.libs.extends;
using linker.plugins.relay.client.transport;
using linker.messenger.relay.client.transport;
using linker.messenger.relay.server;
using MemoryPack;
using System.Net;
@@ -51,104 +52,14 @@ namespace linker.config
#else
public string SecretKey { get; set; } = Guid.NewGuid().ToString().ToUpper();
#endif
public DistributedInfo Distributed { get; set; } = new DistributedInfo { };
}
public sealed class DistributedInfo
{
public RelayNodeInfo Node { get; set; } = new RelayNodeInfo { };
public RelayMasterInfo Master { get; set; } = new RelayMasterInfo { };
public RelayServerNodeInfo Node { get; set; } = new RelayServerNodeInfo { };
public RelayServerMasterInfo Master { get; set; } = new RelayServerMasterInfo { };
}
public sealed class RelayMasterInfo
{
#if DEBUG
public string SecretKey { get; set; } = Helper.GlobalString;
#else
public string SecretKey { get; set; } = Guid.NewGuid().ToString().ToUpper();
#endif
}
public sealed class RelayNodeInfo
{
public const string MASTER_NODE_ID = "824777CF-2804-83FE-DE71-69B7B7D3BBA7";
private string id = Guid.NewGuid().ToString().ToUpper();
public string Id
{
get => id; set
{
id = value.SubStr(0, 36);
}
}
private string name = Dns.GetHostName().SubStr(0, 12);
public string Name
{
get => name; set
{
name = value.SubStr(0, 12);
}
}
public string Host { get; set; } = string.Empty;
public int MaxConnection { get; set; } = 100;
public double MaxBandwidth { get; set; } = 1;
public double MaxBandwidthTotal { get; set; }
public double MaxGbTotal { get; set; }
public ulong MaxGbTotalLastBytes { get; set; }
public int MaxGbTotalMonth { get; set; }
public bool Public { get; set; }
public string MasterHost { get; set; } = string.Empty;
#if DEBUG
public string MasterSecretKey { get; set; } = Helper.GlobalString;
#else
public string MasterSecretKey { get; set; } = string.Empty;
#endif
}
[MemoryPackable]
public sealed partial class RelayNodeReportInfo
{
public string Id { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public int MaxConnection { get; set; }
public double MaxBandwidth { get; set; }
public double MaxBandwidthTotal { get; set; }
public double MaxGbTotal { get; set; }
public ulong MaxGbTotalLastBytes { get; set; }
public double ConnectionRatio { get; set; }
public double BandwidthRatio { get; set; }
public bool Public { get; set; }
public int Delay { get; set; }
[MemoryPackAllowSerialize]
public IPEndPoint EndPoint { get; set; }
public long LastTicks { get; set; }
}
[MemoryPackable]
public sealed partial class RelayNodeDelayInfo
{
public string Id { get; set; } = string.Empty;
public int Delay { get; set; }
[MemoryPackAllowSerialize]
public IPAddress IP { get; set; }
}
[MemoryPackable]
public sealed partial class RelayNodeDelayWrapInfo
{
public string MachineId { get; set; } = string.Empty;
public Dictionary<string, RelayNodeDelayInfo> Nodes { get; set; }
}
/// <summary>
/// 中继服务器
/// </summary>
@@ -169,7 +80,7 @@ namespace linker.config
/// </summary>
public bool SSL { get; set; } = true;
public RelayType RelayType { get; set; } = RelayType.Linker;
public RelayClientType RelayType { get; set; } = RelayClientType.Linker;
}
}

View File

@@ -0,0 +1,33 @@
using linker.libs;
using linker.messenger;
using linker.messenger.signin;
using linker.messenger.relay.messenger;
using linker.messenger.relay.client;
using linker.messenger.relay.server;
using linker.messenger.relay.server.validator;
namespace linker.plugins.relay.messenger
{
/// <summary>
/// 中继客户端
/// </summary>
public sealed class PlusRelayClientMessenger : RelayClientMessenger, IMessenger
{
private readonly RelayClientTransfer relayTransfer;
public PlusRelayClientMessenger(RelayClientTransfer relayTransfer, ISerializer serializer) : base(relayTransfer, serializer)
{
this.relayTransfer = relayTransfer;
}
}
/// <summary>
/// 中继服务端
/// </summary>
public sealed class PlusRelayServerMessenger : RelayServerMessenger, IMessenger
{
public PlusRelayServerMessenger(IMessengerSender messengerSender, SignCaching signCaching, RelayServerMasterTransfer relayServerTransfer, RelayServerValidatorTransfer relayValidatorTransfer, ISerializer serializer)
: base(messengerSender, signCaching, relayServerTransfer, relayValidatorTransfer, serializer)
{
}
}
}

View File

@@ -0,0 +1,18 @@
using linker.messenger.relay.server;
using linker.plugins.resolver;
using linker.plugins.server;
namespace linker.plugins.relay.server
{
public sealed class PlusRelayServerMasterStore : IRelayServerMasterStore
{
public RelayServerMasterInfo Master => relayServerConfigTransfer.Master;
private readonly RelayServerConfigTransfer relayServerConfigTransfer;
public PlusRelayServerMasterStore(RelayServerConfigTransfer relayServerConfigTransfer)
{
this.relayServerConfigTransfer = relayServerConfigTransfer;
}
}
}

View File

@@ -0,0 +1,38 @@
using linker.messenger.relay.server;
using linker.plugins.resolver;
using linker.plugins.server;
namespace linker.plugins.relay.server
{
public sealed class PlusRelayServerNodeStore : IRelayServerNodeStore
{
public byte Flag => (byte)ResolverType.RelayReport;
public int ServicePort => serverConfigTransfer.Port;
public RelayServerNodeInfo Node => relayServerConfigTransfer.Node;
private readonly RelayServerConfigTransfer relayServerConfigTransfer;
private readonly ServerConfigTransfer serverConfigTransfer;
public PlusRelayServerNodeStore(RelayServerConfigTransfer relayServerConfigTransfer, ServerConfigTransfer serverConfigTransfer)
{
this.relayServerConfigTransfer = relayServerConfigTransfer;
this.serverConfigTransfer = serverConfigTransfer;
}
public void Confirm()
{
relayServerConfigTransfer.Update();
}
public void SetMaxGbTotalLastBytes(ulong value)
{
relayServerConfigTransfer.SetMaxGbTotalLastBytes(value);
}
public void SetMaxGbTotalMonth(int month)
{
relayServerConfigTransfer.SetMaxGbTotalMonth(month);
}
}
}

View File

@@ -0,0 +1,15 @@
using linker.messenger.relay.server;
using linker.plugins.resolver;
namespace linker.plugins.relay.server
{
public class PlusRelayServerReportResolver : RelayServerReportResolver, IResolver
{
public ResolverType Type => ResolverType.RelayReport;
public PlusRelayServerReportResolver(RelayServerMasterTransfer relayServerTransfer):base(relayServerTransfer)
{
}
}
}

View File

@@ -0,0 +1,18 @@
using linker.plugins.resolver;
using linker.libs;
using linker.messenger.relay.server;
namespace linker.plugins.relay.server
{
/// <summary>
/// 中继连接处理
/// </summary>
public class PlusRelayServerResolver : RelayServerResolver, IResolver
{
public ResolverType Type => ResolverType.Relay;
public PlusRelayServerResolver(RelayServerNodeTransfer relayServerNodeTransfer,ISerializer serializer):base(relayServerNodeTransfer, serializer)
{
}
}
}

View File

@@ -1,12 +1,13 @@
using linker.config;
using linker.messenger.relay.server;
namespace linker.plugins.relay.server
{
public sealed class RelayServerConfigTransfer
{
public string SecretKey => config.Data.Server.Relay.SecretKey;
public RelayNodeInfo Node=> config.Data.Server.Relay.Distributed.Node;
public RelayMasterInfo Master => config.Data.Server.Relay.Distributed.Master;
public RelayServerNodeInfo Node=> config.Data.Server.Relay.Distributed.Node;
public RelayServerMasterInfo Master => config.Data.Server.Relay.Distributed.Master;
private readonly FileConfig config;

View File

@@ -1,40 +0,0 @@
using linker.config;
using linker.messenger.signin;
using RelayInfo = linker.plugins.relay.client.transport.RelayInfo;
namespace linker.plugins.relay.server.validator
{
public interface IRelayValidator
{
/// <summary>
/// 验证
/// </summary>
/// <param name="relayInfo">中继信息</param>
/// <param name="fromMachine">来源客户端</param>
/// <param name="toMachine">目标客户端可能为null</param>
/// <returns></returns>
public Task<string> Validate(RelayInfo relayInfo, SignCacheInfo fromMachine, SignCacheInfo toMachine);
}
public sealed class RelayValidatorSecretKey : IRelayValidator
{
private readonly FileConfig fileConfig;
private readonly RelayServerConfigTransfer relayServerConfigTransfer;
public RelayValidatorSecretKey(FileConfig fileConfig, RelayServerConfigTransfer relayServerConfigTransfer)
{
this.fileConfig = fileConfig;
this.relayServerConfigTransfer = relayServerConfigTransfer;
}
public async Task<string> Validate(RelayInfo relayInfo, SignCacheInfo fromMachine, SignCacheInfo toMachine)
{
if (relayInfo.SecretKey != relayServerConfigTransfer.SecretKey)
{
return $"SecretKey validate fail";
}
await Task.CompletedTask;
return string.Empty;
}
}
}

View File

@@ -0,0 +1,28 @@
using linker.config;
using linker.messenger.relay.server.validator;
using linker.messenger.signin;
namespace linker.plugins.relay.server.validator
{
public sealed class RelayServerValidatorSecretKey : IRelayServerValidator
{
private readonly FileConfig fileConfig;
private readonly RelayServerConfigTransfer relayServerConfigTransfer;
public RelayServerValidatorSecretKey(FileConfig fileConfig, RelayServerConfigTransfer relayServerConfigTransfer)
{
this.fileConfig = fileConfig;
this.relayServerConfigTransfer = relayServerConfigTransfer;
}
public async Task<string> Validate(linker.messenger.relay.client.transport.RelayInfo relayInfo, SignCacheInfo fromMachine, SignCacheInfo toMachine)
{
if (relayInfo.SecretKey != relayServerConfigTransfer.SecretKey)
{
return $"SecretKey validate fail";
}
await Task.CompletedTask;
return string.Empty;
}
}
}

View File

@@ -1,14 +1,15 @@
using linker.libs;
using linker.messenger.relay.server.validator;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.relay.server.validator
{
public sealed partial class RelayValidatorTypeLoader
public sealed partial class RelayServerValidatorTypeLoader
{
public RelayValidatorTypeLoader(RelayValidatorTransfer relayValidatorTransfer, ServiceProvider serviceProvider)
public RelayServerValidatorTypeLoader(RelayServerValidatorTransfer relayValidatorTransfer, ServiceProvider serviceProvider)
{
var types = GetSourceGeneratorTypes();
var validators = types.Select(c => (IRelayValidator)serviceProvider.GetService(c)).Where(c => c != null).ToList();
var validators = types.Select(c => (IRelayServerValidator)serviceProvider.GetService(c)).Where(c => c != null).ToList();
relayValidatorTransfer.LoadValidators(validators);
LoggerHelper.Instance.Info($"load relay validators:{string.Join(",", validators.Select(c => c.GetType().Name))}");

View File

@@ -22,6 +22,8 @@ namespace linker.plugins.signin
public void AddClient(ServiceCollection serviceCollection, FileConfig config)
{
serviceCollection.AddSingleton<SignInArgsTransfer>();
MemoryPackFormatterProvider.Register(new SignInfoFormatter());
MemoryPackFormatterProvider.Register(new SignCacheInfoFormatter());
MemoryPackFormatterProvider.Register(new SignInListRequestInfoFormatter());
@@ -34,15 +36,17 @@ namespace linker.plugins.signin
serviceCollection.AddSingleton<PlusSignInClientMessenger>();
serviceCollection.AddSingleton<SignInArgsTransfer>();
serviceCollection.AddSingleton<SignInArgsTypesLoader>();
serviceCollection.AddSingleton<SignInArgsMachineKeyClient>();
serviceCollection.AddSingleton<SignInClientApiController>();
}
public void AddServer(ServiceCollection serviceCollection, FileConfig config)
{
serviceCollection.AddSingleton<SignCaching>();
serviceCollection.AddSingleton<SignInArgsTransfer>();
MemoryPackFormatterProvider.Register(new SignInfoFormatter());
MemoryPackFormatterProvider.Register(new SignCacheInfoFormatter());
MemoryPackFormatterProvider.Register(new SignInListRequestInfoFormatter());
@@ -52,16 +56,13 @@ namespace linker.plugins.signin
MemoryPackFormatterProvider.Register(new SignInIdsResponseItemInfoFormatter());
MemoryPackFormatterProvider.Register(new SignInResponseInfoFormatter());
serviceCollection.AddSingleton<SignCaching>();
serviceCollection.AddSingleton<SignInServerMessenger>();
serviceCollection.AddSingleton<ISignInStore, SignInStore>();
serviceCollection.AddSingleton<ISignInStore, SignInStore>();
serviceCollection.AddSingleton<PlusSignInServerMessenger>();
serviceCollection.AddSingleton<SignInArgsTransfer>();
serviceCollection.AddSingleton<SignInArgsTypesLoader>();
serviceCollection.AddSingleton<SignInArgsMachineKeyServer>();
serviceCollection.AddSingleton<SignInConfigTransfer>();
}

View File

@@ -1,5 +1,4 @@
using linker.config;
using linker.tunnel;
using linker.tunnel;
using linker.tunnel.connection;
using linker.libs;
using linker.libs.socks5;
@@ -13,6 +12,7 @@ using linker.plugins.socks5.config;
using System.Text;
using linker.plugins.relay.client;
using linker.plugins.pcp;
using linker.messenger.relay.client;
namespace linker.plugins.socks5
{
@@ -27,7 +27,7 @@ namespace linker.plugins.socks5
protected override string TransactionId => "socks5";
public TunnelProxy(ClientConfigTransfer clientConfigTransfer, TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, PcpTransfer pcpTransfer, ClientSignInTransfer clientSignInTransfer, ClientSignInState clientSignInState, RelayClientConfigTransfer relayClientConfigTransfer)
public TunnelProxy(ClientConfigTransfer clientConfigTransfer, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, ClientSignInTransfer clientSignInTransfer, ClientSignInState clientSignInState, RelayClientConfigTransfer relayClientConfigTransfer)
: base(tunnelTransfer, relayTransfer, pcpTransfer, clientSignInTransfer, clientSignInState, clientConfigTransfer, relayClientConfigTransfer)
{
this.clientSignInTransfer = clientSignInTransfer;

View File

@@ -1,46 +0,0 @@
using linker.tunnel.transport;
using linker.libs;
using linker.plugins.client;
using linker.tunnel.wanport;
using linker.tunnel;
using linker.messenger;
using linker.messenger.tunnel;
namespace linker.plugins.tunnel
{
public sealed class PlusTunnelAdapter : TunnelMessengerAdapter
{
private readonly ClientConfigTransfer clientConfigTransfer;
private readonly TunnelConfigTransfer tunnelConfigTransfer;
public PlusTunnelAdapter(ClientSignInState clientSignInState, IMessengerSender messengerSender,
TunnelExcludeIPTransfer excludeIPTransfer, ClientConfigTransfer clientConfigTransfer, TunnelConfigTransfer tunnelConfigTransfer,
TunnelWanPortTransfer tunnelWanPortTransfer, TunnelUpnpTransfer tunnelUpnpTransfer, TunnelTransfer tunnelTransfer, ISerializer serializer)
: base(messengerSender, excludeIPTransfer, tunnelWanPortTransfer, tunnelUpnpTransfer, tunnelTransfer, serializer)
{
this.clientConfigTransfer = clientConfigTransfer;
this.tunnelConfigTransfer = tunnelConfigTransfer;
clientSignInState.NetworkEnabledHandle += (times) => RefreshPortMap(tunnelConfigTransfer.PortMapLan, tunnelConfigTransfer.PortMapWan);
tunnelConfigTransfer.OnChanged += () => RefreshPortMap(tunnelConfigTransfer.PortMapLan, tunnelConfigTransfer.PortMapWan);
this.GetSignConnection = () => clientSignInState.Connection;
this.GetNetwork = GetLocalConfig;
this.Certificate = () => tunnelConfigTransfer.Certificate;
this.GetTunnelTransports = () => tunnelConfigTransfer.Transports;
this.SetTunnelTransports = (list, update) => tunnelConfigTransfer.SetTransports(list);
}
private NetworkInfo GetLocalConfig()
{
return new NetworkInfo
{
LocalIps = tunnelConfigTransfer.LocalIPs,
RouteLevel = tunnelConfigTransfer.RouteLevel,
MachineId = clientConfigTransfer.Id
};
}
}
}

View File

@@ -10,10 +10,8 @@ namespace linker.plugins.tunnel
{
public ResolverType Type => ResolverType.External;
private readonly TunnelExternalResolver tunnelExternalResolver;
public PlusTunnelExternalResolver(TunnelExternalResolver tunnelExternalResolver)
public PlusTunnelExternalResolver()
{
this.tunnelExternalResolver = tunnelExternalResolver;
}
}
}

View File

@@ -0,0 +1,48 @@
using linker.tunnel.transport;
using linker.plugins.client;
using linker.messenger;
using linker.messenger.tunnel;
using System.Security.Cryptography.X509Certificates;
namespace linker.plugins.tunnel
{
public sealed class PlusTunnelMessengerAdapterStore : ITunnelMessengerAdapterStore
{
public IConnection SignConnection => clientSignInState.Connection;
public NetworkInfo Network => GetLocalConfig();
public X509Certificate2 Certificate => tunnelConfigTransfer.Certificate;
public List<TunnelTransportItemInfo> TunnelTransports => tunnelConfigTransfer.Transports;
private readonly ClientSignInState clientSignInState;
private readonly ClientConfigTransfer clientConfigTransfer;
private readonly TunnelConfigTransfer tunnelConfigTransfer;
public PlusTunnelMessengerAdapterStore(ClientSignInState clientSignInState, ClientConfigTransfer clientConfigTransfer, TunnelConfigTransfer tunnelConfigTransfer, TunnelMessengerAdapter tunnelMessengerAdapter)
{
this.clientSignInState = clientSignInState;
this.clientConfigTransfer = clientConfigTransfer;
this.tunnelConfigTransfer = tunnelConfigTransfer;
clientSignInState.NetworkEnabledHandle += (times) => tunnelMessengerAdapter.RefreshPortMap(tunnelConfigTransfer.PortMapLan, tunnelConfigTransfer.PortMapWan);
tunnelConfigTransfer.OnChanged += () => tunnelMessengerAdapter.RefreshPortMap(tunnelConfigTransfer.PortMapLan, tunnelConfigTransfer.PortMapWan);
}
public bool SetTunnelTransports(List<TunnelTransportItemInfo> list)
{
tunnelConfigTransfer.SetTransports(list);
return true;
}
private NetworkInfo GetLocalConfig()
{
return new NetworkInfo
{
LocalIps = tunnelConfigTransfer.LocalIPs,
RouteLevel = tunnelConfigTransfer.RouteLevel,
MachineId = clientConfigTransfer.Id
};
}
}
}

View File

@@ -6,6 +6,7 @@ using linker.tunnel.connection;
using System.Collections.Concurrent;
using linker.plugins.relay.client;
using linker.plugins.pcp;
using linker.messenger.relay.client;
namespace linker.plugins.tunnel
{
@@ -16,14 +17,14 @@ namespace linker.plugins.tunnel
protected readonly ConcurrentDictionary<string, ITunnelConnection> connections = new ConcurrentDictionary<string, ITunnelConnection>();
private readonly TunnelTransfer tunnelTransfer;
private readonly RelayTransfer relayTransfer;
private readonly RelayClientTransfer relayTransfer;
private readonly PcpTransfer pcpTransfer;
private readonly ClientSignInTransfer clientSignInTransfer;
private readonly ClientSignInState clientSignInState;
private readonly ClientConfigTransfer clientConfigTransfer;
private readonly RelayClientConfigTransfer relayClientConfigTransfer;
public TunnelBase(TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, PcpTransfer pcpTransfer, ClientSignInTransfer clientSignInTransfer, ClientSignInState clientSignInState, ClientConfigTransfer clientConfigTransfer, RelayClientConfigTransfer relayClientConfigTransfer)
public TunnelBase(TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, ClientSignInTransfer clientSignInTransfer, ClientSignInState clientSignInState, ClientConfigTransfer clientConfigTransfer, RelayClientConfigTransfer relayClientConfigTransfer)
{
this.tunnelTransfer = tunnelTransfer;
this.relayTransfer = relayTransfer;

View File

@@ -26,31 +26,33 @@ namespace linker.plugins.tunnel
public void AddClient(ServiceCollection serviceCollection, FileConfig config)
{
//序列化扩展
MemoryPackFormatterProvider.Register(new TunnelTransportWanPortInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelTransportItemInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelTransportInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelWanPortProtocolInfoFormatter());
//管理接口
serviceCollection.AddSingleton<TunnelApiController>();
//命令接口
serviceCollection.AddSingleton<PlusTunnelClientMessenger>();
//外网端口协议
serviceCollection.AddSingleton<TunnelWanPortTransfer>();
//打洞协议
serviceCollection.AddSingleton<TunnelTransfer>();
serviceCollection.AddSingleton<TunnelUpnpTransfer>();
serviceCollection.AddSingleton<TunnelExcludeIPTransfer>();
//序列化扩展
MemoryPackFormatterProvider.Register(new TunnelTransportWanPortInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelTransportItemInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelTransportInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelWanPortProtocolInfoFormatter());
//命令接口
serviceCollection.AddSingleton<PlusTunnelClientMessenger>();
serviceCollection.AddSingleton<ITunnelMessengerAdapterStore, PlusTunnelMessengerAdapterStore>();
serviceCollection.AddSingleton<TunnelExcludeIPTypesLoader>();
serviceCollection.AddSingleton<TunnelConfigTransfer>();
serviceCollection.AddSingleton<TunnelConfigSyncTransports>();
serviceCollection.AddSingleton<TunnelDecenter>();
//管理接口
serviceCollection.AddSingleton<TunnelApiController>();
serviceCollection.AddSingleton<PlusTunnelAdapter>();
}
public void AddServer(ServiceCollection serviceCollection, FileConfig config)
@@ -62,7 +64,6 @@ namespace linker.plugins.tunnel
serviceCollection.AddSingleton<PlusTunnelServerMessenger>();
serviceCollection.AddSingleton<PlusTunnelExternalResolver, PlusTunnelExternalResolver>();
serviceCollection.AddSingleton<TunnelExternalResolver>();
}
public void UseClient(ServiceProvider serviceProvider, FileConfig config)
@@ -73,7 +74,7 @@ namespace linker.plugins.tunnel
ClientConfigTransfer clientConfigTransfer = serviceProvider.GetService<ClientConfigTransfer>();
TunnelConfigTransfer tunnelConfigTransfer = serviceProvider.GetService<TunnelConfigTransfer>();
PlusTunnelAdapter tunnelAdapter = serviceProvider.GetService<PlusTunnelAdapter>();
ITunnelMessengerAdapterStore tunnelAdapter = serviceProvider.GetService<ITunnelMessengerAdapterStore>();
LoggerHelper.Instance.Info($"tunnel route level getting.");
tunnelConfigTransfer.RefreshRouteLevel();

View File

@@ -10,6 +10,7 @@ using linker.plugins.tunnel;
using System.Buffers;
using linker.plugins.relay.client;
using linker.plugins.pcp;
using linker.messenger.relay.client;
namespace linker.plugins.tuntap
{
@@ -29,7 +30,7 @@ namespace linker.plugins.tuntap
protected override string TransactionId => "tuntap";
public TuntapProxy(ClientConfigTransfer clientConfigTransfer,
TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, PcpTransfer pcpTransfer,
TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer,
ClientSignInTransfer clientSignInTransfer, TuntapTransfer tuntapTransfer, ClientSignInState clientSignInState,
RelayClientConfigTransfer relayClientConfigTransfer, TuntapConfigTransfer tuntapConfigTransfer)
: base(tunnelTransfer, relayTransfer, pcpTransfer, clientSignInTransfer, clientSignInState, clientConfigTransfer, relayClientConfigTransfer)

View File

@@ -1,5 +1,5 @@
v1.6.4
2024-12-18 17:41:47
2024-12-19 17:21:14
1. 优化UI显示网络计算IP数
2. 修复内网穿透不停止直接删除导致的无法再次添加的问题
3. 优化网卡的端口转发