🐱‍🏍

This commit is contained in:
Gui.H 2022-07-15 14:35:50 +08:00
parent 4af0ee0f23
commit 4627a1f705
15 changed files with 28 additions and 165 deletions

View File

@ -146,7 +146,7 @@ public class FastTunnelClient : IFastTunnelClient
}
catch (Exception ex)
{
_logger.LogError(ex);
_logger.LogError(ex, "[HandleServerRequest Error]");
}
}

View File

@ -1,19 +0,0 @@
// Licensed under the Apache License, Version 2.0 (the "License").
// You may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE
// Copyright (c) 2019 Gui.H
using Microsoft.Extensions.Logging;
using System;
namespace FastTunnel.Core.Extensions
{
public static class LoggerExtentions
{
public static void LogError(this ILogger logger, Exception ex)
{
logger.LogError(ex, string.Empty);
}
}
}

View File

@ -1,27 +0,0 @@
// Licensed under the Apache License, Version 2.0 (the "License").
// You may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE
// Copyright (c) 2019 Gui.H
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastTunnel.Core.Extensions;
public static class TaskCompletionSourceExtensions
{
public static void SetTimeOut<T>(this TaskCompletionSource<T> tcs, int timeoutMs, Action? action)
{
var ct = new CancellationTokenSource(timeoutMs);
ct.Token.Register(() =>
{
if (tcs.Task.IsCompleted)
return;
tcs.TrySetCanceled();
action?.Invoke();
}, useSynchronizationContext: false);
}
}

View File

@ -25,9 +25,6 @@ public static class WebSocketExtensions
}
var buffer = Encoding.UTF8.GetBytes($"{(char)type}{content}\n");
if (type != MessageType.LogIn && buffer.Length > ProtocolConst.MAX_CMD_LENGTH)
throw new ArgumentOutOfRangeException(nameof(content));
await socket.SendAsync(buffer, WebSocketMessageType.Binary, false, cancellationToken);
}
}

View File

@ -53,8 +53,7 @@ public class FastTunelProtocol
readableBuffer = result.Buffer;
SequencePosition start = readableBuffer.Start;
SequencePosition? position = null;
SequencePosition? position;
do
{
position = readableBuffer.PositionOf(ByteLF);
@ -62,7 +61,7 @@ public class FastTunelProtocol
if (position != null)
{
var readedPosition = readableBuffer.GetPosition(1, position.Value);
if (ProcessHeaderLine(readableBuffer.Slice(0, position.Value), out var _))
if (ProcessHeaderLine(readableBuffer.Slice(0, position.Value), out _))
{
if (Method == ProtocolConst.HTTP_METHOD_SWAP)
{
@ -101,10 +100,10 @@ public class FastTunelProtocol
public string Method;
public string Host = null;
public string MessageId;
public Guid MessageId;
private bool isFirstLine = true;
public FastTunnelServer fastTunnelServer { get; }
private FastTunnelServer fastTunnelServer { get; }
/// <summary>
///
@ -133,7 +132,7 @@ public class FastTunelProtocol
case ProtocolConst.HTTP_METHOD_SWAP:
// 客户端发起消息互转
var endIndex = headerLineStr.IndexOf(" ", 7);
MessageId = headerLineStr.Substring(7, endIndex - 7);
MessageId = Guid.Parse(headerLineStr.Substring(7, endIndex - 7));
break;
default:
// 常规Http请求需要检查Host决定是否进行代理

View File

@ -4,6 +4,7 @@
// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE
// Copyright (c) 2019 Gui.H
using System;
using System.Collections.Generic;
using FastTunnel.Core.Models;
@ -14,7 +15,10 @@ public struct FastTunnelFeature : IFastTunnelFeature
public WebInfo MatchWeb { get; set; }
public IList<string> HasReadLInes { get; set; }
public string Method { get; set; }
public string Host { get; set; }
public string MessageId { get; set; }
public Guid MessageId { get; set; }
}

View File

@ -4,6 +4,7 @@
// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE
// Copyright (c) 2019 Gui.H
using System;
using System.Collections.Generic;
using FastTunnel.Core.Models;
@ -16,6 +17,8 @@ internal interface IFastTunnelFeature
public IList<string> HasReadLInes { get; set; }
public string Method { get; set; }
public string Host { get; set; }
public string MessageId { get; set; }
public Guid MessageId { get; set; }
}

View File

@ -15,6 +15,7 @@ using FastTunnel.Core.Forwarder.Kestrel.Features;
using FastTunnel.Core.Forwarder.Streams;
using FastTunnel.Core.Models.Massage;
using FastTunnel.Core.Protocol;
using FastTunnel.Core.Refs;
using FastTunnel.Core.Server;
using Microsoft.AspNetCore.Connections;
using Microsoft.Extensions.Logging;
@ -74,7 +75,7 @@ internal class ForwarderMiddleware
private async Task waitSwap(ConnectionContext context)
{
var feat = context.Features.Get<IFastTunnelFeature>();
var requestId = Guid.NewGuid().ToString().Replace("-", "");
var requestId = Guid.NewGuid();
Interlocked.Increment(ref UserCount);
@ -162,14 +163,9 @@ internal class ForwarderMiddleware
var closedAwaiter = new TaskCompletionSource<object>();
cancellationTokenSource.Token.Register(() =>
{
closedAwaiter.TrySetCanceled();
});
try
{
await closedAwaiter.Task;
await closedAwaiter.Task.WaitAsync(cancellationTokenSource.Token);
}
catch (Exception)
{

View File

@ -42,7 +42,7 @@ public class ForwardDispatcher
/// <returns></returns>
public async Task DispatchAsync(Socket _socket, WebSocket client)
{
var msgId = Guid.NewGuid().ToString().Replace("-", "");
var msgId = Guid.NewGuid();
(Stream Stream, CancellationTokenSource TokenSource) res = default;
@ -51,10 +51,7 @@ public class ForwardDispatcher
try
{
logger.LogDebug($"[Forward]Swap开始 {msgId}|{_config.RemotePort}=>{_config.LocalIp}:{_config.LocalPort}");
var tcs = new TaskCompletionSource<(Stream Stream, CancellationTokenSource TokenSource)>();
tcs.SetTimeOut(10000, () => { logger.LogDebug($"[Dispatch TimeOut]:{msgId}"); });
if (!_server.ResponseTasks.TryAdd(msgId, tcs))
{
return;
@ -81,11 +78,11 @@ public class ForwardDispatcher
return;
}
res = await tcs.Task;
res = await tcs.Task.WaitAsync(TimeSpan.FromSeconds(5));
//await using var stream2 = new SocketDuplexPipe(_socket);
using var stream2 = new NetworkStream(_socket);
await Task.WhenAny(res.Stream.CopyToAsync(stream2), stream2.CopyToAsync(res.Stream));
await Task.WhenAny(res.Stream.CopyToAsync(stream2), stream2.CopyToAsync(res.Stream)).WaitAsync(res.TokenSource.Token);
}
catch (Exception ex)
{

View File

@ -11,8 +11,5 @@ public class ProtocolConst
public const string FASTTUNNEL_VERSION = "FT_VERSION";
public const string FASTTUNNEL_MSGID = "FT_MSGID";
public const string FASTTUNNEL_TOKEN = "FT_TOKEN";
public const int MAX_CMD_LENGTH = 100;
public const string HTTP_METHOD_SWAP = "PROXY";
}

View File

@ -1,43 +0,0 @@
// Licensed under the Apache License, Version 2.0 (the "License").
// You may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE
// Copyright (c) 2019 Gui.H
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FastTunnel.Core.Extensions;
namespace FastTunnel.Core.Protocol;
public class TunnelProtocol
{
private string massgeTemp;
private readonly string m_sectionFlag = "\n";
public IEnumerable<string> HandleBuffer(byte[] buffer, int offset, int count)
{
var words = buffer.GetString(offset, count);
var sum = massgeTemp + words;
if (sum.Contains(m_sectionFlag))
{
var array = (sum).Split(m_sectionFlag);
massgeTemp = null;
var fullMsg = words.EndsWith(m_sectionFlag);
if (!fullMsg)
{
massgeTemp = array[array.Length - 1];
}
return array.Take(array.Length - 1);
}
else
{
massgeTemp = sum;
return null;
}
}
}

View File

@ -11,12 +11,10 @@ using System.IO.Pipelines;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using FastTunnel.Core.Extensions;
using FastTunnel.Core.Refs;
namespace FastTunnel.Core.Forwarder.Streams;
namespace FastTunnel.Core.Refs;
internal class DuplexPipeStream : System.IO.Stream
internal class DuplexPipeStream : Stream
{
private readonly PipeReader _input;
private readonly PipeWriter _output;

View File

@ -8,7 +8,7 @@ using System.IO.Pipelines;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace FastTunnel.Core.Extensions;
namespace FastTunnel.Core.Refs;
internal static class ValueTaskExtensions
{

View File

@ -23,7 +23,10 @@ public class FastTunnelServer
public readonly IOptionsMonitor<DefaultServerConfig> ServerOption;
private readonly ILogger<FastTunnelServer> logger;
public ConcurrentDictionary<string, TaskCompletionSource<(Stream Stream, CancellationTokenSource Token)>> ResponseTasks { get; } = new();
/// <summary>
/// 待转发列表
/// </summary>
public ConcurrentDictionary<Guid, TaskCompletionSource<(Stream Stream, CancellationTokenSource Token)>> ResponseTasks { get; } = new();
public ConcurrentDictionary<string, WebInfo> WebList { get; private set; } = new();

View File

@ -1,42 +0,0 @@
// Licensed under the Apache License, Version 2.0 (the "License").
// You may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE
// Copyright (c) 2019 Gui.H
using System.Buffers;
using System.IO.Pipelines;
using System.Threading;
using System.Threading.Tasks;
namespace FastTunnel.Core.Utilitys;
internal class SwapUtility
{
IDuplexPipe pipe1;
IDuplexPipe pipe2;
public SwapUtility(IDuplexPipe pipe1, IDuplexPipe pipe2)
{
this.pipe1 = pipe1;
this.pipe2 = pipe2;
}
internal async Task SwapAsync(CancellationToken cancellationToken = default)
{
}
private async Task T1(IDuplexPipe pipe, IDuplexPipe pipe1, CancellationToken cancellationToken = default)
{
while (true)
{
ReadResult result;
ReadOnlySequence<byte> readableBuffer;
result = await pipe.Input.ReadAsync(cancellationToken);
readableBuffer = result.Buffer;
}
}
}