diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 50218a33..7b63187f 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -35,7 +35,7 @@ jobs: release_name: v1.6.9.${{ steps.date.outputs.today }} draft: false prerelease: false - body: "1. 修复litedb抢锁超时导致客户端登录失败问题\r\n2. 同步信标服务器\r\n3. 其它一些修复优化" + body: "1. 优化linux下路由跟踪问题\r\n2. 优化linux下获取本机IP问题\r\n3. 增加ICS,让win7+、win server2008+支持NAT\r\n4. 增加中继卡密\r\n5. 增加内外穿透定时开关功能\r\n6. 优化管理页面连接接口的体验\r\n7. 优化一些UI体验,去除同步页面,将同步功能放置各个实际的位置\r\n8. 其它一些修复优化" - name: publish projects run: ./publish.bat - name: upload-win-x86-oss diff --git a/src/linker.doc.web/docs/1、首页.md b/src/linker.doc.web/docs/1、首页.md index 878c64ad..0c697d8d 100644 --- a/src/linker.doc.web/docs/1、首页.md +++ b/src/linker.doc.web/docs/1、首页.md @@ -57,10 +57,11 @@ sidebar_position: 1 ::: :::danger[win10以下] -1. win7 或 win8 可能需要安装一些环境,才能运行 -2. Microsoft Visual C++ 2015-2019 Redistributable -3. KB3063858 -4. KB3033929 +1. win7、win8、win server 2008、win server 2008 R2 可能需要安装一些环境,才能运行 +2. Microsoft Visual C++ 2015-2019 Redistributable 运行库 +3. KB3063858 运行库 +4. KB3033929 全球化补丁 +5. netframework4.6.2 ICS NAT运行库 ::: diff --git a/src/linker.doc.web/docs/4、通信功能/4.1、虚拟网卡/1.1.2、RRAS.md b/src/linker.doc.web/docs/4、通信功能/4.1、虚拟网卡/1.1.2、RRAS.md deleted file mode 100644 index 6012aeff..00000000 --- a/src/linker.doc.web/docs/4、通信功能/4.1、虚拟网卡/1.1.2、RRAS.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_position: 4 ---- - -# 1.1.2、RRAS - -:::tip[说明] -1. 操作不当可能会导致网络无法访问,请谨慎操作 -2. 有局限性,创建虚拟网卡后,需要重新`“配置并启用路由和远程访问”` - -![](./img/rras1.png) -![](./img/rras2.png) -![](./img/rras3.png) -![](./img/rras4.png) -![](./img/rras5.png) -![](./img/rras6.png) -![](./img/rras7.png) -![](./img/rras8.png) -![](./img/rras9.png) -![](./img/rras10.png) -![](./img/rras11.png) -![](./img/rras12.png) -![](./img/rras13.png) -::: \ No newline at end of file diff --git a/src/linker.doc.web/docs/4、通信功能/4.1、虚拟网卡/1.1.3、ICS.md b/src/linker.doc.web/docs/4、通信功能/4.1、虚拟网卡/1.1.3、ICS.md index ae140ed8..68109886 100644 --- a/src/linker.doc.web/docs/4、通信功能/4.1、虚拟网卡/1.1.3、ICS.md +++ b/src/linker.doc.web/docs/4、通信功能/4.1、虚拟网卡/1.1.3、ICS.md @@ -1,12 +1,11 @@ --- -sidebar_position: 5 +sidebar_position: 4 --- # 1.1.3、ICS :::tip[说明] -1. 操作不当可能会导致网络无法访问,请谨慎操作 - -![](./img/ics1.png) - +1. 如果系统没有netframework4.6.2,就下载安装一下 +2. 需要linker v1.7.0+版本 +3. 剩下的交给linker ::: \ No newline at end of file diff --git a/src/linker.doc.web/docs/4、通信功能/4.1、虚拟网卡/1.2、网对网.md b/src/linker.doc.web/docs/4、通信功能/4.1、虚拟网卡/1.2、网对网.md index 1058b477..bbd982cd 100644 --- a/src/linker.doc.web/docs/4、通信功能/4.1、虚拟网卡/1.2、网对网.md +++ b/src/linker.doc.web/docs/4、通信功能/4.1、虚拟网卡/1.2、网对网.md @@ -1,5 +1,5 @@ --- -sidebar_position: 6 +sidebar_position: 5 --- # 1.2、网对网 diff --git a/src/linker.libs/CommandHelper.cs b/src/linker.libs/CommandHelper.cs index 6e03bdd7..48805521 100644 --- a/src/linker.libs/CommandHelper.cs +++ b/src/linker.libs/CommandHelper.cs @@ -9,9 +9,9 @@ namespace linker.libs { public static string Windows(string arg, string[] commands) { - return Execute("cmd.exe", arg, commands,out string error); + return Execute("cmd.exe", arg, commands, out string error); } - public static string Windows(string arg, string[] commands,out string error) + public static string Windows(string arg, string[] commands, out string error) { return Execute("cmd.exe", arg, commands, out error); } @@ -23,14 +23,14 @@ namespace linker.libs error = "PowerShell is not installed"; return string.Empty; } - return Execute("powershell.exe", arg, commands,out error); + return Execute("powershell.exe", arg, commands, out error); } public static string Linux(string arg, string[] commands) { return Execute("/bin/bash", arg, commands, out string error); } - public static string Linux(string arg, string[] commands,out string error) + public static string Linux(string arg, string[] commands, out string error) { return Execute("/bin/bash", arg, commands, out error); } @@ -56,7 +56,7 @@ namespace linker.libs return proc; } - public static string Execute(string fileName, string arg, string[] commands,out string error) + public static string Execute(string fileName, string arg, string[] commands, out string error) { using Process proc = new Process(); proc.StartInfo.WorkingDirectory = Path.GetFullPath(Path.Join("./")); @@ -80,12 +80,9 @@ namespace linker.libs proc.StandardInput.WriteLine("exit"); proc.StandardInput.Close(); + string output = proc.StandardOutput.ReadToEnd(); error = proc.StandardError.ReadToEnd(); - string output = string.Empty; - if (string.IsNullOrWhiteSpace(error)) - { - output = proc.StandardOutput.ReadToEnd(); - } + proc.WaitForExit(); proc.Close(); proc.Dispose(); diff --git a/src/linker.libs/NetworkHelper.cs b/src/linker.libs/NetworkHelper.cs index 1e9993b1..ba9fa374 100644 --- a/src/linker.libs/NetworkHelper.cs +++ b/src/linker.libs/NetworkHelper.cs @@ -36,7 +36,7 @@ namespace linker.libs public bool Equals(IPNetwork other) { - return ToValue() == other.ToValue(); + return ToValue() == other.ToValue(); } } @@ -142,7 +142,7 @@ namespace linker.libs { result = new List(); - string str = CommandHelper.Linux(string.Empty, new string[] { $"traceroute {server} -4 -m 5" }); + string str = CommandHelper.Linux(string.Empty, new string[] { $"traceroute {server} -4 -m 5 -w 1" }); string[] lines = str.Split(Environment.NewLine); Regex regex = new Regex(@"(\d+\.\d+\.\d+\.\d+)"); @@ -191,33 +191,41 @@ namespace linker.libs private static byte[] ipv6LocalBytes = new byte[] { 254, 128, 0, 0, 0, 0, 0, 0 }; - public static IPAddress[] GetIPV6() + + private static IPAddress[] GetIP() { try { - return Dns.GetHostAddresses(Dns.GetHostName()) - .Where(c => c.AddressFamily == AddressFamily.InterNetworkV6) - .Where(c => c.GetAddressBytes().AsSpan(0, 8).SequenceEqual(ipv6LocalBytes) == false).Distinct().ToArray(); + return Dns.GetHostEntry(Dns.GetHostName()).AddressList; } catch (Exception) { + try + { + return NetworkInterface.GetAllNetworkInterfaces() + .SelectMany(c => c.GetIPProperties().UnicastAddresses) + .Select(c => c.Address) + .ToArray(); + } + catch (Exception) + { + } } return Array.Empty(); } + public static IPAddress[] GetIPV6() + { + return GetIP() + .Where(c => c.AddressFamily == AddressFamily.InterNetworkV6) + .Where(c => c.GetAddressBytes().AsSpan(0, 8).SequenceEqual(ipv6LocalBytes) == false).Distinct().ToArray(); ; + } public static IPAddress[] GetIPV4() { - try - { - return Dns.GetHostEntry(Dns.GetHostName()).AddressList - .Where(c => c.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) + return GetIP() + .Where(c => c.AddressFamily == AddressFamily.InterNetwork) .Where(c => c.IsIPv4MappedToIPv6 == false) .Where(c => c.Equals(IPAddress.Loopback) == false) .Distinct().ToArray(); - } - catch (Exception) - { - } - return Array.Empty(); } public static byte ToPrefixLength(uint ip) diff --git a/src/linker.libs/api/ApiServer.cs b/src/linker.libs/api/ApiServer.cs index 32593b92..6c5072e3 100644 --- a/src/linker.libs/api/ApiServer.cs +++ b/src/linker.libs/api/ApiServer.cs @@ -38,7 +38,7 @@ namespace linker.libs.api server = new WebSocketServer(); try { - server.Start( port); + server.Start(port); } catch (Exception ex) { @@ -51,6 +51,13 @@ namespace linker.libs.api { header.SetHeaderValue(WebsocketHeaderKey.SecWebSocketExtensions, string.Empty); } + + if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) + { + header.TryGetHeaderValue(WebsocketHeaderKey.SecWebSocketProtocol, out string _password1); + LoggerHelper.Instance.Info($"websocket client password {_password1} eq {password}"); + } + return res; }; server.OnOpen = (connection) => diff --git a/src/linker.libs/websocket/WebSocketServer.cs b/src/linker.libs/websocket/WebSocketServer.cs index 40ed2161..f77630ae 100644 --- a/src/linker.libs/websocket/WebSocketServer.cs +++ b/src/linker.libs/websocket/WebSocketServer.cs @@ -313,6 +313,8 @@ namespace linker.libs.websocket { token.Connectrion.SendFrameClose(WebSocketFrameInfo.EnumCloseStatus.ExtendsError); token.Connectrion.Close(); + if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) + LoggerHelper.Instance.Error($"websocket opcode error:{token.FrameInfo.Opcode}"); return; } } @@ -356,6 +358,8 @@ namespace linker.libs.websocket header.StatusCode = HttpStatusCode.MethodNotAllowed; token.Connectrion.ConnectResponse(header); token.Connectrion.Close(); + if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) + LoggerHelper.Instance.Error("websocket SecWebSocketKey error"); return; } @@ -370,6 +374,8 @@ namespace linker.libs.websocket header.StatusCode = HttpStatusCode.Unauthorized; token.Connectrion.ConnectResponse(header); token.Connectrion.Close(); + if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) + LoggerHelper.Instance.Error("websocket OnConnecting false"); } } @@ -479,6 +485,9 @@ namespace linker.libs.websocket { Disposabled = true; Connectrion.Close(); + + if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) + LoggerHelper.Instance.Error($"websocket connection clear"); } } diff --git a/src/linker.messenger.api/Config.cs b/src/linker.messenger.api/Config.cs index 9199e6b1..a3b72239 100644 --- a/src/linker.messenger.api/Config.cs +++ b/src/linker.messenger.api/Config.cs @@ -136,6 +136,9 @@ [AccessDisplay("重置所有接口密码")] SetApiPasswordOther = (ulong)1 << 42, + [AccessDisplay("管理中继CDKEY")] + RelayCdkey = (ulong)1 << 43, + Full = ulong.MaxValue >> 64 - 52, } diff --git a/src/linker.messenger.relay/client/RelayApiController.cs b/src/linker.messenger.relay/client/RelayApiController.cs index c467ffa0..59307bae 100644 --- a/src/linker.messenger.relay/client/RelayApiController.cs +++ b/src/linker.messenger.relay/client/RelayApiController.cs @@ -1,9 +1,12 @@ -using linker.libs.api; +using linker.libs; +using linker.libs.api; using linker.libs.extends; using linker.messenger.api; using linker.messenger.relay.client; using linker.messenger.relay.client.transport; +using linker.messenger.relay.messenger; using linker.messenger.relay.server; +using linker.messenger.signin; namespace linker.messenger.relay { @@ -15,19 +18,23 @@ namespace linker.messenger.relay private readonly RelayClientTestTransfer relayTestTransfer; private readonly RelayClientTransfer relayTransfer; private readonly IRelayClientStore relayClientStore; + private readonly SignInClientState signInClientState; + private readonly IMessengerSender messengerSender; + private readonly ISerializer serializer; + private readonly ISignInClientStore signInClientStore; - public RelayApiController(RelayClientTestTransfer relayTestTransfer, RelayClientTransfer relayTransfer, IRelayClientStore relayClientStore) + public RelayApiController(RelayClientTestTransfer relayTestTransfer, RelayClientTransfer relayTransfer, IRelayClientStore relayClientStore, + SignInClientState signInClientState, IMessengerSender messengerSender, ISerializer serializer, ISignInClientStore signInClientStore) { this.relayTestTransfer = relayTestTransfer; this.relayTransfer = relayTransfer; this.relayClientStore = relayClientStore; + this.signInClientState = signInClientState; + this.messengerSender = messengerSender; + this.serializer = serializer; + this.signInClientStore = signInClientStore; } - /// - /// 设置中继协议 - /// - /// - /// [Access(AccessValue.Config)] public bool SetServers(ApiControllerParamsInfo param) { @@ -50,6 +57,90 @@ namespace linker.messenger.relay return true; } + + public async Task AccessCdkey(ApiControllerParamsInfo param) + { + var resp = await messengerSender.SendReply(new MessageRequestWrap + { + Connection = signInClientState.Connection, + MessengerId = (ushort)RelayMessengerIds.AccessCdkey, + Payload = serializer.Serialize(relayClientStore.Server.SecretKey) + }); + return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray); + } + + [Access(AccessValue.RelayCdkey)] + public async Task AddCdkey(ApiControllerParamsInfo param) + { + RelayServerCdkeyInfo info = param.Content.DeJson(); + var resp = await messengerSender.SendReply(new MessageRequestWrap + { + Connection = signInClientState.Connection, + MessengerId = (ushort)RelayMessengerIds.AddCdkey, + Payload = serializer.Serialize(new RelayServerCdkeyAddInfo + { + Data = info, + SecretKey = relayClientStore.Server.SecretKey + }) + }); + + return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray); + } + + [Access(AccessValue.RelayCdkey)] + public async Task DelCdkey(ApiControllerParamsInfo param) + { + var resp = await messengerSender.SendReply(new MessageRequestWrap + { + Connection = signInClientState.Connection, + MessengerId = (ushort)RelayMessengerIds.DelCdkey, + Payload = serializer.Serialize(new RelayServerCdkeyDelInfo + { + Id = param.Content, + SecretKey = relayClientStore.Server.SecretKey + }) + }); + + return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray); + } + + [Access(AccessValue.RelayCdkey)] + public async Task PageCdkey(ApiControllerParamsInfo param) + { + RelayServerCdkeyPageRequestInfo info = param.Content.DeJson(); + info.SecretKey = relayClientStore.Server.SecretKey; + var resp = await messengerSender.SendReply(new MessageRequestWrap + { + Connection = signInClientState.Connection, + MessengerId = (ushort)RelayMessengerIds.PageCdkey, + Payload = serializer.Serialize(info) + }); + if (resp.Code == MessageResponeCodes.OK) + { + return serializer.Deserialize(resp.Data.Span); + } + + return new RelayServerCdkeyPageResultInfo(); + } + + public async Task MyCdkey(ApiControllerParamsInfo param) + { + RelayServerCdkeyPageRequestInfo info = param.Content.DeJson(); + info.SecretKey = relayClientStore.Server.SecretKey; + info.UserId = signInClientStore.Server.UserId; + var resp = await messengerSender.SendReply(new MessageRequestWrap + { + Connection = signInClientState.Connection, + MessengerId = (ushort)RelayMessengerIds.PageCdkey, + Payload = serializer.Serialize(info) + }); + if (resp.Code == MessageResponeCodes.OK) + { + return serializer.Deserialize(resp.Data.Span); + } + + return new RelayServerCdkeyPageResultInfo(); + } } public sealed class RelayConnectInfo diff --git a/src/linker.messenger.relay/client/RelayClientTransfer.cs b/src/linker.messenger.relay/client/RelayClientTransfer.cs index cdcd12e7..82120fb6 100644 --- a/src/linker.messenger.relay/client/RelayClientTransfer.cs +++ b/src/linker.messenger.relay/client/RelayClientTransfer.cs @@ -18,10 +18,12 @@ namespace linker.messenger.relay.client private Dictionary>> OnConnected { get; } = new Dictionary>>(); private readonly IRelayClientStore relayClientStore; - public RelayClientTransfer(IMessengerSender messengerSender,ISerializer serializer,IRelayClientStore relayClientStore,SignInClientState signInClientState,IMessengerStore messengerStore) + private readonly ISignInClientStore signInClientStore; + public RelayClientTransfer(IMessengerSender messengerSender, ISerializer serializer, IRelayClientStore relayClientStore, SignInClientState signInClientState, IMessengerStore messengerStore, ISignInClientStore signInClientStore) { this.relayClientStore = relayClientStore; - Transports = new List { + this.signInClientStore = signInClientStore; + Transports = new List { new RelayClientTransportSelfHost(messengerSender,serializer,relayClientStore,signInClientState,messengerStore), }; LoggerHelper.Instance.Info($"load relay transport:{string.Join(",", Transports.Select(c => c.GetType().Name))}"); @@ -87,7 +89,8 @@ namespace linker.messenger.relay.client TransactionId = transactionId, TransportName = transport.Name, SSL = relayClientStore.Server.SSL, - NodeId = nodeId + NodeId = nodeId, + UserId = signInClientStore.Server.UserId, }; if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) diff --git a/src/linker.messenger.relay/client/transport/IRelayClientTransport.cs b/src/linker.messenger.relay/client/transport/IRelayClientTransport.cs index edd1779a..3d71cdde 100644 --- a/src/linker.messenger.relay/client/transport/IRelayClientTransport.cs +++ b/src/linker.messenger.relay/client/transport/IRelayClientTransport.cs @@ -112,6 +112,11 @@ namespace linker.messenger.relay.client.transport /// 是否ssl /// public bool SSL { get; set; } = true; + + /// + /// UserId + /// + public string UserId { get; set; } } diff --git a/src/linker.messenger.relay/messenger/RelayMessenger.cs b/src/linker.messenger.relay/messenger/RelayMessenger.cs index 1bd60341..167f5707 100644 --- a/src/linker.messenger.relay/messenger/RelayMessenger.cs +++ b/src/linker.messenger.relay/messenger/RelayMessenger.cs @@ -45,14 +45,18 @@ namespace linker.messenger.relay.messenger private readonly RelayServerMasterTransfer relayServerTransfer; private readonly RelayServerValidatorTransfer relayValidatorTransfer; private readonly ISerializer serializer; + private readonly IRelayServerCdkeyStore relayServerCdkeyStore; + private readonly IRelayServerStore relayServerStore; - public RelayServerMessenger(IMessengerSender messengerSender, SignInServerCaching signCaching, ISerializer serializer, RelayServerMasterTransfer relayServerTransfer, RelayServerValidatorTransfer relayValidatorTransfer) + public RelayServerMessenger(IMessengerSender messengerSender, SignInServerCaching signCaching, ISerializer serializer, RelayServerMasterTransfer relayServerTransfer, RelayServerValidatorTransfer relayValidatorTransfer, IRelayServerCdkeyStore relayServerCdkeyStore, IRelayServerStore relayServerStore) { this.messengerSender = messengerSender; this.signCaching = signCaching; this.relayServerTransfer = relayServerTransfer; this.relayValidatorTransfer = relayValidatorTransfer; this.serializer = serializer; + this.relayServerCdkeyStore = relayServerCdkeyStore; + this.relayServerStore = relayServerStore; } /// @@ -89,7 +93,7 @@ namespace linker.messenger.relay.messenger [MessengerId((ushort)RelayMessengerIds.RelayAsk)] public async Task RelayAsk(IConnection connection) { - client.transport.RelayInfo info = serializer.Deserialize(connection.ReceiveRequestWrap.Payload.Span); + RelayInfo info = serializer.Deserialize(connection.ReceiveRequestWrap.Payload.Span); if (signCaching.TryGet(connection.Id, out SignCacheInfo cacheFrom) == false || signCaching.TryGet(info.RemoteMachineId, out SignCacheInfo cacheTo) == false || cacheFrom.GroupId != cacheTo.GroupId) { connection.Write(serializer.Serialize(new RelayAskResultInfo { })); @@ -105,9 +109,11 @@ namespace linker.messenger.relay.messenger string error = await relayValidatorTransfer.Validate(info, cacheFrom, cacheTo); result.Nodes = relayServerTransfer.GetNodes(string.IsNullOrWhiteSpace(error)); + List cdkeys = await relayServerCdkeyStore.Get(info.UserId); + if (result.Nodes.Count > 0) { - result.FlowingId = relayServerTransfer.AddRelay(cacheFrom.MachineId, cacheFrom.MachineName, cacheTo.MachineId, cacheTo.MachineName, cacheFrom.GroupId); + result.FlowingId = relayServerTransfer.AddRelay(cacheFrom.MachineId, cacheFrom.MachineName, cacheTo.MachineId, cacheTo.MachineName, cacheFrom.GroupId, cdkeys); } connection.Write(serializer.Serialize(result)); @@ -167,5 +173,89 @@ namespace linker.messenger.relay.messenger connection.Write(Helper.FalseArray); } } + + + /// + /// 检查权限 + /// + /// + /// + [MessengerId((ushort)RelayMessengerIds.AccessCdkey)] + public void AccessCdkey(IConnection connection) + { + string secretKey = serializer.Deserialize(connection.ReceiveRequestWrap.Payload.Span); + connection.Write(relayServerStore.SecretKey == secretKey ? Helper.TrueArray : Helper.FalseArray); + } + /// + /// 添加CDKEY + /// + /// + [MessengerId((ushort)RelayMessengerIds.AddCdkey)] + public async Task AddCdkey(IConnection connection) + { + RelayServerCdkeyAddInfo info = serializer.Deserialize(connection.ReceiveRequestWrap.Payload.Span); + if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false) + { + connection.Write(Helper.FalseArray); + return; + } + if (relayServerStore.SecretKey != info.SecretKey) + { + connection.Write(Helper.FalseArray); + return; + } + + await relayServerCdkeyStore.Add(info.Data); + connection.Write(Helper.TrueArray); + } + + /// + /// 删除Cdkey + /// + /// + /// + [MessengerId((ushort)RelayMessengerIds.DelCdkey)] + public async Task DelCdkey(IConnection connection) + { + RelayServerCdkeyDelInfo info = serializer.Deserialize(connection.ReceiveRequestWrap.Payload.Span); + if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false) + { + connection.Write(Helper.FalseArray); + return; + } + if (relayServerStore.SecretKey != info.SecretKey) + { + connection.Write(Helper.FalseArray); + return; + } + + await relayServerCdkeyStore.Del(info.Id); + connection.Write(Helper.TrueArray); + } + + /// + /// 查询CDKEY + /// + /// + /// + [MessengerId((ushort)RelayMessengerIds.PageCdkey)] + public async Task PageCdkey(IConnection connection) + { + RelayServerCdkeyPageRequestInfo info = serializer.Deserialize(connection.ReceiveRequestWrap.Payload.Span); + if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false) + { + connection.Write(serializer.Serialize(new RelayServerCdkeyPageResultInfo { })); + return; + } + if (relayServerStore.SecretKey != info.SecretKey && string.IsNullOrWhiteSpace(info.UserId)) + { + connection.Write(serializer.Serialize(new RelayServerCdkeyPageResultInfo { })); + return; + } + + var page = await relayServerCdkeyStore.Get(info); + + connection.Write(serializer.Serialize(page)); + } } } diff --git a/src/linker.messenger.relay/messenger/RelayMessengerIds.cs b/src/linker.messenger.relay/messenger/RelayMessengerIds.cs index 524dee12..0fe78b01 100644 --- a/src/linker.messenger.relay/messenger/RelayMessengerIds.cs +++ b/src/linker.messenger.relay/messenger/RelayMessengerIds.cs @@ -15,6 +15,11 @@ NodeDelay = 2106, NodeDelayForward = 2107, + AddCdkey = 2108, + PageCdkey = 2109, + DelCdkey = 2110, + AccessCdkey = 2111, + Max = 2199 } } diff --git a/src/linker.messenger.relay/server/IRelayServerCdkeyStore.cs b/src/linker.messenger.relay/server/IRelayServerCdkeyStore.cs new file mode 100644 index 00000000..ac0d5ab9 --- /dev/null +++ b/src/linker.messenger.relay/server/IRelayServerCdkeyStore.cs @@ -0,0 +1,104 @@ +namespace linker.messenger.relay.server +{ + public interface IRelayServerCdkeyStore + { + public Task Add(RelayServerCdkeyInfo info); + public Task Del(string id); + + /// + /// 获取有效的CDKEY + /// + /// + /// + public Task> Get(string userid); + public Task Get(RelayServerCdkeyPageRequestInfo relayServerCdkeyPageRequestInfo); + } + + public sealed partial class RelayServerCdkeyPageRequestInfo + { + public int Page { get; set; } + public int Size { get; set; } + public string Order { get; set; } + public string Sort { get; set; } + public string UserId { get; set; } + public string Remark { get; set; } + public string SecretKey { get; set; } + } + public sealed partial class RelayServerCdkeyPageResultInfo + { + public int Page { get; set; } + public int Size { get; set; } + public int Count { get; set; } + public List List { get; set; } + } + + public sealed partial class RelayServerCdkeyAddInfo + { + public string SecretKey { get; set; } + public RelayServerCdkeyInfo Data { get; set; } + } + public sealed partial class RelayServerCdkeyDelInfo + { + public string SecretKey { get; set; } + public string Id { get; set; } + } + + /// + /// 中继CDKEY + /// + public sealed partial class RelayServerCdkeyInfo + { + public string Id { get; set; } + + /// + /// 用户标识 + /// + public string UserId { get; set; } + + /// + /// KEY + /// + public string CdKey { get; set; } + /// + /// 添加时间 + /// + public DateTime AddTime { get; set; } + /// + /// 开始时间 + /// + public DateTime StartTime { get; set; } + /// + /// 结束时间 + /// + public DateTime EndTime { get; set; } + /// + /// 允许节点 + /// + public List Nodes { get; set; } + /// + /// 带宽Mbps + /// + public double Bandwidth { get; set; } + /// + /// 流量 + /// + public ulong MaxBytes { get; set; } + /// + /// 剩余流量 + /// + public ulong LastBytes { get; set; } + + /// + /// 原价 + /// + public double Memory { get; set; } + /// + /// 支付金额 + /// + public double PayMemory { get; set; } + /// + /// 备注 + /// + public string Remark { get; set; } + } +} diff --git a/src/linker.messenger.relay/server/RelayServerMasterTransfer.cs b/src/linker.messenger.relay/server/RelayServerMasterTransfer.cs index 63de2ef4..cc763c02 100644 --- a/src/linker.messenger.relay/server/RelayServerMasterTransfer.cs +++ b/src/linker.messenger.relay/server/RelayServerMasterTransfer.cs @@ -26,7 +26,7 @@ namespace linker.messenger.relay.server } - public ulong AddRelay(string fromid, string fromName, string toid, string toName, string groupid) + public ulong AddRelay(string fromid, string fromName, string toid, string toName, string groupid, List cdkeys) { ulong flowingId = Interlocked.Increment(ref relayFlowingId); @@ -37,7 +37,8 @@ namespace linker.messenger.relay.server FromName = fromName, ToId = toid, ToName = toName, - GroupId = groupid + GroupId = groupid, + Cdkey = cdkeys }; bool added = relayCaching.TryAdd($"{fromid}->{toid}->{flowingId}", cache, 15000); if (added == false) return 0; @@ -81,7 +82,7 @@ namespace linker.messenger.relay.server } catch (Exception ex) { - if(LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) + if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) { LoggerHelper.Instance.Error(ex); } diff --git a/src/linker.messenger.relay/server/RelayServerResolver.cs b/src/linker.messenger.relay/server/RelayServerResolver.cs index 089bcdda..513ea6a6 100644 --- a/src/linker.messenger.relay/server/RelayServerResolver.cs +++ b/src/linker.messenger.relay/server/RelayServerResolver.cs @@ -256,6 +256,8 @@ namespace linker.messenger.relay.server public string ToId { get; set; } public string ToName { get; set; } public string GroupId { get; set; } + + public List Cdkey { get; set; } } public sealed class RelayWrapInfo diff --git a/src/linker.messenger.serializer.memorypack/Entry.cs b/src/linker.messenger.serializer.memorypack/Entry.cs index 4d436d4f..a1df4b26 100644 --- a/src/linker.messenger.serializer.memorypack/Entry.cs +++ b/src/linker.messenger.serializer.memorypack/Entry.cs @@ -25,7 +25,7 @@ namespace linker.messenger.serializer.memorypack MemoryPackFormatterProvider.Register(new SignInResponseInfoFormatter()); MemoryPackFormatterProvider.Register(new SignInConfigSetNameInfoFormatter()); MemoryPackFormatterProvider.Register(new SignInNamesResponseItemInfoFormatter()); - + MemoryPackFormatterProvider.Register(new SyncInfoFormatter()); @@ -55,6 +55,12 @@ namespace linker.messenger.serializer.memorypack MemoryPackFormatterProvider.Register(new RelayAskResultInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayCacheInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayMessageInfoFormatter()); + MemoryPackFormatterProvider.Register(new RelayServerCdkeyInfoFormatter()); + MemoryPackFormatterProvider.Register(new RelayServerCdkeyPageRequestInfoFormatter()); + MemoryPackFormatterProvider.Register(new RelayServerCdkeyPageResultInfoFormatter()); + MemoryPackFormatterProvider.Register(new RelayServerCdkeyAddInfoFormatter()); + MemoryPackFormatterProvider.Register(new RelayServerCdkeyDelInfoFormatter()); + MemoryPackFormatterProvider.Register(new AccessUpdateInfoFormatter()); MemoryPackFormatterProvider.Register(new AccessInfoFormatter()); @@ -83,7 +89,7 @@ namespace linker.messenger.serializer.memorypack MemoryPackFormatterProvider.Register(new FlowItemInfoFormatter()); MemoryPackFormatterProvider.Register(new FlowReportNetInfoFormatter()); - + MemoryPackFormatterProvider.Register(new FlowInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayFlowItemInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayFlowRequestInfoFormatter()); diff --git a/src/linker.messenger.serializer.memorypack/RelaySerializer.cs b/src/linker.messenger.serializer.memorypack/RelaySerializer.cs index 6605c8ba..045162fd 100644 --- a/src/linker.messenger.serializer.memorypack/RelaySerializer.cs +++ b/src/linker.messenger.serializer.memorypack/RelaySerializer.cs @@ -58,7 +58,7 @@ namespace linker.messenger.serializer.memorypack } } - + [MemoryPackable] public readonly partial struct SerializableRelayInfo @@ -89,11 +89,14 @@ namespace linker.messenger.serializer.memorypack [MemoryPackInclude] bool SSL => info.SSL; + [MemoryPackInclude] + string UserId => info.UserId; + [MemoryPackConstructor] SerializableRelayInfo(string fromMachineId, string fromMachineName, string remoteMachineId, string remoteMachineName, string transactionId, string secretKey, string transportName, ulong flowingId, - string nodeId, IPEndPoint server, bool ssl) + string nodeId, IPEndPoint server, bool ssl, string userid) { var info = new RelayInfo { @@ -107,7 +110,8 @@ namespace linker.messenger.serializer.memorypack TransactionId = transactionId, TransportName = transportName, SecretKey = secretKey, - Server = server + Server = server, + UserId = userid }; this.info = info; } @@ -295,7 +299,6 @@ namespace linker.messenger.serializer.memorypack - [MemoryPackable] public readonly partial struct SerializableRelayCacheInfo { @@ -315,8 +318,11 @@ namespace linker.messenger.serializer.memorypack [MemoryPackInclude] string GroupId => info.GroupId; + [MemoryPackInclude, MemoryPackAllowSerialize] + List Cdkey => info.Cdkey; + [MemoryPackConstructor] - SerializableRelayCacheInfo(ulong flowId, string fromId, string fromName, string toId, string toName, string groupId) + SerializableRelayCacheInfo(ulong flowId, string fromId, string fromName, string toId, string toName, string groupId, List cdkey) { var info = new RelayCacheInfo { @@ -326,6 +332,7 @@ namespace linker.messenger.serializer.memorypack GroupId = groupId, ToId = toId, ToName = toName, + Cdkey = cdkey }; this.info = info; } @@ -427,4 +434,340 @@ namespace linker.messenger.serializer.memorypack value = wrapped.info; } } + + + [MemoryPackable] + public readonly partial struct SerializableRelayServerCdkeyInfo + { + [MemoryPackIgnore] + public readonly RelayServerCdkeyInfo info; + + [MemoryPackInclude] + string Id => info.Id; + [MemoryPackInclude] + string UserId => info.UserId; + + + [MemoryPackInclude] + string CdKey => info.CdKey; + [MemoryPackInclude] + DateTime AddTime => info.AddTime; + [MemoryPackInclude] + DateTime StartTime => info.StartTime; + [MemoryPackInclude] + DateTime EndTime => info.EndTime; + [MemoryPackInclude] + List Nodes => info.Nodes; + [MemoryPackInclude] + double Bandwidth => info.Bandwidth; + [MemoryPackInclude] + ulong MaxBytes => info.MaxBytes; + [MemoryPackInclude] + ulong LastBytes => info.LastBytes; + [MemoryPackInclude] + double Memory => info.Memory; + [MemoryPackInclude] + double PayMemory => info.PayMemory; + [MemoryPackInclude] + string Remark => info.Remark; + + [MemoryPackConstructor] + SerializableRelayServerCdkeyInfo(string id, string userid, string cdKey, DateTime addTime, DateTime startTime, DateTime endTime, + List nodes, double bandwidth, ulong maxBytes, ulong lastBytes, double memory, double payMemory, string remark) + { + var info = new RelayServerCdkeyInfo + { + Id = id, + UserId = userid, + CdKey = cdKey, + AddTime = addTime, + StartTime = startTime, + EndTime = endTime, + Nodes = nodes, + Bandwidth = bandwidth, + MaxBytes = maxBytes, + LastBytes = lastBytes, + Memory = memory, + PayMemory = payMemory, + Remark = remark + }; + this.info = info; + } + + public SerializableRelayServerCdkeyInfo(RelayServerCdkeyInfo info) + { + this.info = info; + } + } + public class RelayServerCdkeyInfoFormatter : MemoryPackFormatter + { + public override void Serialize(ref MemoryPackWriter writer, scoped ref RelayServerCdkeyInfo value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WritePackable(new SerializableRelayServerCdkeyInfo(value)); + } + + public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerCdkeyInfo value) + { + if (reader.PeekIsNull()) + { + reader.Advance(1); // skip null block + value = null; + return; + } + + var wrapped = reader.ReadPackable(); + value = wrapped.info; + } + } + + + + [MemoryPackable] + public readonly partial struct SerializableRelayServerCdkeyAddInfo + { + [MemoryPackIgnore] + public readonly RelayServerCdkeyAddInfo info; + + [MemoryPackInclude] + string SecretKey => info.SecretKey; + [MemoryPackInclude, MemoryPackAllowSerialize] + RelayServerCdkeyInfo Data => info.Data; + + [MemoryPackConstructor] + SerializableRelayServerCdkeyAddInfo(string secretKey, RelayServerCdkeyInfo data) + { + var info = new RelayServerCdkeyAddInfo + { + SecretKey = secretKey, + Data = data + }; + this.info = info; + } + + public SerializableRelayServerCdkeyAddInfo(RelayServerCdkeyAddInfo info) + { + this.info = info; + } + } + public class RelayServerCdkeyAddInfoFormatter : MemoryPackFormatter + { + public override void Serialize(ref MemoryPackWriter writer, scoped ref RelayServerCdkeyAddInfo value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WritePackable(new SerializableRelayServerCdkeyAddInfo(value)); + } + + public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerCdkeyAddInfo value) + { + if (reader.PeekIsNull()) + { + reader.Advance(1); // skip null block + value = null; + return; + } + + var wrapped = reader.ReadPackable(); + value = wrapped.info; + } + } + + + [MemoryPackable] + public readonly partial struct SerializableRelayServerCdkeyDelInfo + { + [MemoryPackIgnore] + public readonly RelayServerCdkeyDelInfo info; + + [MemoryPackInclude] + string SecretKey => info.SecretKey; + [MemoryPackInclude] + string Id => info.Id; + + [MemoryPackConstructor] + SerializableRelayServerCdkeyDelInfo(string secretKey, string id) + { + var info = new RelayServerCdkeyDelInfo + { + SecretKey = secretKey, + Id = id + }; + this.info = info; + } + + public SerializableRelayServerCdkeyDelInfo(RelayServerCdkeyDelInfo info) + { + this.info = info; + } + } + public class RelayServerCdkeyDelInfoFormatter : MemoryPackFormatter + { + public override void Serialize(ref MemoryPackWriter writer, scoped ref RelayServerCdkeyDelInfo value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WritePackable(new SerializableRelayServerCdkeyDelInfo(value)); + } + + public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerCdkeyDelInfo value) + { + if (reader.PeekIsNull()) + { + reader.Advance(1); // skip null block + value = null; + return; + } + + var wrapped = reader.ReadPackable(); + value = wrapped.info; + } + } + + + [MemoryPackable] + public readonly partial struct SerializableRelayServerCdkeyPageRequestInfo + { + [MemoryPackIgnore] + public readonly RelayServerCdkeyPageRequestInfo info; + + [MemoryPackInclude] + int Page => info.Page; + [MemoryPackInclude] + int Size => info.Size; + [MemoryPackInclude] + string Order => info.Order; + [MemoryPackInclude] + string Sort => info.Sort; + + [MemoryPackInclude] + string UserId => info.UserId; + [MemoryPackInclude] + string Remark => info.Remark; + [MemoryPackInclude] + string SecretKey => info.SecretKey; + + [MemoryPackConstructor] + SerializableRelayServerCdkeyPageRequestInfo(int page, int size, string order, string sort, string userid, string remark, string secretKey) + { + var info = new RelayServerCdkeyPageRequestInfo + { + Sort = sort, + Order = order, + Size = size, + Page = page, + UserId = userid, + Remark = remark, + SecretKey = secretKey + }; + this.info = info; + } + + public SerializableRelayServerCdkeyPageRequestInfo(RelayServerCdkeyPageRequestInfo info) + { + this.info = info; + } + } + public class RelayServerCdkeyPageRequestInfoFormatter : MemoryPackFormatter + { + public override void Serialize(ref MemoryPackWriter writer, scoped ref RelayServerCdkeyPageRequestInfo value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WritePackable(new SerializableRelayServerCdkeyPageRequestInfo(value)); + } + + public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerCdkeyPageRequestInfo value) + { + if (reader.PeekIsNull()) + { + reader.Advance(1); // skip null block + value = null; + return; + } + + var wrapped = reader.ReadPackable(); + value = wrapped.info; + } + } + + + + [MemoryPackable] + public readonly partial struct SerializableRelayServerCdkeyPageResultInfo + { + [MemoryPackIgnore] + public readonly RelayServerCdkeyPageResultInfo info; + + [MemoryPackInclude] + int Page => info.Page; + [MemoryPackInclude] + int Size => info.Size; + [MemoryPackInclude] + int Count => info.Count; + [MemoryPackInclude] + List List => info.List; + + [MemoryPackConstructor] + SerializableRelayServerCdkeyPageResultInfo(int page, int size, int count, List list) + { + var info = new RelayServerCdkeyPageResultInfo + { + Count = count, + List = list, + Size = size, + Page = page + }; + this.info = info; + } + + public SerializableRelayServerCdkeyPageResultInfo(RelayServerCdkeyPageResultInfo info) + { + this.info = info; + } + } + public class RelayServerCdkeyPageResultInfoFormatter : MemoryPackFormatter + { + public override void Serialize(ref MemoryPackWriter writer, scoped ref RelayServerCdkeyPageResultInfo value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WritePackable(new SerializableRelayServerCdkeyPageResultInfo(value)); + } + + public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerCdkeyPageResultInfo value) + { + if (reader.PeekIsNull()) + { + reader.Advance(1); // skip null block + value = null; + return; + } + + var wrapped = reader.ReadPackable(); + value = wrapped.info; + } + } + } diff --git a/src/linker.messenger.signin/Config.cs b/src/linker.messenger.signin/Config.cs index 1599912e..21ce1cb9 100644 --- a/src/linker.messenger.signin/Config.cs +++ b/src/linker.messenger.signin/Config.cs @@ -42,7 +42,8 @@ namespace linker.messenger.signin public string Name { get; set; } = string.Empty; public string Host { get; set; } = string.Empty; public string SecretKey { get; set; } = string.Empty; - + public string UserId { get; set; } = Guid.NewGuid().ToString(); + } public sealed class SignInConfigServerInfo diff --git a/src/linker.messenger.signin/ISignInClientStore.cs b/src/linker.messenger.signin/ISignInClientStore.cs index 85fadcdf..77742d99 100644 --- a/src/linker.messenger.signin/ISignInClientStore.cs +++ b/src/linker.messenger.signin/ISignInClientStore.cs @@ -45,6 +45,11 @@ /// public void SetSecretKey(string secretKey); /// + /// 设置用户id + /// + /// + public void SetUserId(string userid); + /// /// 信标服务器 /// /// diff --git a/src/linker.messenger.store.file/Entry.cs b/src/linker.messenger.store.file/Entry.cs index 718d82eb..f3c23797 100644 --- a/src/linker.messenger.store.file/Entry.cs +++ b/src/linker.messenger.store.file/Entry.cs @@ -59,6 +59,7 @@ namespace linker.messenger.store.file serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -66,6 +67,7 @@ namespace linker.messenger.store.file serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -107,6 +109,7 @@ namespace linker.messenger.store.file SyncTreansfer syncTreansfer = serviceProvider.GetService(); syncTreansfer.AddSyncs(new List { serviceProvider.GetService(), + serviceProvider.GetService(), serviceProvider.GetService(), serviceProvider.GetService(), diff --git a/src/linker.messenger.store.file/relay/RelayServerCdkeyStore.cs b/src/linker.messenger.store.file/relay/RelayServerCdkeyStore.cs new file mode 100644 index 00000000..ffb0950e --- /dev/null +++ b/src/linker.messenger.store.file/relay/RelayServerCdkeyStore.cs @@ -0,0 +1,65 @@ +using linker.messenger.relay.server; +using LiteDB; + +namespace linker.messenger.store.file.relay +{ + public sealed class RelayServerCdkeyStore : IRelayServerCdkeyStore + { + private readonly Storefactory dBfactory; + private readonly ILiteCollection liteCollection; + public RelayServerCdkeyStore(Storefactory dBfactory, FileConfig fileConfig) + { + this.dBfactory = dBfactory; + liteCollection = dBfactory.GetCollection("relayCdkey"); + } + + public async Task Add(RelayServerCdkeyInfo info) + { + if (string.IsNullOrWhiteSpace(info.Id)) + { + info.Id = ObjectId.NewObjectId().ToString(); + liteCollection.Insert(info); + } + else + { + liteCollection.Update(info); + } + return await Task.FromResult(true); + } + public async Task Del(string id) + { + return await Task.FromResult(liteCollection.Delete(id)); + } + + public async Task> Get(string userid) + { + return await Task.FromResult(liteCollection.Find(x => x.UserId == userid && x.LastBytes > 0 && x.StartTime <= DateTime.Now && x.EndTime < DateTime.Now).ToList()); + } + + public async Task Get(RelayServerCdkeyPageRequestInfo relayServerCdkeyPageRequestInfo) + { + ILiteQueryable query = liteCollection.Query(); + + if (string.IsNullOrWhiteSpace(relayServerCdkeyPageRequestInfo.Order) == false) + { + query = query.OrderBy(relayServerCdkeyPageRequestInfo.Order, relayServerCdkeyPageRequestInfo.Sort == "asc" ? Query.Ascending : Query.Descending); + } + if (string.IsNullOrWhiteSpace(relayServerCdkeyPageRequestInfo.UserId) == false) + { + query = query.Where(x => x.UserId == relayServerCdkeyPageRequestInfo.UserId); + } + if (string.IsNullOrWhiteSpace(relayServerCdkeyPageRequestInfo.Remark) == false) + { + query = query.Where(x => x.Remark.Contains(relayServerCdkeyPageRequestInfo.Remark)); + } + + return await Task.FromResult(new RelayServerCdkeyPageResultInfo + { + Page = relayServerCdkeyPageRequestInfo.Page, + Size = relayServerCdkeyPageRequestInfo.Size, + Count = query.Count(), + List = query.Skip((relayServerCdkeyPageRequestInfo.Page - 1) * relayServerCdkeyPageRequestInfo.Size).Limit(relayServerCdkeyPageRequestInfo.Size).ToList() + }); + } + } +} diff --git a/src/linker.messenger.store.file/signIn/SignInClientStore.cs b/src/linker.messenger.store.file/signIn/SignInClientStore.cs index c3b03cfc..42123cdf 100644 --- a/src/linker.messenger.store.file/signIn/SignInClientStore.cs +++ b/src/linker.messenger.store.file/signIn/SignInClientStore.cs @@ -43,6 +43,11 @@ namespace linker.messenger.store.file.signIn Server.SecretKey = secretKey; config.Data.Update(); } + public void SetUserId(string userid) + { + Server.UserId = userid; + config.Data.Update(); + } public void SetHost(string host) { Server.Host = host; diff --git a/src/linker.messenger.store.file/signIn/SignInSync.cs b/src/linker.messenger.store.file/signIn/SignInSync.cs index 178f1625..d5b53858 100644 --- a/src/linker.messenger.store.file/signIn/SignInSync.cs +++ b/src/linker.messenger.store.file/signIn/SignInSync.cs @@ -46,6 +46,27 @@ namespace linker.messenger.store.file.signIn signInClientStore.SetSecretKey(serializer.Deserialize(data.Span)); } } + public sealed class SignInSyncUserId : ISync + { + public string Name => "SignInUserId"; + + private readonly ISignInClientStore signInClientStore; + private readonly ISerializer serializer; + public SignInSyncUserId(ISignInClientStore signInClientStore, ISerializer serializer) + { + this.signInClientStore = signInClientStore; + this.serializer = serializer; + } + public Memory GetData() + { + return serializer.Serialize(signInClientStore.Server.UserId); + } + + public void SetData(Memory data) + { + signInClientStore.SetUserId(serializer.Deserialize(data.Span)); + } + } public sealed class SignInSyncGroupSecretKey : ISync { public string Name => "GroupSecretKey"; diff --git a/src/linker.messenger.tunnel/TunnelNetworkTransfer.cs b/src/linker.messenger.tunnel/TunnelNetworkTransfer.cs index 8d2040f5..df6d957f 100644 --- a/src/linker.messenger.tunnel/TunnelNetworkTransfer.cs +++ b/src/linker.messenger.tunnel/TunnelNetworkTransfer.cs @@ -35,10 +35,13 @@ namespace linker.messenger.tunnel { LoggerHelper.Instance.Info($"tunnel route level getting."); Info.RouteLevel = NetworkHelper.GetRouteLevel(signInClientStore.Server.Host, out List ips); - Info.RouteIPs = ips.ToArray(); - Info.LocalIPs = NetworkHelper.GetIPV6().Concat(NetworkHelper.GetIPV4()).ToArray(); LoggerHelper.Instance.Warning($"route ips:{string.Join(",", ips.Select(c => c.ToString()))}"); - LoggerHelper.Instance.Warning($"tunnel local ips :{string.Join(",", Info.LocalIPs.Select(c => c.ToString()))}"); + Info.RouteIPs = ips.ToArray(); + var ipv6 = NetworkHelper.GetIPV6(); + LoggerHelper.Instance.Warning($"tunnel local ip6 :{string.Join(",", ipv6.Select(c => c.ToString()))}"); + var ipv4 = NetworkHelper.GetIPV4(); + LoggerHelper.Instance.Warning($"tunnel local ip4 :{string.Join(",", ipv4.Select(c => c.ToString()))}"); + Info.LocalIPs = ipv6.Concat(ipv4).ToArray(); LoggerHelper.Instance.Warning($"tunnel route level:{Info.RouteLevel}"); } diff --git a/src/linker.tun/LinkerWinTunDevice.cs b/src/linker.tun/LinkerWinTunDevice.cs index bce1909c..a8f9b8b4 100644 --- a/src/linker.tun/LinkerWinTunDevice.cs +++ b/src/linker.tun/LinkerWinTunDevice.cs @@ -22,6 +22,8 @@ namespace linker.tun private IPAddress address; private byte prefixLength = 24; + private string defaultInterfaceName = string.Empty; + private CancellationTokenSource tokenSource; public LinkerWinTunDevice() @@ -67,6 +69,7 @@ namespace linker.tun AddIPV6(); GetWindowsInterfaceNum(); + GetDefaultInterface(); tokenSource = new CancellationTokenSource(); return true; @@ -115,7 +118,6 @@ namespace linker.tun } } - public void Shutdown() { tokenSource?.Cancel(); @@ -137,7 +139,6 @@ namespace linker.tun interfaceNumber = 0; } - public void SetMtu(int value) { CommandHelper.Windows(string.Empty, new string[] { @@ -157,20 +158,18 @@ namespace linker.tun IPAddress network = NetworkHelper.ToNetworkIP(this.address, NetworkHelper.ToPrefixValue(prefixLength)); CommandHelper.PowerShell($"New-NetNat -Name {Name} -InternalIPInterfaceAddressPrefix {network}/{prefixLength}", [], out error); - - if (string.IsNullOrWhiteSpace(error) == false) + if (string.IsNullOrWhiteSpace(error)) { - error = "NetNat Not Supported"; - string result = CommandHelper.Windows(string.Empty, ["netsh routing"]); - if (result.Contains("netsh routing ip")) - { - error = string.Empty; - } - else - { - error += ",RRAS Not Supported"; - } + return; } + + CommandHelper.Windows(string.Empty, [$"net start SharedAccess"]); + string result = CommandHelper.Windows(string.Empty, [$"linker.ics.exe {defaultInterfaceName} {Name} enable"]); + if (result.Contains($"enable success")) + { + return; + } + error = "NetNat and ICS not supported"; } catch (Exception ex) { @@ -186,6 +185,7 @@ namespace linker.tun { CommandHelper.PowerShell($"start-service WinNat", [], out error); CommandHelper.PowerShell($"Remove-NetNat -Name {Name} -Confirm:$false", [], out error); + CommandHelper.Windows(string.Empty, [$"linker.ics.exe {Name} disable"]); } catch (Exception ex) { @@ -327,6 +327,33 @@ namespace linker.tun } } + private void GetDefaultInterface() + { + string[] lines = CommandHelper.Windows(string.Empty, new string[] { $"route print" }).Split(Environment.NewLine); + foreach (var item in lines) + { + if (item.Trim().StartsWith("0.0.0.0")) + { + string[] arr = Regex.Replace(item.Trim(), @"\s+", " ").Split(' '); + IPAddress ip = IPAddress.Parse(arr[arr.Length - 2]); + + foreach (var inter in NetworkInterface.GetAllNetworkInterfaces()) + { + try + { + if (ip.Equals(inter.GetIPProperties().UnicastAddresses.FirstOrDefault(c => c.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).Address)) + { + defaultInterfaceName = inter.Name; + return; + } + } + catch (Exception) + { + } + } + } + } + } private void ClearRegistry() { diff --git a/src/linker.web/src/apis/relay.js b/src/linker.web/src/apis/relay.js index e5dc2d70..23a59da8 100644 --- a/src/linker.web/src/apis/relay.js +++ b/src/linker.web/src/apis/relay.js @@ -8,4 +8,7 @@ export const setRelaySubscribe = () => { } export const relayConnect = (data) => { return sendWebsocketMsg('relay/Connect', data); +} +export const relayCdkeyAccess = () => { + return sendWebsocketMsg('relay/AccessCdkey'); } \ No newline at end of file diff --git a/src/linker.web/src/assets/style.css b/src/linker.web/src/assets/style.css index 9cce7e21..bbb662b7 100644 --- a/src/linker.web/src/assets/style.css +++ b/src/linker.web/src/assets/style.css @@ -119,18 +119,34 @@ a.a-line { padding-right: 1rem; } -.m-r-1 { - margin-right: 1rem; +.mgr-1 { + margin-right: 1rem !important; } -.m-l-1 { +.mgl-1 { margin-left: 1rem; } -.m-b-0 { +.mgl-2 { + margin-left: 2rem; +} + +.mgl-3 { + margin-left: 3rem; +} + +.mgb-0 { margin-bottom: 0 !important; } +.mgb-3 { + margin-bottom: 3rem; +} + +.mgt-3 { + margin-top: 3rem; +} + table { border-spacing: 0; border-collapse: collapse; @@ -174,6 +190,10 @@ span.split-pad10 { color: #e68906 !important; } +.disable { + color: #ddd !important; +} + .gateway { &.green { /* background: linear-gradient(270deg, #caff00, green, #0d6d23, #e38a00, green); */ diff --git a/src/linker.web/src/lang/en-us.js b/src/linker.web/src/lang/en-us.js index 15569a17..b5cb066a 100644 --- a/src/linker.web/src/lang/en-us.js +++ b/src/linker.web/src/lang/en-us.js @@ -7,6 +7,7 @@ export default { 'common.operating': 'In operation', 'common.tips': 'Tips', 'common.option': 'Option', + 'common.access': 'No access', 'head.home': 'Home', 'head.server': 'Server', @@ -36,6 +37,8 @@ export default { 'server.messengerText': 'ip:port or domain:port', 'server.messengerSecretKey': 'Messenger SecretKey', 'server.messengerSecretKeyText': 'Messenger SecretKey', + 'server.messengerUserId': 'User Id', + 'server.messengerUserIdText': 'Your unique identifier,for card key (CDKEY).', 'permission.closed': 'Closed', 'permission.simple': 'Simple', @@ -120,6 +123,8 @@ export default { 'server.relayPublic': 'Public', 'server.relayOper': 'Oper', 'server.relayUse': 'Use', + 'server.relayMyCdkey': 'My CDKEY', + 'server.relayCdkey': 'Manager CDKEY', 'server.sforwardSecretKey': 'Server forward secretKey', 'server.sforwardText': 'The server forward can be used when the key is correct', @@ -148,5 +153,7 @@ export default { 'server.asyncRelaySecretKey': 'Relay secretKey', 'server.asyncSForwardSecretKey': 'Server forward secretKey', 'server.asyncUpdaterSecretKey': 'Update secretKey', - 'server.asyncTunnelTransports': 'Tunnel transports' + 'server.asyncTunnelTransports': 'Tunnel transports', + 'server.asyncSignInUserId': 'User Id', + } \ No newline at end of file diff --git a/src/linker.web/src/lang/zh-cn.js b/src/linker.web/src/lang/zh-cn.js index 197af071..388a9ab9 100644 --- a/src/linker.web/src/lang/zh-cn.js +++ b/src/linker.web/src/lang/zh-cn.js @@ -7,6 +7,7 @@ export default { 'common.operating': '正在操作', 'common.tips': '提示', 'common.option': '选项', + 'common.access': '无权限', 'head.home': '首页', 'head.server': '服务器', @@ -35,6 +36,8 @@ export default { 'server.messengerText': 'ip:端口 或者 域名:端口', 'server.messengerSecretKey': '信标密钥', 'server.messengerSecretKeyText': '密钥正确时可连接服务器', + 'server.messengerUserId': '用户id', + 'server.messengerUserIdText': '你的唯一标识,用于流量卡密CDKEY', 'permission.closed': '禁止通行', 'permission.simple': '简单管理', @@ -122,6 +125,8 @@ export default { 'server.relayPublic': '公开', 'server.relayOper': '操作', 'server.relayUse': '使用', + 'server.relayMyCdkey': '我的CDKEY', + 'server.relayCdkey': '管理CDKEY', 'server.sforwardSecretKey': '服务器穿透密钥', 'server.sforwardText': '当密钥正确是可用', @@ -150,5 +155,6 @@ export default { 'server.asyncRelaySecretKey': '中继密钥', 'server.asyncSForwardSecretKey': '服务器穿透密钥', 'server.asyncUpdaterSecretKey': '更新密钥', - 'server.asyncTunnelTransports': '打洞协议' + 'server.asyncTunnelTransports': '打洞协议', + 'server.asyncSignInUserId': '用户唯一标识', } \ No newline at end of file diff --git a/src/linker.web/src/views/Api.vue b/src/linker.web/src/views/Api.vue index 5cfd2010..a128814d 100644 --- a/src/linker.web/src/views/Api.vue +++ b/src/linker.web/src/views/Api.vue @@ -6,7 +6,7 @@ 接口 :
- 秘钥 : + 秘钥 :
保存密码 diff --git a/src/linker.web/src/views/full/devices/TuntapEdit.vue b/src/linker.web/src/views/full/devices/TuntapEdit.vue index bb5f5287..caec7f9f 100644 --- a/src/linker.web/src/views/full/devices/TuntapEdit.vue +++ b/src/linker.web/src/views/full/devices/TuntapEdit.vue @@ -16,7 +16,7 @@ - +
diff --git a/src/linker.web/src/views/full/devices/TuntapShow.vue b/src/linker.web/src/views/full/devices/TuntapShow.vue index 01aff90b..1723e233 100644 --- a/src/linker.web/src/views/full/devices/TuntapShow.vue +++ b/src/linker.web/src/views/full/devices/TuntapShow.vue @@ -34,13 +34,13 @@
diff --git a/src/linker.web/src/views/full/group/Index.vue b/src/linker.web/src/views/full/group/Index.vue index 836ac3af..87f7f6fb 100644 --- a/src/linker.web/src/views/full/group/Index.vue +++ b/src/linker.web/src/views/full/group/Index.vue @@ -32,6 +32,11 @@ + @@ -11,7 +12,9 @@ import { getSForwardSecretKey,setSForwardSecretKey } from '@/apis/sforward'; import { ElMessage } from 'element-plus'; import {onMounted, reactive } from 'vue' import { useI18n } from 'vue-i18n'; +import Sync from '../sync/Index.vue' export default { + components:{Sync}, setup(props) { const {t} = useI18n(); const state = reactive({ diff --git a/src/linker.web/src/views/full/server/SignInServers.vue b/src/linker.web/src/views/full/server/SignInServers.vue index 0189df98..9a636be2 100644 --- a/src/linker.web/src/views/full/server/SignInServers.vue +++ b/src/linker.web/src/views/full/server/SignInServers.vue @@ -7,16 +7,25 @@
- {{$t('server.messengerText')}} + + {{$t('server.messengerText')}}
- {{$t('server.messengerSecretKeyText')}} + + {{$t('server.messengerSecretKeyText')}}
- + +
+ + + {{$t('server.messengerUserIdText')}} +
+
+ @@ -38,8 +47,9 @@ import SForward from './SForward.vue'; import Updater from './Updater.vue'; import RelayServers from './RelayServers.vue'; import { useI18n } from 'vue-i18n'; +import Sync from '../sync/Index.vue' export default { - components:{SForward,Updater,RelayServers}, + components:{SForward,Updater,RelayServers,Sync}, setup(props) { const {t} = useI18n(); const globalData = injectGlobalData(); diff --git a/src/linker.web/src/views/full/server/Updater.vue b/src/linker.web/src/views/full/server/Updater.vue index 3d89b1c0..71e79107 100644 --- a/src/linker.web/src/views/full/server/Updater.vue +++ b/src/linker.web/src/views/full/server/Updater.vue @@ -2,10 +2,11 @@
- {{$t('server.updaterText')}} + + {{$t('server.updaterText')}}
- + + + \ No newline at end of file diff --git a/src/linker.web/src/views/full/status/Export.vue b/src/linker.web/src/views/full/status/Export.vue index b4fd5149..374bb515 100644 --- a/src/linker.web/src/views/full/status/Export.vue +++ b/src/linker.web/src/views/full/status/Export.vue @@ -56,7 +56,6 @@ export default { const hasExport = computed(()=>globalData.value.hasAccess('Export')); const onlyNode = computed(()=>globalData.value.config.Client.OnlyNode); const machineId = computed(()=>globalData.value.config.Client.Id); - console.log(globalData.value.config.Client); const state = reactive({ show: false, loading:false, diff --git a/src/linker.web/src/views/full/sync/Index.vue b/src/linker.web/src/views/full/sync/Index.vue new file mode 100644 index 00000000..03eb0803 --- /dev/null +++ b/src/linker.web/src/views/full/sync/Index.vue @@ -0,0 +1,45 @@ + + + + + \ No newline at end of file diff --git a/src/linker.web/src/views/full/transport/Index.vue b/src/linker.web/src/views/full/transport/Index.vue index b106a033..d3a0d4ea 100644 --- a/src/linker.web/src/views/full/transport/Index.vue +++ b/src/linker.web/src/views/full/transport/Index.vue @@ -27,6 +27,11 @@
+