diff --git a/FastTunnel.Core/Client/FastTunnelClient - Copy.cs b/FastTunnel.Core/Client/FastTunnelClient - Copy.cs new file mode 100644 index 0000000..4c5a036 --- /dev/null +++ b/FastTunnel.Core/Client/FastTunnelClient - Copy.cs @@ -0,0 +1,244 @@ +using FastTunnel.Core.Config; +using FastTunnel.Core.Models; +using System; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using FastTunnel.Core.Extensions; +using System.Timers; +using System.Threading; +using Microsoft.Extensions.Logging; +using FastTunnel.Core.Handlers.Client; +using Microsoft.Extensions.Configuration; +using FastTunnel.Core.Server; +using FastTunnel.Core.Sockets; +using Microsoft.Extensions.Options; +using System.Net.WebSockets; +using System.Text.Json; +using FastTunnel.Core.Protocol; + +namespace FastTunnel.Core.Client +{ + public class FastTunnelClient : IFastTunnelClient + { + //Socket _client; + private IFastTunnelClientSocket socket; + + protected ILogger _logger; + + System.Timers.Timer timer_heart; + + double heartInterval = 10 * 1000; // 10 秒心跳 + public DateTime lastHeart; + + int reTrySpan = 10 * 1000; // 登陆失败后重试间隔 + HttpRequestHandler _newCustomerHandler; + NewForwardHandler _newSSHHandler; + LogHandler _logHandler; + ClientHeartHandler _clientHeartHandler; + Message loginMsg; + protected readonly IOptionsMonitor _configuration; + private readonly CancellationTokenSource cancellationTokenSource = new(); + + public SuiDaoServer Server { get; protected set; } + + public FastTunnelClient( + ILogger logger, + HttpRequestHandler newCustomerHandler, + NewForwardHandler newSSHHandler, LogHandler logHandler, + IOptionsMonitor configuration, + ClientHeartHandler clientHeartHandler) + { + _logger = logger; + _newCustomerHandler = newCustomerHandler; + _newSSHHandler = newSSHHandler; + _logHandler = logHandler; + _clientHeartHandler = clientHeartHandler; + _configuration = configuration; + + timer_heart = new System.Timers.Timer(); + timer_heart.AutoReset = false; + timer_heart.Interval = heartInterval; + timer_heart.Elapsed += HeartElapsed; + } + + private async Task reConnAsync() + { + Close(); + + do + { + try + { + Thread.Sleep(reTrySpan); + + _logger.LogInformation("登录重试..."); + socket = await loginAsync(CancellationToken.None); + + break; + } + catch (Exception ex) + { + _logger.LogError(ex.Message); + } + } while (true); + + await connSuccessAsync(); + } + + private async void HeartElapsed(object sender, ElapsedEventArgs e) + { + timer_heart.Enabled = false; + + try + { + socket.SendAsync(new Message { MessageType = MessageType.Heart, Content = null }, cancellationTokenSource.Token).Wait(); + } + catch (Exception) + { + // 与服务端断开连接 + await reConnAsync(); + } + finally + { + timer_heart.Enabled = true; + } + } + + /// + /// 启动客户端 + /// + /// + /// 自定义登录信息,可进行扩展业务 + public async Task StartAsync(CancellationToken cancellationToken) + { + CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, this.cancellationTokenSource.Token); + + _logger.LogInformation("===== FastTunnel Client Start ====="); + + try + { + socket = await loginAsync(cancellationToken); + } + catch (Exception ex) + { + _logger.LogError(ex.Message); + + await reConnAsync(); + return; + } + + _ = connSuccessAsync(); + } + + protected virtual async Task loginAsync(CancellationToken cancellationToken) + { + Server = _configuration.CurrentValue.Server; + _logger.LogInformation($"正在连接服务端 {Server.ServerAddr}:{Server.ServerPort}"); + + try + { + // 连接到的目标IP + socket = new DefultClientSocket(); + + await socket.ConnectAsync( + new Uri($"ws://{_configuration.CurrentValue.Server.ServerAddr}:{_configuration.CurrentValue.Server.ServerPort}"), cancellationToken); + + _logger.LogInformation("连接成功"); + } + catch (Exception) + { + throw; + } + + loginMsg = new Message + { + MessageType = MessageType.C_LogIn, + Content = new LogInMassage + { + Webs = _configuration.CurrentValue.Webs, + SSH = _configuration.CurrentValue.Forwards, + }, + }; + + // 登录 + await socket.SendAsync(loginMsg, cancellationToken); + return socket; + } + + void Close() + { + timer_heart.Stop(); + socket.CloseAsync(); + } + + private async Task connSuccessAsync() + { + _logger.LogDebug("通信已建立"); + + // 心跳开始 + timer_heart.Start(); + + await ReceiveServerAsync(socket); + // await new PipeHepler(_client, ProceccLine).ProcessLinesAsync(); + } + + private async Task ReceiveServerAsync(IFastTunnelClientSocket client) + { + var tunnelProtocol = new TunnelProtocol(); + byte[] buffer = new byte[512]; + int n = 0; + + try + { + while (true) + { + n = await client.ReceiveAsync(buffer, cancellationTokenSource.Token); + var cmds = tunnelProtocol.HandleBuffer(buffer, 0, n); + + foreach (var item in cmds) + { + await HandleServerRequestAsync(item); + } + } + } + catch (Exception ex) + { + + throw; + } + } + + private async Task HandleServerRequestAsync(string lineCmd) + { + _logger.LogInformation($"服务端指令 {lineCmd}"); + var cmds = lineCmd.Split("||"); + var type = cmds[0]; + + TunnelMassage msg = null; + IClientHandler handler; + switch (type) + { + case "Heart": + handler = _clientHeartHandler; + break; + case "S_NewCustomer": + handler = _newCustomerHandler; + msg = JsonSerializer.Deserialize(cmds[1]); + break; + case "S_NewSSH": + handler = _newSSHHandler; + msg = JsonSerializer.Deserialize(cmds[1]); + break; + case "Log": + handler = _logHandler; + msg = JsonSerializer.Deserialize(cmds[1]); + break; + default: + throw new Exception($"未处理的消息:{lineCmd}"); + } + + await handler.HandlerMsgAsync(this, msg); + } + } +} diff --git a/FastTunnel.Core/Client/FastTunnelClient.cs b/FastTunnel.Core/Client/FastTunnelClient.cs index 620f622..d87a2d8 100644 --- a/FastTunnel.Core/Client/FastTunnelClient.cs +++ b/FastTunnel.Core/Client/FastTunnelClient.cs @@ -10,7 +10,6 @@ using System.Threading; using Microsoft.Extensions.Logging; using FastTunnel.Core.Handlers.Client; using Microsoft.Extensions.Configuration; -using FastTunnel.Core.Server; using FastTunnel.Core.Sockets; using Microsoft.Extensions.Options; using System.Net.WebSockets; @@ -21,11 +20,8 @@ namespace FastTunnel.Core.Client { public class FastTunnelClient : IFastTunnelClient { - //Socket _client; private IFastTunnelClientSocket socket; - protected ILogger _logger; - public DateTime lastHeart; HttpRequestHandler _newCustomerHandler; @@ -63,17 +59,8 @@ namespace FastTunnel.Core.Client CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, this.cancellationTokenSource.Token); _logger.LogInformation("===== FastTunnel Client Start ====="); - - try - { - socket = await loginAsync(cancellationToken); - } - catch (Exception ex) - { - _logger.LogError(ex.Message); - return; - } - + socket = await loginAsync(cancellationToken); + _logger.LogInformation($"通讯已建立"); await ReceiveServerAsync(socket); } @@ -144,10 +131,6 @@ namespace FastTunnel.Core.Client IClientHandler handler; switch (type) { - case "Heart": - handler = _clientHeartHandler; - msg = JsonSerializer.Deserialize(cmds[1]); - break; case "S_NewCustomer": handler = _newCustomerHandler; msg = JsonSerializer.Deserialize(cmds[1]); diff --git a/FastTunnel.Core/Client/FastTunnelServer.cs b/FastTunnel.Core/Client/FastTunnelServer.cs index fa3c04c..553d9d3 100644 --- a/FastTunnel.Core/Client/FastTunnelServer.cs +++ b/FastTunnel.Core/Client/FastTunnelServer.cs @@ -1,7 +1,6 @@ using FastTunnel.Core.Config; using FastTunnel.Core.Models; using Microsoft.Extensions.Logging; -using FastTunnel.Core.Handlers.Server; using System.Collections.Concurrent; using System; using FastTunnel.Core.Listener; @@ -18,8 +17,6 @@ namespace FastTunnel.Core.Client { public class FastTunnelServer { - public ConcurrentDictionary RequestTemp { get; private set; } = new ConcurrentDictionary(); - public ConcurrentDictionary> ResponseTasks { get; } = new(); public ConcurrentDictionary WebList { get; private set; } = new(); @@ -28,8 +25,6 @@ namespace FastTunnel.Core.Client = new ConcurrentDictionary>(); readonly ILogger _logger; - //readonly ClientListenerV2 clientListener; - //readonly HttpListenerV2 http_listener; public readonly IOptionsMonitor serverOption; public IProxyConfigProvider proxyConfig; diff --git a/FastTunnel.Core/Extensions/ServicesExtensions.cs b/FastTunnel.Core/Client/ServicesExtensions.cs similarity index 100% rename from FastTunnel.Core/Extensions/ServicesExtensions.cs rename to FastTunnel.Core/Client/ServicesExtensions.cs diff --git a/FastTunnel.Core/Config/IServerConfig.cs b/FastTunnel.Core/Config/IServerConfig.cs index a99cc17..4a04e29 100644 --- a/FastTunnel.Core/Config/IServerConfig.cs +++ b/FastTunnel.Core/Config/IServerConfig.cs @@ -6,8 +6,6 @@ namespace FastTunnel.Core.Config { public interface IServerConfig { - // int BindPort { get; set; } - #region Web相关配置 int WebProxyPort { get; set; } diff --git a/FastTunnel.Core/Dispatchers/ClientDispatcher.cs b/FastTunnel.Core/Dispatchers/ClientDispatcher.cs deleted file mode 100644 index 1e06314..0000000 --- a/FastTunnel.Core/Dispatchers/ClientDispatcher.cs +++ /dev/null @@ -1,146 +0,0 @@ -using FastTunnel.Core.Client; -using FastTunnel.Core.Config; -using FastTunnel.Core.Extensions; -using FastTunnel.Core.Handlers; -using FastTunnel.Core.Handlers.Server; -using FastTunnel.Core.Models; -using FastTunnel.Core.Server; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Net.Sockets; -using System.Text; - -namespace FastTunnel.Core.Dispatchers -{ - public class ClientDispatcher : IListenerDispatcher - { - readonly ILogger _logger; - readonly IServerConfig _serverSettings; - readonly FastTunnelServer _fastTunnelServer; - - readonly LoginHandler _loginHandler; - readonly HeartMessageHandler _heartHandler; - readonly SwapMessageHandler _swapMsgHandler; - Action offLineAction; - - public ClientDispatcher(FastTunnelServer fastTunnelServer, ILogger logger, IServerConfig serverSettings) - { - _logger = logger; - _serverSettings = serverSettings; - _fastTunnelServer = fastTunnelServer; - - _loginHandler = new LoginHandler(logger); - _heartHandler = new HeartMessageHandler(); - _swapMsgHandler = new SwapMessageHandler(logger); - } - - string temp = string.Empty; - - public void Dispatch(Socket client) - { - var reader = new DataReciver(client); - reader.OnComplete += Reader_OnComplete; - reader.OnError += Reader_OnError; - reader.OnReset += Reader_OnReset; - reader.ReciveOneAsync(); - } - - private void Reader_OnReset(DataReciver send, Socket socket, SocketAsyncEventArgs e) - { - offLineAction(socket); - } - - private void Reader_OnError(DataReciver send, SocketAsyncEventArgs e) - { - _logger.LogError("接收客户端数据异常 {0}", e.SocketError); - } - - private void Reader_OnComplete(DataReciver reader, byte[] buffer, int offset, int count) - { - var words = Encoding.UTF8.GetString(buffer, offset, count); - words += temp; - temp = string.Empty; - - _logger.LogDebug($"revice from client: {words}"); - - try - { - int index = 0; - bool needRecive = false; - - while (true) - { - var firstIndex = words.IndexOf("\n"); - if (firstIndex < 0) - { - temp += words; - reader.ReciveOneAsync(); - break; - } - - var sub_words = words.Substring(index, firstIndex + 1); - var res = handle(sub_words, reader.Socket); - - if (res.NeedRecive) - needRecive = true; - - words = words.Replace(sub_words, string.Empty); - if (string.IsNullOrEmpty(words)) - break; - } - - if (needRecive) - { - reader.ReciveOneAsync(); - } - } - catch (Exception ex) - { - _logger.LogError(ex); - _logger.LogError($"handle fail msg:{words}"); - - // throw; - reader.Socket.Send(new Message() { MessageType = MessageType.Log, Content = new LogMassage(LogMsgType.Error, ex.Message) }); - reader.ReciveOneAsync(); - } - } - - private IClientMessageHandler handle(string words, Socket client) - { - Message msg = JsonConvert.DeserializeObject>(words); - - - IClientMessageHandler handler = null; - switch (msg.MessageType) - { - case MessageType.C_LogIn: // 登录 - handler = _loginHandler; - break; - case MessageType.Heart: // 心跳 - handler = _heartHandler; - break; - case MessageType.C_SwapMsg: // 交换数据 - handler = _swapMsgHandler; - break; - default: - throw new Exception($"未知的通讯指令 {msg.MessageType}"); - } - - handler.HandlerMsg(this._fastTunnelServer, client, msg); - return handler; - } - - public void Dispatch(Socket httpClient, Action onOffLine) - { - offLineAction = onOffLine; - Dispatch(httpClient); - } - - public void Dispatch(AsyncUserToken token, string words) - { - throw new NotImplementedException(); - } - } -} diff --git a/FastTunnel.Core/Dispatchers/HttpDispatcherV2.cs b/FastTunnel.Core/Dispatchers/HttpDispatcherV2.cs deleted file mode 100644 index 373c5cd..0000000 --- a/FastTunnel.Core/Dispatchers/HttpDispatcherV2.cs +++ /dev/null @@ -1,179 +0,0 @@ -using FastTunnel.Core.Config; -using FastTunnel.Core.Client; -using FastTunnel.Core.Extensions; -using FastTunnel.Core.Models; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Sockets; -using System.Text; -using System.Text.RegularExpressions; -using System.Net.Http; -using System.IO; -using FastTunnel.Core.Server; -using System.Diagnostics; -using Microsoft.Extensions.Options; - -namespace FastTunnel.Core.Dispatchers -{ - public class HttpDispatcherV2 : IListenerDispatcher - { - readonly ILogger _logger; - readonly IOptionsMonitor _serverOption; - readonly FastTunnelServer _fastTunnelServer; - - public HttpDispatcherV2(FastTunnelServer fastTunnelServer, ILogger logger, IOptionsMonitor serverSettings) - { - _logger = logger; - _serverOption = serverSettings; - _fastTunnelServer = fastTunnelServer; - } - - static string pattern = @"[hH]ost:.+"; - - public void Dispatch(AsyncUserToken token, string words) - { - _logger.LogDebug($"=======Dispatch HTTP {token.RequestId}========"); - - Stopwatch sw = new Stopwatch(); - sw.Start(); - - // 1.检查白名单 - try - { - var endpoint = token.Socket.RemoteEndPoint as System.Net.IPEndPoint; - _logger.LogInformation($"Receive HTTP Request {endpoint.Address}:{endpoint.Port}"); - - if (_serverOption.CurrentValue.WebAllowAccessIps != null) - { - if (!_serverOption.CurrentValue.WebAllowAccessIps.Contains(endpoint.Address.ToString())) - { - HandlerHostNotAccess(token.Socket); - return; - } - } - } - catch (Exception ex) - { - _logger.LogError(ex); - } - - string Host; - MatchCollection collection = Regex.Matches(words, pattern); - if (collection.Count == 0) - { - _logger.LogError($"【Host异常】:{words}"); - - // 返回错误页 - HandlerHostRequired(token.Socket); - return; - } - else - { - Host = collection[0].Value; - } - - var domain = Host.Split(":")[1].Trim(); - - _logger.LogDebug($"=======Dispatch domain:{domain} {token.RequestId} ========"); - - // 判断是否为ip - if (IsIpDomian(domain)) - { - // 返回错误页 - HandlerHostRequired(token.Socket); - return; - } - - WebInfo web; - if (!_fastTunnelServer.WebList.TryGetValue(domain, out web)) - { - _logger.LogDebug($"=======站点未登录 {token.RequestId}========"); - HandlerClientNotOnLine(token.Socket, domain); - return; - } - - try - { - // 发送指令给客户端,等待建立隧道 - web.Socket.SendCmd(new Message { MessageType = MessageType.S_NewCustomer, Content = new NewCustomerMassage { MsgId = token.RequestId, WebConfig = web.WebConfig } }); - } - catch (Exception) - { - _logger.LogDebug($"[客户端不在线] {token.RequestId}"); - HandlerClientNotOnLine(token.Socket, domain); - - // 移除 - _fastTunnelServer.WebList.TryRemove(domain, out _); - } - - // 将等待的http请求 - _fastTunnelServer.RequestTemp.TryAdd(token.RequestId, new NewRequest - { - CustomerClient = token.Socket, - Buffer = token.Recived - }); - } - - public void Dispatch(Socket httpClient) - { - throw new NotImplementedException(); - } - - private bool IsIpDomian(string domain) - { - return Regex.IsMatch(domain, @"^\d.\d.\d.\d.\d$"); - } - - private void HandlerHostNotAccess(Socket client) - { - _logger.LogDebug($"### NotAccessIps:'{client.RemoteEndPoint}'"); - string statusLine = "HTTP/1.1 200 OK\r\n"; - string responseHeader = "Content-Type: text/html\r\n"; - - byte[] responseBody = Encoding.UTF8.GetBytes(TunnelResource.Page_NotAccessIps); - - client.Send(Encoding.UTF8.GetBytes(statusLine)); - client.Send(Encoding.UTF8.GetBytes(responseHeader)); - client.Send(Encoding.UTF8.GetBytes("\r\n")); - client.Send(responseBody); - client.Close(); - } - - private void HandlerHostRequired(Socket client) - { - _logger.LogDebug($"### HostRequired:'{client.RemoteEndPoint}'"); - string statusLine = "HTTP/1.1 200 OK\r\n"; - string responseHeader = "Content-Type: text/html\r\n"; - - byte[] responseBody = Encoding.UTF8.GetBytes(TunnelResource.Page_HostRequired); - - client.Send(Encoding.UTF8.GetBytes(statusLine)); - client.Send(Encoding.UTF8.GetBytes(responseHeader)); - client.Send(Encoding.UTF8.GetBytes("\r\n")); - client.Send(responseBody); - client.Close(); - } - - private void HandlerClientNotOnLine(Socket client, string domain) - { - _logger.LogDebug($"### TunnelNotFound:'{domain}'"); - string statusLine = "HTTP/1.1 200 OK\r\n"; - string responseHeader = "Content-Type: text/html\r\n"; - - byte[] responseBody = Encoding.UTF8.GetBytes(TunnelResource.Page_NoTunnel); - - client.Send(Encoding.UTF8.GetBytes(statusLine)); - client.Send(Encoding.UTF8.GetBytes(responseHeader)); - client.Send(Encoding.UTF8.GetBytes("\r\n")); - client.Send(responseBody); - client.Close(); - } - - public void Dispatch(Socket httpClient, Action onOffLine) - { - Dispatch(httpClient); - } - } -} diff --git a/FastTunnel.Core/Dispatchers/IListenerDispatcher.cs b/FastTunnel.Core/Dispatchers/IListenerDispatcher.cs deleted file mode 100644 index 23a4045..0000000 --- a/FastTunnel.Core/Dispatchers/IListenerDispatcher.cs +++ /dev/null @@ -1,16 +0,0 @@ -using FastTunnel.Core.Server; -using System; -using System.Collections.Generic; -using System.Net.Sockets; -using System.Text; -using System.Threading.Tasks; - -namespace FastTunnel.Core.Dispatchers -{ - public interface IListenerDispatcher - { - void Dispatch(AsyncUserToken token, string words); - - void DispatchAsync(Socket httpClient); - } -} diff --git a/FastTunnel.Core/Extensions/ByteArrayExtension.cs b/FastTunnel.Core/Extensions/ByteArrayExtensions.cs similarity index 88% rename from FastTunnel.Core/Extensions/ByteArrayExtension.cs rename to FastTunnel.Core/Extensions/ByteArrayExtensions.cs index 57acf72..f506f51 100644 --- a/FastTunnel.Core/Extensions/ByteArrayExtension.cs +++ b/FastTunnel.Core/Extensions/ByteArrayExtensions.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace FastTunnel.Core.Extensions { - public static class ByteArrayExtension + public static class ByteArrayExtensions { public static string GetString(this byte[] buffer, int offset, int count) { diff --git a/FastTunnel.Core/Extensions/LogExtentions.cs b/FastTunnel.Core/Extensions/LoggerExtentions.cs similarity index 87% rename from FastTunnel.Core/Extensions/LogExtentions.cs rename to FastTunnel.Core/Extensions/LoggerExtentions.cs index 00d9abf..70955d7 100644 --- a/FastTunnel.Core/Extensions/LogExtentions.cs +++ b/FastTunnel.Core/Extensions/LoggerExtentions.cs @@ -5,7 +5,7 @@ using System.Text; namespace FastTunnel.Core.Extensions { - public static class LogExtentions + public static class LoggerExtentions { public static void LogError(this ILogger logger, Exception ex) { diff --git a/FastTunnel.Core/Extensions/SocketExtension.cs b/FastTunnel.Core/Extensions/SocketExtensions.cs similarity index 90% rename from FastTunnel.Core/Extensions/SocketExtension.cs rename to FastTunnel.Core/Extensions/SocketExtensions.cs index 489c0e2..160162c 100644 --- a/FastTunnel.Core/Extensions/SocketExtension.cs +++ b/FastTunnel.Core/Extensions/SocketExtensions.cs @@ -6,7 +6,7 @@ using System.Text; namespace FastTunnel.Core.Extensions { - public static class SocketExtension + public static class SocketExtensions { public static void SendCmd(this Socket socket, Message message) where T : TunnelMassage diff --git a/FastTunnel.Core/Extensions/WebSocketExtension.cs b/FastTunnel.Core/Extensions/WebSocketExtensions.cs similarity index 96% rename from FastTunnel.Core/Extensions/WebSocketExtension.cs rename to FastTunnel.Core/Extensions/WebSocketExtensions.cs index c8c6fac..e5e8476 100644 --- a/FastTunnel.Core/Extensions/WebSocketExtension.cs +++ b/FastTunnel.Core/Extensions/WebSocketExtensions.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace FastTunnel.Core.Extensions { - public static class WebSocketExtension + public static class WebSocketExtensions { public static async Task SendCmdAsync(this WebSocket socket, Message message, WebSocketMessageType webSocketMessage, bool end, CancellationToken cancellationToken) diff --git a/FastTunnel.Core/FastTunnel.Core.csproj b/FastTunnel.Core/FastTunnel.Core.csproj index f619b16..3c9d800 100644 --- a/FastTunnel.Core/FastTunnel.Core.csproj +++ b/FastTunnel.Core/FastTunnel.Core.csproj @@ -26,9 +26,6 @@ - - - @@ -42,7 +39,6 @@ - diff --git a/FastTunnel.Core/Dispatchers/ForwardDispatcher.cs b/FastTunnel.Core/Handlers/Client/ForwardHandler.cs similarity index 81% rename from FastTunnel.Core/Dispatchers/ForwardDispatcher.cs rename to FastTunnel.Core/Handlers/Client/ForwardHandler.cs index eaf3c29..2283b38 100644 --- a/FastTunnel.Core/Dispatchers/ForwardDispatcher.cs +++ b/FastTunnel.Core/Handlers/Client/ForwardHandler.cs @@ -2,7 +2,6 @@ using FastTunnel.Core.Dispatchers; using FastTunnel.Core.Extensions; using FastTunnel.Core.Models; -using FastTunnel.Core.Server; using Microsoft.AspNetCore.Hosting.Server; using System; using System.Collections.Generic; @@ -15,13 +14,13 @@ using System.Threading.Tasks; namespace FastTunnel.Core.Dispatchers { - public class ForwardDispatcher : IListenerDispatcher + public class ForwardHandler { private FastTunnelServer _server; private WebSocket _client; private ForwardConfig _config; - public ForwardDispatcher(FastTunnelServer server, WebSocket client, ForwardConfig config) + public ForwardHandler(FastTunnelServer server, WebSocket client, ForwardConfig config) { _server = server; _client = client; @@ -46,10 +45,5 @@ namespace FastTunnel.Core.Dispatchers { } } - - public void Dispatch(AsyncUserToken token, string words) - { - throw new NotImplementedException(); - } } } diff --git a/FastTunnel.Core/Handlers/Client/HttpRequestHandler.cs b/FastTunnel.Core/Handlers/Client/HttpRequestHandler.cs index 143806d..73e6186 100644 --- a/FastTunnel.Core/Handlers/Client/HttpRequestHandler.cs +++ b/FastTunnel.Core/Handlers/Client/HttpRequestHandler.cs @@ -15,7 +15,6 @@ using System.Net.WebSockets; using FastTunnel.Core.Forwarder; using Microsoft; using Microsoft.AspNetCore.DataProtection; -using FastTunnel.Core.Server; using System.Data.Common; namespace FastTunnel.Core.Handlers.Client diff --git a/FastTunnel.Core/Handlers/Server/HeartMessageHandler.cs b/FastTunnel.Core/Handlers/Server/HeartMessageHandler.cs deleted file mode 100644 index 4688500..0000000 --- a/FastTunnel.Core/Handlers/Server/HeartMessageHandler.cs +++ /dev/null @@ -1,24 +0,0 @@ -using FastTunnel.Core.Client; -using FastTunnel.Core.Extensions; -using FastTunnel.Core.Models; -using System; -using System.Collections.Generic; -using System.Net.Sockets; -using System.Net.WebSockets; -using System.Text; -using System.Threading.Tasks; - -namespace FastTunnel.Core.Handlers.Server -{ - public class HeartMessageHandler : IClientMessageHandler - { - public bool NeedRecive => true; - - public async Task HandlerMsg(FastTunnelServer server, WebSocket client, T msg) - where T : TunnelMassage - { - await client.SendCmdAsync(new Message() { MessageType = MessageType.Heart, Content = new HeartMassage { } }); - return NeedRecive; - } - } -} diff --git a/FastTunnel.Core/Handlers/Server/LoginHandler.cs b/FastTunnel.Core/Handlers/Server/LoginHandler.cs index c626098..84c4830 100644 --- a/FastTunnel.Core/Handlers/Server/LoginHandler.cs +++ b/FastTunnel.Core/Handlers/Server/LoginHandler.cs @@ -3,7 +3,6 @@ using FastTunnel.Core.Dispatchers; using FastTunnel.Core.Extensions; using FastTunnel.Core.Filters; using FastTunnel.Core.Global; -using FastTunnel.Core.Handlers.Server; using FastTunnel.Core.Listener; using FastTunnel.Core.Models; using Microsoft.Extensions.Logging; @@ -94,7 +93,7 @@ namespace FastTunnel.Core.Handlers var ls = new PortProxyListener("0.0.0.0", item.RemotePort, _logger); - ls.Start(new ForwardDispatcher(server, client, item)); + ls.Start(new ForwardHandler(server, client, item)); // listen success server.ForwardList.TryAdd(item.RemotePort, new ForwardInfo { Listener = ls, Socket = client, SSHConfig = item }); diff --git a/FastTunnel.Core/Listener/HttpListenerV2.cs b/FastTunnel.Core/Listener/HttpListenerV2.cs deleted file mode 100644 index 7d60507..0000000 --- a/FastTunnel.Core/Listener/HttpListenerV2.cs +++ /dev/null @@ -1,67 +0,0 @@ -using FastTunnel.Core.Dispatchers; -using FastTunnel.Core.Handlers.Server; -using FastTunnel.Core.Server; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Threading; - -namespace FastTunnel.Core.Listener -{ - public class HttpListenerV2 - { - ILogger _logger; - - public string ListenIp { get; protected set; } - - public int ListenPort { get; protected set; } - - IListenerDispatcher _requestDispatcher; - public IList ConnectedSockets = new List(); - - Server.Server server; - - public HttpListenerV2(string ip, int port, ILogger logger) - { - _logger = logger; - this.ListenIp = ip; - this.ListenPort = port; - - server = new Server.Server(1000, 512, true, _logger); - } - - public void Start(IListenerDispatcher requestDispatcher, int backlog = 100) - { - _requestDispatcher = requestDispatcher; - - IPAddress ipa = IPAddress.Parse(ListenIp); - IPEndPoint localEndPoint = new IPEndPoint(ipa, ListenPort); - - server.Init(); - server.Start(localEndPoint, "\r\n\r\n", handle); - _logger.LogInformation($"监听客户端 -> {ListenIp}:{ListenPort}"); - } - - private bool handle(AsyncUserToken token, string words) - { - try - { - _requestDispatcher.Dispatch(token, words); - return false; - } - catch (Exception ex) - { - _logger.LogCritical(ex, $"【处理HTTP请求异常】{words}"); - } - - return false; - } - - public void Stop() - { - } - } -} diff --git a/FastTunnel.Core/Listener/IListener.cs b/FastTunnel.Core/Listener/IListener.cs index 7bf2373..ca7cfbe 100644 --- a/FastTunnel.Core/Listener/IListener.cs +++ b/FastTunnel.Core/Listener/IListener.cs @@ -1,5 +1,4 @@ using FastTunnel.Core.Dispatchers; -using FastTunnel.Core.Handlers.Server; using System; using System.Collections.Generic; using System.Net.Sockets; diff --git a/FastTunnel.Core/Listener/PortProxyListener.cs b/FastTunnel.Core/Listener/PortProxyListener.cs index b654ef9..6eeee18 100644 --- a/FastTunnel.Core/Listener/PortProxyListener.cs +++ b/FastTunnel.Core/Listener/PortProxyListener.cs @@ -1,5 +1,4 @@ using FastTunnel.Core.Dispatchers; -using FastTunnel.Core.Handlers.Server; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -20,7 +19,7 @@ namespace FastTunnel.Core.Listener int m_numConnectedSockets; bool shutdown = false; - IListenerDispatcher _requestDispatcher; + ForwardHandler _requestDispatcher; Socket listenSocket; public IList ConnectedSockets = new List(); @@ -37,7 +36,7 @@ namespace FastTunnel.Core.Listener listenSocket.Bind(localEndPoint); } - public void Start(IListenerDispatcher requestDispatcher) + public void Start(ForwardHandler requestDispatcher) { shutdown = false; _requestDispatcher = requestDispatcher; diff --git a/FastTunnel.Core/Models/ForwardHandlerArg.cs b/FastTunnel.Core/Models/ForwardHandlerArg.cs index 2800d6f..f16ffca 100644 --- a/FastTunnel.Core/Models/ForwardHandlerArg.cs +++ b/FastTunnel.Core/Models/ForwardHandlerArg.cs @@ -7,8 +7,8 @@ namespace FastTunnel.Core.Models { public class ForwardHandlerArg { - public ForwardConfig SSHConfig { get; internal set; } + public ForwardConfig SSHConfig { get; set; } - public Socket LocalClient { get; internal set; } + public Socket LocalClient { get; set; } } } diff --git a/FastTunnel.Core/Models/Massage/HeartMassage.cs b/FastTunnel.Core/Models/Massage/HeartMassage.cs deleted file mode 100644 index 8590aff..0000000 --- a/FastTunnel.Core/Models/Massage/HeartMassage.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace FastTunnel.Core.Models -{ - public class HeartMassage : TunnelMassage - { - public string Time { get; set; } - } -} diff --git a/FastTunnel.Core/Models/NewRequest.cs b/FastTunnel.Core/Models/NewRequest.cs deleted file mode 100644 index eee11a6..0000000 --- a/FastTunnel.Core/Models/NewRequest.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Sockets; -using System.Text; - -namespace FastTunnel.Core.Models -{ - public class NewRequest - { - public Socket CustomerClient { get; set; } - public byte[] Buffer { get; set; } - } -} diff --git a/FastTunnel.Core/Models/TunnelClient.cs b/FastTunnel.Core/Models/TunnelClient.cs index 3bf7f96..5ba5a6e 100644 --- a/FastTunnel.Core/Models/TunnelClient.cs +++ b/FastTunnel.Core/Models/TunnelClient.cs @@ -1,7 +1,6 @@ using FastTunnel.Core.Client; using FastTunnel.Core.Extensions; using FastTunnel.Core.Handlers; -using FastTunnel.Core.Handlers.Server; using FastTunnel.Core.Protocol; using Microsoft.Extensions.Logging; using System; @@ -20,8 +19,6 @@ namespace FastTunnel.Core.Models public class TunnelClient { readonly LoginHandler _loginHandler; - readonly HeartMessageHandler _heartHandler; - //readonly SwapMessageHandler _swapMsgHandler; FastTunnelServer fastTunnelServer; ILogger logger; WebSocket webSocket; @@ -32,8 +29,6 @@ namespace FastTunnel.Core.Models this.logger = logger; this.fastTunnelServer = fastTunnelServer; this._loginHandler = new LoginHandler(logger, fastTunnelServer.proxyConfig); - this._heartHandler = new HeartMessageHandler(); - // this._swapMsgHandler = new SwapMessageHandler(logger); } public async Task ReviceAsync() @@ -45,6 +40,8 @@ namespace FastTunnel.Core.Models { var res = await webSocket.ReceiveAsync(buffer, CancellationToken.None); var cmds = tunnelProtocol.HandleBuffer(buffer, 0, res.Count); + if (cmds == null) continue; + foreach (var item in cmds) { if (!await HandleCmdAsync(webSocket, item)) @@ -71,9 +68,6 @@ namespace FastTunnel.Core.Models handler = _loginHandler; msg = JsonSerializer.Deserialize(cmds[1]); break; - case "Heart": // 心跳 - handler = _heartHandler; - break; default: throw new Exception($"未知的通讯指令 {lineCmd}"); } diff --git a/FastTunnel.Core/Server/AsyncUserToken.cs b/FastTunnel.Core/Server/AsyncUserToken.cs deleted file mode 100644 index 9a66c0c..0000000 --- a/FastTunnel.Core/Server/AsyncUserToken.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Sockets; -using System.Text; -using System.Threading.Tasks; - -namespace FastTunnel.Core.Server -{ - public class AsyncUserToken - { - public Socket Socket { get; set; } - - public string MassgeTemp { get; set; } - - public byte[] Recived { get; set; } - - public string RequestId { get; set; } - } -} diff --git a/FastTunnel.Core/Server/BufferManeger.cs b/FastTunnel.Core/Server/BufferManeger.cs deleted file mode 100644 index e95bc8c..0000000 --- a/FastTunnel.Core/Server/BufferManeger.cs +++ /dev/null @@ -1,69 +0,0 @@ -// This class creates a single large buffer which can be divided up -// and assigned to SocketAsyncEventArgs objects for use with each -// socket I/O operation. -// This enables bufffers to be easily reused and guards against -// fragmenting heap memory. -// -// The operations exposed on the BufferManager class are not thread safe. -using System.Collections.Generic; -using System.Net.Sockets; - -namespace FastTunnel.Core.Server -{ - class BufferManager - { - int m_numBytes; // the total number of bytes controlled by the buffer pool - byte[] m_buffer; // the underlying byte array maintained by the Buffer Manager - Stack m_freeIndexPool; // - int m_currentIndex; - int m_bufferSize; - - public BufferManager(int totalBytes, int bufferSize) - { - m_numBytes = totalBytes; - m_currentIndex = 0; - m_bufferSize = bufferSize; - m_freeIndexPool = new Stack(); - } - - // Allocates buffer space used by the buffer pool - public void InitBuffer() - { - // create one big large buffer and divide that - // out to each SocketAsyncEventArg object - m_buffer = new byte[m_numBytes]; - } - - // Assigns a buffer from the buffer pool to the - // specified SocketAsyncEventArgs object - // - // true if the buffer was successfully set, else false - public bool SetBuffer(SocketAsyncEventArgs args) - { - if (m_freeIndexPool.Count > 0) - { - args.SetBuffer(m_buffer, m_freeIndexPool.Pop(), m_bufferSize); - } - else - { - if ((m_numBytes - m_bufferSize) < m_currentIndex) - { - return false; - } - - args.SetBuffer(m_buffer, m_currentIndex, m_bufferSize); - m_currentIndex += m_bufferSize; - } - return true; - } - - // Removes the buffer from a SocketAsyncEventArg object. - // This frees the buffer back to the buffer pool - public void FreeBuffer(SocketAsyncEventArgs args) - { - m_freeIndexPool.Push(args.Offset); - args.SetBuffer(null, 0, 0); - } - - } -} \ No newline at end of file diff --git a/FastTunnel.Core/Server/PipeHepler.cs b/FastTunnel.Core/Server/PipeHepler.cs deleted file mode 100644 index 7114bcd..0000000 --- a/FastTunnel.Core/Server/PipeHepler.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System; -using System.Buffers; -using System.Collections.Generic; -using System.IO.Pipelines; -using System.Linq; -using System.Net.Sockets; -using System.Text; -using System.Threading.Tasks; - -namespace FastTunnel.Core.Server -{ - public class PipeHepler - { - Socket m_socket; - Func processLine; - const int minimumBufferSize = 512; - - public PipeHepler(Socket socket, Func processLine) - { - this.processLine = processLine; - m_socket = socket; - } - - public async Task ProcessLinesAsync() - { - var pipe = new Pipe(); - Task writing = FillPipeAsync(pipe.Writer); - Task reading = ReadPipeAsync(pipe.Reader); - await Task.WhenAll(reading, writing); - } - - private async Task FillPipeAsync(PipeWriter writer) - { - while (true) - { - // Allocate at least 512 bytes from the PipeWriter. - Memory memory = writer.GetMemory(minimumBufferSize); - try - { - int bytesRead = await m_socket.ReceiveAsync(memory, SocketFlags.None); - if (bytesRead == 0) - { - break; - } - // Tell the PipeWriter how much was read from the Socket. - writer.Advance(bytesRead); - } - catch (Exception) - { - break; - } - - // Make the data available to the PipeReader. - FlushResult result = await writer.FlushAsync(); - - if (result.IsCompleted) - { - break; - } - } - - // By completing PipeWriter, tell the PipeReader that there's no more data coming. - await writer.CompleteAsync(); - } - - private async Task ReadPipeAsync(PipeReader reader) - { - while (true) - { - ReadResult result = await reader.ReadAsync(); - ReadOnlySequence buffer = result.Buffer; - - while (TryReadLine(ref buffer, out ReadOnlySequence line)) - { - // Process the line. - if (!processLine(m_socket, line.ToArray())) - { - // 停止继续监听 - break; - } - } - - // Tell the PipeReader how much of the buffer has been consumed. - reader.AdvanceTo(buffer.Start, buffer.End); - - // Stop reading if there's no more data coming. - if (result.IsCompleted) - { - break; - } - } - - // Mark the PipeReader as complete. - await reader.CompleteAsync(); - } - - static bool TryReadLine(ref ReadOnlySequence buffer, out ReadOnlySequence line) - { - // Look for a EOL in the buffer. - SequencePosition? position = buffer.PositionOf((byte)'\n'); - - if (position == null) - { - line = default; - return false; - } - - // Skip the line + the \n. - line = buffer.Slice(0, position.Value); - buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); - return true; - } - - } -} diff --git a/FastTunnel.Core/Server/Server.cs b/FastTunnel.Core/Server/Server.cs deleted file mode 100644 index 8bdf53b..0000000 --- a/FastTunnel.Core/Server/Server.cs +++ /dev/null @@ -1,323 +0,0 @@ -// Implements the connection logic for the socket server. -// After accepting a connection, all data read from the client -// is sent back to the client. The read and echo back to the client pattern -// is continued until the client disconnects. -using FastTunnel.Core.Extensions; -using FastTunnel.Core.Utility.Extensions; -using Microsoft.Extensions.Logging; -using System; -using System.Linq; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Threading; - -namespace FastTunnel.Core.Server -{ - public class Server - { - private int m_numConnections; // the maximum number of connections the sample is designed to handle simultaneously - private int m_receiveBufferSize;// buffer size to use for each socket I/O operation - - BufferManager m_bufferManager; // represents a large reusable set of buffers for all socket operations - const int opsToPreAlloc = 2; // read, write (don't alloc buffer space for accepts) - Socket listenSocket; // the socket used to listen for incoming connection requests - // pool of reusable SocketAsyncEventArgs objects for write, read and accept socket operations - SocketAsyncEventArgsPool m_readWritePool; - //int m_totalBytesRead; // counter of the total # bytes received by the server - int m_numConnectedSockets; // the total number of clients connected to the server - Semaphore m_maxNumberAcceptedClients; - - Func m_handller; - string m_sectionFlag; - IPEndPoint _localEndPoint; - bool m_isHttpServer; - - ILogger _logger; - - // Create an uninitialized server instance. - // To start the server listening for connection requests - // call the Init method followed by Start method - // - // the maximum number of connections the sample is designed to handle simultaneously - // buffer size to use for each socket I/O operation - public Server(int numConnections, int receiveBufferSize, bool isHttpServer, ILogger logger) - { - m_isHttpServer = isHttpServer; - _logger = logger; - //m_totalBytesRead = 0; - m_numConnectedSockets = 0; - m_numConnections = numConnections; - m_receiveBufferSize = receiveBufferSize; - // allocate buffers such that the maximum number of sockets can have one outstanding read and - // write posted to the socket simultaneously - m_bufferManager = new BufferManager(receiveBufferSize * numConnections * opsToPreAlloc, - receiveBufferSize); - - m_readWritePool = new SocketAsyncEventArgsPool(numConnections); - - m_maxNumberAcceptedClients = new Semaphore(numConnections, numConnections); - } - - // Initializes the server by preallocating reusable buffers and - // context objects. These objects do not need to be preallocated - // or reused, but it is done this way to illustrate how the API can - // easily be used to create reusable objects to increase server performance. - // - public void Init() - { - // Allocates one large byte buffer which all I/O operations use a piece of. This gaurds - // against memory fragmentation - m_bufferManager.InitBuffer(); - - // preallocate pool of SocketAsyncEventArgs objects - SocketAsyncEventArgs readWriteEventArg; - - for (int i = 0; i < m_numConnections; i++) - { - //Pre-allocate a set of reusable SocketAsyncEventArgs - readWriteEventArg = new SocketAsyncEventArgs(); - readWriteEventArg.Completed += new EventHandler(IO_Completed); - readWriteEventArg.UserToken = new AsyncUserToken(); - - // assign a byte buffer from the buffer pool to the SocketAsyncEventArg object - m_bufferManager.SetBuffer(readWriteEventArg); - - // add SocketAsyncEventArg to the pool - m_readWritePool.Push(readWriteEventArg); - } - } - - // Starts the server such that it is listening for - // incoming connection requests. - // - // The endpoint which the server will listening - // for connection requests on - public void Start(IPEndPoint localEndPoint, string sectionFlag, Func handller) - { - m_handller = handller; - m_sectionFlag = sectionFlag; - _localEndPoint = localEndPoint; - - // create the socket which listens for incoming connections - listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - listenSocket.Bind(localEndPoint); - // start the server with a listen backlog of 100 connections - listenSocket.Listen(); - - // post accepts on the listening socket - StartAccept(null); - } - - // Begins an operation to accept a connection request from the client - // - // The context object to use when issuing - // the accept operation on the server's listening socket - public void StartAccept(SocketAsyncEventArgs acceptEventArg) - { - if (acceptEventArg == null) - { - acceptEventArg = new SocketAsyncEventArgs(); - acceptEventArg.Completed += new EventHandler(AcceptEventArg_Completed); - } - else - { - // socket must be cleared since the context object is being reused - acceptEventArg.AcceptSocket = null; - } - - m_maxNumberAcceptedClients.WaitOne(); - - bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg); - if (!willRaiseEvent) - { - ProcessAccept(acceptEventArg); - } - } - - // This method is the callback method associated with Socket.AcceptAsync - // operations and is invoked when an accept operation is complete - void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e) - { - ProcessAccept(e); - } - - private void ProcessAccept(SocketAsyncEventArgs e) - { - Interlocked.Increment(ref m_numConnectedSockets); - _logger.LogInformation($"[当前连接数]:{_localEndPoint.Port} | {m_numConnectedSockets}"); - - // Get the socket for the accepted client connection and put it into the - // ReadEventArg object user token - SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop(); - var token = readEventArgs.UserToken as AsyncUserToken; - token.Socket = e.AcceptSocket; - token.MassgeTemp = null; - token.Recived = null; - - // 客户端请求不需要分配msgid - if (m_isHttpServer) - { - token.RequestId = $"{DateTime.Now.GetChinaTicks()}_{Guid.NewGuid().ToString().Replace("-", string.Empty)}"; - _logger.LogDebug($"Accept {token.RequestId}"); - } - - // As soon as the client is connected, post a receive to the connection - bool willRaiseEvent = e.AcceptSocket.ReceiveAsync(readEventArgs); - if (!willRaiseEvent) - { - ProcessReceive(readEventArgs); - } - - // Accept the next connection request - StartAccept(e); - } - - // This method is called whenever a receive or send operation is completed on a socket - // - // SocketAsyncEventArg associated with the completed receive operation - void IO_Completed(object sender, SocketAsyncEventArgs e) - { - // determine which type of operation just completed and call the associated handler - switch (e.LastOperation) - { - case SocketAsyncOperation.Receive: - ProcessReceive(e); - break; - case SocketAsyncOperation.Send: - ProcessSend(e); - break; - default: - throw new ArgumentException("The last operation completed on the socket was not a receive or send"); - } - } - - // This method is invoked when an asynchronous receive operation completes. - // If the remote host closed the connection, then the socket is closed. - // If data was received then the data is echoed back to the client. - // - private void ProcessReceive(SocketAsyncEventArgs e) - { - AsyncUserToken token = (AsyncUserToken)e.UserToken; - _logger.LogDebug($"[ProcessReceive]: {_localEndPoint.Port} | {token.RequestId}"); - if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) - { - bool needRecive = false; - var words = e.Buffer.GetString(e.Offset, e.BytesTransferred); - var sum = token.MassgeTemp + words; - - // 只有http请求需要对已发送字节进行存储 - if (m_isHttpServer) - { - if (token.Recived != null) - { - byte[] resArr = new byte[token.Recived.Length + e.BytesTransferred]; - token.Recived.CopyTo(resArr, 0); - Array.Copy(e.Buffer, e.Offset, resArr, token.Recived.Length, e.BytesTransferred); - token.Recived = resArr; - } - else - { - byte[] resArr = new byte[e.BytesTransferred]; - Array.Copy(e.Buffer, e.Offset, resArr, 0, e.BytesTransferred); - token.Recived = resArr; - } - } - - if (sum.Contains(m_sectionFlag)) - { - var array = (sum).Split(m_sectionFlag); - token.MassgeTemp = null; - var fullMsg = words.EndsWith(m_sectionFlag); - - if (!fullMsg) - { - token.MassgeTemp = array[array.Length - 1]; - } - - for (int i = 0; i < array.Length - 1; i++) - { - needRecive = m_handller(token, array[i]); - if (needRecive) - { - continue; - } - else - { - // ÊÍ·Å×ÊÔ´ - release(e); - return; - } - } - } - else - { - token.MassgeTemp = sum; - } - - bool willRaiseEvent = token.Socket.ReceiveAsync(e); - if (!willRaiseEvent) - { - ProcessReceive(e); - } - } - else - { - CloseClientSocket(e); - } - } - - // This method is invoked when an asynchronous send operation completes. - // The method issues another receive on the socket to read any additional - // data sent from the client - // - // - private void ProcessSend(SocketAsyncEventArgs e) - { - if (e.SocketError == SocketError.Success) - { - // done echoing data back to the client - AsyncUserToken token = (AsyncUserToken)e.UserToken; - // read the next block of data send from the client - e.SetBuffer(e.Offset, m_receiveBufferSize); - bool willRaiseEvent = token.Socket.ReceiveAsync(e); - if (!willRaiseEvent) - { - ProcessReceive(e); - } - } - else - { - CloseClientSocket(e); - } - } - - private void CloseClientSocket(SocketAsyncEventArgs e) - { - AsyncUserToken token = e.UserToken as AsyncUserToken; - - // close the socket associated with the client - try - { - token.Socket.Shutdown(SocketShutdown.Send); - } - // throws if client process has already closed - catch (Exception) { } - token.Socket.Close(); - - release(e); - } - - private void release(SocketAsyncEventArgs e) - { - // decrement the counter keeping track of the total number of clients connected to the server - Interlocked.Decrement(ref m_numConnectedSockets); - - _logger.LogInformation($"[SocketCount]:{_localEndPoint.Port} | {m_numConnectedSockets}"); - // Free the SocketAsyncEventArg so they can be reused by another client - m_readWritePool.Push(e); - - m_maxNumberAcceptedClients.Release(); - } - } -} diff --git a/FastTunnel.Core/Server/SocketAsyncEventArgsPool.cs b/FastTunnel.Core/Server/SocketAsyncEventArgsPool.cs deleted file mode 100644 index ebcadce..0000000 --- a/FastTunnel.Core/Server/SocketAsyncEventArgsPool.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Represents a collection of reusable SocketAsyncEventArgs objects. -using System; -using System.Collections.Generic; -using System.Net.Sockets; - -class SocketAsyncEventArgsPool -{ - Stack m_pool; - - // Initializes the object pool to the specified size - // - // The "capacity" parameter is the maximum number of - // SocketAsyncEventArgs objects the pool can hold - public SocketAsyncEventArgsPool(int capacity) - { - m_pool = new Stack(capacity); - } - - // Add a SocketAsyncEventArg instance to the pool - // - //The "item" parameter is the SocketAsyncEventArgs instance - // to add to the pool - public void Push(SocketAsyncEventArgs item) - { - if (item == null) { throw new ArgumentNullException("Items added to a SocketAsyncEventArgsPool cannot be null"); } - lock (m_pool) - { - m_pool.Push(item); - } - } - - // Removes a SocketAsyncEventArgs instance from the pool - // and returns the object removed from the pool - public SocketAsyncEventArgs Pop() - { - lock (m_pool) - { - return m_pool.Pop(); - } - } - - // The number of SocketAsyncEventArgs instances in the pool - public int Count - { - get { return m_pool.Count; } - } - -} - \ No newline at end of file diff --git a/FastTunnel.Core/Services/ServiceFastTunnelClient.cs b/FastTunnel.Core/Services/ServiceFastTunnelClient.cs index 30024d3..4a8f1a0 100644 --- a/FastTunnel.Core/Services/ServiceFastTunnelClient.cs +++ b/FastTunnel.Core/Services/ServiceFastTunnelClient.cs @@ -26,12 +26,20 @@ namespace FastTunnel.Core.Services AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; } - public Task StartAsync(CancellationToken cancellationToken) + public async Task StartAsync(CancellationToken cancellationToken) { - return Task.Run(() => + while (!cancellationToken.IsCancellationRequested) { - _fastTunnelClient.StartAsync(cancellationToken); - }, cancellationToken); + try + { + await _fastTunnelClient.StartAsync(cancellationToken); + } + catch (Exception ex) + { + _logger.LogError(ex.Message); + await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken); + } + } } public Task StopAsync(CancellationToken cancellationToken) diff --git a/FastTunnel.Core/Utility/Helper/FileHelper.cs b/FastTunnel.Core/Utility/Helper/FileHelper.cs deleted file mode 100644 index 89af322..0000000 --- a/FastTunnel.Core/Utility/Helper/FileHelper.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace FastTunnel.Core.Helper -{ - public static class FileHelper - { - public static byte[] GetBytesFromFile(string fileName) - { - if (!File.Exists(fileName)) - { - return null; - } - - FileInfo fi = new FileInfo(fileName); - byte[] buff = new byte[fi.Length]; - - FileStream fs = fi.OpenRead(); - fs.Read(buff, 0, Convert.ToInt32(fs.Length)); - fs.Close(); - - return buff; - } - } -} diff --git a/FastTunnel.Core/Utility/Helper/ValidateHelper.cs b/FastTunnel.Core/Utility/Helper/ValidateHelper.cs deleted file mode 100644 index 5ac7a39..0000000 --- a/FastTunnel.Core/Utility/Helper/ValidateHelper.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace FastTunnel.Core.Helper -{ - public static class ValidateHelper - { - public static string[] ValidateObject(object instance) - { - throw new NotImplementedException(); - } - } -} diff --git a/FastTunnel.Server/FastTunnel.Server.csproj b/FastTunnel.Server/FastTunnel.Server.csproj index 8fbb4df..d223212 100644 --- a/FastTunnel.Server/FastTunnel.Server.csproj +++ b/FastTunnel.Server/FastTunnel.Server.csproj @@ -16,7 +16,6 @@ - diff --git a/FastTunnel.sln b/FastTunnel.sln index 17e40a8..11aee2e 100644 --- a/FastTunnel.sln +++ b/FastTunnel.sln @@ -11,8 +11,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastTunnel.Server", "FastTu EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{0E2A9DA2-26AE-4657-B4C5-3A913E2F5A3C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastTunel.Core.WebApi", "FastTunel.Core.WebApi\FastTunel.Core.WebApi.csproj", "{79B1CA3F-D9E9-45F2-8A50-72084B41A0E6}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -31,17 +29,12 @@ Global {DEF2E322-9075-4C3F-9967-7EAF0EE28CEB}.Debug|Any CPU.Build.0 = Debug|Any CPU {DEF2E322-9075-4C3F-9967-7EAF0EE28CEB}.Release|Any CPU.ActiveCfg = Release|Any CPU {DEF2E322-9075-4C3F-9967-7EAF0EE28CEB}.Release|Any CPU.Build.0 = Release|Any CPU - {79B1CA3F-D9E9-45F2-8A50-72084B41A0E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {79B1CA3F-D9E9-45F2-8A50-72084B41A0E6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {79B1CA3F-D9E9-45F2-8A50-72084B41A0E6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {79B1CA3F-D9E9-45F2-8A50-72084B41A0E6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {C8ADFEB1-59DB-4CE3-8D04-5B547107BCCB} = {0E2A9DA2-26AE-4657-B4C5-3A913E2F5A3C} - {79B1CA3F-D9E9-45F2-8A50-72084B41A0E6} = {0E2A9DA2-26AE-4657-B4C5-3A913E2F5A3C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3D9C6B44-6706-4EE8-9043-802BBE474A2E}