mirror of
https://github.com/FastTunnel/FastTunnel.git
synced 2025-02-08 02:39:29 +08:00
- 修复#31
- 精简代码
This commit is contained in:
parent
6269f4c218
commit
0996221687
|
@ -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) =>
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -9,6 +9,6 @@ namespace FastTunnel.Core.Client
|
|||
{
|
||||
public interface IFastTunnelClient
|
||||
{
|
||||
Task StartAsync(CancellationToken cancellationToken);
|
||||
void StartAsync(CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
44
FastTunnel.Core/Filters/FastTunnelExceptionFilter.cs
Normal file
44
FastTunnel.Core/Filters/FastTunnelExceptionFilter.cs
Normal 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, "[全局异常]");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace FastTunnel.Core.Filters
|
||||
{
|
||||
public interface IFastTunntlfilter
|
||||
{
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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($"客户端断开连接");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,6 @@ namespace FastTunnel.Core.Models
|
|||
|
||||
public ForwardConfig SSHConfig { get; set; }
|
||||
|
||||
public IListener Listener { get; set; }
|
||||
public PortProxyListener Listener { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
11
FastTunnel.Core/TunnelResource.Designer.cs
generated
11
FastTunnel.Core/TunnelResource.Designer.cs
generated
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>();
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
"WebHasNginxProxy": false,
|
||||
|
||||
// 可选,访问白名单,不在白名单的ip拒绝,为空时所有人有权限访问
|
||||
"WebAllowAccessIps": [],
|
||||
"WebAllowAccessIps": [ "192.168.0.101" ],
|
||||
|
||||
// 可选,是否开启SSH,禁用后不处理Forward类型端口转发.默认false。
|
||||
"EnableForward": true
|
||||
|
|
Loading…
Reference in New Issue
Block a user