更新通讯协议

This commit is contained in:
SpringHgui 2021-08-05 01:30:28 +08:00
parent ff32f44223
commit b6a1aaeb71
21 changed files with 191 additions and 405 deletions

View File

@ -15,6 +15,10 @@
//
"ServerPort": 1270
},
/**
* 访
* 穿TCP
*/
"Webs": [
{
// ip
@ -37,8 +41,8 @@
],
/**
*
* 访/mysql/erp/TCP
*
* 穿TCP
* linux#ssh -oPort=12701 {root}@{ServerAddr} ServerAddr iproot
* 访访
*/

View File

@ -15,38 +15,38 @@ using Microsoft.Extensions.Options;
using System.Net.WebSockets;
using System.Text.Json;
using FastTunnel.Core.Protocol;
using Microsoft.AspNetCore.DataProtection;
namespace FastTunnel.Core.Client
{
public class FastTunnelClient : IFastTunnelClient
{
private IFastTunnelClientSocket socket;
private ClientWebSocket socket;
protected ILogger<FastTunnelClient> _logger;
public DateTime lastHeart;
HttpRequestHandler _newCustomerHandler;
NewForwardHandler _newSSHHandler;
ForwardHandler _newCustomerHandler;
LogHandler _logHandler;
ClientHeartHandler _clientHeartHandler;
Message<LogInMassage> loginMsg;
protected readonly IOptionsMonitor<DefaultClientConfig> _configuration;
public DefaultClientConfig ClientConfig { get; private set; }
private readonly CancellationTokenSource cancellationTokenSource = new();
public SuiDaoServer Server { get; protected set; }
public FastTunnelClient(
ILogger<FastTunnelClient> logger,
HttpRequestHandler newCustomerHandler,
NewForwardHandler newSSHHandler, LogHandler logHandler,
ForwardHandler newCustomerHandler,
LogHandler logHandler,
IOptionsMonitor<DefaultClientConfig> configuration,
ClientHeartHandler clientHeartHandler)
{
_logger = logger;
_newCustomerHandler = newCustomerHandler;
_newSSHHandler = newSSHHandler;
_logHandler = logHandler;
_clientHeartHandler = clientHeartHandler;
_configuration = configuration;
ClientConfig = configuration.CurrentValue;
}
/// <summary>
@ -59,23 +59,26 @@ namespace FastTunnel.Core.Client
CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, this.cancellationTokenSource.Token);
_logger.LogInformation("===== FastTunnel Client Start =====");
socket = await loginAsync(cancellationToken);
await loginAsync(cancellationToken);
_logger.LogInformation($"通讯已建立");
await ReceiveServerAsync(socket);
await ReceiveServerAsync();
}
protected virtual async Task<IFastTunnelClientSocket> loginAsync(CancellationToken cancellationToken)
protected virtual async Task loginAsync(CancellationToken cancellationToken)
{
Server = _configuration.CurrentValue.Server;
Server = ClientConfig.Server;
_logger.LogInformation($"正在连接服务端 {Server.ServerAddr}:{Server.ServerPort}");
try
{
// 连接到的目标IP
socket = new DefultClientSocket();
socket = new ClientWebSocket();
socket.Options.RemoteCertificateValidationCallback = delegate { return true; };
socket.Options.SetRequestHeader(HeaderConst.FASTTUNNEL_FLAG, "2.0.0");
socket.Options.SetRequestHeader(HeaderConst.FASTTUNNEL_TYPE, HeaderConst.TYPE_CLIENT);
await socket.ConnectAsync(
new Uri($"ws://{_configuration.CurrentValue.Server.ServerAddr}:{_configuration.CurrentValue.Server.ServerPort}"), cancellationToken);
new Uri($"ws://{ClientConfig.Server.ServerAddr}:{ClientConfig.Server.ServerPort}"), cancellationToken);
_logger.LogInformation("连接成功");
}
@ -84,70 +87,48 @@ namespace FastTunnel.Core.Client
throw;
}
loginMsg = new Message<LogInMassage>
{
MessageType = MessageType.C_LogIn,
Content = new LogInMassage
{
Webs = _configuration.CurrentValue.Webs,
Forwards = _configuration.CurrentValue.Forwards,
},
};
// 登录
await socket.SendAsync(loginMsg, cancellationToken);
return socket;
await socket.SendCmdAsync(MessageType.LogIn, new LogInMassage
{
Webs = ClientConfig.Webs,
Forwards = ClientConfig.Forwards,
}.ToJson());
}
private async Task ReceiveServerAsync(IFastTunnelClientSocket client)
private async Task ReceiveServerAsync()
{
byte[] buffer = new byte[512];
var tunnelProtocol = new TunnelProtocol();
byte[] buffer = new byte[128];
while (true)
{
var res = await client.ReceiveAsync(buffer, CancellationToken.None);
var cmds = tunnelProtocol.HandleBuffer(buffer, 0, res);
if (cmds == null)
continue;
foreach (var item in cmds)
{
HandleServerRequestAsync(item);
}
var res = await socket.ReceiveAsync(buffer, CancellationToken.None);
var type = buffer[0];
var content = Encoding.UTF8.GetString(buffer, 1, res.Count - 1);
HandleServerRequestAsync(type, content);
}
}
private async void HandleServerRequestAsync(string lineCmd)
private async void HandleServerRequestAsync(byte cmd, string ctx)
{
try
{
var cmds = lineCmd.Split("||");
var type = cmds[0];
_logger.LogInformation($"处理 {type}");
TunnelMassage msg = null;
IClientHandler handler;
switch (type)
switch ((MessageType)cmd)
{
case "S_NewCustomer":
case MessageType.SwapMsg:
handler = _newCustomerHandler;
msg = JsonSerializer.Deserialize<NewCustomerMassage>(cmds[1]);
break;
case "S_NewSSH":
handler = _newSSHHandler;
msg = JsonSerializer.Deserialize<NewForwardMessage>(cmds[1]);
case MessageType.Forward:
handler = _newCustomerHandler;
break;
case "Log":
case MessageType.Log:
handler = _logHandler;
msg = JsonSerializer.Deserialize<LogMassage>(cmds[1]);
break;
default:
throw new Exception($"未处理的消息:{lineCmd}");
throw new Exception($"未处理的消息:cmd={cmd}");
}
await handler.HandlerMsgAsync(this, msg);
await handler.HandlerMsgAsync(this, ctx);
}
catch (Exception ex)
{

View File

@ -36,8 +36,8 @@ namespace FastTunnel.Core.Extensions
services.AddSingleton<IFastTunnelClient, FastTunnelClient>()
.AddSingleton<ClientHeartHandler>()
.AddSingleton<LogHandler>()
.AddSingleton<HttpRequestHandler>()
.AddSingleton<NewForwardHandler>();
.AddSingleton<ForwardHandler>()
.AddSingleton<ForwardHandler>();
services.AddHostedService<ServiceFastTunnelClient>();
}

View File

@ -12,19 +12,13 @@ namespace FastTunnel.Core.Extensions
{
public static class WebSocketExtensions
{
public static async Task SendCmdAsync<T>(this WebSocket socket, Message<T> message,
WebSocketMessageType webSocketMessage, bool end, CancellationToken cancellationToken)
where T : TunnelMassage
public static async Task SendCmdAsync(this WebSocket socket, MessageType type, string content)
{
var msg = Encoding.UTF8.GetBytes($"{message.MessageType.ToString()}||{message.Content.ToJson()}\n");
await socket.SendAsync(msg, webSocketMessage, end, cancellationToken);
}
var buffer = Encoding.UTF8.GetBytes((char)type + content + "\n");
if (type != MessageType.LogIn && buffer.Length > 128)
throw new ArgumentOutOfRangeException(nameof(content));
public static async Task SendCmdAsync<T>(this WebSocket socket, Message<T> message)
where T : TunnelMassage
{
var msg = Encoding.UTF8.GetBytes($"{message.MessageType.ToString()}||{message.Content.ToJson()}\n");
await socket.SendAsync(msg, WebSocketMessageType.Binary, false, CancellationToken.None);
await socket.SendAsync(buffer, WebSocketMessageType.Binary, false, CancellationToken.None);
}
}
}

View File

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

View File

@ -36,57 +36,15 @@ namespace FastTunnel.Core.MiddleWares
return;
};
if (HeaderConst.TYPE_CLIENT.Equals(type))
{
await Client(context, next);
}
else if (HeaderConst.TYPE_SWAP.Equals(type))
{
await Swap(context, next);
}
else
{
logger.LogError($"参数异常ConnectionType类型为{type}");
}
await handleClient(context, next);
}
private async Task Swap(HttpContext context, Func<Task> next)
{
var requestId = context.Request.Path.Value.Trim('/');
if (!fastTunnelServer.ResponseTasks.TryGetValue(requestId, out var response))
{
logger.LogError($"requestId不存在:{requestId}");
return;
};
var lifetime = context.Features.Get<IConnectionLifetimeFeature>();
var transport = context.Features.Get<IConnectionTransportFeature>();
if (lifetime == null || transport == null)
{
await next();
return;
}
using var stream = new WebSocketStream(lifetime, transport);
response.TrySetResult(stream);
logger.LogInformation($"Swap Set {requestId}");
var closedAwaiter = new TaskCompletionSource();
lifetime.ConnectionClosed.Register((task) => { (task as TaskCompletionSource).SetResult(); }, closedAwaiter);
await closedAwaiter.Task;
logger.LogInformation($"Swap Completion {requestId}");
}
private async Task Client(HttpContext context, Func<Task> next)
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($"{client} 客户端连接成功");
this.logger.LogInformation($"{webSocket} 客户端连接成功");
try
{

View File

@ -10,7 +10,7 @@ namespace FastTunnel.Core.Handlers.Client
{
public class ClientHeartHandler : IClientHandler
{
public async Task HandlerMsgAsync<T>(FastTunnelClient cleint, T Msg) where T : TunnelMassage
public async Task HandlerMsgAsync(FastTunnelClient cleint, string msg)
{
cleint.lastHeart = DateTime.Now;
await Task.Yield();

View File

@ -0,0 +1,49 @@
using FastTunnel.Core.Client;
using FastTunnel.Core.Dispatchers;
using FastTunnel.Core.Extensions;
using FastTunnel.Core.Models;
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;
using System.Threading;
using System.Threading.Tasks;
namespace FastTunnel.Core.Dispatchers
{
public class ForwardDispatcher
{
private FastTunnelServer _server;
private WebSocket _client;
private ForwardConfig _config;
public ForwardDispatcher(FastTunnelServer server, WebSocket client, ForwardConfig config)
{
_server = server;
_client = client;
_config = config;
}
public async void DispatchAsync(Socket _socket)
{
try
{
var msgid = Guid.NewGuid().ToString();
await _client.SendCmdAsync(MessageType.Forward, $"{msgid}|{_config.LocalIp }:{_config.LocalPort}");
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)
{
}
}
}
}

View File

@ -1,49 +1,71 @@
using FastTunnel.Core.Client;
using FastTunnel.Core.Dispatchers;
using FastTunnel.Core.Extensions;
using FastTunnel.Core.Config;
using FastTunnel.Core.Client;
using FastTunnel.Core.Models;
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;
using System.Threading;
using System.Threading.Tasks;
using FastTunnel.Core.Sockets;
using Microsoft.Extensions.Logging;
using FastTunnel.Core.Utility.Extensions;
using System.Net.WebSockets;
using FastTunnel.Core.Forwarder;
using Microsoft;
using Microsoft.AspNetCore.DataProtection;
using System.Data.Common;
namespace FastTunnel.Core.Dispatchers
namespace FastTunnel.Core.Handlers.Client
{
public class ForwardHandler
public class ForwardHandler : IClientHandler
{
private FastTunnelServer _server;
private WebSocket _client;
private ForwardConfig _config;
ILogger<ForwardHandler> _logger;
public ForwardHandler(FastTunnelServer server, WebSocket client, ForwardConfig config)
public ForwardHandler(ILogger<ForwardHandler> logger)
{
_server = server;
_client = client;
_config = config;
_logger = logger;
}
public async void DispatchAsync(Socket _socket)
public async Task HandlerMsgAsync(FastTunnelClient cleint, string msg)
{
try
{
var msgid = Guid.NewGuid().ToString();
await _client.SendCmdAsync(new Message<NewForwardMessage> { MessageType = MessageType.S_NewSSH, Content = new NewForwardMessage { MsgId = msgid, SSHConfig = _config } });
var msgs = msg.Split('|');
var tcs = new TaskCompletionSource<Stream>();
_server.ResponseTasks.TryAdd(msgid, tcs);
_logger.LogDebug($"开始转发 {msgs[0]}");
using var stream1 = await tcs.Task;
using var stream2 = new NetworkStream(_socket, true);
await Task.WhenAll(stream1.CopyToAsync(stream2), stream2.CopyToAsync(stream1));
}
catch (Exception)
{
}
await Task.Yield();
using Stream serverConn = await server(msgs[0], cleint);
using Stream localConn = await local(msgs[0], msgs[1]);
var taskX = serverConn.CopyToAsync(localConn, CancellationToken.None);
var taskY = localConn.CopyToAsync(serverConn, CancellationToken.None);
await Task.WhenAny(taskX, taskY);
}
private async Task<Stream> local(string requestId, string localhost)
{
_logger.LogDebug($"连接本地成功 {requestId}");
var localConnecter = new DnsSocket(localhost.Split(":")[0], int.Parse(localhost.Split(":")[1]));
await localConnecter.ConnectAsync();
return new NetworkStream(localConnecter.Socket, ownsSocket: true);
}
private async Task<Stream> server(string requestId, FastTunnelClient cleint)
{
var connecter = new DnsSocket(cleint.Server.ServerAddr, cleint.Server.ServerPort);
await connecter.ConnectAsync();
_logger.LogDebug($"连接server成功 {requestId}");
Stream serverConn = new NetworkStream(connecter.Socket, ownsSocket: true);
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);
return serverConn;
}
}
}

View File

@ -1,70 +0,0 @@
using FastTunnel.Core.Config;
using FastTunnel.Core.Client;
using FastTunnel.Core.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using FastTunnel.Core.Sockets;
using Microsoft.Extensions.Logging;
using FastTunnel.Core.Utility.Extensions;
using System.Net.WebSockets;
using FastTunnel.Core.Forwarder;
using Microsoft;
using Microsoft.AspNetCore.DataProtection;
using System.Data.Common;
namespace FastTunnel.Core.Handlers.Client
{
public class HttpRequestHandler : IClientHandler
{
ILogger<HttpRequestHandler> _logger;
public HttpRequestHandler(ILogger<HttpRequestHandler> logger)
{
_logger = logger;
}
public async Task HandlerMsgAsync<T>(FastTunnelClient cleint, T Msg) where T : TunnelMassage
{
var request = Msg as NewCustomerMassage;
await Task.Yield();
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);
}
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;
}
}
}

View File

@ -10,6 +10,6 @@ namespace FastTunnel.Core.Handlers.Client
{
public interface IClientHandler
{
Task HandlerMsgAsync<T>(FastTunnelClient cleint, T Msg) where T : TunnelMassage;
Task HandlerMsgAsync(FastTunnelClient cleint, string msg);
}
}

View File

@ -17,33 +17,10 @@ namespace FastTunnel.Core.Handlers.Client
_logger = logger;
}
public async Task HandlerMsgAsync<T>(FastTunnelClient cleint, T Msg)
where T : TunnelMassage
public async Task HandlerMsgAsync(FastTunnelClient cleint, string msg)
{
try
{
await Task.Yield();
var msg = Msg as LogMassage;
switch (msg.MsgType)
{
case LogMsgType.Info:
_logger.LogInformation($"[Server Info]:{msg.Msg}");
break;
case LogMsgType.Error:
_logger.LogError($"[Server Error]:{msg.Msg}");
break;
case LogMsgType.Debug:
_logger.LogDebug($"[Server Debug]:{msg.Msg}");
break;
default:
break;
}
}
catch (Exception ex)
{
_logger.LogError(ex);
}
_logger.LogInformation(msg.Replace("\n", string.Empty));
await Task.CompletedTask;
}
}
}

View File

@ -1,55 +0,0 @@
using FastTunnel.Core.Config;
using FastTunnel.Core.Client;
using FastTunnel.Core.Models;
using System;
using System.Collections.Generic;
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
{
public class NewForwardHandler : IClientHandler
{
ILogger<NewForwardHandler> _logger;
public NewForwardHandler(ILogger<NewForwardHandler> logger)
{
_logger = logger;
}
public async Task HandlerMsgAsync<T>(FastTunnelClient cleint, T Msg)
where T : TunnelMassage
{
var request = Msg as NewForwardMessage;
await Task.Yield();
using var stream1 = await Server(cleint, request);
using var stream2 = await local(request);
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;
}
}
}

View File

@ -37,8 +37,7 @@ namespace FastTunnel.Core.Handlers
{
bool hasTunnel = false;
var sb = new StringBuilder($"{Environment.NewLine}=====隧道已建立成功,可通过以下方式访问内网服务====={Environment.NewLine}{Environment.NewLine}");
sb.Append($"穿透协议 | 映射关系(公网=>内网){Environment.NewLine}");
await client.SendCmdAsync(MessageType.Log, $"穿透协议 | 映射关系(公网=>内网){Environment.NewLine}");
if (requet.Webs != null && requet.Webs.Count() > 0)
{
hasTunnel = true;
@ -51,8 +50,8 @@ namespace FastTunnel.Core.Handlers
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);
await client.SendCmdAsync(MessageType.Log, $" HTTP | http://{hostName}{(server.serverOption.CurrentValue.WebHasNginxProxy ? string.Empty : ":" + server.serverOption.CurrentValue.WebProxyPort)} => {item.LocalIp}:{item.LocalPort}");
if (item.WWW != null)
{
foreach (var www in item.WWW)
@ -62,8 +61,9 @@ namespace FastTunnel.Core.Handlers
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);
await client.SendCmdAsync(MessageType.Log, $" HTTP | http://{www}{(server.serverOption.CurrentValue.WebHasNginxProxy ? string.Empty : ":" + server.serverOption.CurrentValue.WebProxyPort)} => {item.LocalIp}:{item.LocalPort}");
}
}
}
@ -93,34 +93,26 @@ namespace FastTunnel.Core.Handlers
var ls = new PortProxyListener("0.0.0.0", item.RemotePort, _logger);
ls.Start(new ForwardHandler(server, client, item));
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}");
sb.Append($" TCP | {server.serverOption.CurrentValue.WebDomain}:{item.RemotePort} => {item.LocalIp}:{item.LocalPort}");
sb.Append(Environment.NewLine);
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(new Message<LogMassage> { MessageType = MessageType.Log, Content = new LogMassage(LogMsgType.Info, ex.Message) });
await client.SendCmdAsync(MessageType.Log, ex.Message);
continue;
}
}
}
if (!hasTunnel)
{
await client.SendCmdAsync(new Message<LogMassage> { MessageType = MessageType.Log, Content = new LogMassage(LogMsgType.Info, TunnelResource.NoTunnel) });
}
else
{
sb.Append($"{Environment.NewLine}====================================================");
await client.SendCmdAsync(new Message<LogMassage> { MessageType = MessageType.Log, Content = new LogMassage(LogMsgType.Info, sb.ToString()) });
}
await client.SendCmdAsync(MessageType.Log, TunnelResource.NoTunnel);
}
public async Task<bool> HandlerMsg<T>(FastTunnelServer server, WebSocket client, T msg)

View File

@ -1,10 +1,14 @@
using FastTunnel.Core.Dispatchers;
using FastTunnel.Core.Models;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
namespace FastTunnel.Core.Listener
{
@ -19,7 +23,7 @@ namespace FastTunnel.Core.Listener
int m_numConnectedSockets;
bool shutdown = false;
ForwardHandler _requestDispatcher;
ForwardDispatcher _requestDispatcher;
Socket listenSocket;
public IList<Socket> ConnectedSockets = new List<Socket>();
@ -36,7 +40,7 @@ namespace FastTunnel.Core.Listener
listenSocket.Bind(localEndPoint);
}
public void Start(ForwardHandler requestDispatcher)
public void Start(ForwardDispatcher requestDispatcher)
{
shutdown = false;
_requestDispatcher = requestDispatcher;
@ -120,6 +124,7 @@ namespace FastTunnel.Core.Listener
}
}
private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
ProcessAccept(e);

View File

@ -4,25 +4,18 @@ using System.Text;
namespace FastTunnel.Core.Models
{
public class Message<T>
public struct Message<T>
{
public MessageType MessageType { get; set; }
public T Content { get; set; }
}
public enum MessageType
public enum MessageType : byte
{
// client use below
C_LogIn,
Heart,
C_SwapMsg,
// server use below
S_NewCustomer,
S_NewSSH,
// twoway
Log,
LogIn = 1, // client
SwapMsg = 2,
Forward = 3,
Log = 4,
}
}

View File

@ -57,22 +57,9 @@ namespace FastTunnel.Core.Models
try
{
logger.LogInformation($"client{lineCmd}");
var cmds = lineCmd.Split("||");
var type = cmds[0];
TunnelMassage msg = null;
IClientMessageHandler handler = null;
switch (type)
{
case "C_LogIn": // 登录
handler = _loginHandler;
msg = JsonSerializer.Deserialize<LogInMassage>(cmds[1]);
break;
default:
throw new Exception($"未知的通讯指令 {lineCmd}");
}
return await handler.HandlerMsg(fastTunnelServer, webSocket, msg);
var msg = JsonSerializer.Deserialize<LogInMassage>(lineCmd.Substring(1));
return await _loginHandler.HandlerMsg(fastTunnelServer, webSocket, msg);
}
catch (Exception ex)
{

View File

@ -1,51 +0,0 @@
using FastTunnel.Core.Extensions;
using FastTunnel.Core.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace FastTunnel.Core.Sockets
{
public class DefultClientSocket : IFastTunnelClientSocket
{
ClientWebSocket webSocket;
public DefultClientSocket()
{
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_CLIENT);
}
public async Task ConnectAsync(Uri url, CancellationToken cancellationToken)
{
await webSocket.ConnectAsync(url, cancellationToken);
}
public async Task CloseAsync()
{
if (webSocket.State == WebSocketState.Closed)
return;
await webSocket.CloseAsync(WebSocketCloseStatus.Empty, null, CancellationToken.None);
}
public async Task<int> ReceiveAsync(byte[] buffer, CancellationToken cancellationToken)
{
var res = await webSocket.ReceiveAsync(buffer, cancellationToken);
return res.Count;
}
public async Task SendAsync<T>(Message<T> msg, CancellationToken cancellationToken)
where T : TunnelMassage
{
await webSocket.SendCmdAsync(msg, WebSocketMessageType.Binary, false, cancellationToken);
}
}
}

View File

@ -14,10 +14,10 @@ namespace FastTunnel.Core.Sockets
{
private Stream stream1;
private Stream stream2;
private ILogger<HttpRequestHandler> logger;
private ILogger<ForwardHandler> logger;
private string msgId;
public StreamSwap(Stream serverConnection, NetworkStream localConn, ILogger<HttpRequestHandler> logger, string msgId)
public StreamSwap(Stream serverConnection, NetworkStream localConn, ILogger<ForwardHandler> logger, string msgId)
{
this.stream1 = serverConnection;
this.stream2 = localConn;

View File

@ -37,12 +37,12 @@ namespace FastTunnel.Server
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureLogging((HostBuilderContext context, ILoggingBuilder logging) =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
logging.AddLog4Net();
});
//.ConfigureLogging((HostBuilderContext context, ILoggingBuilder logging) =>
//{
// logging.ClearProviders();
// logging.SetMinimumLevel(LogLevel.Trace);
// logging.AddLog4Net();
//});
}
}

View File

@ -3,7 +3,7 @@
"Logging": {
"LogLevel": {
// Trace Debug Information Warning Error
"Default": "Trace",
"Default": "Debug",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}