diff --git a/cmonitor.viewer.client.win/default.aproj b/cmonitor.viewer.client.win/default.aproj index 9066e58f..cf64e78b 100644 --- a/cmonitor.viewer.client.win/default.aproj +++ b/cmonitor.viewer.client.win/default.aproj @@ -1,5 +1,5 @@  - + diff --git a/cmonitor.viewer.client.win/dist/cmonitor.viewer.client.win.exe b/cmonitor.viewer.client.win/dist/cmonitor.viewer.client.win.exe index 1ca52569..d503eba2 100644 Binary files a/cmonitor.viewer.client.win/dist/cmonitor.viewer.client.win.exe and b/cmonitor.viewer.client.win/dist/cmonitor.viewer.client.win.exe differ diff --git a/cmonitor.viewer.client.win/main.aardio b/cmonitor.viewer.client.win/main.aardio index abbcba32..1d7cc6e4 100644 --- a/cmonitor.viewer.client.win/main.aardio +++ b/cmonitor.viewer.client.win/main.aardio @@ -51,9 +51,9 @@ mainForm.connect = function(){ mainForm.show(); if(!_STUDIO_INVOKED) { - mainForm.fullscreen(); - mainForm.modifyStyleEx(0x40000/*_WS_EX_APPWINDOW*/,0x80/*_WS_EX_TOOLWINDOW*/); - ::SetWindowPos(mainForm.hwnd,-1/*_HWND_TOPMOST*/,0,0,0,0,0x2/*_SWP_NOMOVE*/ + 0x1/*_SWP_NOSIZE*/); + //mainForm.fullscreen(); + //mainForm.modifyStyleEx(0x40000/*_WS_EX_APPWINDOW*/,0x80/*_WS_EX_TOOLWINDOW*/); + //::SetWindowPos(mainForm.hwnd,-1/*_HWND_TOPMOST*/,0,0,0,0,0x2/*_SWP_NOMOVE*/ + 0x1/*_SWP_NOSIZE*/); } mainForm.setInterval( diff --git a/cmonitor/plugins/relay/RelayTransfer.cs b/cmonitor/plugins/relay/RelayTransfer.cs index 079f4f70..5fb55d1b 100644 --- a/cmonitor/plugins/relay/RelayTransfer.cs +++ b/cmonitor/plugins/relay/RelayTransfer.cs @@ -38,7 +38,7 @@ namespace cmonitor.plugins.relay public async Task ConnectAsync(string remoteMachineName, string transactionId, string secretKey) { IEnumerable _transports = transports.OrderBy(c => c.Name); - foreach (RelayCompactInfo item in config.Data.Client.Relay.Servers.Where(c=>c.Disabled == false)) + foreach (RelayCompactInfo item in config.Data.Client.Relay.Servers.Where(c => c.Disabled == false)) { ITransport transport = _transports.FirstOrDefault(c => c.Name == item.Name); if (transport == null) @@ -61,7 +61,7 @@ namespace cmonitor.plugins.relay Socket socket = await transport.RelayAsync(relayInfo); if (socket != null) { - return new RelayTransportState { Info = relayInfo, Socket = socket }; + return new RelayTransportState { Info = relayInfo, Socket = socket, Direction = RelayTransportDirection.Forward }; } } catch (Exception ex) @@ -79,7 +79,7 @@ namespace cmonitor.plugins.relay Socket socket = await _transports.OnBeginAsync(relayInfo); if (socket != null) { - OnConnected(new RelayTransportState { Info = relayInfo, Socket = socket }); + OnConnected(new RelayTransportState { Info = relayInfo, Socket = socket, Direction = RelayTransportDirection.Reverse }); return true; } } diff --git a/cmonitor/plugins/relay/messenger/RelayMessenger.cs b/cmonitor/plugins/relay/messenger/RelayMessenger.cs index 8f52f2b8..c4347ee6 100644 --- a/cmonitor/plugins/relay/messenger/RelayMessenger.cs +++ b/cmonitor/plugins/relay/messenger/RelayMessenger.cs @@ -30,9 +30,9 @@ namespace cmonitor.plugins.relay.messenger private readonly Config config; private readonly MessengerSender messengerSender; private readonly SignCaching signCaching; - private readonly ConcurrentDictionary> dic = new ConcurrentDictionary>(); + private readonly ConcurrentDictionary dic = new ConcurrentDictionary(); private ulong flowingId = 0; - + public RelayServerMessenger(Config config, MessengerSender messengerSender, SignCaching signCaching) { @@ -59,24 +59,24 @@ namespace cmonitor.plugins.relay.messenger } info.FlowingId = Interlocked.Increment(ref flowingId); - TaskCompletionSource tcs = new TaskCompletionSource(); - dic.TryAdd(info.FlowingId, tcs); + TcsWrap tcsWrap = new TcsWrap { Connection = connection, Tcs = new TaskCompletionSource() }; + dic.TryAdd(info.FlowingId, tcsWrap); try { - MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap + bool res = await messengerSender.SendOnly(new MessageRequestWrap { Connection = cache.Connection, MessengerId = (ushort)RelayMessengerIds.Relay, Payload = MemoryPackSerializer.Serialize(info) }); - if (resp.Code != MessageResponeCodes.OK || resp.Data.Span.SequenceEqual(Helper.TrueArray) == false) + if (res == false) { connection.Write(Helper.FalseArray); return; } - IConnection targetConnection = await tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(3000)); + IConnection targetConnection = await tcsWrap.Tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(3000)); connection.TcpTargetSocket = targetConnection.TcpSourceSocket; targetConnection.TcpTargetSocket = connection.TcpSourceSocket; connection.Write(Helper.TrueArray); @@ -92,9 +92,9 @@ namespace cmonitor.plugins.relay.messenger } else { - if (dic.TryRemove(info.FlowingId, out TaskCompletionSource tcs)) + if (dic.TryRemove(info.FlowingId, out TcsWrap tcsWrap)) { - tcs.SetResult(connection); + tcsWrap.Tcs.SetResult(connection); connection.Write(Helper.TrueArray); } else @@ -104,6 +104,12 @@ namespace cmonitor.plugins.relay.messenger return; } } + + public sealed class TcsWrap + { + public TaskCompletionSource Tcs { get; set; } + public IConnection Connection { get; set; } + } } diff --git a/cmonitor/plugins/relay/transport/ITransport.cs b/cmonitor/plugins/relay/transport/ITransport.cs index 5166dc4f..dd50e7fc 100644 --- a/cmonitor/plugins/relay/transport/ITransport.cs +++ b/cmonitor/plugins/relay/transport/ITransport.cs @@ -29,10 +29,18 @@ namespace cmonitor.plugins.relay.transport } + public enum RelayTransportDirection : byte + { + Forward = 0, + Reverse = 1 + } + public sealed class RelayTransportState { public RelayInfo Info { get; set; } + public RelayTransportDirection Direction { get; set; } = RelayTransportDirection.Reverse; + public Socket Socket { get; set; } } } diff --git a/cmonitor/plugins/tunnel/TunnelTransfer.cs b/cmonitor/plugins/tunnel/TunnelTransfer.cs index 6751a6cb..95bd5e3e 100644 --- a/cmonitor/plugins/tunnel/TunnelTransfer.cs +++ b/cmonitor/plugins/tunnel/TunnelTransfer.cs @@ -82,6 +82,7 @@ namespace cmonitor.plugins.tunnel TunnelTransportState state = await transport.ConnectAsync(tunnelTransportInfo); if (state != null) { + state.Direction = TunnelTransportDirection.Forward; _OnConnected(state); return state; } diff --git a/cmonitor/plugins/tunnel/transport/ITransport.cs b/cmonitor/plugins/tunnel/transport/ITransport.cs index 8077914d..780da1e5 100644 --- a/cmonitor/plugins/tunnel/transport/ITransport.cs +++ b/cmonitor/plugins/tunnel/transport/ITransport.cs @@ -105,6 +105,8 @@ namespace cmonitor.plugins.tunnel.transport public string TransportName { get; set; } public ProtocolType TransportType { get; set; } + public TunnelTransportDirection Direction { get; set; } = TunnelTransportDirection.Reverse; + [JsonIgnore] public object ConnectedObject { get; set; } } diff --git a/cmonitor/plugins/viewer/proxy/ViewerProxy.cs b/cmonitor/plugins/viewer/proxy/ViewerProxy.cs index acb739a5..03d3001b 100644 --- a/cmonitor/plugins/viewer/proxy/ViewerProxy.cs +++ b/cmonitor/plugins/viewer/proxy/ViewerProxy.cs @@ -185,14 +185,14 @@ namespace cmonitor.plugins.viewer.proxy if (token.TargetSocket != null) { //发送连接请求包 - await SendToTarget(e, token); + await SendToTarget(e, token).ConfigureAwait(false); token.Proxy.Step = ProxyStep.Forward; token.Proxy.TargetEP = null; //发送后续数据包 token.Proxy.Data = data; - await SendToTarget(e, token); + await SendToTarget(e, token).ConfigureAwait(false); //绑定 dic.TryAdd(new ConnectId(token.Proxy.ConnectId, token.TargetSocket.GetHashCode()), token.SourceSocket); @@ -205,7 +205,7 @@ namespace cmonitor.plugins.viewer.proxy else { token.Proxy.Data = data; - await SendToTarget(e, token); + await SendToTarget(e, token).ConfigureAwait(false); } } private async Task SendToTarget(SocketAsyncEventArgs e, AsyncUserToken token) @@ -225,7 +225,6 @@ namespace cmonitor.plugins.viewer.proxy } } - protected virtual async Task Connect(AsyncUserToken token, ProxyInfo proxyInfo) { await Task.CompletedTask; @@ -235,7 +234,13 @@ namespace cmonitor.plugins.viewer.proxy { try { - BindReceiveTarget(new AsyncUserToken { TargetSocket = targetSocket, SourceSocket = sourceSocket, Proxy = new ProxyInfo { Direction = ProxyDirection.UnPack } }); + BindReceiveTarget(new AsyncUserToken + { + TargetSocket = targetSocket, + SourceSocket = sourceSocket, + Buffer = new ReceiveDataBuffer(), + Proxy = new ProxyInfo { Direction = ProxyDirection.UnPack } + }); return true; } @@ -245,8 +250,6 @@ namespace cmonitor.plugins.viewer.proxy } return false; } - - private void IO_CompletedTarget(object sender, SocketAsyncEventArgs e) { switch (e.LastOperation) @@ -291,7 +294,7 @@ namespace cmonitor.plugins.viewer.proxy int offset = e.Offset; int length = e.BytesTransferred; - await ReadPacketTarget(e, token, e.Buffer.AsMemory(offset, length)); + await ReadPacketTarget(e, token, e.Buffer.AsMemory(offset, length)).ConfigureAwait(false); if (token.TargetSocket.Available > 0) { @@ -300,7 +303,7 @@ namespace cmonitor.plugins.viewer.proxy length = token.TargetSocket.Receive(e.Buffer); if (length > 0) { - await ReadPacketTarget(e, token, e.Buffer.AsMemory(0, length)); + await ReadPacketTarget(e, token, e.Buffer.AsMemory(0, length)).ConfigureAwait(false); } else { @@ -341,58 +344,103 @@ namespace cmonitor.plugins.viewer.proxy //A 到 B if (token.Proxy.Direction == ProxyDirection.UnPack) { - token.Proxy.DeBytes(data); - if (token.Proxy.Step == ProxyStep.Request) + //是一个完整的包 + if (token.Buffer.Size == 0 && data.Length > 4) { - Socket socket = new Socket(token.Proxy.TargetEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - socket.KeepAlive(); - await socket.ConnectAsync(token.Proxy.TargetEP); - - dic.TryAdd(new ConnectId(token.Proxy.ConnectId, token.TargetSocket.GetHashCode()), socket); - - BindReceiveTarget(new AsyncUserToken + int packageLen = data.ToInt32(); + if (packageLen == data.Length - 4) { - TargetSocket = socket, - SourceSocket = token.TargetSocket, - Proxy = new ProxyInfo - { - Direction = ProxyDirection.Pack, - ConnectId = token.Proxy.ConnectId, - Step = ProxyStep.Forward - } - }); + token.Proxy.DeBytes(data.Slice(0, packageLen + 4)); + await ReadPacketTarget(e, token).ConfigureAwait(false); + return; + } } - else - { - ConnectId connectId = new ConnectId(token.Proxy.ConnectId, token.TargetSocket.GetHashCode()); - if (dic.TryGetValue(connectId, out Socket source)) - { - try - { - await source.SendAsync(token.Proxy.Data); - } - catch (Exception) - { - CloseClientSocket(e); - } + //不是完整包 + token.Buffer.AddRange(data); + do + { + int packageLen = token.Buffer.Data.ToInt32(); + if (packageLen > token.Buffer.Size - 4) + { + break; + } + token.Proxy.DeBytes(token.Buffer.Data.Slice(0, packageLen + 4)); + await ReadPacketTarget(e, token).ConfigureAwait(false); + + token.Buffer.RemoveRange(0, packageLen + 4); + } while (token.Buffer.Size > 4); + } + else + { + token.Proxy.Data = data; + await SendToSource(e, token).ConfigureAwait(false); + } + } + private async Task ReadPacketTarget(SocketAsyncEventArgs e, AsyncUserToken token) + { + if (token.Proxy.Step == ProxyStep.Request) + { + await ConnectBind(e, token).ConfigureAwait(false); + } + else + { + await SendToSource(e, token).ConfigureAwait(false); + } + } + private async Task ConnectBind(SocketAsyncEventArgs e, AsyncUserToken token) + { + Socket socket = new Socket(token.Proxy.TargetEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + socket.KeepAlive(); + await socket.ConnectAsync(token.Proxy.TargetEP); + + dic.TryAdd(new ConnectId(token.Proxy.ConnectId, token.TargetSocket.GetHashCode()), socket); + + BindReceiveTarget(new AsyncUserToken + { + TargetSocket = socket, + SourceSocket = token.TargetSocket, + Proxy = new ProxyInfo + { + Direction = ProxyDirection.Pack, + ConnectId = token.Proxy.ConnectId, + Step = ProxyStep.Forward + } + }); + } + private async Task SendToSource(SocketAsyncEventArgs e, AsyncUserToken token) + { + if(token.Proxy.Direction == ProxyDirection.UnPack) + { + ConnectId connectId = new ConnectId(token.Proxy.ConnectId, token.TargetSocket.GetHashCode()); + if (dic.TryGetValue(connectId, out Socket source)) + { + try + { + await source.SendAsync(token.Proxy.Data); + } + catch (Exception) + { + CloseClientSocket(e); + } } } else { - token.Proxy.Data = data; - byte[] bytes = token.Proxy.ToBytes(out int length); + byte[] connectData = token.Proxy.ToBytes(out int length); try { - await token.TargetSocket.SendAsync(bytes.AsMemory(0, length), SocketFlags.None); + await token.SourceSocket.SendAsync(connectData.AsMemory(0, length), SocketFlags.None); } catch (Exception) { CloseClientSocket(e); - } - token.Proxy.Return(bytes); + finally + { + token.Proxy.Return(connectData); + } } } @@ -444,7 +492,7 @@ namespace cmonitor.plugins.viewer.proxy { int ipLength = TargetEP == null ? 0 : (TargetEP.AddressFamily == AddressFamily.InterNetwork ? 4 : 16) + 2; - length = 8 + 1 + length = 4 + 8 + 1 + 1 + ipLength + Data.Length; @@ -452,7 +500,12 @@ namespace cmonitor.plugins.viewer.proxy Memory memory = bytes.AsMemory(); int index = 0; - ConnectId.ToBytes(memory); + + (length - 4).ToBytes(memory); + index += 4; + + + ConnectId.ToBytes(memory.Slice(index)); index += 8; bytes[index] = (byte)Step; @@ -483,10 +536,10 @@ namespace cmonitor.plugins.viewer.proxy public void DeBytes(Memory memory) { - int index = 0; + int index = 4; Span span = memory.Span; - ConnectId = memory.ToUInt64(); + ConnectId = memory.Slice(index).ToUInt64(); index += 8; Step = (ProxyStep)span[index]; @@ -512,11 +565,14 @@ namespace cmonitor.plugins.viewer.proxy public ProxyInfo Proxy { get; set; } + public ReceiveDataBuffer Buffer { get; set; } + public void Clear() { SourceSocket?.SafeClose(); SourceSocket = null; + Buffer?.Clear(); //TargetSocket?.SafeClose(); //TargetSocket = null; diff --git a/cmonitor/plugins/viewer/proxy/ViewerProxyClient.cs b/cmonitor/plugins/viewer/proxy/ViewerProxyClient.cs index f11d9a32..100daf23 100644 --- a/cmonitor/plugins/viewer/proxy/ViewerProxyClient.cs +++ b/cmonitor/plugins/viewer/proxy/ViewerProxyClient.cs @@ -46,6 +46,7 @@ namespace cmonitor.plugins.viewer.proxy } } RelayTransportState relayState = await relayTransfer.ConnectAsync(runningConfig.Data.Viewer.ServerMachine, "viewer", config.Data.Client.Relay.SecretKey); + if (relayState != null) { tunnelSocket = relayState.Socket; @@ -64,14 +65,14 @@ namespace cmonitor.plugins.viewer.proxy { tunnelTransfer.OnConnected += (TunnelTransportState state) => { - if (state != null && state.TransportType == ProtocolType.Tcp && state.TransactionId == "viewer") + if (state != null && state.TransportType == ProtocolType.Tcp && state.TransactionId == "viewer" && state.Direction == TunnelTransportDirection.Reverse) { BindReceiveTarget(state.ConnectedObject as Socket, null); } }; relayTransfer.OnConnected += (RelayTransportState state) => { - if (state != null && state.Info.TransactionId == "viewer") + if (state != null && state.Info.TransactionId == "viewer" && state.Direction == RelayTransportDirection.Reverse) { BindReceiveTarget(state.Socket, null); } diff --git a/cmonitor/server/TcpServer.cs b/cmonitor/server/TcpServer.cs index 5aa1f0fc..f5e67d3e 100644 --- a/cmonitor/server/TcpServer.cs +++ b/cmonitor/server/TcpServer.cs @@ -14,7 +14,7 @@ namespace cmonitor.server private Socket socket; private UdpClient socketUdp; private CancellationTokenSource cancellationTokenSource; - private Memory relayFLagData = Encoding.UTF8.GetBytes("snltty.relay"); + private Memory relayFLagCData = Encoding.UTF8.GetBytes("snltty.relay"); public Func OnPacket { get; set; } = async (connection) => { await Task.CompletedTask; }; public Action OnDisconnected { get; set; } @@ -185,7 +185,10 @@ namespace cmonitor.server int length = e.BytesTransferred; bool res = await ReadPacket(token, e.Buffer, offset, length); - if (res == false) return; + if (res == false) + { + return; + } if (token.Socket.Available > 0) { @@ -195,7 +198,10 @@ namespace cmonitor.server if (length > 0) { res = await ReadPacket(token, e.Buffer, 0, length); - if (res == false) return; + if (res == false) + { + return; + } } else { @@ -240,7 +246,7 @@ namespace cmonitor.server await token.Connection.TcpTargetSocket.SendAsync(data.AsMemory(offset, length), SocketFlags.None); return true; } - else if (length == relayFLagData.Length && data.AsSpan(offset, length).SequenceEqual(relayFLagData.Span)) + else if (length == relayFLagCData.Length && data.AsSpan(offset, relayFLagCData.Length).SequenceEqual(relayFLagCData.Span)) { return false; }