From aa65b168920cad2bd0ce12d90bdd2dad3406e9ce Mon Sep 17 00:00:00 2001 From: snltty <1069410172@qq.com> Date: Wed, 10 Jul 2024 19:03:21 +0800 Subject: [PATCH] sync --- linker.tunnel/TunnelTransfer.cs | 56 ++++++- linker.tunnel/proxy/TunnelProxy.cs | 9 ++ linker.tunnel/proxy/TunnelProxyTcp.cs | 42 +++-- linker.tunnel/proxy/TunnelProxyUdp.cs | 28 ++-- linker.updater/Program.cs | 98 +++++++++++- linker.updater/linker.updater.csproj | 1 + linker.web/src/components/install/Index.vue | 158 +++++++++++++------ linker/client/config/Config.cs | 2 +- linker/plugins/forward/proxy/ForwardProxy.cs | 2 + linker/plugins/tuntap/proxy/TuntapProxy.cs | 1 + linker/plugins/updater/UpdaterStartup.cs | 43 +++++ linker/plugins/updater/config/config.cs | 52 ++++++ publish.bat | 2 +- 13 files changed, 408 insertions(+), 86 deletions(-) create mode 100644 linker/plugins/updater/UpdaterStartup.cs create mode 100644 linker/plugins/updater/config/config.cs diff --git a/linker.tunnel/TunnelTransfer.cs b/linker.tunnel/TunnelTransfer.cs index 06ddbb78..8d959461 100644 --- a/linker.tunnel/TunnelTransfer.cs +++ b/linker.tunnel/TunnelTransfer.cs @@ -118,10 +118,8 @@ namespace linker.tunnel /// public async Task ConnectAsync(string remoteMachineId, string transactionId) { - if (connectingDic.TryAdd(remoteMachineId, true) == false) - { - return null; - } + if (connectingDic.TryAdd(remoteMachineId, true) == false) return null; + if (IsBackground(remoteMachineId, transactionId)) return null; try { @@ -221,7 +219,6 @@ namespace linker.tunnel { connectingDic.TryRemove(remoteMachineId, out _); } - return null; } /// @@ -393,5 +390,54 @@ namespace linker.tunnel tunnelTransportInfo.RemoteEndPoints = eps; } + + + + private ConcurrentDictionary backgroundDic = new ConcurrentDictionary(); + public void StartBackground(string remoteMachineId, string transactionId) + { + if (IsBackground(remoteMachineId, transactionId)) return; + AddBackground(remoteMachineId, transactionId); + Task.Run(async () => + { + try + { + for (int i = 0; i < 10; i++) + { + await Task.Delay(3000); + + ITunnelConnection connection = await ConnectAsync(remoteMachineId, transactionId); + if (connection != null) + { + break; + } + } + } + catch (Exception) + { + } + finally + { + RemoveBackground(remoteMachineId, transactionId); + } + }); + + } + private void AddBackground(string remoteMachineId, string transactionId) + { + backgroundDic.TryAdd(GetBackgroundKey(remoteMachineId, transactionId), true); + } + private void RemoveBackground(string remoteMachineId, string transactionId) + { + backgroundDic.TryRemove(GetBackgroundKey(remoteMachineId, transactionId), out _); + } + private bool IsBackground(string remoteMachineId, string transactionId) + { + return backgroundDic.ContainsKey(GetBackgroundKey(remoteMachineId, transactionId)); + } + private string GetBackgroundKey(string remoteMachineId, string transactionId) + { + return $"{remoteMachineId}@{transactionId}"; + } } } diff --git a/linker.tunnel/proxy/TunnelProxy.cs b/linker.tunnel/proxy/TunnelProxy.cs index 067a95aa..059b3215 100644 --- a/linker.tunnel/proxy/TunnelProxy.cs +++ b/linker.tunnel/proxy/TunnelProxy.cs @@ -277,6 +277,15 @@ namespace linker.tunnel.proxy { GC.Collect(); } + + public ConnectId GetTcpConnectId() + { + return new ConnectId(Proxy.ConnectId, Connection.RemoteMachineId.GetHashCode(), Connection.TransactionId.GetHashCode(), (byte)Proxy.Direction); + } + public ConnectIdUdp GetUdpConnectId() + { + return new ConnectIdUdp(Proxy.ConnectId, Proxy.SourceEP, Connection.RemoteMachineId.GetHashCode(), Connection.TransactionId.GetHashCode()); + } } } diff --git a/linker.tunnel/proxy/TunnelProxyTcp.cs b/linker.tunnel/proxy/TunnelProxyTcp.cs index aa1ceb9d..5e8e1bc9 100644 --- a/linker.tunnel/proxy/TunnelProxyTcp.cs +++ b/linker.tunnel/proxy/TunnelProxyTcp.cs @@ -5,6 +5,7 @@ using System.Buffers; using System.Collections.Concurrent; using System.Net; using System.Net.Sockets; +using System.Collections.Generic; namespace linker.tunnel.proxy { @@ -106,7 +107,7 @@ namespace linker.tunnel.proxy } token.Proxy.Step = ProxyStep.Forward; //绑定 - tcpConnections.TryAdd(new ConnectId(token.Proxy.ConnectId, token.Connection.GetHashCode(), (byte)ProxyDirection.Reverse), token); + tcpConnections.TryAdd(token.GetConnectId(ProxyDirection.Reverse), token); } else if (closeConnect) { @@ -253,12 +254,12 @@ namespace linker.tunnel.proxy token.Socket.EndConnect(result); token.Socket.KeepAlive(); - + if (state.Data.Length > 0) { await token.Socket.SendAsync(state.Data.AsMemory(0, state.Length), SocketFlags.None).ConfigureAwait(false); } - tcpConnections.TryAdd(new ConnectId(token.Proxy.ConnectId, token.Connection.GetHashCode(), (byte)ProxyDirection.Forward), token); + tcpConnections.TryAdd(token.GetConnectId(ProxyDirection.Forward), token); await SendToConnection(token).ConfigureAwait(false); token.Proxy.Step = ProxyStep.Forward; @@ -286,7 +287,7 @@ namespace linker.tunnel.proxy { if (tunnelToken.Proxy.Protocol == ProxyProtocol.Tcp) { - ConnectId connectId = new ConnectId(tunnelToken.Proxy.ConnectId, tunnelToken.Connection.GetHashCode(), (byte)tunnelToken.Proxy.Direction); + ConnectId connectId = tunnelToken.GetTcpConnectId(); if (tcpConnections.TryGetValue(connectId, out AsyncUserToken token)) { _ = ProcessReceive(token); @@ -301,7 +302,7 @@ namespace linker.tunnel.proxy { if (tunnelToken.Proxy.Protocol == ProxyProtocol.Tcp) { - ConnectId connectId = new ConnectId(tunnelToken.Proxy.ConnectId, tunnelToken.Connection.GetHashCode(), (byte)tunnelToken.Proxy.Direction); + ConnectId connectId = tunnelToken.GetTcpConnectId(); if (tcpConnections.TryRemove(connectId, out AsyncUserToken token)) { CloseClientSocket(token); @@ -316,7 +317,7 @@ namespace linker.tunnel.proxy /// private async Task SendToSocketTcp(AsyncUserTunnelToken tunnelToken) { - ConnectId connectId = new ConnectId(tunnelToken.Proxy.ConnectId, tunnelToken.Connection.GetHashCode(), (byte)tunnelToken.Proxy.Direction); + ConnectId connectId = tunnelToken.GetTcpConnectId(); if (tunnelToken.Proxy.Step == ProxyStep.Close || tunnelToken.Proxy.Data.Length == 0) { if (tcpConnections.TryRemove(connectId, out AsyncUserToken token)) @@ -329,6 +330,7 @@ namespace linker.tunnel.proxy { try { + token1.Connection = tunnelToken.Connection; await token1.Socket.SendAsync(tunnelToken.Proxy.Data, SocketFlags.None).AsTask().WaitAsync(TimeSpan.FromMilliseconds(5000)).ConfigureAwait(false); } catch (Exception ex) @@ -348,14 +350,15 @@ namespace linker.tunnel.proxy if (token == null) return; if (token.Connection != null) { - tcpConnections.TryRemove(new ConnectId(token.Proxy.ConnectId, token.Connection.GetHashCode(), (byte)token.Proxy.Direction), out _); + tcpConnections.TryRemove(token.GetConnectId(), out _); } token.Clear(); } private void CloseClientSocketTcp(ITunnelConnection connection) { - int hashcode = connection.GetHashCode(); - var tokens = tcpConnections.Where(c => c.Key.hashcode == hashcode).ToList(); + int hashcode1 = connection.RemoteMachineId.GetHashCode(); + int hashcode2 = connection.TransactionId.GetHashCode(); + var tokens = tcpConnections.Where(c => c.Key.hashcode1 == hashcode1 && c.Key.hashcode2 == hashcode2).ToList(); foreach (var item in tokens) { try @@ -407,23 +410,25 @@ namespace linker.tunnel.proxy { public bool Equals(ConnectId x, ConnectId y) { - return x.connectId == y.connectId && x.hashcode == y.hashcode && x.direction == y.direction; + return x.connectId == y.connectId && x.hashcode1 == y.hashcode1 && x.hashcode2 == y.hashcode2 && x.direction == y.direction; } public int GetHashCode(ConnectId obj) { - return obj.connectId.GetHashCode() ^ obj.hashcode ^ obj.direction; + return obj.connectId.GetHashCode() ^ obj.hashcode1 ^ obj.hashcode2 ^ obj.direction; } } public record struct ConnectId { public ulong connectId; - public int hashcode; + public int hashcode1; + public int hashcode2; public byte direction; - public ConnectId(ulong connectId, int hashcode, byte direction) + public ConnectId(ulong connectId, int hashcode1, int hashcode2, byte direction) { this.connectId = connectId; - this.hashcode = hashcode; + this.hashcode1 = hashcode1; + this.hashcode2 = hashcode2; this.direction = direction; } } @@ -450,6 +455,15 @@ namespace linker.tunnel.proxy GC.Collect(); } + + public ConnectId GetConnectId() + { + return new ConnectId(Proxy.ConnectId, Connection.RemoteMachineId.GetHashCode(), Connection.TransactionId.GetHashCode(), (byte)Proxy.Direction); + } + public ConnectId GetConnectId(ProxyDirection proxyDirection) + { + return new ConnectId(Proxy.ConnectId, Connection.RemoteMachineId.GetHashCode(), Connection.TransactionId.GetHashCode(), (byte)proxyDirection); + } } public sealed class ConnectState { diff --git a/linker.tunnel/proxy/TunnelProxyUdp.cs b/linker.tunnel/proxy/TunnelProxyUdp.cs index cffc2aec..fe1258e3 100644 --- a/linker.tunnel/proxy/TunnelProxyUdp.cs +++ b/linker.tunnel/proxy/TunnelProxyUdp.cs @@ -153,7 +153,7 @@ namespace linker.tunnel.proxy if (tunnelToken.Proxy.Direction == ProxyDirection.Forward) { - ConnectIdUdp connectId = new ConnectIdUdp(tunnelToken.Proxy.ConnectId, tunnelToken.Proxy.SourceEP, tunnelToken.Connection.GetHashCode()); + ConnectIdUdp connectId = tunnelToken.GetUdpConnectId(); try { IPEndPoint target = new IPEndPoint(tunnelToken.Proxy.TargetEP.Address, tunnelToken.Proxy.TargetEP.Port); @@ -185,6 +185,7 @@ namespace linker.tunnel.proxy { try { + asyncUserUdpToken.Connection = tunnelToken.Connection; if (await ConnectionReceiveUdp(tunnelToken, asyncUserUdpToken).ConfigureAwait(false) == false) { await asyncUserUdpToken.SourceSocket.SendToAsync(tunnelToken.Proxy.Data, tunnelToken.Proxy.SourceEP).ConfigureAwait(false); @@ -207,7 +208,7 @@ namespace linker.tunnel.proxy await socket.SendToAsync(tunnelToken.Proxy.Data, target).ConfigureAwait(false); - ConnectIdUdp connectId = new ConnectIdUdp(tunnelToken.Proxy.ConnectId, tunnelToken.Proxy.SourceEP, tunnelToken.Connection.GetHashCode()); + ConnectIdUdp connectId = tunnelToken.GetUdpConnectId(); AsyncUserUdpTokenTarget udpToken = new AsyncUserUdpTokenTarget { Proxy = new ProxyInfo @@ -270,8 +271,8 @@ namespace linker.tunnel.proxy /// private async Task SendToConnection(AsyncUserUdpTokenTarget token) { - // SemaphoreSlim semaphoreSlim = token.Proxy.Direction == ProxyDirection.Forward ? semaphoreSlimForward : semaphoreSlimReverse; - // await semaphoreSlim.WaitAsync(); + // SemaphoreSlim semaphoreSlim = token.Proxy.Direction == ProxyDirection.Forward ? semaphoreSlimForward : semaphoreSlimReverse; + // await semaphoreSlim.WaitAsync(); byte[] connectData = token.Proxy.ToBytes(out int length); @@ -290,7 +291,7 @@ namespace linker.tunnel.proxy finally { token.Proxy.Return(connectData); - // semaphoreSlim.Release(); + // semaphoreSlim.Release(); } } @@ -325,8 +326,9 @@ namespace linker.tunnel.proxy private void CloseClientSocketUdp(ITunnelConnection connection) { - int hashcode = connection.GetHashCode(); - var tokens = udpConnections.Where(c => c.Key.hashcode == hashcode).ToList(); + int hashcode1 = connection.RemoteMachineId.GetHashCode(); + int hashcode2 = connection.TransactionId.GetHashCode(); + var tokens = udpConnections.Where(c => c.Key.hashcode1 == hashcode1 && c.Key.hashcode2 == hashcode2).ToList(); foreach (var item in tokens) { try @@ -437,25 +439,27 @@ namespace linker.tunnel.proxy { public bool Equals(ConnectIdUdp x, ConnectIdUdp y) { - return x.source != null && x.source.Equals(y.source) && x.connectId == y.connectId && x.hashcode == y.hashcode; + return x.source != null && x.source.Equals(y.source) && x.connectId == y.connectId && x.hashcode1 == y.hashcode1 && x.hashcode2 == y.hashcode2; } public int GetHashCode(ConnectIdUdp obj) { if (obj.source == null) return 0; - return obj.source.GetHashCode() ^ obj.connectId.GetHashCode() ^ obj.hashcode; + return obj.source.GetHashCode() ^ obj.connectId.GetHashCode() ^ obj.hashcode1 ^ obj.hashcode2; } } public readonly struct ConnectIdUdp { public readonly IPEndPoint source { get; } public readonly ulong connectId { get; } - public int hashcode { get; } + public int hashcode1 { get; } + public int hashcode2 { get; } - public ConnectIdUdp(ulong connectId, IPEndPoint source, int hashcode) + public ConnectIdUdp(ulong connectId, IPEndPoint source, int hashcode1, int hashcode2) { this.connectId = connectId; this.source = source; - this.hashcode = hashcode; + this.hashcode1 = hashcode1; + this.hashcode2 = hashcode2; } } } diff --git a/linker.updater/Program.cs b/linker.updater/Program.cs index 5fe85c79..1ce7747a 100644 --- a/linker.updater/Program.cs +++ b/linker.updater/Program.cs @@ -1,7 +1,10 @@ using Fizzler.Systems.HtmlAgilityPack; using HtmlAgilityPack; using linker.libs; +using System.Diagnostics; +using System.IO.Compression; using System.Runtime.InteropServices; +using System.Text; namespace linker.updater { @@ -13,17 +16,36 @@ namespace linker.updater await Helper.Await(); } - + static string rootPath = "./updater"; static void Updater() { Task.Factory.StartNew(async () => { while (true) { - UpdateInfo updateInfo = GetUpdateInfo(); - if (updateInfo != null) + try + { + UpdateInfo updateInfo = GetUpdateInfo(); + if (updateInfo != null) + { + if (NeedDownload(updateInfo)) + { + await DownloadUpdate(updateInfo); + } + } + } + catch (Exception) + { + } + try + { + if (NeedExtract()) + { + ExtractUpdate(); + } + } + catch (Exception) { - } await Task.Delay(15000); @@ -32,7 +54,75 @@ namespace linker.updater }, TaskCreationOptions.LongRunning); } + static bool NeedExtract() + { + try + { + return File.Exists(Path.Join(rootPath, "version.txt")) + && File.Exists(Path.Join(rootPath,"updater.zip")) + && File.Exists(Path.Join(rootPath, "extract.txt")) + && File.ReadAllText(Path.Join(rootPath, "version.txt")) != $"v{FileVersionInfo.GetVersionInfo("linker.exe").FileVersion}"; + } + catch (Exception) + { + } + return false; + } + static void ExtractUpdate() + { + try + { + ZipFile.ExtractToDirectory(Path.Join(rootPath, "updater.zip"), "./", Encoding.UTF8, true); + File.Delete(Path.Join(rootPath, "version.txt")); + File.Delete(Path.Join(rootPath, "msg.txt")); + File.Delete(Path.Join(rootPath, "extract.txt")); + File.Delete(Path.Join(rootPath, "updater.zip")); + } + catch (Exception) + { + } + } + + static bool NeedDownload(UpdateInfo updateInfo) + { + try + { + return true; + return (File.Exists(Path.Join(rootPath, "version.txt")) == false + || File.ReadAllText(Path.Join(rootPath, "version.txt")) != updateInfo.Tag) + && $"v{FileVersionInfo.GetVersionInfo("linker.exe").FileVersion}" != updateInfo.Tag; + } + catch (Exception) + { + } + return false; + } + static async Task DownloadUpdate(UpdateInfo updateInfo) + { + try + { + if (Directory.Exists(rootPath) == false) + { + Directory.CreateDirectory(rootPath); + } + + using FileStream fileStream = new FileStream(Path.Join(rootPath, "updater.zip"), FileMode.OpenOrCreate, FileAccess.ReadWrite); + using HttpClient httpClient = new HttpClient(); + using Stream stream = await httpClient.GetStreamAsync(updateInfo.Url); + await stream.CopyToAsync(fileStream); + + fileStream.Flush(); + fileStream.Close(); + fileStream.Dispose(); + + File.WriteAllText(Path.Join(rootPath, "version.txt"), updateInfo.Tag); + File.WriteAllText(Path.Join(rootPath, "msg.txt"), updateInfo.Msg); + } + catch (Exception) + { + } + } static UpdateInfo GetUpdateInfo() { try diff --git a/linker.updater/linker.updater.csproj b/linker.updater/linker.updater.csproj index 69e1f23d..8851a610 100644 --- a/linker.updater/linker.updater.csproj +++ b/linker.updater/linker.updater.csproj @@ -41,6 +41,7 @@ + diff --git a/linker.web/src/components/install/Index.vue b/linker.web/src/components/install/Index.vue index d8990ba3..b74a1e53 100644 --- a/linker.web/src/components/install/Index.vue +++ b/linker.web/src/components/install/Index.vue @@ -1,54 +1,106 @@