sync
56
README.md
@@ -60,62 +60,6 @@
|
||||
<p><img src="./readme/full.png"></p>
|
||||
</div>
|
||||
|
||||
## 收费项目
|
||||
|
||||
<div align="center">
|
||||
|
||||
<table width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>2设备内</th>
|
||||
<th>2-5设备</th>
|
||||
<th>5-10设备</th>
|
||||
<th>10设备以上</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>使用</td>
|
||||
<td>免费</td>
|
||||
<td>免费</td>
|
||||
<td>免费</td>
|
||||
<td>免费</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>开源集成</td>
|
||||
<td>免费</td>
|
||||
<td>免费</td>
|
||||
<td>免费</td>
|
||||
<td>免费</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>安装维护/次</td>
|
||||
<td>免费</td>
|
||||
<td>9.9/台</td>
|
||||
<td>9.9/台</td>
|
||||
<td>9.9/台</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>安装维护/年</td>
|
||||
<td>19.9/年</td>
|
||||
<td>39.9/年</td>
|
||||
<td>79.9/年</td>
|
||||
<td>9.9/年/台</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>商业集成</td>
|
||||
<td colspan="4" align="center">详谈</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>商业功能定制</td>
|
||||
<td colspan="4" align="center">详谈</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
## 可怜作者
|
||||
|
||||
<div align="center">
|
||||
|
7
linker.doc.web/docs/10、公益赞助.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
sidebar_position: 10
|
||||
---
|
||||
|
||||
# 10、公益赞助
|
||||
|
||||

|
@@ -4,12 +4,10 @@ sidebar_position: 6
|
||||
|
||||
# 6、自定义验证
|
||||
|
||||
## 1、不修改源码的Action方式
|
||||
|
||||
:::tip[说明]
|
||||
1. 服务端`action.json`中的,`RelayActionUrl中继`、`SForwardActionUrl穿透`、`SignInActionUrl信标`,都可以设置支持HTTP POST的URL,当不为空时,这些操作都会发送HTTP POST请求到`ActionUrl`,并携带json参数,可用于自定义验证。
|
||||
2. 在`Action验证`中,设置静态参数,或者使用管理接口动态配置参数
|
||||
3. 优先采用动态参数,动态参数为空则使用信标服务器配置的参数。
|
||||
3. 优先采用动态参数,动态参数为空则使用页面配置的静态参数。
|
||||
4. `HTTP POST`返回`ok`表示验证成功,其余均为错误信息。
|
||||
|
||||
|
||||
@@ -118,115 +116,3 @@ public sealed class JsonArgSForwardInfo
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
|
||||
|
||||
|
||||
## 2、修改源码方式
|
||||
|
||||
:::tip[说明]
|
||||
|
||||
你可以在任意对方编写这些代码,可以参考 `plugins->action`,action插件就是使用以下方式实现。
|
||||
|
||||
### 2.1、连接服务器验证
|
||||
```
|
||||
public sealed class MySignArgs:ISignInArgs
|
||||
{
|
||||
//客户端连接服务器时调用,你可以往args里添加你自定义的参数
|
||||
public async Task<string> Invoke(Dictionary<string, string> args)
|
||||
{
|
||||
args.TryAdd("myArg", "");
|
||||
//返回空字符串表示成功操作,非空将断开连接
|
||||
return string.Empty;
|
||||
}
|
||||
public async Task<string> Verify(SignInfo signInfo, SignCacheInfo cache)
|
||||
{
|
||||
//本地连接的参数
|
||||
signInfo.Args.TryGetValue("myArg", out string argNew);
|
||||
//之前连接的参数
|
||||
cache.Args.TryGetValue("myArg", out string argOld);
|
||||
|
||||
//返回空字符串表示验证通过,非空将断开连接
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
```
|
||||
### 2.2、中继验证
|
||||
```
|
||||
public sealed class MyRelayValidator : IRelayValidator
|
||||
{
|
||||
public MyRelayValidator()
|
||||
{
|
||||
}
|
||||
|
||||
// <summary>
|
||||
/// 验证
|
||||
/// </summary>
|
||||
/// <param name="fromMachine">来源客户端</param>
|
||||
/// <param name="toMachine">目标客户端,可能为null</param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> Validate(SignCacheInfo fromMachine, SignCacheInfo toMachine)
|
||||
{
|
||||
//返回空字符串表示验证通过,非空将断开连接
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3、内网穿透验证
|
||||
```
|
||||
public sealed class MySForwardValidator : ISForwardValidator
|
||||
{
|
||||
public MySForwardValidator()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// 验证
|
||||
/// </summary>
|
||||
/// <param name="signCacheInfo">来源客户端</param>
|
||||
/// <param name="sForwardAddInfo">穿透信息</param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> Validate(SignCacheInfo cache, SForwardAddInfo sForwardAddInfo)
|
||||
{
|
||||
//返回空字符串表示验证通过,非空将不允许添加穿透
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.4、实现一个启动器,将你的这些实现注入
|
||||
```
|
||||
public sealed class MyValidatorStartup : IStartup
|
||||
{
|
||||
public StartupLevel Level => StartupLevel.Normal;
|
||||
public string Name => "myValdator";
|
||||
|
||||
public bool Required => false;
|
||||
public string[] Dependent => new string[] {};
|
||||
public StartupLoadType LoadType => StartupLoadType.Normal;
|
||||
|
||||
//客户端
|
||||
public void AddClient(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies)
|
||||
{
|
||||
serviceCollection.AddSingleton<MySignArgs>();
|
||||
serviceCollection.AddSingleton<MyRelayValidator>();
|
||||
serviceCollection.AddSingleton<MySForwardValidator>();
|
||||
}
|
||||
|
||||
//服务端
|
||||
public void AddServer(ServiceCollection serviceCollection, FileConfig config, Assembly[] assemblies)
|
||||
{
|
||||
serviceCollection.AddSingleton<MySignArgs>();
|
||||
serviceCollection.AddSingleton<MyRelayValidator>();
|
||||
serviceCollection.AddSingleton<MySForwardValidator>();
|
||||
}
|
||||
|
||||
public void UseClient(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies)
|
||||
{
|
||||
}
|
||||
public void UseServer(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies)
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
@@ -2,7 +2,10 @@
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# 8.1、集成linker
|
||||
# 8.1、开始运行
|
||||
|
||||
## 1、入口
|
||||
|
||||
:::tip[说明]
|
||||
1. 在你的.NET8.0+项目中,集成linker
|
||||
2. 在nuget安装`linker.messenger.entry`
|
||||
@@ -26,13 +29,13 @@ LinkerMessengerEntry.Build();
|
||||
//apiStore.SetWebPort(0);
|
||||
//apiStore.Confirm();
|
||||
|
||||
//启动
|
||||
LinkerMessengerEntry.Setup();
|
||||
//启动,在这里可以排除一些模块,ExcludeModule.Node 不排除,比如我不需要检测更新和管理接口和网页
|
||||
LinkerMessengerEntry.Setup(ExcludeModule.Updater | ExcludeModule.Api );
|
||||
```
|
||||
:::
|
||||
|
||||
|
||||
# 1、一些配置接口
|
||||
## 2、一些配置接口
|
||||
:::tip[说明]
|
||||
1. 你可以在initialize之后注入覆盖这些实现,和build之后获取这些接口来操作配置
|
||||
3. 管理接口详情请看各个组件里的`IApiController`实现,包含了全部的管理接口
|
@@ -1,8 +1,8 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
sidebar_position: 22
|
||||
---
|
||||
|
||||
# 8.2、单独使用虚拟网卡
|
||||
# 8.22、单独使用虚拟网卡
|
||||
|
||||
## 1、说明
|
||||
|
20
linker.doc.web/docs/8、集成和二次开发/8.2、配置信息存储库.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# 8.2、配置信息存储库
|
||||
|
||||
:::tip[说明]
|
||||
1. 在解决方案中,找到以`linker.messenger`开头的项目里以`Store`结尾的`interface`,实现它们
|
||||
2. 然后注入覆盖原本的文件存储库实现
|
||||
```
|
||||
//初始化
|
||||
LinkerMessengerEntry.Initialize();
|
||||
//在这里可以注入覆盖实现
|
||||
LinkerMessengerEntry.AddService<ICommonStore, MyCommonStore>();
|
||||
|
||||
LinkerMessengerEntry.Build();
|
||||
//排除默认的文件存储库,让它不要生成文件
|
||||
LinkerMessengerEntry.Setup(ExcludeModule.StoreFile);
|
||||
```
|
||||
:::
|
@@ -1,8 +1,8 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
sidebar_position: 33
|
||||
---
|
||||
|
||||
# 8.3、组网和内网穿透流程图
|
||||
# 8.33、组网和内网穿透流程图
|
||||
|
||||
:::tip[说明]
|
||||
|
20
linker.doc.web/docs/8、集成和二次开发/8.3、序列化库.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# 8.3、序列化库
|
||||
|
||||
:::tip[说明]
|
||||
1. 实现`linker.libs.ISerializer`接口
|
||||
2. 然后注入覆盖原本的序列化库实现
|
||||
```
|
||||
//初始化
|
||||
LinkerMessengerEntry.Initialize();
|
||||
//在这里可以注入覆盖实现
|
||||
LinkerMessengerEntry.AddService<linker.libs.ISerializer, MySerializer>();
|
||||
|
||||
LinkerMessengerEntry.Build();
|
||||
//排除默认的序列化库
|
||||
LinkerMessengerEntry.Setup(ExcludeModule.SerializerMemoryPack);
|
||||
```
|
||||
:::
|
96
linker.doc.web/docs/8、集成和二次开发/8.4、登入信标验证.md
Normal file
@@ -0,0 +1,96 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# 8.4、登入信标验证
|
||||
|
||||
:::tip[说明]
|
||||
登入信标,注入自定义参数,或者使用已有参数验证
|
||||
```
|
||||
//初始化
|
||||
LinkerMessengerEntry.Initialize();
|
||||
//在这里注入
|
||||
LinkerMessengerEntry.AddService<MyClientSignInArgs>();
|
||||
LinkerMessengerEntry.AddService<MyServerSignInArgs>();
|
||||
|
||||
//构建
|
||||
LinkerMessengerEntry.Build();
|
||||
|
||||
SignInArgsTransfer signInArgsTransfer = LinkerMessengerEntry.GetService<SignInArgsTransfer>();
|
||||
//可以删除默认的一些验证,group分组密码,machineId设备唯一编号,secretKey信标密钥,version版本验证
|
||||
//signInArgsTransfer.RemoveArgs(new List<string>{ "group","machineId","secretKey","version" });
|
||||
|
||||
ICommonStore commonStore = LinkerMessengerEntry.GetService<ICommonStore>();
|
||||
//客户端则添加客户端类
|
||||
if((commonStore.Modes & CommonModes.Client) == CommonModes.Client)
|
||||
{
|
||||
signInArgsTransfer.AddArgs(new List<ISignInArgs> {
|
||||
LinkerMessengerEntry.GetService<MyClientSignInArgs>()
|
||||
});
|
||||
}
|
||||
//服务端则添加服务端类
|
||||
if((commonStore.Modes & CommonModes.Server) == CommonModes.Server)
|
||||
{
|
||||
signInArgsTransfer.AddArgs(new List<ISignInArgs> {
|
||||
LinkerMessengerEntry.GetService<MyServerSignInArgs>()
|
||||
});
|
||||
}
|
||||
|
||||
//运行
|
||||
LinkerMessengerEntry.Setup();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 客户端
|
||||
/// </summary>
|
||||
public sealed class MyClientSignInArgs : ISignInArgs
|
||||
{
|
||||
public string Name => "mySigninArgs";
|
||||
/// <summary>
|
||||
/// 客户端调用
|
||||
/// </summary>
|
||||
/// <param name="host">登入的服务器</param>
|
||||
/// <param name="args">往这里面添加参数</param>
|
||||
/// <returns>返回不为空则为错误信息,中断登录操作</returns>
|
||||
public async Task<string> Invoke(string host, Dictionary<string, string> args)
|
||||
{
|
||||
args.Add("myArgs", "myArgs")
|
||||
await Task.CompletedTask;
|
||||
return string.Empty;
|
||||
}
|
||||
public async Task<string> Validate(SignInfo signInfo, SignCacheInfo cache)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 服务端
|
||||
/// </summary>
|
||||
public sealed class MyServerSignInArgs : ISignInArgs
|
||||
{
|
||||
public string Name => "mySigninArgs";
|
||||
public async Task<string> Invoke(string host, Dictionary<string, string> args)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 服务端调用
|
||||
/// </summary>
|
||||
/// <param name="signInfo">本次登录参数</param>
|
||||
/// <param name="cache">之前的登录信息,如果以前登录过的话</param>
|
||||
/// <returns>返回不为空则为错误信息,登录失败</returns>
|
||||
public async Task<string> Validate(SignInfo signInfo, SignCacheInfo cache)
|
||||
{
|
||||
if (signInfo.Args.TryGetValue("myArgs", out string arg) == false)
|
||||
{
|
||||
return $"myArgs validate fail";
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
55
linker.doc.web/docs/8、集成和二次开发/8.5、中继验证.md
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
# 8.5、中继验证
|
||||
|
||||
:::tip[说明]
|
||||
验证通过则允许中继
|
||||
```
|
||||
//初始化
|
||||
LinkerMessengerEntry.Initialize();
|
||||
//在这里注入
|
||||
LinkerMessengerEntry.AddService<MyRelayServerValidator>();
|
||||
|
||||
//构建
|
||||
LinkerMessengerEntry.Build();
|
||||
|
||||
RelayServerValidatorTransfer relayServerValidatorTransfer
|
||||
= LinkerMessengerEntry.GetService<RelayServerValidatorTransfer>();
|
||||
//可以删除默认的一些验证,secretKey中继密钥
|
||||
//relayServerValidatorTransfer.RemoveValidators(new List<string>{ "secretKey"});
|
||||
|
||||
ICommonStore commonStore = LinkerMessengerEntry.GetService<ICommonStore>();
|
||||
//服务端则添加
|
||||
if((commonStore.Modes & CommonModes.Server) == CommonModes.Server)
|
||||
{
|
||||
relayServerValidatorTransfer.AddArgs(new List<IRelayServerValidator> {
|
||||
LinkerMessengerEntry.GetService<MyRelayServerValidator>()
|
||||
});
|
||||
}
|
||||
|
||||
//运行
|
||||
LinkerMessengerEntry.Setup();
|
||||
|
||||
|
||||
public sealed class MyRelayServerValidator : IRelayServerValidator
|
||||
{
|
||||
public string Name => "myRelayServerValidator";
|
||||
|
||||
/// <summary>
|
||||
/// 验证
|
||||
/// </summary>
|
||||
/// <param name="relayInfo">中继信息</param>
|
||||
/// <param name="fromMachine">来源客户端</param>
|
||||
/// <param name="toMachine">目标客户端,可能为null</param>
|
||||
/// <returns>返回不为空则为错误信息,中继失败</returns>
|
||||
public async Task<string> Validate(linker.messenger.relay.client.transport.RelayInfo relayInfo,
|
||||
SignCacheInfo fromMachine, SignCacheInfo toMachine)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"label": "8、集成",
|
||||
"label": "8、集成和二次开发",
|
||||
"position": 8,
|
||||
"link": {
|
||||
"type": "generated-index",
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 168 KiB |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
@@ -12,6 +12,7 @@ sidebar_position: 9
|
||||
<th>2-5设备</th>
|
||||
<th>5-10设备</th>
|
||||
<th>10设备以上</th>
|
||||
<th>权益</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -21,6 +22,7 @@ sidebar_position: 9
|
||||
<td>免费</td>
|
||||
<td>免费</td>
|
||||
<td>免费</td>
|
||||
<td>/</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>开源集成</td>
|
||||
@@ -28,28 +30,31 @@ sidebar_position: 9
|
||||
<td>免费</td>
|
||||
<td>免费</td>
|
||||
<td>免费</td>
|
||||
<td>/</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>安装维护/次</td>
|
||||
<td>免费</td>
|
||||
<td>9.9/台</td>
|
||||
<td>9.9/台</td>
|
||||
<td>9.9/台</td>
|
||||
<td>安装配置维护/次</td>
|
||||
<td>20/次</td>
|
||||
<td>50/次</td>
|
||||
<td>100/次</td>
|
||||
<td>10/台/次</td>
|
||||
<td>私有化部署、配置、BUG修复</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>安装维护/年</td>
|
||||
<td>19.9/年</td>
|
||||
<td>39.9/年</td>
|
||||
<td>79.9/年</td>
|
||||
<td>9.9/年/台</td>
|
||||
<td>安装配置维护/年</td>
|
||||
<td>99/年</td>
|
||||
<td>239/年</td>
|
||||
<td>399/年</td>
|
||||
<td>29/台/年</td>
|
||||
<td>私有化部署、配置、BUG修复、技术解答</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>商业集成</td>
|
||||
<td colspan="4" align="center">详谈</td>
|
||||
<td colspan="5" align="center">详谈,技术解答,原理讲解,二开指导</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>商业功能定制</td>
|
||||
<td colspan="4" align="center">详谈</td>
|
||||
<td>功能定制</td>
|
||||
<td colspan="5" align="center">详谈,技术解答,原理讲解,二开指导</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
BIN
linker.doc.web/docs/img/qr.jpg
Normal file
After Width: | Height: | Size: 120 KiB |
@@ -103,6 +103,7 @@ namespace linker.messenger.action
|
||||
|
||||
public sealed class SignInArgsAction : JsonArgReplace, ISignInArgs
|
||||
{
|
||||
public string Name => "action";
|
||||
private readonly ActionTransfer actionTransfer;
|
||||
private readonly IActionClientStore actionStore;
|
||||
private readonly IActionServerStore actionServerStore;
|
||||
|
@@ -113,7 +113,7 @@ namespace linker.messenger.entry
|
||||
if (builded.StartOperation() == false) return;
|
||||
|
||||
serviceProvider = serviceCollection.BuildServiceProvider();
|
||||
serviceProvider.UseMessenger().UseStoreFile().UseSerializerMemoryPack();
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取服务
|
||||
@@ -129,28 +129,110 @@ namespace linker.messenger.entry
|
||||
/// <summary>
|
||||
/// 开始运行
|
||||
/// </summary>
|
||||
public static void Setup()
|
||||
/// <param name="modules">排除哪些模块,默认无</param>
|
||||
public static void Setup(ExcludeModule modules = ExcludeModule.None)
|
||||
{
|
||||
if (setuped.StartOperation() == false) return;
|
||||
|
||||
ICommonStore commonStore = serviceProvider.GetService<ICommonStore>();
|
||||
|
||||
serviceProvider.UseMessenger();
|
||||
if ((modules & ExcludeModule.StoreFile) != ExcludeModule.StoreFile)
|
||||
serviceProvider.UseStoreFile();
|
||||
if ((modules & ExcludeModule.SerializerMemoryPack) != ExcludeModule.SerializerMemoryPack)
|
||||
serviceProvider.UseSerializerMemoryPack();
|
||||
|
||||
if ((commonStore.Modes & CommonModes.Server) == CommonModes.Server)
|
||||
{
|
||||
serviceProvider.UseAccessServer().UseActionServer().UseDecenterServer().UseForwardServer().UsePcpServer().UseRelayServer().UseSForwardServer().UseSignInServer().UseSocks5Server().UseSyncServer().UseTunnelServer().UseTuntapServer().UseUpdaterServer().UseFlowServer();
|
||||
if ((modules & ExcludeModule.Action) != ExcludeModule.Action)
|
||||
serviceProvider.UseActionServer();
|
||||
if ((modules & ExcludeModule.Forward) != ExcludeModule.Forward)
|
||||
serviceProvider.UseForwardServer();
|
||||
if ((modules & ExcludeModule.SForward) != ExcludeModule.SForward)
|
||||
serviceProvider.UseSForwardServer();
|
||||
if ((modules & ExcludeModule.Socks5) != ExcludeModule.Socks5)
|
||||
serviceProvider.UseSocks5Server();
|
||||
if ((modules & ExcludeModule.Tuntap) != ExcludeModule.Tuntap)
|
||||
serviceProvider.UseTuntapServer();
|
||||
if ((modules & ExcludeModule.Updater) != ExcludeModule.Updater)
|
||||
serviceProvider.UseUpdaterServer();
|
||||
|
||||
serviceProvider.UseAccessServer().UseDecenterServer().UsePcpServer().UseRelayServer()
|
||||
.UseSignInServer().UseSyncServer().UseTunnelServer().UseFlowServer();
|
||||
|
||||
serviceProvider.UseListen();
|
||||
}
|
||||
|
||||
if ((commonStore.Modes & CommonModes.Client) == CommonModes.Client)
|
||||
{
|
||||
serviceProvider.UseLoggerClient().UseApiClient().UseExRoute().UseAccessClient().UseActionClient().UseDecenterClient().UseForwardClient().UsePcpClient().UseRelayClient().UseSForwardClient().UseSocks5Client().UseSyncClient().UseTunnelClient().UseTuntapClient().UseUpdaterClient().UseFlowClient();
|
||||
serviceProvider.UseLoggerClient();
|
||||
if ((modules & ExcludeModule.Api) != ExcludeModule.Api)
|
||||
serviceProvider.UseApiClient();
|
||||
if ((modules & ExcludeModule.Action) != ExcludeModule.Action)
|
||||
serviceProvider.UseActionClient();
|
||||
if ((modules & ExcludeModule.Forward) != ExcludeModule.Forward)
|
||||
serviceProvider.UseForwardClient();
|
||||
if ((modules & ExcludeModule.SForward) != ExcludeModule.SForward)
|
||||
serviceProvider.UseSForwardClient();
|
||||
if ((modules & ExcludeModule.Socks5) != ExcludeModule.Socks5)
|
||||
serviceProvider.UseSocks5Client();
|
||||
if ((modules & ExcludeModule.Tuntap) != ExcludeModule.Tuntap)
|
||||
serviceProvider.UseTuntapClient();
|
||||
if ((modules & ExcludeModule.Updater) != ExcludeModule.Updater)
|
||||
serviceProvider.UseUpdaterClient();
|
||||
serviceProvider.UseExRoute().UseAccessClient().UseDecenterClient().UsePcpClient().UseRelayClient().UseSyncClient().UseTunnelClient().UseFlowClient();
|
||||
|
||||
serviceProvider.UseSignInClient();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 排除那些模块
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ExcludeModule : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// 无
|
||||
/// </summary>
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// 端口转发
|
||||
/// </summary>
|
||||
Forward = 1,
|
||||
/// <summary>
|
||||
/// 内网穿透
|
||||
/// </summary>
|
||||
SForward = 2,
|
||||
/// <summary>
|
||||
/// socks5
|
||||
/// </summary>
|
||||
Socks5 = 4,
|
||||
/// <summary>
|
||||
/// 虚拟网卡
|
||||
/// </summary>
|
||||
Tuntap = 8,
|
||||
/// <summary>
|
||||
/// 更新检测
|
||||
/// </summary>
|
||||
Updater = 16,
|
||||
/// <summary>
|
||||
/// 文件存储库
|
||||
/// </summary>
|
||||
StoreFile = 32,
|
||||
/// <summary>
|
||||
/// MemoryPack序列化库
|
||||
/// </summary>
|
||||
SerializerMemoryPack = 64,
|
||||
/// <summary>
|
||||
/// 管理接口和网页
|
||||
/// </summary>
|
||||
Api = 128,
|
||||
/// <summary>
|
||||
/// 自定义认证
|
||||
/// </summary>
|
||||
Action = 256,
|
||||
}
|
||||
}
|
||||
|
@@ -148,6 +148,27 @@ namespace linker.messenger.forward
|
||||
Payload = serializer.Serialize(info)
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> Test(ApiControllerParamsInfo param)
|
||||
{
|
||||
if (param.Content == signInClientStore.Id)
|
||||
{
|
||||
forwardTransfer.SubscribeTest();
|
||||
return true;
|
||||
}
|
||||
await messengerSender.SendOnly(new MessageRequestWrap
|
||||
{
|
||||
Connection = signInClientState.Connection,
|
||||
MessengerId = (ushort)ForwardMessengerIds.TestClientForward,
|
||||
Payload = serializer.Serialize(param.Content)
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ForwardListInfo
|
||||
|
@@ -86,6 +86,22 @@ namespace linker.messenger.forward
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MessengerId((ushort)ForwardMessengerIds.TestClientForward)]
|
||||
public async Task TestClientForward(IConnection connection)
|
||||
{
|
||||
string machineid = serializer.Deserialize<string>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
if (signCaching.TryGet(machineid, out SignCacheInfo cacheTo) && signCaching.TryGet(connection.Id, out SignCacheInfo cacheFrom) && cacheFrom.GroupId == cacheTo.GroupId)
|
||||
{
|
||||
uint requestid = connection.ReceiveRequestWrap.RequestId;
|
||||
await sender.SendOnly(new MessageRequestWrap
|
||||
{
|
||||
Connection = cacheTo.Connection,
|
||||
MessengerId = (ushort)ForwardMessengerIds.TestClientForward
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public sealed class ForwardClientMessenger : IMessenger
|
||||
@@ -125,7 +141,14 @@ namespace linker.messenger.forward
|
||||
uint id = serializer.Deserialize<uint>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
forwardTransfer.Remove(id);
|
||||
}
|
||||
|
||||
|
||||
[MessengerId((ushort)ForwardMessengerIds.TestClient)]
|
||||
public void TestClient(IConnection connection)
|
||||
{
|
||||
forwardTransfer.SubscribeTest();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
using linker.libs.extends;
|
||||
using linker.messenger.forward.proxy;
|
||||
using linker.messenger.signin;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace linker.messenger.forward
|
||||
{
|
||||
@@ -200,5 +201,43 @@ namespace linker.messenger.forward
|
||||
forwardClientStore.Confirm();
|
||||
return true;
|
||||
}
|
||||
|
||||
private readonly OperatingManager testing = new OperatingManager();
|
||||
public void SubscribeTest()
|
||||
{
|
||||
if (testing.StartOperation() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IEnumerable<Task<bool>> tasks = Get().Select(Connect);
|
||||
Task.WhenAll(tasks).ContinueWith((result) =>
|
||||
{
|
||||
testing.StopOperation();
|
||||
OnChanged();
|
||||
});
|
||||
|
||||
async Task<bool> Connect(ForwardInfo info)
|
||||
{
|
||||
Socket socket = new Socket(info.TargetEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||
try
|
||||
{
|
||||
await socket.ConnectAsync(info.TargetEP).WaitAsync(TimeSpan.FromMilliseconds(500));
|
||||
info.TargetMsg = string.Empty;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
info.TargetMsg = ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
socket.SafeClose();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -40,6 +40,13 @@ namespace linker.messenger.pcp
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 连接
|
||||
/// </summary>
|
||||
/// <param name="remoteMachineId">目标id</param>
|
||||
/// <param name="transactionId">事务ID,属于什么事务的,端口转发还是虚拟网卡</param>
|
||||
/// <param name="denyProtocols">不想使用哪些打洞协议</param>
|
||||
/// <returns></returns>
|
||||
public async Task<ITunnelConnection> ConnectAsync(string remoteMachineId, string transactionId, TunnelProtocolType denyProtocols)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
@@ -8,6 +8,7 @@ namespace linker.messenger.relay.server.validator
|
||||
/// </summary>
|
||||
public interface IRelayServerValidator
|
||||
{
|
||||
public string Name { get; }
|
||||
/// <summary>
|
||||
/// 验证
|
||||
/// </summary>
|
||||
|
@@ -4,12 +4,15 @@ namespace linker.messenger.relay.server.validator
|
||||
{
|
||||
public sealed class RelayServerValidatorSecretKey : IRelayServerValidator
|
||||
{
|
||||
public string Name => "secretKey";
|
||||
|
||||
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)
|
||||
|
@@ -26,6 +26,19 @@ namespace linker.messenger.relay.server.validator
|
||||
validators = validators.Concat(list).Distinct(new RelayServerValidatorEqualityComparer()).ToList();
|
||||
LoggerHelper.Instance.Info($"load relay server validator :{string.Join(",", list.Select(c => c.GetType().Name))}");
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除一些验证实现类
|
||||
/// </summary>
|
||||
/// <param name="names"></param>
|
||||
public void RemoveValidators(List<string> names)
|
||||
{
|
||||
foreach (string name in names)
|
||||
{
|
||||
IRelayServerValidator item = validators.FirstOrDefault(c => c.Name == name);
|
||||
if (item != null)
|
||||
validators.Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证
|
||||
|
@@ -154,7 +154,7 @@ namespace linker.messenger.sforward.client
|
||||
{
|
||||
if (param.Content == signInClientStore.Id)
|
||||
{
|
||||
forwardTransfer.TestLocal();
|
||||
forwardTransfer.SubscribeTest();
|
||||
return true;
|
||||
}
|
||||
await messengerSender.SendOnly(new MessageRequestWrap
|
||||
|
@@ -19,7 +19,7 @@ namespace linker.messenger.sforward.client
|
||||
private readonly ISerializer serializer;
|
||||
|
||||
private readonly NumberSpaceUInt32 ns = new NumberSpaceUInt32();
|
||||
private readonly OperatingManager operatingManager = new OperatingManager();
|
||||
|
||||
|
||||
public SForwardClientTransfer(SignInClientState signInClientState, IMessengerSender messengerSender, ISignInClientStore signInClientStore, ISForwardClientStore sForwardClientStore, ISerializer serializer)
|
||||
{
|
||||
@@ -214,49 +214,39 @@ namespace linker.messenger.sforward.client
|
||||
return arr.Length == 2 && int.TryParse(arr[0], out min) && int.TryParse(arr[1], out max);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试本机服务
|
||||
/// </summary>
|
||||
public void TestLocal()
|
||||
private readonly OperatingManager testing = new OperatingManager();
|
||||
public void SubscribeTest()
|
||||
{
|
||||
if (operatingManager.StartOperation() == false) return;
|
||||
|
||||
TimerHelper.Async(async () =>
|
||||
if (testing.StartOperation() == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
var results = sForwardClientStore.Get().Select(c => c.LocalEP).Select(ConnectAsync);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var item in results.Select(c => c.Result))
|
||||
{
|
||||
var forward = sForwardClientStore.Get().FirstOrDefault(c => c.LocalEP.Equals(item.Item1));
|
||||
if (forward != null)
|
||||
{
|
||||
forward.LocalMsg = item.Item2;
|
||||
}
|
||||
}
|
||||
OnChanged();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
operatingManager.StopOperation();
|
||||
IEnumerable<Task<bool>> tasks = sForwardClientStore.Get().Select(Connect);
|
||||
Task.WhenAll(tasks).ContinueWith((result) =>
|
||||
{
|
||||
testing.StopOperation();
|
||||
OnChanged();
|
||||
});
|
||||
|
||||
async Task<(IPEndPoint, string)> ConnectAsync(IPEndPoint ep)
|
||||
async Task<bool> Connect(SForwardInfo info)
|
||||
{
|
||||
Socket socket = new Socket(info.LocalEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||
try
|
||||
{
|
||||
using Socket socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||
await socket.ConnectAsync(ep).WaitAsync(TimeSpan.FromMilliseconds(5000)).ConfigureAwait(false);
|
||||
socket.SafeClose();
|
||||
return (ep, string.Empty);
|
||||
await socket.ConnectAsync(info.LocalEP).WaitAsync(TimeSpan.FromMilliseconds(500));
|
||||
info.LocalMsg = string.Empty;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (ep, ex.Message);
|
||||
info.LocalMsg = ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
socket.SafeClose();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -416,13 +416,13 @@ namespace linker.plugins.sforward.messenger
|
||||
sForwardTransfer.Remove(id);
|
||||
}
|
||||
// <summary>
|
||||
/// 删除
|
||||
/// 测试
|
||||
/// </summary>
|
||||
/// <param name="connection"></param>
|
||||
[MessengerId((ushort)SForwardMessengerIds.TestClient)]
|
||||
public void TestClient(IConnection connection)
|
||||
{
|
||||
sForwardTransfer.TestLocal();
|
||||
sForwardTransfer.SubscribeTest();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -5,6 +5,7 @@
|
||||
/// </summary>
|
||||
public interface ISignInArgs
|
||||
{
|
||||
public string Name { get; }
|
||||
/// <summary>
|
||||
/// 添加参数,客户端调用
|
||||
/// </summary>
|
||||
|
@@ -5,11 +5,16 @@
|
||||
/// </summary>
|
||||
public sealed class SignInArgsGroupPasswordClient : ISignInArgs
|
||||
{
|
||||
public string Name => "group";
|
||||
|
||||
private readonly ISignInClientStore signInClientStore;
|
||||
public SignInArgsGroupPasswordClient(ISignInClientStore signInClientStore)
|
||||
{
|
||||
this.signInClientStore = signInClientStore;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<string> Invoke(string host, Dictionary<string, string> args)
|
||||
{
|
||||
args.TryAdd("signin-gpwd", signInClientStore.Group.Password);
|
||||
@@ -29,6 +34,7 @@
|
||||
/// </summary>
|
||||
public sealed class SignInArgsGroupPasswordServer : ISignInArgs
|
||||
{
|
||||
public string Name => "group";
|
||||
public SignInArgsGroupPasswordServer()
|
||||
{
|
||||
}
|
||||
|
@@ -1,6 +1,4 @@
|
||||
using linker.libs;
|
||||
using linker.messenger.signin;
|
||||
using linker.messenger.signin.args;
|
||||
|
||||
namespace linker.messenger.signin.args
|
||||
{
|
||||
@@ -9,6 +7,7 @@ namespace linker.messenger.signin.args
|
||||
/// </summary>
|
||||
public sealed class SignInArgsMachineKeyClient : ISignInArgs
|
||||
{
|
||||
public string Name => "machineId";
|
||||
public async Task<string> Invoke(string host, Dictionary<string, string> args)
|
||||
{
|
||||
string machineKey = SystemIdHelper.GetSystemId();
|
||||
@@ -38,6 +37,7 @@ namespace linker.messenger.signin.args
|
||||
/// </summary>
|
||||
public sealed class SignInArgsMachineKeyServer : ISignInArgs
|
||||
{
|
||||
public string Name => "machineId";
|
||||
public async Task<string> Invoke(string host, Dictionary<string, string> args)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
@@ -5,6 +5,8 @@
|
||||
/// </summary>
|
||||
public sealed class SignInArgsSecretKeyClient : ISignInArgs
|
||||
{
|
||||
public string Name => "secretKey";
|
||||
|
||||
private readonly ISignInClientStore signInClientStore;
|
||||
public SignInArgsSecretKeyClient(ISignInClientStore signInClientStore)
|
||||
{
|
||||
@@ -29,6 +31,7 @@
|
||||
/// </summary>
|
||||
public sealed class SignInArgsSecretKeyServer : ISignInArgs
|
||||
{
|
||||
public string Name => "secretKey";
|
||||
private readonly ISignInServerStore signInServerStore;
|
||||
public SignInArgsSecretKeyServer(ISignInServerStore signInServerStore)
|
||||
{
|
||||
|
@@ -20,6 +20,20 @@
|
||||
startups = startups.Concat(list).Distinct().ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除实现类
|
||||
/// </summary>
|
||||
/// <param name="names"></param>
|
||||
public void RemoveArgs(List<string> names)
|
||||
{
|
||||
foreach (string name in names)
|
||||
{
|
||||
ISignInArgs item = startups.FirstOrDefault(c => c.Name == name);
|
||||
if (item != null)
|
||||
startups.Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户端调用
|
||||
/// </summary>
|
||||
|
@@ -1,6 +1,4 @@
|
||||
using linker.libs;
|
||||
using linker.messenger.signin;
|
||||
using linker.messenger.signin.args;
|
||||
|
||||
namespace linker.messenger.signin.args
|
||||
{
|
||||
@@ -9,6 +7,7 @@ namespace linker.messenger.signin.args
|
||||
/// </summary>
|
||||
public sealed class SignInArgsVersionClient : ISignInArgs
|
||||
{
|
||||
public string Name => "version";
|
||||
public async Task<string> Invoke(string host, Dictionary<string, string> args)
|
||||
{
|
||||
args.TryAdd("version", VersionHelper.version);
|
||||
@@ -30,6 +29,13 @@ namespace linker.messenger.signin.args
|
||||
/// </summary>
|
||||
public sealed class SignInArgsVersionServer : ISignInArgs
|
||||
{
|
||||
public string Name => "version";
|
||||
/// <summary>
|
||||
/// 客户端调用
|
||||
/// </summary>
|
||||
/// <param name="host"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> Invoke(string host, Dictionary<string, string> args)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
@@ -37,7 +43,7 @@ namespace linker.messenger.signin.args
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证参数
|
||||
/// 服务端调用
|
||||
/// </summary>
|
||||
/// <param name="signInfo">新登录参数</param>
|
||||
/// <param name="cache">之前的登录信息</param>
|
||||
|
@@ -42,7 +42,7 @@ namespace linker.messenger.tuntap
|
||||
tuntapTransfer.OnShutdownSuccess += () => { DeleteForward(); tuntapConfigTransfer.SetRunning(false); };
|
||||
|
||||
//配置有更新,去同步一下
|
||||
tuntapConfigTransfer.OnUpdate += tuntapDecenter.Refresh;
|
||||
tuntapConfigTransfer.OnUpdate += () => { _ = CheckDevice(); tuntapDecenter.Refresh(); };
|
||||
|
||||
//收到新的信息,添加一下路由
|
||||
tuntapDecenter.OnChangeBefore += DelRoute;
|
||||
@@ -60,22 +60,28 @@ namespace linker.messenger.tuntap
|
||||
CheckDeviceTask();
|
||||
}
|
||||
|
||||
|
||||
private void CheckDeviceTask()
|
||||
{
|
||||
ulong configVersion = 0;
|
||||
TimerHelper.SetInterval(async () =>
|
||||
{
|
||||
bool restart =
|
||||
(tuntapConfigTransfer.Version.Eq(configVersion, out ulong _version) == false || await tuntapTransfer.CheckAvailable() == false)
|
||||
&& tuntapConfigTransfer.Running && tuntapTransfer.Status != TuntapStatus.Running && tuntapTransfer.Status != TuntapStatus.Operating;
|
||||
if (restart)
|
||||
{
|
||||
configVersion = _version;
|
||||
await RetstartDevice();
|
||||
}
|
||||
await CheckDevice();
|
||||
return true;
|
||||
}, () => 30000);
|
||||
}
|
||||
ulong configVersion = 0;
|
||||
private async Task CheckDevice()
|
||||
{
|
||||
bool restart =
|
||||
(tuntapConfigTransfer.Version.Eq(configVersion, out ulong _version) == false || await tuntapTransfer.CheckAvailable() == false)
|
||||
&& tuntapConfigTransfer.Running && tuntapTransfer.Status != TuntapStatus.Operating;
|
||||
if (restart)
|
||||
{
|
||||
configVersion = _version;
|
||||
await RetstartDevice();
|
||||
}
|
||||
}
|
||||
|
||||
private TuntapInfo GetCurrentInfo()
|
||||
{
|
||||
return new TuntapInfo
|
||||
@@ -188,9 +194,8 @@ namespace linker.messenger.tuntap
|
||||
|
||||
return infos
|
||||
.Where(c => c.MachineId != signInClientStore.Id)
|
||||
.OrderByDescending(c => c.Status)
|
||||
.OrderBy(c => c.IP, new IPAddressComparer())
|
||||
|
||||
.OrderByDescending(c => c.Status)
|
||||
.Select(c =>
|
||||
{
|
||||
var lans = c.Lans.Where(c => c.Disabled == false && c.IP.Equals(IPAddress.Any) == false).Where(c =>
|
||||
|
@@ -64,7 +64,7 @@ namespace linker.messenger.tuntap
|
||||
await LeaseIP();
|
||||
SetGroupIP();
|
||||
|
||||
if ((ip.Equals(Info.IP) == false || prefixLength != Info.PrefixLength) && Info.Running)
|
||||
if ((ip.Equals(Info.IP) == false || prefixLength != Info.PrefixLength))
|
||||
{
|
||||
Version.Add();
|
||||
}
|
||||
@@ -77,19 +77,7 @@ namespace linker.messenger.tuntap
|
||||
/// </summary>
|
||||
public void RefreshIP()
|
||||
{
|
||||
TimerHelper.Async(async () =>
|
||||
{
|
||||
IPAddress oldIP = Info.IP;
|
||||
byte prefixLength = Info.PrefixLength;
|
||||
|
||||
await RefreshIPASync();
|
||||
|
||||
if ((oldIP.Equals(Info.IP) == false || prefixLength != Info.PrefixLength) && Info.Running)
|
||||
{
|
||||
Version.Add();
|
||||
}
|
||||
OnUpdate();
|
||||
});
|
||||
_ = RefreshIPASync();
|
||||
}
|
||||
/// <summary>
|
||||
/// 刷新IP,不会触发OnChanged
|
||||
@@ -97,9 +85,18 @@ namespace linker.messenger.tuntap
|
||||
/// <returns></returns>
|
||||
public async Task RefreshIPASync()
|
||||
{
|
||||
IPAddress oldIP = Info.IP;
|
||||
byte prefixLength = Info.PrefixLength;
|
||||
|
||||
LoadGroupIP();
|
||||
await LeaseIP();
|
||||
SetGroupIP();
|
||||
|
||||
if ((oldIP.Equals(Info.IP) == false || prefixLength != Info.PrefixLength) && Info.Running)
|
||||
{
|
||||
Version.Add();
|
||||
}
|
||||
|
||||
OnUpdate();
|
||||
}
|
||||
private async Task LeaseIP()
|
||||
|
@@ -67,7 +67,7 @@ namespace linker.messenger.tuntap
|
||||
|
||||
public async Task SubscribeForwardTest(List<TuntapForwardTestInfo> list)
|
||||
{
|
||||
await Task.WhenAll(list.Select(async c =>
|
||||
await Task.WhenAll(list.Where(c=>c.ConnectAddr.Equals(IPAddress.Any)==false && c.ConnectPort > 0 && c.ListenPort > 0).Select(async c =>
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@@ -8,7 +8,8 @@ using System.Buffers;
|
||||
using linker.messenger.relay.client;
|
||||
using linker.messenger.signin;
|
||||
using linker.messenger.pcp;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Reflection.PortableExecutable;
|
||||
|
||||
namespace linker.messenger.tuntap
|
||||
{
|
||||
@@ -113,6 +114,7 @@ namespace linker.messenger.tuntap
|
||||
}, ip);
|
||||
return;
|
||||
}
|
||||
|
||||
await connection.SendAsync(packet.Packet);
|
||||
}
|
||||
|
||||
@@ -177,8 +179,10 @@ namespace linker.messenger.tuntap
|
||||
{
|
||||
string machineId = item.Value[0];
|
||||
ip2MachineDic.AddOrUpdate(item.Key, machineId, (a, b) => machineId);
|
||||
|
||||
if (ipConnections.TryGetValue(item.Key, out ITunnelConnection connection) && item.Value.Count > 0 && machineId != connection.RemoteMachineId)
|
||||
}
|
||||
foreach (var ip in ips)
|
||||
{
|
||||
foreach (var item in ipConnections.Where(c=>(c.Key & ip.NetWork)==ip.NetWork && c.Value.RemoteMachineId != ip.MachineId).ToList())
|
||||
{
|
||||
ipConnections.TryRemove(item.Key, out _);
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project ver="10" name="linker.tray.win" libEmbed="true" icon="..\linker\favicon.ico" ui="win" output="linker.tray.win.exe" CompanyName="snltty" FileDescription="linker.tray.win" LegalCopyright="Copyright (C) snltty 2024" ProductName="linker.tray.win" InternalName="linker.install.win" FileVersion="0.0.0.187" ProductVersion="0.0.0.187" publishDir="/dist/" dstrip="false" local="false" ignored="false">
|
||||
<project ver="10" name="linker.tray.win" libEmbed="true" icon="..\linker\favicon.ico" ui="win" output="linker.tray.win.exe" CompanyName="snltty" FileDescription="linker.tray.win" LegalCopyright="Copyright (C) snltty 2024" ProductName="linker.tray.win" InternalName="linker.install.win" FileVersion="0.0.0.188" ProductVersion="0.0.0.188" publishDir="/dist/" dstrip="false" local="false" ignored="false">
|
||||
<file name="main.aardio" path="main.aardio" comment="main.aardio"/>
|
||||
<folder name="资源文件" path="res" embed="true" local="false" ignored="false">
|
||||
<file name="favicon.ico" path="res\favicon.ico" comment="res\favicon.ico"/>
|
||||
|
BIN
linker.tray.win/dist/linker.tray.win.exe
vendored
@@ -1 +1 @@
|
||||
.table-sort th[data-v-4b2df38c]{border-bottom:0}.dropdown[data-v-6638f97d]{border:1px solid #ddd;padding:.4rem;font-size:1.3rem;border-radius:.4rem;position:relative}.dropdown .el-icon[data-v-6638f97d]{vertical-align:middle}.dropdown .badge[data-v-6638f97d]{position:absolute;right:-1rem;top:-50%;border-radius:10px;background-color:#f1ae05;color:#fff;padding:.2rem .6rem;font-size:1.2rem}a[data-v-6653ef00]{color:#666;text-decoration:underline}a.green[data-v-6653ef00]{color:green;font-weight:700}a.download[data-v-6653ef00]{margin-left:.6rem}a.download .el-icon[data-v-6653ef00]{vertical-align:middle;font-weight:700;margin-left:.3rem}a.download .el-icon.loading[data-v-6653ef00]{animation:loading-6653ef00 1s linear infinite}a.download+a.download[data-v-6653ef00]{margin-left:.2rem}@keyframes loading-6653ef00{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}img.system[data-v-ffd0d512]{height:1.6rem;vertical-align:middle;margin-right:.4rem}.self[data-v-ffd0d512]{color:#d400ff}.self .el-icon[data-v-ffd0d512]{vertical-align:text-bottom}.ipaddress span[data-v-5db71b03]{vertical-align:middle}.el-input[data-v-5db71b03]{width:12rem;margin-right:.6rem}.el-col[data-v-5d52ca48]{text-align:left}span.point[data-v-39aee530]{width:.8rem;height:.8rem;border-radius:50%;display:inline-block;vertical-align:middle;margin:-.2rem .3rem 0 -1.3rem;background-color:#eee;border:1px solid #ddd}span.point.p2p[data-v-39aee530]{background-color:#01c901;border:1px solid #049538}span.point.relay[data-v-39aee530]{background-color:#e3e811;border:1px solid #b3c410}span.point.node[data-v-39aee530]{background-color:#09dda9;border:1px solid #0cac90}.el-icon.loading[data-v-f8059b00],a.loading[data-v-f8059b00]{vertical-align:middle;font-weight:700;animation:loading-f8059b00 1s linear infinite}.el-switch.is-disabled[data-v-f8059b00]{opacity:1}.el-input[data-v-f8059b00]{width:8rem}.delay[data-v-f8059b00]{position:absolute;right:0;bottom:0;line-height:normal}.switch-btn[data-v-f8059b00]{font-size:1.5rem}@keyframes loading-f8059b00{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.wrap[data-v-786fe646]{padding-right:1rem}.remark[data-v-786fe646]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wrap[data-v-4abaaeaf]{padding-right:1rem}.el-switch.is-disabled[data-v-34275839]{opacity:1}.upgrade-wrap[data-v-34275839]{border:1px solid #ddd;margin-bottom:2rem;padding:0 0 1rem 0}.el-switch.is-disabled[data-v-4a28804a]{opacity:1}.calc span[data-v-4a28804a]{display:inline-block}.calc span.label[data-v-4a28804a]{width:6rem}.el-icon.loading[data-v-d37c5992],a.loading[data-v-d37c5992]{vertical-align:middle;font-weight:700;animation:loading-d37c5992 1s linear infinite}.el-switch.is-disabled[data-v-d37c5992]{opacity:1}.el-input[data-v-d37c5992]{width:8rem}.switch-btn[data-v-d37c5992]{font-size:1.5rem}@keyframes loading-d37c5992{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.el-switch.is-disabled[data-v-022e3781]{opacity:1}.upgrade-wrap[data-v-022e3781]{border:1px solid #ddd;margin-bottom:2rem;padding:1rem 0 1rem 0}.lan-item[data-v-022e3781]{margin-bottom:0}.el-switch.is-disabled[data-v-49e16cac]{opacity:1}.green[data-v-49e16cac]{font-weight:700}.el-switch.is-disabled[data-v-6ea047f9]{opacity:1}a[data-v-6e9936ec]{text-decoration:underline}a+a[data-v-6e9936ec]{margin-left:1rem}a.green[data-v-6e9936ec]{font-weight:700}.head[data-v-15b05a01]{padding-bottom:1rem}.green[data-v-15b05a01]{color:green;font-weight:700}.error[data-v-15b05a01]{font-weight:700}.error .el-icon[data-v-15b05a01]{vertical-align:text-bottom}.head[data-v-7eb8e7cc]{padding-bottom:1rem}.error[data-v-7eb8e7cc]{font-weight:700}.error .el-icon[data-v-7eb8e7cc]{vertical-align:text-bottom}.head[data-v-7891b902]{padding-bottom:1rem}.table-sort.el-table th.el-table__cell.is-leaf{border-bottom:0}.table-sort.el-table .el-table__inner-wrapper:before{height:0}.home-list-wrap[data-v-3d1c480c]{padding:1rem}.home-list-wrap .page[data-v-3d1c480c]{padding-top:1rem}.home-list-wrap .page-wrap[data-v-3d1c480c]{display:inline-block}
|
||||
.table-sort th[data-v-4b2df38c]{border-bottom:0}.dropdown[data-v-6638f97d]{border:1px solid #ddd;padding:.4rem;font-size:1.3rem;border-radius:.4rem;position:relative}.dropdown .el-icon[data-v-6638f97d]{vertical-align:middle}.dropdown .badge[data-v-6638f97d]{position:absolute;right:-1rem;top:-50%;border-radius:10px;background-color:#f1ae05;color:#fff;padding:.2rem .6rem;font-size:1.2rem}a[data-v-6653ef00]{color:#666;text-decoration:underline}a.green[data-v-6653ef00]{color:green;font-weight:700}a.download[data-v-6653ef00]{margin-left:.6rem}a.download .el-icon[data-v-6653ef00]{vertical-align:middle;font-weight:700;margin-left:.3rem}a.download .el-icon.loading[data-v-6653ef00]{animation:loading-6653ef00 1s linear infinite}a.download+a.download[data-v-6653ef00]{margin-left:.2rem}@keyframes loading-6653ef00{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}img.system[data-v-ffd0d512]{height:1.6rem;vertical-align:middle;margin-right:.4rem}.self[data-v-ffd0d512]{color:#d400ff}.self .el-icon[data-v-ffd0d512]{vertical-align:text-bottom}.ipaddress span[data-v-5db71b03]{vertical-align:middle}.el-input[data-v-5db71b03]{width:12rem;margin-right:.6rem}.el-col[data-v-7a697708]{text-align:left}span.point[data-v-39aee530]{width:.8rem;height:.8rem;border-radius:50%;display:inline-block;vertical-align:middle;margin:-.2rem .3rem 0 -1.3rem;background-color:#eee;border:1px solid #ddd}span.point.p2p[data-v-39aee530]{background-color:#01c901;border:1px solid #049538}span.point.relay[data-v-39aee530]{background-color:#e3e811;border:1px solid #b3c410}span.point.node[data-v-39aee530]{background-color:#09dda9;border:1px solid #0cac90}.el-icon.loading[data-v-f8059b00],a.loading[data-v-f8059b00]{vertical-align:middle;font-weight:700;animation:loading-f8059b00 1s linear infinite}.el-switch.is-disabled[data-v-f8059b00]{opacity:1}.el-input[data-v-f8059b00]{width:8rem}.delay[data-v-f8059b00]{position:absolute;right:0;bottom:0;line-height:normal}.switch-btn[data-v-f8059b00]{font-size:1.5rem}@keyframes loading-f8059b00{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.wrap[data-v-786fe646]{padding-right:1rem}.remark[data-v-786fe646]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wrap[data-v-4abaaeaf]{padding-right:1rem}.el-switch.is-disabled[data-v-34275839]{opacity:1}.upgrade-wrap[data-v-34275839]{border:1px solid #ddd;margin-bottom:2rem;padding:0 0 1rem 0}.el-switch.is-disabled[data-v-4a28804a]{opacity:1}.calc span[data-v-4a28804a]{display:inline-block}.calc span.label[data-v-4a28804a]{width:6rem}.el-icon.loading[data-v-d37c5992],a.loading[data-v-d37c5992]{vertical-align:middle;font-weight:700;animation:loading-d37c5992 1s linear infinite}.el-switch.is-disabled[data-v-d37c5992]{opacity:1}.el-input[data-v-d37c5992]{width:8rem}.switch-btn[data-v-d37c5992]{font-size:1.5rem}@keyframes loading-d37c5992{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.el-switch.is-disabled[data-v-022e3781]{opacity:1}.upgrade-wrap[data-v-022e3781]{border:1px solid #ddd;margin-bottom:2rem;padding:1rem 0 1rem 0}.lan-item[data-v-022e3781]{margin-bottom:0}.el-switch.is-disabled[data-v-49e16cac]{opacity:1}.green[data-v-49e16cac]{font-weight:700}.el-switch.is-disabled[data-v-6ea047f9]{opacity:1}a[data-v-6e9936ec]{text-decoration:underline}a+a[data-v-6e9936ec]{margin-left:1rem}a.green[data-v-6e9936ec]{font-weight:700}.head[data-v-15b05a01]{padding-bottom:1rem}.green[data-v-15b05a01]{color:green;font-weight:700}.error[data-v-15b05a01]{font-weight:700}.error .el-icon[data-v-15b05a01]{vertical-align:text-bottom}.head[data-v-7eb8e7cc]{padding-bottom:1rem}.error[data-v-7eb8e7cc]{font-weight:700}.error .el-icon[data-v-7eb8e7cc]{vertical-align:text-bottom}.head[data-v-7891b902]{padding-bottom:1rem}.table-sort.el-table th.el-table__cell.is-leaf{border-bottom:0}.table-sort.el-table .el-table__inner-wrapper:before{height:0}.home-list-wrap[data-v-3d1c480c]{padding:1rem}.home-list-wrap .page[data-v-3d1c480c]{padding-top:1rem}.home-list-wrap .page-wrap[data-v-3d1c480c]{display:inline-block}
|
@@ -1 +0,0 @@
|
||||
.action-wrap[data-v-3cb5be52]{font-size:1.3rem;padding:1.5rem}
|
1
linker.tray.win/web/css/57.713ee644.css
Normal file
@@ -0,0 +1 @@
|
||||
.action-wrap[data-v-7e144fd0]{font-size:1.3rem;padding:1.5rem}
|
1
linker.tray.win/web/css/857.4af25108.css
Normal file
@@ -0,0 +1 @@
|
||||
.delay[data-v-3a883663]{margin-left:3rem}.servers-wrap[data-v-57813473]{padding:1rem;font-size:1.3rem;color:#555}.servers-wrap a[data-v-57813473]{color:#333}.el-checkbox[data-v-57813473]{vertical-align:middle;margin-right:1rem}
|
@@ -1 +0,0 @@
|
||||
.delay[data-v-3a883663]{margin-left:3rem}.servers-wrap[data-v-11926c68]{padding:1rem;font-size:1.3rem;color:#555}.servers-wrap a[data-v-11926c68]{color:#333}.el-checkbox[data-v-11926c68]{vertical-align:middle;margin-right:1rem}
|
@@ -1 +1 @@
|
||||
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>linker.web</title><script defer="defer" src="js/chunk-vendors.7b81ea90.js"></script><script defer="defer" src="js/app.1a3b60a6.js"></script><link href="css/chunk-vendors.d8267b33.css" rel="stylesheet"><link href="css/app.1dca501b.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but linker.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
||||
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>linker.web</title><script defer="defer" src="js/chunk-vendors.7b81ea90.js"></script><script defer="defer" src="js/app.d49dc293.js"></script><link href="css/chunk-vendors.d8267b33.css" rel="stylesheet"><link href="css/app.1dca501b.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but linker.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
1
linker.tray.win/web/js/276.b7efbea0.js
Normal file
1
linker.tray.win/web/js/316.71786489.js
Normal file
1
linker.tray.win/web/js/321.3587d77b.js
Normal file
1
linker.tray.win/web/js/352.053f3b66.js
Normal file
@@ -1 +0,0 @@
|
||||
"use strict";(self["webpackChunklinker_web"]=self["webpackChunklinker_web"]||[]).push([[402],{402:function(e,t,n){n.r(t),n.d(t,{default:function(){return h}});var r=n(6768);const o={class:"action-wrap"},s={class:"t-c"};function a(e,t,n,a,l,c){const i=(0,r.g2)("el-input"),u=(0,r.g2)("el-button"),d=(0,r.g2)("el-card");return(0,r.uX)(),(0,r.CE)("div",o,[(0,r.bF)(d,{shadow:"never"},{header:(0,r.k6)((()=>[(0,r.eW)("设置定义验证的静态Json参数")])),footer:(0,r.k6)((()=>[(0,r.Lk)("div",s,[(0,r.bF)(u,{type:"success",onClick:a.handleSave},{default:(0,r.k6)((()=>[(0,r.eW)("确定更改")])),_:1},8,["onClick"])])])),default:(0,r.k6)((()=>[(0,r.Lk)("div",null,[(0,r.bF)(i,{modelValue:a.state.list,"onUpdate:modelValue":t[0]||(t[0]=e=>a.state.list=e),rows:10,type:"textarea",resize:"none",onChange:a.handleSave},null,8,["modelValue","onChange"])])])),_:1})])}var l=n(4);const c=e=>(0,l.zG)("action/SetServerArgs",e);var i=n(3830),u=n(1219),d=n(144),v={setup(e){const t=(0,i.B)(),n=(0,d.Kh)({list:t.value.config.Client.Action.Args[t.value.config.Client.Server.Host]||""}),r=()=>{try{if(n.list&&"object"!=typeof JSON.parse(n.list))return void u.nk.error("Json格式错误")}catch(r){return void u.nk.error("Json格式错误")}const e={};e[t.value.config.Client.Server.Host]=n.list,c(e).then((()=>{u.nk.success("已操作")})).catch((e=>{console.log(e),u.nk.error("操作失败")}))};return{state:n,handleSave:r}}},k=n(1241);const f=(0,k.A)(v,[["render",a],["__scopeId","data-v-3cb5be52"]]);var h=f}}]);
|
1
linker.tray.win/web/js/57.d154f935.js
Normal file
@@ -0,0 +1 @@
|
||||
"use strict";(self["webpackChunklinker_web"]=self["webpackChunklinker_web"]||[]).push([[57],{2057:function(e,n,t){t.r(n),t.d(n,{default:function(){return g}});var r=t(6768);const o={class:"action-wrap"},s={class:"t-c"};function a(e,n,t,a,l,c){const i=(0,r.g2)("el-input"),u=(0,r.g2)("el-button"),d=(0,r.g2)("el-card");return(0,r.uX)(),(0,r.CE)("div",o,[(0,r.bF)(d,{shadow:"never"},{header:(0,r.k6)((()=>[(0,r.eW)("设置定义验证的静态Json参数")])),footer:(0,r.k6)((()=>[(0,r.Lk)("div",s,[(0,r.bF)(u,{type:"success",onClick:a.handleSave},{default:(0,r.k6)((()=>[(0,r.eW)("确定更改")])),_:1},8,["onClick"])])])),default:(0,r.k6)((()=>[(0,r.Lk)("div",null,[(0,r.bF)(i,{modelValue:a.state.list,"onUpdate:modelValue":n[0]||(n[0]=e=>a.state.list=e),rows:10,type:"textarea",resize:"none",onChange:a.handleSave},null,8,["modelValue","onChange"])])])),_:1})])}var l=t(4);const c=e=>(0,l.zG)("action/SetServerArgs",e);var i=t(3830),u=t(1219),d=t(144),v={setup(e){const n=(0,i.B)(),t=(0,d.Kh)({list:n.value.config.Client.Action.Args[n.value.config.Client.Server.Host]||""}),r=()=>{try{if(t.list&&"object"!=typeof JSON.parse(t.list))return void u.nk.error("Json格式错误")}catch(r){return void u.nk.error("Json格式错误")}const e=JSON.parse(JSON.stringify(n.value.config.Client.Action.Args));e[n.value.config.Client.Server.Host]=t.list,c(e).then((()=>{u.nk.success("已操作")})).catch((e=>{console.log(e),u.nk.error("操作失败")}))};return{state:t,handleSave:r}}},k=t(1241);const f=(0,k.A)(v,[["render",a],["__scopeId","data-v-7e144fd0"]]);var g=f}}]);
|
@@ -1 +1 @@
|
||||
"use strict";(self["webpackChunklinker_web"]=self["webpackChunklinker_web"]||[]).push([[966],{673:function(e,a,t){t.r(a),t.d(a,{default:function(){return M}});var n=t(6768);const l={class:"net-wrap app-wrap"},s={class:"inner absolute flex flex-column flex-nowrap"},r={class:"head"},i={class:"body flex-1 relative"},u={class:"status"};function c(e,a,t,c,d,o){const g=(0,n.g2)("Head"),p=(0,n.g2)("List"),v=(0,n.g2)("Status");return(0,n.uX)(),(0,n.CE)("div",l,[(0,n.Lk)("div",s,[(0,n.Lk)("div",r,[(0,n.bF)(g)]),(0,n.Lk)("div",i,[(0,n.bF)(p)]),(0,n.Lk)("div",u,[(0,n.bF)(v,{config:!1})])])])}t(4114);const d=e=>((0,n.Qi)("data-v-3bb95ac8"),e=e(),(0,n.jt)(),e),o={class:"head-wrap"},g={class:"tools flex"},p=d((()=>(0,n.Lk)("span",{class:"label"},"服务器 ",-1))),v=d((()=>(0,n.Lk)("span",{class:"flex-1"},null,-1))),h={style:{"margin-left":"1rem"}};function f(e,a,t,l,s,r){const i=(0,n.g2)("el-option"),u=(0,n.g2)("el-select"),c=(0,n.g2)("Refresh"),d=(0,n.g2)("el-icon"),f=(0,n.g2)("el-button"),k=(0,n.g2)("Background");return(0,n.uX)(),(0,n.CE)("div",o,[(0,n.Lk)("div",g,[p,(0,n.bF)(u,{modelValue:l.state.server,"onUpdate:modelValue":a[0]||(a[0]=e=>l.state.server=e),placeholder:"服务器",style:{width:"16rem"},size:"small"},{default:(0,n.k6)((()=>[((0,n.uX)(!0),(0,n.CE)(n.FK,null,(0,n.pI)(l.state.servers,(e=>((0,n.uX)(),(0,n.Wv)(i,{key:e.Host,label:e.Name,value:e.Host},null,8,["label","value"])))),128))])),_:1},8,["modelValue"]),v,(0,n.bF)(f,{size:"small",onClick:l.handleRefresh},{default:(0,n.k6)((()=>[(0,n.eW)(" 刷新(F5)"),(0,n.bF)(d,null,{default:(0,n.k6)((()=>[(0,n.bF)(c)])),_:1})])),_:1},8,["onClick"]),(0,n.Lk)("div",h,[(0,n.bF)(k,{name:"net"})])])])}var k=t(3830),b=t(144),m=t(7477),C=t(5096),L={components:{Edit:m.ffu,Refresh:m.C42,Background:C.A},setup(){const e=(0,k.B)(),a=(0,b.Kh)({server:"linker.snltty.com:1802",servers:[]});(0,n.wB)((()=>e.value.config.Client.Servers),(()=>{a.servers=(e.value.config.Client.Servers||[]).slice(0,1),a.server=e.value.config.Client.Server.Host}));const t=()=>{window.location.reload()};return{state:a,handleRefresh:t}}},w=t(1241);const S=(0,w.A)(L,[["render",f],["__scopeId","data-v-3bb95ac8"]]);var _=S;const F=e=>((0,n.Qi)("data-v-b6ab4f06"),e=e(),(0,n.jt)(),e),x={class:"net-list-wrap flex flex-column absolute"},z={class:"flex-1 scrollbar"},E={class:"flex"},I=F((()=>(0,n.Lk)("div",{class:"flex-1"},null,-1))),T={class:"tuntap"},A={class:"page t-c"},B={class:"page-wrap t-c"};function P(e,a,t,l,s,r){const i=(0,n.g2)("DeviceName"),u=(0,n.g2)("UpdaterBtn"),c=(0,n.g2)("TuntapShow"),d=(0,n.g2)("el-pagination");return(0,n.uX)(),(0,n.CE)("div",x,[(0,n.Lk)("div",z,[(0,n.Lk)("ul",null,[((0,n.uX)(!0),(0,n.CE)(n.FK,null,(0,n.pI)(l.devices.page.List,((e,a)=>((0,n.uX)(),(0,n.CE)("li",{key:a},[(0,n.Lk)("dl",null,[(0,n.Lk)("dt",E,[(0,n.Lk)("div",null,[(0,n.bF)(i,{item:e},null,8,["item"])]),I,(0,n.Lk)("div",null,[(0,n.bF)(u,{config:!1,item:e},null,8,["item"])])]),(0,n.Lk)("dd",T,[l.tuntap.list[e.MachineId]?((0,n.uX)(),(0,n.Wv)(c,{key:0,item:e},null,8,["item"])):(0,n.Q3)("",!0)])])])))),128))])]),(0,n.Lk)("div",A,[(0,n.Lk)("div",B,[(0,n.bF)(d,{size:"small",background:"",layout:"prev,pager, next","pager-count":5,total:l.devices.page.Count,"page-size":l.devices.page.Request.Size,"current-page":l.devices.page.Request.Page,onCurrentChange:l.handlePageChange,onSizeChange:l.handlePageSizeChange,"page-sizes":[10,20,50,100,255]},null,8,["total","page-size","current-page","onCurrentChange","onSizeChange"])])])])}var y=t(8104),X=t(7985),R=t(9383),D=t(167),U=t(3347),H=t(2950),N={components:{StarFilled:m.BQ2,UpdaterBtn:D.A,DeviceName:U.A,TuntapShow:H.A},setup(e){(0,k.B)();const a=(0,b.Kh)({}),{devices:t,machineId:l,_getSignList:s,_getSignList1:r,handleDeviceEdit:i,handlePageChange:u,handlePageSizeChange:c,handleDel:d,clearDevicesTimeout:o}=(0,X.r)(),{tuntap:g,_getTuntapInfo:p,handleTuntapRefresh:v,clearTuntapTimeout:h,handleTuntapEdit:f,sortTuntapIP:m}=(0,y.O)(),{_getUpdater:C,_subscribeUpdater:L,clearUpdaterTimeout:w}=(0,R.d)();return(0,n.sV)((()=>{u(),v(),s(),r(),p(),C(),L()})),(0,n.hi)((()=>{o(),h(),w()})),{state:a,devices:t,machineId:l,handlePageChange:u,handlePageSizeChange:c,tuntap:g}}};const V=(0,w.A)(N,[["render",P],["__scopeId","data-v-b6ab4f06"]]);var K=V,Q=t(3269),W=t(1387),j={components:{Head:_,List:K,Status:Q.A},setup(){document.addEventListener("contextmenu",(function(e){e.preventDefault()}));const e=(0,k.B)(),a=(0,W.rd)();return(0,n.sV)((()=>{0==e.value.hasAccess("NetManager")&&a.push({name:"NoPermission"})})),{}}};const q=(0,w.A)(j,[["render",c],["__scopeId","data-v-6a3f3b43"]]);var M=q}}]);
|
||||
"use strict";(self["webpackChunklinker_web"]=self["webpackChunklinker_web"]||[]).push([[836],{673:function(e,a,t){t.r(a),t.d(a,{default:function(){return M}});var n=t(6768);const l={class:"net-wrap app-wrap"},s={class:"inner absolute flex flex-column flex-nowrap"},r={class:"head"},i={class:"body flex-1 relative"},u={class:"status"};function c(e,a,t,c,d,o){const g=(0,n.g2)("Head"),p=(0,n.g2)("List"),v=(0,n.g2)("Status");return(0,n.uX)(),(0,n.CE)("div",l,[(0,n.Lk)("div",s,[(0,n.Lk)("div",r,[(0,n.bF)(g)]),(0,n.Lk)("div",i,[(0,n.bF)(p)]),(0,n.Lk)("div",u,[(0,n.bF)(v,{config:!1})])])])}t(4114);const d=e=>((0,n.Qi)("data-v-3bb95ac8"),e=e(),(0,n.jt)(),e),o={class:"head-wrap"},g={class:"tools flex"},p=d((()=>(0,n.Lk)("span",{class:"label"},"服务器 ",-1))),v=d((()=>(0,n.Lk)("span",{class:"flex-1"},null,-1))),h={style:{"margin-left":"1rem"}};function f(e,a,t,l,s,r){const i=(0,n.g2)("el-option"),u=(0,n.g2)("el-select"),c=(0,n.g2)("Refresh"),d=(0,n.g2)("el-icon"),f=(0,n.g2)("el-button"),k=(0,n.g2)("Background");return(0,n.uX)(),(0,n.CE)("div",o,[(0,n.Lk)("div",g,[p,(0,n.bF)(u,{modelValue:l.state.server,"onUpdate:modelValue":a[0]||(a[0]=e=>l.state.server=e),placeholder:"服务器",style:{width:"16rem"},size:"small"},{default:(0,n.k6)((()=>[((0,n.uX)(!0),(0,n.CE)(n.FK,null,(0,n.pI)(l.state.servers,(e=>((0,n.uX)(),(0,n.Wv)(i,{key:e.Host,label:e.Name,value:e.Host},null,8,["label","value"])))),128))])),_:1},8,["modelValue"]),v,(0,n.bF)(f,{size:"small",onClick:l.handleRefresh},{default:(0,n.k6)((()=>[(0,n.eW)(" 刷新(F5)"),(0,n.bF)(d,null,{default:(0,n.k6)((()=>[(0,n.bF)(c)])),_:1})])),_:1},8,["onClick"]),(0,n.Lk)("div",h,[(0,n.bF)(k,{name:"net"})])])])}var k=t(3830),b=t(144),m=t(7477),C=t(5096),L={components:{Edit:m.ffu,Refresh:m.C42,Background:C.A},setup(){const e=(0,k.B)(),a=(0,b.Kh)({server:"linker.snltty.com:1802",servers:[]});(0,n.wB)((()=>e.value.config.Client.Servers),(()=>{a.servers=(e.value.config.Client.Servers||[]).slice(0,1),a.server=e.value.config.Client.Server.Host}));const t=()=>{window.location.reload()};return{state:a,handleRefresh:t}}},w=t(1241);const S=(0,w.A)(L,[["render",f],["__scopeId","data-v-3bb95ac8"]]);var _=S;const F=e=>((0,n.Qi)("data-v-b6ab4f06"),e=e(),(0,n.jt)(),e),x={class:"net-list-wrap flex flex-column absolute"},z={class:"flex-1 scrollbar"},E={class:"flex"},I=F((()=>(0,n.Lk)("div",{class:"flex-1"},null,-1))),T={class:"tuntap"},A={class:"page t-c"},B={class:"page-wrap t-c"};function P(e,a,t,l,s,r){const i=(0,n.g2)("DeviceName"),u=(0,n.g2)("UpdaterBtn"),c=(0,n.g2)("TuntapShow"),d=(0,n.g2)("el-pagination");return(0,n.uX)(),(0,n.CE)("div",x,[(0,n.Lk)("div",z,[(0,n.Lk)("ul",null,[((0,n.uX)(!0),(0,n.CE)(n.FK,null,(0,n.pI)(l.devices.page.List,((e,a)=>((0,n.uX)(),(0,n.CE)("li",{key:a},[(0,n.Lk)("dl",null,[(0,n.Lk)("dt",E,[(0,n.Lk)("div",null,[(0,n.bF)(i,{item:e},null,8,["item"])]),I,(0,n.Lk)("div",null,[(0,n.bF)(u,{config:!1,item:e},null,8,["item"])])]),(0,n.Lk)("dd",T,[l.tuntap.list[e.MachineId]?((0,n.uX)(),(0,n.Wv)(c,{key:0,item:e},null,8,["item"])):(0,n.Q3)("",!0)])])])))),128))])]),(0,n.Lk)("div",A,[(0,n.Lk)("div",B,[(0,n.bF)(d,{size:"small",background:"",layout:"prev,pager, next","pager-count":5,total:l.devices.page.Count,"page-size":l.devices.page.Request.Size,"current-page":l.devices.page.Request.Page,onCurrentChange:l.handlePageChange,onSizeChange:l.handlePageSizeChange,"page-sizes":[10,20,50,100,255]},null,8,["total","page-size","current-page","onCurrentChange","onSizeChange"])])])])}var y=t(8104),X=t(7985),R=t(9383),D=t(167),U=t(3347),H=t(2950),N={components:{StarFilled:m.BQ2,UpdaterBtn:D.A,DeviceName:U.A,TuntapShow:H.A},setup(e){(0,k.B)();const a=(0,b.Kh)({}),{devices:t,machineId:l,_getSignList:s,_getSignList1:r,handleDeviceEdit:i,handlePageChange:u,handlePageSizeChange:c,handleDel:d,clearDevicesTimeout:o}=(0,X.r)(),{tuntap:g,_getTuntapInfo:p,handleTuntapRefresh:v,clearTuntapTimeout:h,handleTuntapEdit:f,sortTuntapIP:m}=(0,y.O)(),{_getUpdater:C,_subscribeUpdater:L,clearUpdaterTimeout:w}=(0,R.d)();return(0,n.sV)((()=>{u(),v(),s(),r(),p(),C(),L()})),(0,n.hi)((()=>{o(),h(),w()})),{state:a,devices:t,machineId:l,handlePageChange:u,handlePageSizeChange:c,tuntap:g}}};const V=(0,w.A)(N,[["render",P],["__scopeId","data-v-b6ab4f06"]]);var K=V,Q=t(3847),W=t(1387),j={components:{Head:_,List:K,Status:Q.A},setup(){document.addEventListener("contextmenu",(function(e){e.preventDefault()}));const e=(0,k.B)(),a=(0,W.rd)();return(0,n.sV)((()=>{0==e.value.hasAccess("NetManager")&&a.push({name:"NoPermission"})})),{}}};const q=(0,w.A)(j,[["render",c],["__scopeId","data-v-6a3f3b43"]]);var M=q}}]);
|
1
linker.tray.win/web/js/848.3d739e8d.js
Normal file
1
linker.tray.win/web/js/952.d90fc618.js
Normal file
1
linker.tray.win/web/js/app.d49dc293.js
Normal file
@@ -537,7 +537,6 @@ namespace linker.tunnel
|
||||
connection = await ConnectAsync(remoteMachineId, transactionId, denyProtocols);
|
||||
if (connection != null)
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
await Task.Delay(i * 3000);
|
||||
|
@@ -26,5 +26,5 @@ export const refreshForward = () => {
|
||||
}
|
||||
|
||||
export const testTargetForwardInfo = (machineid) => {
|
||||
return sendWebsocketMsg('forward/TestTarget', machineid);
|
||||
return sendWebsocketMsg('forward/Test', machineid);
|
||||
}
|
Before Width: | Height: | Size: 58 KiB |
BIN
linker.web/src/assets/qr.jpg
Normal file
After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 43 KiB |
@@ -126,8 +126,8 @@
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import { onMounted,reactive, watch } from 'vue';
|
||||
import { getForwardInfo, removeForwardInfo, addForwardInfo ,getForwardIpv4 } from '@/apis/forward'
|
||||
import { onMounted,onUnmounted,reactive, watch } from 'vue';
|
||||
import { getForwardInfo, removeForwardInfo, addForwardInfo ,getForwardIpv4,testTargetForwardInfo } from '@/apis/forward'
|
||||
import { ElMessage } from 'element-plus';
|
||||
import {WarnTriangleFilled,Delete} from '@element-plus/icons-vue'
|
||||
import { injectGlobalData } from '@/provide';
|
||||
@@ -165,6 +165,14 @@ export default {
|
||||
}
|
||||
});
|
||||
|
||||
const _testTargetForwardInfo = ()=>{
|
||||
testTargetForwardInfo(forward.value.machineId).then((res)=>{
|
||||
state.timer = setTimeout(_testTargetForwardInfo,1000);
|
||||
}).catch(()=>{
|
||||
state.timer = setTimeout(_testTargetForwardInfo,1000);
|
||||
});
|
||||
}
|
||||
|
||||
const _getForwardIpv4 = ()=>{
|
||||
getForwardIpv4().then((res)=>{
|
||||
res.splice(0,0,'127.0.0.1');
|
||||
@@ -265,6 +273,10 @@ export default {
|
||||
onMounted(()=>{
|
||||
_getForwardInfo();
|
||||
_getForwardIpv4();
|
||||
_testTargetForwardInfo();
|
||||
});
|
||||
onUnmounted(()=>{
|
||||
clearTimeout(state.timer);
|
||||
});
|
||||
|
||||
return {
|
||||
|
@@ -107,7 +107,6 @@ export default {
|
||||
}
|
||||
});
|
||||
const _testLocalSForwardInfo = ()=>{
|
||||
console.log(sforward.value.machineid);
|
||||
testLocalSForwardInfo(sforward.value.machineid).then((res)=>{
|
||||
state.timerTestLocal = setTimeout(_testLocalSForwardInfo,1000);
|
||||
}).catch(()=>{
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { getForwardCountInfo, refreshForward, testTargetForwardInfo } from "@/apis/forward";
|
||||
import { getForwardCountInfo, refreshForward } from "@/apis/forward";
|
||||
import { injectGlobalData } from "@/provide";
|
||||
import { inject, provide, ref } from "vue";
|
||||
|
||||
|
@@ -13,10 +13,9 @@
|
||||
<div class="api"><Api :config="config"></Api></div>
|
||||
<div class="server"><Server :config="config"></Server></div>
|
||||
|
||||
<el-dialog v-model="state.showPay" title="赞助linker" width="300" top="1vh">
|
||||
<el-dialog v-model="state.showPay" title="赞助linker" width="400">
|
||||
<div class="pay">
|
||||
<img src="@/assets/wechat.jpg" alt=""/>
|
||||
<img src="@/assets/alipay.jpg" alt=""/>
|
||||
<img src="@/assets/qr.jpg" alt=""/>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
@@ -3,7 +3,6 @@ using System.ServiceProcess;
|
||||
using System.Diagnostics;
|
||||
using linker.messenger.entry;
|
||||
using linker.messenger;
|
||||
using linker.messenger.api;
|
||||
|
||||
namespace linker
|
||||
{
|
||||
@@ -52,7 +51,12 @@ namespace linker
|
||||
{
|
||||
LinkerMessengerEntry.Initialize();
|
||||
LinkerMessengerEntry.Build();
|
||||
LinkerMessengerEntry.Setup();
|
||||
|
||||
ICommonStore commonStore = LinkerMessengerEntry.GetService<ICommonStore>();
|
||||
if((commonStore.Modes & CommonModes.Client) == CommonModes.Client)
|
||||
if((commonStore.Modes & CommonModes.Server) == CommonModes.Server)
|
||||
|
||||
LinkerMessengerEntry.Setup(ExcludeModule.None);
|
||||
|
||||
LoggerHelper.Instance.Warning($"current version : {VersionHelper.version}");
|
||||
LoggerHelper.Instance.Warning($"linker env is docker : {Environment.GetEnvironmentVariable("SNLTTY_LINKER_IS_DOCKER")}");
|
||||
|
@@ -1,5 +1,5 @@
|
||||
v1.6.4
|
||||
2025-01-02 17:30:25
|
||||
2025-01-04 18:18:23
|
||||
1. 优化代码,解耦,简单几步将打洞和中继集成到你自己的项目中
|
||||
2. 增加了组件组合demo
|
||||
3. 测试中,不要更,不要更,不要更
|