mirror of
https://github.com/FastTunnel/FastTunnel.git
synced 2025-02-08 02:39:29 +08:00
Merge branch 'master' of https://github.com/SpringHgui/FastTunnel
This commit is contained in:
commit
841d1e5c40
|
@ -13,8 +13,7 @@
|
|||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0-preview.4.21253.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0-preview.4.21253.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0-preview.4.21253.7" />
|
||||
<PackageReference Include="NLog" Version="4.7.10" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="4.13.0-readme-preview" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="5.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -25,8 +24,8 @@
|
|||
<None Update="appsettings.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="nlog.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<None Update="log4net.config">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -1,14 +1,5 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.IO;
|
||||
using FastTunnel.Core.Services;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using FastTunnel.Core.Client;
|
||||
using FastTunnel.Core.Config;
|
||||
using FastTunnel.Core.Handlers.Client;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NLog.Web;
|
||||
using FastTunnel.Core.Extensions;
|
||||
|
||||
namespace FastTunnel.Client
|
||||
|
@ -17,22 +8,7 @@ namespace FastTunnel.Client
|
|||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
|
||||
try
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
//NLog: catch setup errors
|
||||
logger.Error(exception, "Stopped program because of exception");
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
|
||||
NLog.LogManager.Shutdown();
|
||||
}
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
|
@ -47,7 +23,7 @@ namespace FastTunnel.Client
|
|||
{
|
||||
logging.ClearProviders();
|
||||
logging.SetMinimumLevel(LogLevel.Trace);
|
||||
})
|
||||
.UseNLog(); // NLog: Setup NLog for Dependency injection
|
||||
logging.AddLog4Net();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
72
FastTunnel.Client/log4net.config
Normal file
72
FastTunnel.Client/log4net.config
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<log4net>
|
||||
<!-- If you are looking here and want more output, first thing to do is change root/priority/@value to "INFO" or "ALL". -->
|
||||
<root>
|
||||
Value of priority may be ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF.
|
||||
<priority value="ALL" />
|
||||
<appender-ref ref="error-file" />
|
||||
<appender-ref ref="debug-file" />
|
||||
<appender-ref ref="info-console" />
|
||||
</root>
|
||||
|
||||
<!-- Example of turning on the output from a component or namespace. -->
|
||||
<logger name="Common">
|
||||
<appender-ref ref="debugger"/>
|
||||
<priority value="DEBUG" />
|
||||
</logger>
|
||||
|
||||
<appender name="debugger" type="log4net.Appender.DebugAppender">
|
||||
<!-- Sends log messages to Visual Studio if attached. -->
|
||||
<immediateFlush value="true" />
|
||||
<layout type="log4net.Layout.SimpleLayout" />
|
||||
</appender>
|
||||
|
||||
<appender name="info-console" type="log4net.Appender.ConsoleAppender">
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%date |%level%| %message%newline" />
|
||||
</layout>
|
||||
|
||||
<filter type="log4net.Filter.LevelRangeFilter">
|
||||
<param name="LevelMin" value="Info"/>
|
||||
<param name="LevelMax" value="Fatal"/>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="debug-file" type="log4net.Appender.RollingFileAppender">
|
||||
<param name="Encoding" value="utf-8" />
|
||||
<file value="Logs/debug" />
|
||||
<appendToFile value="true" />
|
||||
<!-- Immediate flush on error log, to avoid data loss with sudden termination. -->
|
||||
<immediateFlush value="true" />
|
||||
<staticLogFileName value="false" />
|
||||
<rollingStyle value="Date" />
|
||||
<datepattern value="-yyyy.MM.dd'.log'" />
|
||||
<!-- Prevents Orchard.exe from displaying locking debug messages. -->
|
||||
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%date %level% [%thread] %logger - %P{Tenant} - %message%newline" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="error-file" type="log4net.Appender.RollingFileAppender">
|
||||
<param name="Encoding" value="utf-8" />
|
||||
<file value="Logs/error" />
|
||||
<appendToFile value="true" />
|
||||
<!-- Immediate flush on error log, to avoid data loss with sudden termination. -->
|
||||
<immediateFlush value="true" />
|
||||
<staticLogFileName value="false" />
|
||||
<rollingStyle value="Date" />
|
||||
<datepattern value="-yyyy.MM.dd'.log'" />
|
||||
<!-- Prevents Orchard.exe from displaying locking debug messages. -->
|
||||
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
|
||||
<filter type="log4net.Filter.LevelRangeFilter">
|
||||
<!-- Only ERROR and FATAL log messages end up in this target, even if child loggers accept lower priority. -->
|
||||
<param name="LevelMin" value="Info"/>
|
||||
<param name="LevelMax" value="Fatal"/>
|
||||
</filter>
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%date [%thread] %logger - %P{Tenant} - %message [%P{Url}]%newline" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
</log4net>
|
|
@ -1,26 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
autoReload="true"
|
||||
internalLogLevel="Info">
|
||||
|
||||
<!-- enable asp.net core layout renderers -->
|
||||
<extensions>
|
||||
<add assembly="NLog.Web.AspNetCore"/>
|
||||
</extensions>
|
||||
<targets>
|
||||
<target xsi:type="File" name="file"
|
||||
layout="${longdate} ${logger} ${message}${exception:format=ToString}"
|
||||
fileName="${basedir}/Logs/${shortdate}.${level}.log" />
|
||||
|
||||
<target xsi:type="Console" name="console"
|
||||
layout="${date}|${level:uppercase=true}|${message} ${exception}" />
|
||||
<!--layout="${date}|${level:uppercase=true}|${message} ${exception}|${logger}|${all-event-properties}" />-->
|
||||
</targets>
|
||||
|
||||
<rules>
|
||||
<logger name="*" minlevel="Debug" writeTo="file,console" />
|
||||
<!--Skip non-critical Microsoft logs and so log only own logs-->
|
||||
<logger name="Microsoft.*" maxlevel="Info" final="true" />
|
||||
</rules>
|
||||
</nlog>
|
|
@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace FastTunnel.Core
|
||||
{
|
||||
public class AsyncSocketSwapV2
|
||||
public class AsyncSocketSwap
|
||||
{
|
||||
private Socket m_sockt1;
|
||||
private Socket m_sockt2;
|
||||
|
@ -18,7 +18,7 @@ namespace FastTunnel.Core
|
|||
SocketAsyncEventArgs e1;
|
||||
SocketAsyncEventArgs e2;
|
||||
|
||||
public AsyncSocketSwapV2(Socket sockt1, Socket sockt2)
|
||||
public AsyncSocketSwap(Socket sockt1, Socket sockt2)
|
||||
{
|
||||
m_sockt1 = sockt1;
|
||||
m_sockt2 = sockt2;
|
||||
|
@ -35,7 +35,7 @@ namespace FastTunnel.Core
|
|||
e2.SetBuffer(m_buffer, 512, 512);
|
||||
}
|
||||
|
||||
public AsyncSocketSwapV2 BeforeSwap(Action fun)
|
||||
public AsyncSocketSwap BeforeSwap(Action fun)
|
||||
{
|
||||
if (m_swaping)
|
||||
throw new Exception("BeforeSwap must be invoked before StartSwap!");
|
|
@ -24,7 +24,6 @@ namespace FastTunnel.Core.Client
|
|||
|
||||
protected ILogger<FastTunnelClient> _logger;
|
||||
|
||||
System.Timers.Timer timer_timeout;
|
||||
System.Timers.Timer timer_heart;
|
||||
|
||||
double heartInterval = 10 * 1000; // 10 秒心跳
|
||||
|
@ -54,65 +53,33 @@ namespace FastTunnel.Core.Client
|
|||
_logHandler = logHandler;
|
||||
_clientHeartHandler = clientHeartHandler;
|
||||
_configuration = configuration;
|
||||
initailTimer();
|
||||
}
|
||||
|
||||
private void initailTimer()
|
||||
{
|
||||
timer_heart = new System.Timers.Timer();
|
||||
timer_heart.AutoReset = false;
|
||||
timer_heart.Interval = heartInterval;
|
||||
timer_heart.Elapsed += HeartElapsed;
|
||||
|
||||
timer_timeout = new System.Timers.Timer();
|
||||
timer_timeout.AutoReset = false;
|
||||
timer_timeout.Interval = heartInterval + heartInterval / 2;
|
||||
timer_timeout.Elapsed += TimeoutElapsed;
|
||||
}
|
||||
|
||||
private void TimeoutElapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
timer_timeout.Enabled = false;
|
||||
|
||||
try
|
||||
{
|
||||
var timer = sender as System.Timers.Timer;
|
||||
var span = (DateTime.Now - lastHeart).TotalMilliseconds;
|
||||
if (span > timer.Interval)
|
||||
{
|
||||
_logger.LogDebug($"last heart recived {span / 1000}s ago");
|
||||
|
||||
// 重新登录
|
||||
reConnectAsync().Wait();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
timer_timeout.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task reConnectAsync()
|
||||
private void reConn()
|
||||
{
|
||||
Close();
|
||||
try
|
||||
while (true)
|
||||
{
|
||||
_logger.LogInformation("登录重试...");
|
||||
_client = lastLogin.Invoke();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("登录重试...");
|
||||
_client = lastLogin.Invoke();
|
||||
|
||||
Thread.Sleep(reTrySpan);
|
||||
await reConnectAsync();
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
Thread.Sleep(reTrySpan);
|
||||
}
|
||||
}
|
||||
|
||||
LogSuccess(_client);
|
||||
connSuccessAsync();
|
||||
}
|
||||
|
||||
private void HeartElapsed(object sender, ElapsedEventArgs e)
|
||||
|
@ -121,11 +88,12 @@ namespace FastTunnel.Core.Client
|
|||
|
||||
try
|
||||
{
|
||||
_client.Send(new Message<HeartMassage> { MessageType = MessageType.Heart, Content = null });
|
||||
_client.SendCmd(new Message<HeartMassage> { MessageType = MessageType.Heart, Content = null });
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
// 与服务端断开连接
|
||||
reConn();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -153,11 +121,11 @@ namespace FastTunnel.Core.Client
|
|||
_logger.LogError(ex.Message);
|
||||
|
||||
Thread.Sleep(reTrySpan);
|
||||
reConnectAsync().Wait();
|
||||
reConn();
|
||||
return;
|
||||
}
|
||||
|
||||
LogSuccess(_client);
|
||||
_ = connSuccessAsync();
|
||||
}
|
||||
|
||||
protected virtual Socket login()
|
||||
|
@ -201,60 +169,44 @@ namespace FastTunnel.Core.Client
|
|||
void Close()
|
||||
{
|
||||
timer_heart.Stop();
|
||||
timer_timeout.Stop();
|
||||
|
||||
try
|
||||
{
|
||||
if (_client != null && _client.Connected)
|
||||
{
|
||||
_client.Shutdown(SocketShutdown.Both);
|
||||
}
|
||||
_client.Shutdown(SocketShutdown.Both);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
_client.Close();
|
||||
}
|
||||
|
||||
private async Task connSuccessAsync()
|
||||
{
|
||||
_logger.LogDebug("通信已建立");
|
||||
|
||||
// 心跳开始
|
||||
timer_heart.Start();
|
||||
|
||||
await new PipeHepler(_client, ProceccLine).ProcessLinesAsync();
|
||||
}
|
||||
|
||||
private bool ProceccLine(Socket socket, byte[] line)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cmd = Encoding.UTF8.GetString(line);
|
||||
HandleServerRequest(cmd);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_client != null)
|
||||
{
|
||||
_client.Close();
|
||||
}
|
||||
|
||||
_logger.LogDebug("已退出登录\n");
|
||||
}
|
||||
}
|
||||
|
||||
private void LogSuccess(Socket socket)
|
||||
{
|
||||
_logger.LogDebug("通信已建立");
|
||||
|
||||
lastHeart = DateTime.Now;
|
||||
|
||||
// 心跳开始
|
||||
timer_heart.Start();
|
||||
timer_timeout.Start();
|
||||
|
||||
//th = new Thread(ReceiveServer);
|
||||
//th.Start(socket);
|
||||
|
||||
ReceiveServerV2(socket);
|
||||
}
|
||||
|
||||
private void ReceiveServerV2(object obj)
|
||||
{
|
||||
var client = obj as Socket;
|
||||
new PipeHepler(client, ProceccLine).ProcessLinesAsync();
|
||||
}
|
||||
|
||||
private bool ProceccLine(Socket socket, byte[] line)
|
||||
{
|
||||
var cmd = Encoding.UTF8.GetString(line);
|
||||
HandleServerRequest(cmd);
|
||||
return true;
|
||||
}
|
||||
|
||||
private IClientHandler HandleServerRequest(string words)
|
||||
private void HandleServerRequest(string words)
|
||||
{
|
||||
var Msg = JsonConvert.DeserializeObject<Message<JObject>>(words);
|
||||
IClientHandler handler;
|
||||
|
@ -277,7 +229,6 @@ namespace FastTunnel.Core.Client
|
|||
}
|
||||
|
||||
handler.HandlerMsg(this, Msg);
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,15 +18,19 @@ namespace FastTunnel.Core.Client
|
|||
/// 外部请求,需要定期清理
|
||||
/// TODO:是否可以实现LRU
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<string, NewRequest> RequestTemp = new ConcurrentDictionary<string, NewRequest>();
|
||||
public ConcurrentDictionary<string, NewRequest> RequestTemp { get; private set; }
|
||||
= new ConcurrentDictionary<string, NewRequest>();
|
||||
|
||||
public ConcurrentDictionary<string, WebInfo> WebList = new ConcurrentDictionary<string, WebInfo>();
|
||||
public ConcurrentDictionary<int, SSHInfo<SSHHandlerArg>> SSHList = new ConcurrentDictionary<int, SSHInfo<SSHHandlerArg>>();
|
||||
public ConcurrentDictionary<string, WebInfo> WebList { get; private set; }
|
||||
= new ConcurrentDictionary<string, WebInfo>();
|
||||
|
||||
public ConcurrentDictionary<int, SSHInfo<SSHHandlerArg>> SSHList { get; private set; }
|
||||
= new ConcurrentDictionary<int, SSHInfo<SSHHandlerArg>>();
|
||||
|
||||
public readonly IServerConfig ServerSettings;
|
||||
readonly ILogger _logger;
|
||||
ClientListenerV2 clientListener;
|
||||
HttpListenerV2 http_listener;
|
||||
readonly ClientListenerV2 clientListener;
|
||||
readonly HttpListenerV2 http_listener;
|
||||
|
||||
public FastTunnelServer(ILogger<FastTunnelServer> logger, IConfiguration configuration)
|
||||
{
|
||||
|
@ -35,8 +39,6 @@ namespace FastTunnel.Core.Client
|
|||
|
||||
clientListener = new ClientListenerV2(this, ServerSettings.BindAddr, ServerSettings.BindPort, _logger);
|
||||
http_listener = new HttpListenerV2(ServerSettings.BindAddr, ServerSettings.WebProxyPort, _logger);
|
||||
|
||||
clientListener.OnClientsChange += Client_listener_OnClientsChange;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
|
@ -67,19 +69,12 @@ namespace FastTunnel.Core.Client
|
|||
http_listener.Start(new HttpDispatcherV2(this, _logger, ServerSettings));
|
||||
}
|
||||
|
||||
private void Client_listener_OnClientsChange(System.Net.Sockets.Socket socket, int count, bool is_oofline)
|
||||
{
|
||||
if (is_oofline)
|
||||
_logger.LogDebug($"客户端 {socket.RemoteEndPoint} 已断开,当前连接数:{count}");
|
||||
else
|
||||
_logger.LogDebug($"客户端 {socket.RemoteEndPoint} 已连接,当前连接数:{count}");
|
||||
}
|
||||
|
||||
public void Stop(CancellationToken cancellationToken)
|
||||
public void Stop()
|
||||
{
|
||||
_logger.LogInformation("===== FastTunnel Server Stoping =====");
|
||||
|
||||
// TODO:释放资源和线程
|
||||
clientListener.Stop();
|
||||
http_listener.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace FastTunnel.Core.Config
|
||||
{
|
||||
public class DefaultServerConfigBuilder
|
||||
{
|
||||
readonly DefaultServerConfig _options = new DefaultServerConfig();
|
||||
|
||||
public DefaultServerConfigBuilder WithBindInfo(string host, int port)
|
||||
{
|
||||
_options.BindAddr = host;
|
||||
_options.BindPort = port;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultServerConfigBuilder WithWebDomain(string domain)
|
||||
{
|
||||
_options.WebDomain = domain;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultServerConfigBuilder WithSSHEnabled(bool enbaled)
|
||||
{
|
||||
_options.SSHEnabled = enbaled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultServerConfigBuilder WithHasNginxProxy(bool has)
|
||||
{
|
||||
_options.WebHasNginxProxy = has;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultServerConfigBuilder WithWebAllowAccessIps(string[] ips)
|
||||
{
|
||||
_options.WebAllowAccessIps = ips;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultServerConfigBuilder WithHTTPPort(int port)
|
||||
{
|
||||
_options.WebProxyPort = port;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultServerConfig Build()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_options.BindAddr))
|
||||
throw new ArgumentNullException("You must use WithBindInfo to set host");
|
||||
|
||||
if (_options.BindPort == 0)
|
||||
throw new ArgumentNullException("You must use WithBindInfo to set port");
|
||||
|
||||
if (string.IsNullOrEmpty(_options.WebDomain))
|
||||
throw new ArgumentNullException("You must use WithWebDomain to set domain");
|
||||
|
||||
return _options;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,11 @@
|
|||
using FastTunnel.Core.Config;
|
||||
using FastTunnel.Core.Models;
|
||||
using FastTunnel.Core.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastTunnel.Core.Client
|
||||
namespace FastTunnel.Core.Config
|
||||
{
|
||||
public interface IClientConfig
|
||||
{
|
|
@ -47,7 +47,7 @@ namespace FastTunnel.Core
|
|||
public void Send<T>(Message<T> msg)
|
||||
where T : TunnelMassage
|
||||
{
|
||||
Socket.Send(msg);
|
||||
Socket.SendCmd(msg);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
|
|
|
@ -28,11 +28,11 @@ namespace FastTunnel.Core.Dispatchers
|
|||
_fastTunnelServer = fastTunnelServer;
|
||||
}
|
||||
|
||||
static string pattern = @"[hH]ost:.+[\r\n]";
|
||||
static string pattern = @"[hH]ost:.+";
|
||||
|
||||
public void Dispatch(AsyncUserToken token, string words)
|
||||
{
|
||||
Console.WriteLine("=======Dispatch HTTP========");
|
||||
_logger.LogDebug("=======Dispatch HTTP========");
|
||||
|
||||
// 1.检查白名单
|
||||
try
|
||||
|
@ -54,13 +54,13 @@ namespace FastTunnel.Core.Dispatchers
|
|||
_logger.LogError(ex);
|
||||
}
|
||||
|
||||
Console.WriteLine("=======Dispatch Matches========");
|
||||
_logger.LogDebug("=======Dispatch Matches========");
|
||||
|
||||
string Host;
|
||||
MatchCollection collection = Regex.Matches(words, pattern);
|
||||
if (collection.Count == 0)
|
||||
{
|
||||
_logger.LogError($"Host异常:{words}");
|
||||
_logger.LogError($"【Host异常】:{words}");
|
||||
|
||||
// 返回错误页
|
||||
HandlerHostRequired(token.Socket);
|
||||
|
@ -74,7 +74,7 @@ namespace FastTunnel.Core.Dispatchers
|
|||
_logger.LogDebug(Host.Replace("\r", ""));
|
||||
var domain = Host.Split(":")[1].Trim();
|
||||
|
||||
Console.WriteLine($"=======Dispatch domain:{domain}========");
|
||||
_logger.LogDebug($"=======Dispatch domain:{domain}========");
|
||||
|
||||
// 判断是否为ip
|
||||
if (IsIpDomian(domain))
|
||||
|
@ -87,12 +87,12 @@ namespace FastTunnel.Core.Dispatchers
|
|||
WebInfo web;
|
||||
if (!_fastTunnelServer.WebList.TryGetValue(domain, out web))
|
||||
{
|
||||
Console.WriteLine($"=======Dispatch 未登录========");
|
||||
_logger.LogDebug($"=======Dispatch 未登录========");
|
||||
HandlerClientNotOnLine(token.Socket, domain);
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine($"=======Dispatch 已找到========");
|
||||
_logger.LogDebug($"=======Dispatch 已找到========");
|
||||
var msgid = Guid.NewGuid().ToString();
|
||||
_fastTunnelServer.RequestTemp.TryAdd(msgid, new NewRequest
|
||||
{
|
||||
|
@ -100,20 +100,20 @@ namespace FastTunnel.Core.Dispatchers
|
|||
Buffer = token.Recived
|
||||
});
|
||||
|
||||
Console.WriteLine($"=======Dispatch 发送msg========");
|
||||
_logger.LogDebug($"=======Dispatch 发送msg========");
|
||||
|
||||
try
|
||||
{
|
||||
_logger.LogDebug($"=======OK========");
|
||||
web.Socket.Send(new Message<NewCustomerMassage> { MessageType = MessageType.S_NewCustomer, Content = new NewCustomerMassage { MsgId = msgid, WebConfig = web.WebConfig } });
|
||||
web.Socket.SendCmd(new Message<NewCustomerMassage> { MessageType = MessageType.S_NewCustomer, Content = new NewCustomerMassage { MsgId = msgid, WebConfig = web.WebConfig } });
|
||||
|
||||
Console.WriteLine($"=======Dispatch OK========");
|
||||
_logger.LogDebug($"=======Dispatch OK========");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
HandlerClientNotOnLine(token.Socket, domain);
|
||||
|
||||
Console.WriteLine($"=======Dispatch 移除========");
|
||||
_logger.LogDebug($"=======Dispatch 移除========");
|
||||
|
||||
// 移除
|
||||
_fastTunnelServer.WebList.TryRemove(domain, out _);
|
||||
|
|
|
@ -8,8 +8,6 @@ namespace FastTunnel.Core.Dispatchers
|
|||
{
|
||||
public interface IListenerDispatcher
|
||||
{
|
||||
void Dispatch(Socket httpClient, Action<Socket> onOffLine);
|
||||
|
||||
void Dispatch(AsyncUserToken token, string words);
|
||||
|
||||
void Dispatch(Socket httpClient);
|
||||
|
|
|
@ -8,7 +8,7 @@ using System.Collections.Generic;
|
|||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
|
||||
namespace FastTunnel.Core.Handlers.Server
|
||||
namespace FastTunnel.Core.Dispatchers
|
||||
{
|
||||
public class SSHDispatcher : IListenerDispatcher
|
||||
{
|
||||
|
@ -26,18 +26,13 @@ namespace FastTunnel.Core.Handlers.Server
|
|||
public void Dispatch(Socket _socket)
|
||||
{
|
||||
var msgid = Guid.NewGuid().ToString();
|
||||
_client.Send(new Message<NewSSHRequest> { MessageType = MessageType.S_NewSSH, Content = new NewSSHRequest { MsgId = msgid, SSHConfig = _config } });
|
||||
_client.SendCmd(new Message<NewSSHRequest> { MessageType = MessageType.S_NewSSH, Content = new NewSSHRequest { MsgId = msgid, SSHConfig = _config } });
|
||||
_server.RequestTemp.TryAdd(msgid, new NewRequest
|
||||
{
|
||||
CustomerClient = _socket,
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispatch(Socket httpClient, Action<Socket> onOffLine)
|
||||
{
|
||||
Dispatch(httpClient);
|
||||
}
|
||||
|
||||
public void Dispatch(AsyncUserToken token, string words)
|
||||
{
|
||||
throw new NotImplementedException();
|
|
@ -22,10 +22,10 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="AsyncSocketSwap.cs" />
|
||||
<Compile Remove="Client\SuiDaoServer.cs.BASE.cs" />
|
||||
<Compile Remove="Client\SuiDaoServer.cs.LOCAL.cs" />
|
||||
<Compile Remove="Client\SuiDaoServer.cs.REMOTE.cs" />
|
||||
<Compile Remove="Dispatchers\ClientDispatcher.cs" />
|
||||
<Compile Remove="Dispatchers\HttpDispatcher.cs" />
|
||||
<Compile Remove="Listener.cs" />
|
||||
<Compile Remove="Listener\ClientListener.cs" />
|
||||
|
@ -44,8 +44,6 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0-preview.4.21253.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0-preview.4.21253.7" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="NLog" Version="4.7.10" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.7.2" />
|
||||
<PackageReference Include="System.IO.Pipelines" Version="5.0.1" />
|
||||
<PackageReference Include="System.Private.ServiceModel" Version="4.8.1" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -26,13 +26,13 @@ namespace FastTunnel.Core.Handlers.Client
|
|||
switch (msg.MsgType)
|
||||
{
|
||||
case LogMsgType.Info:
|
||||
_logger.LogInformation("From Server:" + msg.Msg);
|
||||
_logger.LogInformation($"[Server Info]:{msg.Msg}");
|
||||
break;
|
||||
case LogMsgType.Error:
|
||||
_logger.LogError("From Server:" + msg.Msg);
|
||||
_logger.LogError($"[Server Error]:{msg.Msg}");
|
||||
break;
|
||||
case LogMsgType.Debug:
|
||||
_logger.LogDebug("From Server:" + msg.Msg);
|
||||
_logger.LogDebug($"[Server Debug]:{msg.Msg}");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace FastTunnel.Core.Handlers.Server
|
|||
|
||||
public void HandlerMsg(FastTunnelServer server, Socket client, Message<JObject> msg)
|
||||
{
|
||||
client.Send(new Message<HeartMassage>() { MessageType = MessageType.Heart, Content = null });
|
||||
client.SendCmd(new Message<HeartMassage>() { MessageType = MessageType.Heart, Content = null });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using FastTunnel.Core.Client;
|
||||
using FastTunnel.Core.Dispatchers;
|
||||
using FastTunnel.Core.Extensions;
|
||||
using FastTunnel.Core.Filters;
|
||||
using FastTunnel.Core.Global;
|
||||
|
@ -56,7 +57,7 @@ namespace FastTunnel.Core.Handlers
|
|||
var result = item.Authentication(server, requet);
|
||||
if (!result)
|
||||
{
|
||||
client.Send(new Message<LogMassage>
|
||||
client.SendCmd(new Message<LogMassage>
|
||||
{
|
||||
MessageType = MessageType.Log,
|
||||
Content = new LogMassage(LogMsgType.Error, "认证失败")
|
||||
|
@ -140,7 +141,7 @@ namespace FastTunnel.Core.Handlers
|
|||
{
|
||||
_logger.LogError($"SSH proxy error: {item.RemotePort} => {item.LocalIp}:{item.LocalPort}");
|
||||
_logger.LogError(ex.Message);
|
||||
client.Send(new Message<LogMassage> { MessageType = MessageType.Log, Content = new LogMassage(LogMsgType.Info, ex.Message) });
|
||||
client.SendCmd(new Message<LogMassage> { MessageType = MessageType.Log, Content = new LogMassage(LogMsgType.Info, ex.Message) });
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -148,12 +149,12 @@ namespace FastTunnel.Core.Handlers
|
|||
|
||||
if (!hasTunnel)
|
||||
{
|
||||
client.Send(new Message<LogMassage> { MessageType = MessageType.Log, Content = new LogMassage(LogMsgType.Info, TunnelResource.NoTunnel) });
|
||||
client.SendCmd(new Message<LogMassage> { MessageType = MessageType.Log, Content = new LogMassage(LogMsgType.Info, TunnelResource.NoTunnel) });
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append($"{Environment.NewLine}====================================================");
|
||||
client.Send(new Message<LogMassage> { MessageType = MessageType.Log, Content = new LogMassage(LogMsgType.Info, sb.ToString()) });
|
||||
client.SendCmd(new Message<LogMassage> { MessageType = MessageType.Log, Content = new LogMassage(LogMsgType.Info, sb.ToString()) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,22 +29,22 @@ namespace FastTunnel.Core.Handlers.Server
|
|||
|
||||
if (!string.IsNullOrEmpty(SwapMsg.msgId) && server.RequestTemp.TryGetValue(SwapMsg.msgId, out request))
|
||||
{
|
||||
server.RequestTemp.TryRemove(SwapMsg.msgId, out _);
|
||||
|
||||
// Join
|
||||
// Swap
|
||||
new SocketSwap(request.CustomerClient, client)
|
||||
.BeforeSwap(() =>
|
||||
{
|
||||
if (request.Buffer != null) client.Send(request.Buffer);
|
||||
})
|
||||
.StartSwapAsync();
|
||||
|
||||
server.RequestTemp.TryRemove(SwapMsg.msgId, out _);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 未找到,关闭连接
|
||||
_logger.LogError($"未找到请求:{SwapMsg.msgId}");
|
||||
|
||||
client.Send(new Message<LogMassage> { MessageType = MessageType.Log, Content = new LogMassage(LogMsgType.Debug, $"未找到请求:{SwapMsg.msgId}") });
|
||||
client.SendCmd(new Message<LogMassage> { MessageType = MessageType.Log, Content = new LogMassage(LogMsgType.Debug, $"未找到请求:{SwapMsg.msgId}") });
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -53,10 +53,8 @@ namespace FastTunnel.Core.Handlers.Server
|
|||
catch (Exception)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.Close();
|
||||
}
|
||||
|
||||
client.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,133 +0,0 @@
|
|||
using FastTunnel.Core.Client;
|
||||
using FastTunnel.Core.Extensions;
|
||||
using FastTunnel.Core.Handlers;
|
||||
using FastTunnel.Core.Handlers.Server;
|
||||
using FastTunnel.Core.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
|
||||
namespace FastTunnel.Core.Listener
|
||||
{
|
||||
public class ClientConnection
|
||||
{
|
||||
public Socket Socket { get; }
|
||||
|
||||
readonly ILogger _logger;
|
||||
readonly LoginHandler _loginHandler;
|
||||
readonly HeartMessageHandler _heartHandler;
|
||||
readonly SwapMessageHandler _swapMsgHandler;
|
||||
readonly FastTunnelServer _fastTunnelServer;
|
||||
readonly DataReciver reader;
|
||||
|
||||
public ClientConnection(FastTunnelServer fastTunnelServer, Socket accept, ILogger logerr)
|
||||
{
|
||||
Socket = accept;
|
||||
_logger = logerr;
|
||||
_fastTunnelServer = fastTunnelServer;
|
||||
_loginHandler = new LoginHandler(_logger);
|
||||
_heartHandler = new HeartMessageHandler();
|
||||
_swapMsgHandler = new SwapMessageHandler(_logger);
|
||||
|
||||
|
||||
reader = new DataReciver(Socket);
|
||||
}
|
||||
|
||||
public void StartRecive()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
string temp = string.Empty;
|
||||
|
||||
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.ToString());
|
||||
_logger.LogError($"handle fail msg:{words}");
|
||||
|
||||
// throw;
|
||||
reader.Socket.Send(new Message<LogMassage>() { MessageType = MessageType.Log, Content = new LogMassage(LogMsgType.Error, ex.Message) });
|
||||
reader.ReciveOneAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private IClientMessageHandler handle(string words, Socket client)
|
||||
{
|
||||
Message<JObject> msg = JsonConvert.DeserializeObject<Message<JObject>>(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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ using System.Threading;
|
|||
|
||||
namespace FastTunnel.Core.Listener
|
||||
{
|
||||
public class ClientListenerV2 : IListener
|
||||
public class ClientListenerV2
|
||||
{
|
||||
ILogger _logger;
|
||||
|
||||
|
@ -24,9 +24,6 @@ namespace FastTunnel.Core.Listener
|
|||
|
||||
public int ListenPort { get; set; }
|
||||
|
||||
public event OnClientChangeLine OnClientsChange;
|
||||
|
||||
public IList<ClientConnection> ConnectedSockets = new List<ClientConnection>();
|
||||
FastTunnelServer _fastTunnelServer;
|
||||
Server.Server server;
|
||||
|
||||
|
@ -60,9 +57,18 @@ namespace FastTunnel.Core.Listener
|
|||
|
||||
private bool handle(AsyncUserToken token, string words)
|
||||
{
|
||||
//Console.WriteLine($"[Client请求] {words}");
|
||||
Message<JObject> msg;
|
||||
|
||||
Message<JObject> msg = JsonConvert.DeserializeObject<Message<JObject>>(words);
|
||||
try
|
||||
{
|
||||
msg = JsonConvert.DeserializeObject<Message<JObject>>(words);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogCritical(ex, $"【异常的指令】{words}");
|
||||
token.Socket.Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
IClientMessageHandler handler = null;
|
||||
switch (msg.MessageType)
|
||||
|
|
|
@ -15,17 +15,11 @@ namespace FastTunnel.Core.Listener
|
|||
{
|
||||
ILogger _logger;
|
||||
|
||||
public string ListenIp { get; set; }
|
||||
public string ListenIp { get; protected set; }
|
||||
|
||||
public int ListenPort { get; set; }
|
||||
public int ListenPort { get; protected set; }
|
||||
|
||||
int m_numConnectedSockets;
|
||||
|
||||
public event OnClientChangeLine OnClientsChange;
|
||||
|
||||
bool shutdown = false;
|
||||
IListenerDispatcher _requestDispatcher;
|
||||
Socket listenSocket;
|
||||
public IList<Socket> ConnectedSockets = new List<Socket>();
|
||||
|
||||
Server.Server server;
|
||||
|
@ -39,95 +33,6 @@ namespace FastTunnel.Core.Listener
|
|||
server = new Server.Server(1000, 512);
|
||||
}
|
||||
|
||||
private void OnOffLine(Socket socket)
|
||||
{
|
||||
if (ConnectedSockets.Remove(socket))
|
||||
OnClientsChange?.Invoke(socket, ConnectedSockets.Count, true);
|
||||
}
|
||||
|
||||
private void OnAccept(Socket socket)
|
||||
{
|
||||
ConnectedSockets.Add(socket);
|
||||
OnClientsChange?.Invoke(socket, ConnectedSockets.Count, false);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (shutdown)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
if (listenSocket.Connected)
|
||||
{
|
||||
listenSocket.Shutdown(SocketShutdown.Both);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
shutdown = true;
|
||||
listenSocket.Close();
|
||||
Interlocked.Decrement(ref m_numConnectedSockets);
|
||||
}
|
||||
}
|
||||
|
||||
private void StartAccept(SocketAsyncEventArgs acceptEventArg)
|
||||
{
|
||||
_logger.LogDebug($"【{ListenIp}:{ListenPort}】: StartAccept");
|
||||
if (acceptEventArg == null)
|
||||
{
|
||||
acceptEventArg = new SocketAsyncEventArgs();
|
||||
acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
|
||||
}
|
||||
else
|
||||
{
|
||||
// socket must be cleared since the context object is being reused
|
||||
acceptEventArg.AcceptSocket = null;
|
||||
}
|
||||
|
||||
bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg);
|
||||
if (!willRaiseEvent)
|
||||
{
|
||||
ProcessAccept(acceptEventArg);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessAccept(SocketAsyncEventArgs e)
|
||||
{
|
||||
if (e.SocketError == SocketError.Success)
|
||||
{
|
||||
var accept = e.AcceptSocket;
|
||||
OnAccept(accept);
|
||||
|
||||
Interlocked.Increment(ref m_numConnectedSockets);
|
||||
|
||||
_logger.LogInformation($"【{ListenIp}:{ListenPort}】Accepted. There are {{0}} clients connected to the port",
|
||||
m_numConnectedSockets);
|
||||
|
||||
// Accept the next connection request
|
||||
StartAccept(e);
|
||||
|
||||
// 将此客户端交由Dispatcher进行管理
|
||||
_requestDispatcher.Dispatch(accept, this.OnOffLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
|
||||
{
|
||||
ProcessAccept(e);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public void Start(IListenerDispatcher requestDispatcher, int backlog = 100)
|
||||
{
|
||||
_requestDispatcher = requestDispatcher;
|
||||
|
@ -142,9 +47,22 @@ namespace FastTunnel.Core.Listener
|
|||
|
||||
private bool handle(AsyncUserToken token, string words)
|
||||
{
|
||||
Console.WriteLine(words);
|
||||
_requestDispatcher.Dispatch(token, words);
|
||||
try
|
||||
{
|
||||
Console.WriteLine(words);
|
||||
_requestDispatcher.Dispatch(token, words);
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogCritical(ex, $"【处理HTTP请求异常】{words}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,5 @@ namespace FastTunnel.Core.Listener
|
|||
|
||||
void Close();
|
||||
|
||||
event OnClientChangeLine OnClientsChange;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@ namespace FastTunnel.Core.Listener
|
|||
|
||||
int m_numConnectedSockets;
|
||||
|
||||
public event OnClientChangeLine OnClientsChange;
|
||||
|
||||
bool shutdown = false;
|
||||
IListenerDispatcher _requestDispatcher;
|
||||
Socket listenSocket;
|
||||
|
@ -39,18 +37,6 @@ namespace FastTunnel.Core.Listener
|
|||
listenSocket.Bind(localEndPoint);
|
||||
}
|
||||
|
||||
private void OnOffLine(Socket socket)
|
||||
{
|
||||
if (ConnectedSockets.Remove(socket))
|
||||
OnClientsChange?.Invoke(socket, ConnectedSockets.Count, true);
|
||||
}
|
||||
|
||||
private void OnAccept(Socket socket)
|
||||
{
|
||||
ConnectedSockets.Add(socket);
|
||||
OnClientsChange?.Invoke(socket, ConnectedSockets.Count, false);
|
||||
}
|
||||
|
||||
public void Start(IListenerDispatcher requestDispatcher, int backlog = 100)
|
||||
{
|
||||
shutdown = false;
|
||||
|
@ -110,7 +96,6 @@ namespace FastTunnel.Core.Listener
|
|||
if (e.SocketError == SocketError.Success)
|
||||
{
|
||||
var accept = e.AcceptSocket;
|
||||
OnAccept(accept);
|
||||
|
||||
Interlocked.Increment(ref m_numConnectedSockets);
|
||||
|
||||
|
@ -121,7 +106,7 @@ namespace FastTunnel.Core.Listener
|
|||
StartAccept(e);
|
||||
|
||||
// 将此客户端交由Dispatcher进行管理
|
||||
_requestDispatcher.Dispatch(accept, this.OnOffLine);
|
||||
_requestDispatcher.Dispatch(accept);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
using NLog;
|
||||
using NLog.Config;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace FastTunnel.Core.Logger
|
||||
{
|
||||
public class NlogConfig
|
||||
{
|
||||
public static LoggingConfiguration getNewConfig()
|
||||
{
|
||||
var config = new LoggingConfiguration();
|
||||
|
||||
// Targets where to log to: File and Console
|
||||
var logfile = new NLog.Targets.FileTarget("file")
|
||||
{
|
||||
FileName = "${basedir}/Logs/${shortdate}.${level}.log",
|
||||
Layout = "${longdate} ${logger} ${message}${exception:format=ToString}"
|
||||
};
|
||||
|
||||
var logconsole = new NLog.Targets.ConsoleTarget("console")
|
||||
{
|
||||
Layout = "${date}|${level:uppercase=true}|${message} ${exception} ${all-event-properties}"
|
||||
};
|
||||
|
||||
// Rules for mapping loggers to targets
|
||||
config.AddRule(LogLevel.Debug, LogLevel.Fatal, logconsole);
|
||||
config.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile);
|
||||
|
||||
return config;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
using FastTunnel.Core.Client;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace FastTunnel.Core.Models
|
||||
{
|
||||
public class ClientContext
|
||||
{
|
||||
public FastTunnelServer CurrentServer { get; internal set; }
|
||||
public LogInMassage LogInMassage { get; internal set; }
|
||||
}
|
||||
}
|
|
@ -46,7 +46,7 @@ namespace FastTunnel.Core.Server
|
|||
// Tell the PipeWriter how much was read from the Socket.
|
||||
writer.Advance(bytesRead);
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ namespace FastTunnel.Core.Server
|
|||
|
||||
Func<AsyncUserToken, string, bool> m_handller;
|
||||
string m_sectionFlag;
|
||||
bool showLog;
|
||||
|
||||
// Create an uninitialized server instance.
|
||||
// To start the server listening for connection requests
|
||||
|
@ -43,7 +42,7 @@ namespace FastTunnel.Core.Server
|
|||
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
|
||||
// write posted to the socket simultaneously
|
||||
m_bufferManager = new BufferManager(receiveBufferSize * numConnections * opsToPreAlloc,
|
||||
receiveBufferSize);
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@ using Microsoft.Extensions.Logging;
|
|||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.IO;
|
||||
|
||||
namespace FastTunnel.Core.Services
|
||||
{
|
||||
|
@ -19,6 +22,9 @@ namespace FastTunnel.Core.Services
|
|||
{
|
||||
_logger = logger;
|
||||
_fastTunnelClient = fastTunnelClient;
|
||||
|
||||
AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
|
@ -34,5 +40,39 @@ namespace FastTunnel.Core.Services
|
|||
_logger.LogInformation("===== FastTunnel Client Stoping =====");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogError("【UnhandledException】" + e.ExceptionObject);
|
||||
_logger.LogError("【UnhandledException】" + JsonConvert.SerializeObject(e.ExceptionObject));
|
||||
var type = e.ExceptionObject.GetType();
|
||||
_logger.LogError("ExceptionObject GetType " + type);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void CurrentDomain_FirstChanceException(object sender, FirstChanceExceptionEventArgs e)
|
||||
{
|
||||
if (e.Exception is DirectoryNotFoundException)
|
||||
{
|
||||
// nlog第一次找不到文件的错误,跳过
|
||||
}
|
||||
else if (e.Exception is PlatformNotSupportedException)
|
||||
{
|
||||
// log4net
|
||||
}
|
||||
else if (e.Exception is IOException && e.Exception.Source == "System.Net.Security")
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError(e.Exception, "【FirstChanceException】");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,10 @@ namespace FastTunnel.Core.Services
|
|||
{
|
||||
// nlog第一次找不到文件的错误,跳过
|
||||
}
|
||||
else if (e.Exception is PlatformNotSupportedException)
|
||||
{
|
||||
// log4net
|
||||
}
|
||||
else if (e.Exception is IOException && e.Exception.Source == "System.Net.Security")
|
||||
{
|
||||
}
|
||||
|
@ -88,7 +92,7 @@ namespace FastTunnel.Core.Services
|
|||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
_server.Stop(cancellationToken);
|
||||
_server.Stop();
|
||||
}, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace FastTunnel.Core.Extensions
|
|||
{
|
||||
public static class SocketExtension
|
||||
{
|
||||
public static void Send<T>(this Socket socket, Message<T> message)
|
||||
public static void SendCmd<T>(this Socket socket, Message<T> message)
|
||||
where T : TunnelMassage
|
||||
{
|
||||
try
|
|
@ -6,21 +6,10 @@
|
|||
<RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="nlog.config" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="nlog.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0-preview.4.21253.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="6.0.0-preview.4.21253.7" />
|
||||
<PackageReference Include="NLog" Version="4.7.10" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="4.13.0-readme-preview" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="5.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -5,7 +5,6 @@ using Microsoft.Extensions.Configuration;
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NLog.Web;
|
||||
using System;
|
||||
|
||||
namespace FastTunnel.Server
|
||||
|
@ -14,22 +13,7 @@ namespace FastTunnel.Server
|
|||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
|
||||
try
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
//NLog: catch setup errors
|
||||
logger.Error(exception, "Stopped program because of exception");
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
|
||||
NLog.LogManager.Shutdown();
|
||||
}
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
|
@ -58,7 +42,7 @@ namespace FastTunnel.Server
|
|||
{
|
||||
logging.ClearProviders();
|
||||
logging.SetMinimumLevel(LogLevel.Trace);
|
||||
})
|
||||
.UseNLog(); // NLog: Setup NLog for Dependency injection
|
||||
logging.AddLog4Net();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
"BindPort": 1271,
|
||||
|
||||
// 自定义域名web穿透必须
|
||||
"WebDomain": "my.com",
|
||||
"WebDomain": "test.cc",
|
||||
|
||||
// 服务监听的端口号, 访问自定义域名站点时url为 http://{SubDomain}.{Domain}:{ProxyPort_HTTP}/
|
||||
// web穿透必须
|
||||
|
|
72
FastTunnel.Server/log4net.config
Normal file
72
FastTunnel.Server/log4net.config
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<log4net>
|
||||
<!-- If you are looking here and want more output, first thing to do is change root/priority/@value to "INFO" or "ALL". -->
|
||||
<root>
|
||||
Value of priority may be ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF.
|
||||
<priority value="ALL" />
|
||||
<appender-ref ref="error-file" />
|
||||
<appender-ref ref="debug-file" />
|
||||
<appender-ref ref="info-console" />
|
||||
</root>
|
||||
|
||||
<!-- Example of turning on the output from a component or namespace. -->
|
||||
<logger name="Common">
|
||||
<appender-ref ref="debugger"/>
|
||||
<priority value="DEBUG" />
|
||||
</logger>
|
||||
|
||||
<appender name="debugger" type="log4net.Appender.DebugAppender">
|
||||
<!-- Sends log messages to Visual Studio if attached. -->
|
||||
<immediateFlush value="true" />
|
||||
<layout type="log4net.Layout.SimpleLayout" />
|
||||
</appender>
|
||||
|
||||
<appender name="info-console" type="log4net.Appender.ConsoleAppender">
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%date |%level%| %message%newline" />
|
||||
</layout>
|
||||
|
||||
<filter type="log4net.Filter.LevelRangeFilter">
|
||||
<param name="LevelMin" value="Info"/>
|
||||
<param name="LevelMax" value="Fatal"/>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="debug-file" type="log4net.Appender.RollingFileAppender">
|
||||
<param name="Encoding" value="utf-8" />
|
||||
<file value="Logs/debug" />
|
||||
<appendToFile value="true" />
|
||||
<!-- Immediate flush on error log, to avoid data loss with sudden termination. -->
|
||||
<immediateFlush value="true" />
|
||||
<staticLogFileName value="false" />
|
||||
<rollingStyle value="Date" />
|
||||
<datepattern value="-yyyy.MM.dd'.log'" />
|
||||
<!-- Prevents Orchard.exe from displaying locking debug messages. -->
|
||||
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%date %level% [%thread] %logger - %P{Tenant} - %message%newline" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="error-file" type="log4net.Appender.RollingFileAppender">
|
||||
<param name="Encoding" value="utf-8" />
|
||||
<file value="Logs/error" />
|
||||
<appendToFile value="true" />
|
||||
<!-- Immediate flush on error log, to avoid data loss with sudden termination. -->
|
||||
<immediateFlush value="true" />
|
||||
<staticLogFileName value="false" />
|
||||
<rollingStyle value="Date" />
|
||||
<datepattern value="-yyyy.MM.dd'.log'" />
|
||||
<!-- Prevents Orchard.exe from displaying locking debug messages. -->
|
||||
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
|
||||
<filter type="log4net.Filter.LevelRangeFilter">
|
||||
<!-- Only ERROR and FATAL log messages end up in this target, even if child loggers accept lower priority. -->
|
||||
<param name="LevelMin" value="Info"/>
|
||||
<param name="LevelMax" value="Fatal"/>
|
||||
</filter>
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%date [%thread] %logger - %P{Tenant} - %message [%P{Url}]%newline" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
</log4net>
|
|
@ -1,26 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
autoReload="true"
|
||||
internalLogLevel="Info">
|
||||
|
||||
<!-- enable asp.net core layout renderers -->
|
||||
<extensions>
|
||||
<add assembly="NLog.Web.AspNetCore"/>
|
||||
</extensions>
|
||||
<targets>
|
||||
<target xsi:type="File" name="file"
|
||||
layout="${longdate} ${logger} ${message}${exception:format=ToString}"
|
||||
fileName="${basedir}/Logs/${shortdate}.${level}.log" />
|
||||
|
||||
<target xsi:type="Console" name="console"
|
||||
layout="${date}|${level:uppercase=true}|${message} ${exception}" />
|
||||
<!--layout="${date}|${level:uppercase=true}|${message} ${exception}|${logger}|${all-event-properties}" />-->
|
||||
</targets>
|
||||
|
||||
<rules>
|
||||
<logger name="*" minlevel="Debug" writeTo="file,console" />
|
||||
<!--Skip non-critical Microsoft logs and so log only own logs-->
|
||||
<logger name="Microsoft.*" maxlevel="Info" final="true" />
|
||||
</rules>
|
||||
</nlog>
|
Loading…
Reference in New Issue
Block a user