mirror of
https://github.com/FastTunnel/FastTunnel.git
synced 2025-02-08 02:39:29 +08:00
1
This commit is contained in:
parent
3e5020b890
commit
3e6a3bbc2a
|
@ -1,29 +0,0 @@
|
|||
using FastTunnel.Core.Client;
|
||||
using FastTunnel.Core.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastTunel.Core.WebApi.Controllers
|
||||
{
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class TunnelController : ControllerBase
|
||||
{
|
||||
FastTunnelServer _fastTunnelServer;
|
||||
|
||||
public TunnelController(FastTunnelServer fastTunnelServer)
|
||||
{
|
||||
_fastTunnelServer = fastTunnelServer;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public int GetWebCount()
|
||||
{
|
||||
return _fastTunnelServer.WebList.Count;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FastTunnel.Core\FastTunnel.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Controller_SelectedScaffolderID>ApiControllerEmptyScaffolder</Controller_SelectedScaffolderID>
|
||||
<Controller_SelectedScaffolderCategoryPath>root/Common/Api</Controller_SelectedScaffolderCategoryPath>
|
||||
<ActiveDebugProfile>IIS Express</ActiveDebugProfile>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -1,9 +0,0 @@
|
|||
namespace FastTunel.Core.WebApi
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,7 +42,7 @@
|
|||
* 远程linux示例:#ssh -oPort=12701 {root}@{ServerAddr} ServerAddr 填入服务端ip,root对应内网用户名
|
||||
* 通过服务端返回的访问方式进行访问即可
|
||||
*/
|
||||
"Forward": [
|
||||
"Forwards": [
|
||||
{
|
||||
"LocalIp": "127.0.0.1",
|
||||
"LocalPort": 8090,
|
||||
|
|
|
@ -15,6 +15,7 @@ using FastTunnel.Core.Sockets;
|
|||
using Microsoft.Extensions.Options;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text.Json;
|
||||
using FastTunnel.Core.Protocol;
|
||||
|
||||
namespace FastTunnel.Core.Client
|
||||
{
|
||||
|
@ -25,12 +26,8 @@ namespace FastTunnel.Core.Client
|
|||
|
||||
protected ILogger<FastTunnelClient> _logger;
|
||||
|
||||
System.Timers.Timer timer_heart;
|
||||
|
||||
double heartInterval = 10 * 1000; // 10 秒心跳
|
||||
public DateTime lastHeart;
|
||||
|
||||
int reTrySpan = 10 * 1000; // 登陆失败后重试间隔
|
||||
HttpRequestHandler _newCustomerHandler;
|
||||
NewForwardHandler _newSSHHandler;
|
||||
LogHandler _logHandler;
|
||||
|
@ -54,54 +51,6 @@ namespace FastTunnel.Core.Client
|
|||
_logHandler = logHandler;
|
||||
_clientHeartHandler = clientHeartHandler;
|
||||
_configuration = configuration;
|
||||
|
||||
timer_heart = new System.Timers.Timer();
|
||||
timer_heart.AutoReset = false;
|
||||
timer_heart.Interval = heartInterval;
|
||||
timer_heart.Elapsed += HeartElapsed;
|
||||
}
|
||||
|
||||
private async Task reConnAsync()
|
||||
{
|
||||
Close();
|
||||
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.Sleep(reTrySpan);
|
||||
|
||||
_logger.LogInformation("登录重试...");
|
||||
socket = await loginAsync(CancellationToken.None);
|
||||
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
}
|
||||
} while (true);
|
||||
|
||||
connSuccessAsync();
|
||||
}
|
||||
|
||||
private void HeartElapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
timer_heart.Enabled = false;
|
||||
|
||||
try
|
||||
{
|
||||
socket.SendAsync(new Message<HeartMassage> { MessageType = MessageType.Heart, Content = null }, cancellationTokenSource.Token).Wait();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 与服务端断开连接
|
||||
reConnAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
timer_heart.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -122,52 +71,12 @@ namespace FastTunnel.Core.Client
|
|||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
|
||||
reConnAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
_ = connSuccessAsync();
|
||||
await ReceiveServerAsync(socket);
|
||||
}
|
||||
//protected virtual Socket login()
|
||||
//{
|
||||
// Server = _configuration.CurrentValue.Server;
|
||||
|
||||
// DnsSocket _client = null;
|
||||
// _logger.LogInformation($"正在连接服务端 {Server.ServerAddr}:{Server.ServerPort}");
|
||||
|
||||
// try
|
||||
// {
|
||||
// // 连接到的目标IP
|
||||
// if (_client == null)
|
||||
// {
|
||||
// _client = new DnsSocket(Server.ServerAddr, Server.ServerPort);
|
||||
// }
|
||||
|
||||
// _client.Connect();
|
||||
|
||||
// _logger.LogInformation("连接成功");
|
||||
// }
|
||||
// catch (Exception)
|
||||
// {
|
||||
// throw;
|
||||
// }
|
||||
|
||||
// loginMsg = new Message<LogInMassage>
|
||||
// {
|
||||
// MessageType = MessageType.C_LogIn,
|
||||
// Content = new LogInMassage
|
||||
// {
|
||||
// Webs = _configuration.CurrentValue.Webs,
|
||||
// SSH = _configuration.CurrentValue.SSH,
|
||||
// },
|
||||
// };
|
||||
|
||||
// // 登录
|
||||
// _client.Send(loginMsg);
|
||||
|
||||
// return _client.Socket;
|
||||
//}
|
||||
protected virtual async Task<IFastTunnelClientSocket> loginAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Server = _configuration.CurrentValue.Server;
|
||||
|
@ -194,7 +103,7 @@ namespace FastTunnel.Core.Client
|
|||
Content = new LogInMassage
|
||||
{
|
||||
Webs = _configuration.CurrentValue.Webs,
|
||||
SSH = _configuration.CurrentValue.Forwards,
|
||||
Forwards = _configuration.CurrentValue.Forwards,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -203,125 +112,34 @@ namespace FastTunnel.Core.Client
|
|||
return socket;
|
||||
}
|
||||
|
||||
void Close()
|
||||
private async Task ReceiveServerAsync(IFastTunnelClientSocket client)
|
||||
{
|
||||
timer_heart.Stop();
|
||||
socket.CloseAsync();
|
||||
}
|
||||
|
||||
private async Task connSuccessAsync()
|
||||
{
|
||||
_logger.LogDebug("通信已建立");
|
||||
|
||||
// 心跳开始
|
||||
timer_heart.Start();
|
||||
|
||||
var th = new Thread(ReceiveServer);
|
||||
th.Start(socket);
|
||||
// await new PipeHepler(_client, ProceccLine).ProcessLinesAsync();
|
||||
}
|
||||
|
||||
private bool ProceccLine(Socket socket, byte[] line)
|
||||
{
|
||||
var cmd = Encoding.UTF8.GetString(line);
|
||||
HandleServerRequest(cmd);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ReceiveServer(object obj)
|
||||
{
|
||||
var client = obj as IFastTunnelClientSocket;
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
string lastBuffer = string.Empty;
|
||||
int n = 0;
|
||||
byte[] buffer = new byte[512];
|
||||
var tunnelProtocol = new TunnelProtocol();
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
n = client.ReceiveAsync(buffer, cancellationTokenSource.Token).GetAwaiter().GetResult();
|
||||
if (n == 0)
|
||||
{
|
||||
client.CloseAsync();
|
||||
break;
|
||||
}
|
||||
}
|
||||
/// <see cref="https://docs.microsoft.com/zh-cn/windows/win32/winsock/windows-sockets-error-codes-2"/>
|
||||
catch (SocketException socketEx)
|
||||
{
|
||||
// Connection timed out.
|
||||
if (socketEx.ErrorCode == 10060)
|
||||
{
|
||||
_logger.LogInformation("Connection timed out");
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError(socketEx);
|
||||
}
|
||||
var res = await client.ReceiveAsync(buffer, CancellationToken.None);
|
||||
var cmds = tunnelProtocol.HandleBuffer(buffer, 0, res);
|
||||
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex);
|
||||
break;
|
||||
}
|
||||
|
||||
string words = Encoding.UTF8.GetString(buffer, 0, n);
|
||||
if (!string.IsNullOrEmpty(lastBuffer))
|
||||
{
|
||||
words = lastBuffer + words;
|
||||
lastBuffer = null;
|
||||
}
|
||||
|
||||
var msgs = words.Split("\n");
|
||||
|
||||
_logger.LogDebug("recive from server:" + words);
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < msgs.Length - 1; i++)
|
||||
{
|
||||
var item = msgs[i];
|
||||
if (string.IsNullOrEmpty(item))
|
||||
continue;
|
||||
|
||||
if (item.EndsWith("}"))
|
||||
{
|
||||
HandleServerRequest(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
lastBuffer = item;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(msgs[msgs.Length - 1]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
lastBuffer = msgs[msgs.Length - 1];
|
||||
_logger.LogDebug($"lastBuffer={lastBuffer}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"HandleMsg Error {msgs.ToJson()}");
|
||||
if (cmds == null)
|
||||
continue;
|
||||
|
||||
foreach (var item in cmds)
|
||||
{
|
||||
HandleServerRequestAsync(item);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogInformation("stop receive from server");
|
||||
}
|
||||
|
||||
private void HandleServerRequest(string lineCmd)
|
||||
private async void HandleServerRequestAsync(string lineCmd)
|
||||
{
|
||||
Task.Run(() =>
|
||||
try
|
||||
{
|
||||
var cmds = lineCmd.Split("||");
|
||||
var type = cmds[0];
|
||||
|
||||
_logger.LogInformation($"处理 {type}");
|
||||
TunnelMassage msg = null;
|
||||
IClientHandler handler;
|
||||
switch (type)
|
||||
|
@ -346,8 +164,12 @@ namespace FastTunnel.Core.Client
|
|||
throw new Exception($"未处理的消息:{lineCmd}");
|
||||
}
|
||||
|
||||
handler.HandlerMsgAsync(this, msg);
|
||||
});
|
||||
await handler.HandlerMsgAsync(this, msg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,16 +18,13 @@ namespace FastTunnel.Core.Client
|
|||
{
|
||||
public class FastTunnelServer
|
||||
{
|
||||
[Obsolete("ResponseTasks替换", false)]
|
||||
public ConcurrentDictionary<string, NewRequest> RequestTemp { get; private set; }
|
||||
= new ConcurrentDictionary<string, NewRequest>();
|
||||
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>();
|
||||
public ConcurrentDictionary<string, WebInfo> WebList { get; private set; } = new();
|
||||
|
||||
public ConcurrentDictionary<int, ForwardInfo<ForwardHandlerArg>> SSHList { get; private set; }
|
||||
public ConcurrentDictionary<int, ForwardInfo<ForwardHandlerArg>> ForwardList { get; private set; }
|
||||
= new ConcurrentDictionary<int, ForwardInfo<ForwardHandlerArg>>();
|
||||
|
||||
readonly ILogger _logger;
|
||||
|
|
|
@ -3,8 +3,10 @@ using FastTunnel.Core.Dispatchers;
|
|||
using FastTunnel.Core.Extensions;
|
||||
using FastTunnel.Core.Models;
|
||||
using FastTunnel.Core.Server;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.Sockets;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
|
@ -26,15 +28,23 @@ namespace FastTunnel.Core.Dispatchers
|
|||
_config = config;
|
||||
}
|
||||
|
||||
public async Task DispatchAsync(Socket _socket)
|
||||
public async void DispatchAsync(Socket _socket)
|
||||
{
|
||||
var msgid = Guid.NewGuid().ToString();
|
||||
await _client.SendCmdAsync(new Message<NewForwardMessage> { MessageType = MessageType.S_NewSSH, Content = new NewForwardMessage { MsgId = msgid, SSHConfig = _config } });
|
||||
|
||||
_server.RequestTemp.TryAdd(msgid, new NewRequest
|
||||
try
|
||||
{
|
||||
CustomerClient = _socket,
|
||||
});
|
||||
var msgid = Guid.NewGuid().ToString();
|
||||
await _client.SendCmdAsync(new Message<NewForwardMessage> { MessageType = MessageType.S_NewSSH, Content = new NewForwardMessage { MsgId = msgid, SSHConfig = _config } });
|
||||
|
||||
var tcs = new TaskCompletionSource<Stream>();
|
||||
_server.ResponseTasks.TryAdd(msgid, tcs);
|
||||
|
||||
using var stream1 = await tcs.Task;
|
||||
using var stream2 = new NetworkStream(_socket, true);
|
||||
await Task.WhenAll(stream1.CopyToAsync(stream2), stream2.CopyToAsync(stream1));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispatch(AsyncUserToken token, string words)
|
||||
|
|
|
@ -11,6 +11,6 @@ namespace FastTunnel.Core.Dispatchers
|
|||
{
|
||||
void Dispatch(AsyncUserToken token, string words);
|
||||
|
||||
Task DispatchAsync(Socket httpClient);
|
||||
void DispatchAsync(Socket httpClient);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,95 +32,40 @@ namespace FastTunnel.Core.Handlers.Client
|
|||
public async Task HandlerMsgAsync<T>(FastTunnelClient cleint, T Msg) where T : TunnelMassage
|
||||
{
|
||||
var request = Msg as NewCustomerMassage;
|
||||
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");
|
||||
}
|
||||
|
||||
//var webSocket = new ClientWebSocket();
|
||||
//webSocket.Options.RemoteCertificateValidationCallback = delegate { return true; };
|
||||
//webSocket.Options.SetRequestHeader(HeaderConst.FASTTUNNEL_FLAG, "2.0.0");
|
||||
//webSocket.Options.SetRequestHeader(HeaderConst.FASTTUNNEL_TYPE, HeaderConst.TYPE_SWAP);
|
||||
|
||||
//var uri = new Uri($"ws://{cleint.Server.ServerAddr}:{cleint.Server.ServerPort}/{request.MsgId}");
|
||||
//webSocket.ConnectAsync(uri, CancellationToken.None);
|
||||
|
||||
await Task.Yield();
|
||||
|
||||
var connecter = new DnsSocket(cleint.Server.ServerAddr, cleint.Server.ServerPort);
|
||||
connecter.Connect();
|
||||
// connecter.Send(new Message<SwapMassage> { MessageType = MessageType.C_SwapMsg, Content = new SwapMassage(request.MsgId) });
|
||||
|
||||
Stream serverConn = new NetworkStream(connecter.Socket, ownsSocket: true);
|
||||
var reverse = $"PROXY /{request.MsgId} HTTP/1.1\r\nHost: {cleint.Server.ServerAddr}:{cleint.Server.ServerPort}\r\n\r\n";
|
||||
|
||||
var requestMsg = Encoding.ASCII.GetBytes(reverse);
|
||||
serverConn.WriteAsync(requestMsg, CancellationToken.None).GetAwaiter().GetResult();
|
||||
|
||||
_logger.LogDebug($"连接server成功 {request.MsgId}");
|
||||
var localConnecter = new DnsSocket(request.WebConfig.LocalIp, request.WebConfig.LocalPort);
|
||||
|
||||
try
|
||||
{
|
||||
localConnecter.Connect();
|
||||
}
|
||||
catch (SocketException sex)
|
||||
{
|
||||
if (sex.ErrorCode == 10061)
|
||||
{
|
||||
_logger.LogInformation($"内网服务不存在:{request.WebConfig.LocalIp}:{request.WebConfig.LocalPort}");
|
||||
// 内网的站点不存在或无法访问
|
||||
//string statusLine = "HTTP/1.1 200 OK\r\n";
|
||||
//string responseHeader = "Content-Type: text/html\r\n";
|
||||
//byte[] responseBody;
|
||||
//responseBody = Encoding.UTF8.GetBytes(TunnelResource.Page_NoSite);
|
||||
|
||||
//connecter.Send(Encoding.UTF8.GetBytes(statusLine));
|
||||
//connecter.Send(Encoding.UTF8.GetBytes(responseHeader));
|
||||
//connecter.Send(Encoding.UTF8.GetBytes("\r\n"));
|
||||
//connecter.Send(responseBody);
|
||||
|
||||
//connecter.Socket.Disconnect(false);
|
||||
//connecter.Socket.Close();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
localConnecter.Close();
|
||||
throw;
|
||||
}
|
||||
|
||||
_logger.LogDebug($"连接本地成功 {request.MsgId}");
|
||||
//var streamServer = new WebSocktReadWriteStream(webSocket);
|
||||
//var streamLocal = new SocketReadWriteStream(localConnecter.Socket);
|
||||
|
||||
var localConn = new NetworkStream(localConnecter.Socket, ownsSocket: true);
|
||||
using Stream serverConn = await Server(cleint, request);
|
||||
using Stream localConn = await local(request);
|
||||
|
||||
_logger.LogDebug($"开始转发 {request.MsgId}");
|
||||
var taskX = serverConn.CopyToAsync(localConn, CancellationToken.None);
|
||||
var taskY = localConn.CopyToAsync(serverConn, CancellationToken.None);
|
||||
|
||||
await Task.WhenAny(taskX, taskY);
|
||||
|
||||
try
|
||||
{
|
||||
localConn.Close();
|
||||
serverConn.Close();
|
||||
|
||||
_logger.LogDebug($"转发结束 {request.MsgId}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogDebug(ex, $"转发结束 {request.MsgId}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<Stream> local(NewCustomerMassage request)
|
||||
{
|
||||
_logger.LogDebug($"连接server成功 {request.MsgId}");
|
||||
var localConnecter = new DnsSocket(request.WebConfig.LocalIp, request.WebConfig.LocalPort);
|
||||
await localConnecter.ConnectAsync();
|
||||
|
||||
_logger.LogDebug($"连接本地成功 {request.MsgId}");
|
||||
|
||||
return new NetworkStream(localConnecter.Socket, ownsSocket: true);
|
||||
}
|
||||
|
||||
private async Task<Stream> Server(FastTunnelClient cleint, NewCustomerMassage request)
|
||||
{
|
||||
var connecter = new DnsSocket(cleint.Server.ServerAddr, cleint.Server.ServerPort);
|
||||
await connecter.ConnectAsync();
|
||||
Stream serverConn = new NetworkStream(connecter.Socket, ownsSocket: true);
|
||||
var reverse = $"PROXY /{request.MsgId} 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);
|
||||
return serverConn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@ using System.Text;
|
|||
using FastTunnel.Core.Sockets;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
|
||||
namespace FastTunnel.Core.Handlers.Client
|
||||
{
|
||||
|
@ -21,16 +24,32 @@ namespace FastTunnel.Core.Handlers.Client
|
|||
public async Task HandlerMsgAsync<T>(FastTunnelClient cleint, T Msg)
|
||||
where T : TunnelMassage
|
||||
{
|
||||
var request_ssh = Msg as NewForwardMessage;
|
||||
var request = Msg as NewForwardMessage;
|
||||
await Task.Yield();
|
||||
|
||||
var connecter_ssh = new DnsSocket(cleint.Server.ServerAddr, cleint.Server.ServerPort);
|
||||
connecter_ssh.Connect();
|
||||
connecter_ssh.Send(new Message<SwapMassage> { MessageType = MessageType.C_SwapMsg, Content = new SwapMassage(request_ssh.MsgId) });
|
||||
using var stream1 = await Server(cleint, request);
|
||||
using var stream2 = await local(request);
|
||||
|
||||
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();
|
||||
await Task.WhenAll(stream1.CopyToAsync(stream2), stream2.CopyToAsync(stream1));
|
||||
}
|
||||
|
||||
private async Task<Stream> local(NewForwardMessage request)
|
||||
{
|
||||
var localConnecter = new DnsSocket(request.SSHConfig.LocalIp, request.SSHConfig.LocalPort);
|
||||
await localConnecter.ConnectAsync();
|
||||
return new NetworkStream(localConnecter.Socket, true);
|
||||
}
|
||||
|
||||
private async Task<Stream> Server(FastTunnelClient cleint, NewForwardMessage request)
|
||||
{
|
||||
var connecter = new DnsSocket(cleint.Server.ServerAddr, cleint.Server.ServerPort);
|
||||
await connecter.ConnectAsync();
|
||||
Stream serverConn = new NetworkStream(connecter.Socket, ownsSocket: true);
|
||||
var reverse = $"PROXY /{request.MsgId} 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);
|
||||
return serverConn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,21 +70,14 @@ namespace FastTunnel.Core.Handlers
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (requet.SSH != null && requet.SSH.Count() > 0)
|
||||
if (requet.Forwards != null && requet.Forwards.Count() > 0)
|
||||
{
|
||||
hasTunnel = true;
|
||||
|
||||
foreach (var item in requet.SSH)
|
||||
foreach (var item in requet.Forwards)
|
||||
{
|
||||
try
|
||||
{
|
||||
//if (item.RemotePort.Equals(server.serverOption.CurrentValue.BindPort))
|
||||
//{
|
||||
// _logger.LogError($"RemotePort can not be same with BindPort: {item.RemotePort}");
|
||||
// continue;
|
||||
//}
|
||||
|
||||
if (item.RemotePort.Equals(server.serverOption.CurrentValue.WebProxyPort))
|
||||
{
|
||||
_logger.LogError($"RemotePort can not be same with ProxyPort_HTTP: {item.RemotePort}");
|
||||
|
@ -92,11 +85,11 @@ namespace FastTunnel.Core.Handlers
|
|||
}
|
||||
|
||||
ForwardInfo<ForwardHandlerArg> old;
|
||||
if (server.SSHList.TryGetValue(item.RemotePort, out old))
|
||||
if (server.ForwardList.TryGetValue(item.RemotePort, out old))
|
||||
{
|
||||
_logger.LogDebug($"Remove Listener {old.Listener.ListenIp}:{old.Listener.ListenPort}");
|
||||
old.Listener.Stop();
|
||||
server.SSHList.TryRemove(item.RemotePort, out ForwardInfo<ForwardHandlerArg> _);
|
||||
server.ForwardList.TryRemove(item.RemotePort, out ForwardInfo<ForwardHandlerArg> _);
|
||||
}
|
||||
|
||||
var ls = new PortProxyListener("0.0.0.0", item.RemotePort, _logger);
|
||||
|
@ -104,7 +97,7 @@ namespace FastTunnel.Core.Handlers
|
|||
ls.Start(new ForwardDispatcher(server, client, item));
|
||||
|
||||
// listen success
|
||||
server.SSHList.TryAdd(item.RemotePort, new ForwardInfo<ForwardHandlerArg> { Listener = ls, Socket = client, SSHConfig = item });
|
||||
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}");
|
||||
|
||||
sb.Append($" TCP | {server.serverOption.CurrentValue.WebDomain}:{item.RemotePort} => {item.LocalIp}:{item.LocalPort}");
|
||||
|
|
|
@ -37,12 +37,12 @@ namespace FastTunnel.Core.Listener
|
|||
listenSocket.Bind(localEndPoint);
|
||||
}
|
||||
|
||||
public void Start(IListenerDispatcher requestDispatcher, int backlog = 100)
|
||||
public void Start(IListenerDispatcher requestDispatcher)
|
||||
{
|
||||
shutdown = false;
|
||||
_requestDispatcher = requestDispatcher;
|
||||
|
||||
listenSocket.Listen(backlog);
|
||||
listenSocket.Listen();
|
||||
|
||||
StartAccept(null);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,6 @@ namespace FastTunnel.Core.Models
|
|||
/// <summary>
|
||||
/// 端口转发隧道列表
|
||||
/// </summary>
|
||||
public IEnumerable<ForwardConfig> SSH { get; set; }
|
||||
public IEnumerable<ForwardConfig> Forwards { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastTunnel.Core.Sockets
|
||||
{
|
||||
|
@ -30,6 +31,13 @@ namespace FastTunnel.Core.Sockets
|
|||
Socket.Connect(dnsEndPoint);
|
||||
}
|
||||
|
||||
|
||||
public async Task ConnectAsync()
|
||||
{
|
||||
DnsEndPoint dnsEndPoint = new DnsEndPoint(_host, _port);
|
||||
await Socket.ConnectAsync(dnsEndPoint);
|
||||
}
|
||||
|
||||
public void Send(byte[] data)
|
||||
{
|
||||
Socket.Send(data);
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
@*
|
||||
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
|
||||
*@
|
||||
@{
|
||||
}
|
||||
<div style="text-align:center;padding:50px;">Soming soon!</div>
|
Loading…
Reference in New Issue
Block a user