mirror of
https://github.com/FastTunnel/FastTunnel.git
synced 2025-02-08 02:39:29 +08:00
1
This commit is contained in:
parent
e3ce510943
commit
2228750243
27
FastTunel.Core.WebApi/Properties/launchSettings.json
Normal file
27
FastTunel.Core.WebApi/Properties/launchSettings.json
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:63078/",
|
||||
"sslPort": 44352
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"FastTunel.Core.WebApi": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using FastTunnel.Core.Extensions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using FastTunnel.Core.Client;
|
||||
|
||||
namespace FastTunnel.Client
|
||||
{
|
||||
|
@ -18,6 +20,8 @@ namespace FastTunnel.Client
|
|||
{
|
||||
// -------------------FastTunnel START------------------
|
||||
services.AddFastTunnelClient(hostContext.Configuration.GetSection("ClientSettings"));
|
||||
|
||||
services.AddSingleton<IFastTunnelClient, FastTunnelClient>();
|
||||
// -------------------FastTunnel EDN--------------------
|
||||
})
|
||||
.ConfigureLogging((HostBuilderContext context, ILoggingBuilder logging) =>
|
||||
|
|
|
@ -18,7 +18,7 @@ using Microsoft.Extensions.Options;
|
|||
|
||||
namespace FastTunnel.Core.Client
|
||||
{
|
||||
public class FastTunnelClient
|
||||
public class FastTunnelClient : IFastTunnelClient
|
||||
{
|
||||
Socket _client;
|
||||
|
||||
|
@ -266,7 +266,7 @@ namespace FastTunnel.Core.Client
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
_logger.LogError(ex, "HandleMsg Error");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -274,24 +274,6 @@ namespace FastTunnel.Core.Client
|
|||
_logger.LogInformation("stop receive from server");
|
||||
}
|
||||
|
||||
private bool ProceccLine(Socket socket, byte[] line)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var cmd = Encoding.UTF8.GetString(line);
|
||||
HandleServerRequest(cmd);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex);
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void HandleServerRequest(string words)
|
||||
{
|
||||
var Msg = JsonConvert.DeserializeObject<Message<JObject>>(words);
|
||||
|
|
|
@ -10,18 +10,20 @@ using System.Threading.Tasks;
|
|||
using System.Threading;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.IO;
|
||||
using Yarp.Sample;
|
||||
using Yarp.ReverseProxy.Configuration;
|
||||
|
||||
namespace FastTunnel.Core.Client
|
||||
{
|
||||
public class FastTunnelServer
|
||||
{
|
||||
/// <summary>
|
||||
/// 外部请求,需要定期清理
|
||||
/// TODO:是否可以实现LRU
|
||||
/// </summary>
|
||||
[Obsolete("ResponseTasks替换", false)]
|
||||
public ConcurrentDictionary<string, NewRequest> RequestTemp { get; private set; }
|
||||
= new ConcurrentDictionary<string, NewRequest>();
|
||||
|
||||
public ConcurrentDictionary<string, TaskCompletionSource<Stream>> ResponseTasks { get; } = new();
|
||||
|
||||
public ConcurrentDictionary<string, WebInfo> WebList { get; private set; }
|
||||
= new ConcurrentDictionary<string, WebInfo>();
|
||||
|
||||
|
@ -33,12 +35,12 @@ namespace FastTunnel.Core.Client
|
|||
readonly HttpListenerV2 http_listener;
|
||||
public readonly IOptionsMonitor<DefaultServerConfig> serverOption;
|
||||
|
||||
public FastTunnelServer(ILogger<FastTunnelServer> logger, IOptionsMonitor<DefaultServerConfig> serverSettings)
|
||||
public FastTunnelServer(ILogger<FastTunnelServer> logger, IProxyConfigProvider proxyConfig, IOptionsMonitor<DefaultServerConfig> serverSettings)
|
||||
{
|
||||
_logger = logger;
|
||||
serverOption = serverSettings;
|
||||
|
||||
clientListener = new ClientListenerV2(this, "0.0.0.0", serverOption.CurrentValue.BindPort, _logger);
|
||||
clientListener = new ClientListenerV2(this, proxyConfig, "0.0.0.0", serverOption.CurrentValue.BindPort, _logger);
|
||||
http_listener = new HttpListenerV2("0.0.0.0", serverOption.CurrentValue.WebProxyPort, _logger);
|
||||
}
|
||||
|
||||
|
@ -47,7 +49,7 @@ namespace FastTunnel.Core.Client
|
|||
_logger.LogInformation("===== FastTunnel Server Starting =====");
|
||||
|
||||
listenClient();
|
||||
listenHttp();
|
||||
//listenHttp();
|
||||
}
|
||||
|
||||
private void listenClient()
|
||||
|
@ -55,10 +57,10 @@ namespace FastTunnel.Core.Client
|
|||
clientListener.Start();
|
||||
}
|
||||
|
||||
private void listenHttp()
|
||||
{
|
||||
http_listener.Start(new HttpDispatcherV2(this, _logger, serverOption));
|
||||
}
|
||||
//private void listenHttp()
|
||||
//{
|
||||
// http_listener.Start(new HttpDispatcherV2(this, _logger, serverOption));
|
||||
//}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
|
|
13
FastTunnel.Core/Client/IFastTunnelClient.cs
Normal file
13
FastTunnel.Core/Client/IFastTunnelClient.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastTunnel.Core.Client
|
||||
{
|
||||
public interface IFastTunnelClient
|
||||
{
|
||||
void Start();
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using FastTunnel.Core.Client;
|
||||
using FastTunnel.Core.Config;
|
||||
using FastTunnel.Core.Filters;
|
||||
using FastTunnel.Core.Handlers;
|
||||
using FastTunnel.Core.Handlers.Client;
|
||||
using FastTunnel.Core.Services;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
@ -32,7 +33,7 @@ namespace FastTunnel.Core.Extensions
|
|||
{
|
||||
services.Configure<DefaultClientConfig>(configurationSection);
|
||||
|
||||
services.AddSingleton<FastTunnelClient>()
|
||||
services.AddSingleton<IFastTunnelClient, FastTunnelClient>()
|
||||
.AddSingleton<ClientHeartHandler>()
|
||||
.AddSingleton<LogHandler>()
|
||||
.AddSingleton<HttpRequestHandler>()
|
|
@ -27,10 +27,12 @@
|
|||
<Compile Remove="Client\SuiDaoServer.cs.REMOTE.cs" />
|
||||
<Compile Remove="Dispatchers\ClientDispatcher.cs" />
|
||||
<Compile Remove="Dispatchers\HttpDispatcher.cs" />
|
||||
<Compile Remove="Dispatchers\HttpDispatcherV2.cs" />
|
||||
<Compile Remove="Listener.cs" />
|
||||
<Compile Remove="Listener\ClientListener.cs" />
|
||||
<Compile Remove="Listener\HttpListener.cs" />
|
||||
<Compile Remove="Server.cs" />
|
||||
<Compile Remove="Sockets\AsyncSocketSwap.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -38,6 +40,7 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Yarp.ReverseProxy" Version="1.0.0-preview.12.21328.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
using FastTunnel.Core.Client;
|
||||
using FastTunnel.Core.Extensions;
|
||||
using FastTunnel.Core.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Yarp.ReverseProxy.Forwarder;
|
||||
|
||||
namespace FastTunnel.Core.Forwarder
|
||||
{
|
||||
public class FastTunnelForwarderHttpClientFactory : ForwarderHttpClientFactory
|
||||
{
|
||||
ILogger<FastTunnelForwarderHttpClientFactory> _logger;
|
||||
FastTunnelServer _fastTunnelServer;
|
||||
|
||||
public FastTunnelForwarderHttpClientFactory(ILogger<FastTunnelForwarderHttpClientFactory> logger, FastTunnelServer fastTunnelServer)
|
||||
{
|
||||
this._fastTunnelServer = fastTunnelServer;
|
||||
this._logger = logger;
|
||||
}
|
||||
|
||||
protected override void ConfigureHandler(ForwarderHttpClientContext context, SocketsHttpHandler handler)
|
||||
{
|
||||
base.ConfigureHandler(context, handler);
|
||||
handler.ConnectCallback = ConnectCallback;
|
||||
}
|
||||
|
||||
private async ValueTask<Stream> ConnectCallback(SocketsHttpConnectionContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
var host = context.InitialRequestMessage.RequestUri.Host;
|
||||
_logger.LogDebug($"ConnectCallback start:{host} {context.GetHashCode()}");
|
||||
|
||||
try
|
||||
{
|
||||
var res = await proxyAsync(host, cancellationToken);
|
||||
_logger.LogDebug($"ConnectCallback successfully:{host} {context.GetHashCode()}");
|
||||
return res;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this._logger.LogError(ex, "代理出现异常");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Stream> proxyAsync(string host, CancellationToken cancellation)
|
||||
{
|
||||
|
||||
WebInfo web;
|
||||
if (!_fastTunnelServer.WebList.TryGetValue(host, out web))
|
||||
{
|
||||
throw new Exception($"站点未登录:{host}");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var RequestId = Guid.NewGuid().ToString().Replace("-", "");
|
||||
_logger.LogDebug($"[send swap]:{RequestId}");
|
||||
|
||||
// 发送指令给客户端,等待建立隧道
|
||||
web.Socket.SendCmd(new Message<NewCustomerMassage> { MessageType = MessageType.S_NewCustomer, Content = new NewCustomerMassage { MsgId = RequestId, WebConfig = web.WebConfig } });
|
||||
|
||||
// TODO:超时处理
|
||||
TaskCompletionSource<Stream> task = new(cancellation);
|
||||
|
||||
_fastTunnelServer.ResponseTasks.TryAdd(RequestId, task);
|
||||
return await task.Task;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "proxyAsync Error");
|
||||
|
||||
// 移除
|
||||
_fastTunnelServer.WebList.TryRemove(host, out _);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
34
FastTunnel.Core/Forwarder/FastTunnelProxyConfig.cs
Normal file
34
FastTunnel.Core/Forwarder/FastTunnelProxyConfig.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using Microsoft.Extensions.Primitives;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Yarp.ReverseProxy.Configuration;
|
||||
|
||||
namespace FastTunnel.Core.Forwarder
|
||||
{
|
||||
public class FastTunnelProxyConfig : IProxyConfig
|
||||
{
|
||||
public FastTunnelProxyConfig()
|
||||
: this(Array.Empty<RouteConfig>(), Array.Empty<ClusterConfig>())
|
||||
{
|
||||
}
|
||||
|
||||
public FastTunnelProxyConfig(IReadOnlyList<RouteConfig> routes, IReadOnlyList<ClusterConfig> clusters)
|
||||
{
|
||||
this.Routes = routes;
|
||||
this.Clusters = clusters;
|
||||
this.ChangeToken = new CancellationChangeToken(cancellationToken.Token);
|
||||
}
|
||||
|
||||
public IReadOnlyList<RouteConfig> Routes { get; }
|
||||
|
||||
public IReadOnlyList<ClusterConfig> Clusters { get; }
|
||||
|
||||
public IChangeToken ChangeToken { get; }
|
||||
|
||||
private readonly CancellationTokenSource cancellationToken = new();
|
||||
}
|
||||
}
|
17
FastTunnel.Core/Forwarder/FastTunnelProxyConfigProvider.cs
Normal file
17
FastTunnel.Core/Forwarder/FastTunnelProxyConfigProvider.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yarp.ReverseProxy.Configuration;
|
||||
|
||||
namespace FastTunnel.Core.Forwarder
|
||||
{
|
||||
public class FastTunnelProxyConfigProvider : IProxyConfigProvider
|
||||
{
|
||||
public IProxyConfig GetConfig()
|
||||
{
|
||||
return new FastTunnelProxyConfig();
|
||||
}
|
||||
}
|
||||
}
|
120
FastTunnel.Core/Forwarder/InMemoryConfigProvider.cs
Normal file
120
FastTunnel.Core/Forwarder/InMemoryConfigProvider.cs
Normal file
|
@ -0,0 +1,120 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Yarp.ReverseProxy.Configuration;
|
||||
using System.Linq;
|
||||
|
||||
namespace Yarp.Sample
|
||||
{
|
||||
/// <summary>
|
||||
/// Extends the IReverseProxyBuilder to support the InMemoryConfigProvider
|
||||
/// </summary>
|
||||
public static class InMemoryConfigProviderExtensions
|
||||
{
|
||||
public static IReverseProxyBuilder LoadFromMemory(this IReverseProxyBuilder builder)
|
||||
{
|
||||
builder.Services.AddSingleton<IProxyConfigProvider>(
|
||||
new InMemoryConfigProvider(Array.Empty<RouteConfig>(), Array.Empty<ClusterConfig>()));
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides an implementation of IProxyConfigProvider to support config being generated by code.
|
||||
/// </summary>
|
||||
public class InMemoryConfigProvider : IProxyConfigProvider
|
||||
{
|
||||
// Marked as volatile so that updates are atomic
|
||||
private volatile InMemoryConfig _config;
|
||||
|
||||
public InMemoryConfigProvider(IReadOnlyList<RouteConfig> routes, IReadOnlyList<ClusterConfig> clusters)
|
||||
{
|
||||
_config = new InMemoryConfig(routes, clusters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of the IProxyConfigProvider.GetConfig method to supply the current snapshot of configuration
|
||||
/// </summary>
|
||||
/// <returns>An immutable snapshot of the current configuration state</returns>
|
||||
public IProxyConfig GetConfig() => _config;
|
||||
|
||||
/// <summary>
|
||||
/// Swaps the config state with a new snapshot of the configuration, then signals the change
|
||||
/// </summary>
|
||||
public void Update(IReadOnlyList<RouteConfig> routes, IReadOnlyList<ClusterConfig> clusters)
|
||||
{
|
||||
var oldConfig = _config;
|
||||
_config = new InMemoryConfig(routes, clusters);
|
||||
oldConfig.SignalChange();
|
||||
}
|
||||
|
||||
public void AddWeb(string hostName)
|
||||
{
|
||||
Console.WriteLine($"ÐÂÔöhostName£º{hostName}");
|
||||
var oldConfig = _config;
|
||||
|
||||
var newRoutes = oldConfig.Routes.ToList();
|
||||
newRoutes.Add(new RouteConfig
|
||||
{
|
||||
ClusterId = hostName,
|
||||
RouteId = hostName,
|
||||
Match = new RouteMatch { Hosts = new string[] { hostName } }
|
||||
});
|
||||
|
||||
var newClusters = oldConfig.Clusters.ToList();
|
||||
newClusters.Add(new ClusterConfig
|
||||
{
|
||||
ClusterId = hostName,
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "default", new DestinationConfig() {Address = $"http://{hostName}",} }
|
||||
}
|
||||
});
|
||||
|
||||
_config = new InMemoryConfig(newRoutes, newClusters);
|
||||
oldConfig.SignalChange();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of IProxyConfig which is a snapshot of the current config state. The data for this class should be immutable.
|
||||
/// </summary>
|
||||
private class InMemoryConfig : IProxyConfig
|
||||
{
|
||||
// Used to implement the change token for the state
|
||||
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
|
||||
public InMemoryConfig(IReadOnlyList<RouteConfig> routes, IReadOnlyList<ClusterConfig> clusters)
|
||||
{
|
||||
Routes = routes;
|
||||
Clusters = clusters;
|
||||
ChangeToken = new CancellationChangeToken(_cts.Token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A snapshot of the list of routes for the proxy
|
||||
/// </summary>
|
||||
public IReadOnlyList<RouteConfig> Routes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A snapshot of the list of Clusters which are collections of interchangable destination endpoints
|
||||
/// </summary>
|
||||
public IReadOnlyList<ClusterConfig> Clusters { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Fired to indicate the the proxy state has changed, and that this snapshot is now stale
|
||||
/// </summary>
|
||||
public IChangeToken ChangeToken { get; }
|
||||
|
||||
internal void SignalChange()
|
||||
{
|
||||
_cts.Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastTunnel.Core.MiddleWares
|
||||
{
|
||||
public class FastTunnelClientHandler
|
||||
{
|
||||
public static async Task Handle(HttpContext context, Func<Task> next)
|
||||
{
|
||||
if (!context.WebSockets.IsWebSocketRequest)
|
||||
{
|
||||
await next();
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,9 +27,12 @@ namespace FastTunnel.Core.Handlers.Client
|
|||
public void HandlerMsg(FastTunnelClient cleint, Message<JObject> Msg)
|
||||
{
|
||||
var request = Msg.Content.ToObject<NewCustomerMassage>();
|
||||
var interval = long.Parse(DateTime.Now.GetChinaTicks()) - long.Parse(request.MsgId.Split('_')[0]);
|
||||
if (request.MsgId.Contains("_"))
|
||||
{
|
||||
var interval = long.Parse(DateTime.Now.GetChinaTicks()) - long.Parse(request.MsgId.Split('_')[0]);
|
||||
|
||||
_logger.LogDebug($"Start SwapMassage {request.MsgId} 服务端耗时:{interval}ms");
|
||||
_logger.LogDebug($"Start SwapMassage {request.MsgId} 服务端耗时:{interval}ms");
|
||||
}
|
||||
|
||||
var connecter = new DnsSocket(cleint.Server.ServerAddr, cleint.Server.ServerPort);
|
||||
connecter.Connect();
|
||||
|
@ -44,7 +47,7 @@ namespace FastTunnel.Core.Handlers.Client
|
|||
localConnecter.Connect();
|
||||
_logger.LogDebug($"连接本地成功 {request.MsgId}");
|
||||
|
||||
new SocketSwap(connecter.Socket, localConnecter.Socket, _logger, request.MsgId).StartSwap();
|
||||
new SocketSwap(connecter.Socket, localConnecter.Socket, _logger, request.MsgId).StartSwapAsync();
|
||||
}
|
||||
catch (SocketException sex)
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace FastTunnel.Core.Handlers.Client
|
|||
var localConnecter_ssh = new DnsSocket(request_ssh.SSHConfig.LocalIp, request_ssh.SSHConfig.LocalPort);
|
||||
localConnecter_ssh.Connect();
|
||||
|
||||
new SocketSwap(connecter_ssh.Socket, localConnecter_ssh.Socket, _logger, request_ssh.MsgId).StartSwap();
|
||||
new SocketSwap(connecter_ssh.Socket, localConnecter_ssh.Socket, _logger, request_ssh.MsgId).StartSwapAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using Yarp.ReverseProxy.Configuration;
|
||||
using Yarp.Sample;
|
||||
|
||||
namespace FastTunnel.Core.Handlers
|
||||
{
|
||||
|
@ -24,12 +26,15 @@ namespace FastTunnel.Core.Handlers
|
|||
IConfigHandler _configHandler;
|
||||
|
||||
static object _locker = new object();
|
||||
IProxyConfigProvider proxyConfig;
|
||||
|
||||
public LoginHandler(ILogger logger)
|
||||
public LoginHandler(ILogger logger, IProxyConfigProvider proxyConfig)
|
||||
{
|
||||
_logger = logger;
|
||||
this.proxyConfig = proxyConfig;
|
||||
this._logger = logger;
|
||||
|
||||
var custome = FastTunnelGlobal.GetCustomHandler<IConfigHandler>();
|
||||
_configHandler = custome == null ? new ConfigHandler() : custome;
|
||||
this._configHandler = custome == null ? new ConfigHandler() : custome;
|
||||
}
|
||||
|
||||
public LogInMassage GetConfig(JObject content)
|
||||
|
@ -80,6 +85,8 @@ namespace FastTunnel.Core.Handlers
|
|||
|
||||
_logger.LogDebug($"new domain '{hostName}'");
|
||||
server.WebList.AddOrUpdate(hostName, info, (key, oldInfo) => { return info; });
|
||||
(proxyConfig as InMemoryConfigProvider).AddWeb(hostName);
|
||||
|
||||
sb.Append($" HTTP | http://{hostName}{(server.serverOption.CurrentValue.WebHasNginxProxy ? string.Empty : ":" + server.serverOption.CurrentValue.WebProxyPort)} => {item.LocalIp}:{item.LocalPort}");
|
||||
sb.Append(Environment.NewLine);
|
||||
if (item.WWW != null)
|
||||
|
@ -90,6 +97,7 @@ namespace FastTunnel.Core.Handlers
|
|||
_logger.LogInformation($"WWW {www}");
|
||||
|
||||
server.WebList.AddOrUpdate(www, info, (key, oldInfo) => { return info; });
|
||||
(proxyConfig as InMemoryConfigProvider).AddWeb(hostName);
|
||||
sb.Append($" HTTP | http://{www}{(server.serverOption.CurrentValue.WebHasNginxProxy ? string.Empty : ":" + server.serverOption.CurrentValue.WebProxyPort)} => {item.LocalIp}:{item.LocalPort}");
|
||||
sb.Append(Environment.NewLine);
|
||||
}
|
||||
|
|
|
@ -27,26 +27,19 @@ namespace FastTunnel.Core.Handlers.Server
|
|||
public void HandlerMsg(FastTunnelServer server, Socket client, Message<JObject> msg)
|
||||
{
|
||||
var SwapMsg = msg.Content.ToObject<SwapMassage>();
|
||||
NewRequest request;
|
||||
|
||||
if (SwapMsg.msgId.Contains("_"))
|
||||
{
|
||||
var interval = long.Parse(DateTime.Now.GetChinaTicks()) - long.Parse(SwapMsg.msgId.Split('_')[0]);
|
||||
_logger.LogDebug($"[开始转发HTTP]:{SwapMsg.msgId} 客户端耗时:{interval}ms");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(SwapMsg.msgId) && server.RequestTemp.TryGetValue(SwapMsg.msgId, out request))
|
||||
if (!string.IsNullOrEmpty(SwapMsg.msgId) && server.ResponseTasks.TryGetValue(SwapMsg.msgId, out var response))
|
||||
{
|
||||
server.RequestTemp.TryRemove(SwapMsg.msgId, out _);
|
||||
server.ResponseTasks.TryRemove(SwapMsg.msgId, out _);
|
||||
|
||||
_logger.LogDebug($"SwapMassage:{SwapMsg.msgId}");
|
||||
|
||||
new SocketSwap(request.CustomerClient, client, _logger, SwapMsg.msgId)
|
||||
.BeforeSwap(() =>
|
||||
{
|
||||
if (request.Buffer != null) client.Send(request.Buffer);
|
||||
})
|
||||
.StartSwap();
|
||||
response.SetResult(new NetworkStream(client));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@ using System.Collections.Generic;
|
|||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using Yarp.ReverseProxy.Configuration;
|
||||
|
||||
namespace FastTunnel.Core.Listener
|
||||
{
|
||||
|
@ -31,14 +32,14 @@ namespace FastTunnel.Core.Listener
|
|||
readonly HeartMessageHandler _heartHandler;
|
||||
readonly SwapMessageHandler _swapMsgHandler;
|
||||
|
||||
public ClientListenerV2(FastTunnelServer fastTunnelServer, string ip, int port, ILogger logerr)
|
||||
public ClientListenerV2(FastTunnelServer fastTunnelServer, IProxyConfigProvider proxyConfig, string ip, int port, ILogger logerr)
|
||||
{
|
||||
_fastTunnelServer = fastTunnelServer;
|
||||
_logger = logerr;
|
||||
this.ListenIp = ip;
|
||||
this.ListenPort = port;
|
||||
|
||||
_loginHandler = new LoginHandler(_logger);
|
||||
_loginHandler = new LoginHandler(_logger, proxyConfig);
|
||||
_heartHandler = new HeartMessageHandler();
|
||||
_swapMsgHandler = new SwapMessageHandler(_logger);
|
||||
|
||||
|
|
|
@ -16,9 +16,9 @@ namespace FastTunnel.Core.Services
|
|||
public class ServiceFastTunnelClient : IHostedService
|
||||
{
|
||||
readonly ILogger<ServiceFastTunnelClient> _logger;
|
||||
readonly FastTunnelClient _fastTunnelClient;
|
||||
readonly IFastTunnelClient _fastTunnelClient;
|
||||
|
||||
public ServiceFastTunnelClient(ILogger<ServiceFastTunnelClient> logger, FastTunnelClient fastTunnelClient)
|
||||
public ServiceFastTunnelClient(ILogger<ServiceFastTunnelClient> logger, IFastTunnelClient fastTunnelClient)
|
||||
{
|
||||
_logger = logger;
|
||||
_fastTunnelClient = fastTunnelClient;
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace FastTunnel.Core.Sockets
|
|||
return this;
|
||||
}
|
||||
|
||||
public void StartSwap()
|
||||
public Task StartSwapAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -65,11 +65,14 @@ namespace FastTunnel.Core.Sockets
|
|||
{
|
||||
ProcessReceive(e2);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.ToString());
|
||||
ExceptionDispatchInfo.Capture(ex).Throw();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,6 @@ namespace FastTunnel.Core.Sockets
|
|||
/// <returns></returns>
|
||||
ISocketSwap BeforeSwap(Action fun);
|
||||
|
||||
void StartSwap();
|
||||
Task StartSwapAsync();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,15 +35,38 @@ namespace FastTunnel.Core.Sockets
|
|||
m_logger = logger;
|
||||
}
|
||||
|
||||
public void StartSwap()
|
||||
public async Task StartSwapAsync()
|
||||
{
|
||||
m_logger.LogDebug($"StartSwap start {m_msgId}");
|
||||
var st1 = new NetworkStream(m_sockt1, ownsSocket: true);
|
||||
var st2 = new NetworkStream(m_sockt2, ownsSocket: true);
|
||||
|
||||
var taskX = st1.CopyToAsync(st2);
|
||||
var taskY = st2.CopyToAsync(st1);
|
||||
|
||||
Task.WhenAny(taskX, taskY);
|
||||
await Task.WhenAny(taskX, taskY);
|
||||
m_logger.LogDebug($"StartSwap end {m_msgId}");
|
||||
|
||||
try
|
||||
{
|
||||
st1.Close();
|
||||
// m_sockt1.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
st2.Close();
|
||||
m_sockt2.Close();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ISocketSwap BeforeSwap(Action fun)
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
using FastTunnel.Core.Client;
|
||||
using FastTunnel.Core.Filters;
|
||||
using FastTunnel.Core.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastTunnel.Server.Filters
|
||||
{
|
||||
public class TestAuthenticationFilter : IAuthenticationFilter
|
||||
{
|
||||
public bool Authentication(FastTunnelServer server, LogInMassage requet)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,12 +28,12 @@ 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--------------------
|
||||
})
|
||||
//.ConfigureServices((hostContext, services) =>
|
||||
//{
|
||||
// // -------------------FastTunnel START------------------
|
||||
// services.AddFastTunnelServer(hostContext.Configuration.GetSection("ServerSettings"));
|
||||
// // -------------------FastTunnel END--------------------
|
||||
//})
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<DeleteExistingFiles>False</DeleteExistingFiles>
|
||||
<ExcludeApp_Data>False</ExcludeApp_Data>
|
||||
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
|
||||
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||
<PublishProvider>FileSystem</PublishProvider>
|
||||
<PublishUrl>bin\Release\net5.0\publish\</PublishUrl>
|
||||
<WebPublishMethod>FileSystem</WebPublishMethod>
|
||||
<SiteUrlToLaunchAfterPublish />
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<ProjectGuid>def2e322-9075-4c3f-9967-7eaf0ee28ceb</ProjectGuid>
|
||||
<SelfContained>false</SelfContained>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -1,17 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FastTunnel.Core.Filters;
|
||||
using FastTunnel.Server.Filters;
|
||||
using FastTunnel.Core.Extensions;
|
||||
using FastTunnel.Core.Forwarder;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.HttpsPolicy;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Yarp.ReverseProxy.Configuration;
|
||||
using Yarp.ReverseProxy.Forwarder;
|
||||
using Yarp.Sample;
|
||||
|
||||
namespace FastTunnel.Server
|
||||
{
|
||||
|
@ -27,14 +26,15 @@ namespace FastTunnel.Server
|
|||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddControllers();
|
||||
services.AddSwaggerGen(c =>
|
||||
{
|
||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "FastTunel.Core.WebApi", Version = "v1" });
|
||||
});
|
||||
// -------------------FastTunnel START------------------
|
||||
services.AddFastTunnelServer(Configuration.GetSection("ServerSettings"));
|
||||
// -------------------FastTunnel END--------------------
|
||||
|
||||
// Add the reverse proxy to capability to the server
|
||||
services.AddReverseProxy().LoadFromMemory();
|
||||
|
||||
// ------------------------Custom Business------------------------------
|
||||
services.AddTransient<IAuthenticationFilter, TestAuthenticationFilter>();
|
||||
services.AddSingleton<IForwarderHttpClientFactory, FastTunnelForwarderHttpClientFactory>();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
|
@ -42,20 +42,14 @@ namespace FastTunnel.Server
|
|||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "FastTunel.Core.WebApi v1"));
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
endpoints.MapReverseProxy();
|
||||
//endpoints.MapControllers();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user