diff --git a/cmonitor.tests/MemoryPackIPEndPointSerialize.cs b/cmonitor.tests/MemoryPackIPEndPointSerialize.cs index c8c22ed6..19588d45 100644 --- a/cmonitor.tests/MemoryPackIPEndPointSerialize.cs +++ b/cmonitor.tests/MemoryPackIPEndPointSerialize.cs @@ -1,3 +1,5 @@ +using cmonitor.plugins.tunnel.server; +using cmonitor.plugins.tunnel.transport; using cmonitor.serializes; using MemoryPack; using System.Net; @@ -11,10 +13,18 @@ namespace cmonitor.tests public void Serialize() { MemoryPackFormatterProvider.Register(new IPEndPointFormatter()); - MemoryPackIPEndPointSerializeInfo info = new MemoryPackIPEndPointSerializeInfo { EP = new IPEndPoint(IPAddress.Loopback, 12345) }; - MemoryPackIPEndPointSerializeInfo info1 = MemoryPackSerializer.Deserialize(MemoryPackSerializer.Serialize(info)); + TunnelTransportInfo info = new TunnelTransportInfo + { + Direction = TunnelTransportDirection.Reverse, + Local = new TunnelTransportExternalIPInfo { Local = new IPEndPoint(IPAddress.Loopback, 12345), Remote = new IPEndPoint(IPAddress.Loopback, 12345), MachineName = "111", RouteLevel = 1 }, + Remote = new TunnelTransportExternalIPInfo { Local = new IPEndPoint(IPAddress.Loopback, 12345), Remote = new IPEndPoint(IPAddress.Loopback, 12345), MachineName = "111", RouteLevel = 1 }, + TransactionId = "111", + TransportName = "111", + TransportType = System.Net.Sockets.ProtocolType.Tcp + }; + TunnelTransportInfo info1 = MemoryPackSerializer.Deserialize(MemoryPackSerializer.Serialize(info)); - Assert.AreEqual(info.EP, info1.EP); + Assert.AreEqual(info.Local.Local, info1.Local.Local); } } diff --git a/cmonitor.web.client/src/App.vue b/cmonitor.web.client/src/App.vue index 992fbd30..a2ef3a11 100644 --- a/cmonitor.web.client/src/App.vue +++ b/cmonitor.web.client/src/App.vue @@ -2,7 +2,7 @@
-
+
diff --git a/cmonitor.web.client/src/apis/tunnel.js b/cmonitor.web.client/src/apis/tunnel.js index f7e805ae..623667f4 100644 --- a/cmonitor.web.client/src/apis/tunnel.js +++ b/cmonitor.web.client/src/apis/tunnel.js @@ -13,6 +13,13 @@ export const updateConfigSetServers = (servers) => { export const getSignInfo = () => { return sendWebsocketMsg('tunnel/signininfo'); } +export const getSignList = (data) => { + return sendWebsocketMsg('tunnel/SignInList', data); +} export const updateSignInDel = (machineName) => { return sendWebsocketMsg('tunnel/signindel', machineName); -} \ No newline at end of file +} + +export const updateTunnelConnect = (machineName) => { + return sendWebsocketMsg('tunnel/TunnelConnect', machineName); +} diff --git a/cmonitor.web.client/src/components/Head.vue b/cmonitor.web.client/src/components/Head.vue index 06bcc278..93570e87 100644 --- a/cmonitor.web.client/src/components/Head.vue +++ b/cmonitor.web.client/src/components/Head.vue @@ -46,16 +46,21 @@ export default { const state = reactive({ api: route.query.api ? `${window.location.hostname}:${route.query.api}` : (localStorage.getItem('api') || `${window.location.hostname}:1805`), apipsd: route.query.apipsd ? `${route.query.apipsd}` : (localStorage.getItem('apipsd') || `snltty`), + groupid: route.query.groupid ? `${route.query.groupid}` : (localStorage.getItem('groupid') || `snltty`), showPort: false }); localStorage.setItem('api', state.api); localStorage.setItem('apipsd', state.apipsd); + localStorage.setItem('groupid', state.groupid); + globalData.value.groupid = state.groupid; const showPort = computed(() => globalData.value.connected == false && state.showPort); const handleConnect = () => { initWebsocket(`ws://${state.api}`,state.apipsd); localStorage.setItem('api', state.api); localStorage.setItem('apipsd', state.apipsd); + localStorage.setItem('groupid', state.groupid); + globalData.value.groupid = state.groupid; } const _getConfig = ()=>{ diff --git a/cmonitor.web.client/src/provide.js b/cmonitor.web.client/src/provide.js index dd5d453c..2d247df5 100644 --- a/cmonitor.web.client/src/provide.js +++ b/cmonitor.web.client/src/provide.js @@ -9,7 +9,8 @@ export const provideGlobalData = () => { connected: false, updateFlag: false, config: { Common: {}, Client: {} }, - signin: { Connected: false, Connecting: false } + signin: { Connected: false, Connecting: false }, + groupid: '' }); subWebsocketState((state) => { globalData.value.connected = state; diff --git a/cmonitor.web.client/src/views/Index.vue b/cmonitor.web.client/src/views/Index.vue index f2f7189a..91d32581 100644 --- a/cmonitor.web.client/src/views/Index.vue +++ b/cmonitor.web.client/src/views/Index.vue @@ -1,10 +1,13 @@ diff --git a/cmonitor.web.client/src/views/List.vue b/cmonitor.web.client/src/views/List.vue new file mode 100644 index 00000000..5fc1494a --- /dev/null +++ b/cmonitor.web.client/src/views/List.vue @@ -0,0 +1,108 @@ + + + \ No newline at end of file diff --git a/cmonitor/client/api/ApiStartup.cs b/cmonitor/client/api/ApiStartup.cs index 7d08d021..11234483 100644 --- a/cmonitor/client/api/ApiStartup.cs +++ b/cmonitor/client/api/ApiStartup.cs @@ -11,18 +11,15 @@ namespace cmonitor.client.api public StartupLevel Level => StartupLevel.Normal; public void AddClient(ServiceCollection serviceCollection, Config config, Assembly[] assemblies) { + serviceCollection.AddSingleton(); } public void AddServer(ServiceCollection serviceCollection, Config config, Assembly[] assemblies) { - serviceCollection.AddSingleton(); + } public void UseClient(ServiceProvider serviceProvider, Config config, Assembly[] assemblies) - { - } - - public void UseServer(ServiceProvider serviceProvider, Config config, Assembly[] assemblies) { Logger.Instance.Info($"start client api server"); IApiClientServer clientServer = serviceProvider.GetService(); @@ -31,5 +28,10 @@ namespace cmonitor.client.api Logger.Instance.Info($"client api listen:{config.Data.Client.ApiPort}"); Logger.Instance.Info($"client api password:{config.Data.Client.ApiPassword}"); } + + public void UseServer(ServiceProvider serviceProvider, Config config, Assembly[] assemblies) + { + + } } } diff --git a/cmonitor/cmonitor.csproj b/cmonitor/cmonitor.csproj index ff6c5654..7e399758 100644 --- a/cmonitor/cmonitor.csproj +++ b/cmonitor/cmonitor.csproj @@ -2,7 +2,7 @@ Exe - net7.0;net8.0 + net8.0;net7.0 enable disable true diff --git a/cmonitor/plugins/hijack/report/HijackWindows.cs b/cmonitor/plugins/hijack/report/HijackWindows.cs index 7b43e282..1ed7be20 100644 --- a/cmonitor/plugins/hijack/report/HijackWindows.cs +++ b/cmonitor/plugins/hijack/report/HijackWindows.cs @@ -1,4 +1,5 @@ using cmonitor.plugins.hijack.report.hijack; +using common.libs; namespace cmonitor.plugins.hijack.report { @@ -20,7 +21,14 @@ namespace cmonitor.plugins.hijack.report public void Start() { - hijackController.Start(); + try + { + hijackController.Start(); + } + catch (Exception ex) + { + Logger.Instance.Error(ex); + } } public void Stop() { diff --git a/cmonitor/plugins/hijack/report/hijack/HijackEventHandler.cs b/cmonitor/plugins/hijack/report/hijack/HijackEventHandler.cs index 0f13863e..b562c69a 100644 --- a/cmonitor/plugins/hijack/report/hijack/HijackEventHandler.cs +++ b/cmonitor/plugins/hijack/report/hijack/HijackEventHandler.cs @@ -284,6 +284,7 @@ namespace cmonitor.plugins.hijack.report.hijack { while (dnsDataQueue.TryDequeue(out DnsInfo dns)) { + if (dns.Len == 0) continue; try { DnsUnpackResultInfo dnsPack = DnsUnpack(dns); diff --git a/cmonitor/plugins/signIn/messenger/SignCaching.cs b/cmonitor/plugins/signIn/messenger/SignCaching.cs index c71bca48..5dd5c4c9 100644 --- a/cmonitor/plugins/signIn/messenger/SignCaching.cs +++ b/cmonitor/plugins/signIn/messenger/SignCaching.cs @@ -3,6 +3,7 @@ using common.libs.database; using MemoryPack; using System.Collections.Concurrent; using System.ComponentModel.DataAnnotations.Schema; +using System.Net; using System.Text.Json.Serialization; namespace cmonitor.plugins.signin.messenger @@ -44,7 +45,7 @@ namespace cmonitor.plugins.signin.messenger } public List Get(string groupId) { - return config.Clients.Values.Where(c=>c.GroupId == groupId).ToList(); + return config.Clients.Values.Where(c => c.GroupId == groupId).ToList(); } public bool Del(string machineName) @@ -83,26 +84,57 @@ namespace cmonitor.plugins.signin.messenger public ConcurrentDictionary Clients { get; set; } = new ConcurrentDictionary(); } - public sealed class SignCacheInfo + [MemoryPackable] + public sealed partial class SignCacheInfo { public string MachineName { get; set; } public string Version { get; set; } = "1.0.0.0"; public string GroupId { get; set; } = "snltty"; public DateTime LastSignIn { get; set; } = DateTime.Now; - public Dictionary Args { get; set; } = new Dictionary(); + + private IPEndPoint ip = new IPEndPoint(IPAddress.Any, 0); + [MemoryPackAllowSerialize] + public IPEndPoint IP + { + get + { + if (Connection != null) + { + ip = Connection.Address; + } + return ip; + } + set + { + ip = value; + } + } + + private bool connected = false; public bool Connected { get { - return Connection != null && Connection.Connected == true; + if (Connection != null) + { + connected = Connection.Connected == true; + } + return connected; + } + set + { + connected = value; } } + [JsonIgnore] + [MemoryPackIgnore] public IConnection Connection { get; set; } } + [MemoryPackable] public sealed partial class SignInfo { diff --git a/cmonitor/plugins/signIn/messenger/SignInMessenger.cs b/cmonitor/plugins/signIn/messenger/SignInMessenger.cs index b84871c3..5d772fc9 100644 --- a/cmonitor/plugins/signIn/messenger/SignInMessenger.cs +++ b/cmonitor/plugins/signIn/messenger/SignInMessenger.cs @@ -1,6 +1,7 @@ using cmonitor.config; using cmonitor.server; using common.libs; +using common.libs.extends; using MemoryPack; namespace cmonitor.plugins.signin.messenger diff --git a/cmonitor/plugins/tunnel/TunnelApiController.cs b/cmonitor/plugins/tunnel/TunnelApiController.cs index 1a1853bb..2cb7534f 100644 --- a/cmonitor/plugins/tunnel/TunnelApiController.cs +++ b/cmonitor/plugins/tunnel/TunnelApiController.cs @@ -5,6 +5,7 @@ using cmonitor.plugins.signin.messenger; using cmonitor.plugins.tunnel.server; using cmonitor.plugins.tunnel.transport; using cmonitor.server; +using common.libs; using common.libs.api; using common.libs.extends; using MemoryPack; @@ -68,7 +69,6 @@ namespace cmonitor.plugins.tunnel Payload = MemoryPackSerializer.Serialize(param.Content) }); } - public async Task SignInList(ApiControllerParamsInfo param) { SignInListRequestInfo request = param.Content.DeJson(); @@ -84,6 +84,7 @@ namespace cmonitor.plugins.tunnel } return new SignInListResponseInfo { }; } + public Dictionary TunnelConnections(ApiControllerParamsInfo param) { return tunnelTransfer.Connections; @@ -92,27 +93,36 @@ namespace cmonitor.plugins.tunnel { Task.Run(async () => { - TunnelTransportState state = await tunnelTransfer.ConnectAsync(param.Content,"test"); - if(state != null) + try { - var socket = state.ConnectedObject as Socket; - for (int i = 0; i < 10; i++) + TunnelTransportState state = await tunnelTransfer.ConnectAsync(param.Content, "test"); + if (state != null) { - socket.Send(BitConverter.GetBytes(i)); - await Task.Delay(10); + var socket = state.ConnectedObject as Socket; + for (int i = 0; i < 10; i++) + { + Logger.Instance.Debug($"tunnel [test] send {i}"); + socket.Send(BitConverter.GetBytes(i)); + await Task.Delay(10); + } + socket.SafeClose(); } } + catch (Exception ex) + { + Console.WriteLine(ex+""); + } }); } private void TunnelTest() { tunnelTransfer.OnConnected += (TunnelTransportState state) => { - if(state.TransactionId == "test" && state.TransportType == ProtocolType.Tcp) + if (state.TransactionId == "test" && state.TransportType == ProtocolType.Tcp) { tunnelBindServer.BindReceive(state.ConnectedObject as Socket, null, async (token,data) => { - Console.WriteLine(BitConverter.ToInt32(data.Span)); + Logger.Instance.Debug($"tunnel [{state.TransactionId}] receive {BitConverter.ToInt32(data.Span)}"); }); } }; diff --git a/cmonitor/plugins/tunnel/TunnelStartup.cs b/cmonitor/plugins/tunnel/TunnelStartup.cs index 12bc8452..2113fbbb 100644 --- a/cmonitor/plugins/tunnel/TunnelStartup.cs +++ b/cmonitor/plugins/tunnel/TunnelStartup.cs @@ -28,7 +28,7 @@ namespace cmonitor.plugins.tunnel serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); - serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(); Logger.Instance.Info($"tunnel route level getting."); diff --git a/cmonitor/plugins/tunnel/TunnelTransfer.cs b/cmonitor/plugins/tunnel/TunnelTransfer.cs index 0a04e174..7a2fb972 100644 --- a/cmonitor/plugins/tunnel/TunnelTransfer.cs +++ b/cmonitor/plugins/tunnel/TunnelTransfer.cs @@ -5,11 +5,11 @@ using cmonitor.plugins.tunnel.messenger; using cmonitor.plugins.tunnel.transport; using cmonitor.server; using common.libs; +using common.libs.extends; using MemoryPack; using Microsoft.Extensions.DependencyInjection; using System.Net.Sockets; using System.Reflection; -using System.Transactions; namespace cmonitor.plugins.tunnel { @@ -46,7 +46,6 @@ namespace cmonitor.plugins.tunnel item.OnConnectBegin = OnConnectBegin; item.OnConnecting = OnConnecting; item.OnConnected = _OnConnected; - item.OnConnected += OnConnected; item.OnDisConnected = OnDisConnected; item.OnConnectFail = OnConnectFail; } @@ -81,11 +80,10 @@ namespace cmonitor.plugins.tunnel Local = localInfo, Remote = remoteInfo, }; - + TunnelTransportState state = await transport.ConnectAsync(tunnelTransportInfo); if (state != null) { - _OnConnected(state); return state; } @@ -106,7 +104,7 @@ namespace cmonitor.plugins.tunnel if (_transports != null) { _transports.OnFail(tunnelTransportInfo); - OnConnectFail(tunnelTransportInfo.FromMachineName); + OnConnectFail(tunnelTransportInfo.Remote.MachineName); } } public async Task Info(TunnelTransportExternalIPRequestInfo request) @@ -187,7 +185,7 @@ namespace cmonitor.plugins.tunnel { if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG) { - Logger.Instance.Debug($"tunnel connect from {tunnelTransportInfo.Local.MachineName}"); + Logger.Instance.Debug($"tunnel connect from {tunnelTransportInfo.Local.MachineName}->{tunnelTransportInfo.ToJson()}"); } CheckDic(tunnelTransportInfo.Local.MachineName, out TunnelConnectInfo info); info.Status = TunnelConnectStatus.Connecting; @@ -203,6 +201,7 @@ namespace cmonitor.plugins.tunnel info.Status = TunnelConnectStatus.Connected; info.State = state; Interlocked.Exchange(ref connectionsChangeFlag, 1); + OnConnected(state); } private void OnDisConnected(TunnelTransportState state) { @@ -214,7 +213,7 @@ namespace cmonitor.plugins.tunnel private void OnConnectFail(string machineName) { if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG) - { + { Logger.Instance.Error($"tunnel connect {machineName} fail"); } CheckDic(machineName, out TunnelConnectInfo info); diff --git a/cmonitor/plugins/tunnel/compact/CompactSelfHost.cs b/cmonitor/plugins/tunnel/compact/CompactSelfHost.cs index 7511ae75..36a8e6de 100644 --- a/cmonitor/plugins/tunnel/compact/CompactSelfHost.cs +++ b/cmonitor/plugins/tunnel/compact/CompactSelfHost.cs @@ -17,16 +17,18 @@ namespace cmonitor.plugins.tunnel.compact socket.IPv6Only(server.AddressFamily, false); await socket.ConnectAsync(server).WaitAsync(TimeSpan.FromSeconds(5)); - byte[] bytes = new byte[20]; + byte[] bytes = new byte[128]; int length = await socket.ReceiveAsync(bytes.AsMemory(), SocketFlags.None); if (length == 0) { return null; } + IPEndPoint local = socket.LocalEndPoint as IPEndPoint; + socket.SafeClose(); TunnelExternalIPInfo tunnelExternalIPInfo = MemoryPackSerializer.Deserialize(bytes.AsSpan(0,length)); - return new TunnelCompactIPEndPoint { Local = socket.LocalEndPoint as IPEndPoint, Remote = tunnelExternalIPInfo.ExternalIP }; + return new TunnelCompactIPEndPoint { Local = local, Remote = tunnelExternalIPInfo.ExternalIP }; } public async Task GetUdpExternalIPAsync(IPEndPoint server) diff --git a/cmonitor/plugins/tunnel/messenger/TunnelMessenger.cs b/cmonitor/plugins/tunnel/messenger/TunnelMessenger.cs index 4f5b332e..35316c49 100644 --- a/cmonitor/plugins/tunnel/messenger/TunnelMessenger.cs +++ b/cmonitor/plugins/tunnel/messenger/TunnelMessenger.cs @@ -1,6 +1,4 @@ -using cmonitor.client; -using cmonitor.config; -using cmonitor.plugins.signin.messenger; +using cmonitor.plugins.signin.messenger; using cmonitor.plugins.tunnel.transport; using cmonitor.server; using common.libs; @@ -21,6 +19,10 @@ namespace cmonitor.plugins.tunnel.messenger public void Begin(IConnection connection) { TunnelTransportInfo tunnelTransportInfo = MemoryPackSerializer.Deserialize(connection.ReceiveRequestWrap.Payload.Span); + TunnelTransportExternalIPInfo local = tunnelTransportInfo.Local; + tunnelTransportInfo.Local = tunnelTransportInfo.Remote; + tunnelTransportInfo.Remote = local; + tunnel.OnBegin(tunnelTransportInfo); connection.Write(Helper.TrueArray); } @@ -40,6 +42,10 @@ namespace cmonitor.plugins.tunnel.messenger public void Fail(IConnection connection) { TunnelTransportInfo tunnelTransportInfo = MemoryPackSerializer.Deserialize(connection.ReceiveRequestWrap.Payload.Span); + TunnelTransportExternalIPInfo local = tunnelTransportInfo.Local; + tunnelTransportInfo.Local = tunnelTransportInfo.Remote; + tunnelTransportInfo.Remote = local; + tunnel.OnFail(tunnelTransportInfo); } } @@ -86,7 +92,7 @@ namespace cmonitor.plugins.tunnel.messenger }); if (resp.Code == MessageResponeCodes.OK) { - connection.Write(MemoryPackSerializer.Serialize(MemoryPackSerializer.Deserialize(resp.Data.Span))); + connection.Write(MemoryPackSerializer.Serialize(MemoryPackSerializer.Deserialize(resp.Data.Span))); } } } @@ -95,7 +101,7 @@ namespace cmonitor.plugins.tunnel.messenger public async Task FailForward(IConnection connection) { TunnelTransportInfo tunnelTransportInfo = MemoryPackSerializer.Deserialize(connection.ReceiveRequestWrap.Payload.Span); - if (signCaching.Get(tunnelTransportInfo.FromMachineName, out SignCacheInfo cache) && signCaching.Get(connection.Name, out SignCacheInfo cache1) && cache.GroupId == cache1.GroupId) + if (signCaching.Get(tunnelTransportInfo.Remote.MachineName, out SignCacheInfo cache) && signCaching.Get(connection.Name, out SignCacheInfo cache1) && cache.GroupId == cache1.GroupId) { await messengerSender.SendOnly(new MessageRequestWrap { diff --git a/cmonitor/plugins/tunnel/server/TunnelBindServer.cs b/cmonitor/plugins/tunnel/server/TunnelBindServer.cs index b5f721a5..8552a46f 100644 --- a/cmonitor/plugins/tunnel/server/TunnelBindServer.cs +++ b/cmonitor/plugins/tunnel/server/TunnelBindServer.cs @@ -8,7 +8,6 @@ namespace cmonitor.plugins.tunnel.server { public sealed class TunnelBindServer { - private SocketAsyncEventArgs acceptEventArg; private UdpClient socketUdp; public Action OnTcpConnected { get; set; } = (state, socket) => { }; @@ -26,16 +25,18 @@ namespace cmonitor.plugins.tunnel.server socket.ReuseBind(new IPEndPoint(IPAddress.Any, local.Port)); socket.Listen(int.MaxValue); - acceptEventArg = new SocketAsyncEventArgs + AsyncUserToken token = new AsyncUserToken { - UserToken = new AsyncUserToken - { - SourceSocket = socket, - State = state, - Saea = acceptEventArg - }, + SourceSocket = socket, + State = state, + LocalPort = local.Port + }; + SocketAsyncEventArgs acceptEventArg = new SocketAsyncEventArgs + { + UserToken = token, SocketFlags = SocketFlags.None, }; + token.Saea = acceptEventArg; acceptBinds.AddOrUpdate(local.Port, acceptEventArg, (a, b) => acceptEventArg); acceptEventArg.Completed += IO_Completed; @@ -84,6 +85,9 @@ namespace cmonitor.plugins.tunnel.server case SocketAsyncOperation.Accept: ProcessAccept(e); break; + case SocketAsyncOperation.Receive: + ProcessReceive(e); + break; default: break; } @@ -92,14 +96,14 @@ namespace cmonitor.plugins.tunnel.server { if (e.AcceptSocket != null) { - AsyncUserToken token = e.UserToken as AsyncUserToken; + if (e.AcceptSocket.RemoteEndPoint != null) + { - acceptBinds.AddOrUpdate(e.AcceptSocket.GetHashCode(), e, (a, b) => e); - acceptBinds.TryRemove((token.SourceSocket.LocalEndPoint as IPEndPoint).Port, out _); - - OnTcpConnected(token.State, e.AcceptSocket); - StartAccept(e); + AsyncUserToken token = (AsyncUserToken)e.UserToken; + OnTcpConnected(token.State, e.AcceptSocket); + } } + StartAccept(e); } private void ReceiveCallbackUdp(IAsyncResult result) { @@ -127,7 +131,8 @@ namespace cmonitor.plugins.tunnel.server { SourceSocket = socket, State = state, - OnData = dataCallback + OnData = dataCallback, + LocalPort = (socket.LocalEndPoint as IPEndPoint).Port, }; SocketAsyncEventArgs readEventArgs = new SocketAsyncEventArgs @@ -200,17 +205,16 @@ namespace cmonitor.plugins.tunnel.server if (e == null || e.UserToken == null) return; AsyncUserToken token = e.UserToken as AsyncUserToken; - e.UserToken = null; - if (token.SourceSocket != null) + Socket socket = token.SourceSocket; + if (socket != null) { token.Clear(); e.Dispose(); - - if (acceptBinds.TryRemove(token.SourceSocket.GetHashCode(), out SocketAsyncEventArgs saea)) + if (acceptBinds.TryRemove(token.LocalPort, out SocketAsyncEventArgs saea1)) { - CloseClientSocket(saea); - OnDisConnected(token.State); + CloseClientSocket(saea1); } + OnDisConnected(token.State); } } @@ -222,8 +226,10 @@ namespace cmonitor.plugins.tunnel.server public Socket SourceSocket { get; set; } public SocketAsyncEventArgs Saea { get; set; } public object State { get; set; } + public OnTunnelData OnData { get; set; } + public int LocalPort { get; set; } public void Clear() { diff --git a/cmonitor/plugins/tunnel/server/TunnelExternalIPServer.cs b/cmonitor/plugins/tunnel/server/TunnelExternalIPServer.cs index d666ddbf..3d6aea80 100644 --- a/cmonitor/plugins/tunnel/server/TunnelExternalIPServer.cs +++ b/cmonitor/plugins/tunnel/server/TunnelExternalIPServer.cs @@ -78,7 +78,16 @@ namespace cmonitor.plugins.tunnel.server { if (e.AcceptSocket != null) { - WriteExternalIP(e); + SocketAsyncEventArgs receiveEventArg = new SocketAsyncEventArgs + { + UserToken = new AsyncUserToken + { + SourceSocket = e.AcceptSocket + }, + SocketFlags = SocketFlags.None, + }; + + WriteExternalIP(receiveEventArg); StartAccept(e); } } diff --git a/cmonitor/plugins/tunnel/transport/ITransport.cs b/cmonitor/plugins/tunnel/transport/ITransport.cs index b9160b94..f916bcea 100644 --- a/cmonitor/plugins/tunnel/transport/ITransport.cs +++ b/cmonitor/plugins/tunnel/transport/ITransport.cs @@ -87,13 +87,6 @@ namespace cmonitor.plugins.tunnel.transport public string TransportName { get; set; } public TunnelTransportDirection Direction { get; set; } - - [JsonIgnore] - [MemoryPackIgnore] - public string FromMachineName => Direction == TunnelTransportDirection.Forward ? Remote.MachineName : Local.MachineName; - [JsonIgnore] - [MemoryPackIgnore] - public IPEndPoint BindEP => Direction == TunnelTransportDirection.Forward ? Remote.Local : Local.Local; } diff --git a/cmonitor/plugins/tunnel/transport/TransportTcpNutssb.cs b/cmonitor/plugins/tunnel/transport/TransportTcpNutssb.cs index dfe101db..d56cea63 100644 --- a/cmonitor/plugins/tunnel/transport/TransportTcpNutssb.cs +++ b/cmonitor/plugins/tunnel/transport/TransportTcpNutssb.cs @@ -36,42 +36,45 @@ namespace cmonitor.plugins.tunnel.transport tunnelTransportInfo.Direction = TunnelTransportDirection.Forward; await OnSendConnectBegin(tunnelTransportInfo); - TunnelTransportState state = await ConnectForward(tunnelTransportInfo.Local, tunnelTransportInfo.Remote, tunnelTransportInfo); + TunnelTransportState state = await ConnectForward(tunnelTransportInfo); if (state != null) { - //OnConnected(state); return state; } TunnelTransportInfo tunnelTransportInfo1 = tunnelTransportInfo.ToJsonFormat().DeJson(); tunnelTransportInfo1.Direction = TunnelTransportDirection.Reverse; - BindAndTTL(tunnelTransportInfo1.Local, tunnelTransportInfo1.Remote, tunnelTransportInfo1); - _ = OnSendConnectBegin(tunnelTransportInfo1); + tunnelBindServer.Bind(tunnelTransportInfo1.Local.Local, tunnelTransportInfo1); + BindAndTTL(tunnelTransportInfo1); + await OnSendConnectBegin(tunnelTransportInfo1); state = await WaitReverse(tunnelTransportInfo1); if (state != null) { - //OnConnected(state); return state; } await OnSendConnectFail(tunnelTransportInfo); - OnConnectFail(tunnelTransportInfo1.Remote.MachineName); + OnConnectFail(tunnelTransportInfo.Remote.MachineName); return null; } public void OnBegin(TunnelTransportInfo tunnelTransportInfo) { OnConnectBegin(tunnelTransportInfo); + if (tunnelTransportInfo.Direction == TunnelTransportDirection.Forward) + { + tunnelBindServer.Bind(tunnelTransportInfo.Local.Local, tunnelTransportInfo); + } Task.Run(async () => { if (tunnelTransportInfo.Direction == TunnelTransportDirection.Forward) { - BindAndTTL(tunnelTransportInfo.Remote, tunnelTransportInfo.Local, tunnelTransportInfo); + BindAndTTL(tunnelTransportInfo); } else { - TunnelTransportState state = await ConnectForward(tunnelTransportInfo.Remote, tunnelTransportInfo.Local, tunnelTransportInfo); + TunnelTransportState state = await ConnectForward(tunnelTransportInfo); if (state != null) { OnConnected(state); @@ -87,74 +90,85 @@ namespace cmonitor.plugins.tunnel.transport public void OnFail(TunnelTransportInfo tunnelTransportInfo) { - tunnelBindServer.RemoveBind(tunnelTransportInfo.BindEP.Port); + tunnelBindServer.RemoveBind(tunnelTransportInfo.Local.Local.Port); } - private async Task ConnectForward(TunnelTransportExternalIPInfo local, TunnelTransportExternalIPInfo remote, TunnelTransportInfo tunnelTransportInfo) + private async Task ConnectForward(TunnelTransportInfo tunnelTransportInfo) { + await Task.Delay(20); //要连接哪些IP IPEndPoint[] eps = new IPEndPoint[] { - new IPEndPoint(remote.Local.Address,remote.Local.Port), - new IPEndPoint(remote.Local.Address,remote.Remote.Port), - new IPEndPoint(remote.Local.Address,remote.Remote.Port+1), - new IPEndPoint(remote.Remote.Address,remote.Remote.Port), - new IPEndPoint(remote.Remote.Address,remote.Remote.Port+1), + new IPEndPoint(tunnelTransportInfo.Remote.Local.Address,tunnelTransportInfo.Remote.Local.Port), + new IPEndPoint(tunnelTransportInfo.Remote.Local.Address,tunnelTransportInfo.Remote.Remote.Port), + new IPEndPoint(tunnelTransportInfo.Remote.Local.Address,tunnelTransportInfo.Remote.Remote.Port+1), + new IPEndPoint(tunnelTransportInfo.Remote.Remote.Address,tunnelTransportInfo.Remote.Remote.Port), + new IPEndPoint(tunnelTransportInfo.Remote.Remote.Address,tunnelTransportInfo.Remote.Remote.Port+1), }; - //过滤掉不支持IPV6的情况,去尝试连接 - IEnumerable results = eps.Where(c => NotIPv6Support(c.Address) == false).Select(ip => + foreach (IPEndPoint ep in eps) { - using Socket targetSocket = new(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - targetSocket.IPv6Only(ip.Address.AddressFamily, false); - targetSocket.ReuseBind(new IPEndPoint(ip.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, local.Local.Port)); - IAsyncResult result = targetSocket.BeginConnect(ip, null, targetSocket); - return result; - }); - //检查一下是否连接成功 - for (int i = 0; i < 10; i++) - { - //全部完成,但是没有连接成功的 - if (results.Count(c => c.IsCompleted && (c.AsyncState as Socket).Connected == false) == results.Count()) - { - return null; - } + Socket targetSocket = new(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + targetSocket.IPv6Only(ep.Address.AddressFamily, false); + targetSocket.ReuseBind(new IPEndPoint(ep.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, tunnelTransportInfo.Local.Local.Port)); - IAsyncResult result = results.FirstOrDefault(c => c.IsCompleted && (c.AsyncState as Socket).Connected); - if (result != null) + IAsyncResult result = targetSocket.BeginConnect(ep, null, null); + + for (int i = 0; i < 25; i++) { + if (result.IsCompleted) + { + break; + } + await Task.Delay(20); + } + try + { + if (result.IsCompleted == false) + { + targetSocket.SafeClose(); + continue; + } + + targetSocket.EndConnect(result); return new TunnelTransportState { - ConnectedObject = result.AsyncState as Socket, + ConnectedObject = targetSocket, TransactionId = tunnelTransportInfo.TransactionId, - RemoteMachineName = remote.MachineName, + RemoteMachineName = tunnelTransportInfo.Remote.MachineName, TransportName = Name, TransportType = Type }; } - await Task.Delay(10); + catch (Exception ex) + { + if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG) + { + Logger.Instance.Error(targetSocket.RemoteEndPoint.ToString()); + Logger.Instance.Error(ex); + } + targetSocket.SafeClose(); + } } return null; } - private void BindAndTTL(TunnelTransportExternalIPInfo local, TunnelTransportExternalIPInfo remote, TunnelTransportInfo tunnelTransportInfo) + private void BindAndTTL(TunnelTransportInfo tunnelTransportInfo) { - tunnelBindServer.Bind(local.Local, tunnelTransportInfo); - //给对方发送TTL消息 IPEndPoint[] eps = new IPEndPoint[] { - new IPEndPoint(remote.Local.Address,remote.Local.Port), - new IPEndPoint(remote.Local.Address,remote.Remote.Port), - new IPEndPoint(remote.Local.Address,remote.Remote.Port+1), - new IPEndPoint(remote.Remote.Address,remote.Remote.Port), - new IPEndPoint(remote.Remote.Address,remote.Remote.Port+1), + new IPEndPoint(tunnelTransportInfo.Remote.Local.Address,tunnelTransportInfo.Local.Local.Port), + new IPEndPoint(tunnelTransportInfo.Remote.Local.Address,tunnelTransportInfo.Remote.Remote.Port), + new IPEndPoint(tunnelTransportInfo.Remote.Local.Address,tunnelTransportInfo.Remote.Remote.Port+1), + new IPEndPoint(tunnelTransportInfo.Remote.Remote.Address,tunnelTransportInfo.Remote.Remote.Port), + new IPEndPoint(tunnelTransportInfo.Remote.Remote.Address,tunnelTransportInfo.Remote.Remote.Port+1), }; //过滤掉不支持IPV6的情况 IEnumerable sockets = eps.Where(c => NotIPv6Support(c.Address) == false).Select(ip => { - using Socket targetSocket = new(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + Socket targetSocket = new(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { targetSocket.IPv6Only(ip.Address.AddressFamily, false); - targetSocket.Ttl = (short)(local.RouteLevel); - targetSocket.ReuseBind(new IPEndPoint(ip.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, local.Local.Port)); + targetSocket.Ttl = (short)(tunnelTransportInfo.Local.RouteLevel + 1); + targetSocket.ReuseBind(new IPEndPoint(ip.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, tunnelTransportInfo.Local.Local.Port)); _ = targetSocket.ConnectAsync(ip); return targetSocket; } @@ -190,14 +204,13 @@ namespace cmonitor.plugins.tunnel.transport { TunnelTransportState result = new TunnelTransportState { - RemoteMachineName = _state.FromMachineName, + RemoteMachineName = _state.Remote.MachineName, TransportType = ProtocolType.Tcp, ConnectedObject = socket, TransactionId = _state.TransactionId, TransportName = _state.TransportName, }; - - if (reverseDic.TryRemove(_state.FromMachineName, out TaskCompletionSource tcs)) + if (reverseDic.TryRemove(_state.Remote.MachineName, out TaskCompletionSource tcs)) { tcs.SetResult(result); return; @@ -212,12 +225,12 @@ namespace cmonitor.plugins.tunnel.transport { TunnelTransportState result = new TunnelTransportState { - RemoteMachineName = _state.FromMachineName, + RemoteMachineName = _state.Remote.MachineName, TransportType = ProtocolType.Tcp, TransactionId = _state.TransactionId, TransportName = _state.TransportName, }; - OnConnected(result); + OnDisConnected(result); } } @@ -226,5 +239,11 @@ namespace cmonitor.plugins.tunnel.transport return ip.AddressFamily == AddressFamily.InterNetworkV6 && (NetworkHelper.IPv6Support == false); } + public sealed class ConnectResultInfo + { + public IAsyncResult Result { get; set; } + public Socket Socket { get; set; } + public bool EndConnected { get; set; } + } } } diff --git a/cmonitor/serializes/IPEndPointFormatter.cs b/cmonitor/serializes/IPEndPointFormatter.cs index ccbcd8bf..a485f58a 100644 --- a/cmonitor/serializes/IPEndPointFormatter.cs +++ b/cmonitor/serializes/IPEndPointFormatter.cs @@ -1,6 +1,5 @@ using common.libs.extends; using MemoryPack; -using System.Linq; using System.Net; namespace cmonitor.serializes diff --git a/common.libs/extends/SerialzeExtends.cs b/common.libs/extends/SerialzeExtends.cs index 2434bf42..e70e3cb7 100644 --- a/common.libs/extends/SerialzeExtends.cs +++ b/common.libs/extends/SerialzeExtends.cs @@ -6,6 +6,14 @@ namespace common.libs.extends { public static class SerialzeExtends { + private static JsonSerializerOptions jsonSerializerOptions1 = new JsonSerializerOptions + { + Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(UnicodeRanges.All), + AllowTrailingCommas = true, + ReadCommentHandling = JsonCommentHandling.Skip, + PropertyNameCaseInsensitive = true, + Converters = { new IPAddressJsonConverter(), new IPEndpointJsonConverter(), new DateTimeConverter() } + }; private static JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions { Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(UnicodeRanges.All), @@ -26,7 +34,7 @@ namespace common.libs.extends }; public static string ToJson(this object obj) { - return JsonSerializer.Serialize(obj); + return JsonSerializer.Serialize(obj, jsonSerializerOptions1); } public static string ToJsonFormat(this object obj) { diff --git a/common.libs/websocket/WebSocketServer.cs b/common.libs/websocket/WebSocketServer.cs index c7f8babe..ebcd6062 100644 --- a/common.libs/websocket/WebSocketServer.cs +++ b/common.libs/websocket/WebSocketServer.cs @@ -395,7 +395,14 @@ namespace common.libs.websocket } public int SendRaw(Memory buffer) { - return Socket.Send(buffer.Span, SocketFlags.None); + try + { + return Socket.Send(buffer.Span, SocketFlags.None); + } + catch (Exception) + { + } + return 0; } public int SendFrame(WebSocketFrameRemarkInfo remark) {