This commit is contained in:
SpringHgui 2021-08-08 20:36:42 +08:00
parent 6e0d00bed5
commit 1e127f5e6e
15 changed files with 84 additions and 65 deletions

View File

@ -1,12 +1,12 @@
{ {
"Logging": { //"Logging": {
"LogLevel": { // "LogLevel": {
// Trace Debug Information Warning Error // // Trace Debug Information Warning Error
"Default": "Information", // "Default": "Information",
"Microsoft": "Warning", // "Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information" // "Microsoft.Hosting.Lifetime": "Information"
} // }
}, //},
"EnableFileLog": false, "EnableFileLog": false,
"ClientSettings": { "ClientSettings": {
"Server": { "Server": {

View File

@ -34,13 +34,14 @@ namespace FastTunnel.Core.Client
public FastTunnelClient( public FastTunnelClient(
ILogger<FastTunnelClient> logger, ILogger<FastTunnelClient> logger,
SwapHandler newCustomerHandler, SwapHandler newCustomerHandler,
LogHandler logHandler, LogHandler logHandler,
IOptionsMonitor<DefaultClientConfig> configuration) IOptionsMonitor<DefaultClientConfig> configuration)
{ {
_logger = logger; _logger = logger;
_newCustomerHandler = newCustomerHandler; _newCustomerHandler = newCustomerHandler;
_logHandler = logHandler; _logHandler = logHandler;
ClientConfig = configuration.CurrentValue; ClientConfig = configuration.CurrentValue;
Server = ClientConfig.Server;
} }
/// <summary> /// <summary>
@ -69,41 +70,46 @@ namespace FastTunnel.Core.Client
_logger.LogInformation("===== FastTunnel Client End ====="); _logger.LogInformation("===== FastTunnel Client End =====");
} }
protected virtual async Task loginAsync(CancellationToken cancellationToken) private async Task loginAsync(CancellationToken cancellationToken)
{ {
Server = ClientConfig.Server;
_logger.LogInformation($"正在连接服务端 {Server.ServerAddr}:{Server.ServerPort}");
try try
{ {
var logMsg = GetLoginMsg();
// 连接到的目标IP // 连接到的目标IP
socket = new ClientWebSocket(); socket = new ClientWebSocket();
socket.Options.RemoteCertificateValidationCallback = delegate { return true; }; socket.Options.RemoteCertificateValidationCallback = delegate { return true; };
socket.Options.SetRequestHeader(FastTunnelConst.FASTTUNNEL_FLAG, "2.0.0"); socket.Options.SetRequestHeader(FastTunnelConst.FASTTUNNEL_FLAG, "2.0.0");
socket.Options.SetRequestHeader(FastTunnelConst.FASTTUNNEL_TYPE, FastTunnelConst.TYPE_CLIENT); socket.Options.SetRequestHeader(FastTunnelConst.FASTTUNNEL_TYPE, FastTunnelConst.TYPE_CLIENT);
_logger.LogInformation($"正在连接服务端 {Server.ServerAddr}:{Server.ServerPort}");
await socket.ConnectAsync( await socket.ConnectAsync(
new Uri($"ws://{ClientConfig.Server.ServerAddr}:{ClientConfig.Server.ServerPort}"), cancellationToken); new Uri($"ws://{Server.ServerAddr}:{Server.ServerPort}"), cancellationToken);
_logger.LogDebug("连接服务端成功"); _logger.LogDebug("连接服务端成功");
// 登录
await socket.SendCmdAsync(MessageType.LogIn, logMsg, cancellationToken);
} }
catch (Exception) catch (Exception)
{ {
throw; throw;
} }
}
// 登录 public virtual string GetLoginMsg()
await socket.SendCmdAsync(MessageType.LogIn, new LogInMassage {
Server = ClientConfig.Server;
return new LogInMassage
{ {
Webs = ClientConfig.Webs, Webs = ClientConfig.Webs,
Forwards = ClientConfig.Forwards, Forwards = ClientConfig.Forwards,
}.ToJson(), cancellationToken); }.ToJson();
} }
private async Task ReceiveServerAsync(CancellationToken cancellationToken) private async Task ReceiveServerAsync(CancellationToken cancellationToken)
{ {
byte[] buffer = new byte[128]; byte[] buffer = new byte[FastTunnelConst.CMD_MAX_LENGTH];
while (!cancellationToken.IsCancellationRequested) while (!cancellationToken.IsCancellationRequested)
{ {
var res = await socket.ReceiveAsync(buffer, cancellationToken); var res = await socket.ReceiveAsync(buffer, cancellationToken);
@ -115,14 +121,14 @@ namespace FastTunnel.Core.Client
private async void HandleServerRequestAsync(byte cmd, string ctx, CancellationToken cancellationToken) private async void HandleServerRequestAsync(byte cmd, string ctx, CancellationToken cancellationToken)
{ {
await Task.Yield();
try try
{ {
IClientHandler handler; IClientHandler handler;
switch ((MessageType)cmd) switch ((MessageType)cmd)
{ {
case MessageType.SwapMsg: case MessageType.SwapMsg:
handler = _newCustomerHandler;
break;
case MessageType.Forward: case MessageType.Forward:
handler = _newCustomerHandler; handler = _newCustomerHandler;
break; break;
@ -144,10 +150,13 @@ namespace FastTunnel.Core.Client
public void Stop(CancellationToken cancellationToken) public void Stop(CancellationToken cancellationToken)
{ {
_logger.LogInformation("===== FastTunnel Client Stoping ====="); _logger.LogInformation("===== FastTunnel Client Stoping =====");
if (socket == null)
return;
if (socket.State == WebSocketState.Connecting) if (socket.State == WebSocketState.Connecting)
return; return;
socket.CloseAsync(WebSocketCloseStatus.Empty, "客户端主动关闭", cancellationToken); socket.CloseAsync(WebSocketCloseStatus.Empty, string.Empty, cancellationToken);
} }
} }
} }

View File

@ -9,8 +9,6 @@ namespace FastTunnel.Core.Config
{ {
public string WebDomain { get; set; } public string WebDomain { get; set; }
public int WebProxyPort { get; set; } = 1270;
public string[] WebAllowAccessIps { get; set; } public string[] WebAllowAccessIps { get; set; }
public bool EnableForward { get; set; } = false; public bool EnableForward { get; set; } = false;

View File

@ -6,16 +6,10 @@ namespace FastTunnel.Core.Config
{ {
public interface IServerConfig public interface IServerConfig
{ {
#region Web相关配置
int WebProxyPort { get; set; }
string WebDomain { get; set; } string WebDomain { get; set; }
string[] WebAllowAccessIps { get; set; } string[] WebAllowAccessIps { get; set; }
#endregion
bool EnableForward { get; set; } bool EnableForward { get; set; }
} }
} }

View File

@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Builder;
using FastTunnel.Core.Filters; using FastTunnel.Core.Filters;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using FastTunnel.Core.Models; using FastTunnel.Core.Models;
using FastTunnel.Core.Handlers.Server;
namespace FastTunnel.Core namespace FastTunnel.Core
{ {
@ -25,10 +26,16 @@ namespace FastTunnel.Core
public static void AddFastTunnelClient(this IServiceCollection services, IConfigurationSection configurationSection) public static void AddFastTunnelClient(this IServiceCollection services, IConfigurationSection configurationSection)
{ {
services.Configure<DefaultClientConfig>(configurationSection); services.Configure<DefaultClientConfig>(configurationSection);
services.AddFastTunnelClient();
}
public static void AddFastTunnelClient(this IServiceCollection services)
{
services.AddTransient<IFastTunnelClient, FastTunnelClient>() services.AddTransient<IFastTunnelClient, FastTunnelClient>()
.AddSingleton<IExceptionFilter, FastTunnelExceptionFilter>() .AddSingleton<IExceptionFilter, FastTunnelExceptionFilter>()
.AddSingleton<ILoginHandler, LoginHandler>()
.AddSingleton<LogHandler>() .AddSingleton<LogHandler>()
.AddTransient<TunnelClient>()
.AddSingleton<SwapHandler>(); .AddSingleton<SwapHandler>();
services.AddHostedService<ServiceFastTunnelClient>(); services.AddHostedService<ServiceFastTunnelClient>();
@ -45,9 +52,10 @@ namespace FastTunnel.Core
services.Configure<DefaultServerConfig>(configurationSection) services.Configure<DefaultServerConfig>(configurationSection)
.AddSingleton<IExceptionFilter, FastTunnelExceptionFilter>() .AddSingleton<IExceptionFilter, FastTunnelExceptionFilter>()
.AddSingleton<FastTunnelClientHandler, FastTunnelClientHandler>() .AddTransient<TunnelClient>()
.AddSingleton<FastTunnelSwapHandler, FastTunnelSwapHandler>() .AddSingleton<FastTunnelClientHandler>()
.AddSingleton<FastTunnelServer, FastTunnelServer>(); .AddSingleton<FastTunnelSwapHandler>()
.AddSingleton<FastTunnelServer>();
} }
/// <summary> /// <summary>

View File

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

View File

@ -15,5 +15,7 @@ namespace FastTunnel.Core
public const string TYPE_CLIENT = "CLIENT"; public const string TYPE_CLIENT = "CLIENT";
public const string TYPE_SWAP = "SWAP"; public const string TYPE_SWAP = "SWAP";
public const int CMD_MAX_LENGTH = 100;
} }
} }

View File

@ -46,8 +46,7 @@ namespace FastTunnel.Core.MiddleWares
private async Task handleClient(HttpContext context, Func<Task> next) private async Task handleClient(HttpContext context, Func<Task> next)
{ {
using var webSocket = await context.WebSockets.AcceptWebSocketAsync(); using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
var tunnelClient = context.RequestServices.GetRequiredService<TunnelClient>().SetSocket(webSocket);
var tunnelClient = new TunnelClient(logger, fastTunnelServer).SetSocket(webSocket);
try try
{ {

View File

@ -34,8 +34,6 @@ namespace FastTunnel.Core.Handlers.Client
var requestId = msgs[0]; var requestId = msgs[0];
var address = msgs[1]; var address = msgs[1];
await Task.Yield();
try try
{ {
using Stream serverStream = await createRemote(requestId, cleint, cancellationToken); using Stream serverStream = await createRemote(requestId, cleint, cancellationToken);
@ -66,7 +64,7 @@ namespace FastTunnel.Core.Handlers.Client
await connecter.ConnectAsync(); await connecter.ConnectAsync();
Stream serverConn = new NetworkStream(connecter.Socket, true); Stream serverConn = new NetworkStream(connecter.Socket, true);
var reverse = $"PROXY /{requestId} HTTP/1.1\r\nHost: {cleint.Server.ServerAddr}:{cleint.Server.ServerPort}\r\nConnection: keep-alive\r\n\r\n"; 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); var requestMsg = Encoding.ASCII.GetBytes(reverse);
await serverConn.WriteAsync(requestMsg, cancellationToken); await serverConn.WriteAsync(requestMsg, cancellationToken);

View File

@ -13,6 +13,6 @@ namespace FastTunnel.Core.Handlers
{ {
bool NeedRecive { get; } bool NeedRecive { get; }
Task<bool> HandlerMsg<T>(FastTunnelServer server, WebSocket client, T msg) where T : TunnelMassage; Task<bool> HandlerMsg(FastTunnelServer server, WebSocket client, string msg);
} }
} }

View File

@ -0,0 +1,15 @@
using FastTunnel.Core.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading.Tasks;
namespace FastTunnel.Core.Handlers.Server
{
public interface ILoginHandler
{
Task<bool> HandlerMsg(FastTunnelServer fastTunnelServer, WebSocket webSocket, string lineCmd);
}
}

View File

@ -10,28 +10,27 @@ using System.Linq;
using System.Net.Sockets; using System.Net.Sockets;
using System.Net.WebSockets; using System.Net.WebSockets;
using System.Text; using System.Text;
using System.Text.Json;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Yarp.ReverseProxy.Configuration; using Yarp.ReverseProxy.Configuration;
using Yarp.Sample; using Yarp.Sample;
namespace FastTunnel.Core.Handlers namespace FastTunnel.Core.Handlers.Server
{ {
public class LoginHandler : IClientMessageHandler public class LoginHandler : ILoginHandler
{ {
ILogger _logger; ILogger _logger;
public bool NeedRecive => true;
IProxyConfigProvider proxyConfig; IProxyConfigProvider proxyConfig;
public const bool NeedRecive = true;
public LoginHandler(ILogger logger, IProxyConfigProvider proxyConfig) public LoginHandler(ILogger<LoginHandler> logger, IProxyConfigProvider proxyConfig)
{ {
this.proxyConfig = proxyConfig; this.proxyConfig = proxyConfig;
this._logger = logger; this._logger = logger;
} }
private async Task HandleLoginAsync(FastTunnelServer server, WebSocket client, LogInMassage requet) protected async Task HandleLoginAsync(FastTunnelServer server, WebSocket client, LogInMassage requet)
{ {
bool hasTunnel = false; bool hasTunnel = false;
@ -48,7 +47,7 @@ namespace FastTunnel.Core.Handlers
server.WebList.AddOrUpdate(hostName, info, (key, oldInfo) => { return info; }); server.WebList.AddOrUpdate(hostName, info, (key, oldInfo) => { return info; });
(proxyConfig as InMemoryConfigProvider).AddWeb(hostName); (proxyConfig as InMemoryConfigProvider).AddWeb(hostName);
await client.SendCmdAsync(MessageType.Log, $" HTTP | http://{hostName}:{server.serverOption.CurrentValue.WebProxyPort} => {item.LocalIp}:{item.LocalPort}", CancellationToken.None); await client.SendCmdAsync(MessageType.Log, $" HTTP | http://{hostName} => {item.LocalIp}:{item.LocalPort}", CancellationToken.None);
if (item.WWW != null) if (item.WWW != null)
{ {
@ -60,7 +59,7 @@ namespace FastTunnel.Core.Handlers
server.WebList.AddOrUpdate(www, info, (key, oldInfo) => { return info; }); server.WebList.AddOrUpdate(www, info, (key, oldInfo) => { return info; });
(proxyConfig as InMemoryConfigProvider).AddWeb(hostName); (proxyConfig as InMemoryConfigProvider).AddWeb(hostName);
await client.SendCmdAsync(MessageType.Log, $" HTTP | http://{www}:{server.serverOption.CurrentValue.WebProxyPort} => {item.LocalIp}:{item.LocalPort}", CancellationToken.None); await client.SendCmdAsync(MessageType.Log, $" HTTP | http://{www} => {item.LocalIp}:{item.LocalPort}", CancellationToken.None);
} }
} }
@ -77,12 +76,6 @@ namespace FastTunnel.Core.Handlers
{ {
try try
{ {
if (item.RemotePort.Equals(server.serverOption.CurrentValue.WebProxyPort))
{
_logger.LogError($"RemotePort can not be same with ProxyPort_HTTP: {item.RemotePort}");
continue;
}
ForwardInfo<ForwardHandlerArg> old; ForwardInfo<ForwardHandlerArg> old;
if (server.ForwardList.TryGetValue(item.RemotePort, out old)) if (server.ForwardList.TryGetValue(item.RemotePort, out old))
{ {
@ -120,10 +113,10 @@ namespace FastTunnel.Core.Handlers
await client.SendCmdAsync(MessageType.Log, TunnelResource.NoTunnel, CancellationToken.None); await client.SendCmdAsync(MessageType.Log, TunnelResource.NoTunnel, CancellationToken.None);
} }
public async Task<bool> HandlerMsg<T>(FastTunnelServer server, WebSocket client, T msg) public virtual async Task<bool> HandlerMsg(FastTunnelServer server, WebSocket client, string content)
where T : TunnelMassage
{ {
await HandleLoginAsync(server, client, msg as LogInMassage); var msg = JsonSerializer.Deserialize<LogInMassage>(content);
await HandleLoginAsync(server, client, msg);
return NeedRecive; return NeedRecive;
} }
} }

View File

@ -1,6 +1,7 @@
using FastTunnel.Core.Client; using FastTunnel.Core.Client;
using FastTunnel.Core.Extensions; using FastTunnel.Core.Extensions;
using FastTunnel.Core.Handlers; using FastTunnel.Core.Handlers;
using FastTunnel.Core.Handlers.Server;
using FastTunnel.Core.Protocol; using FastTunnel.Core.Protocol;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
@ -18,16 +19,16 @@ namespace FastTunnel.Core.Models
{ {
public class TunnelClient public class TunnelClient
{ {
readonly LoginHandler _loginHandler; readonly ILoginHandler _loginHandler;
FastTunnelServer fastTunnelServer; FastTunnelServer fastTunnelServer;
ILogger logger; ILogger logger;
WebSocket webSocket; WebSocket webSocket;
public TunnelClient(ILogger logger, FastTunnelServer fastTunnelServer) public TunnelClient(ILogger<TunnelClient> logger, FastTunnelServer fastTunnelServer, ILoginHandler loginHandler)
{ {
this.logger = logger; this.logger = logger;
this.fastTunnelServer = fastTunnelServer; this.fastTunnelServer = fastTunnelServer;
this._loginHandler = new LoginHandler(logger, fastTunnelServer.proxyConfig); this._loginHandler = loginHandler;
} }
public TunnelClient SetSocket(WebSocket webSocket) public TunnelClient SetSocket(WebSocket webSocket)
@ -38,7 +39,7 @@ namespace FastTunnel.Core.Models
public async Task ReviceAsync(CancellationToken cancellationToken) public async Task ReviceAsync(CancellationToken cancellationToken)
{ {
var buffer = new byte[128]; var buffer = new byte[FastTunnelConst.CMD_MAX_LENGTH];
var tunnelProtocol = new TunnelProtocol(); var tunnelProtocol = new TunnelProtocol();
while (true) while (true)
@ -62,9 +63,7 @@ namespace FastTunnel.Core.Models
try try
{ {
logger.LogDebug($"client{lineCmd}"); logger.LogDebug($"client{lineCmd}");
return await _loginHandler.HandlerMsg(fastTunnelServer, webSocket, lineCmd.Substring(1));
var msg = JsonSerializer.Deserialize<LogInMassage>(lineCmd.Substring(1));
return await _loginHandler.HandlerMsg(fastTunnelServer, webSocket, msg);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -1,10 +1,12 @@
using FastTunnel.Core.Extensions; using FastTunnel.Core.Extensions;
using FastTunnel.Core.Services; using FastTunnel.Core.Services;
using log4net.Repository.Hierarchy;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Serilog;
using System; using System;
namespace FastTunnel.Server namespace FastTunnel.Server

View File

@ -5,5 +5,7 @@ echo 127.0.0.1 test1.test.cc >>C:\Windows\System32\drivers\etc\hosts
echo 127.0.0.1 test2.test.cc >>C:\Windows\System32\drivers\etc\hosts echo 127.0.0.1 test2.test.cc >>C:\Windows\System32\drivers\etc\hosts
echo 127.0.0.1 test3.test.cc >>C:\Windows\System32\drivers\etc\hosts echo 127.0.0.1 test3.test.cc >>C:\Windows\System32\drivers\etc\hosts
echo 127.0.0.1 www.abc.com >>C:\Windows\System32\drivers\etc\hosts echo 127.0.0.1 www.abc.com >>C:\Windows\System32\drivers\etc\hosts
echo 127.0.0.1 sd.test.cc >>C:\Windows\System32\drivers\etc\hosts
echo 127.0.0.1 test9527.sd.test.cc >>C:\Windows\System32\drivers\etc\hosts
pause pause