This commit is contained in:
snltty
2024-10-21 16:36:00 +08:00
parent 03145bb6d0
commit 47404bf414
84 changed files with 658 additions and 1862 deletions

View File

@@ -12,16 +12,16 @@ namespace linker.gen
public class InterfaceSourceGenerator : IIncrementalGenerator public class InterfaceSourceGenerator : IIncrementalGenerator
{ {
private List<GeneratorInfo> generators = new List<GeneratorInfo> { private List<GeneratorInfo> generators = new List<GeneratorInfo> {
new GeneratorInfo{ ClassName="FlowTransfer", ClassNameSpace="linker.plugins.flow", InterfaceName="linker.plugins.flow.IFlow" }, new GeneratorInfo{ ClassName="FlowTypesLoader", ClassNameSpace="linker.plugins.flow", InterfaceName="linker.plugins.flow.IFlow" },
new GeneratorInfo{ ClassName="RelayValidatorTransfer", ClassNameSpace="linker.plugins.relay.validator", InterfaceName="linker.plugins.relay.validator.IRelayValidator" }, new GeneratorInfo{ ClassName="RelayValidatorTypeLoader", ClassNameSpace="linker.plugins.relay.validator", InterfaceName="linker.plugins.relay.validator.IRelayValidator" },
new GeneratorInfo{ ClassName="SignInArgsTransfer", ClassNameSpace="linker.plugins.signIn.args", InterfaceName="linker.plugins.signIn.args.ISignInArgs" }, new GeneratorInfo{ ClassName="SignInArgsTypesLoader", ClassNameSpace="linker.plugins.signIn.args", InterfaceName="linker.plugins.signIn.args.ISignInArgs" },
new GeneratorInfo{ ClassName="RelayTransfer", ClassNameSpace="linker.plugins.relay", InterfaceName="linker.plugins.relay.transport.ITransport" }, new GeneratorInfo{ ClassName="RelayTypesLoader", ClassNameSpace="linker.plugins.relay", InterfaceName="linker.plugins.relay.transport.ITransport" },
new GeneratorInfo{ ClassName="ResolverTransfer", ClassNameSpace="linker.plugins.resolver", InterfaceName="linker.plugins.resolver.IResolver" }, new GeneratorInfo{ ClassName="ResolverTypesLoader", ClassNameSpace="linker.plugins.resolver", InterfaceName="linker.plugins.resolver.IResolver" },
new GeneratorInfo{ ClassName="TunnelExcludeIPTransfer", ClassNameSpace="linker.plugins.tunnel.excludeip", InterfaceName="linker.plugins.tunnel.excludeip.ITunnelExcludeIP" }, new GeneratorInfo{ ClassName="TunnelExcludeIPTypesLoader", ClassNameSpace="linker.plugins.tunnel.excludeip", InterfaceName="linker.plugins.tunnel.excludeip.ITunnelExcludeIP" },
new GeneratorInfo{ ClassName="StartupTransfer", ClassNameSpace="linker.startup", InterfaceName="linker.startup.IStartup", Instance=true }, new GeneratorInfo{ ClassName="StartupTransfer", ClassNameSpace="linker.startup", InterfaceName="linker.startup.IStartup", Instance=true },
new GeneratorInfo{ ClassName="MessengerResolverTypes", ClassNameSpace="linker.plugins.messenger", InterfaceName="linker.plugins.messenger.IMessenger"}, new GeneratorInfo{ ClassName="MessengerResolverTypesLoader", ClassNameSpace="linker.plugins.messenger", InterfaceName="linker.plugins.messenger.IMessenger"},
new GeneratorInfo{ ClassName="ApiClientServer", ClassNameSpace="linker.plugins.capi", InterfaceName="linker.plugins.capi.IApiClientController"}, new GeneratorInfo{ ClassName="ApiClientTypesLoader", ClassNameSpace="linker.plugins.capi", InterfaceName="linker.plugins.capi.IApiClientController"},
new GeneratorInfo{ ClassName="ConfigSyncTreansfer", ClassNameSpace="linker.plugins.config", InterfaceName="linker.plugins.config.IConfigSync"}, new GeneratorInfo{ ClassName="ConfigSyncTypesLoader", ClassNameSpace="linker.plugins.config", InterfaceName="linker.plugins.config.IConfigSync"},
}; };
public void Initialize(IncrementalGeneratorInitializationContext context) public void Initialize(IncrementalGeneratorInitializationContext context)

View File

@@ -1,128 +0,0 @@
using linker.libs.extends;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using System;
using linker.messenger.resolver;
using System.Threading;
namespace linker.plugins.server
{
public sealed class MessengerServer
{
private Socket socket;
private Socket socketUdp;
private CancellationTokenSource cancellationTokenSource;
private readonly ResolverTransfer resolverTransfer;
public MessengerServer(ResolverTransfer resolverTransfer)
{
this.resolverTransfer = resolverTransfer;
cancellationTokenSource = new CancellationTokenSource();
}
public void Start(int port)
{
if (socket == null)
{
socket = BindAccept(port);
}
}
private async Task BindUdp(int port)
{
socketUdp = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socketUdp.Bind(new IPEndPoint(IPAddress.Any, port));
socketUdp.WindowsUdpBug();
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort);
byte[] buffer = new byte[1 * 1024 * 1024];
while (true)
{
try
{
SocketReceiveFromResult result = await socketUdp.ReceiveFromAsync(buffer, SocketFlags.None, endPoint).ConfigureAwait(false);
IPEndPoint ep = result.RemoteEndPoint as IPEndPoint;
try
{
await resolverTransfer.BeginReceive(socketUdp, ep, buffer.AsMemory(0, result.ReceivedBytes)).ConfigureAwait(false);
}
catch (Exception)
{
}
}
catch (Exception)
{
break;
}
}
}
private Socket BindAccept(int port)
{
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, port);
Socket socket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.IPv6Only(localEndPoint.AddressFamily, false);
socket.ReuseBind(localEndPoint);
socket.Listen(int.MaxValue);
SocketAsyncEventArgs acceptEventArg = new SocketAsyncEventArgs
{
UserToken = socket,
SocketFlags = SocketFlags.None,
};
acceptEventArg.Completed += IO_Completed;
StartAccept(acceptEventArg);
_ = BindUdp(port);
return socket;
}
private void StartAccept(SocketAsyncEventArgs acceptEventArg)
{
acceptEventArg.AcceptSocket = null;
Socket token = (Socket)acceptEventArg.UserToken;
try
{
if (token.AcceptAsync(acceptEventArg) == false)
{
ProcessAccept(acceptEventArg);
}
}
catch (Exception)
{
token?.SafeClose();
}
}
private void IO_Completed(object sender, SocketAsyncEventArgs e)
{
switch (e.LastOperation)
{
case SocketAsyncOperation.Accept:
ProcessAccept(e);
break;
default:
break;
}
}
private void ProcessAccept(SocketAsyncEventArgs e)
{
if (e.AcceptSocket != null)
{
_ = resolverTransfer.BeginReceive(e.AcceptSocket);
StartAccept(e);
}
}
public void Stop()
{
cancellationTokenSource?.Cancel();
socket?.SafeClose();
socket = null;
}
public void Disponse()
{
Stop();
}
}
}

View File

@@ -1,26 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFrameworks>net8.0</TargetFrameworks>
<PublishAot>false</PublishAot>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release</Configurations>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<Title>linker libs</Title>
<Authors>snltty</Authors>
<Company>snltty</Company>
<Description>linker libs</Description>
<Copyright>snltty</Copyright>
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<Version>1.5.0</Version>
<AssemblyVersion>1.5.0</AssemblyVersion>
<FileVersion>1.5.0</FileVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\linker.libs\linker.libs.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,31 +0,0 @@
using System;
namespace linker.messenger.messenger
{
/// <summary>
/// 消息接口
/// </summary>
public interface IMessenger
{
}
/// <summary>
/// 消息id
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public sealed class MessengerIdAttribute : Attribute
{
/// <summary>
/// id
/// </summary>
public ushort Id { get; set; }
/// <summary>
///
/// </summary>
/// <param name="id"></param>
public MessengerIdAttribute(ushort id)
{
Id = id;
}
}
}

View File

@@ -1,506 +0,0 @@
using linker.libs;
using linker.libs.extends;
using System;
using System.Buffers;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace linker.messenger.messenger
{
public interface IConnectionReceiveCallback
{
public Task Receive(IMessengerConnection connection, ReadOnlyMemory<byte> data, object state);
}
public interface IMessengerConnection
{
/// <summary>
/// 连接id存的应该是客户端id
/// </summary>
public string Id { get; set; }
/// <summary>
/// 链接名
/// </summary>
public string Name { get; set; }
public bool Connected { get; }
/// <summary>
/// 外网IP
/// </summary>
public IPEndPoint Address { get; }
/// <summary>
/// 内网IP
/// </summary>
public IPEndPoint LocalAddress { get; }
/// <summary>
/// 你的ssl流
/// </summary>
public SslStream SourceStream { get; }
/// <summary>
/// 你的socket
/// </summary>
public Socket SourceSocket { get; }
/// <summary>
/// 你的网络流
/// </summary>
public NetworkStream SourceNetworkStream { get; }
/// <summary>
/// 对方的网络流
/// </summary>
public SslStream TargetStream { get; set; }
/// <summary>
/// 对方的socket
/// </summary>
public Socket TargetSocket { get; set; }
/// <summary>
/// 对方的网络流
/// </summary>
public NetworkStream TargetNetworkStream { get; set; }
/// <summary>
/// 延迟ms
/// </summary>
public int Delay { get; }
/// <summary>
/// 已发送字节数
/// </summary>
public long SendBytes { get; }
/// <summary>
/// 已接收字节数
/// </summary>
public long ReceiveBytes { get; }
#region
public MessageRequestWrap ReceiveRequestWrap { get; }
public MessageResponseWrap ReceiveResponseWrap { get; }
public ReadOnlyMemory<byte> ReceiveData { get; set; }
#endregion
/// <summary>
/// 开始就接收数据
/// </summary>
/// <param name="callback">处理回调</param>
/// <param name="userToken">携带自定义数据,回调时带过去</param>
/// <param name="byFrame">是否处理粘包</param>
public void BeginReceive(IConnectionReceiveCallback callback, object userToken, bool byFrame = true);
/// <summary>
/// 发送数据
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public Task<bool> SendAsync(ReadOnlyMemory<byte> data);
/// <summary>
/// 发送数据
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
public Task<bool> SendAsync(byte[] data, int length);
public void Disponse(int value = 0);
#region
public Memory<byte> ResponseData { get; }
public void Write(Memory<byte> data);
public void Write(ulong num);
public void Write(ushort num);
public void Write(ushort[] nums);
public void WriteUTF8(string str);
public void WriteUTF16(string str);
public void Return();
#endregion
}
public abstract class MessengerConnection : IMessengerConnection
{
public MessengerConnection()
{
}
public string Id { get; set; }
public string Name { get; set; }
public virtual bool Connected => false;
public IPEndPoint Address { get; protected set; }
public IPEndPoint LocalAddress { get; protected set; }
public SslStream SourceStream { get; protected set; }
public Socket SourceSocket { get; protected set; }
public NetworkStream SourceNetworkStream { get; set; }
public SslStream TargetStream { get; set; }
public Socket TargetSocket { get; set; }
public NetworkStream TargetNetworkStream { get; set; }
public int Delay { get; protected set; }
public long SendBytes { get; protected set; }
public long ReceiveBytes { get; protected set; }
#region
public MessageRequestWrap ReceiveRequestWrap { get; set; }
public MessageResponseWrap ReceiveResponseWrap { get; set; }
public ReadOnlyMemory<byte> ReceiveData { get; set; }
#endregion
#region
public Memory<byte> ResponseData { get; private set; }
private byte[] responseData;
private int length = 0;
public void Write(Memory<byte> data)
{
ResponseData = data;
length = 0;
}
public void Write(ulong num)
{
length = 8;
responseData = ArrayPool<byte>.Shared.Rent(length);
num.ToBytes(responseData);
ResponseData = responseData.AsMemory(0, length);
}
public void Write(ushort num)
{
length = 2;
responseData = ArrayPool<byte>.Shared.Rent(length);
num.ToBytes(responseData);
ResponseData = responseData.AsMemory(0, length);
}
public void Write(ushort[] nums)
{
length = nums.Length * 2;
responseData = ArrayPool<byte>.Shared.Rent(length);
nums.ToBytes(responseData);
ResponseData = responseData.AsMemory(0, length);
}
public void WriteUTF8(string str)
{
var span = str.AsSpan();
responseData = ArrayPool<byte>.Shared.Rent((span.Length + 1) * 3 + 8);
var memory = responseData.AsMemory();
int utf8Length = span.ToUTF8Bytes(memory.Slice(8));
span.Length.ToBytes(memory);
utf8Length.ToBytes(memory.Slice(4));
length = utf8Length + 8;
ResponseData = responseData.AsMemory(0, length);
}
public void WriteUTF16(string str)
{
var span = str.GetUTF16Bytes();
length = span.Length + 4;
responseData = ArrayPool<byte>.Shared.Rent(length);
str.Length.ToBytes(responseData);
span.CopyTo(responseData.AsSpan(4));
ResponseData = responseData.AsMemory(0, length);
}
public void Return()
{
if (length > 0 && ResponseData.Length > 0)
{
ArrayPool<byte>.Shared.Return(responseData);
}
ResponseData = Helper.EmptyArray;
responseData = null;
length = 0;
}
#endregion
public abstract void BeginReceive(IConnectionReceiveCallback callback, object userToken, bool byFrame = true);
public abstract Task<bool> SendAsync(ReadOnlyMemory<byte> data);
public abstract Task<bool> SendAsync(byte[] data, int length);
public virtual void Disponse(int value = 0)
{
}
}
public sealed class TcpMessengerConnection : MessengerConnection
{
public TcpMessengerConnection(SslStream stream, NetworkStream networkStream, Socket socket, IPEndPoint local, IPEndPoint remote) : base()
{
SourceStream = stream;
SourceNetworkStream = networkStream;
SourceSocket = socket;
if (remote.Address.AddressFamily == AddressFamily.InterNetworkV6 && remote.Address.IsIPv4MappedToIPv6)
{
remote = new IPEndPoint(new IPAddress(remote.Address.GetAddressBytes()[^4..]), remote.Port);
}
Address = remote;
if (local.Address.AddressFamily == AddressFamily.InterNetworkV6 && local.Address.IsIPv4MappedToIPv6)
{
local = new IPEndPoint(new IPAddress(local.Address.GetAddressBytes()[^4..]), local.Port);
}
LocalAddress = local;
}
public override bool Connected => SourceSocket != null && lastTicks.Expired(15000) == false;
private IConnectionReceiveCallback callback;
private CancellationTokenSource cancellationTokenSource;
private CancellationTokenSource cancellationTokenSourceWrite;
private object userToken;
private bool framing;
private ReceiveDataBuffer bufferCache = new ReceiveDataBuffer();
private LastTicksManager lastTicks = new LastTicksManager();
private LastTicksManager pingTicks = new LastTicksManager();
private static byte[] pingBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.tcp.ping");
private static byte[] pongBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.tcp.pong");
private bool pong = true;
public override void BeginReceive(IConnectionReceiveCallback callback, object userToken, bool framing = true)
{
if (this.callback != null) return;
this.callback = callback;
this.userToken = userToken;
this.framing = framing;
cancellationTokenSource = new CancellationTokenSource();
cancellationTokenSourceWrite = new CancellationTokenSource();
_ = ProcessWrite();
_ = ProcessHeart();
}
private async Task ProcessWrite()
{
byte[] buffer = new byte[8 * 1024];
try
{
int length = 0;
while (cancellationTokenSource.IsCancellationRequested == false)
{
if (SourceStream != null)
{
length = await SourceStream.ReadAsync(buffer, cancellationTokenSource.Token).ConfigureAwait(false);
}
else
{
length = await SourceSocket.ReceiveAsync(buffer, SocketFlags.None, cancellationTokenSource.Token).ConfigureAwait(false);
}
if (length == 0)
{
Disponse(1);
break;
}
ReceiveBytes += length;
lastTicks.Update();
await ReadPacket(buffer.AsMemory(0, length)).ConfigureAwait(false);
}
}
catch (OperationCanceledException)
{
}
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{
LoggerHelper.Instance.Error(ex);
}
}
finally
{
Disponse(2);
}
}
private async Task ReadPacket(Memory<byte> buffer)
{
if (framing == false)
{
await CallbackPacket(buffer).ConfigureAwait(false);
return;
}
//是一个完整的包
if (bufferCache.Size == 0 && buffer.Length > 4)
{
int packageLen = buffer.Span.ToInt32();
if (packageLen + 4 <= buffer.Length)
{
await CallbackPacket(buffer.Slice(4, packageLen)).ConfigureAwait(false);
buffer = buffer.Slice(4 + packageLen);
}
if (buffer.Length == 0)
return;
}
bufferCache.AddRange(buffer);
do
{
int packageLen = bufferCache.Data.Span.ToInt32();
if (packageLen + 4 > bufferCache.Size)
{
break;
}
await CallbackPacket(bufferCache.Data.Slice(4, packageLen)).ConfigureAwait(false);
bufferCache.RemoveRange(0, packageLen + 4);
} while (bufferCache.Size > 4);
}
private async Task CallbackPacket(Memory<byte> packet)
{
if (packet.Length == pingBytes.Length && (packet.Span.SequenceEqual(pingBytes) || packet.Span.SequenceEqual(pongBytes)))
{
if (packet.Span.SequenceEqual(pingBytes))
{
await SendPingPong(pongBytes).ConfigureAwait(false);
}
else if (packet.Span.SequenceEqual(pongBytes))
{
Delay = (int)pingTicks.Diff();
pong = true;
}
}
else
{
try
{
await callback.Receive(this, packet, userToken).ConfigureAwait(false);
}
catch (Exception)
{
}
}
}
private async Task ProcessHeart()
{
try
{
while (cancellationTokenSource.IsCancellationRequested == false)
{
if (lastTicks.DiffGreater(3000))
{
pingTicks.Update();
await SendPingPong(pingBytes).ConfigureAwait(false);
}
await Task.Delay(3000).ConfigureAwait(false);
}
}
catch (Exception)
{
}
}
private SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1);
private async Task SendPingPong(byte[] data)
{
int length = 4 + pingBytes.Length;
byte[] heartData = ArrayPool<byte>.Shared.Rent(length);
data.Length.ToBytes(heartData);
data.AsMemory().CopyTo(heartData.AsMemory(4));
await semaphoreSlim.WaitAsync().ConfigureAwait(false);
try
{
if (SourceStream != null)
{
await SourceStream.WriteAsync(heartData.AsMemory(0, length), cancellationTokenSource.Token).ConfigureAwait(false);
}
else
{
await SourceSocket.SendAsync(heartData.AsMemory(0, length), cancellationTokenSource.Token).ConfigureAwait(false);
}
}
catch (Exception)
{
pong = true;
}
finally
{
semaphoreSlim.Release();
}
ArrayPool<byte>.Shared.Return(heartData);
}
public async Task SendPing()
{
if (pong == false) return;
pong = false;
pingTicks.Update();
await SendPingPong(pingBytes);
}
public override async Task<bool> SendAsync(ReadOnlyMemory<byte> data)
{
if (SourceStream != null) await semaphoreSlim.WaitAsync().ConfigureAwait(false);
try
{
if (SourceStream != null)
await SourceStream.WriteAsync(data, cancellationTokenSourceWrite.Token).ConfigureAwait(false);
else
await SourceSocket.SendAsync(data, cancellationTokenSourceWrite.Token).ConfigureAwait(false);
SendBytes += data.Length;
lastTicks.Update();
}
catch (OperationCanceledException)
{
}
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{
LoggerHelper.Instance.Error(ex);
}
Disponse(3);
}
finally
{
if (SourceStream != null) semaphoreSlim.Release();
}
return true;
}
public override async Task<bool> SendAsync(byte[] data, int length)
{
return await SendAsync(data.AsMemory(0, length)).ConfigureAwait(false);
}
public override void Disponse(int value = 0)
{
callback = null;
userToken = null;
cancellationTokenSource?.Cancel();
bufferCache.Clear(true);
cancellationTokenSourceWrite?.Cancel();
base.Disponse();
try
{
SourceNetworkStream?.Close();
SourceNetworkStream?.Dispose();
TargetNetworkStream?.Close();
TargetNetworkStream?.Dispose();
}
catch (Exception)
{
}
SourceSocket?.SafeClose();
TargetSocket?.SafeClose();
lastTicks.Clear();
}
}
}

View File

@@ -1,257 +0,0 @@
using linker.libs;
using System.Net.Security;
using System.Net.Sockets;
using System.Net;
using System.Reflection;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using linker.libs.extends;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using linker.messenger.resolver;
using System.IO;
namespace linker.messenger.messenger
{
/// <summary>
/// 消息处理总线
/// </summary>
public class MessengerResolver : IConnectionReceiveCallback, IResolver
{
public ResolverType Type => ResolverType.Messenger;
delegate void VoidDelegate(IMessengerConnection connection);
delegate Task TaskDelegate(IMessengerConnection connection);
private readonly Dictionary<ushort, MessengerCacheInfo> messengers = new();
private readonly MessengerSender messengerSender;
private X509Certificate serverCertificate;
public MessengerResolver(MessengerSender messengerSender)
{
this.messengerSender = messengerSender;
}
public void Init(string certificate, string password)
{
string path = Path.GetFullPath(certificate);
if (File.Exists(path))
{
serverCertificate = new X509Certificate(path, password);
}
else
{
LoggerHelper.Instance.Error($"file {path} not found");
Environment.Exit(0);
}
}
public virtual void OnSendt(ushort id, ulong length)
{
}
public virtual void OnReceived(ushort id, ulong length)
{
}
public async Task Resolve(Socket socket, Memory<byte> memory)
{
try
{
NetworkStream networkStream = new NetworkStream(socket, false);
SslStream sslStream = new SslStream(networkStream, true);
await sslStream.AuthenticateAsServerAsync(serverCertificate, false, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false).ConfigureAwait(false);
IMessengerConnection connection = CreateConnection(sslStream, networkStream, socket, socket.LocalEndPoint as IPEndPoint, socket.RemoteEndPoint as IPEndPoint);
connection.BeginReceive(this, null, true);
}
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error(ex);
}
}
public async Task Resolve(Socket socket, IPEndPoint ep, Memory<byte> memory)
{
await Task.CompletedTask;
}
public async Task<IMessengerConnection> BeginReceiveClient(Socket socket)
{
try
{
if (socket == null || socket.RemoteEndPoint == null)
{
return null;
}
socket.KeepAlive();
await socket.SendAsync(new byte[] { (byte)ResolverType.Messenger }).ConfigureAwait(false);
NetworkStream networkStream = new NetworkStream(socket, false);
SslStream sslStream = new SslStream(networkStream, true, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
await sslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions
{
AllowRenegotiation = true,
EnabledSslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13
}).ConfigureAwait(false);
IMessengerConnection connection = CreateConnection(sslStream, networkStream, socket, socket.LocalEndPoint as IPEndPoint, socket.RemoteEndPoint as IPEndPoint);
connection.BeginReceive(this, null, true);
return connection;
}
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error(ex);
}
return null;
}
private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
private IMessengerConnection CreateConnection(SslStream stream, NetworkStream networkStream, Socket socket, IPEndPoint local, IPEndPoint remote)
{
return new TcpMessengerConnection(stream, networkStream, socket, local, remote)
{
ReceiveRequestWrap = new MessageRequestWrap(),
ReceiveResponseWrap = new MessageResponseWrap()
};
}
/// <summary>
/// 加载所有消息处理器
/// </summary>
public void LoadMessenger(List<IMessenger> list)
{
Type voidType = typeof(void);
Type midType = typeof(MessengerIdAttribute);
foreach (IMessenger messenger in list)
{
Type type = messenger.GetType();
foreach (var method in type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly))
{
MessengerIdAttribute mid = method.GetCustomAttribute(midType) as MessengerIdAttribute;
if (mid != null)
{
if (messengers.ContainsKey(mid.Id) == false)
{
MessengerCacheInfo cache = new MessengerCacheInfo
{
Target = messenger
};
//void方法
if (method.ReturnType == voidType)
{
cache.VoidMethod = (VoidDelegate)Delegate.CreateDelegate(typeof(VoidDelegate), messenger, method);
}
//异步方法
else if (method.ReturnType.GetProperty("IsCompleted") != null && method.ReturnType.GetMethod("GetAwaiter") != null)
{
cache.TaskMethod = (TaskDelegate)Delegate.CreateDelegate(typeof(TaskDelegate), messenger, method);
}
messengers.TryAdd(mid.Id, cache);
}
}
}
}
}
/// <summary>
/// 处理消息
/// </summary>
/// <param name="connection"></param>
/// <param name="data"></param>
/// <param name="state"></param>
/// <returns></returns>
public async Task Receive(IMessengerConnection connection, ReadOnlyMemory<byte> data, object state)
{
MessageResponseWrap responseWrap = connection.ReceiveResponseWrap;
MessageRequestWrap requestWrap = connection.ReceiveRequestWrap;
try
{
//回复的消息
if ((MessageTypes)(data.Span[0] & 0b0000_1111) == MessageTypes.RESPONSE)
{
responseWrap.FromArray(data);
messengerSender.Response(responseWrap);
return;
}
//新的请求
requestWrap.FromArray(data);
OnReceived(requestWrap.MessengerId, (ulong)data.Length);
//404,没这个插件
if (messengers.TryGetValue(requestWrap.MessengerId, out MessengerCacheInfo plugin) == false)
{
if (requestWrap.Reply == true)
{
bool res = await messengerSender.ReplyOnly(new MessageResponseWrap
{
Connection = connection,
Code = MessageResponeCodes.NOT_FOUND,
RequestId = requestWrap.RequestId
}, requestWrap.MessengerId).ConfigureAwait(false);
}
return;
}
if (plugin.VoidMethod != null)
{
plugin.VoidMethod(connection);
}
else if (plugin.TaskMethod != null)
{
await plugin.TaskMethod(connection).ConfigureAwait(false);
}
//有需要回复的
if (requestWrap.Reply == true && connection.ResponseData.Length > 0)
{
bool res = await messengerSender.ReplyOnly(new MessageResponseWrap
{
Connection = connection,
Payload = connection.ResponseData,
RequestId = requestWrap.RequestId
}, requestWrap.MessengerId).ConfigureAwait(false);
}
}
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error(ex);
}
finally
{
connection.Return();
}
}
/// <summary>
/// 消息插件缓存
/// </summary>
private struct MessengerCacheInfo
{
/// <summary>
/// 对象
/// </summary>
public object Target { get; set; }
/// <summary>
/// 空返回方法
/// </summary>
public VoidDelegate VoidMethod { get; set; }
/// <summary>
/// Task返回方法
/// </summary>
public TaskDelegate TaskMethod { get; set; }
}
}
}

View File

@@ -1,170 +0,0 @@
using linker.libs;
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace linker.messenger.messenger
{
/// <summary>
/// 消息发送器
/// </summary>
public class MessengerSender
{
public NumberSpaceUInt32 requestIdNumberSpace = new NumberSpaceUInt32(0);
private ConcurrentDictionary<uint, ReplyWrapInfo> sends = new ConcurrentDictionary<uint, ReplyWrapInfo>();
public MessengerSender()
{
}
public virtual void OnSendt(ushort id,ulong length)
{
}
public virtual void OnReceived(ushort id, ulong length)
{
}
/// <summary>
/// 发送并等待回复
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public async Task<MessageResponeInfo> SendReply(MessageRequestWrap msg)
{
if (msg.Connection == null || msg.Connection.Connected == false)
{
return new MessageResponeInfo { Code = MessageResponeCodes.NOT_CONNECT };
}
if (msg.RequestId == 0)
{
uint id = msg.RequestId;
Interlocked.CompareExchange(ref id, requestIdNumberSpace.Increment(), 0);
msg.RequestId = id;
}
msg.Reply = true;
if (msg.Timeout <= 0)
{
msg.Timeout = 15000;
}
TaskCompletionSource<MessageResponeInfo> tcs = new TaskCompletionSource<MessageResponeInfo>(TaskCreationOptions.RunContinuationsAsynchronously);
sends.TryAdd(msg.RequestId, new ReplyWrapInfo { Tcs = tcs, MessengerId = msg.MessengerId });
bool res = await SendOnly(msg).ConfigureAwait(false);
if (res == false)
{
sends.TryRemove(msg.RequestId, out _);
tcs.SetResult(new MessageResponeInfo { Code = MessageResponeCodes.NOT_CONNECT });
}
try
{
return await tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(msg.Timeout)).ConfigureAwait(false);
}
catch (Exception)
{
return new MessageResponeInfo { Code = MessageResponeCodes.TIMEOUT };
}
}
/// <summary>
/// 只发送,不等回复
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public async Task<bool> SendOnly(MessageRequestWrap msg)
{
if (msg.Connection == null || msg.Connection.Connected == false)
{
return false;
}
try
{
if (msg.RequestId == 0)
{
uint id = msg.RequestId;
Interlocked.CompareExchange(ref id, requestIdNumberSpace.Increment(), 0);
msg.RequestId = id;
}
byte[] bytes = msg.ToArray(out int length);
OnSendt(msg.MessengerId, (ulong)bytes.Length);
bool res = await msg.Connection.SendAsync(bytes.AsMemory(0, length)).ConfigureAwait(false);
msg.Return(bytes);
return res;
}
catch (Exception ex)
{
LoggerHelper.Instance.Error(ex);
}
return false;
}
/// <summary>
/// 回复远程消息,收到某个连接的消息后,通过这个再返回消息给它
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public async ValueTask<bool> ReplyOnly(MessageResponseWrap msg, ushort messengerId)
{
if (msg.Connection == null)
{
return false;
}
try
{
byte[] bytes = msg.ToArray(out int length);
OnSendt(messengerId, (ulong)length);
bool res = await msg.Connection.SendAsync(bytes.AsMemory(0, length)).ConfigureAwait(false);
msg.Return(bytes);
return res;
}
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error(ex);
}
return false;
}
/// <summary>
/// 回复本地消息发送消息后socket收到消息通过这个方法回复给刚刚发送的对象
/// </summary>
/// <param name="wrap"></param>
public void Response(MessageResponseWrap wrap)
{
if (sends.TryRemove(wrap.RequestId, out ReplyWrapInfo info))
{
byte[] bytes = new byte[wrap.Payload.Length];
wrap.Payload.CopyTo(bytes);
OnReceived(info.MessengerId, (ulong)bytes.Length);
info.Tcs.SetResult(new MessageResponeInfo { Code = wrap.Code, Data = bytes, Connection = wrap.Connection });
}
}
}
public sealed class ReplyWrapInfo
{
public TaskCompletionSource<MessageResponeInfo> Tcs { get; set; }
public ushort MessengerId { get; set; }
}
public sealed class MessageResponeInfo
{
public MessageResponeCodes Code { get; set; }
public ReadOnlyMemory<byte> Data { get; set; }
public IMessengerConnection Connection { get; set; }
}
}

View File

@@ -1,206 +0,0 @@
using linker.libs.extends;
using System;
using System.Buffers;
namespace linker.messenger.messenger
{
/// <summary>
/// 请求数据包
/// </summary>
public sealed class MessageRequestWrap
{
/// <summary>
/// 超时ms
/// </summary>
public int Timeout { get; set; }
/// <summary>
/// 消息id
/// </summary>
public ushort MessengerId { get; set; }
/// <summary>
/// 请求id
/// </summary>
public uint RequestId { get; set; }
/// <summary>
/// 是否需要回复
/// </summary>
public bool Reply { get; internal set; }
/// <summary>
/// 荷载
/// </summary>
public ReadOnlyMemory<byte> Payload { get; set; }
/// <summary>
/// 连接对象
/// </summary>
public IMessengerConnection Connection { get; set; }
/// <summary>
/// 序列化,使用了池化,用完后记得调用 Return
/// </summary>
/// <param name="length"></param>
/// <returns></returns>
public byte[] ToArray(out int length)
{
int index = 0;
length = 4
+ 1 //Reply + type
+ 4
+ 2
+ Payload.Length;
byte[] res = ArrayPool<byte>.Shared.Rent(length);
((uint)length - 4).ToBytes(res);
index += 4;
res[index] = (byte)((Reply ? 1 : 0) << 4 | (byte)MessageTypes.REQUEST);
index += 1;
RequestId.ToBytes(res.AsMemory(index));
index += 4;
MessengerId.ToBytes(res.AsMemory(index));
index += 2;
Payload.CopyTo(res.AsMemory(index, Payload.Length));
index += Payload.Length;
return res;
}
/// <summary>
/// 反序列化
/// </summary>
/// <param name="memory"></param>
public unsafe void FromArray(ReadOnlyMemory<byte> memory)
{
var span = memory.Span;
int index = 0;
Reply = span[index] >> 4 == 1;
index += 1;
RequestId = span.Slice(index).ToUInt32();
index += 4;
MessengerId = span.Slice(index).ToUInt16();
index += 2;
Payload = memory.Slice(index);
}
public void Return(byte[] array)
{
ArrayPool<byte>.Shared.Return(array);
}
}
/// <summary>
/// 回执消息包
/// </summary>
public sealed class MessageResponseWrap
{
/// <summary>
/// 连接对象
/// </summary>
public IMessengerConnection Connection { get; set; }
/// <summary>
/// 返回码
/// </summary>
public MessageResponeCodes Code { get; set; }
/// <summary>
/// 消息id
/// </summary>
public uint RequestId { get; set; }
/// <summary>
/// 何在
/// </summary>
public ReadOnlyMemory<byte> Payload { get; set; }
/// <summary>
/// 序列化。用了池化,用完记得 Return
/// </summary>
/// <returns></returns>
public byte[] ToArray(out int length)
{
length = 4
+ 1 //type
+ 1 //code
+ 4 //requestid
+ Payload.Length;
byte[] res = ArrayPool<byte>.Shared.Rent(length);
int index = 0;
((uint)length - 4).ToBytes(res);
index += 4;
res[index] = (byte)MessageTypes.RESPONSE;
index += 1;
res[index] = (byte)Code;
index += 1;
RequestId.ToBytes(res.AsMemory(index));
index += 4;
if (Payload.Length > 0)
{
Payload.CopyTo(res.AsMemory(index, Payload.Length));
index += Payload.Length;
}
return res;
}
/// <summary>
/// 解包
/// </summary>
/// <param name="memory"></param>
public void FromArray(ReadOnlyMemory<byte> memory)
{
var span = memory.Span;
int index = 0;
index += 1;
Code = (MessageResponeCodes)span[index];
index += 1;
RequestId = span.Slice(index).ToUInt32();
index += 4;
Payload = memory.Slice(index);
}
public void Return(byte[] array)
{
ArrayPool<byte>.Shared.Return(array);
}
}
/// <summary>
/// 消息状态
/// </summary>
[Flags]
public enum MessageResponeCodes : byte
{
OK = 0,
NOT_CONNECT = 1,
NOT_FOUND = 2,
TIMEOUT = 3,
ERROR = 4,
}
/// <summary>
/// 消息类别
/// </summary>
[Flags]
public enum MessageTypes : byte
{
REQUEST = 0,
RESPONSE = 1
}
}

View File

@@ -1,25 +0,0 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace linker.messenger.resolver
{
public enum ResolverType : byte
{
External = 0,
Messenger = 1,
Relay = 2,
Socks4 = 4,
Socks5 = 5,
Flow = 6
}
public interface IResolver
{
public ResolverType Type { get; }
public Task Resolve(Socket socket, Memory<byte> memory);
public Task Resolve(Socket socket, IPEndPoint ep, Memory<byte> memory);
}
}

View File

@@ -1,64 +0,0 @@
using linker.libs;
using System.Net.Sockets;
using linker.libs.extends;
using System.Buffers;
using System.Net;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace linker.messenger.resolver
{
public sealed partial class ResolverTransfer
{
private readonly Dictionary<ResolverType, IResolver> resolvers = new Dictionary<ResolverType, IResolver>();
public ResolverTransfer()
{
}
public void LoadResolvers(List<IResolver> list)
{
foreach (var resolver in list)
{
resolvers.TryAdd(resolver.Type, resolver);
}
}
public async Task BeginReceive(Socket socket)
{
byte[] buffer = ArrayPool<byte>.Shared.Rent(1024);
try
{
if (socket == null || socket.RemoteEndPoint == null)
{
return;
}
socket.KeepAlive();
int length = await socket.ReceiveAsync(buffer.AsMemory(0, 1), SocketFlags.None).ConfigureAwait(false);
ResolverType type = (ResolverType)buffer[0];
if (resolvers.TryGetValue(type, out IResolver resolver))
{
await resolver.Resolve(socket, buffer.AsMemory(0, length));
}
}
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error(ex);
}
finally
{
ArrayPool<byte>.Shared.Return(buffer);
}
}
public async Task BeginReceive(Socket socket, IPEndPoint ep, Memory<byte> memory)
{
if (resolvers.TryGetValue((ResolverType)memory.Span[0], out IResolver resolver))
{
await resolver.Resolve(socket, ep, memory);
}
}
}
}

View File

@@ -1,94 +0,0 @@
using System.Net.Sockets;
using System.Net;
using System.Buffers;
using linker.libs.extends;
using linker.messenger.resolver;
using System;
using System.Threading.Tasks;
namespace linker.messenger.tunnel
{
/// <summary>
/// 外网端口处理器
/// </summary>
public class ExternalResolver : IResolver
{
public ResolverType Type => ResolverType.External;
public ExternalResolver()
{
}
public virtual void OnSendt( ulong length)
{
}
public virtual void OnReceived( ulong length)
{
}
/// <summary>
/// UDP
/// </summary>
/// <param name="socket"></param>
/// <param name="ep"></param>
/// <param name="memory"></param>
/// <returns></returns>
public async Task Resolve(Socket socket, IPEndPoint ep, Memory<byte> memory)
{
OnReceived((ulong)memory.Length);
byte[] sendData = ArrayPool<byte>.Shared.Rent(20);
try
{
var send = BuildSendData(sendData, ep);
OnSendt((ulong)send.Length);
await socket.SendToAsync(send, SocketFlags.None, ep).ConfigureAwait(false);
}
catch (Exception)
{
}
finally
{
ArrayPool<byte>.Shared.Return(sendData);
}
}
/// <summary>
/// TCP
/// </summary>
/// <param name="socket"></param>
/// <returns></returns>
public async Task Resolve(Socket socket, Memory<byte> memory)
{
byte[] sendData = ArrayPool<byte>.Shared.Rent(20);
try
{
memory = BuildSendData(sendData, socket.RemoteEndPoint as IPEndPoint);
OnSendt((ulong)memory.Length);
await socket.SendAsync(memory, SocketFlags.None).ConfigureAwait(false);
}
catch (Exception)
{
}
finally
{
ArrayPool<byte>.Shared.Return(sendData);
}
}
private Memory<byte> BuildSendData(byte[] data, IPEndPoint ep)
{
//给客户端返回他的IP+端口
data[0] = (byte)ep.AddressFamily;
ep.Address.TryWriteBytes(data.AsSpan(1), out int length);
((ushort)ep.Port).ToBytes(data.AsMemory(1 + length));
//防止一些网关修改掉它的外网IP
for (int i = 0; i < 1 + length + 2; i++)
{
data[i] = (byte)(data[i] ^ byte.MaxValue);
}
return data.AsMemory(0, 1 + length + 2);
}
}
}

View File

@@ -17,8 +17,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.tun.test", "linker.t
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.gen", "linker.gen\linker.gen.csproj", "{031C3589-72BB-4A3F-B1A5-BC0665FDF01B}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.gen", "linker.gen\linker.gen.csproj", "{031C3589-72BB-4A3F-B1A5-BC0665FDF01B}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linker.messenger", "linker.messenger\linker.messenger.csproj", "{95F13B7F-EC39-4E23-9B70-8B747E55777A}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -113,18 +111,6 @@ Global
{031C3589-72BB-4A3F-B1A5-BC0665FDF01B}.Release|x64.Build.0 = Release|Any CPU {031C3589-72BB-4A3F-B1A5-BC0665FDF01B}.Release|x64.Build.0 = Release|Any CPU
{031C3589-72BB-4A3F-B1A5-BC0665FDF01B}.Release|x86.ActiveCfg = Release|Any CPU {031C3589-72BB-4A3F-B1A5-BC0665FDF01B}.Release|x86.ActiveCfg = Release|Any CPU
{031C3589-72BB-4A3F-B1A5-BC0665FDF01B}.Release|x86.Build.0 = Release|Any CPU {031C3589-72BB-4A3F-B1A5-BC0665FDF01B}.Release|x86.Build.0 = Release|Any CPU
{95F13B7F-EC39-4E23-9B70-8B747E55777A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{95F13B7F-EC39-4E23-9B70-8B747E55777A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95F13B7F-EC39-4E23-9B70-8B747E55777A}.Debug|x64.ActiveCfg = Debug|Any CPU
{95F13B7F-EC39-4E23-9B70-8B747E55777A}.Debug|x64.Build.0 = Debug|Any CPU
{95F13B7F-EC39-4E23-9B70-8B747E55777A}.Debug|x86.ActiveCfg = Debug|Any CPU
{95F13B7F-EC39-4E23-9B70-8B747E55777A}.Debug|x86.Build.0 = Debug|Any CPU
{95F13B7F-EC39-4E23-9B70-8B747E55777A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95F13B7F-EC39-4E23-9B70-8B747E55777A}.Release|Any CPU.Build.0 = Release|Any CPU
{95F13B7F-EC39-4E23-9B70-8B747E55777A}.Release|x64.ActiveCfg = Release|Any CPU
{95F13B7F-EC39-4E23-9B70-8B747E55777A}.Release|x64.Build.0 = Release|Any CPU
{95F13B7F-EC39-4E23-9B70-8B747E55777A}.Release|x86.ActiveCfg = Release|Any CPU
{95F13B7F-EC39-4E23-9B70-8B747E55777A}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -15,6 +15,7 @@ namespace linker.tunnel
private List<ITunnelTransport> transports; private List<ITunnelTransport> transports;
private TunnelWanPortTransfer compactTransfer; private TunnelWanPortTransfer compactTransfer;
private ITunnelAdapter tunnelAdapter; private ITunnelAdapter tunnelAdapter;
private TunnelUpnpTransfer TunnelUpnpTransfer;
private ConcurrentDictionary<string, bool> connectingDic = new ConcurrentDictionary<string, bool>(); private ConcurrentDictionary<string, bool> connectingDic = new ConcurrentDictionary<string, bool>();
private uint flowid = 1; private uint flowid = 1;
@@ -28,11 +29,12 @@ namespace linker.tunnel
/// 加载打洞协议 /// 加载打洞协议
/// </summary> /// </summary>
/// <param name="assembs"></param> /// <param name="assembs"></param>
public void LoadTransports(TunnelWanPortTransfer compactTransfer, ITunnelAdapter tunnelAdapter, List<ITunnelTransport> transports) public void LoadTransports(TunnelWanPortTransfer compactTransfer, ITunnelAdapter tunnelAdapter, TunnelUpnpTransfer TunnelUpnpTransfer, List<ITunnelTransport> transports)
{ {
this.compactTransfer = compactTransfer; this.compactTransfer = compactTransfer;
this.tunnelAdapter = tunnelAdapter; this.tunnelAdapter = tunnelAdapter;
this.transports = transports; this.transports = transports;
this.TunnelUpnpTransfer = TunnelUpnpTransfer;
foreach (var item in transports) foreach (var item in transports)
{ {
@@ -317,7 +319,7 @@ namespace linker.tunnel
TunnelWanPortEndPoint ip = await compactTransfer.GetWanPortAsync(tunnelAdapter.LocalIP, info).ConfigureAwait(false); TunnelWanPortEndPoint ip = await compactTransfer.GetWanPortAsync(tunnelAdapter.LocalIP, info).ConfigureAwait(false);
if (ip != null) if (ip != null)
{ {
PortMapInfo portMapInfo = tunnelAdapter.PortMap ?? new PortMapInfo { LanPort = 0, WanPort = 0 }; MapInfo portMapInfo = TunnelUpnpTransfer.PortMap ?? new MapInfo { PrivatePort = 0, PublicPort = 0 };
var config = tunnelAdapter.GetLocalConfig(); var config = tunnelAdapter.GetLocalConfig();
return new TunnelTransportWanPortInfo return new TunnelTransportWanPortInfo
{ {
@@ -326,8 +328,8 @@ namespace linker.tunnel
LocalIps = config.LocalIps, LocalIps = config.LocalIps,
RouteLevel = config.RouteLevel, RouteLevel = config.RouteLevel,
MachineId = config.MachineId, MachineId = config.MachineId,
PortMapLan = portMapInfo.LanPort, PortMapLan = portMapInfo.PrivatePort,
PortMapWan = portMapInfo.WanPort, PortMapWan = portMapInfo.PublicPort,
}; };
} }
return null; return null;
@@ -426,7 +428,7 @@ namespace linker.tunnel
/// </summary> /// </summary>
/// <param name="remoteMachineId"></param> /// <param name="remoteMachineId"></param>
/// <param name="transactionId"></param> /// <param name="transactionId"></param>
public void StartBackground(string remoteMachineId, string transactionId, TunnelProtocolType denyProtocols, Func<bool> stopCallback, int times = 10,int delay = 10000) public void StartBackground(string remoteMachineId, string transactionId, TunnelProtocolType denyProtocols, Func<bool> stopCallback, int times = 10, int delay = 10000)
{ {
if (AddBackground(remoteMachineId, transactionId) == false) if (AddBackground(remoteMachineId, transactionId) == false)
{ {

View File

@@ -1,6 +1,8 @@
using linker.libs; using linker.libs;
using linker.tunnel.transport;
using Mono.Nat; using Mono.Nat;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Net;
namespace linker.tunnel namespace linker.tunnel
{ {
@@ -11,9 +13,17 @@ namespace linker.tunnel
private readonly ConcurrentDictionary<NatProtocol, INatDevice> natDevices = new ConcurrentDictionary<NatProtocol, INatDevice>(); private readonly ConcurrentDictionary<NatProtocol, INatDevice> natDevices = new ConcurrentDictionary<NatProtocol, INatDevice>();
public MapInfo MapInfo { get; private set; } public MapInfo MapInfo { get; private set; }
public MapInfo MapInfo1 { get; private set; }
public TunnelUpnpTransfer() public MapInfo PortMap => MapInfo1 ?? MapInfo;
private readonly TransportTcpPortMap transportTcpPortMap;
private readonly TransportUdpPortMap transportUdpPortMap;
public TunnelUpnpTransfer(TransportTcpPortMap transportTcpPortMap, TransportUdpPortMap transportUdpPortMap)
{ {
this.transportTcpPortMap = transportTcpPortMap;
this.transportUdpPortMap = transportUdpPortMap;
NatUtility.DeviceFound += DeviceFound; NatUtility.DeviceFound += DeviceFound;
NatUtility.StartDiscovery(); NatUtility.StartDiscovery();
LoopDiscovery(); LoopDiscovery();
@@ -91,9 +101,20 @@ namespace linker.tunnel
return false; return false;
} }
public void SetMap(IPAddress lanIP, int privatePort)
{
int ip = lanIP.GetAddressBytes()[3];
MapInfo = new MapInfo { PrivatePort = privatePort, PublicPort = privatePort + ip };
AddMap();
_ = transportTcpPortMap.Listen(privatePort);
_ = transportUdpPortMap.Listen(privatePort);
}
public void SetMap(int privatePort, int publicPort) public void SetMap(int privatePort, int publicPort)
{ {
MapInfo = new MapInfo { PrivatePort = privatePort, PublicPort = publicPort }; MapInfo1 = new MapInfo { PrivatePort = privatePort, PublicPort = publicPort };
_ = transportTcpPortMap.Listen(privatePort);
_ = transportUdpPortMap.Listen(privatePort);
} }
} }

View File

@@ -12,11 +12,6 @@ namespace linker.tunnel.adapter
/// </summary> /// </summary>
public IPAddress LocalIP { get; } public IPAddress LocalIP { get; }
/// <summary>
/// 端口映射,一般不用管
/// </summary>
public PortMapInfo PortMap { get; }
/// <summary> /// <summary>
/// ssl加密证书没有证书则无法加密通信 /// ssl加密证书没有证书则无法加密通信
/// </summary> /// </summary>

View File

@@ -1,7 +1,6 @@
using linker.config; using linker.config;
using linker.libs; using linker.libs;
using linker.libs.api; using linker.libs.api;
using Microsoft.Extensions.DependencyInjection;
using System.Reflection; using System.Reflection;
namespace linker.plugins.capi namespace linker.plugins.capi
@@ -11,37 +10,25 @@ namespace linker.plugins.capi
/// </summary> /// </summary>
public sealed partial class ApiClientServer : ApiServer, IApiClientServer public sealed partial class ApiClientServer : ApiServer, IApiClientServer
{ {
private readonly ServiceProvider serviceProvider;
private readonly FileConfig config; private readonly FileConfig config;
public ApiClientServer(ServiceProvider serviceProvider, FileConfig config) public ApiClientServer(FileConfig config)
{ {
this.serviceProvider = serviceProvider;
this.config = config; this.config = config;
LoadPlugins();
} }
/// <summary> /// <summary>
/// 加载插件 /// 加载插件
/// </summary> /// </summary>
private void LoadPlugins() public void LoadPlugins(List<object> list)
{ {
Type voidType = typeof(void); Type voidType = typeof(void);
IEnumerable<Type> types = GetSourceGeneratorTypes(); foreach (object obj in list)
foreach (Type item in types)
{ {
object obj = serviceProvider.GetService(item); Type type = obj.GetType();
if (obj == null) string path = type.Name.Replace("ApiController", "").Replace("ApiController", "");
{ foreach (MethodInfo method in type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly))
continue;
}
LoggerHelper.Instance.Info($"load client api:{item.Name}");
string path = item.Name.Replace("ApiController", "").Replace("ApiController", "");
foreach (MethodInfo method in item.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly))
{ {
string key = $"{path}/{method.Name}".ToLower(); string key = $"{path}/{method.Name}".ToLower();
if (plugins.ContainsKey(key) == false) if (plugins.ContainsKey(key) == false)

View File

@@ -0,0 +1,17 @@
using linker.libs;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.capi
{
public sealed partial class ApiClientTypesLoader
{
public ApiClientTypesLoader(IApiClientServer apiClientServer, ServiceProvider serviceProvider)
{
var types = GetSourceGeneratorTypes();
var flows = types.Select(c => serviceProvider.GetService(c)).Where(c => c != null).ToList();
apiClientServer.LoadPlugins(flows);
LoggerHelper.Instance.Info($"load client apis :{string.Join(",", flows.Select(c => c.GetType().Name))}");
}
}
}

View File

@@ -17,10 +17,14 @@ namespace linker.plugins.capi
{ {
serviceCollection.AddSingleton<IApiClientServer, ApiClientServer>(); serviceCollection.AddSingleton<IApiClientServer, ApiClientServer>();
serviceCollection.AddSingleton<IWebClientServer, WebClientServer>(); serviceCollection.AddSingleton<IWebClientServer, WebClientServer>();
serviceCollection.AddSingleton<ApiClientTypesLoader>();
} }
public void UseClient(ServiceProvider serviceProvider, FileConfig config) public void UseClient(ServiceProvider serviceProvider, FileConfig config)
{ {
ApiClientTypesLoader apiClientTypesLoader = serviceProvider.GetService<ApiClientTypesLoader>();
if (config.Data.Client.CApi.ApiPort > 0) if (config.Data.Client.CApi.ApiPort > 0)
{ {
LoggerHelper.Instance.Info($"start client api server"); LoggerHelper.Instance.Info($"start client api server");

View File

@@ -9,6 +9,7 @@ namespace linker.plugins.capi
public interface IApiClientServer : IApiServer public interface IApiClientServer : IApiServer
{ {
public void LoadPlugins(List<object> list);
} }
} }

View File

@@ -8,7 +8,6 @@ using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using linker.plugins.messenger; using linker.plugins.messenger;
using linker.plugins.signIn.args; using linker.plugins.signIn.args;
using linker.plugins.signin;
namespace linker.plugins.client namespace linker.plugins.client
{ {
@@ -20,11 +19,11 @@ namespace linker.plugins.client
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly RunningConfig runningConfig; private readonly RunningConfig runningConfig;
private readonly FileConfig config; private readonly FileConfig config;
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly MessengerResolver messengerResolver; private readonly IMessengerResolver messengerResolver;
private readonly SignInArgsTransfer signInArgsTransfer; private readonly SignInArgsTransfer signInArgsTransfer;
public ClientSignInTransfer(ClientSignInState clientSignInState, RunningConfig runningConfig, FileConfig config, MessengerSender messengerSender, MessengerResolver messengerResolver, SignInArgsTransfer signInArgsTransfer) public ClientSignInTransfer(ClientSignInState clientSignInState, RunningConfig runningConfig, FileConfig config, IMessengerSender messengerSender, IMessengerResolver messengerResolver, SignInArgsTransfer signInArgsTransfer)
{ {
this.clientSignInState = clientSignInState; this.clientSignInState = clientSignInState;
this.runningConfig = runningConfig; this.runningConfig = runningConfig;

View File

@@ -13,9 +13,9 @@ namespace linker.plugins.config
private Dictionary<string, ClientApiAccess> accesss = new Dictionary<string, ClientApiAccess>(); private Dictionary<string, ClientApiAccess> accesss = new Dictionary<string, ClientApiAccess>();
private readonly FileConfig fileConfig; private readonly FileConfig fileConfig;
private readonly MessengerSender sender; private readonly IMessengerSender sender;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
public AccessTransfer(FileConfig fileConfig, MessengerSender sender, ClientSignInState clientSignInState) public AccessTransfer(FileConfig fileConfig, IMessengerSender sender, ClientSignInState clientSignInState)
{ {
this.fileConfig = fileConfig; this.fileConfig = fileConfig;
this.sender = sender; this.sender = sender;

View File

@@ -17,12 +17,12 @@ namespace linker.plugins.config
private readonly RunningConfig runningConfig; private readonly RunningConfig runningConfig;
private readonly FileConfig config; private readonly FileConfig config;
private readonly ClientSignInTransfer clientSignInTransfer; private readonly ClientSignInTransfer clientSignInTransfer;
private readonly MessengerSender sender; private readonly IMessengerSender sender;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly AccessTransfer accessTransfer; private readonly AccessTransfer accessTransfer;
private readonly ConfigSyncTreansfer configSyncTreansfer; private readonly ConfigSyncTreansfer configSyncTreansfer;
public ConfigClientApiController(RunningConfig runningConfig, FileConfig config, ClientSignInTransfer clientSignInTransfer, MessengerSender sender, ClientSignInState clientSignInState, AccessTransfer accessTransfer, ConfigSyncTreansfer configSyncTreansfer) public ConfigClientApiController(RunningConfig runningConfig, FileConfig config, ClientSignInTransfer clientSignInTransfer, IMessengerSender sender, ClientSignInState clientSignInState, AccessTransfer accessTransfer, ConfigSyncTreansfer configSyncTreansfer)
{ {
this.runningConfig = runningConfig; this.runningConfig = runningConfig;
this.config = config; this.config = config;

View File

@@ -30,6 +30,7 @@ namespace linker.plugins.config
serviceCollection.AddSingleton<AccessTransfer>(); serviceCollection.AddSingleton<AccessTransfer>();
serviceCollection.AddSingleton<ConfigSyncTreansfer>(); serviceCollection.AddSingleton<ConfigSyncTreansfer>();
serviceCollection.AddSingleton<ConfigSyncTypesLoader>();
} }
@@ -44,6 +45,7 @@ namespace linker.plugins.config
RunningConfig runningConfig = serviceProvider.GetService<RunningConfig>(); RunningConfig runningConfig = serviceProvider.GetService<RunningConfig>();
ConfigSyncTreansfer configSyncTreansfer = serviceProvider.GetService<ConfigSyncTreansfer>(); ConfigSyncTreansfer configSyncTreansfer = serviceProvider.GetService<ConfigSyncTreansfer>();
ConfigSyncTypesLoader configSyncTypesLoader = serviceProvider.GetService<ConfigSyncTypesLoader>();
} }
public void UseServer(ServiceProvider serviceProvider, FileConfig config) public void UseServer(ServiceProvider serviceProvider, FileConfig config)

View File

@@ -22,21 +22,22 @@ namespace linker.plugins.config
public Memory<byte> Data { get; set; } public Memory<byte> Data { get; set; }
} }
public sealed partial class ConfigSyncTreansfer public sealed class ConfigSyncTreansfer
{ {
private readonly SemaphoreSlim slim = new SemaphoreSlim(1); private readonly SemaphoreSlim slim = new SemaphoreSlim(1);
private List<IConfigSync> syncs = new List<IConfigSync>(); private List<IConfigSync> syncs = new List<IConfigSync>();
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
public ConfigSyncTreansfer(ServiceProvider serviceProvider, MessengerSender messengerSender, ClientSignInState clientSignInState) public ConfigSyncTreansfer(IMessengerSender messengerSender, ClientSignInState clientSignInState)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.clientSignInState = clientSignInState; this.clientSignInState = clientSignInState;
}
IEnumerable<Type> types = GetSourceGeneratorTypes(); public void LoadConfigSyncs(List<IConfigSync> list)
syncs = types.Select(c => (IConfigSync)serviceProvider.GetService(c)).Where(c => c != null).Where(c => string.IsNullOrWhiteSpace(c.Name) == false).ToList(); {
LoggerHelper.Instance.Info($"load config sync transport:{string.Join(",", syncs.Select(c => c.Name))}"); syncs = list;
} }
public List<string> GetNames() public List<string> GetNames()

View File

@@ -0,0 +1,17 @@
using linker.libs;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.config
{
public sealed partial class ConfigSyncTypesLoader
{
public ConfigSyncTypesLoader(ConfigSyncTreansfer configSyncTreansfer, ServiceProvider serviceProvider)
{
var types = GetSourceGeneratorTypes();
var syncs = types.Select(c => (IConfigSync)serviceProvider.GetService(c)).Where(c => c != null).ToList();
configSyncTreansfer.LoadConfigSyncs(syncs);
LoggerHelper.Instance.Info($"load config sync transport:{string.Join(",", syncs.Select(c => c.GetType().Name))}");
}
}
}

View File

@@ -1,5 +1,4 @@
using linker.client.config; using linker.config;
using linker.config;
using linker.libs; using linker.libs;
using linker.plugins.client; using linker.plugins.client;
using linker.plugins.messenger; using linker.plugins.messenger;
@@ -10,10 +9,10 @@ namespace linker.plugins.config.messenger
{ {
public sealed class ConfigServerMessenger : IMessenger public sealed class ConfigServerMessenger : IMessenger
{ {
private readonly MessengerSender sender; private readonly IMessengerSender sender;
private readonly SignCaching signCaching; private readonly SignCaching signCaching;
public ConfigServerMessenger(MessengerSender sender, SignCaching signCaching) public ConfigServerMessenger(IMessengerSender sender, SignCaching signCaching)
{ {
this.sender = sender; this.sender = sender;
this.signCaching = signCaching; this.signCaching = signCaching;

View File

@@ -0,0 +1,34 @@
using linker.plugins.tunnel;
namespace linker.plugins.flow
{
public sealed class ExternalFlow : IFlow
{
public ulong ReceiveBytes { get; private set; }
public ulong SendtBytes { get; private set; }
public string FlowName => "External";
public ExternalFlow()
{
}
public void AddReceive(ulong bytes) { ReceiveBytes += bytes; }
public void AddSendt(ulong bytes) { SendtBytes += bytes; }
}
/// <summary>
/// 外网端口处理器
/// </summary>
public sealed class ExternalResolverFlow : ExternalResolver
{
private readonly ExternalFlow externalFlow;
public ExternalResolverFlow(ExternalFlow externalFlow)
{
this.externalFlow = externalFlow;
}
public override void AddReceive(ulong bytes) { externalFlow.AddReceive(bytes); }
public override void AddSendt(ulong bytes) { externalFlow.AddSendt(bytes); }
}
}

View File

@@ -14,12 +14,12 @@ namespace linker.plugins.flow
{ {
public sealed class FlowClientApiController : IApiClientController public sealed class FlowClientApiController : IApiClientController
{ {
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly FileConfig config; private readonly FileConfig config;
private readonly RunningConfig runningConfig; private readonly RunningConfig runningConfig;
public FlowClientApiController(MessengerSender messengerSender, ClientSignInState clientSignInState, FileConfig config, RunningConfig runningConfig) public FlowClientApiController(IMessengerSender messengerSender, ClientSignInState clientSignInState, FileConfig config, RunningConfig runningConfig)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.clientSignInState = clientSignInState; this.clientSignInState = clientSignInState;

View File

@@ -1,5 +1,9 @@
using linker.config; using linker.config;
using linker.plugins.flow.messenger; using linker.plugins.flow.messenger;
using linker.plugins.messenger;
using linker.plugins.relay;
using linker.plugins.sforward.proxy;
using linker.plugins.tunnel;
using linker.startup; using linker.startup;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@@ -7,7 +11,7 @@ namespace linker.plugins.flow
{ {
public sealed class FlowStartup : IStartup public sealed class FlowStartup : IStartup
{ {
public StartupLevel Level => StartupLevel.Normal; public StartupLevel Level => StartupLevel.Bottom;
public string Name => "flow"; public string Name => "flow";
public bool Required => false; public bool Required => false;
public string[] Dependent => new string[] { }; public string[] Dependent => new string[] { };
@@ -17,23 +21,45 @@ namespace linker.plugins.flow
{ {
serviceCollection.AddSingleton<FlowClientApiController>(); serviceCollection.AddSingleton<FlowClientApiController>();
serviceCollection.AddSingleton<FlowTransfer>(); serviceCollection.AddSingleton<FlowTransfer>();
serviceCollection.AddSingleton<FlowTypesLoader>();
serviceCollection.AddSingleton<MessengerFlow>();
serviceCollection.AddSingleton<IMessengerResolver,MessengerResolverFlow>();
serviceCollection.AddSingleton<IMessengerSender,MessengerSenderFlow>();
serviceCollection.AddSingleton<RelayFlow>();
serviceCollection.AddSingleton<RelayResolver, RelayResolverFlow>();
} }
public void AddServer(ServiceCollection serviceCollection, FileConfig config) public void AddServer(ServiceCollection serviceCollection, FileConfig config)
{ {
serviceCollection.AddSingleton<FlowMessenger>(); serviceCollection.AddSingleton<FlowMessenger>();
serviceCollection.AddSingleton<FlowTransfer>(); serviceCollection.AddSingleton<FlowTransfer>();
serviceCollection.AddSingleton<FlowTypesLoader>();
serviceCollection.AddSingleton<FlowResolver>(); serviceCollection.AddSingleton<FlowResolver>();
serviceCollection.AddSingleton<MessengerFlow>();
serviceCollection.AddSingleton<IMessengerResolver, MessengerResolverFlow>();
serviceCollection.AddSingleton<IMessengerSender, MessengerSenderFlow>();
serviceCollection.AddSingleton<RelayFlow>();
serviceCollection.AddSingleton<RelayResolver, RelayResolverFlow>();
serviceCollection.AddSingleton<ExternalFlow>();
serviceCollection.AddSingleton<ExternalResolver, ExternalResolverFlow>();
serviceCollection.AddSingleton<SForwardFlow>();
serviceCollection.AddSingleton<SForwardProxy, SForwardProxyFlow>();
} }
public void UseClient(ServiceProvider serviceProvider, FileConfig config) public void UseClient(ServiceProvider serviceProvider, FileConfig config)
{ {
FlowTransfer flowTransfer = serviceProvider.GetService<FlowTransfer>(); FlowTypesLoader flowTypesLoader = serviceProvider.GetService<FlowTypesLoader>();
} }
public void UseServer(ServiceProvider serviceProvider, FileConfig config) public void UseServer(ServiceProvider serviceProvider, FileConfig config)
{ {
FlowTransfer flowTransfer = serviceProvider.GetService<FlowTransfer>(); FlowTypesLoader flowTypesLoader = serviceProvider.GetService<FlowTypesLoader>();
} }
} }
} }

View File

@@ -1,14 +1,15 @@
using Microsoft.Extensions.DependencyInjection; namespace linker.plugins.flow
namespace linker.plugins.flow
{ {
public sealed partial class FlowTransfer public sealed class FlowTransfer
{ {
private List<IFlow> flows = new List<IFlow>(); private List<IFlow> flows = new List<IFlow>();
public FlowTransfer()
public FlowTransfer(ServiceProvider serviceProvider)
{ {
var types = GetSourceGeneratorTypes(); }
flows = types.Select(c => (IFlow)serviceProvider.GetService(c)).Where(c => c != null).ToList();
public void LoadFlows(List<IFlow> flows)
{
this.flows = flows;
} }
public Dictionary<string, FlowItemInfo> GetFlows() public Dictionary<string, FlowItemInfo> GetFlows()

View File

@@ -0,0 +1,16 @@
using linker.libs;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.flow
{
public sealed partial class FlowTypesLoader
{
public FlowTypesLoader(FlowTransfer flowTransfer, ServiceProvider serviceProvider)
{
var types = GetSourceGeneratorTypes();
var flows = types.Select(c => (IFlow)serviceProvider.GetService(c)).Where(c => c != null).ToList();
flowTransfer.LoadFlows(flows);
LoggerHelper.Instance.Info($"load flows :{string.Join(",", flows.Select(c => c.GetType().Name))}");
}
}
}

View File

@@ -1,8 +1,46 @@
using linker.plugins.flow; using linker.plugins.messenger;
namespace linker.plugins.messenger namespace linker.plugins.flow
{ {
public sealed class MessengerFlow : IFlow
public sealed class MessengerResolverFlow : MessengerResolver
{
private readonly MessengerFlow messengerFlow;
public MessengerResolverFlow(IMessengerSender sender, MessengerFlow messengerFlow) : base(sender)
{
this.messengerFlow = messengerFlow;
}
public override void AddReceive(ushort id, ulong bytes)
{
messengerFlow.AddReceive(id, bytes);
}
public override void AddSendt(ushort id, ulong bytes)
{
messengerFlow.AddSendt(id, bytes);
}
}
public sealed class MessengerSenderFlow : MessengerSender
{
private readonly MessengerFlow messengerFlow;
public MessengerSenderFlow(MessengerFlow messengerFlow)
{
this.messengerFlow = messengerFlow;
}
public override void AddReceive(ushort id, ulong bytes)
{
messengerFlow.AddReceive(id, bytes);
}
public override void AddSendt(ushort id, ulong bytes)
{
messengerFlow.AddSendt(id, bytes);
}
}
public sealed class MessengerFlow : IFlow
{ {
public ulong ReceiveBytes { get; private set; } public ulong ReceiveBytes { get; private set; }
public ulong SendtBytes { get; private set; } public ulong SendtBytes { get; private set; }

View File

@@ -1,10 +1,37 @@
using linker.libs; using linker.libs;
using linker.plugins.flow; using linker.plugins.relay;
using MemoryPack; using MemoryPack;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace linker.plugins.relay namespace linker.plugins.flow
{ {
public sealed class RelayResolverFlow : RelayResolver
{
private readonly RelayFlow relayFlow;
public RelayResolverFlow(RelayFlow relayFlow)
{
this.relayFlow = relayFlow;
}
public override void AddReceive(string key, string from, string to, ulong bytes)
{
relayFlow.AddReceive(key, from, to, bytes);
}
public override void AddSendt(string key, string from, string to, ulong bytes)
{
relayFlow.AddSendt(key, from, to, bytes);
}
public override void AddReceive(string key, ulong bytes)
{
relayFlow.AddReceive(key, bytes);
}
public override void AddSendt(string key, ulong bytes)
{
relayFlow.AddSendt(key, bytes);
}
}
public sealed class RelayFlow : IFlow public sealed class RelayFlow : IFlow
{ {
public ulong ReceiveBytes { get; private set; } public ulong ReceiveBytes { get; private set; }
@@ -78,6 +105,7 @@ namespace linker.plugins.relay
} }
} }
public RelayFlowResponseInfo GetFlows(RelayFlowRequestInfo info) public RelayFlowResponseInfo GetFlows(RelayFlowRequestInfo info)
{ {
var items = flows.Values.Where(c => string.IsNullOrWhiteSpace(info.Key) || c.FromName.Contains(info.Key) || c.ToName.Contains(info.Key)); var items = flows.Values.Where(c => string.IsNullOrWhiteSpace(info.Key) || c.FromName.Contains(info.Key) || c.ToName.Contains(info.Key));

View File

@@ -1,10 +1,27 @@
using linker.libs; using linker.libs;
using linker.plugins.flow; using linker.plugins.sforward.proxy;
using MemoryPack; using MemoryPack;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace linker.plugins.sforward.proxy namespace linker.plugins.flow
{ {
public sealed class SForwardProxyFlow: SForwardProxy
{
private readonly SForwardFlow sForwardFlow;
public SForwardProxyFlow(SForwardFlow sForwardFlow)
{
this.sForwardFlow = sForwardFlow;
}
public override void AddReceive(string key, ulong bytes)
{
sForwardFlow.AddReceive(key, bytes);
}
public override void AddSendt(string key, ulong bytes)
{
sForwardFlow.AddSendt(key, bytes);
}
}
public sealed class SForwardFlow : IFlow public sealed class SForwardFlow : IFlow
{ {
public ulong ReceiveBytes { get; private set; } public ulong ReceiveBytes { get; private set; }

View File

@@ -8,7 +8,6 @@ namespace linker.plugins.flow.messenger
{ {
public sealed class FlowMessenger : IMessenger public sealed class FlowMessenger : IMessenger
{ {
private readonly MessengerResolver messengerResolver;
private readonly FlowTransfer flowTransfer; private readonly FlowTransfer flowTransfer;
private readonly MessengerFlow messengerFlow; private readonly MessengerFlow messengerFlow;
private readonly SForwardFlow sForwardFlow; private readonly SForwardFlow sForwardFlow;
@@ -17,9 +16,8 @@ namespace linker.plugins.flow.messenger
private DateTime start = DateTime.Now; private DateTime start = DateTime.Now;
public FlowMessenger(MessengerResolver messengerResolver, FlowTransfer flowTransfer, MessengerFlow messengerFlow, SForwardFlow sForwardFlow, RelayFlow relayFlow, SignCaching signCaching) public FlowMessenger( FlowTransfer flowTransfer, MessengerFlow messengerFlow, SForwardFlow sForwardFlow, RelayFlow relayFlow, SignCaching signCaching)
{ {
this.messengerResolver = messengerResolver;
this.flowTransfer = flowTransfer; this.flowTransfer = flowTransfer;
this.messengerFlow = messengerFlow; this.messengerFlow = messengerFlow;
this.sForwardFlow = sForwardFlow; this.sForwardFlow = sForwardFlow;

View File

@@ -19,12 +19,12 @@ namespace linker.plugins.forward
{ {
private readonly ForwardTransfer forwardTransfer; private readonly ForwardTransfer forwardTransfer;
private readonly ForwardProxy forwardProxy; private readonly ForwardProxy forwardProxy;
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
public ForwardClientApiController(ForwardTransfer forwardTransfer, ForwardProxy forwardProxy, MessengerSender messengerSender, ClientSignInState clientSignInState) public ForwardClientApiController(ForwardTransfer forwardTransfer, ForwardProxy forwardProxy, IMessengerSender messengerSender, ClientSignInState clientSignInState)
{ {
this.forwardTransfer = forwardTransfer; this.forwardTransfer = forwardTransfer;
this.forwardProxy = forwardProxy; this.forwardProxy = forwardProxy;

View File

@@ -18,13 +18,13 @@ namespace linker.plugins.forward
private readonly RunningConfig running; private readonly RunningConfig running;
private readonly ForwardProxy forwardProxy; private readonly ForwardProxy forwardProxy;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly NumberSpaceUInt32 ns = new NumberSpaceUInt32(); private readonly NumberSpaceUInt32 ns = new NumberSpaceUInt32();
public VersionManager Version { get; } = new VersionManager(); public VersionManager Version { get; } = new VersionManager();
public ForwardTransfer(RunningConfig running, ForwardProxy forwardProxy, ClientSignInState clientSignInState, MessengerSender messengerSender) public ForwardTransfer(RunningConfig running, ForwardProxy forwardProxy, ClientSignInState clientSignInState, IMessengerSender messengerSender)
{ {
this.running = running; this.running = running;
this.forwardProxy = forwardProxy; this.forwardProxy = forwardProxy;

View File

@@ -10,10 +10,10 @@ namespace linker.plugins.forward.messenger
public sealed class ForwardServerMessenger : IMessenger public sealed class ForwardServerMessenger : IMessenger
{ {
private readonly MessengerSender sender; private readonly IMessengerSender sender;
private readonly SignCaching signCaching; private readonly SignCaching signCaching;
public ForwardServerMessenger(MessengerSender sender, SignCaching signCaching) public ForwardServerMessenger(IMessengerSender sender, SignCaching signCaching)
{ {
this.sender = sender; this.sender = sender;
this.signCaching = signCaching; this.signCaching = signCaching;
@@ -80,9 +80,9 @@ namespace linker.plugins.forward.messenger
public sealed class ForwardClientMessenger : IMessenger public sealed class ForwardClientMessenger : IMessenger
{ {
private readonly ForwardTransfer forwardTransfer; private readonly ForwardTransfer forwardTransfer;
private readonly MessengerSender sender; private readonly IMessengerSender sender;
public ForwardClientMessenger(ForwardTransfer forwardTransfer, MessengerSender sender) public ForwardClientMessenger(ForwardTransfer forwardTransfer, IMessengerSender sender)
{ {
this.forwardTransfer = forwardTransfer; this.forwardTransfer = forwardTransfer;
this.sender = sender; this.sender = sender;

View File

@@ -1,5 +1,4 @@
using linker.libs; using linker.libs;
using Microsoft.Extensions.DependencyInjection;
using System.Net.Security; using System.Net.Security;
using System.Net.Sockets; using System.Net.Sockets;
using System.Net; using System.Net;
@@ -8,35 +7,56 @@ using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using linker.libs.extends; using linker.libs.extends;
using linker.plugins.resolver; using linker.plugins.resolver;
using MemoryPack;
namespace linker.plugins.messenger namespace linker.plugins.messenger
{ {
/// <summary> public interface IMessengerResolver
/// 消息处理总线 {
/// </summary> public void Initialize(string certificate, string password);
public sealed class MessengerResolver : IConnectionReceiveCallback, IResolver public Task<IConnection> BeginReceiveClient(Socket socket);
public void LoadMessenger(List<IMessenger> list);
public Task Resolve(Socket socket, Memory<byte> memory);
public Task Resolve(Socket socket, IPEndPoint ep, Memory<byte> memory);
}
public sealed class MessengerResolverResolver : IResolver
{ {
public ResolverType Type => ResolverType.Messenger; public ResolverType Type => ResolverType.Messenger;
private readonly IMessengerResolver messengerResolver;
public MessengerResolverResolver(IMessengerResolver messengerResolver)
{
this.messengerResolver = messengerResolver;
}
public async Task Resolve(Socket socket, Memory<byte> memory)
{
await messengerResolver.Resolve(socket, memory);
}
public async Task Resolve(Socket socket, IPEndPoint ep, Memory<byte> memory)
{
await messengerResolver.Resolve(socket, ep, memory);
}
}
/// <summary>
/// 消息处理总线
/// </summary>
public class MessengerResolver : IConnectionReceiveCallback, IMessengerResolver
{
delegate void VoidDelegate(IConnection connection); delegate void VoidDelegate(IConnection connection);
delegate Task TaskDelegate(IConnection connection); delegate Task TaskDelegate(IConnection connection);
private readonly Dictionary<ushort, MessengerCacheInfo> messengers = new(); private readonly Dictionary<ushort, MessengerCacheInfo> messengers = new();
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly ServiceProvider serviceProvider;
private readonly MessengerFlow messengerFlow;
private X509Certificate serverCertificate; private X509Certificate serverCertificate;
public MessengerResolver(MessengerSender messengerSender, ServiceProvider serviceProvider, MessengerFlow messengerFlow) public MessengerResolver(IMessengerSender messengerSender)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.serviceProvider = serviceProvider;
this.messengerFlow = messengerFlow;
} }
public void Init(string certificate, string password) public void Initialize(string certificate, string password)
{ {
string path = Path.GetFullPath(certificate); string path = Path.GetFullPath(certificate);
if (File.Exists(path)) if (File.Exists(path))
@@ -50,6 +70,11 @@ namespace linker.plugins.messenger
} }
} }
public virtual void AddReceive(ushort id, ulong bytes) { }
public virtual void AddSendt(ushort id, ulong bytes) { }
public async Task Resolve(Socket socket, Memory<byte> memory) public async Task Resolve(Socket socket, Memory<byte> memory)
{ {
try try
@@ -106,6 +131,7 @@ namespace linker.plugins.messenger
{ {
return true; return true;
} }
private IConnection CreateConnection(SslStream stream, NetworkStream networkStream, Socket socket, IPEndPoint local, IPEndPoint remote) private IConnection CreateConnection(SslStream stream, NetworkStream networkStream, Socket socket, IPEndPoint local, IPEndPoint remote)
{ {
return new TcpConnection(stream, networkStream, socket, local, remote) return new TcpConnection(stream, networkStream, socket, local, remote)
@@ -118,21 +144,14 @@ namespace linker.plugins.messenger
/// <summary> /// <summary>
/// 加载所有消息处理器 /// 加载所有消息处理器
/// </summary> /// </summary>
public void LoadMessenger() public void LoadMessenger(List<IMessenger> list)
{ {
Type voidType = typeof(void); Type voidType = typeof(void);
Type midType = typeof(MessengerIdAttribute); Type midType = typeof(MessengerIdAttribute);
IEnumerable<Type> types = MessengerResolverTypes.GetSourceGeneratorTypes();
foreach (Type type in types.Distinct()) foreach (IMessenger messenger in list.Distinct())
{ {
object obj = serviceProvider.GetService(type); Type type = messenger.GetType();
if (obj == null)
{
continue;
}
LoggerHelper.Instance.Info($"load messenger:{type.Name}");
foreach (var method in type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)) foreach (var method in type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly))
{ {
MessengerIdAttribute mid = method.GetCustomAttribute(midType) as MessengerIdAttribute; MessengerIdAttribute mid = method.GetCustomAttribute(midType) as MessengerIdAttribute;
@@ -142,24 +161,20 @@ namespace linker.plugins.messenger
{ {
MessengerCacheInfo cache = new MessengerCacheInfo MessengerCacheInfo cache = new MessengerCacheInfo
{ {
Target = obj Target = messenger
}; };
//void方法 //void方法
if (method.ReturnType == voidType) if (method.ReturnType == voidType)
{ {
cache.VoidMethod = (VoidDelegate)Delegate.CreateDelegate(typeof(VoidDelegate), obj, method); cache.VoidMethod = (VoidDelegate)Delegate.CreateDelegate(typeof(VoidDelegate), messenger, method);
} }
//异步方法 //异步方法
else if (method.ReturnType.GetProperty("IsCompleted") != null && method.ReturnType.GetMethod("GetAwaiter") != null) else if (method.ReturnType.GetProperty("IsCompleted") != null && method.ReturnType.GetMethod("GetAwaiter") != null)
{ {
cache.TaskMethod = (TaskDelegate)Delegate.CreateDelegate(typeof(TaskDelegate), obj, method); cache.TaskMethod = (TaskDelegate)Delegate.CreateDelegate(typeof(TaskDelegate), messenger, method);
} }
messengers.TryAdd(mid.Id, cache); messengers.TryAdd(mid.Id, cache);
} }
else
{
LoggerHelper.Instance.Warning($"{type.Name}->{method.Name}->{mid.Id} 消息id已存在");
}
} }
} }
} }
@@ -189,7 +204,7 @@ namespace linker.plugins.messenger
//新的请求 //新的请求
requestWrap.FromArray(data); requestWrap.FromArray(data);
messengerFlow.AddReceive(requestWrap.MessengerId, (ulong)data.Length); AddReceive(requestWrap.MessengerId, (ulong)data.Length);
//404,没这个插件 //404,没这个插件
if (messengers.TryGetValue(requestWrap.MessengerId, out MessengerCacheInfo plugin) == false) if (messengers.TryGetValue(requestWrap.MessengerId, out MessengerCacheInfo plugin) == false)
{ {
@@ -256,16 +271,4 @@ namespace linker.plugins.messenger
} }
} }
public static partial class MessengerResolverTypes
{
}
[MemoryPackable]
public sealed partial class MessengerFlowItemInfo
{
public ulong ReceiveBytes { get; set; }
public ulong SendtBytes { get; set; }
}
} }

View File

@@ -0,0 +1,17 @@
using linker.libs;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.messenger
{
public sealed partial class MessengerResolverTypesLoader
{
public MessengerResolverTypesLoader(IMessengerResolver messengerResolver, ServiceProvider serviceProvider)
{
var types = GetSourceGeneratorTypes();
var messengers = types.Select(c => (IMessenger)serviceProvider.GetService(c)).Where(c => c != null).ToList();
messengerResolver.LoadMessenger(messengers);
LoggerHelper.Instance.Info($"load messengers :{string.Join(",", messengers.Select(c => c.GetType().Name))}");
}
}
}

View File

@@ -3,20 +3,49 @@ using System.Collections.Concurrent;
namespace linker.plugins.messenger namespace linker.plugins.messenger
{ {
public interface IMessengerSender
{
/// <summary>
/// 发送并等待回复
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public Task<MessageResponeInfo> SendReply(MessageRequestWrap msg);
/// <summary>
/// 仅发送
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public Task<bool> SendOnly(MessageRequestWrap msg);
/// <summary>
/// 仅回复
/// </summary>
/// <param name="msg"></param>
/// <param name="messengerId"></param>
/// <returns></returns>
public ValueTask<bool> ReplyOnly(MessageResponseWrap msg, ushort messengerId);
/// <summary>
/// 回复
/// </summary>
/// <param name="wrap"></param>
public void Response(MessageResponseWrap wrap);
}
/// <summary> /// <summary>
/// 消息发送器 /// 消息发送器
/// </summary> /// </summary>
public sealed class MessengerSender public class MessengerSender : IMessengerSender
{ {
public NumberSpaceUInt32 requestIdNumberSpace = new NumberSpaceUInt32(0); public NumberSpaceUInt32 requestIdNumberSpace = new NumberSpaceUInt32(0);
private ConcurrentDictionary<uint, ReplyWrapInfo> sends = new ConcurrentDictionary<uint, ReplyWrapInfo>(); private ConcurrentDictionary<uint, ReplyWrapInfo> sends = new ConcurrentDictionary<uint, ReplyWrapInfo>();
private readonly MessengerFlow messengerFlow; public MessengerSender()
public MessengerSender(MessengerFlow messengerFlow)
{ {
this.messengerFlow = messengerFlow;
} }
public virtual void AddReceive(ushort id, ulong bytes) { }
public virtual void AddSendt(ushort id, ulong bytes) { }
/// <summary> /// <summary>
/// 发送并等待回复 /// 发送并等待回复
/// </summary> /// </summary>
@@ -84,7 +113,7 @@ namespace linker.plugins.messenger
byte[] bytes = msg.ToArray(out int length); byte[] bytes = msg.ToArray(out int length);
messengerFlow.AddSendt(msg.MessengerId, (ulong)bytes.Length); AddSendt(msg.MessengerId, (ulong)bytes.Length);
bool res = await msg.Connection.SendAsync(bytes.AsMemory(0, length)).ConfigureAwait(false); bool res = await msg.Connection.SendAsync(bytes.AsMemory(0, length)).ConfigureAwait(false);
msg.Return(bytes); msg.Return(bytes);
@@ -102,7 +131,7 @@ namespace linker.plugins.messenger
/// </summary> /// </summary>
/// <param name="msg"></param> /// <param name="msg"></param>
/// <returns></returns> /// <returns></returns>
public async ValueTask<bool> ReplyOnly(MessageResponseWrap msg,ushort messengerId) public async ValueTask<bool> ReplyOnly(MessageResponseWrap msg, ushort messengerId)
{ {
if (msg.Connection == null) if (msg.Connection == null)
{ {
@@ -114,7 +143,7 @@ namespace linker.plugins.messenger
byte[] bytes = msg.ToArray(out int length); byte[] bytes = msg.ToArray(out int length);
messengerFlow.AddSendt(messengerId, (ulong)length); AddSendt(messengerId, (ulong)length);
bool res = await msg.Connection.SendAsync(bytes.AsMemory(0, length)).ConfigureAwait(false); bool res = await msg.Connection.SendAsync(bytes.AsMemory(0, length)).ConfigureAwait(false);
msg.Return(bytes); msg.Return(bytes);
@@ -138,7 +167,7 @@ namespace linker.plugins.messenger
byte[] bytes = new byte[wrap.Payload.Length]; byte[] bytes = new byte[wrap.Payload.Length];
wrap.Payload.CopyTo(bytes); wrap.Payload.CopyTo(bytes);
messengerFlow.AddReceive(info.MessengerId, (ulong)bytes.Length); AddReceive(info.MessengerId, (ulong)bytes.Length);
info.Tcs.SetResult(new MessageResponeInfo { Code = wrap.Code, Data = bytes, Connection = wrap.Connection }); info.Tcs.SetResult(new MessageResponeInfo { Code = wrap.Code, Data = bytes, Connection = wrap.Connection });
} }
} }

View File

@@ -18,17 +18,21 @@ namespace linker.plugins.messenger
public void AddClient(ServiceCollection serviceCollection, FileConfig config) public void AddClient(ServiceCollection serviceCollection, FileConfig config)
{ {
serviceCollection.AddSingleton<MessengerSender>(); serviceCollection.AddSingleton<IMessengerSender, MessengerSender>();
serviceCollection.AddSingleton<MessengerResolver>(); serviceCollection.AddSingleton<IMessengerResolver, MessengerResolver>();
serviceCollection.AddSingleton<MessengerFlow>(); serviceCollection.AddSingleton<MessengerResolverResolver>();
serviceCollection.AddSingleton<MessengerResolverTypesLoader>();
} }
public void AddServer(ServiceCollection serviceCollection, FileConfig config) public void AddServer(ServiceCollection serviceCollection, FileConfig config)
{ {
serviceCollection.AddSingleton<MessengerSender>(); serviceCollection.AddSingleton<IMessengerSender, MessengerSender>();
serviceCollection.AddSingleton<MessengerResolver>(); serviceCollection.AddSingleton<IMessengerResolver, MessengerResolver>();
serviceCollection.AddSingleton<MessengerFlow>(); serviceCollection.AddSingleton<MessengerResolverResolver>();
serviceCollection.AddSingleton<MessengerResolverTypesLoader>();
} }
@@ -39,9 +43,10 @@ namespace linker.plugins.messenger
{ {
loaded = true; loaded = true;
MessengerResolver messengerResolver = serviceProvider.GetService<MessengerResolver>(); IMessengerResolver messengerResolver = serviceProvider.GetService<IMessengerResolver>();
messengerResolver.LoadMessenger(); messengerResolver.Initialize(config.Data.Client.SSL.File, config.Data.Client.SSL.Password);
messengerResolver.Init(config.Data.Client.SSL.File, config.Data.Client.SSL.Password);
MessengerResolverTypesLoader messengerResolverTypesLoader = serviceProvider.GetService<MessengerResolverTypesLoader>();
} }
} }
@@ -52,10 +57,10 @@ namespace linker.plugins.messenger
{ {
loaded = true; loaded = true;
MessengerResolver messengerResolver = serviceProvider.GetService<MessengerResolver>(); IMessengerResolver messengerResolver = serviceProvider.GetService<IMessengerResolver>();
messengerResolver.LoadMessenger(); messengerResolver.Initialize(config.Data.Server.SSL.File, config.Data.Server.SSL.Password);
messengerResolver.Init(config.Data.Server.SSL.File, config.Data.Server.SSL.Password);
MessengerResolverTypesLoader messengerResolverTypesLoader = serviceProvider.GetService<MessengerResolverTypesLoader>();
} }
} }
} }

View File

@@ -15,9 +15,9 @@ namespace linker.plugins.relay
private readonly FileConfig config; private readonly FileConfig config;
private readonly RelayTransfer relayTransfer; private readonly RelayTransfer relayTransfer;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
public RelayApiController(FileConfig config, RelayTransfer relayTransfer, ClientSignInState clientSignInState, MessengerSender messengerSender) public RelayApiController(FileConfig config, RelayTransfer relayTransfer, ClientSignInState clientSignInState, IMessengerSender messengerSender)
{ {
this.config = config; this.config = config;
this.relayTransfer = relayTransfer; this.relayTransfer = relayTransfer;

View File

@@ -10,14 +10,12 @@ namespace linker.plugins.relay
/// <summary> /// <summary>
/// 中继连接处理 /// 中继连接处理
/// </summary> /// </summary>
public sealed class RelayResolver : IResolver public class RelayResolver : IResolver
{ {
public ResolverType Type => ResolverType.Relay; public ResolverType Type => ResolverType.Relay;
private readonly RelayFlow relayFlow; public RelayResolver()
public RelayResolver(RelayFlow relayFlow)
{ {
this.relayFlow = relayFlow;
} }
private readonly ConcurrentDictionary<ulong, RelayWrap> relayDic = new ConcurrentDictionary<ulong, RelayWrap>(); private readonly ConcurrentDictionary<ulong, RelayWrap> relayDic = new ConcurrentDictionary<ulong, RelayWrap>();
@@ -50,6 +48,22 @@ namespace linker.plugins.relay
return flowingId; return flowingId;
} }
public virtual void AddReceive(string key, string from, string to, ulong bytes)
{
}
public virtual void AddSendt(string key, string from, string to, ulong bytes)
{
}
public virtual void AddReceive(string key, ulong bytes)
{
}
public virtual void AddSendt(string key, ulong bytes)
{
}
public async Task Resolve(Socket socket, IPEndPoint ep, Memory<byte> memory) public async Task Resolve(Socket socket, IPEndPoint ep, Memory<byte> memory)
{ {
await Task.CompletedTask; await Task.CompletedTask;
@@ -67,7 +81,7 @@ namespace linker.plugins.relay
socket.SafeClose(); socket.SafeClose();
return; return;
} }
relayFlow.AddReceive(relayWrap.FromId, relayWrap.FromName, relayWrap.ToName, (ulong)length); AddReceive(relayWrap.FromId, relayWrap.FromName, relayWrap.ToName, (ulong)length);
try try
{ {
if (relayMessage.Type == RelayMessengerType.Ask) if (relayMessage.Type == RelayMessengerType.Ask)
@@ -121,8 +135,8 @@ namespace linker.plugins.relay
int bytesRead; int bytesRead;
while ((bytesRead = await source.ReceiveAsync(buffer.AsMemory()).ConfigureAwait(false)) != 0) while ((bytesRead = await source.ReceiveAsync(buffer.AsMemory()).ConfigureAwait(false)) != 0)
{ {
relayFlow.AddReceive(fromid, fromName, toName, (ulong)bytesRead); AddReceive(fromid, fromName, toName, (ulong)bytesRead);
relayFlow.AddSendt(fromid, fromName, toName, (ulong)bytesRead); AddSendt(fromid, fromName, toName, (ulong)bytesRead);
await destination.SendAsync(buffer.AsMemory(0, bytesRead)).ConfigureAwait(false); await destination.SendAsync(buffer.AsMemory(0, bytesRead)).ConfigureAwait(false);
} }
} }

View File

@@ -27,10 +27,11 @@ namespace linker.plugins.relay
serviceCollection.AddSingleton<RelayClientMessenger>(); serviceCollection.AddSingleton<RelayClientMessenger>();
serviceCollection.AddSingleton<TransportSelfHost>(); serviceCollection.AddSingleton<TransportSelfHost>();
serviceCollection.AddSingleton<RelayTransfer>(); serviceCollection.AddSingleton<RelayTransfer>();
serviceCollection.AddSingleton<RelayFlow>();
serviceCollection.AddSingleton<ConfigSyncRelaySecretKey>(); serviceCollection.AddSingleton<ConfigSyncRelaySecretKey>();
serviceCollection.AddSingleton<RelayTypesLoader>();
} }
public void AddServer(ServiceCollection serviceCollection, FileConfig config) public void AddServer(ServiceCollection serviceCollection, FileConfig config)
@@ -40,20 +41,21 @@ namespace linker.plugins.relay
serviceCollection.AddSingleton<RelayResolver>(); serviceCollection.AddSingleton<RelayResolver>();
serviceCollection.AddSingleton<RelayValidatorTransfer>(); serviceCollection.AddSingleton<RelayValidatorTransfer>();
serviceCollection.AddSingleton<RelayValidatorSecretKey>(); serviceCollection.AddSingleton<RelayValidatorTypeLoader>();
serviceCollection.AddSingleton<RelayFlow>(); serviceCollection.AddSingleton<RelayValidatorSecretKey>();
} }
public void UseClient(ServiceProvider serviceProvider, FileConfig config) public void UseClient(ServiceProvider serviceProvider, FileConfig config)
{ {
RelayTransfer relayTransfer = serviceProvider.GetService<RelayTransfer>(); RelayTransfer relayTransfer = serviceProvider.GetService<RelayTransfer>();
RelayTypesLoader relayTypesLoader = serviceProvider.GetService<RelayTypesLoader>();
} }
public void UseServer(ServiceProvider serviceProvider, FileConfig config) public void UseServer(ServiceProvider serviceProvider, FileConfig config)
{ {
RelayValidatorTransfer relayValidatorTransfer = serviceProvider.GetService<RelayValidatorTransfer>(); RelayValidatorTypeLoader relayValidatorTypeLoader = serviceProvider.GetService<RelayValidatorTypeLoader>();
} }
} }
} }

View File

@@ -14,7 +14,7 @@ namespace linker.plugins.relay
/// <summary> /// <summary>
/// 中继 /// 中继
/// </summary> /// </summary>
public sealed partial class RelayTransfer public sealed class RelayTransfer
{ {
private List<ITransport> transports; private List<ITransport> transports;
@@ -32,10 +32,6 @@ namespace linker.plugins.relay
this.serviceProvider = serviceProvider; this.serviceProvider = serviceProvider;
InitConfig(); InitConfig();
TestTask(); TestTask();
IEnumerable<Type> types = GetSourceGeneratorTypes();
transports = types.Select(c => (ITransport)serviceProvider.GetService(c)).Where(c => c != null).Where(c => string.IsNullOrWhiteSpace(c.Name) == false).ToList();
LoggerHelper.Instance.Info($"load relay transport:{string.Join(",", transports.Select(c => c.Name))}");
} }
private void InitConfig() private void InitConfig()
{ {
@@ -54,6 +50,11 @@ namespace linker.plugins.relay
} }
} }
public void LoadTransports(List<ITransport> list)
{
transports = list;
}
/// <summary> /// <summary>
/// 获取所有中继协议 /// 获取所有中继协议
/// </summary> /// </summary>

View File

@@ -0,0 +1,17 @@
using linker.libs;
using linker.plugins.relay.transport;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.relay
{
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

@@ -40,13 +40,13 @@ namespace linker.plugins.relay.messenger
public sealed class RelayServerMessenger : IMessenger public sealed class RelayServerMessenger : IMessenger
{ {
private readonly FileConfig config; private readonly FileConfig config;
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly SignCaching signCaching; private readonly SignCaching signCaching;
private readonly RelayResolver relayResolver; private readonly RelayResolver relayResolver;
private readonly RelayValidatorTransfer relayValidatorTransfer; private readonly RelayValidatorTransfer relayValidatorTransfer;
public RelayServerMessenger(FileConfig config, MessengerSender messengerSender, SignCaching signCaching, RelayResolver relayResolver, RelayValidatorTransfer relayValidatorTransfer) public RelayServerMessenger(FileConfig config, IMessengerSender messengerSender, SignCaching signCaching, RelayResolver relayResolver, RelayValidatorTransfer relayValidatorTransfer)
{ {
this.config = config; this.config = config;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;

View File

@@ -21,16 +21,14 @@ namespace linker.plugins.relay.transport
public RelayType Type => RelayType.Linker; public RelayType Type => RelayType.Linker;
public TunnelProtocolType ProtocolType => TunnelProtocolType.Tcp; public TunnelProtocolType ProtocolType => TunnelProtocolType.Tcp;
private readonly MessengerResolver messengerResolver; private readonly IMessengerSender messengerSender;
private readonly MessengerSender messengerSender;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private X509Certificate2 certificate; private X509Certificate2 certificate;
public TransportSelfHost(MessengerResolver messengerResolver, MessengerSender messengerSender, ClientSignInState clientSignInState, FileConfig config) public TransportSelfHost(IMessengerSender messengerSender, ClientSignInState clientSignInState, FileConfig config)
{ {
this.messengerResolver = messengerResolver;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.clientSignInState = clientSignInState; this.clientSignInState = clientSignInState;

View File

@@ -1,23 +1,24 @@
using linker.libs; using linker.plugins.relay.transport;
using linker.plugins.relay.transport;
using linker.plugins.signin.messenger; using linker.plugins.signin.messenger;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.relay.validator namespace linker.plugins.relay.validator
{ {
public sealed partial class RelayValidatorTransfer public sealed partial class RelayValidatorTransfer
{ {
private List<IRelayValidator> startups; private List<IRelayValidator> validators;
public RelayValidatorTransfer(ServiceProvider serviceProvider) public RelayValidatorTransfer()
{ {
var types = GetSourceGeneratorTypes(); }
startups = types.Select(c => serviceProvider.GetService(c) as IRelayValidator).Where(c => c != null).ToList();
public void LoadValidators(List<IRelayValidator> list)
{
validators = list;
} }
public async Task<string> Validate(RelayInfo relayInfo, SignCacheInfo cache, SignCacheInfo cache1) public async Task<string> Validate(RelayInfo relayInfo, SignCacheInfo cache, SignCacheInfo cache1)
{ {
foreach (var item in startups) foreach (var item in validators)
{ {
string result = await item.Validate(relayInfo, cache, cache1); string result = await item.Validate(relayInfo, cache, cache1);
if (string.IsNullOrWhiteSpace(result) == false) if (string.IsNullOrWhiteSpace(result) == false)

View File

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

View File

@@ -19,12 +19,14 @@ namespace linker.plugins.resolver
{ {
serviceCollection.AddSingleton<ResolverTransfer>(); serviceCollection.AddSingleton<ResolverTransfer>();
serviceCollection.AddSingleton<ResolverTypesLoader>();
} }
public void AddServer(ServiceCollection serviceCollection, FileConfig config) public void AddServer(ServiceCollection serviceCollection, FileConfig config)
{ {
serviceCollection.AddSingleton<ResolverTransfer>(); serviceCollection.AddSingleton<ResolverTransfer>();
serviceCollection.AddSingleton<ResolverTypesLoader>();
} }
@@ -35,8 +37,7 @@ namespace linker.plugins.resolver
if (loaded == false) if (loaded == false)
{ {
loaded = true; loaded = true;
ResolverTypesLoader resolver = serviceProvider.GetService<ResolverTypesLoader>();
ResolverTransfer resolver = serviceProvider.GetService<ResolverTransfer>();
} }
} }
@@ -46,8 +47,7 @@ namespace linker.plugins.resolver
if (loaded == false) if (loaded == false)
{ {
loaded = true; loaded = true;
ResolverTypesLoader resolver = serviceProvider.GetService<ResolverTypesLoader>();
ResolverTransfer resolver = serviceProvider.GetService<ResolverTransfer>();
} }
} }
} }

View File

@@ -2,31 +2,26 @@
using System.Net.Sockets; using System.Net.Sockets;
using linker.libs.extends; using linker.libs.extends;
using System.Buffers; using System.Buffers;
using Microsoft.Extensions.DependencyInjection;
using System.Net; using System.Net;
using System;
namespace linker.plugins.resolver namespace linker.plugins.resolver
{ {
public sealed partial class ResolverTransfer public sealed class ResolverTransfer
{ {
private readonly Dictionary<ResolverType, IResolver> resolvers = new Dictionary<ResolverType, IResolver>(); private readonly Dictionary<ResolverType, IResolver> resolvers = new Dictionary<ResolverType, IResolver>();
public ResolverTransfer(ServiceProvider serviceProvider) public ResolverTransfer()
{ {
var types = GetSourceGeneratorTypes(); }
foreach (Type type in types) public void LoadResolvers(List<IResolver> list)
{
foreach (IResolver resolver in list)
{ {
IResolver resolver = (IResolver)serviceProvider.GetService(type);
if (resolver == null)
{
continue;
}
LoggerHelper.Instance.Info($"load Resolver:{type.Name}");
resolvers.TryAdd(resolver.Type, resolver); resolvers.TryAdd(resolver.Type, resolver);
} }
} }
public async Task BeginReceive(Socket socket) public async Task BeginReceive(Socket socket)
{ {
byte[] buffer = ArrayPool<byte>.Shared.Rent(1024); byte[] buffer = ArrayPool<byte>.Shared.Rent(1024);

View File

@@ -0,0 +1,17 @@
using linker.libs;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.resolver
{
public sealed partial class ResolverTypesLoader
{
public ResolverTypesLoader(ResolverTransfer resolverTransfer, ServiceProvider serviceProvider)
{
var types = GetSourceGeneratorTypes();
var resolvers = types.Select(c => (IResolver)serviceProvider.GetService(c)).Where(c => c != null).ToList();
resolverTransfer.LoadResolvers(resolvers);
LoggerHelper.Instance.Info($"load resolvers:{string.Join(",", resolvers.Select(c => c.GetType().Name))}");
}
}
}

View File

@@ -45,7 +45,7 @@ namespace linker.plugins.server
{ {
LoggerHelper.Instance.Error(ex); LoggerHelper.Instance.Error(ex);
} }
LoggerHelper.Instance.Info($"server listen:{config.Data.Server.ServicePort}"); LoggerHelper.Instance.Warning($"server listen:{config.Data.Server.ServicePort}");
} }
} }

View File

@@ -13,10 +13,10 @@ namespace linker.plugins.sforward
public sealed class SForwardClientApiController : IApiClientController public sealed class SForwardClientApiController : IApiClientController
{ {
private readonly SForwardTransfer forwardTransfer; private readonly SForwardTransfer forwardTransfer;
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
public SForwardClientApiController(SForwardTransfer forwardTransfer, MessengerSender messengerSender, ClientSignInState clientSignInState) public SForwardClientApiController(SForwardTransfer forwardTransfer, IMessengerSender messengerSender, ClientSignInState clientSignInState)
{ {
this.forwardTransfer = forwardTransfer; this.forwardTransfer = forwardTransfer;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;

View File

@@ -28,11 +28,8 @@ namespace linker.plugins.sforward
serviceCollection.AddSingleton<SForwardTransfer>(); serviceCollection.AddSingleton<SForwardTransfer>();
serviceCollection.AddSingleton<SForwardClientMessenger>(); serviceCollection.AddSingleton<SForwardClientMessenger>();
serviceCollection.AddSingleton<SForwardFlow>();
serviceCollection.AddSingleton<ConfigSyncSForwardSecretKey>(); serviceCollection.AddSingleton<ConfigSyncSForwardSecretKey>();
} }
public void AddServer(ServiceCollection serviceCollection, FileConfig config) public void AddServer(ServiceCollection serviceCollection, FileConfig config)
@@ -42,7 +39,6 @@ namespace linker.plugins.sforward
serviceCollection.AddSingleton<ISForwardServerCahing, SForwardServerCahing>(); serviceCollection.AddSingleton<ISForwardServerCahing, SForwardServerCahing>();
serviceCollection.AddSingleton<ISForwardValidator, Validator>(); serviceCollection.AddSingleton<ISForwardValidator, Validator>();
serviceCollection.AddSingleton<SForwardFlow>();
} }
bool added = false; bool added = false;
@@ -51,7 +47,7 @@ namespace linker.plugins.sforward
if (added == false) if (added == false)
{ {
added = true; added = true;
serviceCollection.AddSingleton<SForwardProxy>(); serviceCollection.AddSingleton<SForwardProxy, SForwardProxy>();
} }
} }
@@ -66,9 +62,9 @@ namespace linker.plugins.sforward
if (config.Data.Server.SForward.WebPort > 0) if (config.Data.Server.SForward.WebPort > 0)
{ {
sForwardProxy.Start(config.Data.Server.SForward.WebPort, true, config.Data.Server.SForward.BufferSize); sForwardProxy.Start(config.Data.Server.SForward.WebPort, true, config.Data.Server.SForward.BufferSize);
LoggerHelper.Instance.Info($"listen server forward web in {config.Data.Server.SForward.WebPort}"); LoggerHelper.Instance.Warning($"listen server forward web in {config.Data.Server.SForward.WebPort}");
} }
LoggerHelper.Instance.Info($"listen server forward tunnel in {string.Join("-", config.Data.Server.SForward.TunnelPortRange)}"); LoggerHelper.Instance.Warning($"listen server forward tunnel in {string.Join("-", config.Data.Server.SForward.TunnelPortRange)}");
} }
} }

View File

@@ -17,13 +17,13 @@ namespace linker.plugins.sforward
private readonly FileConfig fileConfig; private readonly FileConfig fileConfig;
private readonly RunningConfig running; private readonly RunningConfig running;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly NumberSpaceUInt32 ns = new NumberSpaceUInt32(); private readonly NumberSpaceUInt32 ns = new NumberSpaceUInt32();
public VersionManager Version { get; } = new VersionManager(); public VersionManager Version { get; } = new VersionManager();
public SForwardTransfer(FileConfig fileConfig,RunningConfig running, ClientSignInState clientSignInState, MessengerSender messengerSender) public SForwardTransfer(FileConfig fileConfig,RunningConfig running, ClientSignInState clientSignInState, IMessengerSender messengerSender)
{ {
this.fileConfig = fileConfig; this.fileConfig = fileConfig;
this.running = running; this.running = running;

View File

@@ -8,7 +8,6 @@ using linker.config;
using LiteDB; using LiteDB;
using System.Net; using System.Net;
using linker.plugins.messenger; using linker.plugins.messenger;
using System.Buffers.Binary;
using linker.libs; using linker.libs;
namespace linker.plugins.sforward.messenger namespace linker.plugins.sforward.messenger
@@ -21,12 +20,12 @@ namespace linker.plugins.sforward.messenger
private readonly SForwardProxy proxy; private readonly SForwardProxy proxy;
private readonly ISForwardServerCahing sForwardServerCahing; private readonly ISForwardServerCahing sForwardServerCahing;
private readonly MessengerSender sender; private readonly IMessengerSender sender;
private readonly SignCaching signCaching; private readonly SignCaching signCaching;
private readonly FileConfig configWrap; private readonly FileConfig configWrap;
private readonly ISForwardValidator validator; private readonly ISForwardValidator validator;
public SForwardServerMessenger(SForwardProxy proxy, ISForwardServerCahing sForwardServerCahing, MessengerSender sender, SignCaching signCaching, FileConfig configWrap, ISForwardValidator validator) public SForwardServerMessenger(SForwardProxy proxy, ISForwardServerCahing sForwardServerCahing, IMessengerSender sender, SignCaching signCaching, FileConfig configWrap, ISForwardValidator validator)
{ {
this.proxy = proxy; this.proxy = proxy;
proxy.WebConnect = WebConnect; proxy.WebConnect = WebConnect;

View File

@@ -1,7 +1,5 @@
using linker.libs; using linker.libs;
using linker.plugins.flow;
using System.Text; using System.Text;
namespace linker.plugins.sforward.proxy namespace linker.plugins.sforward.proxy
{ {
public partial class SForwardProxy public partial class SForwardProxy
@@ -10,14 +8,19 @@ namespace linker.plugins.sforward.proxy
private readonly NumberSpace ns = new NumberSpace(); private readonly NumberSpace ns = new NumberSpace();
private byte[] flagBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.sforward"); private byte[] flagBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.sforward");
private readonly SForwardFlow sForwardFlow; public SForwardProxy()
public SForwardProxy(SForwardFlow sForwardFlow)
{ {
this.sForwardFlow = sForwardFlow;
UdpTask(); UdpTask();
} }
public virtual void AddReceive(string key, ulong bytes)
{
}
public virtual void AddSendt(string key, ulong bytes)
{
}
public string Start(int port, bool isweb, byte bufferSize) public string Start(int port, bool isweb, byte bufferSize)
{ {
try try

View File

@@ -283,13 +283,13 @@ namespace linker.plugins.sforward.proxy
{ {
if (isDomain) if (isDomain)
{ {
sForwardFlow.AddReceive(domain, (ulong)bytesRead); AddReceive(domain, (ulong)bytesRead);
sForwardFlow.AddSendt(domain, (ulong)bytesRead); AddSendt(domain, (ulong)bytesRead);
} }
else else
{ {
sForwardFlow.AddReceive(portStr, (ulong)bytesRead); AddReceive(portStr, (ulong)bytesRead);
sForwardFlow.AddSendt(portStr, (ulong)bytesRead); AddSendt(portStr, (ulong)bytesRead);
} }
await target.SendAsync(buffer.Slice(0, bytesRead), SocketFlags.None).ConfigureAwait(false); await target.SendAsync(buffer.Slice(0, bytesRead), SocketFlags.None).ConfigureAwait(false);
} }

View File

@@ -53,13 +53,13 @@ namespace linker.plugins.sforward.proxy
Memory<byte> memory = buffer.AsMemory(0, result.ReceivedBytes); Memory<byte> memory = buffer.AsMemory(0, result.ReceivedBytes);
sForwardFlow.AddReceive(portStr, (ulong)memory.Length); AddReceive(portStr, (ulong)memory.Length);
IPEndPoint source = result.RemoteEndPoint as IPEndPoint; IPEndPoint source = result.RemoteEndPoint as IPEndPoint;
//已经连接 //已经连接
if (udpConnections.TryGetValue(source, out UdpTargetCache cache) && cache != null) if (udpConnections.TryGetValue(source, out UdpTargetCache cache) && cache != null)
{ {
sForwardFlow.AddSendt(portStr, (ulong)memory.Length); AddSendt(portStr, (ulong)memory.Length);
cache.LastTicks.Update(); cache.LastTicks.Update();
await token.SourceSocket.SendToAsync(memory, cache.IPEndPoint).ConfigureAwait(false); await token.SourceSocket.SendToAsync(memory, cache.IPEndPoint).ConfigureAwait(false);
} }
@@ -193,8 +193,8 @@ namespace linker.plugins.sforward.proxy
Memory<byte> memory = buffer.AsMemory(0, result.ReceivedBytes); Memory<byte> memory = buffer.AsMemory(0, result.ReceivedBytes);
sForwardFlow.AddReceive(portStr, (ulong)memory.Length); AddReceive(portStr, (ulong)memory.Length);
sForwardFlow.AddSendt(portStr, (ulong)memory.Length); AddSendt(portStr, (ulong)memory.Length);
if (serviceUdp == null) if (serviceUdp == null)
{ {
@@ -222,8 +222,8 @@ namespace linker.plugins.sforward.proxy
break; break;
} }
Memory<byte> memory = buffer.AsMemory(0, result.ReceivedBytes); Memory<byte> memory = buffer.AsMemory(0, result.ReceivedBytes);
sForwardFlow.AddReceive(portStr, (ulong)memory.Length); AddReceive(portStr, (ulong)memory.Length);
sForwardFlow.AddSendt(portStr, (ulong)memory.Length); AddSendt(portStr, (ulong)memory.Length);
await socketUdp.SendToAsync(memory, server).ConfigureAwait(false); await socketUdp.SendToAsync(memory, server).ConfigureAwait(false);
cache.LastTicks.Update(); cache.LastTicks.Update();

View File

@@ -14,9 +14,9 @@ namespace linker.plugins.signin
private readonly FileConfig config; private readonly FileConfig config;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly ClientSignInTransfer clientSignInTransfer; private readonly ClientSignInTransfer clientSignInTransfer;
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
public SignInClientApiController(FileConfig config, ClientSignInState clientSignInState, ClientSignInTransfer clientSignInTransfer, MessengerSender messengerSender) public SignInClientApiController(FileConfig config, ClientSignInState clientSignInState, ClientSignInTransfer clientSignInTransfer, IMessengerSender messengerSender)
{ {
this.config = config; this.config = config;
this.clientSignInState = clientSignInState; this.clientSignInState = clientSignInState;

View File

@@ -24,6 +24,8 @@ namespace linker.plugins.signin
serviceCollection.AddSingleton<SignInClientApiController>(); serviceCollection.AddSingleton<SignInClientApiController>();
serviceCollection.AddSingleton<SignInArgsTransfer>(); serviceCollection.AddSingleton<SignInArgsTransfer>();
serviceCollection.AddSingleton<SignInArgsTypesLoader>();
serviceCollection.AddSingleton<SignInArgsMachineKeyClient>(); serviceCollection.AddSingleton<SignInArgsMachineKeyClient>();
} }
@@ -33,15 +35,18 @@ namespace linker.plugins.signin
serviceCollection.AddSingleton<SignInServerMessenger>(); serviceCollection.AddSingleton<SignInServerMessenger>();
serviceCollection.AddSingleton<SignInArgsTransfer>(); serviceCollection.AddSingleton<SignInArgsTransfer>();
serviceCollection.AddSingleton<SignInArgsTypesLoader>();
serviceCollection.AddSingleton<SignInArgsMachineKeyServer>(); serviceCollection.AddSingleton<SignInArgsMachineKeyServer>();
} }
public void UseClient(ServiceProvider serviceProvider, FileConfig config) public void UseClient(ServiceProvider serviceProvider, FileConfig config)
{ {
SignInArgsTypesLoader signInArgsTypesLoader = serviceProvider.GetService<SignInArgsTypesLoader>();
} }
public void UseServer(ServiceProvider serviceProvider, FileConfig config) public void UseServer(ServiceProvider serviceProvider, FileConfig config)
{ {
SignInArgsTypesLoader signInArgsTypesLoader = serviceProvider.GetService<SignInArgsTypesLoader>();
} }
} }
} }

View File

@@ -1,5 +1,4 @@
using linker.plugins.signin.messenger; using linker.plugins.signin.messenger;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.signIn.args namespace linker.plugins.signIn.args
{ {
@@ -7,10 +6,13 @@ namespace linker.plugins.signIn.args
{ {
private List<ISignInArgs> startups; private List<ISignInArgs> startups;
public SignInArgsTransfer(ServiceProvider serviceProvider) public SignInArgsTransfer()
{ {
var types = GetSourceGeneratorTypes(); }
startups = types.Select(c => serviceProvider.GetService(c) as ISignInArgs).Where(c => c != null).ToList();
public void LoadArgs(List<ISignInArgs> list)
{
startups = list;
} }
public async Task<string> Invoke(string host, Dictionary<string, string> args) public async Task<string> Invoke(string host, Dictionary<string, string> args)

View File

@@ -0,0 +1,18 @@

using linker.libs;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.signIn.args
{
public sealed partial class SignInArgsTypesLoader
{
public SignInArgsTypesLoader(SignInArgsTransfer signInArgsTransfer, ServiceProvider serviceProvider)
{
var types = GetSourceGeneratorTypes();
var args = types.Select(c => (ISignInArgs)serviceProvider.GetService(c)).Where(c => c != null).ToList();
signInArgsTransfer.LoadArgs(args);
LoggerHelper.Instance.Info($"load sign in args:{string.Join(",", args.Select(c => c.GetType().Name))}");
}
}
}

View File

@@ -29,9 +29,9 @@ namespace linker.plugins.signin.messenger
{ {
private readonly SignCaching signCaching; private readonly SignCaching signCaching;
private readonly FileConfig config; private readonly FileConfig config;
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
public SignInServerMessenger(SignCaching signCaching, FileConfig config, MessengerSender messengerSender) public SignInServerMessenger(SignCaching signCaching, FileConfig config, IMessengerSender messengerSender)
{ {
this.signCaching = signCaching; this.signCaching = signCaching;
this.config = config; this.config = config;

View File

@@ -3,25 +3,22 @@ using System.Net;
using System.Buffers; using System.Buffers;
using linker.libs.extends; using linker.libs.extends;
using linker.plugins.resolver; using linker.plugins.resolver;
using linker.plugins.flow;
namespace linker.plugins.tunnel namespace linker.plugins.tunnel
{ {
/// <summary> /// <summary>
/// 外网端口处理器 /// 外网端口处理器
/// </summary> /// </summary>
public sealed class ExternalResolver : IResolver, IFlow public class ExternalResolver : IResolver
{ {
public ulong ReceiveBytes { get; private set; }
public ulong SendtBytes { get; private set; }
public string FlowName => "External";
public ResolverType Type => ResolverType.External; public ResolverType Type => ResolverType.External;
public ExternalResolver() public ExternalResolver()
{ {
} }
public virtual void AddReceive( ulong bytes) { }
public virtual void AddSendt(ulong bytes) { }
/// <summary> /// <summary>
/// UDP /// UDP
/// </summary> /// </summary>
@@ -31,12 +28,12 @@ namespace linker.plugins.tunnel
/// <returns></returns> /// <returns></returns>
public async Task Resolve(Socket socket, IPEndPoint ep, Memory<byte> memory) public async Task Resolve(Socket socket, IPEndPoint ep, Memory<byte> memory)
{ {
ReceiveBytes += (ulong)memory.Length; AddReceive((ulong)memory.Length);
byte[] sendData = ArrayPool<byte>.Shared.Rent(20); byte[] sendData = ArrayPool<byte>.Shared.Rent(20);
try try
{ {
var send = BuildSendData(sendData, ep); var send = BuildSendData(sendData, ep);
SendtBytes += (ulong)send.Length; AddSendt((ulong)send.Length);
await socket.SendToAsync(send, SocketFlags.None, ep).ConfigureAwait(false); await socket.SendToAsync(send, SocketFlags.None, ep).ConfigureAwait(false);
} }
catch (Exception) catch (Exception)
@@ -58,7 +55,7 @@ namespace linker.plugins.tunnel
try try
{ {
memory = BuildSendData(sendData, socket.RemoteEndPoint as IPEndPoint); memory = BuildSendData(sendData, socket.RemoteEndPoint as IPEndPoint);
SendtBytes += (ulong)memory.Length; AddSendt((ulong)memory.Length);
await socket.SendAsync(memory, SocketFlags.None).ConfigureAwait(false); await socket.SendAsync(memory, SocketFlags.None).ConfigureAwait(false);
} }
catch (Exception) catch (Exception)

View File

@@ -8,7 +8,6 @@ using MemoryPack;
using System.Net; using System.Net;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using linker.tunnel.wanport; using linker.tunnel.wanport;
using System.Buffers.Binary;
using linker.plugins.client; using linker.plugins.client;
using linker.plugins.messenger; using linker.plugins.messenger;
using linker.plugins.tunnel.excludeip; using linker.plugins.tunnel.excludeip;
@@ -22,26 +21,20 @@ namespace linker.plugins.tunnel
? running.Data.Tunnel.Interface : (clientSignInState.Connection?.LocalAddress.Address ?? IPAddress.Any); ? running.Data.Tunnel.Interface : (clientSignInState.Connection?.LocalAddress.Address ?? IPAddress.Any);
public X509Certificate2 Certificate { get; private set; } public X509Certificate2 Certificate { get; private set; }
public PortMapInfo PortMap => running.Data.Tunnel.PortMapWan > 0
? new PortMapInfo { WanPort = running.Data.Tunnel.PortMapWan, LanPort = running.Data.Tunnel.PortMapLan }
: upnpTransfer.MapInfo != null ? new PortMapInfo { WanPort = upnpTransfer.MapInfo.PublicPort, LanPort = upnpTransfer.MapInfo.PrivatePort }
: new PortMapInfo { WanPort = 0, LanPort = 0 };
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly FileConfig config; private readonly FileConfig config;
private readonly RunningConfig running; private readonly RunningConfig running;
private readonly TunnelExcludeIPTransfer excludeIPTransfer; private readonly TunnelExcludeIPTransfer excludeIPTransfer;
private readonly TunnelUpnpTransfer upnpTransfer;
public TunnelAdapter(ClientSignInState clientSignInState, MessengerSender messengerSender, FileConfig config, RunningConfig running, TunnelExcludeIPTransfer excludeIPTransfer, TunnelUpnpTransfer upnpTransfer) public TunnelAdapter(ClientSignInState clientSignInState, IMessengerSender messengerSender, FileConfig config, RunningConfig running, TunnelExcludeIPTransfer excludeIPTransfer)
{ {
this.clientSignInState = clientSignInState; this.clientSignInState = clientSignInState;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.config = config; this.config = config;
this.running = running; this.running = running;
this.excludeIPTransfer = excludeIPTransfer; this.excludeIPTransfer = excludeIPTransfer;
this.upnpTransfer = upnpTransfer;
string path = Path.GetFullPath(config.Data.Client.SSL.File); string path = Path.GetFullPath(config.Data.Client.SSL.File);
if (File.Exists(path)) if (File.Exists(path))

View File

@@ -25,12 +25,12 @@ namespace linker.plugins.tunnel
private readonly FileConfig config; private readonly FileConfig config;
private readonly TunnelWanPortTransfer compactTransfer; private readonly TunnelWanPortTransfer compactTransfer;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly TunnelConfigTransfer tunnelConfigTransfer; private readonly TunnelConfigTransfer tunnelConfigTransfer;
private readonly ITunnelAdapter tunnelMessengerAdapter; private readonly ITunnelAdapter tunnelMessengerAdapter;
private readonly TunnelExcludeIPTransfer excludeIPTransfer; private readonly TunnelExcludeIPTransfer excludeIPTransfer;
public TunnelApiController(FileConfig config, TunnelWanPortTransfer compactTransfer, ClientSignInState clientSignInState, MessengerSender messengerSender, TunnelConfigTransfer tunnelConfigTransfer, ITunnelAdapter tunnelMessengerAdapter, TunnelExcludeIPTransfer excludeIPTransfer) public TunnelApiController(FileConfig config, TunnelWanPortTransfer compactTransfer, ClientSignInState clientSignInState, IMessengerSender messengerSender, TunnelConfigTransfer tunnelConfigTransfer, ITunnelAdapter tunnelMessengerAdapter, TunnelExcludeIPTransfer excludeIPTransfer)
{ {
this.config = config; this.config = config;
this.compactTransfer = compactTransfer; this.compactTransfer = compactTransfer;

View File

@@ -6,7 +6,6 @@ using linker.plugins.messenger;
using linker.plugins.tunnel.messenger; using linker.plugins.tunnel.messenger;
using linker.tunnel; using linker.tunnel;
using linker.tunnel.adapter; using linker.tunnel.adapter;
using linker.tunnel.transport;
using linker.tunnel.wanport; using linker.tunnel.wanport;
using MemoryPack; using MemoryPack;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@@ -20,33 +19,30 @@ namespace linker.plugins.tunnel
private readonly FileConfig config; private readonly FileConfig config;
private readonly RunningConfig running; private readonly RunningConfig running;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly ITunnelAdapter tunnelAdapter; private readonly ITunnelAdapter tunnelAdapter;
private readonly TransportTcpPortMap transportTcpPortMap;
private readonly TransportUdpPortMap transportUdpPortMap;
private readonly TunnelUpnpTransfer upnpTransfer; private readonly TunnelUpnpTransfer upnpTransfer;
public VersionManager Version { get; } = new VersionManager(); public VersionManager Version { get; } = new VersionManager();
public ConcurrentDictionary<string, TunnelTransportRouteLevelInfo> Config { get; } = new ConcurrentDictionary<string, TunnelTransportRouteLevelInfo>(); public ConcurrentDictionary<string, TunnelTransportRouteLevelInfo> Config { get; } = new ConcurrentDictionary<string, TunnelTransportRouteLevelInfo>();
public TunnelConfigTransfer(FileConfig config, RunningConfig running, ClientSignInState clientSignInState, MessengerSender messengerSender, ITunnelAdapter tunnelAdapter, TransportTcpPortMap transportTcpPortMap, TransportUdpPortMap transportUdpPortMap, TunnelUpnpTransfer upnpTransfer) public TunnelConfigTransfer(FileConfig config, RunningConfig running, ClientSignInState clientSignInState, IMessengerSender messengerSender, ITunnelAdapter tunnelAdapter, TunnelUpnpTransfer upnpTransfer)
{ {
this.config = config; this.config = config;
this.running = running; this.running = running;
this.clientSignInState = clientSignInState; this.clientSignInState = clientSignInState;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.tunnelAdapter = tunnelAdapter; this.tunnelAdapter = tunnelAdapter;
this.transportTcpPortMap = transportTcpPortMap;
this.transportUdpPortMap = transportUdpPortMap;
this.upnpTransfer = upnpTransfer; this.upnpTransfer = upnpTransfer;
InitRouteLevel();
InitConfig(); InitConfig();
clientSignInState.NetworkEnabledHandle += (times) =>
{
RefreshRouteLevel();
GetRemoteRouteLevel();
RefreshPortMap();
};
TestQuic(); TestQuic();
RefreshPortMap();
} }
private void RefreshRouteLevel() private void RefreshRouteLevel()
@@ -108,7 +104,6 @@ namespace linker.plugins.tunnel
running.Data.Tunnel.PortMapLan = tunnelTransportFileConfigInfo.PortMapLan; running.Data.Tunnel.PortMapLan = tunnelTransportFileConfigInfo.PortMapLan;
running.Data.Update(); running.Data.Update();
GetRemoteRouteLevel(); GetRemoteRouteLevel();
RefreshPortMap();
} }
/// <summary> /// <summary>
/// 收到别人的信息 /// 收到别人的信息
@@ -157,16 +152,7 @@ namespace linker.plugins.tunnel
NeedReboot = false NeedReboot = false
}; };
} }
private void InitRouteLevel()
{
clientSignInState.NetworkEnabledHandle += (times) =>
{
RefreshRouteLevel();
GetRemoteRouteLevel();
};
}
public void SetInterface(IPAddress ip) public void SetInterface(IPAddress ip)
{ {
running.Data.Tunnel.Interface = ip; running.Data.Tunnel.Interface = ip;
@@ -214,28 +200,15 @@ namespace linker.plugins.tunnel
} }
} }
private void RefreshPortMap() private void RefreshPortMap()
{ {
try
{
int port = 18180;
int ip = Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(c => c.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).GetAddressBytes()[3];
upnpTransfer.SetMap(port, port + ip);
}
catch (Exception)
{
}
if (running.Data.Tunnel.PortMapLan > 0) if (running.Data.Tunnel.PortMapLan > 0)
{ {
_ = transportTcpPortMap.Listen(running.Data.Tunnel.PortMapLan); upnpTransfer.SetMap(running.Data.Tunnel.PortMapLan, running.Data.Tunnel.PortMapWan);
_ = transportUdpPortMap.Listen(running.Data.Tunnel.PortMapLan);
} }
else if (upnpTransfer.MapInfo != null) else
{ {
_ = transportTcpPortMap.Listen(upnpTransfer.MapInfo.PrivatePort); upnpTransfer.SetMap(clientSignInState.Connection.LocalAddress.Address,18180);
_ = transportUdpPortMap.Listen(upnpTransfer.MapInfo.PrivatePort);
} }
} }

View File

@@ -47,7 +47,7 @@ namespace linker.plugins.tunnel
serviceCollection.AddSingleton<TunnelWanPortProtocolLinkerUdp>(); serviceCollection.AddSingleton<TunnelWanPortProtocolLinkerUdp>();
serviceCollection.AddSingleton<TunnelWanPortProtocolLinkerTcp>(); serviceCollection.AddSingleton<TunnelWanPortProtocolLinkerTcp>();
serviceCollection.AddSingleton<TunnelWanPortProtocolStun>(); serviceCollection.AddSingleton<TunnelWanPortProtocolStun>();
//打洞协议 //打洞协议
serviceCollection.AddSingleton<TunnelTransfer>(); serviceCollection.AddSingleton<TunnelTransfer>();
@@ -60,6 +60,7 @@ namespace linker.plugins.tunnel
serviceCollection.AddSingleton<TunnelExcludeIPTransfer>(); serviceCollection.AddSingleton<TunnelExcludeIPTransfer>();
serviceCollection.AddSingleton<TunnelExcludeIPTypesLoader>();
serviceCollection.AddSingleton<TunnelConfigTransfer>(); serviceCollection.AddSingleton<TunnelConfigTransfer>();
serviceCollection.AddSingleton<ITunnelAdapter, TunnelAdapter>(); serviceCollection.AddSingleton<ITunnelAdapter, TunnelAdapter>();
@@ -86,15 +87,16 @@ namespace linker.plugins.tunnel
MemoryPackFormatterProvider.Register(new TunnelWanPortProtocolInfoFormatter()); MemoryPackFormatterProvider.Register(new TunnelWanPortProtocolInfoFormatter());
serviceCollection.AddSingleton<TunnelServerMessenger>(); serviceCollection.AddSingleton<TunnelServerMessenger>();
serviceCollection.AddSingleton<ExternalResolver>(); serviceCollection.AddSingleton<ExternalResolver, ExternalResolver>();
serviceCollection.AddSingleton<TunnelUpnpTransfer>(); serviceCollection.AddSingleton<TunnelUpnpTransfer>();
} }
public void UseClient(ServiceProvider serviceProvider, FileConfig config) public void UseClient(ServiceProvider serviceProvider, FileConfig config)
{ {
ITunnelAdapter tunnelAdapter = serviceProvider.GetService<ITunnelAdapter>(); ITunnelAdapter tunnelAdapter = serviceProvider.GetService<ITunnelAdapter>();
TunnelUpnpTransfer upnpTransfer = serviceProvider.GetService<TunnelUpnpTransfer>();
IEnumerable<Type> types = new List<Type> { IEnumerable<Type> types = new List<Type> {
typeof(TunnelWanPortProtocolLinkerUdp), typeof(TunnelWanPortProtocolLinkerUdp),
typeof(TunnelWanPortProtocolLinkerTcp), typeof(TunnelWanPortProtocolLinkerTcp),
typeof(TunnelWanPortProtocolStun), typeof(TunnelWanPortProtocolStun),
@@ -114,11 +116,12 @@ namespace linker.plugins.tunnel
}; };
List<ITunnelTransport> transports = types.Select(c => (ITunnelTransport)serviceProvider.GetService(c)).Where(c => c != null).Where(c => string.IsNullOrWhiteSpace(c.Name) == false).ToList(); List<ITunnelTransport> transports = types.Select(c => (ITunnelTransport)serviceProvider.GetService(c)).Where(c => c != null).Where(c => string.IsNullOrWhiteSpace(c.Name) == false).ToList();
TunnelTransfer tunnel = serviceProvider.GetService<TunnelTransfer>(); TunnelTransfer tunnel = serviceProvider.GetService<TunnelTransfer>();
tunnel.LoadTransports(compack, tunnelAdapter, transports); tunnel.LoadTransports(compack, tunnelAdapter, upnpTransfer, transports);
TunnelConfigTransfer tunnelConfigTransfer = serviceProvider.GetService<TunnelConfigTransfer>(); TunnelConfigTransfer tunnelConfigTransfer = serviceProvider.GetService<TunnelConfigTransfer>();
TunnelExcludeIPTransfer excludeIPTransfer = serviceProvider.GetService<TunnelExcludeIPTransfer>(); TunnelExcludeIPTransfer excludeIPTransfer = serviceProvider.GetService<TunnelExcludeIPTransfer>();
TunnelUpnpTransfer upnpTransfer = serviceProvider.GetService<TunnelUpnpTransfer>(); TunnelExcludeIPTypesLoader tunnelExcludeIPTypesLoader = serviceProvider.GetService<TunnelExcludeIPTypesLoader>();
} }

View File

@@ -3,29 +3,28 @@ using linker.config;
using linker.libs; using linker.libs;
using linker.plugins.client; using linker.plugins.client;
using MemoryPack; using MemoryPack;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.tunnel.excludeip namespace linker.plugins.tunnel.excludeip
{ {
public sealed partial class TunnelExcludeIPTransfer public sealed partial class TunnelExcludeIPTransfer
{ {
private readonly List<ITunnelExcludeIP> excludeIPs; private List<ITunnelExcludeIP> excludeIPs;
private readonly RunningConfig running; private readonly RunningConfig running;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly FileConfig fileConfig; private readonly FileConfig fileConfig;
private readonly ServiceProvider serviceProvider; public TunnelExcludeIPTransfer(RunningConfig running, ClientSignInState clientSignInState, FileConfig fileConfig)
public TunnelExcludeIPTransfer(RunningConfig running, ClientSignInState clientSignInState, FileConfig fileConfig, ServiceProvider serviceProvider)
{ {
this.running = running; this.running = running;
this.clientSignInState = clientSignInState; this.clientSignInState = clientSignInState;
this.fileConfig = fileConfig; this.fileConfig = fileConfig;
this.serviceProvider = serviceProvider; }
IEnumerable<Type> types = GetSourceGeneratorTypes(); public void LoadTunnelExcludeIPs(List<ITunnelExcludeIP> list)
excludeIPs = types.Select(c => (ITunnelExcludeIP)serviceProvider.GetService(c)).Where(c => c != null).ToList(); {
LoggerHelper.Instance.Info($"load tunnel excludeips :{string.Join(",", types.Select(c => c.Name))}"); excludeIPs = list;
} }
public List<ExcludeIPItem> Get() public List<ExcludeIPItem> Get()
@@ -43,7 +42,7 @@ namespace linker.plugins.tunnel.excludeip
{ {
result.AddRange(running.Data.Tunnel.ExcludeIPs); result.AddRange(running.Data.Tunnel.ExcludeIPs);
} }
return result; return result;
} }
@@ -56,10 +55,5 @@ namespace linker.plugins.tunnel.excludeip
running.Data.Tunnel.ExcludeIPs = ips; running.Data.Tunnel.ExcludeIPs = ips;
running.Data.Update(); running.Data.Update();
} }
private void SettExcludeIPs(Memory<byte> data)
{
running.Data.Tunnel.ExcludeIPs = MemoryPackSerializer.Deserialize<ExcludeIPItem[]>(data.Span);
running.Data.Update();
}
} }
} }

View File

@@ -0,0 +1,17 @@
using linker.libs;
using Microsoft.Extensions.DependencyInjection;
namespace linker.plugins.tunnel.excludeip
{
public sealed partial class TunnelExcludeIPTypesLoader
{
public TunnelExcludeIPTypesLoader(TunnelExcludeIPTransfer tunnelExcludeIPTransfer, ServiceProvider serviceProvider)
{
var types = GetSourceGeneratorTypes();
var flows = types.Select(c => (ITunnelExcludeIP)serviceProvider.GetService(c)).Where(c => c != null).ToList();
tunnelExcludeIPTransfer.LoadTunnelExcludeIPs(flows);
LoggerHelper.Instance.Info($"load tunnel excludeips :{string.Join(",", flows.Select(c => c.GetType().Name))}");
}
}
}

View File

@@ -14,9 +14,9 @@ namespace linker.plugins.tunnel.messenger
{ {
private readonly TunnelTransfer tunnel; private readonly TunnelTransfer tunnel;
private readonly TunnelConfigTransfer tunnelConfigTransfer; private readonly TunnelConfigTransfer tunnelConfigTransfer;
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
public TunnelClientMessenger(TunnelTransfer tunnel, TunnelConfigTransfer tunnelConfigTransfer, MessengerSender messengerSender) public TunnelClientMessenger(TunnelTransfer tunnel, TunnelConfigTransfer tunnelConfigTransfer, IMessengerSender messengerSender)
{ {
this.tunnel = tunnel; this.tunnel = tunnel;
this.tunnelConfigTransfer = tunnelConfigTransfer; this.tunnelConfigTransfer = tunnelConfigTransfer;
@@ -108,11 +108,11 @@ namespace linker.plugins.tunnel.messenger
public sealed class TunnelServerMessenger : IMessenger public sealed class TunnelServerMessenger : IMessenger
{ {
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly SignCaching signCaching; private readonly SignCaching signCaching;
private readonly ConcurrentDictionary<string, TunnelRecordInfo> records = new ConcurrentDictionary<string, TunnelRecordInfo>(); private readonly ConcurrentDictionary<string, TunnelRecordInfo> records = new ConcurrentDictionary<string, TunnelRecordInfo>();
public TunnelServerMessenger(MessengerSender messengerSender, SignCaching signCaching) public TunnelServerMessenger(IMessengerSender messengerSender, SignCaching signCaching)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.signCaching = signCaching; this.signCaching = signCaching;

View File

@@ -16,7 +16,7 @@ namespace linker.plugins.tuntap.client
{ {
public sealed class TuntapClientApiController : IApiClientController public sealed class TuntapClientApiController : IApiClientController
{ {
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly TuntapTransfer tuntapTransfer; private readonly TuntapTransfer tuntapTransfer;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly FileConfig config; private readonly FileConfig config;
@@ -27,7 +27,7 @@ namespace linker.plugins.tuntap.client
private readonly TuntapPingTransfer pingTransfer; private readonly TuntapPingTransfer pingTransfer;
public TuntapClientApiController(MessengerSender messengerSender, TuntapTransfer tuntapTransfer, ClientSignInState clientSignInState, FileConfig config, TuntapProxy tuntapProxy, RunningConfig runningConfig, TuntapConfigTransfer tuntapConfigTransfer, LeaseClientTreansfer leaseClientTreansfer, TuntapPingTransfer pingTransfer) public TuntapClientApiController(IMessengerSender messengerSender, TuntapTransfer tuntapTransfer, ClientSignInState clientSignInState, FileConfig config, TuntapProxy tuntapProxy, RunningConfig runningConfig, TuntapConfigTransfer tuntapConfigTransfer, LeaseClientTreansfer leaseClientTreansfer, TuntapPingTransfer pingTransfer)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.tuntapTransfer = tuntapTransfer; this.tuntapTransfer = tuntapTransfer;

View File

@@ -15,7 +15,7 @@ namespace linker.plugins.tuntap.client
{ {
public sealed class TuntapConfigTransfer public sealed class TuntapConfigTransfer
{ {
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly FileConfig config; private readonly FileConfig config;
private readonly TuntapProxy tuntapProxy; private readonly TuntapProxy tuntapProxy;
@@ -28,7 +28,7 @@ namespace linker.plugins.tuntap.client
public ConcurrentDictionary<string, TuntapInfo> Infos => tuntapInfos; public ConcurrentDictionary<string, TuntapInfo> Infos => tuntapInfos;
private readonly SemaphoreSlim slim = new SemaphoreSlim(1); private readonly SemaphoreSlim slim = new SemaphoreSlim(1);
public TuntapConfigTransfer(MessengerSender messengerSender, ClientSignInState clientSignInState, FileConfig config, TuntapProxy tuntapProxy, RunningConfig runningConfig, TuntapTransfer tuntapTransfer, LeaseClientTreansfer leaseClientTreansfer) public TuntapConfigTransfer(IMessengerSender messengerSender, ClientSignInState clientSignInState, FileConfig config, TuntapProxy tuntapProxy, RunningConfig runningConfig, TuntapTransfer tuntapTransfer, LeaseClientTreansfer leaseClientTreansfer)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.clientSignInState = clientSignInState; this.clientSignInState = clientSignInState;

View File

@@ -9,10 +9,10 @@ namespace linker.plugins.tuntap.lease
{ {
public sealed class LeaseClientTreansfer public sealed class LeaseClientTreansfer
{ {
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
public LeaseClientTreansfer(MessengerSender messengerSender, ClientSignInState clientSignInState) public LeaseClientTreansfer(IMessengerSender messengerSender, ClientSignInState clientSignInState)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.clientSignInState = clientSignInState; this.clientSignInState = clientSignInState;

View File

@@ -80,12 +80,12 @@ namespace linker.plugins.tuntap.messenger
public sealed class TuntapServerMessenger : IMessenger public sealed class TuntapServerMessenger : IMessenger
{ {
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly SignCaching signCaching; private readonly SignCaching signCaching;
private readonly FileConfig config; private readonly FileConfig config;
private readonly LeaseServerTreansfer leaseTreansfer; private readonly LeaseServerTreansfer leaseTreansfer;
public TuntapServerMessenger(MessengerSender messengerSender, SignCaching signCaching, FileConfig config, LeaseServerTreansfer leaseTreansfer) public TuntapServerMessenger(IMessengerSender messengerSender, SignCaching signCaching, FileConfig config, LeaseServerTreansfer leaseTreansfer)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.signCaching = signCaching; this.signCaching = signCaching;

View File

@@ -14,13 +14,13 @@ namespace linker.plugins.updater
{ {
public sealed class UpdaterClientApiController : IApiClientController public sealed class UpdaterClientApiController : IApiClientController
{ {
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly UpdaterClientTransfer updaterTransfer; private readonly UpdaterClientTransfer updaterTransfer;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly FileConfig config; private readonly FileConfig config;
private readonly RunningConfig runningConfig; private readonly RunningConfig runningConfig;
public UpdaterClientApiController(MessengerSender messengerSender, UpdaterClientTransfer updaterTransfer, ClientSignInState clientSignInState, FileConfig config, RunningConfig runningConfig) public UpdaterClientApiController(IMessengerSender messengerSender, UpdaterClientTransfer updaterTransfer, ClientSignInState clientSignInState, FileConfig config, RunningConfig runningConfig)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.updaterTransfer = updaterTransfer; this.updaterTransfer = updaterTransfer;

View File

@@ -16,7 +16,7 @@ namespace linker.plugins.updater
private ConcurrentDictionary<string, LastTicksManager> subscribes = new ConcurrentDictionary<string, LastTicksManager>(); private ConcurrentDictionary<string, LastTicksManager> subscribes = new ConcurrentDictionary<string, LastTicksManager>();
private readonly FileConfig fileConfig; private readonly FileConfig fileConfig;
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly UpdaterHelper updaterHelper; private readonly UpdaterHelper updaterHelper;
@@ -24,7 +24,7 @@ namespace linker.plugins.updater
public VersionManager Version { get; } = new VersionManager(); public VersionManager Version { get; } = new VersionManager();
public UpdaterClientTransfer(FileConfig fileConfig, MessengerSender messengerSender, ClientSignInState clientSignInState, UpdaterHelper updaterHelper, RunningConfig running) public UpdaterClientTransfer(FileConfig fileConfig, IMessengerSender messengerSender, ClientSignInState clientSignInState, UpdaterHelper updaterHelper, RunningConfig running)
{ {
this.fileConfig = fileConfig; this.fileConfig = fileConfig;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;

View File

@@ -57,12 +57,12 @@ namespace linker.plugins.updater.messenger
public sealed class UpdaterServerMessenger : IMessenger public sealed class UpdaterServerMessenger : IMessenger
{ {
private readonly MessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly SignCaching signCaching; private readonly SignCaching signCaching;
private readonly UpdaterServerTransfer updaterServerTransfer; private readonly UpdaterServerTransfer updaterServerTransfer;
private readonly FileConfig fileConfig; private readonly FileConfig fileConfig;
public UpdaterServerMessenger(MessengerSender messengerSender, SignCaching signCaching, UpdaterServerTransfer updaterServerTransfer, FileConfig fileConfig) public UpdaterServerMessenger(IMessengerSender messengerSender, SignCaching signCaching, UpdaterServerTransfer updaterServerTransfer, FileConfig fileConfig)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.signCaching = signCaching; this.signCaching = signCaching;

View File

@@ -57,7 +57,7 @@ namespace linker.startup
config.Data.Common.Plugins = startups.Select(c => c.Name).ToArray(); config.Data.Common.Plugins = startups.Select(c => c.Name).ToArray();
LoggerHelper.Instance.Info($"load startup : {string.Join(",", startups.Select(c => c.Name))}"); LoggerHelper.Instance.Info($"load startup : {string.Join(",", startups.Select(c => c.GetType().Name))}");
} }
/// <summary> /// <summary>
/// 加载插件依赖 /// 加载插件依赖
@@ -84,16 +84,15 @@ namespace linker.startup
/// <param name="assemblies"></param> /// <param name="assemblies"></param>
public static void Add(ServiceCollection serviceCollection, FileConfig config) public static void Add(ServiceCollection serviceCollection, FileConfig config)
{ {
LoggerHelper.Instance.Info($"add startup : {string.Join(",", startups.Select(c => c.GetType().Name))}");
foreach (var startup in startups) foreach (var startup in startups)
{ {
if (config.Data.Common.Modes.Contains("client")) if (config.Data.Common.Modes.Contains("client"))
{ {
LoggerHelper.Instance.Info($"add startup {startup.Name} client");
startup.AddClient(serviceCollection, config); startup.AddClient(serviceCollection, config);
} }
if (config.Data.Common.Modes.Contains("server")) if (config.Data.Common.Modes.Contains("server"))
{ {
LoggerHelper.Instance.Info($"add startup {startup.Name} server");
startup.AddServer(serviceCollection, config); startup.AddServer(serviceCollection, config);
} }
} }
@@ -107,16 +106,15 @@ namespace linker.startup
/// <param name="assemblies"></param> /// <param name="assemblies"></param>
public static void Use(ServiceProvider serviceProvider, FileConfig config) public static void Use(ServiceProvider serviceProvider, FileConfig config)
{ {
LoggerHelper.Instance.Info($"use startup : {string.Join(",", startups.Select(c => c.GetType().Name))}");
foreach (var startup in startups) foreach (var startup in startups)
{ {
if (config.Data.Common.Modes.Contains("client")) if (config.Data.Common.Modes.Contains("client"))
{ {
LoggerHelper.Instance.Info($"use startup {startup.Name} client");
startup.UseClient(serviceProvider, config); startup.UseClient(serviceProvider, config);
} }
if (config.Data.Common.Modes.Contains("server")) if (config.Data.Common.Modes.Contains("server"))
{ {
LoggerHelper.Instance.Info($"use startup {startup.Name} server");
startup.UseServer(serviceProvider, config); startup.UseServer(serviceProvider, config);
} }
} }

View File

@@ -1,5 +1,5 @@
v1.5.0 v1.5.0
2024-10-20 23:26:57 2024-10-21 16:35:59
1. 新增多分组管理,方便分组切换 1. 新增多分组管理,方便分组切换
2. 增加分组密码,提高分组隔离安全性 2. 增加分组密码,提高分组隔离安全性
3. 优化配置同步,可自由选择同步哪些信息 3. 优化配置同步,可自由选择同步哪些信息