This commit is contained in:
snltty
2025-01-02 15:55:00 +08:00
parent 0ad8e6ebfa
commit a5cc3c5110
52 changed files with 829 additions and 219 deletions

View File

@@ -51,7 +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
- [x] 集成linker使用`linker.messenger.entry`入口库,轻松集成到你的项目中
## 大概长这个样子

View File

@@ -34,7 +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
- [x] 集成linker使用`linker.messenger.entry`入口库,轻松集成到你的项目中
#### 1.3、加入组织

View File

@@ -1,108 +0,0 @@
---
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

@@ -0,0 +1,51 @@
---
sidebar_position: 1
---
# 8.1、集成linker
:::tip[说明]
1. 在你的.NET8.0+项目中集成linker
2. 在nuget安装`linker.messenger.entry`
```
//初始化
LinkerMessengerEntry.Initialize();
//在这里可以注入你自己的内容,比如覆盖一下公共配置存储库的实现
//LinkerMessengerEntry.AddService<ICommonStore, MyCommonStore>();
//构建
LinkerMessengerEntry.Build();
//在build之后可以获取服务做一些操作
//比如获取一下公共配置设置运行模式为client+server
//ICommonStore commonStore = LinkerMessengerEntry.GetService<ICommonStore>();
//commonStore.SetModes( CommonModes.Client | CommonModes.Server);
//commonStore.Confirm();
//比如不启用api和网页
//IApiStore apiStore = LinkerMessengerEntry.GetService<IApiStore>();
//apiStore.SetApiPort(0);
//apiStore.SetWebPort(0);
//apiStore.Confirm();
//启动
LinkerMessengerEntry.Setup();
```
:::
# 1、一些配置接口
:::tip[说明]
1. 你可以在initialize之后注入覆盖这些实现和build之后获取这些接口来操作配置
2. 客户端服务端公共配置`ICommonStore`
3. 自定义验证Action的配置客户端`IActionClientStore`,服务端`IActionServerStore`
4. 管理api配置`IApiStore`,权限设置,`IAccessStore`
5. 端口转发配置 `IForwardClientStore`(增删改使用`ForwardTransfer`操作)
6. 服务端监听配置 `IListenStore`
7. 日志配置 `ILoggerStore`
8. 中继配置,客户端`IRelayClientStore`,服务端`IRelayServerStore`,服务端中继节点`IRelayServerNodeStore`,服务端中继主机`IRelayServerMasterStore`
9. 服务器穿透,客户端`ISForwardClientStore`(增删改使用`SForwardClientTransfer`操作),服务端`ISForwardServerStore`
10. 登录相关配置,客户端`ISignInClientStore`,服务端`ISignInServerStore`
11. socks5配置`ISocks5Store`
12. 打洞配置`ITunnelClientStore`
13. 虚拟网卡配置`ITuntapClientStore`
14. 自动更新,公共配置`IUpdaterCommonStore`,客户端`IUpdaterClientStore`,服务端`IUpdaterServerStore`
:::

View File

@@ -2,7 +2,7 @@
sidebar_position: 2
---
# 8.2、独使用虚拟网卡
# 8.2、独使用虚拟网卡
## 1、说明

View File

@@ -6,9 +6,9 @@ namespace linker.messenger.action
{
public sealed class ActionApiController : IApiController
{
private readonly IActionStore actionStore;
private readonly IActionClientStore actionStore;
public ActionApiController(IActionStore actionStore)
public ActionApiController(IActionClientStore actionStore)
{
this.actionStore = actionStore;
}
@@ -18,13 +18,13 @@ namespace linker.messenger.action
public bool SetArgs(ApiControllerParamsInfo param)
{
actionStore.SetActionArg(param.Content);
return true;
return actionStore.Confirm();
}
[Access(AccessValue.Action)]
public bool SetServerArgs(ApiControllerParamsInfo param)
{
actionStore.SetActionArgs(param.Content.DeJson<Dictionary<string, string>>());
return true;
return actionStore.Confirm();
}
}

View File

@@ -0,0 +1,34 @@
namespace linker.messenger.action
{
public sealed class ActionInfo
{
public string Arg { get; set; } = string.Empty;
public Dictionary<string, string> Args { get; set; } = new Dictionary<string, string>();
}
public interface IActionClientStore
{
/// <summary>
/// 设置动态验证参数,优先使用
/// </summary>
/// <param name="action"></param>
public void SetActionArg(string action);
/// <summary>
/// 设置静态验证参数,动态参数为空时使用
/// </summary>
/// <param name="actions">action参数列表host->arg不同的服务器不同的参数</param>
public void SetActionArgs(Dictionary<string, string> actions);
/// <summary>
/// 从配置里获取验证参数添加到args
/// </summary>
/// <param name="host">当前服务器地址</param>
/// <param name="args">一个字典</param>
/// <returns></returns>
public bool TryAddActionArg(string host, Dictionary<string, string> args);
/// <summary>
/// 提交更新
/// </summary>
/// <returns></returns>
public bool Confirm();
}
}

View File

@@ -0,0 +1,52 @@
namespace linker.messenger.action
{
public interface IActionServerStore
{
/// <summary>
/// 登录验证地址
/// </summary>
public string SignInActionUrl{ get; }
/// <summary>
/// 中继验证地址
/// </summary>
public string RelayActionUrl { get; }
/// <summary>
/// 内网穿透验证地址
/// </summary>
public string SForwardActionUrl { get; }
/// <summary>
/// 登录验证地址
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public bool SetSignInActionUrl(string url);
/// <summary>
/// 中继验证地址
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public bool SetRelayActionUrl(string url);
/// <summary>
/// 登录验证地址
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public bool SetSForwardActionUrl(string url);
/// <summary>
/// 从args里获取验证参数
/// </summary>
/// <param name="args"></param>
/// <param name="str"></param>
/// <param name="machineKey"></param>
/// <returns></returns>
public bool TryGetActionArg(Dictionary<string, string> args, out string str, out string machineKey);
/// <summary>
/// 提交更新
/// </summary>
/// <returns></returns>
public bool Confirm();
}
}

View File

@@ -1,18 +0,0 @@
namespace linker.messenger.action
{
public sealed class ActionInfo
{
public string Arg { get; set; } = string.Empty;
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

@@ -104,12 +104,13 @@ namespace linker.messenger.action
public sealed class SignInArgsAction : JsonArgReplace, ISignInArgs
{
private readonly ActionTransfer actionTransfer;
private readonly IActionStore actionStore;
public SignInArgsAction(ActionTransfer actionTransfer, IActionStore actionStore)
private readonly IActionClientStore actionStore;
private readonly IActionServerStore actionServerStore;
public SignInArgsAction(ActionTransfer actionTransfer, IActionClientStore actionStore, IActionServerStore actionServerStore)
{
this.actionTransfer = actionTransfer;
this.actionStore = actionStore;
this.actionServerStore = actionServerStore;
}
public async Task<string> Invoke(string host, Dictionary<string, string> args)
@@ -121,9 +122,9 @@ namespace linker.messenger.action
public async Task<string> Validate(SignInfo signInfo, SignCacheInfo cache)
{
if (string.IsNullOrWhiteSpace(actionStore.SignInActionUrl) == false)
if (string.IsNullOrWhiteSpace(actionServerStore.SignInActionUrl) == false)
{
if (actionStore.TryGetActionArg(signInfo.Args, out string str, out string machineKey) == false)
if (actionServerStore.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 +140,7 @@ namespace linker.messenger.action
IPAddress = signInfo.Connection.Address.Address
}
};
return await actionTransfer.ExcuteActions(Replace(replace, str), actionStore.SignInActionUrl);
return await actionTransfer.ExcuteActions(Replace(replace, str), actionServerStore.SignInActionUrl);
}
return string.Empty;
@@ -149,22 +150,22 @@ namespace linker.messenger.action
public sealed class RelayValidatorAction : JsonArgReplace, IRelayServerValidator
{
private readonly ActionTransfer actionTransfer;
private readonly IActionStore actionStore;
public RelayValidatorAction(ActionTransfer actionTransfer, IActionStore actionStore)
private readonly IActionServerStore actionServerStore;
public RelayValidatorAction(ActionTransfer actionTransfer, IActionServerStore actionServerStore)
{
this.actionTransfer = actionTransfer;
this.actionStore = actionStore;
this.actionServerStore = actionServerStore;
}
public async Task<string> Validate(linker.messenger.relay.client.transport.RelayInfo relayInfo, SignCacheInfo fromMachine, SignCacheInfo toMachine)
{
if (string.IsNullOrWhiteSpace(actionStore.RelayActionUrl) == false)
if (string.IsNullOrWhiteSpace(actionServerStore.RelayActionUrl) == false)
{
if (actionStore.TryGetActionArg(fromMachine.Args, out string str, out string machineKey) == false)
if (actionServerStore.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 && actionStore.TryGetActionArg(toMachine.Args, out string str1, out string machineKey1) == false)
if (toMachine != null && actionServerStore.TryGetActionArg(toMachine.Args, out string str1, out string machineKey1) == false)
{
return $"relay action URL exists, but [{toMachine.MachineName}]e action value is not configured";
}
@@ -189,7 +190,7 @@ namespace linker.messenger.action
IPAddress = fromMachine.Connection.Address.Address,
}
};
return await actionTransfer.ExcuteActions(Replace(replace, str), actionStore.RelayActionUrl);
return await actionTransfer.ExcuteActions(Replace(replace, str), actionServerStore.RelayActionUrl);
}
return string.Empty;
}
@@ -198,18 +199,18 @@ namespace linker.messenger.action
public sealed class SForwardValidatorAction : JsonArgReplace, ISForwardValidator
{
private readonly ActionTransfer actionTransfer;
private readonly IActionStore actionStore;
public SForwardValidatorAction(ActionTransfer actionTransfer, IActionStore actionStore)
private readonly IActionServerStore actionServerStore;
public SForwardValidatorAction(ActionTransfer actionTransfer, IActionServerStore actionServerStore)
{
this.actionTransfer = actionTransfer;
this.actionStore = actionStore;
this.actionServerStore = actionServerStore;
}
public async Task<string> Validate(SignCacheInfo cache, SForwardAddInfo sForwardAddInfo)
{
if (string.IsNullOrWhiteSpace(actionStore.SForwardActionUrl) == false)
if (string.IsNullOrWhiteSpace(actionServerStore.SForwardActionUrl) == false)
{
if (actionStore.TryGetActionArg(cache.Args, out string str, out string machineKey) == false)
if (actionServerStore.TryGetActionArg(cache.Args, out string str, out string machineKey) == false)
{
return $"sforward action URL exists, but [{cache.MachineName}] action value is not configured";
}
@@ -230,7 +231,7 @@ namespace linker.messenger.action
IPAddress = cache.Connection.Address.Address
}
};
return await actionTransfer.ExcuteActions(Replace(replace, str), actionStore.SForwardActionUrl);
return await actionTransfer.ExcuteActions(Replace(replace, str), actionServerStore.SForwardActionUrl);
}
return string.Empty;
}

View File

@@ -2,14 +2,32 @@
{
public interface IAccessStore
{
/// <summary>
/// 权限值
/// </summary>
public AccessValue Access { get; }
/// <summary>
/// 发生变化
/// </summary>
public Action OnChanged { get; set; }
/// <summary>
/// 设置权限
/// </summary>
/// <param name="info"></param>
public void SetAccess(AccessUpdateInfo info);
/// <summary>
/// 合并权限
/// </summary>
/// <param name="access">将access与自身拥有的权限进行合并</param>
/// <returns></returns>
public AccessValue AssignAccess(AccessValue access);
public bool HasAccess(AccessValue clientManagerAccess);
/// <summary>
/// 是否拥有指定权限
/// </summary>
/// <param name="access"></param>
/// <returns></returns>
public bool HasAccess(AccessValue access);
}
}

View File

@@ -25,5 +25,41 @@ namespace linker.messenger.api
public interface IApiStore
{
public ApiClientInfo Info { get; }
/// <summary>
/// 设置
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public bool Set(ApiClientInfo info);
/// <summary>
/// 设置接口端口
/// </summary>
/// <param name="port"></param>
/// <returns></returns>
public bool SetApiPort(int port);
/// <summary>
/// 设置接口密码
/// </summary>
/// <param name="password"></param>
/// <returns></returns>
public bool SetApiPassword(string password);
/// <summary>
/// 设置网页端口
/// </summary>
/// <param name="port"></param>
/// <returns></returns>
public bool SetWebPort(int port);
/// <summary>
/// 设置网页根目录
/// </summary>
/// <param name="rootPath"></param>
/// <returns></returns>
public bool SetWebRoot(string rootPath);
/// <summary>
/// 提交保存
/// </summary>
/// <returns></returns>
public bool Confirm();
}
}

View File

@@ -27,6 +27,7 @@ namespace linker.messenger.entry
private static ServiceProvider serviceProvider;
private static OperatingManager inited = new OperatingManager();
private static OperatingManager builded = new OperatingManager();
private static OperatingManager setuped = new OperatingManager();
/// <summary>
/// 开始初始化
@@ -85,7 +86,6 @@ namespace linker.messenger.entry
//序列化 MemoryPack
.AddSerializerMemoryPack();
}
/// <summary>
/// 注入
/// </summary>
@@ -105,7 +105,7 @@ namespace linker.messenger.entry
}
/// <summary>
/// 运行起来
/// 构建
/// </summary>
/// <returns></returns>
public static void Build()
@@ -114,8 +114,27 @@ namespace linker.messenger.entry
serviceProvider = serviceCollection.BuildServiceProvider();
serviceProvider.UseMessenger().UseStoreFile().UseSerializerMemoryPack();
}
/// <summary>
/// 获取服务
/// </summary>
/// <typeparam name="TService"></typeparam>
/// <returns></returns>
public static TService GetService<TService>() where TService : class
{
return serviceProvider.GetService<TService>();
}
/// <summary>
/// 开始运行
/// </summary>
public static void Setup()
{
if (setuped.StartOperation() == false) return;
ICommonStore commonStore = serviceProvider.GetService<ICommonStore>();
if ((commonStore.Modes & CommonModes.Server) == CommonModes.Server)
{
serviceProvider.UseAccessServer().UseActionServer().UseDecenterServer().UseForwardServer().UsePcpServer().UseRelayServer().UseSForwardServer().UseSignInServer().UseSocks5Server().UseSyncServer().UseTunnelServer().UseTuntapServer().UseUpdaterServer().UseFlowServer();
@@ -131,15 +150,7 @@ namespace linker.messenger.entry
}
}
/// <summary>
/// 获取服务
/// </summary>
/// <typeparam name="TService"></typeparam>
/// <returns></returns>
public static TService GetService<TService>() where TService : class
{
return serviceProvider.GetService<TService>();
}
}
}

View File

@@ -4,6 +4,10 @@ namespace linker.messenger.exroute
{
public interface IExRoute
{
/// <summary>
/// 获取排除的路由
/// </summary>
/// <returns></returns>
public List<IPAddress> Get();
}
}

View File

@@ -2,15 +2,52 @@
{
public interface IForwardClientStore
{
/// <summary>
/// 获取数量
/// </summary>
/// <returns></returns>
public int Count();
/// <summary>
/// 获取端口转发列表
/// </summary>
/// <returns></returns>
public List<ForwardInfo> Get();
/// <summary>
/// 根据id获取
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public ForwardInfo Get(uint id);
/// <summary>
/// 根据分组获取
/// </summary>
/// <param name="groupId"></param>
/// <returns></returns>
public List<ForwardInfo> Get(string groupId);
/// <summary>
/// 添加转发
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public bool Add(ForwardInfo info);
/// <summary>
/// 更新转发
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public bool Update(ForwardInfo info);
/// <summary>
/// 删除转发
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public bool Remove(uint id);
/// <summary>
/// 提交更新
/// </summary>
/// <returns></returns>
public bool Confirm();
}
}

View File

@@ -1,13 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace linker.messenger.listen
namespace linker.messenger.listen
{
public interface IListenStore
{
/// <summary>
/// 端口
/// </summary>
public int Port { get; }
/// <summary>
/// 设置端口
/// </summary>
/// <param name="port"></param>
/// <returns></returns>
public bool SetPort(int port);
/// <summary>
/// 提交
/// </summary>
/// <returns></returns>
public bool Confirm();
}
}

View File

@@ -4,12 +4,31 @@ namespace linker.messenger.logger
{
public interface ILoggerStore
{
/// <summary>
/// 日志等级
/// </summary>
public LoggerTypes LoggerType { get; }
/// <summary>
/// 日志最大存储量
/// </summary>
public int LoggerSize { get; }
/// <summary>
/// 设置等级
/// </summary>
/// <param name="level"></param>
/// <returns></returns>
public bool SetLevel(LoggerTypes level);
/// <summary>
/// 设置存储量
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
public bool SetSize(int size);
/// <summary>
/// 提交
/// </summary>
/// <returns></returns>
public bool Confirm();
}
}

View File

@@ -17,9 +17,27 @@ namespace linker.messenger.relay.client
/// </summary>
public RelayServerInfo Server { get; }
/// <summary>
/// 设置默认节点id
/// </summary>
/// <param name="defaultNodeId"></param>
public void SetDefaultNodeId(string defaultNodeId);
/// <summary>
/// 设置中继服务器
/// </summary>
/// <param name="server"></param>
public void SetServer(RelayServerInfo server);
/// <summary>
/// 设置中继密钥
/// </summary>
/// <param name="secretKey"></param>
public void SetServerSecretKey(string secretKey);
/// <summary>
/// 提交
/// </summary>
/// <returns></returns>
public bool Confirm();
}
}

View File

@@ -11,6 +11,18 @@ namespace linker.messenger.relay.server
/// 主服务器信息
/// </summary>
public RelayServerMasterInfo Master { get; }
/// <summary>
/// 设置
/// </summary>
/// <param name="info"></param>
public void SetInfo(RelayServerMasterInfo info);
/// <summary>
/// 提交
/// </summary>
/// <returns></returns>
public bool Confirm();
}
public sealed class RelayServerMasterInfo

View File

@@ -18,6 +18,12 @@ namespace linker.messenger.relay.server
/// </summary>
public RelayServerNodeInfo Node { get; }
/// <summary>
/// 设置
/// </summary>
/// <param name="node"></param>
public void SetInfo(RelayServerNodeInfo node);
/// <summary>
/// 设置月份
/// </summary>

View File

@@ -1,13 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace linker.messenger.relay.server
namespace linker.messenger.relay.server
{
public interface IRelayServerStore
{
/// <summary>
/// 中继密钥
/// </summary>
public string SecretKey { get; }
/// <summary>
/// 设置中继密钥
/// </summary>
/// <param name="secretKey"></param>
public void SetSecretKey(string secretKey);
/// <summary>
/// 提交
/// </summary>
/// <returns></returns>
public bool Confirm();
}
}

View File

@@ -2,20 +2,69 @@
{
public interface ISForwardClientStore
{
/// <summary>
/// 穿透密钥
/// </summary>
public string SecretKey { get; }
/// <summary>
/// 设置穿透密钥
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool SetSecretKey(string key);
/// <summary>
/// 穿透数量
/// </summary>
/// <returns></returns>
public int Count();
/// <summary>
/// 获取穿透列表
/// </summary>
/// <returns></returns>
public List<SForwardInfo> Get();
/// <summary>
/// 获取穿透
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public SForwardInfo Get(uint id);
/// <summary>
/// 获取穿透
/// </summary>
/// <param name="domain"></param>
/// <returns></returns>
public SForwardInfo Get(string domain);
/// <summary>
/// 获取穿透
/// </summary>
/// <param name="port"></param>
/// <returns></returns>
public SForwardInfo Get(int port);
/// <summary>
/// 添加穿透
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public bool Add(SForwardInfo info);
/// <summary>
/// 更新穿透
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public bool Update(SForwardInfo info);
/// <summary>
/// 删除穿透
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public bool Remove(uint id);
/// <summary>
/// 提交保存
/// </summary>
/// <returns></returns>
public bool Confirm();
}
}

View File

@@ -2,9 +2,52 @@
{
public interface ISForwardServerStore
{
/// <summary>
/// 穿透密钥
/// </summary>
public string SecretKey { get; }
/// <summary>
/// 缓冲区大小
/// </summary>
public byte BufferSize { get; }
/// <summary>
/// web端口
/// </summary>
public int WebPort { get; }
/// <summary>
/// 端口隧道范围
/// </summary>
public int[] TunnelPortRange { get; }
/// <summary>
/// 穿透密钥
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool SetSecretKey(string key);
/// <summary>
/// 缓冲区大小
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
public bool SetBufferSize(byte size);
/// <summary>
/// web端口
/// </summary>
/// <param name="port"></param>
/// <returns></returns>
public bool SetWebPort(int port);
/// <summary>
/// 端口隧道范围
/// </summary>
/// <param name="ports"></param>
/// <returns></returns>
public bool SetTunnelPortRange(int[] ports);
/// <summary>
/// 提交保存
/// </summary>
/// <returns></returns>
public bool Confirm();
}
}

View File

@@ -2,17 +2,55 @@
{
public interface ISignInClientStore
{
/// <summary>
/// 信标服务器
/// </summary>
public SignInClientServerInfo Server { get; }
/// <summary>
/// 分组
/// </summary>
public SignInClientGroupInfo Group { get; }
/// <summary>
/// id
/// </summary>
public string Id { get; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; }
/// <summary>
/// 设置名称
/// </summary>
/// <param name="newName"></param>
public void SetName(string newName);
/// <summary>
/// 设置分组,第一个生效
/// </summary>
/// <param name="groups"></param>
public void SetGroups(SignInClientGroupInfo[] groups);
/// <summary>
/// 设置生效分组的密码
/// </summary>
/// <param name="password"></param>
public void SetGroupPassword(string password);
/// <summary>
/// 设置信标服务器
/// </summary>
/// <param name="servers"></param>
public void SetServer(SignInClientServerInfo servers);
/// <summary>
/// 设置信标密钥
/// </summary>
/// <param name="secretKey"></param>
public void SetSecretKey(string secretKey);
/// <summary>
/// 设置id
/// </summary>
/// <param name="id"></param>
public void SetId(string id);
public bool Confirm();
}
}

View File

@@ -7,6 +7,14 @@ namespace linker.messenger.signin
/// </summary>
public interface ISignInServerStore : IStore<SignCacheInfo>
{
/// <summary>
/// 信标密钥
/// </summary>
public string SecretKey { get; }
/// <summary>
/// 设置信标密钥
/// </summary>
/// <param name="secretKey"></param>
public void SetSecretKey(string secretKey);
}
}

View File

@@ -83,12 +83,38 @@ namespace linker.messenger.socks5
}
public interface ISocks5Store
{
/// <summary>
/// 局域网IP
/// </summary>
public List<Socks5LanInfo> Lans { get; }
/// <summary>
/// 监听端口
/// </summary>
public int Port { get; }
/// <summary>
/// 是否启动
/// </summary>
public bool Running { get;}
/// <summary>
/// 设置局域网ip
/// </summary>
/// <param name="lans"></param>
public void SetLans(List<Socks5LanInfo> lans);
/// <summary>
/// 设置监听端口
/// </summary>
/// <param name="port"></param>
public void SetPort(int port);
/// <summary>
/// 设置启动状态
/// </summary>
/// <param name="running"></param>
public void SetRunning(bool running);
/// <summary>
/// 提交保存
/// </summary>
/// <returns></returns>
public bool Confirm();
}
}

View File

@@ -69,7 +69,8 @@ namespace linker.messenger.store.file
serviceCollection.AddSingleton<SignInSyncGroupSecretKey>();
serviceCollection.AddSingleton<IActionStore, ActionStore>();
serviceCollection.AddSingleton<IActionClientStore, ActionClientStore>();
serviceCollection.AddSingleton<IActionServerStore, ActionServerStore>();
serviceCollection.AddSingleton<IListenStore, ListenStore>();

View File

@@ -214,11 +214,7 @@ namespace linker.messenger.store.file
{
public ConfigCommonInfo() { }
#if DEBUG
public bool Install { get; set; } = false;
#else
public bool Install { get; set; } = false;
#endif
public ConfigCommonInfo Load(string text)
{
return text.DeJson<ConfigCommonInfo>();

View File

@@ -1,16 +1,12 @@
using linker.messenger.action;
namespace linker.messenger.store.file.action
{
public sealed class ActionStore : IActionStore
public sealed class ActionClientStore : IActionClientStore
{
public const string ACTION_ARG_KEY = "ACTION_ARGS";
public string SignInActionUrl => config.Data.Action.SignInActionUrl;
public string RelayActionUrl => config.Data.Action.SignInActionUrl;
public string SForwardActionUrl => config.Data.Action.SignInActionUrl;
public const string ACTION_ARG_KEY = "SNLTTY_ACTION_ARGS";
private readonly FileConfig config;
public ActionStore(FileConfig config)
public ActionClientStore(FileConfig config)
{
this.config = config;
}
@@ -22,7 +18,7 @@ namespace linker.messenger.store.file.action
public void SetActionArgs(Dictionary<string, string> actions)
{
config.Data.Client.Action.Args = actions;
config.Data.Update();
}
public bool TryAddActionArg(string host, Dictionary<string, string> args)
{
@@ -36,13 +32,10 @@ namespace linker.messenger.store.file.action
}
return true;
}
public bool TryGetActionArg(Dictionary<string, string> args, out string str, out string machineKey)
public bool Confirm()
{
args.TryGetValue("machineKey", out machineKey);
machineKey = machineKey ?? string.Empty;
return args.TryGetValue(ACTION_ARG_KEY, out str) && string.IsNullOrWhiteSpace(str) == false;
config.Data.Update();
return true;
}
}

View File

@@ -0,0 +1,53 @@
using linker.messenger.action;
namespace linker.messenger.store.file.action
{
public sealed class ActionServerStore : IActionServerStore
{
public const string ACTION_ARG_KEY = "SNLTTY_ACTION_ARGS";
public string SignInActionUrl => config.Data.Action.SignInActionUrl;
public string RelayActionUrl => config.Data.Action.RelayActionUrl;
public string SForwardActionUrl => config.Data.Action.SForwardActionUrl;
private readonly FileConfig config;
public ActionServerStore(FileConfig config)
{
this.config = config;
}
public bool SetSignInActionUrl(string url)
{
config.Data.Action.SignInActionUrl = url;
return true;
}
public bool SetRelayActionUrl(string url)
{
config.Data.Action.RelayActionUrl = url;
return true;
}
public bool SetSForwardActionUrl(string url)
{
config.Data.Action.SForwardActionUrl = url;
return true;
}
public bool TryGetActionArg(Dictionary<string, string> args, out string str, out string machineKey)
{
args.TryGetValue("machineKey", out machineKey);
machineKey = machineKey ?? string.Empty;
return args.TryGetValue(ACTION_ARG_KEY, out str) && string.IsNullOrWhiteSpace(str) == false;
}
public bool Confirm()
{
config.Data.Update();
return true;
}
}
}

View File

@@ -12,6 +12,40 @@ namespace linker.messenger.store.file.api
this.fileConfig = fileConfig;
}
public bool Set(ApiClientInfo Info)
{
fileConfig.Data.Client.CApi = Info;
return true;
}
public bool Confirm()
{
fileConfig.Data.Update();
return true;
}
public bool SetApiPort(int port)
{
fileConfig.Data.Client.CApi.ApiPort = port;
return true;
}
public bool SetApiPassword(string password)
{
fileConfig.Data.Client.CApi.ApiPassword = password;
return true;
}
public bool SetWebPort(int port)
{
fileConfig.Data.Client.CApi.WebPort= port;
return true;
}
public bool SetWebRoot(string rootPath)
{
fileConfig.Data.Client.CApi.WebRoot = rootPath;
return true;
}
}
}

View File

@@ -24,5 +24,29 @@
{
this.fileConfig = fileConfig;
}
public void SetModes(CommonModes modes)
{
List<string> modesStr = new List<string>();
if((modes & CommonModes.Client) == CommonModes.Client)
{
modesStr.Add("client");
}
if ((modes & CommonModes.Server) == CommonModes.Server)
{
modesStr.Add("server");
}
fileConfig.Data.Common.Modes = modesStr.ToArray();
}
public void SetInstalled(bool installed)
{
fileConfig.Data.Common.Install = installed;
}
public void Confirm()
{
fileConfig.Data.Update();
}
}
}

View File

@@ -4,6 +4,11 @@
public sealed partial class ConfigCommonInfo
{
public string[] Modes { get; set; } = new string[] { "client", "server" };
#if DEBUG
public bool Install { get; set; } = false;
#else
public bool Install { get; set; } = false;
#endif
}
}

View File

@@ -43,5 +43,11 @@ namespace linker.messenger.store.file.relay
}
config.Data.Update();
}
public bool Confirm()
{
config.Data.Update();
return true;
}
}
}

View File

@@ -12,5 +12,15 @@ namespace linker.messenger.store.file.relay
this.config = config;
}
public void SetInfo(RelayServerMasterInfo info)
{
config.Data.Server.Relay.Distributed.Master = info;
}
public bool Confirm()
{
config.Data.Update();
return true;
}
}
}

View File

@@ -18,6 +18,10 @@ namespace linker.messenger.store.file.relay
config.Data.Update();
}
public void SetInfo(RelayServerNodeInfo node)
{
config.Data.Server.Relay.Distributed.Node = node;
}
public void SetMaxGbTotalLastBytes(ulong value)
{
config.Data.Server.Relay.Distributed.Node.MaxGbTotalLastBytes=value;
@@ -27,5 +31,7 @@ namespace linker.messenger.store.file.relay
{
config.Data.Server.Relay.Distributed.Node.MaxGbTotalMonth = month;
}
}
}

View File

@@ -10,5 +10,16 @@ namespace linker.messenger.store.file.relay
{
this.config = config;
}
public void SetSecretKey(string secretKey)
{
config.Data.Server.Relay.SecretKey = secretKey;
}
public bool Confirm()
{
config.Data.Update();
return true;
}
}
}

View File

@@ -11,5 +11,17 @@ namespace linker.messenger.store.file.server
{
this.config = config;
}
public bool SetPort(int port)
{
config.Data.Server.ServicePort = port;
return true;
}
public bool Confirm()
{
config.Data.Update();
return true;
}
}
}

View File

@@ -17,5 +17,36 @@ namespace linker.messenger.store.file.sforward
{
this.fileConfig = fileConfig;
}
public bool SetSecretKey(string key)
{
fileConfig.Data.Server.SForward.SecretKey = key;
return true;
}
public bool SetBufferSize(byte size)
{
fileConfig.Data.Server.SForward.BufferSize = size;
return true;
}
public bool SetWebPort(int port)
{
fileConfig.Data.Server.SForward.WebPort = port;
return true;
}
public bool SetTunnelPortRange(int[] ports)
{
if (ports == null || ports.Length != 2) return false;
fileConfig.Data.Server.SForward.TunnelPortRange = ports;
return true;
}
public bool Confirm()
{
fileConfig.Data.Update();
return true;
}
}
}

View File

@@ -23,6 +23,7 @@ namespace linker.messenger.store.file.signIn
}
public void SetGroups(SignInClientGroupInfo[] groups)
{
if (groups == null || groups.Length == 0) return;
config.Data.Client.Groups = groups;
config.Data.Update();
}
@@ -48,5 +49,11 @@ namespace linker.messenger.store.file.signIn
config.Data.Client.Id = id;
config.Data.Update();
}
public bool Confirm()
{
config.Data.Update();
return true;
}
}
}

View File

@@ -16,10 +16,15 @@ namespace linker.messenger.store.file.signIn
liteCollection = dBfactory.GetCollection<SignCacheInfo>("signs");
this.fileConfig = fileConfig;
}
public void SetSecretKey(string secretKey)
{
fileConfig.Data.Server.SignIn.SecretKey = secretKey;
}
public void Confirm()
{
dBfactory.Confirm();
fileConfig.Data.Update();
}
public bool Delete(string id)
@@ -51,5 +56,7 @@ namespace linker.messenger.store.file.signIn
{
return liteCollection.Update(value);
}
}
}

View File

@@ -33,5 +33,11 @@ namespace linker.messenger.store.file.socks5
runningConfig.Data.Socks5.Running = running;
runningConfig.Data.Update();
}
public bool Confirm()
{
runningConfig.Data.Update();
return true;
}
}
}

View File

@@ -21,5 +21,20 @@ namespace linker.messenger.store.file.updater
fileConfig.Data.Common.UpdateIntervalSeconds = sec;
fileConfig.Data.Update();
}
public void SetUrl(string url)
{
fileConfig.Data.Common.UpdateUrl = url;
}
public void SetCheck(bool checke)
{
fileConfig.Data.Common.CheckUpdate = checke;
}
public void Confirm()
{
fileConfig.Data.Update();
}
}
}

View File

@@ -12,5 +12,16 @@ namespace linker.messenger.store.file.updater
{
this.fileConfig = fileConfig;
}
public void SetSecretKey(string key)
{
fileConfig.Data.Server.Updater.SecretKey = key;
}
public bool Confirm()
{
fileConfig.Data.Update();
return true;
}
}
}

View File

@@ -5,6 +5,9 @@ namespace linker.messenger.tuntap
{
public TuntapConfigInfo Info{ get; }
/// <summary>
/// 提交保存
/// </summary>
public void Confirm();
}
}

View File

@@ -2,8 +2,14 @@
{
public interface IUpdaterClientStore
{
/// <summary>
/// 更新密钥
/// </summary>
public string SecretKey { get; }
/// <summary>
/// 设置更新密钥
/// </summary>
/// <param name="key"></param>
public void SetSecretKey(string key);
}
}

View File

@@ -5,9 +5,11 @@
public string UpdateUrl { get; }
public int UpdateIntervalSeconds { get; }
public bool CheckUpdate { get; }
public void SetUrl(string url);
public void SetInterval(int sec);
public void SetCheck(bool checke);
public void Confirm();
}
}

View File

@@ -2,6 +2,15 @@
{
public interface IUpdaterServerStore
{
/// <summary>
/// 更新密钥
/// </summary>
public string SecretKey { get; }
/// <summary>
/// 设置更新密钥
/// </summary>
/// <param name="key"></param>
public void SetSecretKey(string key);
public bool Confirm();
}
}

View File

@@ -3,12 +3,17 @@
public interface ICommonStore
{
public CommonModes Modes { get; }
public void SetModes(CommonModes modes);
public void SetInstalled(bool installed);
public void Confirm();
}
[Flags]
public enum CommonModes : byte
{
Client = 1,
Server = 2
Server = 2,
All = 1 | 2
}
}

View File

@@ -3,7 +3,7 @@
<el-card shadow="never">
<template #header>设置定义验证的静态Json参数</template>
<div>
<el-input v-model="state.list" :rows="10" type="textarea" resize="none" @change="handleSave"/>
<el-input v-model="state.list" :rows="10" type="textarea" resize="none" @change="handleSave" />
</div>
<template #footer>
<div class="t-c">
@@ -17,34 +17,34 @@
import { setArgs } from '@/apis/action';
import { injectGlobalData } from '@/provide';
import { ElMessage } from 'element-plus';
import { reactive } from 'vue'
import { reactive } from 'vue'
export default {
setup(props) {
const globalData = injectGlobalData();
const state = reactive({
list:globalData.value.config.Client.Action.Args[globalData.value.config.Client.Server.Host] || ''
list: globalData.value.config.Client.Action.Args[globalData.value.config.Client.Server.Host] || ''
});
const handleSave = ()=>{
try{
if(state.list && typeof(JSON.parse(state.list)) != 'object'){
const handleSave = () => {
try {
if (state.list && typeof (JSON.parse(state.list)) != 'object') {
ElMessage.error('Json格式错误');
return;
}
}catch(e){
} catch (e) {
ElMessage.error('Json格式错误');
return;
}
const json = {};
const json = JSON.parse(JSON.stringify(globalData.value.config.Client.Action.Args));
json[globalData.value.config.Client.Server.Host] = state.list;
setArgs(json).then(()=>{
setArgs(json).then(() => {
ElMessage.success('已操作');
}).catch((err)=>{
}).catch((err) => {
console.log(err);
ElMessage.error('操作失败');
});;
}
return {state,handleSave}
return { state, handleSave }
}
}
</script>

View File

@@ -2,6 +2,8 @@
using System.ServiceProcess;
using System.Diagnostics;
using linker.messenger.entry;
using linker.messenger;
using linker.messenger.api;
namespace linker
{
@@ -50,6 +52,7 @@ namespace linker
{
LinkerMessengerEntry.Initialize();
LinkerMessengerEntry.Build();
LinkerMessengerEntry.Setup();
LoggerHelper.Instance.Warning($"current version : {VersionHelper.version}");
LoggerHelper.Instance.Warning($"linker env is docker : {Environment.GetEnvironmentVariable("SNLTTY_LINKER_IS_DOCKER")}");

View File

@@ -1,5 +1,5 @@
v1.6.4
2025-01-01 19:01:06
2025-01-02 15:55:00
1. 优化代码,解耦,简单几步将打洞和中继集成到你自己的项目中
2. 增加了组件组合demo
3. 测试中,不要更,不要更,不要更