- 修复#31

- 精简代码
This commit is contained in:
ioxygen 2021-08-06 22:45:03 +08:00
parent 6269f4c218
commit 0996221687
29 changed files with 216 additions and 274 deletions

View File

@ -29,8 +29,6 @@ namespace FastTunnel.Client
{
// -------------------FastTunnel START------------------
services.AddFastTunnelClient(hostContext.Configuration.GetSection("ClientSettings"));
services.AddSingleton<IFastTunnelClient, FastTunnelClient>();
// -------------------FastTunnel EDN--------------------
})
.ConfigureLogging((HostBuilderContext context, ILoggingBuilder logging) =>

View File

@ -50,14 +50,25 @@ namespace FastTunnel.Core.Client
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="customLoginMsg">自定义登录信息,可进行扩展业务</param>
public async Task StartAsync(CancellationToken cancellationToken)
public async void StartAsync(CancellationToken cancellationToken)
{
CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, this.cancellationTokenSource.Token);
_logger.LogInformation("===== FastTunnel Client Start =====");
await loginAsync(cancellationToken);
_logger.LogInformation($"通讯已建立");
await ReceiveServerAsync();
while (!cancellationToken.IsCancellationRequested)
{
try
{
await loginAsync(cancellationToken);
await ReceiveServerAsync(cancellationToken);
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken);
}
}
_logger.LogInformation("===== FastTunnel Client End =====");
}
protected virtual async Task loginAsync(CancellationToken cancellationToken)
@ -88,23 +99,23 @@ namespace FastTunnel.Core.Client
{
Webs = ClientConfig.Webs,
Forwards = ClientConfig.Forwards,
}.ToJson());
}.ToJson(), cancellationToken);
}
private async Task ReceiveServerAsync()
private async Task ReceiveServerAsync(CancellationToken cancellationToken)
{
byte[] buffer = new byte[128];
while (true)
while (!cancellationToken.IsCancellationRequested)
{
var res = await socket.ReceiveAsync(buffer, CancellationToken.None);
var res = await socket.ReceiveAsync(buffer, cancellationToken);
var type = buffer[0];
var content = Encoding.UTF8.GetString(buffer, 1, res.Count - 1);
HandleServerRequestAsync(type, content);
HandleServerRequestAsync(type, content, cancellationToken);
}
}
private async void HandleServerRequestAsync(byte cmd, string ctx)
private async void HandleServerRequestAsync(byte cmd, string ctx, CancellationToken cancellationToken)
{
try
{
@ -124,7 +135,7 @@ namespace FastTunnel.Core.Client
throw new Exception($"未处理的消息cmd={cmd}");
}
await handler.HandlerMsgAsync(this, ctx);
await handler.HandlerMsgAsync(this, ctx, cancellationToken);
}
catch (Exception ex)
{

View File

@ -9,6 +9,6 @@ namespace FastTunnel.Core.Client
{
public interface IFastTunnelClient
{
Task StartAsync(CancellationToken cancellationToken);
void StartAsync(CancellationToken cancellationToken);
}
}

View File

@ -13,8 +13,6 @@ namespace FastTunnel.Core.Config
public string[] WebAllowAccessIps { get; set; }
public bool WebHasNginxProxy { get; set; } = false;
public bool EnableForward { get; set; } = false;
}
}

View File

@ -12,16 +12,6 @@ namespace FastTunnel.Core.Config
string WebDomain { get; set; }
/// <summary>
/// 可选项
/// 当前服务器是否开启了80端口转发至ProxyPort_HTTP的配置
/// </summary>
bool WebHasNginxProxy { get; set; }
/// <summary>
/// 可选项
/// 访问web白名单
/// </summary>
string[] WebAllowAccessIps { get; set; }
#endregion

View File

@ -1,9 +1,7 @@
using FastTunnel.Core.Client;
using FastTunnel.Core.Config;
using FastTunnel.Core.Filters;
using FastTunnel.Core.Forwarder.MiddleWare;
using FastTunnel.Core.Forwarder;
using FastTunnel.Core.Handlers;
using FastTunnel.Core.Handlers.Client;
using FastTunnel.Core.MiddleWares;
using FastTunnel.Core.Services;
@ -12,31 +10,16 @@ using Microsoft.Extensions.DependencyInjection;
using Yarp.ReverseProxy.Forwarder;
using Yarp.Sample;
using Microsoft.AspNetCore.Builder;
using FastTunnel.Core.Filters;
using Microsoft.AspNetCore.Mvc.Filters;
using FastTunnel.Core.Models;
namespace FastTunnel.Core
{
public static class ServicesExtensions
{
/// <summary>
/// 添加服务端后台进程
/// </summary>
/// <param name="services"></param>
public static void AddFastTunnelServer(this IServiceCollection services, IConfigurationSection configurationSection)
{
services.AddReverseProxy().LoadFromMemory();
services.Configure<DefaultServerConfig>(configurationSection);
services.AddSingleton<IAuthenticationFilter, DefaultAuthenticationFilter>();
services.AddSingleton<FastTunnelServer, FastTunnelServer>();
services.AddSingleton<IForwarderHttpClientFactory, FastTunnelForwarderHttpClientFactory>();
services.AddSingleton<FastTunnelClientHandler, FastTunnelClientHandler>();
services.AddSingleton<FastTunnelSwapHandler, FastTunnelSwapHandler>();
}
/// <summary>
/// 添加客户端后台进程
/// 客户端依赖及HostedService
/// </summary>
/// <param name="services"></param>
public static void AddFastTunnelClient(this IServiceCollection services, IConfigurationSection configurationSection)
@ -44,17 +27,38 @@ namespace FastTunnel.Core
services.Configure<DefaultClientConfig>(configurationSection);
services.AddSingleton<IFastTunnelClient, FastTunnelClient>()
.AddSingleton<ClientHeartHandler>()
.AddSingleton<IExceptionFilter, FastTunnelExceptionFilter>()
.AddSingleton<LogHandler>()
.AddSingleton<SwapHandler>()
.AddSingleton<SwapHandler>();
services.AddHostedService<ServiceFastTunnelClient>();
}
/// <summary>
/// 添加服务端后台进程
/// </summary>
/// <param name="services"></param>
public static void AddFastTunnelServer(this IServiceCollection services, IConfigurationSection configurationSection)
{
services.AddReverseProxy().LoadFromMemory();
services.AddSingleton<IForwarderHttpClientFactory, FastTunnelForwarderHttpClientFactory>();
services.Configure<DefaultServerConfig>(configurationSection)
.AddSingleton<TunnelClient>()
.AddSingleton<IExceptionFilter, FastTunnelExceptionFilter>()
.AddSingleton<FastTunnelClientHandler, FastTunnelClientHandler>()
.AddSingleton<FastTunnelSwapHandler, FastTunnelSwapHandler>()
.AddSingleton<FastTunnelServer, FastTunnelServer>();
}
/// <summary>
/// 服务端中间件
/// </summary>
/// <param name="app"></param>
public static void UseFastTunnelServer(this IApplicationBuilder app)
{
app.UseWebSockets();
var swapHandler = app.ApplicationServices.GetRequiredService<FastTunnelSwapHandler>();
var clientHandler = app.ApplicationServices.GetRequiredService<FastTunnelClientHandler>();
app.Use(clientHandler.Handle);

View File

@ -12,13 +12,13 @@ namespace FastTunnel.Core.Extensions
{
public static class WebSocketExtensions
{
public static async Task SendCmdAsync(this WebSocket socket, MessageType type, string content)
public static async Task SendCmdAsync(this WebSocket socket, MessageType type, string content, CancellationToken cancellationToken)
{
var buffer = Encoding.UTF8.GetBytes((char)type + content + "\n");
if (type != MessageType.LogIn && buffer.Length > 128)
throw new ArgumentOutOfRangeException(nameof(content));
await socket.SendAsync(buffer, WebSocketMessageType.Binary, false, CancellationToken.None);
await socket.SendAsync(buffer, WebSocketMessageType.Binary, false, cancellationToken);
}
}
}

View File

@ -1,16 +0,0 @@
using FastTunnel.Core.Client;
using FastTunnel.Core.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace FastTunnel.Core.Filters
{
public class DefaultAuthenticationFilter : IAuthenticationFilter
{
public virtual bool Authentication(FastTunnelServer server, LogInMassage requet)
{
return true;
}
}
}

View File

@ -0,0 +1,44 @@
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using FastTunnel.Core;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using FastTunnel.Core.Client;
using Microsoft.Extensions.Logging;
using FastTunnel.Core.Extensions;
namespace FastTunnel.Core.Filters
{
public class FastTunnelExceptionFilter : IExceptionFilter
{
private readonly IWebHostEnvironment _hostingEnvironment;
private readonly ILogger<FastTunnelExceptionFilter> logger;
public FastTunnelExceptionFilter(
ILogger<FastTunnelExceptionFilter> logger,
IWebHostEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
}
public void OnException(ExceptionContext context)
{
if (!_hostingEnvironment.IsDevelopment())
{
return;
}
logger.LogError(context.Exception, "[全局异常]");
}
}
}

View File

@ -1,13 +0,0 @@
using FastTunnel.Core.Client;
using FastTunnel.Core.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace FastTunnel.Core.Filters
{
public interface IAuthenticationFilter : IFastTunntlfilter
{
bool Authentication(FastTunnelServer server, LogInMassage requet);
}
}

View File

@ -1,10 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace FastTunnel.Core.Filters
{
public interface IFastTunntlfilter
{
}
}

View File

@ -64,7 +64,7 @@ namespace FastTunnel.Core.Forwarder
_logger.LogInformation($"[发送swap指令]:{RequestId}");
// 发送指令给客户端,等待建立隧道
await web.Socket.SendCmdAsync(MessageType.SwapMsg, $"{RequestId}|{web.WebConfig.LocalIp}:{web.WebConfig.LocalPort}");
await web.Socket.SendCmdAsync(MessageType.SwapMsg, $"{RequestId}|{web.WebConfig.LocalIp}:{web.WebConfig.LocalPort}", cancellation);
// TODO:超时处理
TaskCompletionSource<Stream> task = new(cancellation);

View File

@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Yarp.ReverseProxy.Configuration;
@ -19,11 +20,15 @@ namespace FastTunnel.Core.MiddleWares
{
ILogger<FastTunnelClientHandler> logger;
FastTunnelServer fastTunnelServer;
TunnelClient tunnelClient;
public FastTunnelClientHandler(ILogger<FastTunnelClientHandler> logger, FastTunnelServer fastTunnelServer)
public FastTunnelClientHandler(
ILogger<FastTunnelClientHandler> logger,
FastTunnelServer fastTunnelServer, TunnelClient tunnelClient)
{
this.logger = logger;
this.fastTunnelServer = fastTunnelServer;
this.tunnelClient = tunnelClient;
}
public async Task Handle(HttpContext context, Func<Task> next)
@ -42,20 +47,20 @@ namespace FastTunnel.Core.MiddleWares
private async Task handleClient(HttpContext context, Func<Task> next)
{
using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
var client = new TunnelClient(logger, webSocket, fastTunnelServer);
this.logger.LogInformation($"{webSocket} 客户端连接成功");
tunnelClient.SetSocket(webSocket);
this.logger.LogInformation($"客户端连接成功");
try
{
await client.ReviceAsync();
await tunnelClient.ReviceAsync(CancellationToken.None);
}
catch (Exception ex)
{
logger.LogError(ex, "通信异常");
}
this.logger.LogInformation($"{client} 客户端断开连接");
this.logger.LogInformation($"客户端断开连接");
}
}
}

View File

@ -1,39 +0,0 @@
using FastTunnel.Core.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FastTunnel.Core.Global
{
public static class FastTunnelGlobal
{
static IList<IFastTunntlfilter> m_filters = new List<IFastTunntlfilter>();
static Dictionary<Type, object> m_customHandlers = new Dictionary<Type, object>();
public static void AddFilter(IFastTunntlfilter filter)
{
m_filters.Add(filter);
}
public static IEnumerable<IFastTunntlfilter> GetFilters(Type type)
{
return m_filters.Where(x => { return x.GetType().GetInterfaces().Contains(type); });
}
public static void AddCustomHandler<Tbase, Impl>(Impl _impl)
where Impl : class, Tbase
{
m_customHandlers.Add(typeof(Tbase), _impl);
}
public static Tbase GetCustomHandler<Tbase>()
where Tbase : class
{
object custom;
m_customHandlers.TryGetValue(typeof(Tbase), out custom);
return (Tbase)custom;
}
}
}

View File

@ -1,19 +0,0 @@
using FastTunnel.Core.Config;
using FastTunnel.Core.Client;
using FastTunnel.Core.Models;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace FastTunnel.Core.Handlers.Client
{
public class ClientHeartHandler : IClientHandler
{
public async Task HandlerMsgAsync(FastTunnelClient cleint, string msg)
{
cleint.lastHeart = DateTime.Now;
await Task.Yield();
}
}
}

View File

@ -3,6 +3,7 @@ using FastTunnel.Core.Dispatchers;
using FastTunnel.Core.Extensions;
using FastTunnel.Core.Models;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
@ -19,9 +20,11 @@ namespace FastTunnel.Core.Dispatchers
private FastTunnelServer _server;
private WebSocket _client;
private ForwardConfig _config;
ILogger logger;
public ForwardDispatcher(FastTunnelServer server, WebSocket client, ForwardConfig config)
public ForwardDispatcher(ILogger logger, FastTunnelServer server, WebSocket client, ForwardConfig config)
{
this.logger = logger;
_server = server;
_client = client;
_config = config;
@ -32,7 +35,7 @@ namespace FastTunnel.Core.Dispatchers
try
{
var msgid = Guid.NewGuid().ToString();
await _client.SendCmdAsync(MessageType.Forward, $"{msgid}|{_config.LocalIp }:{_config.LocalPort}");
await _client.SendCmdAsync(MessageType.Forward, $"{msgid}|{_config.LocalIp }:{_config.LocalPort}", CancellationToken.None);
var tcs = new TaskCompletionSource<Stream>();
_server.ResponseTasks.TryAdd(msgid, tcs);
@ -41,8 +44,9 @@ namespace FastTunnel.Core.Dispatchers
using var stream2 = new NetworkStream(_socket, true);
await Task.WhenAll(stream1.CopyToAsync(stream2), stream2.CopyToAsync(stream1));
}
catch (Exception)
catch (Exception ex)
{
logger.LogError(ex);
}
}
}

View File

@ -5,11 +5,12 @@ using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace FastTunnel.Core.Handlers.Client
{
public interface IClientHandler
{
Task HandlerMsgAsync(FastTunnelClient cleint, string msg);
Task HandlerMsgAsync(FastTunnelClient cleint, string msg, CancellationToken cancellationToken);
}
}

View File

@ -5,6 +5,7 @@ using System;
using FastTunnel.Core.Extensions;
using FastTunnel.Core.Client;
using System.Threading.Tasks;
using System.Threading;
namespace FastTunnel.Core.Handlers.Client
{
@ -17,7 +18,7 @@ namespace FastTunnel.Core.Handlers.Client
_logger = logger;
}
public async Task HandlerMsgAsync(FastTunnelClient cleint, string msg)
public async Task HandlerMsgAsync(FastTunnelClient cleint, string msg, CancellationToken cancellationToken)
{
_logger.LogInformation(msg.Replace("\n", string.Empty));
await Task.CompletedTask;

View File

@ -28,24 +28,34 @@ namespace FastTunnel.Core.Handlers.Client
_logger = logger;
}
public async Task HandlerMsgAsync(FastTunnelClient cleint, string msg)
public async Task HandlerMsgAsync(FastTunnelClient cleint, string msg, CancellationToken cancellationToken)
{
var msgs = msg.Split('|');
var requestId = msgs[0];
var address = msgs[1];
_logger.LogDebug($"开始转发 {msgs[0]}");
_logger.LogDebug($"Swap start {requestId}");
await Task.Yield();
using Stream serverConn = await server(msgs[0], cleint);
using Stream localConn = await local(msgs[0], msgs[1]);
try
{
using Stream serverStream = await createRemote(requestId, cleint, cancellationToken);
using Stream localStream = await createLocal(requestId, address, cancellationToken);
var taskX = serverConn.CopyToAsync(localConn, CancellationToken.None);
var taskY = localConn.CopyToAsync(serverConn, CancellationToken.None);
var taskX = serverStream.CopyToAsync(localStream, cancellationToken);
var taskY = localStream.CopyToAsync(serverStream, cancellationToken);
await Task.WhenAny(taskX, taskY);
await Task.WhenAny(taskX, taskY);
_logger.LogDebug($"Swap success {requestId}");
}
catch (Exception ex)
{
_logger.LogError(ex, $"Swap error {requestId}");
}
}
private async Task<Stream> local(string requestId, string localhost)
private async Task<Stream> createLocal(string requestId, string localhost, CancellationToken cancellationToken)
{
_logger.LogDebug($"连接本地成功 {requestId}");
var localConnecter = new DnsSocket(localhost.Split(":")[0], int.Parse(localhost.Split(":")[1]));
@ -54,7 +64,7 @@ namespace FastTunnel.Core.Handlers.Client
return new NetworkStream(localConnecter.Socket, ownsSocket: true);
}
private async Task<Stream> server(string requestId, FastTunnelClient cleint)
private async Task<Stream> createRemote(string requestId, FastTunnelClient cleint, CancellationToken cancellationToken)
{
var connecter = new DnsSocket(cleint.Server.ServerAddr, cleint.Server.ServerPort);
await connecter.ConnectAsync();
@ -64,7 +74,7 @@ namespace FastTunnel.Core.Handlers.Client
var reverse = $"PROXY /{requestId} HTTP/1.1\r\nHost: {cleint.Server.ServerAddr}:{cleint.Server.ServerPort}\r\n\r\n";
var requestMsg = Encoding.ASCII.GetBytes(reverse);
await serverConn.WriteAsync(requestMsg, CancellationToken.None);
await serverConn.WriteAsync(requestMsg, cancellationToken);
return serverConn;
}
}

View File

@ -1,8 +1,6 @@
using FastTunnel.Core.Client;
using FastTunnel.Core.Dispatchers;
using FastTunnel.Core.Extensions;
using FastTunnel.Core.Filters;
using FastTunnel.Core.Global;
using FastTunnel.Core.Listener;
using FastTunnel.Core.Models;
using Microsoft.Extensions.Logging;
@ -12,6 +10,7 @@ using System.Linq;
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Yarp.ReverseProxy.Configuration;
using Yarp.Sample;
@ -36,7 +35,7 @@ namespace FastTunnel.Core.Handlers
{
bool hasTunnel = false;
await client.SendCmdAsync(MessageType.Log, $"穿透协议 | 映射关系(公网=>内网){Environment.NewLine}");
await client.SendCmdAsync(MessageType.Log, $"穿透协议 | 映射关系(公网=>内网){Environment.NewLine}", CancellationToken.None);
if (requet.Webs != null && requet.Webs.Count() > 0)
{
hasTunnel = true;
@ -49,7 +48,7 @@ namespace FastTunnel.Core.Handlers
server.WebList.AddOrUpdate(hostName, info, (key, oldInfo) => { return info; });
(proxyConfig as InMemoryConfigProvider).AddWeb(hostName);
await client.SendCmdAsync(MessageType.Log, $" HTTP | http://{hostName}{(server.serverOption.CurrentValue.WebHasNginxProxy ? string.Empty : ":" + server.serverOption.CurrentValue.WebProxyPort)} => {item.LocalIp}:{item.LocalPort}");
await client.SendCmdAsync(MessageType.Log, $" HTTP | http://{hostName}:{server.serverOption.CurrentValue.WebProxyPort} => {item.LocalIp}:{item.LocalPort}", CancellationToken.None);
if (item.WWW != null)
{
@ -61,7 +60,7 @@ namespace FastTunnel.Core.Handlers
server.WebList.AddOrUpdate(www, info, (key, oldInfo) => { return info; });
(proxyConfig as InMemoryConfigProvider).AddWeb(hostName);
await client.SendCmdAsync(MessageType.Log, $" HTTP | http://{www}{(server.serverOption.CurrentValue.WebHasNginxProxy ? string.Empty : ":" + server.serverOption.CurrentValue.WebProxyPort)} => {item.LocalIp}:{item.LocalPort}");
await client.SendCmdAsync(MessageType.Log, $" HTTP | http://{www}:{server.serverOption.CurrentValue.WebProxyPort} => {item.LocalIp}:{item.LocalPort}", CancellationToken.None);
}
}
@ -70,48 +69,55 @@ namespace FastTunnel.Core.Handlers
if (requet.Forwards != null && requet.Forwards.Count() > 0)
{
hasTunnel = true;
foreach (var item in requet.Forwards)
if (server.serverOption.CurrentValue.EnableForward)
{
try
hasTunnel = true;
foreach (var item in requet.Forwards)
{
if (item.RemotePort.Equals(server.serverOption.CurrentValue.WebProxyPort))
try
{
_logger.LogError($"RemotePort can not be same with ProxyPort_HTTP: {item.RemotePort}");
if (item.RemotePort.Equals(server.serverOption.CurrentValue.WebProxyPort))
{
_logger.LogError($"RemotePort can not be same with ProxyPort_HTTP: {item.RemotePort}");
continue;
}
ForwardInfo<ForwardHandlerArg> old;
if (server.ForwardList.TryGetValue(item.RemotePort, out old))
{
_logger.LogDebug($"Remove Listener {old.Listener.ListenIp}:{old.Listener.ListenPort}");
old.Listener.Stop();
server.ForwardList.TryRemove(item.RemotePort, out ForwardInfo<ForwardHandlerArg> _);
}
var ls = new PortProxyListener("0.0.0.0", item.RemotePort, _logger);
ls.Start(new ForwardDispatcher(_logger, server, client, item));
// listen success
server.ForwardList.TryAdd(item.RemotePort, new ForwardInfo<ForwardHandlerArg> { Listener = ls, Socket = client, SSHConfig = item });
_logger.LogDebug($"SSH proxy success: {item.RemotePort} => {item.LocalIp}:{item.LocalPort}");
await client.SendCmdAsync(MessageType.Log, $" TCP | {server.serverOption.CurrentValue.WebDomain}:{item.RemotePort} => {item.LocalIp}:{item.LocalPort}", CancellationToken.None);
}
catch (Exception ex)
{
_logger.LogError($"SSH proxy error: {item.RemotePort} => {item.LocalIp}:{item.LocalPort}");
_logger.LogError(ex.Message);
await client.SendCmdAsync(MessageType.Log, ex.Message, CancellationToken.None);
continue;
}
ForwardInfo<ForwardHandlerArg> old;
if (server.ForwardList.TryGetValue(item.RemotePort, out old))
{
_logger.LogDebug($"Remove Listener {old.Listener.ListenIp}:{old.Listener.ListenPort}");
old.Listener.Stop();
server.ForwardList.TryRemove(item.RemotePort, out ForwardInfo<ForwardHandlerArg> _);
}
var ls = new PortProxyListener("0.0.0.0", item.RemotePort, _logger);
ls.Start(new ForwardDispatcher(server, client, item));
// listen success
server.ForwardList.TryAdd(item.RemotePort, new ForwardInfo<ForwardHandlerArg> { Listener = ls, Socket = client, SSHConfig = item });
_logger.LogDebug($"SSH proxy success: {item.RemotePort} => {item.LocalIp}:{item.LocalPort}");
await client.SendCmdAsync(MessageType.Log, $" TCP | {server.serverOption.CurrentValue.WebDomain}:{item.RemotePort} => {item.LocalIp}:{item.LocalPort}");
}
catch (Exception ex)
{
_logger.LogError($"SSH proxy error: {item.RemotePort} => {item.LocalIp}:{item.LocalPort}");
_logger.LogError(ex.Message);
await client.SendCmdAsync(MessageType.Log, ex.Message);
continue;
}
}
else
{
await client.SendCmdAsync(MessageType.Log, TunnelResource.ForwardDisabled, CancellationToken.None);
}
}
if (!hasTunnel)
await client.SendCmdAsync(MessageType.Log, TunnelResource.NoTunnel);
await client.SendCmdAsync(MessageType.Log, TunnelResource.NoTunnel, CancellationToken.None);
}
public async Task<bool> HandlerMsg<T>(FastTunnelServer server, WebSocket client, T msg)

View File

@ -1,24 +0,0 @@
using FastTunnel.Core.Dispatchers;
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
namespace FastTunnel.Core.Listener
{
public delegate void OnClientChangeLine(Socket socket, int count, bool is_offline);
public interface IListener
{
string ListenIp { get; }
int ListenPort { get; }
void Start(int backlog = 100);
void Stop();
void Close();
}
}

View File

@ -12,7 +12,7 @@ using System.Threading.Tasks;
namespace FastTunnel.Core.Listener
{
public class PortProxyListener : IListener
public class PortProxyListener
{
ILogger _logerr;
@ -105,9 +105,6 @@ namespace FastTunnel.Core.Listener
_logerr.LogInformation($"【{ListenIp}:{ListenPort}】Accepted. There are {{0}} clients connected to the port",
m_numConnectedSockets);
// Accept the next connection request
StartAccept(e);
try
{
// 将此客户端交由Dispatcher进行管理
@ -117,6 +114,9 @@ namespace FastTunnel.Core.Listener
{
_logerr.LogError(ex, "RequestDispatcher Fail");
}
// Accept the next connection request
StartAccept(e);
}
else
{
@ -124,19 +124,9 @@ namespace FastTunnel.Core.Listener
}
}
private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
ProcessAccept(e);
}
public void Close()
{
}
public void Start(int backlog = 100)
{
throw new NotImplementedException();
}
}
}

View File

@ -13,6 +13,6 @@ namespace FastTunnel.Core.Models
public ForwardConfig SSHConfig { get; set; }
public IListener Listener { get; set; }
public PortProxyListener Listener { get; set; }
}
}

View File

@ -23,22 +23,26 @@ namespace FastTunnel.Core.Models
ILogger logger;
WebSocket webSocket;
public TunnelClient(ILogger logger, WebSocket webSocket, FastTunnelServer fastTunnelServer)
public TunnelClient(ILogger<TunnelClient> logger, FastTunnelServer fastTunnelServer)
{
this.webSocket = webSocket;
this.logger = logger;
this.fastTunnelServer = fastTunnelServer;
this._loginHandler = new LoginHandler(logger, fastTunnelServer.proxyConfig);
}
public async Task ReviceAsync()
public void SetSocket(WebSocket webSocket)
{
var buffer = new byte[512];
this.webSocket = webSocket;
}
public async Task ReviceAsync(CancellationToken cancellationToken)
{
var buffer = new byte[128];
var tunnelProtocol = new TunnelProtocol();
while (true)
{
var res = await webSocket.ReceiveAsync(buffer, CancellationToken.None);
var res = await webSocket.ReceiveAsync(buffer, cancellationToken);
var cmds = tunnelProtocol.HandleBuffer(buffer, 0, res.Count);
if (cmds == null) continue;

View File

@ -21,25 +21,16 @@ namespace FastTunnel.Core.Services
{
_logger = logger;
_fastTunnelClient = fastTunnelClient;
//AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
#if DEBUG
AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
#endif
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
try
{
await _fastTunnelClient.StartAsync(cancellationToken);
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken);
}
}
_fastTunnelClient.StartAsync(cancellationToken);
await Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)

View File

@ -19,7 +19,7 @@ namespace FastTunnel.Core {
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class TunnelResource {
@ -60,6 +60,15 @@ namespace FastTunnel.Core {
}
}
/// <summary>
/// 查找类似 服务端禁用了Forward 的本地化字符串。
/// </summary>
internal static string ForwardDisabled {
get {
return ResourceManager.GetString("ForwardDisabled", resourceCulture);
}
}
/// <summary>
/// 查找类似 您尚未创建任何隧道请登录https://suidao.io 创建后重试。 的本地化字符串。
/// </summary>

View File

@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ForwardDisabled" xml:space="preserve">
<value>服务端禁用了Forward</value>
</data>
<data name="NoTunnel" xml:space="preserve">
<value>您尚未创建任何隧道请登录https://suidao.io 创建后重试。</value>
</data>

View File

@ -28,12 +28,6 @@ namespace FastTunnel.Server
.AddJsonFile($"config/appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
});
})
//.ConfigureServices((hostContext, services) =>
//{
// // -------------------FastTunnel START------------------
// services.AddFastTunnelServer(hostContext.Configuration.GetSection("ServerSettings"));
// // -------------------FastTunnel END--------------------
//})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();

View File

@ -17,7 +17,7 @@
"WebHasNginxProxy": false,
// 访ip访
"WebAllowAccessIps": [],
"WebAllowAccessIps": [ "192.168.0.101" ],
// SSHForward.false
"EnableForward": true