This commit is contained in:
snltty
2024-12-29 20:38:37 +08:00
parent 9ef71ce4cb
commit ec8e407cde
358 changed files with 5909 additions and 5231 deletions

View File

@@ -28,6 +28,7 @@ jobs:
dotnet build ./linker.messenger.relay -c release
dotnet build ./linker.messenger.signin -c release
dotnet build ./linker.messenger.tunnel -c release
dotnet build ./linker.messenger.decenter -c release
- name: Pack
run: |
@@ -38,6 +39,7 @@ jobs:
dotnet pack ./linker.messenger.relay -c release
dotnet pack ./linker.messenger.signin -c release
dotnet pack ./linker.messenger.tunnel -c release
dotnet pack ./linker.messenger.decenter -c release
- name: Install Nuget
uses: nuget/setup-nuget@v1
@@ -53,3 +55,4 @@ jobs:
nuget push ./linker.messenger/bin/release/linker.messenger.relay.1.6.4.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NUGET_KEY }} -NoSymbol
nuget push ./linker.messenger/bin/release/linker.messenger.signin.1.6.4.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NUGET_KEY }} -NoSymbol
nuget push ./linker.messenger/bin/release/linker.messenger.tunnel.1.6.4.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NUGET_KEY }} -NoSymbol
nuget push ./linker.messenger/bin/release/linker.messenger.decenter.1.6.4.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NUGET_KEY }} -NoSymbol

View File

@@ -51,6 +51,7 @@
- [x] 网络配置主客户端设置网络所有客户端自动分配IP
- [x] 分布式,多中继服务器节点,承载海量设备
- [x] socks5代理端口转发需要指定端口而socks5代理可以代理所有端口
- [x] 集成linker使用`linker.messenger`信标,`linker.messenger.signin`登录,`linker.messenger.tunnel`打洞,`linker.messenger.relay`中继,轻松在你的项目中集成打洞和中继,`linker.messenger.example`是一个完整的登录打洞中继demo
## 大概长这个样子

View File

@@ -34,6 +34,7 @@ sidebar_position: 1
- [x] 网络配置主客户端设置网络所有客户端自动分配IP
- [x] 分布式,多中继服务器节点,承载海量设备
- [x] socks5代理端口转发需要指定端口而socks5代理可以代理所有端口
- [x] 集成linker使用`linker.messenger`信标,`linker.messenger.signin`登录,`linker.messenger.tunnel`打洞,`linker.messenger.relay`中继,轻松在你的项目中集成打洞和中继,`linker.messenger.example`是一个完整的登录打洞中继demo
#### 1.3、加入组织

View File

@@ -46,7 +46,7 @@ sidebar_position: 2
//主服务器地址
"MasterHost": "linker.snltty.com:1802",
//主服务器的密钥
//主服务器的密钥主服务里的Master里的SecretKey
"MasterSecretKey": ""
},
//我是主服务器,接收其它中继节点服务器的信息

View File

@@ -0,0 +1,108 @@
---
sidebar_position: 1
---
# 8.1、使用打洞和中继
:::tip[说明]
1. 在你的.NET8.0+项目中集成linker的打洞和中继
2. 分别在服务端和客户端使用nuget安装`linker.messenger`,`linker.messenger.signin`,`linker.messenger.tunnel`,`linker.messenger.relay`
3. 然后参照样例[https://github.com/snltty/linker/tree/master/linker.messenger.example](https://github.com/snltty/linker/tree/master/linker.messenger.example)
:::
## 1、自定义登录参数和验证
:::tip[说明]
实现自定义的登录参数验证,
```
//在客户端和服务端操作
SignInArgsTransfer signInArgsTransfer = new SignInArgsTransfer();
//加载你写的类
signInArgsTransfer.LoadArgs(new List<ISignInArgs> {
new MySignInArgs()
});
//在客户端,登录操作事情执行一下,然后把 argsDic 传过去就行
Dictionary<string, string> argsDic = new Dictionary<string, string>();
await signInArgsTransfer.Invoke(string.Empty, argsDic);
//像这样传过去
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = 与服务器的连接对象,
MessengerId = (ushort)SignInMessengerIds.SignIn_V_1_3_1,
Timeout = 2000,
Payload = serializer.Serialize(new SignInfo
{
MachineName = Dns.GetHostName(),
MachineId = string.Empty,
Version = VersionHelper.version,
Args = argsDic,
GroupId = "default"
})
}).ConfigureAwait(false);
public sealed class MySignInArgs : ISignInArgs
{
/// <summary>
/// 客户端调用
/// </summary>
/// <param name="host"></param>
/// <param name="args"></param>
/// <returns></returns>
public async Task<string> Invoke(string host, Dictionary<string, string> args)
{
//在这里加入你喜欢的数据
//返回空字符串,表示成功,不空为错误信息
return await Task.FromResult(string.Empty);
}
/// <summary>
/// 服务端调用
/// </summary>
/// <param name="signInfo">本次登录的信息</param>
/// <param name="cache">如果以前登录过就有信息否则MachineId为空</param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<string> Validate(SignInfo signInfo, SignCacheInfo cache)
{
//在这里进行你的验证
//返回空字符串,表示成功,不空为错误信息则登录失败
return await Task.FromResult(string.Empty);
}
}
```
:::
## 1、自定义中继认证
:::tip[说明]
实现自定义的中继验证,
```
//在服务端操作
RelayServerValidatorTransfer relayServerValidatorTransfer = new RelayServerValidatorTransfer();
//加载你写的类
relayServerValidatorTransfer.LoadValidators(new List<IRelayServerValidator> {
new MyRelayServerValidator()
});
public sealed class MyRelayServerValidator : IRelayServerValidator
{
/// <summary>
/// 验证,服务端会调用
/// </summary>
/// <param name="relayInfo">中继参数</param>
/// <param name="fromMachine">来源客户端</param>
/// <param name="toMachine">目标客户端</param>
/// <returns></returns>
public async Task<string> Validate(RelayInfo relayInfo, SignCacheInfo fromMachine, SignCacheInfo toMachine)
{
//返回空字符串,表示成功,不空为错误信息则登录失败
return await Task.FromResult(string.Empty);
}
}
```
:::

View File

@@ -1,8 +1,8 @@
---
sidebar_position: 9
sidebar_position: 2
---
# 9、集成tun网卡到你的项目
# 8.2、独立使用虚拟网卡
## 1、说明

View File

@@ -1,8 +1,8 @@
---
sidebar_position: 10
sidebar_position: 3
---
# 10、组网和内网穿透流程图
# 8.3、组网和内网穿透流程图
:::tip[说明]

View File

@@ -0,0 +1,8 @@
{
"label": "8、集成",
"position": 8,
"link": {
"type": "generated-index",
"description": "这里是一些高级用法,如果你不懂代码,就不用看"
}
}

View File

Before

Width:  |  Height:  |  Size: 168 KiB

After

Width:  |  Height:  |  Size: 168 KiB

View File

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 81 KiB

View File

@@ -1,65 +0,0 @@
---
sidebar_position: 8
---
# 8、集成打洞到你的项目
:::tip[说明]
1. 你需要自己实现信标服务器,用于交换打洞信息
2. `linker.tunnel`源码在[https://github.com/snltty/linker/tree/master/linker.tunnel](https://github.com/snltty/linker/tree/master/linker.tunnel)
3. 使用nuget安装`linker.tunnel`
## 1、初始化
```c#
//实现你的适配器
ITunnelAdapter tunnelAdapter = new MyTunnelAdapter();
//获取外网端口类列表
List<ITunnelWanPortProtocol> tunnelWanPorts = new List<ITunnelWanPortProtocol>{
new MyWanPort(),//你自己的获取外网端口的方法
};
//创建一个获取外网端口处理器
TunnelWanPortTransfer tunnelWanPortTransfer = new TunnelWanPortTransfer();
tunnelWanPortTransfer.Init(tunnelWanPorts);
//打洞协议列表
List<ITunnelTransport> transports = new List<ITunnelTransport>{
new TransportUdp(),//udp打洞
new TransportTcpP2PNAT()//tcp打洞
};
//创建一个打洞处理器
TunnelTransfer tunnelTransfer = new TunnelTransfer();
tunnelTransfer.Init(tunnelWanPortTransfer, tunnelAdapter, transports);
```
## 2、监听打洞成功事件
```c#
//监听打洞成功事件
tunnelTransfer.SetConnectedCallback("你的事务名",Action<ITunnelConnection> callback);
//移除打洞成功事件
tunnelTransfer.RemoveConnectedCallback("你的事务名",Action<ITunnelConnection> callback)
```
## 3、处理打洞消息
```c#
//开始打洞会调用ITunnelAdapter.SendConnectBegin 发送给对方,你需要实现这个方法
//对方收到消息,你应该调用
tunnelTransfer.OnBegin();
//打洞失败则会调用 ITunnelAdapter.SendConnectFail 发送给对方,你需要实现这个方法
//对方收到消息,你应该调用
tunnelTransfer.OnFail();
//打洞成功则会调用 ITunnelAdapter.SendConnectSuccess 发送给对方,你需要实现这个方法
//对方收到消息,你应该调用
tunnelTransfer.OnSuccess();
```
## 4、开始打洞
```c#
//会通过 ITunnelAdapter.SendConnectBegin 发送给对方,你需要实现这个方法
tunnelTransfer.ConnectAsync("对方的名字或编号,取决于的你信标服务器实现","事务名",TunnelProtocolType.None);
```
:::

View File

@@ -9,7 +9,7 @@ import { themes as prismThemes } from 'prism-react-renderer';
/** @type {import('@docusaurus/types').Config} */
const config = {
title: 'linker-doc',
tagline: 'linker、一个免费开源的P2P内网穿透内核',
tagline: 'linker、一个免费开源的P2P异地组网和内网穿透内核',
favicon: 'img/favicon.ico',
// Set the production url of your site here
@@ -20,7 +20,7 @@ const config = {
// GitHub pages deployment config.
// If you aren't using GitHub pages, you don't need these.
organizationName: 'facebook', // Usually your GitHub org/user name.
organizationName: 'snltty', // Usually your GitHub org/user name.
projectName: 'linker.doc.web', // Usually your repo name.
onBrokenLinks: 'throw',
@@ -93,6 +93,8 @@ const config = {
footer: {
style: 'light',
links: [
{ href: 'https://mi-d.cn', label: '米多贝克', position: 'left' },
{ href: 'https://www.wpe64.com', label: 'WPE64代理和抓包', position: 'left' },
],
copyright: `Copyright © ${new Date().getFullYear()} linker, Inc. Built with Docusaurus.`,
},

View File

@@ -4,11 +4,11 @@ import styles from './styles.module.css';
const FeatureList = [
{
title: '跨平台、易操作、且安全',
title: '跨平台、高性能、可视化',
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
description: (
<>
<code>.NET8</code><code>MemoryPack</code>webSSL
跨平台高性能的<code>.NET8</code>webSSL
</>
),
},
@@ -17,12 +17,12 @@ const FeatureList = [
Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
description: (
<>
3TCP打洞 + 1UDP打洞 + 1TCP端口映射连接 + 1TCP服务器中继连接 + 1TCP+UDP服务器穿透穿透
TCP+UDP打洞服务器中继服务器穿透简单几步将打洞和中继集成到你自己的项目中
</>
),
},
{
title: 'TCP、UDP、什么P',
title: '组网和转发',
Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
description: (
<>

View File

@@ -33,7 +33,7 @@ export default function Home() {
return (
<Layout
title={`${siteConfig.title}`}
description="linker、一个免费开源的P2P内网穿透内核">
description="linker、一个免费开源的P2P异地组网和内网穿透内核">
<HomepageHeader />
<main>
<HomepageFeatures />

View File

@@ -1,167 +0,0 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis;
using System.Linq;
using System.Collections.Generic;
using Microsoft.CodeAnalysis.Text;
using System.Text;
using System.Diagnostics;
namespace linker.gen
{
[Generator(LanguageNames.CSharp)]
public class InterfaceSourceGenerator : IIncrementalGenerator
{
private List<GeneratorInfo> generators = new List<GeneratorInfo> {
new GeneratorInfo{ ClassName="linker.plugins.flow.FlowTypesLoader", InterfaceName="linker.plugins.flow.IFlow" },
new GeneratorInfo{ ClassName="linker.plugins.relay.client.RelayClientTypesLoader", InterfaceName="linker.messenger.relay.client.transport.IRelayClientTransport" },
new GeneratorInfo{ ClassName="linker.plugins.relay.server.validator.RelayServerValidatorTypeLoader", InterfaceName="linker.messenger.relay.server.validator.IRelayServerValidator" },
new GeneratorInfo{ ClassName="linker.plugins.signIn.args.SignInArgsTypesLoader", InterfaceName="linker.messenger.signin.ISignInArgs" },
new GeneratorInfo{ ClassName="linker.plugins.resolver.ResolverTypesLoader", InterfaceName="linker.plugins.resolver.IResolver" },
new GeneratorInfo{ ClassName="linker.plugins.tunnel.TunnelExcludeIPTypesLoader", InterfaceName="linker.messenger.tunnel.ITunnelExcludeIP" },
new GeneratorInfo{ ClassName="linker.startup.StartupTransfer", InterfaceName="linker.startup.IStartup", Instance=true },
new GeneratorInfo{ ClassName="linker.plugins.messenger.MessengerResolverTypesLoader", InterfaceName="linker.messenger.IMessenger"},
new GeneratorInfo{ ClassName="linker.plugins.capi.ApiClientTypesLoader",InterfaceName="linker.plugins.capi.IApiClientController"},
new GeneratorInfo{ ClassName="linker.plugins.config.ConfigSyncTypesLoader", InterfaceName="linker.plugins.config.IConfigSync"},
new GeneratorInfo{ ClassName="linker.plugins.decenter.DecenterTypesLoader", InterfaceName="linker.plugins.decenter.IDecenter"},
new GeneratorInfo{ ClassName="linker.plugins.route.RouteExcludeIPTypesLoader", InterfaceName="linker.plugins.route.IRouteExcludeIP" },
};
public void Initialize(IncrementalGeneratorInitializationContext context)
{
IncrementalValueProvider<Compilation> compilations = context.CompilationProvider.Select((compilation, cancellationToken) => compilation);
context.RegisterSourceOutput(compilations, (sourceProductionContext, compilation) =>
{
foreach (GeneratorInfo info in generators)
{
var iFlowSymbol = compilation.GetTypeByMetadataName(info.InterfaceName);
List<string> types = new List<string> { };
List<string> classs = new List<string> { };
List<string> namespaces = new List<string> { };
foreach (var syntaxTree in compilation.SyntaxTrees)
{
if (syntaxTree == null)
{
continue;
}
var root = syntaxTree.GetRoot(sourceProductionContext.CancellationToken);
var classDeclarationSyntaxs = root
.DescendantNodes(descendIntoTrivia: true)
.OfType<ClassDeclarationSyntax>();
foreach (var classDeclarationSyntax in classDeclarationSyntaxs)
{
var model = compilation.GetSemanticModel(classDeclarationSyntax.SyntaxTree);
var classSymbol = model.GetDeclaredSymbol(classDeclarationSyntax) as INamedTypeSymbol;
if (classSymbol.AllInterfaces.Contains(iFlowSymbol))
{
types.Add($"typeof({classDeclarationSyntax.Identifier.Text})");
if (info.Instance)
classs.Add($"new {classDeclarationSyntax.Identifier.Text}()");
var namespaceDecl = classDeclarationSyntax.FirstAncestorOrSelf<NamespaceDeclarationSyntax>();
if (namespaceDecl != null)
{
namespaces.Add($"using {namespaceDecl.Name.ToString()};");
}
}
}
}
/*
var referencedAssemblySymbols = compilation.SourceModule.ReferencedAssemblySymbols;
foreach (IAssemblySymbol referencedAssemblySymbol in referencedAssemblySymbols)
{
var allTypeSymbol = GetAllTypeSymbol(referencedAssemblySymbol.GlobalNamespace).SelectMany(c=>c.DeclaringSyntaxReferences).Select(c=>c.SyntaxTree).ToList();
foreach (var item in allTypeSymbol)
{
var root = item.GetRoot(sourceProductionContext.CancellationToken);
var classDeclarationSyntaxs = root
.DescendantNodes(descendIntoTrivia: true)
.OfType<ClassDeclarationSyntax>();
foreach (var classDeclarationSyntax in classDeclarationSyntaxs)
{
var model = compilation.GetSemanticModel(classDeclarationSyntax.SyntaxTree);
var classSymbol = model.GetDeclaredSymbol(classDeclarationSyntax) as INamedTypeSymbol;
if (classSymbol.AllInterfaces.Contains(iFlowSymbol))
{
types.Add($"typeof({classDeclarationSyntax.Identifier.Text})");
if (info.Instance)
classs.Add($"new {classDeclarationSyntax.Identifier.Text}()");
var namespaceDecl = classDeclarationSyntax.FirstAncestorOrSelf<NamespaceDeclarationSyntax>();
if (namespaceDecl != null)
{
namespaces.Add($"using {namespaceDecl.Name.ToString()};");
}
}
}
}
}
*/
var spaces = info.ClassName.Split('.');
var source = $@"
using System;
using System.Collections.Generic;
{string.Join("\r\n", namespaces.Distinct())}
namespace {string.Join(".", spaces.Take(spaces.Count() - 1))}
{{
public partial class {spaces.LastOrDefault()}
{{
public static List<Type> GetSourceGeneratorTypes()
{{
return new List<Type> {{
{string.Join(",", types)}
}};
}}
public static List<{info.InterfaceName}> GetSourceGeneratorInstances()
{{
return new List<{info.InterfaceName}> {{
{string.Join(",", classs)}
}};
}}
}}
}}";
var sourceText = SourceText.From(source, Encoding.UTF8);
sourceProductionContext.AddSource($"{info.ClassName}Instances.g.cs", sourceText);
}
});
}
private static IEnumerable<INamedTypeSymbol> GetAllTypeSymbol(INamespaceSymbol namespaceSymbol)
{
var typeMemberList = namespaceSymbol.GetTypeMembers();
foreach (var typeSymbol in typeMemberList)
{
yield return typeSymbol;
}
foreach (var namespaceMember in namespaceSymbol.GetNamespaceMembers())
{
foreach (var typeSymbol in GetAllTypeSymbol(namespaceMember))
{
yield return typeSymbol;
}
}
}
public sealed class GeneratorInfo
{
public string ClassName { get; set; }
public string InterfaceName { get; set; }
public bool Instance { get; set; }
}
}
}

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Release\publish\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<History>True|2024-10-10T09:23:14.3539248Z||;</History>
<LastFailureDetails />
</PropertyGroup>
</Project>

View File

@@ -1,21 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AnalyzerLanguage>cs</AnalyzerLanguage>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<IsRoslynComponent>true</IsRoslynComponent>
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_LastSelectedProfileId>C:\Users\snltty\Desktop\linker\linker.gen\Properties\PublishProfiles\FolderProfile.pubxml</_LastSelectedProfileId>
</PropertyGroup>
</Project>

View File

@@ -38,7 +38,7 @@ namespace linker.libs.api
server = new WebSocketServer();
try
{
server.Start(System.Net.IPAddress.Any, port);
server.Start( port);
}
catch (Exception ex)
{

View File

@@ -70,6 +70,10 @@ namespace linker.libs.extends
}
public static void ReuseBind(this Socket socket, IPEndPoint ip)
{
if(ip.AddressFamily == AddressFamily.InterNetworkV6)
{
socket.IPv6Only(ip.AddressFamily,false);
}
socket.Reuse(true);
socket.Bind(ip);
}

View File

@@ -141,7 +141,6 @@ namespace linker.libs.socks5
res[^1] = *pp;
}
return res;
}
/// <summary>
@@ -212,21 +211,13 @@ namespace linker.libs.socks5
{
/*
* VERSION METHODS_COUNT METHODS
1字节 1字节 1到255字节长度由METHODS_COUNT值决定
0x05 0x03 0x00 0x01 0x02
* 1字节 1字节 1到255字节长度由METHODS_COUNT值决定
* 0x05 0x03 0x00 0x01 0x02
*/
if (data.Length < 2 || data.Length < 2 + data.Span[1])
{
return EnumProxyValidateDataResult.TooShort;
}
/*
if (data.Length > 2 + data.Span[1])
{
return EnumProxyValidateDataResult.TooLong;
}*/
return EnumProxyValidateDataResult.Equal;
}
/// <summary>
@@ -255,12 +246,6 @@ namespace linker.libs.socks5
{
return EnumProxyValidateDataResult.TooShort;
}
/*
if (data.Length > 4 + addrLength)
{
return EnumProxyValidateDataResult.TooLong;
}
*/
return EnumProxyValidateDataResult.Equal;
}
/// <summary>
@@ -309,12 +294,6 @@ namespace linker.libs.socks5
{
return EnumProxyValidateDataResult.TooShort;
}
/*
if (span.Length > 1 + 1 + nameLength + passwordLength)
{
return EnumProxyValidateDataResult.TooLong;
}
*/
return EnumProxyValidateDataResult.Equal;
}

View File

@@ -97,7 +97,7 @@ namespace linker.libs.websocket
}
var socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
//socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
socket.KeepAlive();
AsyncServerUserToken token = new AsyncServerUserToken

View File

@@ -83,12 +83,12 @@ namespace linker.libs.websocket
{ WebSocketFrameInfo.EnumOpcode.Pong,HandlePong},
};
}
public void Start(IPAddress bindip, int port)
public void Start(int port)
{
IPEndPoint localEndPoint = new IPEndPoint(bindip, port);
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.IPv6Any, port);
socket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
socket.IPv6Only(localEndPoint.AddressFamily,false);
socket.Bind(localEndPoint);
socket.Listen(int.MaxValue);
@@ -351,7 +351,7 @@ namespace linker.libs.websocket
private void HandleConnect(AsyncUserToken token, Memory<byte> data)
{
WebsocketHeaderInfo header = WebsocketHeaderInfo.Parse(data);
if (header.TryGetHeaderValue(WebsocketHeaderKey.SecWebSocketKey,out string key) == false)
if (header.TryGetHeaderValue(WebsocketHeaderKey.SecWebSocketKey, out string key) == false)
{
header.StatusCode = HttpStatusCode.MethodNotAllowed;
token.Connectrion.ConnectResponse(header);

View File

@@ -1,29 +1,25 @@
using linker.config;
using linker.libs.api;
using linker.libs.api;
using linker.libs.extends;
using linker.plugins.capi;
using linker.libs;
using linker.plugins.client;
using linker.plugins.messenger;
using MemoryPack;
using linker.plugins.access.messenger;
using linker.messenger;
using linker.messenger.signin;
namespace linker.plugins.access
namespace linker.messenger.access
{
public sealed class AccessApiController : IApiClientController
public sealed class AccessApiController : IApiController
{
private readonly IMessengerSender sender;
private readonly ClientSignInState clientSignInState;
private readonly SignInClientState signInClientState;
private readonly AccessDecenter accessDecenter;
private readonly ClientConfigTransfer clientConfigTransfer;
private readonly ISignInClientStore signInClientStore;
private readonly ISerializer serializer;
public AccessApiController(IMessengerSender sender, ClientSignInState clientSignInState, AccessDecenter accessDecenter, ClientConfigTransfer clientConfigTransfer)
public AccessApiController(IMessengerSender sender, SignInClientState signInClientState, AccessDecenter accessDecenter, ISignInClientStore signInClientStore, ISerializer serializer)
{
this.sender = sender;
this.clientSignInState = clientSignInState;
this.signInClientState = signInClientState;
this.accessDecenter = accessDecenter;
this.clientConfigTransfer = clientConfigTransfer;
this.signInClientStore = signInClientStore;
this.serializer = serializer;
}
public void Refresh(ApiControllerParamsInfo param)
@@ -45,20 +41,20 @@ namespace linker.plugins.access
return new AccessListInfo { HashCode = version };
}
[ClientApiAccessAttribute(ClientApiAccess.Access)]
[Access(AccessValue.Access)]
public async Task<bool> SetAccess(ApiControllerParamsInfo param)
{
ConfigUpdateAccessInfo configUpdateAccessInfo = param.Content.DeJson<ConfigUpdateAccessInfo>();
if (configUpdateAccessInfo.ToMachineId == clientConfigTransfer.Id)
AccessUpdateInfo configUpdateAccessInfo = param.Content.DeJson<AccessUpdateInfo>();
if (configUpdateAccessInfo.ToMachineId == signInClientStore.Id)
{
return false;
}
configUpdateAccessInfo.FromMachineId = clientConfigTransfer.Id;
configUpdateAccessInfo.FromMachineId = signInClientStore.Id;
MessageResponeInfo resp = await sender.SendReply(new MessageRequestWrap
{
Connection = clientSignInState.Connection,
Connection = signInClientState.Connection,
MessengerId = (ushort)AccessMessengerIds.AccessUpdateForward,
Payload = MemoryPackSerializer.Serialize(configUpdateAccessInfo)
Payload = serializer.Serialize(configUpdateAccessInfo)
});
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
}
@@ -68,7 +64,7 @@ namespace linker.plugins.access
public sealed class AccessListInfo
{
public Dictionary<string, ClientApiAccess> List { get; set; }
public Dictionary<string, AccessValue> List { get; set; }
public ulong HashCode { get; set; }
}
}

View File

@@ -0,0 +1,55 @@
using linker.libs;
using linker.messenger.decenter;
using linker.messenger.signin;
namespace linker.messenger.access
{
public sealed class AccessDecenter : IDecenter
{
public string Name => "access";
public VersionManager SyncVersion { get; } = new VersionManager();
public VersionManager DataVersion { get; } = new VersionManager();
public Dictionary<string, AccessValue> Accesss { get; } = new Dictionary<string, AccessValue>();
private readonly ISignInClientStore signInClientStore;
private readonly IAccessStore accessStore;
private readonly ISerializer serializer;
public AccessDecenter(SignInClientState signInClientState, ISignInClientStore signInClientStore, IAccessStore accessStore, ISerializer serializer)
{
this.signInClientStore = signInClientStore;
this.accessStore = accessStore;
this.serializer = serializer;
signInClientState.NetworkEnabledHandle += (times) => SyncVersion.Add();
accessStore.OnChanged += SyncVersion.Add;
}
public void Refresh()
{
SyncVersion.Add();
}
public Memory<byte> GetData()
{
AccessInfo info = new AccessInfo { MachineId = signInClientStore.Id, Access = accessStore.Access };
Accesss[info.MachineId] = info.Access;
DataVersion.Add();
return serializer.Serialize(info);
}
public void SetData(Memory<byte> data)
{
AccessInfo access = serializer.Deserialize<AccessInfo>(data.Span);
Accesss[access.MachineId] = access.Access;
DataVersion.Add();
}
public void SetData(List<ReadOnlyMemory<byte>> data)
{
List<AccessInfo> list = data.Select(c => serializer.Deserialize<AccessInfo>(c.Span)).ToList();
foreach (var item in list)
{
Accesss[item.MachineId] = item.Access;
}
DataVersion.Add();
}
}
}

View File

@@ -1,27 +1,24 @@
using linker.config;
using linker.libs;
using linker.messenger;
using linker.libs;
using linker.messenger.signin;
using linker.plugins.client;
using MemoryPack;
namespace linker.plugins.access.messenger
namespace linker.messenger.access
{
public sealed class AccessServerMessenger : IMessenger
{
private readonly IMessengerSender sender;
private readonly SignCaching signCaching;
public AccessServerMessenger(IMessengerSender sender, SignCaching signCaching)
private readonly SignInServerCaching signCaching;
private readonly ISerializer serializer;
public AccessServerMessenger(IMessengerSender sender, SignInServerCaching signCaching, ISerializer serializer)
{
this.sender = sender;
this.signCaching = signCaching;
this.serializer = serializer;
}
[MessengerId((ushort)AccessMessengerIds.AccessUpdateForward)]
public void AccessUpdateForward(IConnection connection)
{
ConfigUpdateAccessInfo info = MemoryPackSerializer.Deserialize<ConfigUpdateAccessInfo>(connection.ReceiveRequestWrap.Payload.Span);
AccessUpdateInfo info = serializer.Deserialize<AccessUpdateInfo>(connection.ReceiveRequestWrap.Payload.Span);
info.FromMachineId = connection.Id;
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) && signCaching.TryGet(info.ToMachineId, out SignCacheInfo cache1) && cache1.GroupId == cache.GroupId)
{
@@ -31,7 +28,7 @@ namespace linker.plugins.access.messenger
{
Connection = cache1.Connection,
MessengerId = (ushort)AccessMessengerIds.AccessUpdate,
Payload = MemoryPackSerializer.Serialize(info),
Payload = serializer.Serialize(info),
Timeout = 3000,
}).ContinueWith(async (result) =>
{
@@ -49,21 +46,18 @@ namespace linker.plugins.access.messenger
public sealed class AccessClientMessenger : IMessenger
{
private readonly AccessTransfer accessTransfer;
private readonly FileConfig fileConfig;
private readonly ClientSignInTransfer clientSignInTransfer;
public AccessClientMessenger(AccessTransfer accessTransfer, FileConfig fileConfig, ClientSignInTransfer clientSignInTransfer)
private readonly IAccessStore accessStore;
private readonly ISerializer serializer;
public AccessClientMessenger(IAccessStore accessStore, ISerializer serializer)
{
this.accessTransfer = accessTransfer;
this.fileConfig = fileConfig;
this.clientSignInTransfer = clientSignInTransfer;
this.accessStore = accessStore;
this.serializer = serializer;
}
[MessengerId((ushort)AccessMessengerIds.AccessUpdate)]
public void AccessUpdate(IConnection connection)
{
ConfigUpdateAccessInfo info = MemoryPackSerializer.Deserialize<ConfigUpdateAccessInfo>(connection.ReceiveRequestWrap.Payload.Span);
accessTransfer.SetAccess(info);
AccessUpdateInfo info = serializer.Deserialize<AccessUpdateInfo>(connection.ReceiveRequestWrap.Payload.Span);
accessStore.SetAccess(info);
connection.Write(Helper.TrueArray);
}
}

View File

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

View File

@@ -0,0 +1,170 @@
namespace linker.messenger.access
{
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public sealed class AccessAttribute : Attribute
{
public AccessValue Value { get; set; }
public AccessAttribute(AccessValue value)
{
Value = value;
}
}
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
public sealed class AccessDisplayAttribute : Attribute
{
public string Value { get; set; }
public AccessDisplayAttribute(string value)
{
Value = value;
}
}
[Flags]
public enum AccessValue : ulong
{
None = 0,
[AccessDisplay("简单管理")]
NetManager = 1,
[AccessDisplay("专业管理")]
FullManager = 1 << 1,
[AccessDisplay("服务器配置")]
Config = 1 << 2,
[AccessDisplay("日志列表")]
LoggerShow = 1 << 3,
[AccessDisplay("日志配置")]
LoggerLevel = 1 << 4,
[AccessDisplay("修改本机设备名")]
RenameSelf = 1 << 5,
[AccessDisplay("修改所有设备名")]
RenameOther = 1 << 6,
[AccessDisplay("显示公网信息")]
ExternalShow = 1 << 7,
[AccessDisplay("升级本机")]
UpdateSelf = 1 << 8,
[AccessDisplay("升级所有设备")]
UpdateOther = 1 << 9,
[AccessDisplay("升级服务器")]
UpdateServer = 1 << 10,
[AccessDisplay("开关本机网卡")]
TuntapStatusSelf = 1 << 11,
[AccessDisplay("开关所有网卡")]
TuntapStatusOther = 1 << 12,
[AccessDisplay("修改本机网卡")]
TuntapChangeSelf = 1 << 13,
[AccessDisplay("修改所有网卡")]
TuntapChangeOther = 1 << 14,
[AccessDisplay("显示本机端口转发")]
ForwardShowSelf = 1 << 15,
[AccessDisplay("显示所有设备端口转发")]
ForwardShowOther = 1 << 16,
[AccessDisplay("配置本机端口转发")]
ForwardSelf = 1 << 17,
[AccessDisplay("配置所有设备端口转发")]
ForwardOther = 1 << 18,
[AccessDisplay("重启其它设备")]
Reboot = 1 << 19,
[AccessDisplay("删除其它设备")]
Remove = 1 << 20,
[AccessDisplay("修改本机网关")]
TunnelChangeSelf = 1 << 21,
[AccessDisplay("修改所有设备网关")]
TunnelChangeOther = 1 << 22,
[AccessDisplay("删除隧道连接")]
TunnelRemove = 1 << 23,
[AccessDisplay("开启管理API")]
Api = 1 << 24,
[AccessDisplay("开启管理网页")]
Web = 1 << 25,
[AccessDisplay("导出配置")]
Export = 1 << 26,
[AccessDisplay("修改权限")]
Access = 1 << 27,
[AccessDisplay("修改打洞协议")]
Transport = 1 << 28,
[AccessDisplay("修改验证参数")]
Action = 1 << 29,
[AccessDisplay("查看内网穿透流量")]
SForwardFlow = 1 << 30,
[AccessDisplay("查看中继流量")]
RelayFlow = (ulong)1 << 31,
[AccessDisplay("查看信标流量")]
SigninFlow = (ulong)1 << 32,
[AccessDisplay("查看流量")]
Flow = (ulong)1 << 33,
[AccessDisplay("同步配置")]
Sync = (ulong)1 << 34,
[AccessDisplay("配置组网网络")]
Lease = (ulong)1 << 35,
[AccessDisplay("开关本机socks5")]
Socks5StatusSelf = (ulong)1 << 36,
[AccessDisplay("开关所有socks5")]
Socks5StatusOther = (ulong)1 << 37,
[AccessDisplay("修改本机socks5")]
Socks5ChangeSelf = (ulong)1 << 38,
[AccessDisplay("修改所有socks5")]
Socks5ChangeOther = (ulong)1 << 39,
[AccessDisplay("配置分组")]
Group = (ulong)1 << 40,
Full = ulong.MaxValue >> 64 - 52,
}
public sealed class AccessTextInfo
{
public ulong Value { get; set; }
public string Text { get; set; }
}
public sealed partial class AccessUpdateInfo
{
/// <summary>
/// 设备
/// </summary>
public string FromMachineId { get; set; }
/// <summary>
/// 设备
/// </summary>
public string ToMachineId { get; set; }
/// <summary>
/// 权限
/// </summary>
public ulong Access { get; set; }
}
public sealed partial class AccessInfo
{
/// <summary>
/// 设备
/// </summary>
public string MachineId { get; set; }
/// <summary>
/// 权限
/// </summary>
public AccessValue Access { get; set; }
}
}

View File

@@ -0,0 +1,39 @@
using linker.libs;
using linker.libs.web;
using linker.messenger.access;
using linker.messenger.decenter;
using Microsoft.Extensions.DependencyInjection;
namespace linker.messenger.api
{
public static class Entry
{
public static ServiceCollection AddAccessClient(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<AccessApiController>();
serviceCollection.AddSingleton<AccessDecenter>();
serviceCollection.AddSingleton<AccessClientMessenger>();
return serviceCollection;
}
public static ServiceProvider UseAccessClient(this ServiceProvider serviceProvider)
{
IApiServer apiServer = serviceProvider.GetService<IApiServer>();
apiServer.AddPlugins(new List<libs.api.IApiController> { serviceProvider.GetService<AccessApiController>() });
DecenterClientTransfer decenterClientTransfer = serviceProvider.GetService<DecenterClientTransfer>();
decenterClientTransfer.AddDecenters(new List<IDecenter> { serviceProvider.GetService<AccessDecenter>() });
return serviceProvider;
}
public static ServiceCollection AddAccessServer(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<AccessServerMessenger>();
return serviceCollection;
}
public static ServiceProvider UseAccessServer(this ServiceProvider serviceProvider)
{
return serviceProvider;
}
}
}

View File

@@ -0,0 +1,15 @@
namespace linker.messenger.access
{
public interface IAccessStore
{
public AccessValue Access { get; }
public Action OnChanged { get; set; }
public void SetAccess(AccessUpdateInfo info);
public AccessValue AssignAccess(AccessValue access);
public bool HasAccess(AccessValue clientManagerAccess);
}
}

View File

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

View File

@@ -0,0 +1,29 @@
using linker.libs.api;
using linker.libs.extends;
namespace linker.messenger.action
{
public sealed class ActionApiController : IApiController
{
private readonly IActionStore actionStore;
public ActionApiController(IActionStore actionStore)
{
this.actionStore = actionStore;
}
public bool SetArgs(ApiControllerParamsInfo param)
{
actionStore.SetActionArg(param.Content);
return true;
}
public bool SetServerArgs(ApiControllerParamsInfo param)
{
actionStore.SetActionArgs(param.Content.DeJson<Dictionary<string, string>>());
return true;
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Net.Http.Json;
using System.Text.Json.Nodes;
namespace linker.messenger.action
{
public sealed class ActionTransfer
{
public async Task<string> ExcuteActions(string actionJson, string url)
{
if (string.IsNullOrWhiteSpace(url)) return string.Empty;
try
{
using HttpClient client = new HttpClient();
JsonContent json = JsonContent.Create(JsonObject.Parse(actionJson));
HttpResponseMessage resp = await client.PostAsync(url, json);
if (resp.IsSuccessStatusCode)
{
string result = await resp.Content.ReadAsStringAsync();
if (result.Equals("ok", StringComparison.CurrentCultureIgnoreCase) == false)
{
return $"post {url} fail->{result}";
}
}
else
{
return $"post {url} fail->{resp.StatusCode}";
}
}
catch (Exception ex)
{
return $"post {url} fail->{ex.Message}";
}
return string.Empty;
}
}
}

View File

@@ -0,0 +1,38 @@
using linker.messenger.action;
using Microsoft.Extensions.DependencyInjection;
namespace linker.messenger.api
{
public static class Entry
{
public static ServiceCollection AddActionClient(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<ActionApiController>();
serviceCollection.AddSingleton<ActionTransfer>();
serviceCollection.AddSingleton<SignInArgsAction>();
serviceCollection.AddSingleton<RelayValidatorAction>();
serviceCollection.AddSingleton<SForwardValidatorAction>();
return serviceCollection;
}
public static ServiceProvider UseActionClient(this ServiceProvider serviceProvider)
{
ApiServer apiServer=serviceProvider.GetService<ApiServer>();
apiServer.AddPlugins(new List<libs.api.IApiController> { serviceProvider.GetService<ActionApiController>() });
return serviceProvider;
}
public static ServiceCollection AddActionServer(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<ActionTransfer>();
serviceCollection.AddSingleton<SignInArgsAction>();
serviceCollection.AddSingleton<RelayValidatorAction>();
serviceCollection.AddSingleton<SForwardValidatorAction>();
return serviceCollection;
}
public static ServiceProvider UseActionServer(this ServiceProvider serviceProvider)
{
return serviceProvider;
}
}
}

View File

@@ -0,0 +1,18 @@
namespace linker.messenger.action
{
public sealed class ActionInfo
{
public string Arg { get; set; }
public Dictionary<string, string> Args { get; set; } = new Dictionary<string, string>();
}
public interface IActionStore
{
public string SignInActionUrl{ get; }
public string RelayActionUrl { get; }
public string SForwardActionUrl { get; }
public void SetActionArg(string action);
public void SetActionArgs(Dictionary<string, string> actions);
public bool TryAddActionArg(string host, Dictionary<string, string> args);
public bool TryGetActionArg(Dictionary<string, string> args, out string str, out string machineKey);
}
}

View File

@@ -1,13 +1,11 @@
using linker.config;
using linker.libs.extends;
using linker.messenger.signin;
using linker.plugins.sforward.config;
using linker.plugins.sforward.validator;
using linker.libs.extends;
using linker.messenger.relay.server.validator;
using linker.messenger.signin;
using linker.messenger.signin.args;
using System.Net;
using System.Text.Json.Nodes;
namespace linker.plugins.action
namespace linker.messenger.action
{
public sealed class JsonArgInfo
{
@@ -104,26 +102,26 @@ namespace linker.plugins.action
public sealed class SignInArgsAction : JsonArgReplace, ISignInArgs
{
private readonly ActionTransfer actionTransfer;
private readonly FileConfig fileConfig;
private readonly IActionStore actionStore;
public SignInArgsAction(ActionTransfer actionTransfer, FileConfig fileConfig)
public SignInArgsAction(ActionTransfer actionTransfer, IActionStore actionStore)
{
this.actionTransfer = actionTransfer;
this.fileConfig = fileConfig;
this.actionStore = actionStore;
}
public async Task<string> Invoke(string host, Dictionary<string, string> args)
{
actionTransfer.TryAddActionArg(host, args);
actionStore.TryAddActionArg(host, args);
await Task.CompletedTask;
return string.Empty;
}
public async Task<string> Validate(SignInfo signInfo, SignCacheInfo cache)
{
if (string.IsNullOrWhiteSpace(actionTransfer.SignInActionUrl) == false)
if (string.IsNullOrWhiteSpace(actionStore.SignInActionUrl) == false)
{
if (actionTransfer.TryGetActionArg(signInfo.Args, out string str, out string machineKey) == false)
if (actionStore.TryGetActionArg(signInfo.Args, out string str, out string machineKey) == false)
{
return $"singin action URL exists, but [{signInfo.MachineName}] action value is not configured";
}
@@ -139,7 +137,7 @@ namespace linker.plugins.action
IPAddress = signInfo.Connection.Address.Address
}
};
return await actionTransfer.ExcuteActions(Replace(replace, str), actionTransfer.SignInActionUrl);
return await actionTransfer.ExcuteActions(Replace(replace, str), actionStore.SignInActionUrl);
}
return string.Empty;
@@ -149,23 +147,22 @@ namespace linker.plugins.action
public sealed class RelayValidatorAction : JsonArgReplace, IRelayServerValidator
{
private readonly ActionTransfer actionTransfer;
private readonly FileConfig fileConfig;
public RelayValidatorAction(ActionTransfer actionTransfer, FileConfig fileConfig)
private readonly IActionStore actionStore;
public RelayValidatorAction(ActionTransfer actionTransfer, IActionStore actionStore)
{
this.actionTransfer = actionTransfer;
this.fileConfig = fileConfig;
this.actionStore = actionStore;
}
public async Task<string> Validate(linker.messenger.relay.client.transport.RelayInfo relayInfo, SignCacheInfo fromMachine, SignCacheInfo toMachine)
{
if (string.IsNullOrWhiteSpace(actionTransfer.RelayActionUrl) == false)
if (string.IsNullOrWhiteSpace(actionStore.RelayActionUrl) == false)
{
if (actionTransfer.TryGetActionArg(fromMachine.Args, out string str, out string machineKey) == false)
if (actionStore.TryGetActionArg(fromMachine.Args, out string str, out string machineKey) == false)
{
return $"relay action URL exists, but [{fromMachine.MachineName}] action value is not configured";
}
if (toMachine != null && actionTransfer.TryGetActionArg(toMachine.Args, out string str1, out string machineKey1) == false)
if (toMachine != null && actionStore.TryGetActionArg(toMachine.Args, out string str1, out string machineKey1) == false)
{
return $"relay action URL exists, but [{toMachine.MachineName}]e action value is not configured";
}
@@ -190,7 +187,7 @@ namespace linker.plugins.action
IPAddress = fromMachine.Connection.Address.Address,
}
};
return await actionTransfer.ExcuteActions(Replace(replace, str), actionTransfer.RelayActionUrl);
return await actionTransfer.ExcuteActions(Replace(replace, str), actionStore.RelayActionUrl);
}
return string.Empty;
}
@@ -199,19 +196,18 @@ namespace linker.plugins.action
public sealed class SForwardValidatorAction : JsonArgReplace, ISForwardValidator
{
private readonly ActionTransfer actionTransfer;
private readonly FileConfig fileConfig;
public SForwardValidatorAction(ActionTransfer actionTransfer, FileConfig fileConfig)
private readonly IActionStore actionStore;
public SForwardValidatorAction(ActionTransfer actionTransfer, IActionStore actionStore)
{
this.actionTransfer = actionTransfer;
this.fileConfig = fileConfig;
this.actionStore = actionStore;
}
public async Task<string> Validate(SignCacheInfo cache, SForwardAddInfo sForwardAddInfo)
{
if (string.IsNullOrWhiteSpace(actionTransfer.SForwardActionUrl) == false)
if (string.IsNullOrWhiteSpace(actionStore.SForwardActionUrl) == false)
{
if (actionTransfer.TryGetActionArg(cache.Args, out string str, out string machineKey) == false)
if (actionStore.TryGetActionArg(cache.Args, out string str, out string machineKey) == false)
{
return $"sforward action URL exists, but [{cache.MachineName}] action value is not configured";
}
@@ -232,7 +228,7 @@ namespace linker.plugins.action
IPAddress = cache.Connection.Address.Address
}
};
return await actionTransfer.ExcuteActions(Replace(replace, str), actionTransfer.SForwardActionUrl);
return await actionTransfer.ExcuteActions(Replace(replace, str), actionStore.SForwardActionUrl);
}
return string.Empty;
}

View File

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

View File

@@ -1,31 +1,25 @@
using linker.config;
using linker.libs.api;
using linker.plugins.access;
using linker.libs.api;
using System.Reflection;
namespace linker.plugins.capi
namespace linker.messenger.api
{
/// <summary>
/// 前段接口服务
/// </summary>
public sealed partial class ApiClientServer : ApiServer, IApiClientServer
public sealed partial class ApiServer : libs.api.ApiServer, IApiServer
{
private readonly FileConfig config;
private readonly AccessTransfer accessTransfer;
public ApiClientServer(FileConfig config, AccessTransfer accessTransfer)
public ApiServer()
{
this.config = config;
this.accessTransfer = accessTransfer;
}
/// <summary>
/// 加载插件
/// </summary>
public void LoadPlugins(List<object> list)
public void AddPlugins(List<IApiController> list)
{
Type voidType = typeof(void);
foreach (object obj in list)
foreach (IApiController obj in list)
{
Type type = obj.GetType();
string path = type.Name.Replace("ApiController", "").Replace("ApiController", "");
@@ -36,13 +30,14 @@ namespace linker.plugins.capi
{
bool istask = method.ReturnType.GetProperty("IsCompleted") != null && method.ReturnType.GetMethod("GetAwaiter") != null;
bool isTaskResult = method.ReturnType.GetProperty("Result") != null;
/*
ClientApiAccessAttribute accessAttr = method.GetCustomAttribute<ClientApiAccessAttribute>();
ulong access = 0;
if (accessAttr != null)
{
access = (ulong)accessAttr.Value;
}
*/
plugins.TryAdd(key, new PluginPathCacheInfo
{
IsVoid = method.ReturnType == voidType,
@@ -50,7 +45,7 @@ namespace linker.plugins.capi
Target = obj,
IsTask = istask,
IsTaskResult = isTaskResult,
Access = access,
Access = 0,
HasAccess = HasAccess,
});
}
@@ -59,7 +54,8 @@ namespace linker.plugins.capi
}
private bool HasAccess(ulong access)
{
return accessTransfer.HasAccess((ClientApiAccess)access);
return true;
//return accessTransfer.HasAccess((ClientApiAccess)access);
}
}
}

View File

@@ -0,0 +1,35 @@
using linker.libs;
using linker.libs.web;
using Microsoft.Extensions.DependencyInjection;
namespace linker.messenger.api
{
public static class Entry
{
public static ServiceCollection AddApiClient(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<IApiServer, ApiServer>();
serviceCollection.AddSingleton<IWebServer, WebServer>();
return serviceCollection;
}
public static ServiceProvider UseApiClient(this ServiceProvider serviceProvider)
{
IApiStore apiStore = serviceProvider.GetService<IApiStore>();
if (apiStore.Info.ApiPort > 0)
{
LoggerHelper.Instance.Info($"start client api server");
IApiServer server = serviceProvider.GetService<IApiServer>();
server.Websocket(apiStore.Info.ApiPort, apiStore.Info.ApiPassword);
LoggerHelper.Instance.Warning($"client api listen:{apiStore.Info.ApiPort}");
LoggerHelper.Instance.Warning($"client api password:{apiStore.Info.ApiPassword}");
}
if (apiStore.Info.WebPort > 0)
{
IWebServer webServer = serviceProvider.GetService<IWebServer>();
webServer.Start(apiStore.Info.WebPort, apiStore.Info.WebRoot);
LoggerHelper.Instance.Warning($"client web listen:{apiStore.Info.WebPort}");
}
return serviceProvider;
}
}
}

View File

@@ -0,0 +1,10 @@
using linker.libs.api;
namespace linker.messenger.api
{
public interface IApiServer : libs.api.IApiServer
{
public void AddPlugins(List<IApiController> list);
}
}

View File

@@ -1,16 +1,7 @@
using linker.libs;
namespace linker.config
namespace linker.messenger.api
{
public partial class ConfigClientInfo
{
/// <summary>
/// 客户端管理接口配置
/// </summary>
public CApiConfigClientInfo CApi { get; set; } = new CApiConfigClientInfo();
}
public sealed class CApiConfigClientInfo
public sealed class ApiClientInfo
{
/// <summary>
/// 管理接口端口
@@ -30,4 +21,9 @@ namespace linker.config
/// </summary>
public string WebRoot { get; set; } = "./web/";
}
public interface IApiStore
{
public ApiClientInfo Info { get; }
}
}

View File

@@ -0,0 +1,12 @@
using linker.libs.web;
namespace linker.messenger.api
{
/// <summary>
/// 本地web管理端服务器
/// </summary>
public sealed class WebServer : libs.web.WebServer, IWebServer
{
}
}

View File

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

View File

@@ -1,16 +1,15 @@
using linker.libs;
using linker.libs.extends;
using linker.plugins.client;
using linker.tunnel;
using linker.tunnel.connection;
using System.Collections.Concurrent;
using linker.plugins.relay.client;
using linker.plugins.pcp;
using linker.messenger.relay.client;
using linker.messenger.pcp;
using linker.messenger.signin;
namespace linker.plugins.tunnel
namespace linker.messenger.channel
{
public class TunnelBase
public class Channel
{
public VersionManager Version { get; } = new VersionManager();
protected virtual string TransactionId { get; }
@@ -19,20 +18,18 @@ namespace linker.plugins.tunnel
private readonly TunnelTransfer tunnelTransfer;
private readonly RelayClientTransfer relayTransfer;
private readonly PcpTransfer pcpTransfer;
private readonly ClientSignInTransfer clientSignInTransfer;
private readonly ClientSignInState clientSignInState;
private readonly ClientConfigTransfer clientConfigTransfer;
private readonly RelayClientConfigTransfer relayClientConfigTransfer;
private readonly SignInClientTransfer signInClientTransfer;
private readonly ISignInClientStore signInClientStore;
private readonly IRelayClientStore relayClientStore;
public TunnelBase(TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, ClientSignInTransfer clientSignInTransfer, ClientSignInState clientSignInState, ClientConfigTransfer clientConfigTransfer, RelayClientConfigTransfer relayClientConfigTransfer)
public Channel(TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, SignInClientTransfer signInClientTransfer, ISignInClientStore signInClientStore, IRelayClientStore relayClientStore)
{
this.tunnelTransfer = tunnelTransfer;
this.relayTransfer = relayTransfer;
this.pcpTransfer = pcpTransfer;
this.clientSignInTransfer = clientSignInTransfer;
this.clientSignInState = clientSignInState;
this.clientConfigTransfer = clientConfigTransfer;
this.relayClientConfigTransfer = relayClientConfigTransfer;
this.signInClientTransfer = signInClientTransfer;
this.signInClientStore = signInClientStore;
this.relayClientStore = relayClientStore;
//监听打洞成功
tunnelTransfer.SetConnectedCallback(TransactionId, OnConnected);
@@ -40,7 +37,7 @@ namespace linker.plugins.tunnel
relayTransfer.SetConnectedCallback(TransactionId, OnConnected);
//监听节点中继成功回调
pcpTransfer.SetConnectedCallback(TransactionId, OnConnected);
}
protected virtual void Connected(ITunnelConnection connection)
{
@@ -76,7 +73,7 @@ namespace linker.plugins.tunnel
}
protected async ValueTask<ITunnelConnection> ConnectTunnel(string machineId, TunnelProtocolType denyProtocols)
{
if (clientConfigTransfer.Id == machineId)
if (signInClientStore.Id == machineId)
{
return null;
}
@@ -99,7 +96,7 @@ namespace linker.plugins.tunnel
return connection;
}
//不在线就不必连了
if (await clientSignInTransfer.GetOnline(machineId) == false)
if (await signInClientTransfer.GetOnline(machineId) == false)
{
return null;
}
@@ -126,7 +123,7 @@ namespace linker.plugins.tunnel
{
//中继
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"{TransactionId} relay to {machineId}");
ITunnelConnection connection = await relayTransfer.ConnectAsync(clientConfigTransfer.Id, machineId, TransactionId, relayClientConfigTransfer.DefaultNodeId).ConfigureAwait(false);
ITunnelConnection connection = await relayTransfer.ConnectAsync(signInClientStore.Id, machineId, TransactionId, relayClientStore.DefaultNodeId).ConfigureAwait(false);
if (connection != null)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"{TransactionId} relay success,{connection.ToString()}");

View File

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

View File

@@ -1,14 +1,8 @@
using linker.plugins.client;
using linker.plugins.messenger;
using MemoryPack;
using linker.libs;
using linker.plugins.decenter.messenger;
using linker.messenger;
using linker.libs;
using linker.messenger.signin;
namespace linker.plugins.decenter
namespace linker.messenger.decenter
{
[MemoryPackable]
public sealed partial class DecenterSyncInfo
{
public DecenterSyncInfo() { }
@@ -16,22 +10,24 @@ namespace linker.plugins.decenter
public Memory<byte> Data { get; set; }
}
public sealed class DecenterTransfer
public sealed class DecenterClientTransfer
{
private List<IDecenter> syncs = new List<IDecenter>();
private readonly IMessengerSender messengerSender;
private readonly ClientSignInState clientSignInState;
public DecenterTransfer(IMessengerSender messengerSender, ClientSignInState clientSignInState)
private readonly SignInClientState signInClientState;
private readonly ISerializer serializer;
public DecenterClientTransfer(IMessengerSender messengerSender, SignInClientState signInClientState, ISerializer serializer)
{
this.messengerSender = messengerSender;
this.clientSignInState = clientSignInState;
this.signInClientState = signInClientState;
this.serializer = serializer;
SyncTask();
}
public void LoadDecenters(List<IDecenter> list)
public void AddDecenters(List<IDecenter> list)
{
syncs = list;
syncs = syncs.Concat(list).Distinct().ToList();
}
public Memory<byte> Sync(DecenterSyncInfo decenterSyncInfo)
@@ -59,9 +55,9 @@ namespace linker.plugins.decenter
Time = Environment.TickCount64,
Task = messengerSender.SendReply(new MessageRequestWrap
{
Connection = clientSignInState.Connection,
Connection = signInClientState.Connection,
MessengerId = (ushort)DecenterMessengerIds.SyncForward,
Payload = MemoryPackSerializer.Serialize(new DecenterSyncInfo { Name = c.Name, Data = c.GetData() }),
Payload = serializer.Serialize(new DecenterSyncInfo { Name = c.Name, Data = c.GetData() }),
Timeout = 15000
})
};
@@ -71,7 +67,7 @@ namespace linker.plugins.decenter
{
if (task.Task.Result.Code == MessageResponeCodes.OK)
{
List<ReadOnlyMemory<byte>> list = MemoryPackSerializer.Deserialize<List<ReadOnlyMemory<byte>>>(task.Task.Result.Data.Span);
List<ReadOnlyMemory<byte>> list = serializer.Deserialize<List<ReadOnlyMemory<byte>>>(task.Task.Result.Data.Span);
task.Decenter.SetData(list);
}
else
@@ -81,12 +77,6 @@ namespace linker.plugins.decenter
LoggerHelper.Instance.Error($"decenter {task.Decenter.Name}->{task.Task.Result.Code}");
}
}
/*
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{
LoggerHelper.Instance.Debug($"decenter {task.Decenter.Name}->{Environment.TickCount64 - task.Time}ms");
}
*/
}
}
catch (Exception ex)

View File

@@ -0,0 +1,39 @@
using Microsoft.Extensions.DependencyInjection;
namespace linker.messenger.decenter
{
public static class Entry
{
public static ServiceCollection AddDecenterClient(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<DecenterClientTransfer>();
serviceCollection.AddSingleton<DecenterClientMessenger>();
return serviceCollection;
}
public static ServiceProvider UseDecenterClient(this ServiceProvider serviceProvider)
{
DecenterClientTransfer decenterClientTransfer = serviceProvider.GetService<DecenterClientTransfer>();
IMessengerResolver messengerResolver = serviceProvider.GetService<IMessengerResolver>();
messengerResolver.AddMessenger(new List<IMessenger> { serviceProvider.GetService<DecenterClientMessenger>() });
return serviceProvider;
}
public static ServiceCollection AddDecenterServer(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<DecenterServerMessenger>();
return serviceCollection;
}
public static ServiceProvider UseDecenterServer(this ServiceProvider serviceProvider)
{
IMessengerResolver messengerResolver = serviceProvider.GetService<IMessengerResolver>();
messengerResolver.AddMessenger(new List<IMessenger> { serviceProvider.GetService<DecenterServerMessenger>() });
return serviceProvider;
}
}
}

View File

@@ -1,6 +1,6 @@
using linker.libs;
namespace linker.plugins.decenter
namespace linker.messenger.decenter
{
public interface IDecenter
{

View File

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

View File

@@ -1,26 +1,26 @@
using linker.libs;
using linker.messenger;
using linker.messenger.signin;
using MemoryPack;
namespace linker.plugins.decenter.messenger
namespace linker.messenger.decenter
{
public sealed class DecenterServerMessenger : IMessenger
{
private readonly IMessengerSender sender;
private readonly SignCaching signCaching;
private readonly SignInServerCaching signCaching;
private readonly ISerializer serializer;
public DecenterServerMessenger(IMessengerSender sender, SignCaching signCaching)
public DecenterServerMessenger(IMessengerSender sender, SignInServerCaching signCaching, ISerializer serializer)
{
this.sender = sender;
this.signCaching = signCaching;
this.serializer = serializer;
}
[MessengerId((ushort)DecenterMessengerIds.SyncForward)]
public void SyncForward(IConnection connection)
{
DecenterSyncInfo info = MemoryPackSerializer.Deserialize<DecenterSyncInfo>(connection.ReceiveRequestWrap.Payload.Span);
DecenterSyncInfo info = serializer.Deserialize<DecenterSyncInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache))
{
uint requiestid = connection.ReceiveRequestWrap.RequestId;
@@ -47,7 +47,7 @@ namespace linker.plugins.decenter.messenger
{
RequestId = requiestid,
Connection = connection,
Payload = MemoryPackSerializer.Serialize(results)
Payload = serializer.Serialize(results)
}, (ushort)DecenterMessengerIds.SyncForward).ConfigureAwait(false);
}
@@ -62,17 +62,19 @@ namespace linker.plugins.decenter.messenger
public sealed class DecenterClientMessenger : IMessenger
{
private readonly DecenterTransfer syncTreansfer;
private readonly DecenterClientTransfer syncTreansfer;
private readonly ISerializer serializer;
public DecenterClientMessenger(DecenterTransfer syncTreansfer)
public DecenterClientMessenger(DecenterClientTransfer syncTreansfer, ISerializer serializer)
{
this.syncTreansfer = syncTreansfer;
this.serializer = serializer;
}
[MessengerId((ushort)DecenterMessengerIds.Sync)]
public void Sync(IConnection connection)
{
DecenterSyncInfo info = MemoryPackSerializer.Deserialize<DecenterSyncInfo>(connection.ReceiveRequestWrap.Payload.Span);
DecenterSyncInfo info = serializer.Deserialize<DecenterSyncInfo>(connection.ReceiveRequestWrap.Payload.Span);
connection.Write(syncTreansfer.Sync(info));
}

View File

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

View File

@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PublishAot>false</PublishAot>
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
<EnablePreviewFeatures>True</EnablePreviewFeatures>
<Title>linker messenger entry</Title>
<Authors>snltty</Authors>
<Company>snltty</Company>
<Description>linker messenger entry</Description>
<Copyright>snltty</Copyright>
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker messenger entry</PackageReleaseNotes>
<Version>1.6.4</Version>
<AssemblyVersion>1.6.4</AssemblyVersion>
<FileVersion>1.6.4</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
<Optimize>True</Optimize>
</PropertyGroup>
</Project>

View File

@@ -7,6 +7,7 @@ using linker.messenger.relay.server;
using linker.messenger.relay.server.caching;
using linker.messenger.relay.server.validator;
using linker.messenger.signin;
using linker.messenger.signin.args;
using linker.messenger.tunnel;
using linker.plugins.tunnel;
using linker.tunnel;
@@ -26,9 +27,11 @@ namespace linker.messenger.example
Certificate = new X509Certificate2("./snltty.pfx", "oeq9tw1o"),
TunnelTransports = new List<TunnelTransportItemInfo>
{
new TunnelTransportItemInfo{ BufferSize=3, Disabled=false, DisableReverse=false, DisableSSL=false, Name="udp", Order=0, ProtocolType= TunnelProtocolType.Udp.ToString(), Reverse=true, SSL=true },
new TunnelTransportItemInfo{ BufferSize=3, Disabled=false, DisableReverse=false, DisableSSL=false, Name="TcpP2PNAT", Order=1, ProtocolType= TunnelProtocolType.Tcp.ToString(), Reverse=true, SSL=true },
new TunnelTransportItemInfo{ BufferSize=3, Disabled=false, DisableReverse=false, DisableSSL=false, Name="TcpNutssb", Order=2, ProtocolType= TunnelProtocolType.Tcp.ToString(), Reverse=true, SSL=true },
new TunnelTransportItemInfo{ BufferSize=3, Disabled=false, DisableReverse=false, DisableSSL=false, Name="udp", Order=1, ProtocolType= TunnelProtocolType.Udp.ToString(), Reverse=true, SSL=true },
// new TunnelTransportItemInfo{ BufferSize=3, Disabled=false, DisableReverse=false, DisableSSL=false, Name="UdpPortMap", Order=2, ProtocolType= TunnelProtocolType.Udp.ToString(), Reverse=true, SSL=true },
new TunnelTransportItemInfo{ BufferSize=3, Disabled=false, DisableReverse=false, DisableSSL=false, Name="TcpP2PNAT", Order=3, ProtocolType= TunnelProtocolType.Tcp.ToString(), Reverse=true, SSL=true },
// new TunnelTransportItemInfo{ BufferSize=3, Disabled=false, DisableReverse=false, DisableSSL=false, Name="TransportUdpPortMap", Order=4, ProtocolType= TunnelProtocolType.Tcp.ToString(), Reverse=true, SSL=true },
// new TunnelTransportItemInfo{ BufferSize=3, Disabled=false, DisableReverse=false, DisableSSL=false, Name="TcpPortMap", Order=5, ProtocolType= TunnelProtocolType.Tcp.ToString(), Reverse=true, SSL=true },
}
};
@@ -75,9 +78,9 @@ namespace linker.messenger.example
IMessengerResolver messengerResolver = new MessengerResolver(messengerSender);
//打洞相关
TunnelExcludeIPTransfer tunnelExcludeIPTransfer = new TunnelExcludeIPTransfer();
TunnelClientExcludeIPTransfer tunnelExcludeIPTransfer = new TunnelClientExcludeIPTransfer();
//tunnelExcludeIPTransfer.LoadTunnelExcludeIPs(new List<ITunnelExcludeIP>());
TunnelMessengerAdapter tunnelMessengerAdapter = new TunnelMessengerAdapter(messengerSender, tunnelExcludeIPTransfer, serializer, new TunnelMessengerAdapterStore());
TunnelClientMessengerAdapter tunnelMessengerAdapter = new TunnelClientMessengerAdapter(messengerSender, tunnelExcludeIPTransfer, serializer, new TunnelMessengerAdapterStore());
TunnelTransfer tunnelTransfer = new TunnelTransfer(tunnelMessengerAdapter);
tunnelTransfer.SetConnectedCallback("default", (connection) =>
{
@@ -98,13 +101,21 @@ namespace linker.messenger.example
RelayClientMessenger relayClientMessenger = new RelayClientMessenger(relayClientTransfer, serializer);
//加载这些信标处理器
messengerResolver.LoadMessenger(new List<IMessenger>
messengerResolver.AddMessenger(new List<IMessenger>
{
tunnelClientMessenger,
relayClientMessenger
});
//加载登录参数
SignInArgsTransfer signInArgsTransfer = new SignInArgsTransfer();
signInArgsTransfer.AddArgs(new List<ISignInArgs> {
new MySignInArgs()
});
Dictionary<string, string> argsDic = new Dictionary<string, string>();
await signInArgsTransfer.Invoke(string.Empty, argsDic);
Console.WriteLine($"输入服务端ip端口:");
publicConfigInfo.Host = Console.ReadLine();
@@ -113,7 +124,7 @@ namespace linker.messenger.example
Socket socket = new Socket(server.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.KeepAlive();
await socket.ConnectAsync(server).WaitAsync(TimeSpan.FromMilliseconds(5000)).ConfigureAwait(false);
publicConfigInfo.SignConnection = await messengerResolver.BeginReceiveClient(socket, true, 1).ConfigureAwait(false);
publicConfigInfo.SignConnection = await messengerResolver.BeginReceiveClient(socket, true, (byte)ResolverType.Messenger).ConfigureAwait(false);
Console.WriteLine($"开始登录");
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
@@ -126,7 +137,7 @@ namespace linker.messenger.example
MachineName = Dns.GetHostName(),
MachineId = string.Empty,
Version = VersionHelper.version,
Args = new Dictionary<string, string>(),
Args = argsDic,
GroupId = "default"
})
}).ConfigureAwait(false);
@@ -180,12 +191,16 @@ namespace linker.messenger.example
{
case "1":
{
Console.WriteLine($"正在打洞.......");
tunnelConnection = await tunnelTransfer.ConnectAsync(id, "default", TunnelProtocolType.None);
Console.WriteLine($"打洞==》{(tunnelConnection == null ? "" : "")}");
}
break;
case "2":
{
Console.WriteLine($"正在中继.......");
tunnelConnection = await relayClientTransfer.ConnectAsync(publicConfigInfo.SignConnection.Id, id, "default");
Console.WriteLine($"中继==》{(tunnelConnection == null ? "" : "")}");
}
break;
default:
@@ -196,6 +211,7 @@ namespace linker.messenger.example
for (int i = 0; i < 10; i++)
{
string msg = $"hello {i}";
Console.WriteLine($"发送:{msg}");
var msgBytes = msg.ToBytes();
//首部4字节存长度剩下的才是真实数据
@@ -221,16 +237,19 @@ namespace linker.messenger.example
IMessengerSender messengerSender = new MessengerSender();
IMessengerResolver messengerResolver = new MessengerResolver(messengerSender);
messengerResolver.Initialize(publicConfigInfo.Certificate);
MessengerResolverResolver messengerResolverResolver = new MessengerResolverResolver(messengerResolver);
//登录相关
SignInArgsTransfer signInArgsTransfer = new SignInArgsTransfer();
//signInArgsTransfer.LoadArgs(new List<ISignInArgs>());
ISignInStore signInStore = new SignInStore();
SignCaching signCaching = new SignCaching(signInStore, signInArgsTransfer);
signInArgsTransfer.AddArgs(new List<ISignInArgs> {
new MySignInArgs()
});
ISignInServerStore signInStore = new SignInStore();
SignInServerCaching signCaching = new SignInServerCaching(signInStore, signInArgsTransfer);
SignInServerMessenger signInServerMessenger = new SignInServerMessenger(messengerSender, signCaching, serializer);
//打洞相关
TunnelExternalResolver tunnelExternalResolver = new TunnelExternalResolver();
TunnelServerExternalResolver tunnelExternalResolver = new TunnelServerExternalResolver();
TunnelServerMessenger tunnelServerMessenger = new TunnelServerMessenger(messengerSender, signCaching, serializer);
//中继相关
@@ -246,14 +265,24 @@ namespace linker.messenger.example
//relayServerValidatorTransfer.LoadValidators(new List<IRelayServerValidator> { });
RelayServerMessenger relayServerMessenger = new RelayServerMessenger(messengerSender, signCaching, serializer, relayServerMasterTransfer, relayServerValidatorTransfer);
//加载这些信标处理器
messengerResolver.LoadMessenger(new List<IMessenger>
//加载信标处理器
messengerResolver.AddMessenger(new List<IMessenger>
{
signInServerMessenger,
tunnelServerMessenger,
relayServerMessenger
});
//加载消息分发器
ResolverTransfer resolverTransfer = new ResolverTransfer();
resolverTransfer.AddResolvers(new List<IResolver> {
messengerResolverResolver,
tunnelExternalResolver,
relayServerReportResolver,
relayServerResolver
});
//TCP
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(new IPEndPoint(IPAddress.Any, publicConfigInfo.Port));
@@ -263,38 +292,7 @@ namespace linker.messenger.example
while (true)
{
var client = await socket.AcceptAsync();
TimerHelper.Async(async () =>
{
try
{
var bytes = new byte[1024];
int length = await client.ReceiveAsync(bytes.AsMemory(0, 1));
//外网端口
if (bytes[0] == 0)
{
await tunnelExternalResolver.Resolve(client, Helper.EmptyArray);
}
//信标
else if (bytes[0] == 1)
{
await messengerResolver.BeginReceiveServer(client, Helper.EmptyArray);
}
//中继
else if (bytes[0] == 2)
{
await relayServerResolver.Resolve(client, Helper.EmptyArray);
}
//中继节点报告
else if (bytes[0] == 3)
{
await relayServerReportResolver.Resolve(client, Helper.EmptyArray);
}
}
catch (Exception ex)
{
LoggerHelper.Instance.Error(ex);
}
});
_ = resolverTransfer.BeginReceive(client);
}
});
@@ -312,23 +310,7 @@ namespace linker.messenger.example
{
SocketReceiveFromResult result = await socketUdp.ReceiveFromAsync(buffer, SocketFlags.None, endPoint).ConfigureAwait(false);
IPEndPoint ep = result.RemoteEndPoint as IPEndPoint;
try
{
//外网端口
if (buffer[0] == 0)
{
await tunnelExternalResolver.Resolve(socketUdp, ep, buffer.AsMemory(1, result.ReceivedBytes - 1));
}
//中继节点报告
else if (buffer[0] == 3)
{
await relayServerReportResolver.Resolve(socketUdp, ep, buffer.AsMemory(1, result.ReceivedBytes - 1));
}
}
catch (Exception ex)
{
LoggerHelper.Instance.Error(ex);
}
_ = resolverTransfer.BeginReceive(socketUdp, ep, buffer.AsMemory(0, result.ReceivedBytes));
}
catch (Exception ex)
{
@@ -368,6 +350,54 @@ namespace linker.messenger.example
}
}
public sealed class MyRelayServerValidator : IRelayServerValidator
{
/// <summary>
/// 验证,服务端会调用
/// </summary>
/// <param name="relayInfo">中继参数</param>
/// <param name="fromMachine">来源客户端</param>
/// <param name="toMachine">目标客户端</param>
/// <returns></returns>
public async Task<string> Validate(RelayInfo relayInfo, SignCacheInfo fromMachine, SignCacheInfo toMachine)
{
//返回空字符串,表示成功,不空为错误信息则登录失败
return await Task.FromResult(string.Empty);
}
}
public sealed class MySignInArgs : ISignInArgs
{
/// <summary>
/// 客户端调用
/// </summary>
/// <param name="host"></param>
/// <param name="args"></param>
/// <returns></returns>
public async Task<string> Invoke(string host, Dictionary<string, string> args)
{
//在这里加入你喜欢的数据
//返回空字符串,表示成功,不空为错误信息
return await Task.FromResult(string.Empty);
}
/// <summary>
/// 服务端调用
/// </summary>
/// <param name="signInfo">本次登录的信息</param>
/// <param name="cache">如果以前登录过就有信息否则MachineId为空</param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<string> Validate(SignInfo signInfo, SignCacheInfo cache)
{
//在这里进行你的验证
//返回空字符串,表示成功,不空为错误信息则登录失败
return await Task.FromResult(string.Empty);
}
}
public sealed class PublicConfigInfo
{
public IConnection SignConnection { get; set; }
@@ -383,8 +413,6 @@ namespace linker.messenger.example
/// </summary>
public sealed class RelayClientStore : IRelayClientStore
{
public byte Flag => 2;
public X509Certificate2 Certificate => Program.publicConfigInfo.Certificate;
public IConnection SigninConnection => Program.publicConfigInfo.SignConnection;
@@ -403,8 +431,6 @@ namespace linker.messenger.example
/// </summary>
public sealed class RelayServerNodeStore : IRelayServerNodeStore
{
public byte Flag => 3;
public int ServicePort => Program.publicConfigInfo.Port;
public RelayServerNodeInfo Node => new RelayServerNodeInfo { };
@@ -432,7 +458,7 @@ namespace linker.messenger.example
/// <summary>
/// 自定义打洞的存储库
/// </summary>
public sealed class TunnelMessengerAdapterStore : ITunnelMessengerAdapterStore
public sealed class TunnelMessengerAdapterStore : ITunnelClientStore
{
public IConnection SignConnection => Program.publicConfigInfo.SignConnection;
public X509Certificate2 Certificate => Program.publicConfigInfo.Certificate;
@@ -473,7 +499,7 @@ namespace linker.messenger.example
/// <summary>
/// 自定义登录持久化存储
/// </summary>
public sealed class SignInStore : ISignInStore
public sealed class SignInStore : ISignInServerStore
{
public void Confirm()
{

View File

@@ -0,0 +1,18 @@
using Microsoft.Extensions.DependencyInjection;
namespace linker.messenger.exroute
{
public static class Entry
{
public static ServiceCollection AddExRoute(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<ExRouteTransfer>();
return serviceCollection;
}
public static ServiceProvider UseExRoute(this ServiceProvider serviceProvider)
{
ExRouteTransfer exRouteTransfer = serviceProvider.GetService<ExRouteTransfer>();
return serviceProvider;
}
}
}

View File

@@ -0,0 +1,29 @@
using System.Net;
namespace linker.messenger.exroute
{
public sealed partial class ExRouteTransfer
{
private List<IExRoute> excludes = new List<IExRoute>();
public ExRouteTransfer()
{
}
public void AddExRoutes(List<IExRoute> list)
{
excludes = excludes.Concat(list).Distinct().ToList();
}
public List<IPAddress> Get()
{
List<IPAddress> result = new List<IPAddress>();
foreach (var item in excludes)
{
result.AddRange(item.Get());
}
return result;
}
}
}

View File

@@ -1,8 +1,8 @@
using System.Net;
namespace linker.plugins.route
namespace linker.messenger.exroute
{
public interface IRouteExcludeIP
public interface IExRoute
{
public List<IPAddress> Get();
}

View File

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

View File

@@ -0,0 +1,32 @@
using linker.libs;
using Microsoft.Extensions.DependencyInjection;
using System.Security.Cryptography.X509Certificates;
namespace linker.messenger.listen
{
public static class Entry
{
public static ServiceCollection AddListen(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<TcpServer>();
return serviceCollection;
}
public static ServiceProvider UseListen(this ServiceProvider serviceProvider, X509Certificate2 certificate)
{
TcpServer tcpServer = serviceProvider.GetService<TcpServer>();
IListenStore listenStore = serviceProvider.GetService<IListenStore>();
LoggerHelper.Instance.Info($"start server");
try
{
tcpServer.Start(listenStore.Port);
}
catch (Exception ex)
{
LoggerHelper.Instance.Error(ex);
}
LoggerHelper.Instance.Warning($"server listen:{listenStore.Port}");
return serviceProvider;
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace linker.messenger.listen
{
public interface IListenStore
{
public int Port { get; }
}
}

View File

@@ -1,9 +1,8 @@
using linker.libs.extends;
using linker.plugins.resolver;
using System.Net;
using System.Net.Sockets;
namespace linker.plugins.server
namespace linker.messenger.listen
{
public sealed class TcpServer
{

View File

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

View File

@@ -0,0 +1,33 @@
using Microsoft.Extensions.DependencyInjection;
namespace linker.messenger.pcp
{
public static class Entry
{
public static ServiceCollection AddRelayClient(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<PcpTransfer>();
serviceCollection.AddSingleton<PcpClientMessenger>();
return serviceCollection;
}
public static ServiceProvider UseRelayClient(this ServiceProvider serviceProvider)
{
IMessengerResolver messengerResolver = serviceProvider.GetService<IMessengerResolver>();
messengerResolver.AddMessenger(new List<IMessenger> { serviceProvider.GetService<PcpClientMessenger>() });
return serviceProvider;
}
public static ServiceCollection AddRelayServer(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<PcpServerMessenger>();
return serviceCollection;
}
public static ServiceProvider UseRelayServer(this ServiceProvider serviceProvider)
{
IMessengerResolver messengerResolver = serviceProvider.GetService<IMessengerResolver>();
messengerResolver.AddMessenger(new List<IMessenger> { serviceProvider.GetService<PcpServerMessenger>() });
return serviceProvider;
}
}
}

View File

@@ -0,0 +1,17 @@
using linker.tunnel.connection;
namespace linker.messenger.pcp
{
public sealed class PcpHistoryInfo
{
public PcpHistoryInfo() { }
public List<string> History { get; set; } = new List<string>();
}
public interface IPcpStore
{
public PcpHistoryInfo PcpHistory { get; }
public void AddHistory(ITunnelConnection connection);
}
}

View File

@@ -0,0 +1,65 @@
using linker.libs;
using linker.messenger.decenter;
using linker.messenger.signin;
using System.Collections.Concurrent;
namespace linker.messenger.pcp
{
public sealed class PcpDecenter : IDecenter
{
public string Name => "pcp";
public VersionManager SyncVersion { get; } = new VersionManager();
public VersionManager DataVersion { get; } = new VersionManager();
private ConcurrentDictionary<string, List<string>> history = new ConcurrentDictionary<string, List<string>>();
private readonly SignInClientState signInClientState;
private readonly ISignInClientStore signInClientStore;
private readonly IPcpStore pcpStore;
private readonly ISerializer serializer;
public PcpDecenter( SignInClientState signInClientState, ISignInClientStore signInClientStore, IPcpStore pcpStore, ISerializer serializer)
{
this.signInClientState = signInClientState;
this.signInClientStore = signInClientStore;
this.pcpStore = pcpStore;
this.serializer = serializer;
signInClientState.NetworkEnabledHandle += (times) => SyncVersion.Add();
}
public List<string> GetNodes(string fromMachineId, string toMachineId)
{
if (history.TryGetValue(fromMachineId, out List<string> from) && history.TryGetValue(toMachineId, out List<string> to))
{
}
return new List<string>();
}
public Memory<byte> GetData()
{
HistoryDecenterInfo historyDecenterInfo = new HistoryDecenterInfo { MachineId = signInClientStore.Id, List = pcpStore.PcpHistory.History };
history.AddOrUpdate(historyDecenterInfo.MachineId, historyDecenterInfo.List, (a, b) => historyDecenterInfo.List);
return serializer.Serialize(historyDecenterInfo);
}
public void SetData(Memory<byte> data)
{
HistoryDecenterInfo historyDecenterInfo = serializer.Deserialize<HistoryDecenterInfo>(data.Span);
history.AddOrUpdate(historyDecenterInfo.MachineId, historyDecenterInfo.List, (a, b) => historyDecenterInfo.List);
}
public void SetData(List<ReadOnlyMemory<byte>> data)
{
List<HistoryDecenterInfo> list = data.Select(c => serializer.Deserialize<HistoryDecenterInfo>(c.Span)).ToList();
foreach (var historyDecenterInfo in list)
{
history.AddOrUpdate(historyDecenterInfo.MachineId, historyDecenterInfo.List, (a, b) => historyDecenterInfo.List);
}
}
}
public sealed partial class HistoryDecenterInfo
{
public string MachineId { get; set; }
public List<string> List { get; set; }
}
}

View File

@@ -1,11 +1,9 @@
using linker.tunnel;
using linker.tunnel.transport;
using linker.libs;
using MemoryPack;
using linker.messenger;
using linker.messenger.signin;
namespace linker.plugins.pcp.messenger
namespace linker.messenger.pcp
{
public sealed class PcpClientMessenger : IMessenger
{
@@ -40,17 +38,19 @@ namespace linker.plugins.pcp.messenger
public sealed class PcpServerMessenger : IMessenger
{
private readonly IMessengerSender messengerSender;
private readonly SignCaching signCaching;
public PcpServerMessenger(IMessengerSender messengerSender, SignCaching signCaching)
private readonly SignInServerCaching signCaching;
private readonly ISerializer serializer;
public PcpServerMessenger(IMessengerSender messengerSender, SignInServerCaching signCaching, ISerializer serializer)
{
this.messengerSender = messengerSender;
this.signCaching = signCaching;
this.serializer = serializer;
}
[MessengerId((ushort)PcpMessengerIds.BeginForward)]
public async Task BeginForward(IConnection connection)
{
TunnelTransportInfo tunnelTransportInfo = MemoryPackSerializer.Deserialize<TunnelTransportInfo>(connection.ReceiveRequestWrap.Payload.Span);
TunnelTransportInfo tunnelTransportInfo = serializer.Deserialize<TunnelTransportInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(tunnelTransportInfo.Remote.MachineId, out SignCacheInfo cacheTo) && signCaching.TryGet(connection.Id, out SignCacheInfo cacheFrom) && cacheFrom.GroupId == cacheTo.GroupId)
{
@@ -61,7 +61,7 @@ namespace linker.plugins.pcp.messenger
{
Connection = cacheTo.Connection,
MessengerId = (ushort)PcpMessengerIds.Begin,
Payload = MemoryPackSerializer.Serialize(tunnelTransportInfo)
Payload = serializer.Serialize(tunnelTransportInfo)
}).ConfigureAwait(false);
connection.Write(Helper.TrueArray);
}
@@ -71,7 +71,7 @@ namespace linker.plugins.pcp.messenger
[MessengerId((ushort)PcpMessengerIds.FailForward)]
public async Task FailForward(IConnection connection)
{
TunnelTransportInfo tunnelTransportInfo = MemoryPackSerializer.Deserialize<TunnelTransportInfo>(connection.ReceiveRequestWrap.Payload.Span);
TunnelTransportInfo tunnelTransportInfo = serializer.Deserialize<TunnelTransportInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(tunnelTransportInfo.Remote.MachineId, out SignCacheInfo cache) && signCaching.TryGet(connection.Id, out SignCacheInfo cache1) && cache.GroupId == cache1.GroupId)
{
tunnelTransportInfo.Local.MachineName = cache1.MachineName;
@@ -80,7 +80,7 @@ namespace linker.plugins.pcp.messenger
{
Connection = cache.Connection,
MessengerId = (ushort)PcpMessengerIds.Fail,
Payload = MemoryPackSerializer.Serialize(tunnelTransportInfo)
Payload = serializer.Serialize(tunnelTransportInfo)
}).ConfigureAwait(false);
}
}
@@ -89,7 +89,7 @@ namespace linker.plugins.pcp.messenger
[MessengerId((ushort)PcpMessengerIds.SuccessForward)]
public async Task SuccessForward(IConnection connection)
{
TunnelTransportInfo tunnelTransportInfo = MemoryPackSerializer.Deserialize<TunnelTransportInfo>(connection.ReceiveRequestWrap.Payload.Span);
TunnelTransportInfo tunnelTransportInfo = serializer.Deserialize<TunnelTransportInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(tunnelTransportInfo.Remote.MachineId, out SignCacheInfo cache) && signCaching.TryGet(connection.Id, out SignCacheInfo cache1) && cache.GroupId == cache1.GroupId)
{
tunnelTransportInfo.Local.MachineName = cache1.MachineName;
@@ -98,7 +98,7 @@ namespace linker.plugins.pcp.messenger
{
Connection = cache.Connection,
MessengerId = (ushort)PcpMessengerIds.Success,
Payload = MemoryPackSerializer.Serialize(tunnelTransportInfo)
Payload = serializer.Serialize(tunnelTransportInfo)
}).ConfigureAwait(false);
}
}

View File

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

View File

@@ -3,17 +3,17 @@ using linker.libs.extends;
using linker.tunnel;
using linker.tunnel.connection;
namespace linker.plugins.pcp
namespace linker.messenger.pcp
{
public sealed class PcpTransfer
{
private readonly string transactionId = "pcp";
private readonly PcpConfigTransfer pcpConfigTransfer;
private readonly IPcpStore pcpStore;
private readonly TunnelTransfer tunnelTransfer;
public PcpTransfer(PcpConfigTransfer pcpConfigTransfer, TunnelTransfer tunnelTransfer)
public PcpTransfer(IPcpStore pcpStore, TunnelTransfer tunnelTransfer)
{
this.pcpConfigTransfer = pcpConfigTransfer;
this.pcpStore = pcpStore;
this.tunnelTransfer = tunnelTransfer;
tunnelTransfer.SetConnectedCallback(transactionId, OnConnected);
@@ -77,7 +77,7 @@ namespace linker.plugins.pcp
public void AddConnection(ITunnelConnection connection)
{
pcpConfigTransfer.AddHistory(connection);
pcpStore.AddHistory(connection);
}
sealed class TunnelTagInfo

View File

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

View File

@@ -0,0 +1,83 @@
using linker.messenger.api;
using linker.messenger.relay.client;
using linker.messenger.relay.messenger;
using linker.messenger.relay.server;
using linker.messenger.relay.server.caching;
using linker.messenger.relay.server.validator;
using linker.messenger.sync;
using Microsoft.Extensions.DependencyInjection;
using System.Security.Cryptography.X509Certificates;
namespace linker.messenger.relay
{
public static class Entry
{
public static X509Certificate2 certificate;
public static ServiceCollection AddRelayClient(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<RelayClientTransfer>();
serviceCollection.AddSingleton<RelayClientMessenger>();
serviceCollection.AddSingleton<RelaySyncSecretKey>();
serviceCollection.AddSingleton<RelayApiController>();
serviceCollection.AddSingleton<RelayClientTestTransfer>();
return serviceCollection;
}
public static ServiceProvider UseRelayClient(this ServiceProvider serviceProvider, X509Certificate2 certificate)
{
Entry.certificate = certificate;
IMessengerResolver messengerResolver = serviceProvider.GetService<IMessengerResolver>();
messengerResolver.AddMessenger(new List<IMessenger> { serviceProvider.GetService<RelayClientMessenger>() });
SyncTreansfer syncTreansfer = serviceProvider.GetService<SyncTreansfer>();
syncTreansfer.AddSyncs(new List<ISync> { serviceProvider.GetService<RelaySyncSecretKey>() });
IApiServer apiServer = serviceProvider.GetService<IApiServer>();
apiServer.AddPlugins(new List<libs.api.IApiController> { serviceProvider.GetService<RelayApiController>() });
RelayClientTestTransfer relayClientTestTransfer = serviceProvider.GetService<RelayClientTestTransfer>();
return serviceProvider;
}
public static ServiceCollection AddRelayServer(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<RelayServerMessenger>();
serviceCollection.AddSingleton<RelayServerNodeTransfer>();
serviceCollection.AddSingleton<RelayServerMasterTransfer>();
serviceCollection.AddSingleton<RelayServerReportResolver>();
serviceCollection.AddSingleton<RelayServerResolver>();
serviceCollection.AddSingleton<IRelayServerCaching, RelayServerCachingMemory>();
serviceCollection.AddSingleton<RelayServerValidatorSecretKey>();
serviceCollection.AddSingleton<RelayServerValidatorTransfer>();
return serviceCollection;
}
public static ServiceProvider UseRelayServer(this ServiceProvider serviceProvider)
{
IMessengerResolver messengerResolver = serviceProvider.GetService<IMessengerResolver>();
messengerResolver.AddMessenger(new List<IMessenger> { serviceProvider.GetService<RelayServerMessenger>() });
ResolverTransfer resolverTransfer = serviceProvider.GetService<ResolverTransfer>();
resolverTransfer.AddResolvers(new List<IResolver>
{
serviceProvider.GetService<RelayServerReportResolver>(),
serviceProvider.GetService<RelayServerResolver>(),
});
RelayServerNodeTransfer relayServerNodeTransfer = serviceProvider.GetService<RelayServerNodeTransfer>();
RelayServerMasterTransfer relayServerMasterTransfer = serviceProvider.GetService<RelayServerMasterTransfer>();
RelayServerValidatorTransfer relayServerValidatorTransfer = serviceProvider.GetService<RelayServerValidatorTransfer>();
relayServerValidatorTransfer.AddValidators(new List<IRelayServerValidator> { serviceProvider.GetService<RelayServerValidatorSecretKey>() });
return serviceProvider;
}
}
}

View File

@@ -1,5 +1,4 @@
using linker.messenger.relay.client.transport;
using System.Security.Cryptography.X509Certificates;
namespace linker.messenger.relay.client
{
@@ -9,34 +8,18 @@ namespace linker.messenger.relay.client
public interface IRelayClientStore
{
/// <summary>
/// 标志当所有业务使用同一端口时flag区分0则不发送
/// 默认中继节点
/// </summary>
public byte Flag { get; }
/// <summary>
/// 加密证书
/// </summary>
public X509Certificate2 Certificate { get; }
/// <summary>
/// 登录连接
/// </summary>
public IConnection SigninConnection { get; }
public string DefaultNodeId { get; }
/// <summary>
/// 密钥
/// 服务器配置
/// </summary>
public string SecretKey { get; }
/// <summary>
/// 禁用
/// </summary>
public bool Disabled { get; }
/// <summary>
/// 开启ssl
/// </summary>
public bool SSL { get;}
/// <summary>
/// 中继类型
/// </summary>
public RelayClientType RelayType { get; }
public RelayServerInfo Server { get; }
public void SetDefaultNodeId(string defaultNodeId);
public void SetServer(RelayServerInfo server);
public void SetServerSecretKey(string secretKey);
}
}

View File

@@ -1,26 +1,25 @@
using linker.config;
using linker.libs.api;
using linker.libs.api;
using linker.libs.extends;
using linker.messenger.relay.client;
using linker.messenger.relay.client.transport;
using linker.messenger.relay.server;
using linker.plugins.capi;
namespace linker.plugins.relay.client
namespace linker.messenger.relay
{
/// <summary>
/// 中继管理接口
/// </summary>
public sealed class RelayApiController : IApiClientController
public sealed class RelayApiController : IApiController
{
private readonly RelayClientTestTransfer relayTestTransfer;
private readonly RelayClientTransfer relayTransfer;
private readonly RelayClientConfigTransfer relayClientConfigTransfer;
private readonly IRelayClientStore relayClientStore;
public RelayApiController(RelayClientTestTransfer relayTestTransfer, RelayClientTransfer relayTransfer, RelayClientConfigTransfer relayClientConfigTransfer)
public RelayApiController(RelayClientTestTransfer relayTestTransfer, RelayClientTransfer relayTransfer, IRelayClientStore relayClientStore)
{
this.relayTestTransfer = relayTestTransfer;
this.relayTransfer = relayTransfer;
this.relayClientConfigTransfer = relayClientConfigTransfer;
this.relayClientStore = relayClientStore;
}
/// <summary>
@@ -28,11 +27,10 @@ namespace linker.plugins.relay.client
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
[ClientApiAccess(ClientApiAccess.Config)]
public bool SetServers(ApiControllerParamsInfo param)
{
RelayServerInfo info = param.Content.DeJson<RelayServerInfo>();
relayClientConfigTransfer.SetServer(info);
relayClientStore.SetServer(info);
return true;
}
@@ -46,7 +44,7 @@ namespace linker.plugins.relay.client
{
RelayConnectInfo relayConnectInfo = param.Content.DeJson<RelayConnectInfo>();
_ = relayTransfer.ConnectAsync(relayConnectInfo.FromMachineId, relayConnectInfo.ToMachineId, relayConnectInfo.TransactionId, relayConnectInfo.NodeId);
relayClientConfigTransfer.SetDefaultNodeId(relayConnectInfo.NodeId);
relayClientStore.SetDefaultNodeId(relayConnectInfo.NodeId);
return true;
}

View File

@@ -2,11 +2,11 @@
using linker.messenger.relay.client;
using linker.messenger.relay.client.transport;
using linker.messenger.relay.server;
using linker.plugins.client;
using linker.messenger.signin;
using System.Net;
using System.Net.NetworkInformation;
namespace linker.plugins.relay.client
namespace linker.messenger.relay
{
/// <summary>
/// 中继
@@ -14,18 +14,18 @@ namespace linker.plugins.relay.client
public sealed class RelayClientTestTransfer
{
private readonly RelayClientTransfer relayTransfer;
private readonly ClientSignInState clientSignInState;
private readonly ClientConfigTransfer clientConfigTransfer;
private readonly RelayClientConfigTransfer relayClientConfigTransfer;
private readonly SignInClientState signInClientState;
private readonly ISignInClientStore signInClientStore;
private readonly IRelayClientStore relayClientStore;
public List<RelayServerNodeReportInfo> Nodes { get; private set; } = new List<RelayServerNodeReportInfo>();
public RelayClientTestTransfer(RelayClientTransfer relayTransfer, ClientSignInState clientSignInState, ClientConfigTransfer clientConfigTransfer, RelayClientConfigTransfer relayClientConfigTransfer)
public RelayClientTestTransfer(RelayClientTransfer relayTransfer, SignInClientState signInClientState, ISignInClientStore signInClientStore, IRelayClientStore relayClientStore)
{
this.relayTransfer = relayTransfer;
this.clientSignInState = clientSignInState;
this.clientConfigTransfer = clientConfigTransfer;
this.relayClientConfigTransfer = relayClientConfigTransfer;
this.signInClientState = signInClientState;
this.signInClientStore = signInClientStore;
this.relayClientStore = relayClientStore;
TestTask();
}
@@ -40,17 +40,17 @@ namespace linker.plugins.relay.client
{
try
{
IRelayClientTransport transport = relayTransfer.Transports.FirstOrDefault(d => d.Type == relayClientConfigTransfer.Server.RelayType);
IRelayClientTransport transport = relayTransfer.Transports.FirstOrDefault(d => d.Type == relayClientStore.Server.RelayType);
if (transport != null)
{
Nodes = await transport.RelayTestAsync(new RelayTestInfo
{
MachineId = clientConfigTransfer.Id,
SecretKey = relayClientConfigTransfer.Server.SecretKey
MachineId = signInClientStore.Id,
SecretKey = relayClientStore.Server.SecretKey
});
var tasks = Nodes.Select(async (c) =>
{
IPEndPoint ep = c.EndPoint == null || c.EndPoint.Address.Equals(IPAddress.Any) ? clientSignInState.Connection.Address : c.EndPoint;
IPEndPoint ep = c.EndPoint == null || c.EndPoint.Address.Equals(IPAddress.Any) ? signInClientState.Connection.Address : c.EndPoint;
using Ping ping = new Ping();
var resp = await ping.SendPingAsync(ep.Address, 1000);

View File

@@ -3,6 +3,7 @@ using linker.tunnel.connection;
using linker.libs;
using linker.libs.extends;
using System.Collections.Concurrent;
using linker.messenger.signin;
namespace linker.messenger.relay.client
{
@@ -17,11 +18,11 @@ namespace linker.messenger.relay.client
private Dictionary<string, List<Action<ITunnelConnection>>> OnConnected { get; } = new Dictionary<string, List<Action<ITunnelConnection>>>();
private readonly IRelayClientStore relayClientStore;
public RelayClientTransfer(IMessengerSender messengerSender,ISerializer serializer,IRelayClientStore relayClientStore)
public RelayClientTransfer(IMessengerSender messengerSender,ISerializer serializer,IRelayClientStore relayClientStore,SignInClientState signInClientState)
{
this.relayClientStore = relayClientStore;
Transports = new List<IRelayClientTransport> {
new RelayClientTransportSelfHost(messengerSender,serializer,relayClientStore),
new RelayClientTransportSelfHost(messengerSender,serializer,relayClientStore,signInClientState),
};
LoggerHelper.Instance.Info($"load relay transport:{string.Join(",", Transports.Select(c => c.GetType().Name))}");
}
@@ -67,11 +68,11 @@ namespace linker.messenger.relay.client
}
try
{
IRelayClientTransport transport = Transports.FirstOrDefault(c => c.Type == relayClientStore.RelayType && relayClientStore.Disabled == false);
IRelayClientTransport transport = Transports.FirstOrDefault(c => c.Type == relayClientStore.Server.RelayType && relayClientStore.Server.Disabled == false);
if (transport == null)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error($"relay to {remoteMachineId} fail,transport not found {relayClientStore.RelayType},{relayClientStore.Disabled}");
LoggerHelper.Instance.Error($"relay to {remoteMachineId} fail,transport not found {relayClientStore.Server.RelayType},{relayClientStore.Server.Disabled}");
return null;
}
@@ -82,10 +83,10 @@ namespace linker.messenger.relay.client
FromMachineName = string.Empty,
RemoteMachineId = remoteMachineId,
RemoteMachineName = string.Empty,
SecretKey = relayClientStore.SecretKey,
SecretKey = relayClientStore.Server.SecretKey,
TransactionId = transactionId,
TransportName = transport.Name,
SSL = relayClientStore.SSL,
SSL = relayClientStore.Server.SSL,
NodeId = nodeId
};

View File

@@ -0,0 +1,28 @@
using linker.libs;
using linker.messenger.sync;
namespace linker.messenger.relay.client
{
public sealed class RelaySyncSecretKey : ISync
{
public string Name => "RelaySecretKey";
private readonly IRelayClientStore relayClientStore;
private readonly ISerializer serializer;
public RelaySyncSecretKey(IRelayClientStore relayClientStore, ISerializer serializer)
{
this.relayClientStore = relayClientStore;
this.serializer = serializer;
}
public Memory<byte> GetData()
{
return serializer.Serialize(relayClientStore.Server.SecretKey);
}
public void SetData(Memory<byte> data)
{
string value = serializer.Deserialize<string>(data.Span);
relayClientStore.SetServerSecretKey(value);
}
}
}

View File

@@ -1,4 +1,5 @@
using linker.messenger.relay.server;
using linker.libs;
using linker.messenger.relay.server;
using linker.tunnel.connection;
using System.Net;
@@ -113,4 +114,23 @@ namespace linker.messenger.relay.client.transport
public bool SSL { get; set; } = true;
}
public sealed partial class RelayServerInfo
{
public RelayServerInfo() { }
/// <summary>
/// 密钥
/// </summary>
public string SecretKey { get; set; } = Helper.GlobalString;
/// <summary>
/// 禁用
/// </summary>
public bool Disabled { get; set; }
/// <summary>
/// 开启ssl
/// </summary>
public bool SSL { get; set; } = true;
public RelayClientType RelayType { get; set; } = RelayClientType.Linker;
}
}

View File

@@ -10,6 +10,7 @@ using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Buffers;
using linker.messenger.relay.server;
using linker.messenger.signin;
namespace linker.messenger.relay.client.transport
{
@@ -25,11 +26,13 @@ namespace linker.messenger.relay.client.transport
private readonly IMessengerSender messengerSender;
private readonly ISerializer serializer;
private readonly IRelayClientStore relayClientStore;
public RelayClientTransportSelfHost(IMessengerSender messengerSender, ISerializer serializer, IRelayClientStore relayClientStore)
private readonly SignInClientState signInClientState;
public RelayClientTransportSelfHost(IMessengerSender messengerSender, ISerializer serializer, IRelayClientStore relayClientStore, SignInClientState signInClientState)
{
this.messengerSender = messengerSender;
this.serializer = serializer;
this.relayClientStore = relayClientStore;
this.signInClientState = signInClientState;
}
public async Task<ITunnelConnection> RelayAsync(RelayInfo relayInfo)
@@ -117,7 +120,7 @@ namespace linker.messenger.relay.client.transport
{
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = relayClientStore.SigninConnection,
Connection = signInClientState.Connection,
MessengerId = (ushort)RelayMessengerIds.RelayAsk,
Payload = serializer.Serialize(relayInfo),
Timeout = 2000
@@ -145,7 +148,7 @@ namespace linker.messenger.relay.client.transport
IPEndPoint ep = node.EndPoint;
if (ep == null || ep.Address.Equals(IPAddress.Any))
{
ep = relayClientStore.SigninConnection.Address;
ep = signInClientState.Connection.Address;
}
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
@@ -165,8 +168,7 @@ namespace linker.messenger.relay.client.transport
ToId = relayInfo.RemoteMachineId,
NodeId = node.Id,
};
if (relayClientStore.Flag > 0)
await socket.SendAsync(new byte[] { relayClientStore.Flag });
await socket.SendAsync(new byte[] { (byte)ResolverType.Relay });
await socket.SendAsync(serializer.Serialize(relayMessage));
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"relay connected {ep}");
@@ -211,7 +213,7 @@ namespace linker.messenger.relay.client.transport
//通知对方去确认中继
var resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = relayClientStore.SigninConnection,
Connection = signInClientState.Connection,
MessengerId = (ushort)RelayMessengerIds.RelayForward,
Payload = serializer.Serialize(relayInfo),
});
@@ -227,7 +229,7 @@ namespace linker.messenger.relay.client.transport
{
try
{
IPEndPoint ep = relayInfo.Server == null || relayInfo.Server.Address.Equals(IPAddress.Any) ? relayClientStore.SigninConnection.Address : relayInfo.Server;
IPEndPoint ep = relayInfo.Server == null || relayInfo.Server.Address.Equals(IPAddress.Any) ? signInClientState.Connection.Address : relayInfo.Server;
Socket socket = new Socket(ep.AddressFamily, SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
socket.KeepAlive();
@@ -241,8 +243,7 @@ namespace linker.messenger.relay.client.transport
ToId = relayInfo.RemoteMachineId,
NodeId = relayInfo.NodeId,
};
if (relayClientStore.Flag > 0)
await socket.SendAsync(new byte[] { relayClientStore.Flag });
await socket.SendAsync(new byte[] { (byte)ResolverType.Relay });
await socket.SendAsync(serializer.Serialize(relayMessage));
_ = WaitSSL(socket, relayInfo).ContinueWith((result) =>
@@ -271,7 +272,7 @@ namespace linker.messenger.relay.client.transport
if (relayInfo.SSL)
{
sslStream = new SslStream(new NetworkStream(socket, false), false);
await sslStream.AuthenticateAsServerAsync(relayClientStore.Certificate, false, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false).ConfigureAwait(false);
await sslStream.AuthenticateAsServerAsync(Entry.certificate, false, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false).ConfigureAwait(false);
}
return new TunnelConnectionTcp
{
@@ -308,7 +309,7 @@ namespace linker.messenger.relay.client.transport
{
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = relayClientStore.SigninConnection,
Connection = signInClientState.Connection,
MessengerId = (ushort)RelayMessengerIds.RelayTest,
Payload = serializer.Serialize(relayTestInfo),
Timeout = 2000

View File

@@ -37,8 +37,9 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\linker.libs\linker.libs.csproj" />
<ProjectReference Include="..\linker.messenger.signin\linker.messenger.signin.csproj" />
<ProjectReference Include="..\linker.messenger.sync\linker.messenger.sync.csproj" />
<ProjectReference Include="..\linker.messenger\linker.messenger.csproj" />
<ProjectReference Include="..\linker.signin\linker.messenger.signin.csproj" />
<ProjectReference Include="..\linker.tunnel\linker.tunnel.csproj" />
</ItemGroup>

View File

@@ -41,12 +41,12 @@ namespace linker.messenger.relay.messenger
public class RelayServerMessenger : IMessenger
{
private readonly IMessengerSender messengerSender;
private readonly SignCaching signCaching;
private readonly SignInServerCaching signCaching;
private readonly RelayServerMasterTransfer relayServerTransfer;
private readonly RelayServerValidatorTransfer relayValidatorTransfer;
private readonly ISerializer serializer;
public RelayServerMessenger(IMessengerSender messengerSender, SignCaching signCaching, ISerializer serializer, RelayServerMasterTransfer relayServerTransfer, RelayServerValidatorTransfer relayValidatorTransfer)
public RelayServerMessenger(IMessengerSender messengerSender, SignInServerCaching signCaching, ISerializer serializer, RelayServerMasterTransfer relayServerTransfer, RelayServerValidatorTransfer relayValidatorTransfer)
{
this.messengerSender = messengerSender;
this.signCaching = signCaching;

View File

@@ -9,10 +9,6 @@ namespace linker.messenger.relay.server
/// </summary>
public interface IRelayServerNodeStore
{
/// <summary>
/// 标志0不发送大于0发送当一个端口用于多个服务时使用用于区分不同业务
/// </summary>
public byte Flag { get; }
/// <summary>
/// 服务端端口
/// </summary>

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace linker.messenger.relay.server
{
public interface IRelayServerStore
{
public string SecretKey { get; }
}
}

View File

@@ -51,8 +51,7 @@ namespace linker.messenger.relay.server
await socket.ConnectAsync(server).ConfigureAwait(false);
long time = Environment.TickCount64 - start;
if (relayServerNodeStore.Flag > 0)
await socket.SendAsync(new byte[] { relayServerNodeStore.Flag });
await socket.SendAsync(new byte[] { (byte)ResolverType.RelayReport });
await socket.SendAsync(key.ToBytes());
int length = await socket.ReceiveAsync(buffer.AsMemory(), SocketFlags.None).AsTask().WaitAsync(TimeSpan.FromMilliseconds(Math.Max(time * 2, 5000))).ConfigureAwait(false);
socket.SafeClose();
@@ -234,7 +233,7 @@ namespace linker.messenger.relay.server
byte[] content = crypto.Encode(serializer.Serialize(relayNodeReportInfo));
byte[] data = new byte[content.Length + 1];
data[0] = relayServerNodeStore.Flag;
data[0] = (byte)ResolverType.RelayReport;
content.AsMemory().CopyTo(data.AsMemory(1));
using UdpClient udpClient = new UdpClient(AddressFamily.InterNetwork);

View File

@@ -8,8 +8,10 @@ namespace linker.messenger.relay.server
/// <summary>
/// 中继节点报告处理器
/// </summary>
public class RelayServerReportResolver
public class RelayServerReportResolver: IResolver
{
public ResolverType Type => ResolverType.RelayReport;
private readonly RelayServerMasterTransfer relayServerTransfer;
public RelayServerReportResolver(RelayServerMasterTransfer relayServerTransfer)
{

View File

@@ -10,8 +10,10 @@ namespace linker.messenger.relay.server
/// <summary>
/// 中继连接处理
/// </summary>
public class RelayServerResolver
public class RelayServerResolver: IResolver
{
public ResolverType Type => ResolverType.Relay;
private readonly RelayServerNodeTransfer relayServerNodeTransfer;
private readonly ISerializer serializer;
public RelayServerResolver(RelayServerNodeTransfer relayServerNodeTransfer, ISerializer serializer)
@@ -22,6 +24,7 @@ namespace linker.messenger.relay.server
private readonly ConcurrentDictionary<ulong, RelayWrapInfo> relayDic = new ConcurrentDictionary<ulong, RelayWrapInfo>();
public virtual void AddReceive(string key, string from, string to, string groupid, ulong bytes)
{

View File

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

View File

@@ -1,6 +1,7 @@
using linker.messenger.signin;
using linker.messenger.relay.client.transport;
using linker.libs;
using System.Diagnostics.CodeAnalysis;
namespace linker.messenger.relay.server.validator
{
@@ -19,10 +20,11 @@ namespace linker.messenger.relay.server.validator
/// 加载中继验证实现类
/// </summary>
/// <param name="list"></param>
public void LoadValidators(List<IRelayServerValidator> list)
public void AddValidators(List<IRelayServerValidator> list)
{
validators = list;
LoggerHelper.Instance.Info($"load relay server validator :{string.Join(",", validators.Select(c => c.GetType().Name))}");
if (list == null) return;
validators = validators.Concat(list).Distinct(new RelayServerValidatorEqualityComparer()).ToList();
LoggerHelper.Instance.Info($"load relay server validator :{string.Join(",", list.Select(c => c.GetType().Name))}");
}
/// <summary>
@@ -44,5 +46,18 @@ namespace linker.messenger.relay.server.validator
}
return string.Empty;
}
public sealed class RelayServerValidatorEqualityComparer : IEqualityComparer<IRelayServerValidator>
{
public bool Equals(IRelayServerValidator x, IRelayServerValidator y)
{
return x.GetType().FullName == y.GetType().FullName;
}
public int GetHashCode([DisallowNull] IRelayServerValidator obj)
{
return obj.GetHashCode();
}
}
}
}

View File

@@ -0,0 +1,111 @@
using MemoryPack;
using linker.messenger.access;
namespace linker.messenger.serializer.memorypack
{
[MemoryPackable]
public readonly partial struct SerializableAccessUpdateInfo
{
[MemoryPackIgnore]
public readonly AccessUpdateInfo info;
[MemoryPackInclude]
string FromMachineId => info.FromMachineId;
[MemoryPackInclude]
string ToMachineId => info.ToMachineId;
[MemoryPackInclude]
ulong Access => info.Access;
[MemoryPackConstructor]
SerializableAccessUpdateInfo(string fromMachineId, string toMachineId, ulong access)
{
var info = new AccessUpdateInfo { FromMachineId = fromMachineId, ToMachineId = toMachineId, Access = access };
this.info = info;
}
public SerializableAccessUpdateInfo(AccessUpdateInfo info)
{
this.info = info;
}
}
public class AccessUpdateInfoFormatter : MemoryPackFormatter<AccessUpdateInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref AccessUpdateInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableAccessUpdateInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref AccessUpdateInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableAccessUpdateInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableAccessInfo
{
[MemoryPackIgnore]
public readonly AccessInfo info;
[MemoryPackInclude]
string MachineId => info.MachineId;
[MemoryPackInclude]
AccessValue Access => info.Access;
[MemoryPackConstructor]
SerializableAccessInfo(string machineId, AccessValue access)
{
var info = new AccessInfo { MachineId= machineId, Access = access };
this.info = info;
}
public SerializableAccessInfo(AccessInfo info)
{
this.info = info;
}
}
public class AccessInfoFormatter : MemoryPackFormatter<AccessInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref AccessInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableAccessInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref AccessInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableAccessInfo>();
value = wrapped.info;
}
}
}

View File

@@ -1,7 +1,7 @@
using linker.messenger;
using MemoryPack;
namespace linker.serializer
namespace linker.messenger.serializer.memorypack
{
/// <summary>
/// MemoryPack 的IConnection序列化扩展

View File

@@ -0,0 +1,57 @@
using MemoryPack;
using linker.messenger.decenter;
namespace linker.messenger.serializer.memorypack
{
[MemoryPackable]
public readonly partial struct SerializableDecenterSyncInfo
{
[MemoryPackIgnore]
public readonly DecenterSyncInfo info;
[MemoryPackInclude]
string Name => info.Name;
[MemoryPackInclude]
Memory<byte> Data => info.Data;
[MemoryPackConstructor]
SerializableDecenterSyncInfo(string name, Memory<byte> data)
{
var info = new DecenterSyncInfo { Name = name, Data = data };
this.info = info;
}
public SerializableDecenterSyncInfo(DecenterSyncInfo tunnelCompactInfo)
{
this.info = tunnelCompactInfo;
}
}
public class DecenterSyncInfoFormatter : MemoryPackFormatter<DecenterSyncInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref DecenterSyncInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableDecenterSyncInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref DecenterSyncInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableDecenterSyncInfo>();
value = wrapped.info;
}
}
}

View File

@@ -0,0 +1,69 @@
using linker.libs;
using MemoryPack;
using Microsoft.Extensions.DependencyInjection;
namespace linker.messenger.serializer.memorypack
{
public static class Entry
{
public static ServiceCollection AddSerializerMemoryPack(this ServiceCollection serviceCollection)
{
MemoryPackFormatterProvider.Register(new IPEndPointFormatter());
MemoryPackFormatterProvider.Register(new IPAddressFormatter());
MemoryPackFormatterProvider.Register(new TunnelConnectionFormatter());
MemoryPackFormatterProvider.Register(new ConnectionFormatter());
serviceCollection.AddSingleton<ISerializer, PlusMemoryPackSerializer>();
MemoryPackFormatterProvider.Register(new SignInfoFormatter());
MemoryPackFormatterProvider.Register(new SignCacheInfoFormatter());
MemoryPackFormatterProvider.Register(new SignInListRequestInfoFormatter());
MemoryPackFormatterProvider.Register(new SignInListResponseInfoFormatter());
MemoryPackFormatterProvider.Register(new SignInIdsRequestInfoFormatter());
MemoryPackFormatterProvider.Register(new SignInIdsResponseInfoFormatter());
MemoryPackFormatterProvider.Register(new SignInIdsResponseItemInfoFormatter());
MemoryPackFormatterProvider.Register(new SignInResponseInfoFormatter());
MemoryPackFormatterProvider.Register(new SignInConfigSetNameInfoFormatter());
MemoryPackFormatterProvider.Register(new SyncInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelTransportWanPortInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelTransportItemInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelTransportInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelWanPortProtocolInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelRouteLevelInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelSetRouteLevelInfoFormatter());
MemoryPackFormatterProvider.Register(new DecenterSyncInfoFormatter());
MemoryPackFormatterProvider.Register(new UpdaterConfirmInfoFormatter());
MemoryPackFormatterProvider.Register(new UpdaterConfirmServerInfoFormatter());
MemoryPackFormatterProvider.Register(new UpdaterClientInfoFormatter());
MemoryPackFormatterProvider.Register(new UpdaterInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayTestInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerNodeReportInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayAskResultInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayCacheInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayMessageInfoFormatter());
MemoryPackFormatterProvider.Register(new AccessUpdateInfoFormatter());
MemoryPackFormatterProvider.Register(new AccessInfoFormatter());
MemoryPackFormatterProvider.Register(new Socks5LanInfoFormatter());
MemoryPackFormatterProvider.Register(new Socks5InfoFormatter());
return serviceCollection;
}
public static ServiceProvider UseSerializerMemoryPack(this ServiceProvider serviceProvider)
{
return serviceProvider;
}
}
}

View File

@@ -1,7 +1,7 @@
using MemoryPack;
using System.Net;
namespace linker.serializer
namespace linker.messenger.serializer.memorypack
{
/// <summary>
/// MemoryPack 的 IPAddress序列化扩展

View File

@@ -2,7 +2,7 @@
using MemoryPack;
using System.Net;
namespace linker.serializer
namespace linker.messenger.serializer.memorypack
{
/// <summary>
/// MemoryPack 的 IPEndPoint序列化扩展

View File

@@ -2,18 +2,31 @@
using MemoryPack;
using System.Diagnostics.CodeAnalysis;
namespace linker.serializer
namespace linker.messenger.serializer.memorypack
{
public sealed class PlusMemoryPackSerializer : ISerializer
{
public T Deserialize<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(ReadOnlySpan<byte> buffer)
{
return MemoryPackSerializer.Deserialize<T>(buffer);
return Serializer.Deserialize<T>(buffer);
}
public byte[] Serialize<T>(T value)
{
return MemoryPackSerializer.Serialize(value);
}
}
public sealed class Serializer
{
public static T Deserialize<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(ReadOnlySpan<byte> buffer)
{
return MemoryPackSerializer.Deserialize<T>(buffer);
}
public static byte[] Serialize<T>(T value)
{
return MemoryPackSerializer.Serialize(value);
}
}
}

View File

@@ -3,7 +3,7 @@ using linker.messenger.relay.server;
using MemoryPack;
using System.Net;
namespace linker.plugins.relay
namespace linker.messenger.serializer.memorypack
{
[MemoryPackable]
public readonly partial struct SerializableRelayTestInfo

View File

@@ -2,7 +2,7 @@
using MemoryPack;
using System.Net;
namespace linker.plugins.signIn
namespace linker.messenger.serializer.memorypack
{
[MemoryPackable]
public readonly partial struct SerializableSignInfo
@@ -72,8 +72,6 @@ namespace linker.plugins.signIn
[MemoryPackIgnore]
public readonly SignCacheInfo info;
[MemoryPackInclude]
string Id => info.Id;
[MemoryPackInclude]
string MachineId => info.MachineId;
[MemoryPackInclude]
@@ -85,10 +83,10 @@ namespace linker.plugins.signIn
string GroupId => info.GroupId;
[MemoryPackInclude]
Dictionary<string, string> Args => info.Args;
DateTime LastSignIn => info.LastSignIn;
[MemoryPackInclude]
DateTime LastSignIn => info.LastSignIn;
Dictionary<string, string> Args => info.Args;
[MemoryPackInclude, MemoryPackAllowSerialize]
IPEndPoint IP => info.IP;
@@ -96,16 +94,13 @@ namespace linker.plugins.signIn
[MemoryPackInclude, MemoryPackAllowSerialize]
bool Connected => info.Connected;
[MemoryPackInclude, MemoryPackAllowSerialize]
uint Order => info.Order;
[MemoryPackConstructor]
SerializableSignCacheInfo(string id, string machineId, string machineName, string version, string groupId, Dictionary<string, string> args, DateTime lastSignIn, IPEndPoint ip, bool connected, uint order)
SerializableSignCacheInfo(string machineId, string machineName, string version, string groupId, DateTime lastSignIn, Dictionary<string, string> args, IPEndPoint ip, bool connected)
{
var info = new SignCacheInfo
{
Id = id,
Id = string.Empty,
MachineId = machineId,
MachineName = machineName,
GroupId = groupId,
@@ -114,7 +109,7 @@ namespace linker.plugins.signIn
LastSignIn = lastSignIn,
IP = ip,
Connected = connected,
Order = order
Order = 0
};
this.info = info;
}
@@ -277,7 +272,6 @@ namespace linker.plugins.signIn
[MemoryPackable]
public readonly partial struct SerializableSignInIdsRequestInfo
{
@@ -394,7 +388,6 @@ namespace linker.plugins.signIn
[MemoryPackable]
public readonly partial struct SerializableSignInIdsResponseItemInfo
{
@@ -409,9 +402,9 @@ namespace linker.plugins.signIn
[MemoryPackConstructor]
SerializableSignInIdsResponseItemInfo(string machineId, string machineName )
SerializableSignInIdsResponseItemInfo(string machineId, string machineName)
{
var info = new SignInIdsResponseItemInfo { MachineId = machineId, MachineName = machineName};
var info = new SignInIdsResponseItemInfo { MachineId = machineId, MachineName = machineName };
this.info = info;
}
@@ -466,9 +459,9 @@ namespace linker.plugins.signIn
[MemoryPackConstructor]
SerializableSignInResponseInfo(bool status,string machineId, string msg)
SerializableSignInResponseInfo(bool status, string machineId, string msg)
{
var info = new SignInResponseInfo { Status= status, MachineId = machineId, Msg = msg };
var info = new SignInResponseInfo { Status = status, MachineId = machineId, Msg = msg };
this.info = info;
}
@@ -503,4 +496,58 @@ namespace linker.plugins.signIn
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableSignInConfigSetNameInfo
{
[MemoryPackIgnore]
public readonly SignInConfigSetNameInfo info;
[MemoryPackInclude]
string Id => info.Id;
[MemoryPackInclude]
string NewName => info.NewName;
[MemoryPackConstructor]
SerializableSignInConfigSetNameInfo(string id, string newName)
{
var info = new SignInConfigSetNameInfo { Id = id, NewName = newName };
this.info = info;
}
public SerializableSignInConfigSetNameInfo(SignInConfigSetNameInfo signInfo)
{
this.info = signInfo;
}
}
public class SignInConfigSetNameInfoFormatter : MemoryPackFormatter<SignInConfigSetNameInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref SignInConfigSetNameInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableSignInConfigSetNameInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref SignInConfigSetNameInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableSignInConfigSetNameInfo>();
value = wrapped.info;
}
}
}

View File

@@ -0,0 +1,129 @@
using MemoryPack;
using linker.messenger.access;
using linker.messenger.socks5;
using System.Net;
namespace linker.messenger.serializer.memorypack
{
[MemoryPackable]
public readonly partial struct SerializableSocks5LanInfo
{
[MemoryPackIgnore]
public readonly Socks5LanInfo info;
[MemoryPackInclude, MemoryPackAllowSerialize]
IPAddress IP => info.IP;
[MemoryPackInclude]
byte PrefixLength => info.PrefixLength;
[MemoryPackInclude]
bool Disabled => info.Disabled;
[MemoryPackInclude]
bool Exists => info.Exists;
[MemoryPackInclude]
string Error => info.Error;
[MemoryPackConstructor]
SerializableSocks5LanInfo(IPAddress ip, byte prefixLength, bool disabled, bool exists, string error)
{
var info = new Socks5LanInfo { Disabled = disabled, Error = error, Exists = exists, IP = ip, PrefixLength = prefixLength };
this.info = info;
}
public SerializableSocks5LanInfo(Socks5LanInfo info)
{
this.info = info;
}
}
public class Socks5LanInfoFormatter : MemoryPackFormatter<Socks5LanInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref Socks5LanInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableSocks5LanInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref Socks5LanInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableSocks5LanInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableSocks5Info
{
[MemoryPackIgnore]
public readonly Socks5Info info;
[MemoryPackInclude]
string MachineId => info.MachineId;
[MemoryPackInclude]
Socks5Status Status => info.Status;
[MemoryPackInclude]
int Port => info.Port;
[MemoryPackInclude]
List<Socks5LanInfo> Lans => info.Lans;
[MemoryPackInclude]
string SetupError => info.SetupError;
[MemoryPackConstructor]
SerializableSocks5Info(string machineId, Socks5Status status, int port, List<Socks5LanInfo> lans, string setupError)
{
var info = new Socks5Info { MachineId = machineId, Lans = lans, Port = port, SetupError = setupError, Status = status };
this.info = info;
}
public SerializableSocks5Info(Socks5Info info)
{
this.info = info;
}
}
public class Socks5InfoFormatter : MemoryPackFormatter<Socks5Info>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref Socks5Info value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableSocks5Info(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref Socks5Info value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableSocks5Info>();
value = wrapped.info;
}
}
}

View File

@@ -0,0 +1,59 @@
using linker.messenger.sync;
using MemoryPack;
namespace linker.messenger.serializer.memorypack
{
[MemoryPackable]
public readonly partial struct SerializableSyncInfo
{
[MemoryPackIgnore]
public readonly SyncInfo info;
[MemoryPackInclude]
string Name => info.Name;
[MemoryPackInclude]
Memory<byte> Data => info.Data;
[MemoryPackConstructor]
SerializableSyncInfo(string name, Memory<byte> data)
{
var info = new SyncInfo { Name = name, Data = data };
this.info = info;
}
public SerializableSyncInfo(SyncInfo signInfo)
{
this.info = signInfo;
}
}
public class SyncInfoFormatter : MemoryPackFormatter<SyncInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref SyncInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableSyncInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref SyncInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableSyncInfo>();
value = wrapped.info;
}
}
}

View File

@@ -1,7 +1,7 @@
using linker.tunnel.connection;
using MemoryPack;
namespace linker.serializer
namespace linker.messenger.serializer.memorypack
{
/// <summary>
/// MemoryPack 的ITunnelConnection序列化扩展

Some files were not shown because too many files have changed in this diff Show More