整理代码

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> { private List<GeneratorInfo> generators = new List<GeneratorInfo> {
new GeneratorInfo{ ClassName="linker.plugins.flow.FlowTypesLoader", InterfaceName="linker.plugins.flow.IFlow" }, 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.client.RelayClientTypesLoader", InterfaceName="linker.messenger.relay.client.transport.IRelayClientTransport" },
new GeneratorInfo{ ClassName="linker.plugins.relay.server.validator.RelayValidatorTypeLoader", InterfaceName="linker.plugins.relay.server.validator.IRelayValidator" }, 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.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.resolver.ResolverTypesLoader", InterfaceName="linker.plugins.resolver.IResolver" },
new GeneratorInfo{ ClassName="linker.plugins.tunnel.TunnelExcludeIPTypesLoader", InterfaceName="linker.messenger.tunnel.ITunnelExcludeIP" }, 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.messenger.relay.client.transport;
using linker.plugins.relay.client.transport;
using linker.tunnel.connection; using linker.tunnel.connection;
using linker.libs; using linker.libs;
using linker.libs.extends; using linker.libs.extends;
using System.Collections.Concurrent; using System.Collections.Concurrent;
namespace linker.plugins.relay.client namespace linker.messenger.relay.client
{ {
/// <summary> /// <summary>
/// 中继 /// 中继
/// </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 ConcurrentDictionary<string, bool> connectingDic = new ConcurrentDictionary<string, bool>();
private Dictionary<string, List<Action<ITunnelConnection>>> OnConnected { get; } = new Dictionary<string, List<Action<ITunnelConnection>>>(); private Dictionary<string, List<Action<ITunnelConnection>>> OnConnected { get; } = new Dictionary<string, List<Action<ITunnelConnection>>>();
private readonly RelayClientConfigTransfer relayClientConfigTransfer; private readonly IRelayClientStore relayClientStore;
public RelayTransfer(RelayClientConfigTransfer relayClientConfigTransfer) public RelayClientTransfer(IRelayClientStore relayClientStore)
{ {
this.relayClientConfigTransfer = relayClientConfigTransfer; this.relayClientStore = relayClientStore;
} }
public void LoadTransports(List<ITransport> list) public void LoadTransports(List<IRelayClientTransport> list)
{ {
Transports = list; Transports = list;
} }
@@ -69,7 +68,7 @@ namespace linker.plugins.relay.client
} }
try 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) if (transport == null)
{ {
return null; return null;
@@ -82,10 +81,10 @@ namespace linker.plugins.relay.client
FromMachineName = string.Empty, FromMachineName = string.Empty,
RemoteMachineId = remoteMachineId, RemoteMachineId = remoteMachineId,
RemoteMachineName = string.Empty, RemoteMachineName = string.Empty,
SecretKey = relayClientConfigTransfer.Server.SecretKey, SecretKey = relayClientStore.SecretKey,
TransactionId = transactionId, TransactionId = transactionId,
TransportName = transport.Name, TransportName = transport.Name,
SSL = relayClientConfigTransfer.Server.SSL, SSL = relayClientStore.SSL,
NodeId = nodeId NodeId = nodeId
}; };
@@ -131,7 +130,7 @@ namespace linker.plugins.relay.client
try try
{ {
ITransport _transports = Transports.FirstOrDefault(c => c.Name == relayInfo.TransportName); IRelayClientTransport _transports = Transports.FirstOrDefault(c => c.Name == relayInfo.TransportName);
if (_transports == null) return false; if (_transports == null) return false;
await _transports.OnBeginAsync(relayInfo, (connection) => await _transports.OnBeginAsync(relayInfo, (connection) =>

View File

@@ -1,18 +1,17 @@
using linker.config; using linker.messenger.relay.server;
using linker.tunnel.connection; using linker.tunnel.connection;
using MemoryPack;
using System.Net; 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, Linker = 0,
} }
/// <summary> /// <summary>
/// 中继接口 /// 中继接口
/// </summary> /// </summary>
public interface ITransport public interface IRelayClientTransport
{ {
/// <summary> /// <summary>
/// 接口名 /// 接口名
@@ -21,7 +20,7 @@ namespace linker.plugins.relay.client.transport
/// <summary> /// <summary>
/// 中继类型 /// 中继类型
/// </summary> /// </summary>
public RelayType Type { get; } public RelayClientType Type { get; }
/// <summary> /// <summary>
/// 协议 /// 协议
/// </summary> /// </summary>
@@ -44,26 +43,22 @@ namespace linker.plugins.relay.client.transport
/// </summary> /// </summary>
/// <param name="relayTestInfo"></param> /// <param name="relayTestInfo"></param>
/// <returns></returns> /// <returns></returns>
public Task<List<RelayNodeReportInfo>> RelayTestAsync(RelayTestInfo relayTestInfo); public Task<List<RelayServerNodeReportInfo>> RelayTestAsync(RelayTestInfo relayTestInfo);
} }
/// <summary> /// <summary>
/// 中继测试 /// 中继测试
/// </summary> /// </summary>
[MemoryPackable]
public sealed partial class RelayTestInfo public sealed partial class RelayTestInfo
{ {
public string MachineId { get; set; } public string MachineId { get; set; }
public string SecretKey { get; set; } public string SecretKey { get; set; }
[MemoryPackAllowSerialize]
public IPEndPoint Server { get; set; } public IPEndPoint Server { get; set; }
} }
/// <summary> /// <summary>
/// 中继交换数据 /// 中继交换数据
/// </summary> /// </summary>
[MemoryPackable]
public sealed partial class RelayInfo public sealed partial class RelayInfo
{ {
/// <summary> /// <summary>
@@ -107,7 +102,6 @@ namespace linker.plugins.relay.client.transport
/// <summary> /// <summary>
/// 服务器a端选择用什么服务器就带给bb直接用不需要再做复杂的选择 /// 服务器a端选择用什么服务器就带给bb直接用不需要再做复杂的选择
/// </summary> /// </summary>
[MemoryPackAllowSerialize]
public IPEndPoint Server { get; set; } public IPEndPoint Server { get; set; }
/// <summary> /// <summary>
@@ -115,4 +109,5 @@ namespace linker.plugins.relay.client.transport
/// </summary> /// </summary>
public bool SSL { get; set; } = true; 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.tunnel.connection;
using linker.libs; using linker.libs;
using linker.libs.extends; using linker.libs.extends;
using MemoryPack;
using System.Net; using System.Net;
using System.Net.Security; using System.Net.Security;
using System.Net.Sockets; using System.Net.Sockets;
using System.Security.Authentication; using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using linker.plugins.messenger;
using linker.plugins.client;
using System.Buffers; using System.Buffers;
using linker.plugins.relay.server; using linker.messenger.relay.server;
using linker.plugins.resolver;
using System.Net.NetworkInformation;
using linker.messenger;
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 string Name => "Linker";
public RelayType Type => RelayType.Linker; public RelayClientType Type => RelayClientType.Linker;
public TunnelProtocolType ProtocolType => TunnelProtocolType.Tcp; public TunnelProtocolType ProtocolType => TunnelProtocolType.Tcp;
private readonly IMessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly ClientSignInState clientSignInState; private readonly ISerializer serializer;
private readonly IRelayClientStore relayClientStore;
private X509Certificate2 certificate; public RelayClientTransportSelfHost(IMessengerSender messengerSender, ISerializer serializer, IRelayClientStore relayClientStore)
public TransportSelfHost(IMessengerSender messengerSender, ClientSignInState clientSignInState, ClientConfigTransfer clientConfigTransfer)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.clientSignInState = clientSignInState; this.serializer = serializer;
this.relayClientStore = relayClientStore;
string path = Path.GetFullPath(clientConfigTransfer.SSL.File);
if (File.Exists(path))
{
certificate = new X509Certificate2(path, clientConfigTransfer.SSL.Password, X509KeyStorageFlags.Exportable);
}
} }
public async Task<ITunnelConnection> RelayAsync(RelayInfo relayInfo) public async Task<ITunnelConnection> RelayAsync(RelayInfo relayInfo)
@@ -128,9 +114,9 @@ namespace linker.plugins.relay.client.transport
{ {
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{ {
Connection = clientSignInState.Connection, Connection = relayClientStore.SigninConnection,
MessengerId = (ushort)RelayMessengerIds.RelayAsk, MessengerId = (ushort)RelayMessengerIds.RelayAsk,
Payload = MemoryPackSerializer.Serialize(relayInfo), Payload = serializer.Serialize(relayInfo),
Timeout = 2000 Timeout = 2000
}).ConfigureAwait(false); }).ConfigureAwait(false);
if (resp.Code != MessageResponeCodes.OK) if (resp.Code != MessageResponeCodes.OK)
@@ -138,66 +124,12 @@ namespace linker.plugins.relay.client.transport
return new RelayAskResultInfo(); return new RelayAskResultInfo();
} }
RelayAskResultInfo result = MemoryPackSerializer.Deserialize<RelayAskResultInfo>(resp.Data.Span); RelayAskResultInfo result = serializer.Deserialize<RelayAskResultInfo>(resp.Data.Span);
return result; return result;
} }
private async Task<List<RelayNodeReportInfo>> TestDelay(List<RelayNodeReportInfo> list) private async Task<Socket> ConnectNodeServer(RelayInfo relayInfo, List<RelayServerNodeReportInfo> nodes)
{
//测试前几个就行了
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)
{ {
byte[] buffer = ArrayPool<byte>.Shared.Rent(1 * 1024); byte[] buffer = ArrayPool<byte>.Shared.Rent(1 * 1024);
@@ -210,7 +142,7 @@ namespace linker.plugins.relay.client.transport
IPEndPoint ep = node.EndPoint; IPEndPoint ep = node.EndPoint;
if (ep == null || ep.Address.Equals(IPAddress.Any)) if (ep == null || ep.Address.Equals(IPAddress.Any))
{ {
ep = clientSignInState.Connection.Address; ep = relayClientStore.SigninConnection.Address;
} }
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) 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); await socket.ConnectAsync(ep).WaitAsync(TimeSpan.FromMilliseconds(5000)).ConfigureAwait(false);
//建立关联 //建立关联
RelayMessage relayMessage = new RelayMessage RelayMessageInfo relayMessage = new RelayMessageInfo
{ {
FlowId = relayInfo.FlowingId, FlowId = relayInfo.FlowingId,
Type = RelayMessengerType.Ask, Type = RelayMessengerType.Ask,
@@ -230,8 +162,9 @@ namespace linker.plugins.relay.client.transport
ToId = relayInfo.RemoteMachineId, ToId = relayInfo.RemoteMachineId,
NodeId = node.Id, NodeId = node.Id,
}; };
await socket.SendAsync(new byte[] { (byte)ResolverType.Relay }); if (relayClientStore.Flag > 0)
await socket.SendAsync(MemoryPackSerializer.Serialize(relayMessage)); 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}"); 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 var resp = await messengerSender.SendReply(new MessageRequestWrap
{ {
Connection = clientSignInState.Connection, Connection = relayClientStore.SigninConnection,
MessengerId = (ushort)RelayMessengerIds.RelayForward, MessengerId = (ushort)RelayMessengerIds.RelayForward,
Payload = MemoryPackSerializer.Serialize(relayInfo), Payload = serializer.Serialize(relayInfo),
}); });
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray); return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
} }
@@ -291,13 +224,13 @@ namespace linker.plugins.relay.client.transport
{ {
try 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 socket = new Socket(ep.AddressFamily, SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
socket.KeepAlive(); socket.KeepAlive();
await socket.ConnectAsync(ep).WaitAsync(TimeSpan.FromMilliseconds(5000)).ConfigureAwait(false); await socket.ConnectAsync(ep).WaitAsync(TimeSpan.FromMilliseconds(5000)).ConfigureAwait(false);
RelayMessage relayMessage = new RelayMessage RelayMessageInfo relayMessage = new RelayMessageInfo
{ {
FlowId = relayInfo.FlowingId, FlowId = relayInfo.FlowingId,
Type = RelayMessengerType.Answer, Type = RelayMessengerType.Answer,
@@ -305,8 +238,9 @@ namespace linker.plugins.relay.client.transport
ToId = relayInfo.RemoteMachineId, ToId = relayInfo.RemoteMachineId,
NodeId = relayInfo.NodeId, NodeId = relayInfo.NodeId,
}; };
await socket.SendAsync(new byte[] { (byte)ResolverType.Relay }); if (relayClientStore.Flag > 0)
await socket.SendAsync(MemoryPackSerializer.Serialize(relayMessage)); await socket.SendAsync(new byte[] { relayClientStore.Flag });
await socket.SendAsync(serializer.Serialize(relayMessage));
_ = WaitSSL(socket, relayInfo).ContinueWith((result) => _ = WaitSSL(socket, relayInfo).ContinueWith((result) =>
{ {
@@ -333,14 +267,8 @@ namespace linker.plugins.relay.client.transport
SslStream sslStream = null; SslStream sslStream = null;
if (relayInfo.SSL) if (relayInfo.SSL)
{ {
if (certificate == null)
{
LoggerHelper.Instance.Error($"need ssl");
socket.SafeClose();
return null;
}
sslStream = new SslStream(new NetworkStream(socket, false), false); 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 return new TunnelConnectionTcp
{ {
@@ -371,27 +299,27 @@ namespace linker.plugins.relay.client.transport
return null; return null;
} }
public async Task<List<RelayNodeReportInfo>> RelayTestAsync(RelayTestInfo relayTestInfo) public async Task<List<RelayServerNodeReportInfo>> RelayTestAsync(RelayTestInfo relayTestInfo)
{ {
try try
{ {
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{ {
Connection = clientSignInState.Connection, Connection = relayClientStore.SigninConnection,
MessengerId = (ushort)RelayMessengerIds.RelayTest, MessengerId = (ushort)RelayMessengerIds.RelayTest,
Payload = MemoryPackSerializer.Serialize(relayTestInfo), Payload = serializer.Serialize(relayTestInfo),
Timeout = 2000 Timeout = 2000
}).ConfigureAwait(false); }).ConfigureAwait(false);
if (resp.Code == MessageResponeCodes.OK) if (resp.Code == MessageResponeCodes.OK)
{ {
return MemoryPackSerializer.Deserialize<List<RelayNodeReportInfo>>(resp.Data.Span); return serializer.Deserialize<List<RelayServerNodeReportInfo>>(resp.Data.Span);
} }
} }
catch (Exception) 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 linker.libs;
using MemoryPack; using linker.messenger.relay.client;
using linker.plugins.relay.client; using linker.messenger.relay.server;
using linker.plugins.relay.server.validator;
using linker.plugins.relay.server;
using System.Net.NetworkInformation;
using linker.messenger;
using linker.messenger.signin; using linker.messenger.signin;
using linker.messenger.relay.server.validator;
namespace linker.plugins.relay.messenger namespace linker.messenger.relay.messenger
{ {
/// <summary> /// <summary>
/// 中继客户端 /// 中继客户端
/// </summary> /// </summary>
public sealed class RelayClientMessenger : IMessenger public class RelayClientMessenger : IMessenger
{ {
private readonly RelayTransfer relayTransfer; private readonly RelayClientTransfer relayTransfer;
public RelayClientMessenger(RelayTransfer relayTransfer) private readonly ISerializer serializer;
public RelayClientMessenger(RelayClientTransfer relayTransfer, ISerializer serializer)
{ {
this.relayTransfer = relayTransfer; this.relayTransfer = relayTransfer;
this.serializer = serializer;
} }
/// <summary> /// <summary>
@@ -30,52 +29,30 @@ namespace linker.plugins.relay.messenger
[MessengerId((ushort)RelayMessengerIds.Relay)] [MessengerId((ushort)RelayMessengerIds.Relay)]
public async Task Relay(IConnection connection) 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); bool res = await relayTransfer.OnBeginAsync(info).ConfigureAwait(false);
connection.Write(res ? Helper.TrueArray : Helper.FalseArray); 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>
/// 中继服务端 /// 中继服务端
/// </summary> /// </summary>
public sealed class RelayServerMessenger : IMessenger public class RelayServerMessenger : IMessenger
{ {
private readonly FileConfig config;
private readonly IMessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly SignCaching signCaching; private readonly SignCaching signCaching;
private readonly RelayServerMasterTransfer relayServerTransfer; private readonly RelayServerMasterTransfer relayServerTransfer;
private readonly RelayValidatorTransfer relayValidatorTransfer; private readonly RelayServerValidatorTransfer relayValidatorTransfer;
private readonly ISerializer serializer;
public RelayServerMessenger(IMessengerSender messengerSender, SignCaching signCaching, RelayServerMasterTransfer relayServerTransfer, RelayServerValidatorTransfer relayValidatorTransfer, ISerializer serializer)
public RelayServerMessenger(FileConfig config, IMessengerSender messengerSender, SignCaching signCaching, RelayServerMasterTransfer relayServerTransfer, RelayValidatorTransfer relayValidatorTransfer)
{ {
this.config = config;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.signCaching = signCaching; this.signCaching = signCaching;
this.relayServerTransfer = relayServerTransfer; this.relayServerTransfer = relayServerTransfer;
this.relayValidatorTransfer = relayValidatorTransfer; this.relayValidatorTransfer = relayValidatorTransfer;
this.serializer = serializer;
} }
/// <summary> /// <summary>
@@ -85,7 +62,7 @@ namespace linker.plugins.relay.messenger
[MessengerId((ushort)RelayMessengerIds.RelayTest)] [MessengerId((ushort)RelayMessengerIds.RelayTest)]
public async Task RelayTest(IConnection connection) 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) if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false)
{ {
connection.Write(Helper.FalseArray); connection.Write(Helper.FalseArray);
@@ -101,7 +78,7 @@ namespace linker.plugins.relay.messenger
}, cache, null); }, cache, null);
var nodes = relayServerTransfer.GetNodes(string.IsNullOrWhiteSpace(result)); 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)] [MessengerId((ushort)RelayMessengerIds.RelayAsk)]
public async Task RelayAsk(IConnection connection) 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) 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; return;
} }
@@ -133,7 +110,7 @@ namespace linker.plugins.relay.messenger
result.FlowingId = relayServerTransfer.AddRelay(cacheFrom.MachineId, cacheFrom.MachineName, cacheTo.MachineId, cacheTo.MachineName, cacheFrom.GroupId); 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> /// <summary>
@@ -144,7 +121,7 @@ namespace linker.plugins.relay.messenger
[MessengerId((ushort)RelayMessengerIds.RelayForward)] [MessengerId((ushort)RelayMessengerIds.RelayForward)]
public async Task RelayForward(IConnection connection) 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) 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); connection.Write(Helper.FalseArray);
@@ -176,7 +153,7 @@ namespace linker.plugins.relay.messenger
{ {
Connection = cacheTo.Connection, Connection = cacheTo.Connection,
MessengerId = (ushort)RelayMessengerIds.Relay, MessengerId = (ushort)RelayMessengerIds.Relay,
Payload = MemoryPackSerializer.Serialize(info) Payload = serializer.Serialize(info)
}).ConfigureAwait(false); }).ConfigureAwait(false);
if (resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray)) if (resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray))
{ {
@@ -190,59 +167,5 @@ namespace linker.plugins.relay.messenger
connection.Write(Helper.FalseArray); 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 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.libs; using linker.messenger.relay.server.caching;
using linker.plugins.relay.server.caching;
using MemoryPack;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Net; using System.Net;
namespace linker.plugins.relay.server namespace linker.messenger.relay.server
{ {
public class RelayServerMasterTransfer public class RelayServerMasterTransfer
{ {
private ulong relayFlowingId = 0; private ulong relayFlowingId = 0;
private readonly IRelayCaching relayCaching;
private readonly ICrypto crypto; 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; 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); ulong flowingId = Interlocked.Increment(ref relayFlowingId);
RelayCache cache = new RelayCache RelayCacheInfo cache = new RelayCacheInfo
{ {
FlowId = flowingId, FlowId = flowingId,
FromId = fromid, FromId = fromid,
@@ -46,9 +44,9 @@ namespace linker.plugins.relay.server
public Memory<byte> TryGetRelayCache(string key) 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 bytes;
} }
return Helper.EmptyArray; return Helper.EmptyArray;
@@ -66,9 +64,9 @@ namespace linker.plugins.relay.server
if (crypto == null) return; if (crypto == null) return;
data = crypto.Decode(data.ToArray()); 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); relayNodeReportInfo.EndPoint = new IPEndPoint(IPAddress.Any, 0);
} }
@@ -88,7 +86,7 @@ namespace linker.plugins.relay.server
/// </summary> /// </summary>
/// <param name="validated">是否已认证</param> /// <param name="validated">是否已认证</param>
/// <returns></returns> /// <returns></returns>
public List<RelayNodeReportInfo> GetNodes(bool validated) public List<RelayServerNodeReportInfo> GetNodes(bool validated)
{ {
var result = reports.Values var result = reports.Values
.Where(c => c.Public || (c.Public == false && validated)) .Where(c => c.Public || (c.Public == false && validated))
@@ -113,7 +111,7 @@ namespace linker.plugins.relay.server
/// <returns></returns> /// <returns></returns>
public bool NodeValidate(string nodeId) 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.libs.extends;
using linker.plugins.relay.server.caching; using linker.messenger.relay.server.caching;
using linker.plugins.resolver;
using linker.plugins.server;
using MemoryPack;
using System.Buffers; using System.Buffers;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
namespace linker.plugins.relay.server namespace linker.messenger.relay.server
{ {
public class RelayServerNodeTransfer public class RelayServerNodeTransfer
{ {
private uint connectionNum = 0; 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 cryptoNode;
private readonly ICrypto cryptoMaster; private readonly ICrypto cryptoMaster;
private ulong bytes = 0; private ulong bytes = 0;
private ulong lastBytes = 0; private ulong lastBytes = 0;
RelaySpeedLimit limitTotal = new RelaySpeedLimit(); 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.relayCaching = relayCaching;
this.fileConfig = fileConfig; this.relayServerNodeStore = relayServerNodeStore;
this.relayServerConfigTransfer = relayServerConfigTransfer; this.relayServerMasterStore = relayServerMasterStore;
this.serverConfigTransfer = serverConfigTransfer;
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); cryptoNode = CryptoFactory.CreateSymmetric(relayServerNodeStore.Node.MasterSecretKey);
cryptoMaster = CryptoFactory.CreateSymmetric(relayServerConfigTransfer.Master.SecretKey); cryptoMaster = CryptoFactory.CreateSymmetric(relayServerMasterStore.Master.SecretKey);
ReportTask(); 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); byte[] buffer = ArrayPool<byte>.Shared.Rent(2 * 1024);
try try
{ {
IPEndPoint server = nodeid == RelayNodeInfo.MASTER_NODE_ID IPEndPoint server = nodeid == RelayServerNodeInfo.MASTER_NODE_ID
? new IPEndPoint(IPAddress.Loopback, serverConfigTransfer.Port) ? new IPEndPoint(IPAddress.Loopback, relayServerNodeStore.ServicePort)
: await NetworkHelper.GetEndPointAsync(relayServerConfigTransfer.Node.MasterHost, 1802); : await NetworkHelper.GetEndPointAsync(relayServerNodeStore.Node.MasterHost, 1802);
ICrypto crypto = nodeid == RelayNodeInfo.MASTER_NODE_ID ? cryptoMaster : cryptoNode; ICrypto crypto = nodeid == RelayServerNodeInfo.MASTER_NODE_ID ? cryptoMaster : cryptoNode;
Socket socket = new Socket(server.AddressFamily, SocketType.Stream, ProtocolType.Tcp); Socket socket = new Socket(server.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
long start = Environment.TickCount64; long start = Environment.TickCount64;
await socket.ConnectAsync(server).ConfigureAwait(false); await socket.ConnectAsync(server).ConfigureAwait(false);
long time = Environment.TickCount64 - start; 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()); 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); int length = await socket.ReceiveAsync(buffer.AsMemory(), SocketFlags.None).AsTask().WaitAsync(TimeSpan.FromMilliseconds(Math.Max(time * 2, 5000))).ConfigureAwait(false);
socket.SafeClose(); 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; return result;
} }
catch (Exception ex) catch (Exception ex)
@@ -106,9 +101,9 @@ namespace linker.plugins.relay.server
/// <returns></returns> /// <returns></returns>
public bool ValidateConnection() 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) 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; return res;
} }
@@ -119,11 +114,11 @@ namespace linker.plugins.relay.server
/// <returns></returns> /// <returns></returns>
public bool ValidateBytes() public bool ValidateBytes()
{ {
bool res = relayServerConfigTransfer.Node.MaxGbTotal == 0 bool res = relayServerNodeStore.Node.MaxGbTotal == 0
|| (relayServerConfigTransfer.Node.MaxGbTotal > 0 && relayServerConfigTransfer.Node.MaxGbTotalLastBytes > 0); || (relayServerNodeStore.Node.MaxGbTotal > 0 && relayServerNodeStore.Node.MaxGbTotalLastBytes > 0);
if (res == false && LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) 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; return res;
} }
@@ -135,15 +130,15 @@ namespace linker.plugins.relay.server
public bool AddBytes(ulong length) public bool AddBytes(ulong length)
{ {
bytes += length; bytes += length;
if (relayServerConfigTransfer.Node.MaxGbTotal == 0) if (relayServerNodeStore.Node.MaxGbTotal == 0)
{ {
return true; return true;
} }
if (relayServerConfigTransfer.Node.MaxGbTotalLastBytes >= length) if (relayServerNodeStore.Node.MaxGbTotalLastBytes >= length)
relayServerConfigTransfer.SetMaxGbTotalLastBytes(relayServerConfigTransfer.Node.MaxGbTotalLastBytes - length); relayServerNodeStore.SetMaxGbTotalLastBytes(relayServerNodeStore.Node.MaxGbTotalLastBytes - length);
else relayServerConfigTransfer.SetMaxGbTotalLastBytes(0); else relayServerNodeStore.SetMaxGbTotalLastBytes(0);
return relayServerConfigTransfer.Node.MaxGbTotalLastBytes > 0; return relayServerNodeStore.Node.MaxGbTotalLastBytes > 0;
} }
/// <summary> /// <summary>
@@ -152,7 +147,7 @@ namespace linker.plugins.relay.server
/// <returns></returns> /// <returns></returns>
public uint GetBandwidthLimit() 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> /// <summary>
/// 是否需要总限速 /// 是否需要总限速
@@ -175,12 +170,12 @@ namespace linker.plugins.relay.server
private void ResetBytes() private void ResetBytes()
{ {
if (relayServerConfigTransfer.Node.MaxGbTotalMonth != DateTime.Now.Month) if (relayServerNodeStore.Node.MaxGbTotalMonth != DateTime.Now.Month)
{ {
relayServerConfigTransfer.SetMaxGbTotalMonth(DateTime.Now.Month); relayServerNodeStore.SetMaxGbTotalMonth(DateTime.Now.Month);
relayServerConfigTransfer.SetMaxGbTotalLastBytes((ulong)(relayServerConfigTransfer.Node.MaxGbTotal * 1024 * 1024 * 1024)); relayServerNodeStore.SetMaxGbTotalLastBytes((ulong)(relayServerNodeStore.Node.MaxGbTotal * 1024 * 1024 * 1024));
} }
relayServerConfigTransfer.Update(); relayServerNodeStore.Confirm();
} }
private void ReportTask() private void ReportTask()
@@ -188,14 +183,14 @@ namespace linker.plugins.relay.server
TimerHelper.SetInterval(async () => TimerHelper.SetInterval(async () =>
{ {
ResetBytes(); ResetBytes();
IEnumerable<RelayNodeInfo> nodes = new List<RelayNodeInfo> IEnumerable<RelayServerNodeInfo> nodes = new List<RelayServerNodeInfo>
{ {
//默认报告给自己,作为本服务器的一个默认中继节点 //默认报告给自己,作为本服务器的一个默认中继节点
new RelayNodeInfo{ new RelayServerNodeInfo{
Id = RelayNodeInfo.MASTER_NODE_ID, Id = RelayServerNodeInfo.MASTER_NODE_ID,
Host = new IPEndPoint(IPAddress.Any,serverConfigTransfer.Port).ToString(), Host = new IPEndPoint(IPAddress.Any, relayServerNodeStore.ServicePort).ToString(),
MasterHost = new IPEndPoint(IPAddress.Loopback,serverConfigTransfer.Port).ToString(), MasterHost = new IPEndPoint(IPAddress.Loopback, relayServerNodeStore.ServicePort).ToString(),
MasterSecretKey = relayServerConfigTransfer.Master.SecretKey, MasterSecretKey = relayServerMasterStore.Master.SecretKey,
MaxBandwidth = 0, MaxBandwidth = 0,
MaxConnection = 0, MaxConnection = 0,
MaxBandwidthTotal=0, MaxBandwidthTotal=0,
@@ -206,7 +201,7 @@ namespace linker.plugins.relay.server
Public = false Public = false
}, },
//配置的中继节点 //配置的中继节点
relayServerConfigTransfer.Node relayServerNodeStore.Node
}.Where(c => string.IsNullOrWhiteSpace(c.MasterHost) == false && string.IsNullOrWhiteSpace(c.MasterSecretKey) == false) }.Where(c => string.IsNullOrWhiteSpace(c.MasterHost) == false && string.IsNullOrWhiteSpace(c.MasterSecretKey) == false)
.Where(c => string.IsNullOrWhiteSpace(c.Name) == false && string.IsNullOrWhiteSpace(c.Id) == false); .Where(c => string.IsNullOrWhiteSpace(c.Name) == false && string.IsNullOrWhiteSpace(c.Id) == false);
@@ -217,10 +212,10 @@ namespace linker.plugins.relay.server
{ {
try try
{ {
ICrypto crypto = node.Id == RelayNodeInfo.MASTER_NODE_ID ? cryptoMaster : cryptoNode; ICrypto crypto = node.Id == RelayServerNodeInfo.MASTER_NODE_ID ? cryptoMaster : cryptoNode;
IPEndPoint endPoint = await NetworkHelper.GetEndPointAsync(node.Host, serverConfigTransfer.Port) ?? new IPEndPoint(IPAddress.Any, serverConfigTransfer.Port); 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, Id = node.Id,
Name = node.Name, Name = node.Name,
@@ -235,11 +230,11 @@ namespace linker.plugins.relay.server
EndPoint = endPoint, 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]; byte[] data = new byte[content.Length + 1];
data[0] = (byte)ResolverType.RelayReport; data[0] = relayServerNodeStore.Flag;
content.AsMemory().CopyTo(data.AsMemory(1)); content.AsMemory().CopyTo(data.AsMemory(1));
using UdpClient udpClient = new UdpClient(AddressFamily.InterNetwork); using UdpClient udpClient = new UdpClient(AddressFamily.InterNetwork);

View File

@@ -1,17 +1,14 @@
using linker.libs.extends; using linker.libs.extends;
using linker.plugins.resolver;
using System.Buffers; using System.Buffers;
using System.Net; using System.Net;
using System.Net.Sockets; 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; private readonly RelayServerMasterTransfer relayServerTransfer;
public RelayReportResolver(RelayServerMasterTransfer relayServerTransfer) public RelayServerReportResolver(RelayServerMasterTransfer relayServerTransfer)
{ {
this.relayServerTransfer = relayServerTransfer; this.relayServerTransfer = relayServerTransfer;
} }

View File

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

View File

@@ -1,19 +1,22 @@
using MemoryPack; using linker.libs;
using Microsoft.Extensions.Caching.Memory; 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"; public string Name => "memory";
private readonly IMemoryCache cache = new MemoryCache(new MemoryCacheOptions { }); 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) 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; return true;
} }
@@ -22,7 +25,7 @@ namespace linker.plugins.relay.server.caching
bool result = cache.TryGetValue(key, out byte[] bytes); bool result = cache.TryGetValue(key, out byte[] bytes);
if (result) if (result)
value = MemoryPackSerializer.Deserialize<T>(bytes); value = serializer.Deserialize<T>(bytes);
else value = default; else value = default;
return true; 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.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; 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"); if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"{ep} get udp external port");
AddReceive((ulong)memory.Length); AddReceive((ulong)memory.Length);
byte[] sendData = ArrayPool<byte>.Shared.Rent(20); byte[] sendData = ArrayPool<byte>.Shared.Rent(1024);
try try
{ {
var send = BuildSendData(sendData, ep); var send = BuildSendData(sendData, ep);

View File

@@ -9,33 +9,37 @@ using System.Security.Cryptography.X509Certificates;
namespace linker.plugins.tunnel 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>
/// 打洞信标适配 /// 打洞信标适配
/// </summary> /// </summary>
public class TunnelMessengerAdapter 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 IMessengerSender messengerSender;
private readonly TunnelExcludeIPTransfer excludeIPTransfer; private readonly TunnelExcludeIPTransfer excludeIPTransfer;
@@ -50,7 +54,9 @@ namespace linker.plugins.tunnel
private readonly ISerializer serializer; 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.messengerSender = messengerSender;
this.excludeIPTransfer = excludeIPTransfer; this.excludeIPTransfer = excludeIPTransfer;
@@ -61,6 +67,8 @@ namespace linker.plugins.tunnel
this.serializer = serializer; this.serializer = serializer;
this.tunnelMessengerAdapterStore = tunnelMessengerAdapterStore;
//加载外网端口 //加载外网端口
tunnelWanPortTransfer.LoadTransports(new List<ITunnelWanPortProtocol> tunnelWanPortTransfer.LoadTransports(new List<ITunnelWanPortProtocol>
{ {
@@ -68,11 +76,11 @@ namespace linker.plugins.tunnel
new TunnelWanPortProtocolLinkerTcp(), new TunnelWanPortProtocolLinkerTcp(),
}); });
tunnelTransfer.LocalIP = () => { IConnection connection = GetSignConnection(); return connection?.LocalAddress.Address ?? IPAddress.Any; }; tunnelTransfer.LocalIP = () => tunnelMessengerAdapterStore.SignConnection?.LocalAddress.Address ?? IPAddress.Any; ;
tunnelTransfer.ServerHost = () => { IConnection connection = GetSignConnection(); return connection?.Address ?? null; }; tunnelTransfer.ServerHost = () => tunnelMessengerAdapterStore.SignConnection?.Address ?? null;
tunnelTransfer.Certificate = () => Certificate(); tunnelTransfer.Certificate = () => tunnelMessengerAdapterStore.Certificate;
tunnelTransfer.GetTunnelTransports = () => GetTunnelTransports(); tunnelTransfer.GetTunnelTransports = () => tunnelMessengerAdapterStore.TunnelTransports;
tunnelTransfer.SetTunnelTransports = (transports, update) => SetTunnelTransports(transports, update); tunnelTransfer.SetTunnelTransports = (transports, update) => tunnelMessengerAdapterStore.SetTunnelTransports(transports);
tunnelTransfer.GetLocalConfig = GetLocalConfig; tunnelTransfer.GetLocalConfig = GetLocalConfig;
tunnelTransfer.GetRemoteWanPort = GetRemoteWanPort; tunnelTransfer.GetRemoteWanPort = GetRemoteWanPort;
tunnelTransfer.SendConnectBegin = SendConnectBegin; tunnelTransfer.SendConnectBegin = SendConnectBegin;
@@ -96,7 +104,7 @@ namespace linker.plugins.tunnel
{ {
var excludeips = excludeIPTransfer.Get(); var excludeips = excludeIPTransfer.Get();
NetworkInfo networkInfo = GetNetwork(); NetworkInfo networkInfo = tunnelMessengerAdapterStore.Network;
networkInfo.LocalIps = networkInfo.LocalIps.Where(c => networkInfo.LocalIps = networkInfo.LocalIps.Where(c =>
{ {
if (c.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) if (c.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
@@ -122,7 +130,7 @@ namespace linker.plugins.tunnel
{ {
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{ {
Connection = GetSignConnection(), Connection = tunnelMessengerAdapterStore.SignConnection,
MessengerId = (ushort)TunnelMessengerIds.InfoForward, MessengerId = (ushort)TunnelMessengerIds.InfoForward,
Payload = serializer.Serialize(info) Payload = serializer.Serialize(info)
}).ConfigureAwait(false); }).ConfigureAwait(false);
@@ -136,7 +144,7 @@ namespace linker.plugins.tunnel
{ {
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{ {
Connection = GetSignConnection(), Connection = tunnelMessengerAdapterStore.SignConnection,
MessengerId = (ushort)TunnelMessengerIds.BeginForward, MessengerId = (ushort)TunnelMessengerIds.BeginForward,
Payload = serializer.Serialize(tunnelTransportInfo) Payload = serializer.Serialize(tunnelTransportInfo)
}).ConfigureAwait(false); }).ConfigureAwait(false);
@@ -146,7 +154,7 @@ namespace linker.plugins.tunnel
{ {
await messengerSender.SendOnly(new MessageRequestWrap await messengerSender.SendOnly(new MessageRequestWrap
{ {
Connection = GetSignConnection(), Connection = tunnelMessengerAdapterStore.SignConnection,
MessengerId = (ushort)TunnelMessengerIds.FailForward, MessengerId = (ushort)TunnelMessengerIds.FailForward,
Payload = serializer.Serialize(tunnelTransportInfo) Payload = serializer.Serialize(tunnelTransportInfo)
}).ConfigureAwait(false); }).ConfigureAwait(false);
@@ -156,7 +164,7 @@ namespace linker.plugins.tunnel
{ {
await messengerSender.SendOnly(new MessageRequestWrap await messengerSender.SendOnly(new MessageRequestWrap
{ {
Connection = GetSignConnection(), Connection = tunnelMessengerAdapterStore.SignConnection,
MessengerId = (ushort)TunnelMessengerIds.SuccessForward, MessengerId = (ushort)TunnelMessengerIds.SuccessForward,
Payload = serializer.Serialize(tunnelTransportInfo) Payload = serializer.Serialize(tunnelTransportInfo)
}).ConfigureAwait(false); }).ConfigureAwait(false);
@@ -178,10 +186,9 @@ namespace linker.plugins.tunnel
} }
else else
{ {
IConnection connection = GetSignConnection(); if (tunnelMessengerAdapterStore.SignConnection != null && tunnelMessengerAdapterStore.SignConnection.Connected)
if (connection != null && connection.Connected)
{ {
int ip = connection.LocalAddress.Address.GetAddressBytes()[3]; int ip = tunnelMessengerAdapterStore.SignConnection.LocalAddress.Address.GetAddressBytes()[3];
tunnelUpnpTransfer.SetMap(18180 + ip); tunnelUpnpTransfer.SetMap(18180 + ip);
_ = transportTcpPortMap.Listen(18180 + ip); _ = transportTcpPortMap.Listen(18180 + ip);

View File

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

View File

@@ -17,7 +17,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.messenger", "linker.
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.messenger.signin", "linker.signin\linker.messenger.signin.csproj", "{5B1F4754-D1B6-426B-B310-8C21F26879D2}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.messenger.signin", "linker.signin\linker.messenger.signin.csproj", "{5B1F4754-D1B6-426B-B310-8C21F26879D2}"
EndProject 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 EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution 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|x64.Build.0 = Release|Any CPU
{92582A55-8BBF-4B82-892D-75CEC8969EAF}.Release|x86.ActiveCfg = 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 {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 EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

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

View File

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

View File

@@ -1,9 +1,9 @@
using linker.config; using linker.config;
using linker.libs.extends; using linker.libs.extends;
using linker.messenger.signin; using linker.messenger.signin;
using linker.plugins.relay.server.validator;
using linker.plugins.sforward.config; using linker.plugins.sforward.config;
using linker.plugins.sforward.validator; using linker.plugins.sforward.validator;
using linker.messenger.relay.server.validator;
using System.Net; using System.Net;
using System.Text.Json.Nodes; 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 ActionTransfer actionTransfer;
private readonly FileConfig fileConfig; private readonly FileConfig fileConfig;
@@ -157,7 +157,7 @@ namespace linker.plugins.action
this.fileConfig = fileConfig; 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) if (string.IsNullOrWhiteSpace(actionTransfer.RelayActionUrl) == false)
{ {

View File

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

View File

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

View File

@@ -1,4 +1,5 @@
using linker.libs; using linker.libs;
using linker.messenger.relay.server;
using linker.plugins.relay.server; using linker.plugins.relay.server;
using MemoryPack; using MemoryPack;
using System.Text.Json.Serialization; 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; private readonly RelayReportFlow relayReportFlow;
public RelayReportResolverFlow(RelayReportFlow relayReportFlow, RelayServerMasterTransfer relayServerTransfer) : base(relayServerTransfer) 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; 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; this.relayFlow = relayFlow;
} }

View File

@@ -1,14 +1,12 @@
using linker.config; using linker.tunnel;
using linker.tunnel;
using linker.tunnel.connection; using linker.tunnel.connection;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Net; using System.Net;
using linker.plugins.client; using linker.plugins.client;
using linker.plugins.tunnel; using linker.plugins.tunnel;
using linker.plugins.messenger;
using linker.plugins.relay.client; using linker.plugins.relay.client;
using linker.client.config;
using linker.plugins.pcp; using linker.plugins.pcp;
using linker.messenger.relay.client;
namespace linker.plugins.forward.proxy namespace linker.plugins.forward.proxy
{ {
@@ -20,7 +18,7 @@ namespace linker.plugins.forward.proxy
protected override string TransactionId => "forward"; 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) : base(tunnelTransfer, relayTransfer, pcpTransfer, clientSignInTransfer, clientSignInState, clientConfigTransfer, relayClientConfigTransfer)
{ {
TaskUdp(); 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.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;
using linker.plugins.relay.client.transport;
using linker.plugins.relay.messenger; using linker.plugins.relay.messenger;
using linker.plugins.relay.server; using linker.plugins.relay.server;
using linker.plugins.relay.server.caching;
using linker.plugins.relay.server.validator; using linker.plugins.relay.server.validator;
using linker.startup; using linker.startup;
using MemoryPack;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.relay namespace linker.plugins.relay
@@ -26,50 +30,68 @@ namespace linker.plugins.relay
public void AddClient(ServiceCollection serviceCollection, FileConfig config) 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<RelayApiController>();
serviceCollection.AddSingleton<RelayClientMessenger>(); serviceCollection.AddSingleton<RelayClientTestTransfer>();
serviceCollection.AddSingleton<TransportSelfHost>(); serviceCollection.AddSingleton<RelayClientTypesLoader>();
serviceCollection.AddSingleton<RelayTransfer>();
serviceCollection.AddSingleton<RelayTestTransfer>();
serviceCollection.AddSingleton<RelaConfigSyncSecretKey>(); serviceCollection.AddSingleton<RelaConfigSyncSecretKey>();
serviceCollection.AddSingleton<RelayTypesLoader>();
serviceCollection.AddSingleton<RelayClientConfigTransfer>(); serviceCollection.AddSingleton<RelayClientConfigTransfer>();
} }
public void AddServer(ServiceCollection serviceCollection, FileConfig config) public void AddServer(ServiceCollection serviceCollection, FileConfig config)
{ {
serviceCollection.AddSingleton<RelayServerMessenger>();
serviceCollection.AddSingleton<RelayResolver>();
serviceCollection.AddSingleton<RelayReportResolver>();
serviceCollection.AddSingleton<RelayServerMasterTransfer>(); serviceCollection.AddSingleton<RelayServerMasterTransfer>();
serviceCollection.AddSingleton<RelayServerNodeTransfer>(); 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<PlusRelayServerMessenger>();
serviceCollection.AddSingleton<RelayValidatorTypeLoader>(); 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>(); serviceCollection.AddSingleton<RelayServerConfigTransfer>();
} }
public void UseClient(ServiceProvider serviceProvider, FileConfig config) public void UseClient(ServiceProvider serviceProvider, FileConfig config)
{ {
RelayTransfer relayTransfer = serviceProvider.GetService<RelayTransfer>(); RelayClientTransfer relayTransfer = serviceProvider.GetService<RelayClientTransfer>();
RelayTypesLoader relayTypesLoader = serviceProvider.GetService<RelayTypesLoader>(); RelayClientTypesLoader relayTypesLoader = serviceProvider.GetService<RelayClientTypesLoader>();
} }
public void UseServer(ServiceProvider serviceProvider, FileConfig config) public void UseServer(ServiceProvider serviceProvider, FileConfig config)
{ {
RelayValidatorTypeLoader relayValidatorTypeLoader = serviceProvider.GetService<RelayValidatorTypeLoader>(); RelayServerValidatorTypeLoader relayValidatorTypeLoader = serviceProvider.GetService<RelayServerValidatorTypeLoader>();
IRelayCaching relayCaching = serviceProvider.GetService<IRelayCaching>(); IRelayServerCaching relayCaching = serviceProvider.GetService<IRelayServerCaching>();
RelayReportResolver relayReportResolver = serviceProvider.GetService<RelayReportResolver>(); PlusRelayServerReportResolver relayReportResolver = serviceProvider.GetService<PlusRelayServerReportResolver>();
RelayServerMasterTransfer relayServerMasterTransfer = serviceProvider.GetService<RelayServerMasterTransfer>(); 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.config;
using linker.libs.api; using linker.libs.api;
using linker.libs.extends; using linker.libs.extends;
using linker.messenger.relay.client;
using linker.messenger.relay.server;
using linker.plugins.capi; using linker.plugins.capi;
namespace linker.plugins.relay.client namespace linker.plugins.relay.client
@@ -10,11 +12,11 @@ namespace linker.plugins.relay.client
/// </summary> /// </summary>
public sealed class RelayApiController : IApiClientController public sealed class RelayApiController : IApiClientController
{ {
private readonly RelayTestTransfer relayTestTransfer; private readonly RelayClientTestTransfer relayTestTransfer;
private readonly RelayTransfer relayTransfer; private readonly RelayClientTransfer relayTransfer;
private readonly RelayClientConfigTransfer relayClientConfigTransfer; private readonly RelayClientConfigTransfer relayClientConfigTransfer;
public RelayApiController(RelayTestTransfer relayTestTransfer, RelayTransfer relayTransfer, RelayClientConfigTransfer relayClientConfigTransfer) public RelayApiController(RelayClientTestTransfer relayTestTransfer, RelayClientTransfer relayTransfer, RelayClientConfigTransfer relayClientConfigTransfer)
{ {
this.relayTestTransfer = relayTestTransfer; this.relayTestTransfer = relayTestTransfer;
this.relayTransfer = relayTransfer; this.relayTransfer = relayTransfer;
@@ -34,7 +36,7 @@ namespace linker.plugins.relay.client
return true; return true;
} }
public List<RelayNodeReportInfo> Subscribe(ApiControllerParamsInfo param) public List<RelayServerNodeReportInfo> Subscribe(ApiControllerParamsInfo param)
{ {
relayTestTransfer.Subscribe(); relayTestTransfer.Subscribe();
return relayTestTransfer.Nodes; 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.client;
using linker.plugins.relay.client.transport;
using System.Net; using System.Net;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
@@ -10,16 +11,16 @@ namespace linker.plugins.relay.client
/// <summary> /// <summary>
/// 中继 /// 中继
/// </summary> /// </summary>
public sealed class RelayTestTransfer public sealed class RelayClientTestTransfer
{ {
private readonly RelayTransfer relayTransfer; private readonly RelayClientTransfer relayTransfer;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly ClientConfigTransfer clientConfigTransfer; private readonly ClientConfigTransfer clientConfigTransfer;
private readonly RelayClientConfigTransfer relayClientConfigTransfer; 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.relayTransfer = relayTransfer;
this.clientSignInState = clientSignInState; this.clientSignInState = clientSignInState;
@@ -39,7 +40,7 @@ namespace linker.plugins.relay.client
{ {
try 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) if (transport != null)
{ {
Nodes = await transport.RelayTestAsync(new RelayTestInfo 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;
using linker.libs.extends; using linker.libs.extends;
using linker.plugins.relay.client.transport; using linker.messenger.relay.client.transport;
using linker.messenger.relay.server;
using MemoryPack; using MemoryPack;
using System.Net; using System.Net;
@@ -51,104 +52,14 @@ namespace linker.config
#else #else
public string SecretKey { get; set; } = Guid.NewGuid().ToString().ToUpper(); public string SecretKey { get; set; } = Guid.NewGuid().ToString().ToUpper();
#endif #endif
public DistributedInfo Distributed { get; set; } = new DistributedInfo { }; public DistributedInfo Distributed { get; set; } = new DistributedInfo { };
} }
public sealed class DistributedInfo public sealed class DistributedInfo
{ {
public RelayNodeInfo Node { get; set; } = new RelayNodeInfo { }; public RelayServerNodeInfo Node { get; set; } = new RelayServerNodeInfo { };
public RelayMasterInfo Master { get; set; } = new RelayMasterInfo { }; 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>
/// 中继服务器 /// 中继服务器
/// </summary> /// </summary>
@@ -169,7 +80,7 @@ namespace linker.config
/// </summary> /// </summary>
public bool SSL { get; set; } = true; 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.config;
using linker.messenger.relay.server;
namespace linker.plugins.relay.server namespace linker.plugins.relay.server
{ {
public sealed class RelayServerConfigTransfer public sealed class RelayServerConfigTransfer
{ {
public string SecretKey => config.Data.Server.Relay.SecretKey; public string SecretKey => config.Data.Server.Relay.SecretKey;
public RelayNodeInfo Node=> config.Data.Server.Relay.Distributed.Node; public RelayServerNodeInfo Node=> config.Data.Server.Relay.Distributed.Node;
public RelayMasterInfo Master => config.Data.Server.Relay.Distributed.Master; public RelayServerMasterInfo Master => config.Data.Server.Relay.Distributed.Master;
private readonly FileConfig config; 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.libs;
using linker.messenger.relay.server.validator;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.relay.server.validator 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 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); relayValidatorTransfer.LoadValidators(validators);
LoggerHelper.Instance.Info($"load relay validators:{string.Join(",", validators.Select(c => c.GetType().Name))}"); 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) public void AddClient(ServiceCollection serviceCollection, FileConfig config)
{ {
serviceCollection.AddSingleton<SignInArgsTransfer>();
MemoryPackFormatterProvider.Register(new SignInfoFormatter()); MemoryPackFormatterProvider.Register(new SignInfoFormatter());
MemoryPackFormatterProvider.Register(new SignCacheInfoFormatter()); MemoryPackFormatterProvider.Register(new SignCacheInfoFormatter());
MemoryPackFormatterProvider.Register(new SignInListRequestInfoFormatter()); MemoryPackFormatterProvider.Register(new SignInListRequestInfoFormatter());
@@ -34,15 +36,17 @@ namespace linker.plugins.signin
serviceCollection.AddSingleton<PlusSignInClientMessenger>(); serviceCollection.AddSingleton<PlusSignInClientMessenger>();
serviceCollection.AddSingleton<SignInArgsTransfer>();
serviceCollection.AddSingleton<SignInArgsTypesLoader>(); serviceCollection.AddSingleton<SignInArgsTypesLoader>();
serviceCollection.AddSingleton<SignInArgsMachineKeyClient>(); serviceCollection.AddSingleton<SignInArgsMachineKeyClient>();
serviceCollection.AddSingleton<SignInClientApiController>(); serviceCollection.AddSingleton<SignInClientApiController>();
} }
public void AddServer(ServiceCollection serviceCollection, FileConfig config) public void AddServer(ServiceCollection serviceCollection, FileConfig config)
{ {
serviceCollection.AddSingleton<SignCaching>();
serviceCollection.AddSingleton<SignInArgsTransfer>();
MemoryPackFormatterProvider.Register(new SignInfoFormatter()); MemoryPackFormatterProvider.Register(new SignInfoFormatter());
MemoryPackFormatterProvider.Register(new SignCacheInfoFormatter()); MemoryPackFormatterProvider.Register(new SignCacheInfoFormatter());
MemoryPackFormatterProvider.Register(new SignInListRequestInfoFormatter()); MemoryPackFormatterProvider.Register(new SignInListRequestInfoFormatter());
@@ -52,16 +56,13 @@ namespace linker.plugins.signin
MemoryPackFormatterProvider.Register(new SignInIdsResponseItemInfoFormatter()); MemoryPackFormatterProvider.Register(new SignInIdsResponseItemInfoFormatter());
MemoryPackFormatterProvider.Register(new SignInResponseInfoFormatter()); MemoryPackFormatterProvider.Register(new SignInResponseInfoFormatter());
serviceCollection.AddSingleton<SignCaching>();
serviceCollection.AddSingleton<SignInServerMessenger>();
serviceCollection.AddSingleton<ISignInStore, SignInStore>(); serviceCollection.AddSingleton<ISignInStore, SignInStore>();
serviceCollection.AddSingleton<PlusSignInServerMessenger>(); serviceCollection.AddSingleton<PlusSignInServerMessenger>();
serviceCollection.AddSingleton<SignInArgsTransfer>();
serviceCollection.AddSingleton<SignInArgsTypesLoader>(); serviceCollection.AddSingleton<SignInArgsTypesLoader>();
serviceCollection.AddSingleton<SignInArgsMachineKeyServer>(); serviceCollection.AddSingleton<SignInArgsMachineKeyServer>();
serviceCollection.AddSingleton<SignInConfigTransfer>(); serviceCollection.AddSingleton<SignInConfigTransfer>();
} }

View File

@@ -1,5 +1,4 @@
using linker.config; using linker.tunnel;
using linker.tunnel;
using linker.tunnel.connection; using linker.tunnel.connection;
using linker.libs; using linker.libs;
using linker.libs.socks5; using linker.libs.socks5;
@@ -13,6 +12,7 @@ using linker.plugins.socks5.config;
using System.Text; using System.Text;
using linker.plugins.relay.client; using linker.plugins.relay.client;
using linker.plugins.pcp; using linker.plugins.pcp;
using linker.messenger.relay.client;
namespace linker.plugins.socks5 namespace linker.plugins.socks5
{ {
@@ -27,7 +27,7 @@ namespace linker.plugins.socks5
protected override string TransactionId => "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) : base(tunnelTransfer, relayTransfer, pcpTransfer, clientSignInTransfer, clientSignInState, clientConfigTransfer, relayClientConfigTransfer)
{ {
this.clientSignInTransfer = clientSignInTransfer; 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; public ResolverType Type => ResolverType.External;
private readonly TunnelExternalResolver tunnelExternalResolver; public PlusTunnelExternalResolver()
public PlusTunnelExternalResolver(TunnelExternalResolver tunnelExternalResolver)
{ {
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 System.Collections.Concurrent;
using linker.plugins.relay.client; using linker.plugins.relay.client;
using linker.plugins.pcp; using linker.plugins.pcp;
using linker.messenger.relay.client;
namespace linker.plugins.tunnel namespace linker.plugins.tunnel
{ {
@@ -16,14 +17,14 @@ namespace linker.plugins.tunnel
protected readonly ConcurrentDictionary<string, ITunnelConnection> connections = new ConcurrentDictionary<string, ITunnelConnection>(); protected readonly ConcurrentDictionary<string, ITunnelConnection> connections = new ConcurrentDictionary<string, ITunnelConnection>();
private readonly TunnelTransfer tunnelTransfer; private readonly TunnelTransfer tunnelTransfer;
private readonly RelayTransfer relayTransfer; private readonly RelayClientTransfer relayTransfer;
private readonly PcpTransfer pcpTransfer; private readonly PcpTransfer pcpTransfer;
private readonly ClientSignInTransfer clientSignInTransfer; private readonly ClientSignInTransfer clientSignInTransfer;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly ClientConfigTransfer clientConfigTransfer; private readonly ClientConfigTransfer clientConfigTransfer;
private readonly RelayClientConfigTransfer relayClientConfigTransfer; 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.tunnelTransfer = tunnelTransfer;
this.relayTransfer = relayTransfer; this.relayTransfer = relayTransfer;

View File

@@ -26,31 +26,33 @@ namespace linker.plugins.tunnel
public void AddClient(ServiceCollection serviceCollection, FileConfig config) 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<TunnelWanPortTransfer>();
//打洞协议 //打洞协议
serviceCollection.AddSingleton<TunnelTransfer>(); serviceCollection.AddSingleton<TunnelTransfer>();
serviceCollection.AddSingleton<TunnelUpnpTransfer>(); serviceCollection.AddSingleton<TunnelUpnpTransfer>();
serviceCollection.AddSingleton<TunnelExcludeIPTransfer>(); 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<TunnelExcludeIPTypesLoader>();
serviceCollection.AddSingleton<TunnelConfigTransfer>(); serviceCollection.AddSingleton<TunnelConfigTransfer>();
serviceCollection.AddSingleton<TunnelConfigSyncTransports>(); serviceCollection.AddSingleton<TunnelConfigSyncTransports>();
serviceCollection.AddSingleton<TunnelDecenter>(); serviceCollection.AddSingleton<TunnelDecenter>();
//管理接口
serviceCollection.AddSingleton<TunnelApiController>();
serviceCollection.AddSingleton<PlusTunnelAdapter>();
} }
public void AddServer(ServiceCollection serviceCollection, FileConfig config) public void AddServer(ServiceCollection serviceCollection, FileConfig config)
@@ -62,7 +64,6 @@ namespace linker.plugins.tunnel
serviceCollection.AddSingleton<PlusTunnelServerMessenger>(); serviceCollection.AddSingleton<PlusTunnelServerMessenger>();
serviceCollection.AddSingleton<PlusTunnelExternalResolver, PlusTunnelExternalResolver>(); serviceCollection.AddSingleton<PlusTunnelExternalResolver, PlusTunnelExternalResolver>();
serviceCollection.AddSingleton<TunnelExternalResolver>();
} }
public void UseClient(ServiceProvider serviceProvider, FileConfig config) public void UseClient(ServiceProvider serviceProvider, FileConfig config)
@@ -73,7 +74,7 @@ namespace linker.plugins.tunnel
ClientConfigTransfer clientConfigTransfer = serviceProvider.GetService<ClientConfigTransfer>(); ClientConfigTransfer clientConfigTransfer = serviceProvider.GetService<ClientConfigTransfer>();
TunnelConfigTransfer tunnelConfigTransfer = serviceProvider.GetService<TunnelConfigTransfer>(); TunnelConfigTransfer tunnelConfigTransfer = serviceProvider.GetService<TunnelConfigTransfer>();
PlusTunnelAdapter tunnelAdapter = serviceProvider.GetService<PlusTunnelAdapter>(); ITunnelMessengerAdapterStore tunnelAdapter = serviceProvider.GetService<ITunnelMessengerAdapterStore>();
LoggerHelper.Instance.Info($"tunnel route level getting."); LoggerHelper.Instance.Info($"tunnel route level getting.");
tunnelConfigTransfer.RefreshRouteLevel(); tunnelConfigTransfer.RefreshRouteLevel();

View File

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

View File

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