This commit is contained in:
Gui.H 2022-05-03 09:34:54 +08:00
parent d22084f6ce
commit 401276cb6a
22 changed files with 177 additions and 68 deletions

View File

@ -8,9 +8,9 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using Microsoft.AspNetCore.Builder;
using FastTunnel.Core;
using Microsoft.Extensions.Configuration;
using Serilog;
using FastTunnel.Core.Extensions;
namespace FastTunnel.Client;

View File

@ -1,4 +1,4 @@
// Licensed under the Apache License, Version 2.0 (the "License").
// 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
@ -16,6 +16,7 @@ using FastTunnel.Core.Handlers.Client;
using Microsoft.Extensions.Options;
using System.Net.WebSockets;
using FastTunnel.Core.Utilitys;
using FastTunnel.Core.Models.Massage;
namespace FastTunnel.Core.Client
{

View File

@ -10,7 +10,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FastTunnel.Core.Client;
using FastTunnel.Core.Forwarder.MiddleWare;
using FastTunnel.Core.Forwarder.Kestrel;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@ -19,13 +19,17 @@ namespace FastTunnel.Core.Extensions;
public static class ListenOptionsSwapExtensions
{
public static ListenOptions UseFastTunnelSwap(this ListenOptions listenOptions)
public static ListenOptions UseConnectionFastTunnel(this ListenOptions listenOptions)
{
var loggerFactory = listenOptions.KestrelServerOptions.ApplicationServices.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger<SwapConnectionMiddleware>();
var loggerClient = loggerFactory.CreateLogger<ClientConnectionMiddleware>();
var fastTunnelServer = listenOptions.KestrelServerOptions.ApplicationServices.GetRequiredService<FastTunnelServer>();
listenOptions.Use(next => new SwapConnectionMiddleware(next, logger, fastTunnelServer).OnConnectionAsync);
// 登录频率低,放在后面
//listenOptions.Use(next => new ClientConnectionMiddleware(next, loggerClient, fastTunnelServer).OnConnectionAsync);
return listenOptions;
}
}

View File

@ -9,12 +9,10 @@ using FastTunnel.Core.Config;
using FastTunnel.Core.Forwarder.MiddleWare;
using FastTunnel.Core.Forwarder;
using FastTunnel.Core.Handlers.Client;
using FastTunnel.Core.MiddleWares;
using FastTunnel.Core.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Yarp.ReverseProxy.Forwarder;
using Yarp.Sample;
using Microsoft.AspNetCore.Builder;
using FastTunnel.Core.Filters;
using Microsoft.AspNetCore.Mvc.Filters;
@ -26,7 +24,7 @@ using System.Threading.Tasks;
using System.Threading;
using Microsoft.AspNetCore.Http;
namespace FastTunnel.Core
namespace FastTunnel.Core.Extensions
{
public static class ServicesExtensions
{
@ -78,7 +76,6 @@ namespace FastTunnel.Core
var swapHandler = app.ApplicationServices.GetRequiredService<FastTunnelSwapHandler>();
var clientHandler = app.ApplicationServices.GetRequiredService<FastTunnelClientHandler>();
app.Use(clientHandler.Handle);
app.Use(swapHandler.Handle);
}
public static void MapFastTunnelServer(this IEndpointRouteBuilder endpoints)

View File

@ -5,6 +5,7 @@
// Copyright (c) 2019 Gui.H
using FastTunnel.Core.Models;
using FastTunnel.Core.Models.Massage;
using System;
using System.Collections.Generic;
using System.Net.Sockets;

View File

@ -1,4 +1,4 @@
// Copyright (c) 2019-2022 Gui.H. https://github.com/FastTunnel/FastTunnel
// Copyright (c) 2019-2022 Gui.H. https://github.com/FastTunnel/FastTunnel
// The FastTunnel licenses this file to you under the Apache License Version 2.0.
// For more details,You may obtain License file at: https://github.com/FastTunnel/FastTunnel/blob/v2/LICENSE
@ -48,8 +48,9 @@ namespace FastTunnel.Core.Forwarder
var res = await proxyAsync(host, context, cancellationToken);
return res;
}
catch (Exception)
catch (Exception ex)
{
logger.LogError(ex, "ConnectCallback Error");
throw;
}
}

View File

@ -1,17 +0,0 @@
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();
}
}
}

View File

@ -9,7 +9,7 @@ using Microsoft.Extensions.Primitives;
using Yarp.ReverseProxy.Configuration;
using System.Linq;
namespace Yarp.Sample
namespace FastTunnel.Core.Forwarder
{
/// <summary>
/// Extends the IReverseProxyBuilder to support the InMemoryConfigProvider

View File

@ -0,0 +1,110 @@
// 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.Buffers;
using System.Collections.Generic;
using System.IO.Pipelines;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FastTunnel.Core.Client;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Connections.Features;
using Microsoft.Extensions.Logging;
namespace FastTunnel.Core.Forwarder.Kestrel;
internal class ClientConnectionMiddleware
{
readonly ConnectionDelegate next;
readonly ILogger<ClientConnectionMiddleware> logger;
FastTunnelServer fastTunnelServer;
public ClientConnectionMiddleware(ConnectionDelegate next, ILogger<ClientConnectionMiddleware> logger, FastTunnelServer fastTunnelServer)
{
this.next = next;
this.logger = logger;
this.fastTunnelServer = fastTunnelServer;
}
internal async Task OnConnectionAsync(ConnectionContext context)
{
var oldTransport = context.Transport;
try
{
if (!await ReadPipeAsync(context))
{
await next(context);
}
await next(context);
}
finally
{
context.Transport = oldTransport;
}
}
async Task<bool> ReadPipeAsync(ConnectionContext context)
{
var reader = context.Transport.Input;
var isProxy = false;
while (true)
{
var result = await reader.ReadAsync();
var buffer = result.Buffer;
SequencePosition? position = null;
do
{
position = buffer.PositionOf((byte)'\n');
if (position != null)
{
isProxy = ProcessProxyLine(buffer.Slice(0, position.Value));
if (isProxy)
{
await Login(buffer, position.Value, context);
return true;
}
else
{
context.Transport.Input.AdvanceTo(buffer.Start, buffer.Start);
return false;
}
}
}
while (position != null);
if (result.IsCompleted)
{
break;
}
}
return false;
}
private async Task Login(ReadOnlySequence<byte> buffer, SequencePosition position, ConnectionContext context)
{
}
/// <summary>
///
/// </summary>
/// <param name="readOnlySequence"></param>
private bool ProcessProxyLine(ReadOnlySequence<byte> readOnlySequence)
{
var str = Encoding.UTF8.GetString(readOnlySequence);
return str.StartsWith("LOGIN");
}
}

View File

@ -12,11 +12,12 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FastTunnel.Core.Client;
using FastTunnel.Core.Forwarder.MiddleWare;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Connections.Features;
using Microsoft.Extensions.Logging;
namespace FastTunnel.Core.Forwarder.MiddleWare;
namespace FastTunnel.Core.Forwarder.Kestrel;
internal class SwapConnectionMiddleware
{
@ -35,30 +36,21 @@ internal class SwapConnectionMiddleware
{
var oldTransport = context.Transport;
try
if (!await ReadPipeAsync(context))
{
if (!await ReadPipeAsync(context))
{
await next(context);
}
await next(context);
}
finally
{
context.Transport = oldTransport;
}
}
async Task<bool> ReadPipeAsync(ConnectionContext context)
{
var reader = context.Transport.Input;
bool isProxy = false;
var isProxy = false;
while (true)
{
ReadResult result = await reader.ReadAsync();
ReadOnlySequence<byte> buffer = result.Buffer;
var result = await reader.ReadAsync();
var buffer = result.Buffer;
SequencePosition? position = null;
do
@ -121,9 +113,20 @@ internal class SwapConnectionMiddleware
(task as TaskCompletionSource<object>).SetResult(null);
}, closedAwaiter);
await closedAwaiter.Task;
logger.LogDebug($"[PROXY]:Closed {requestId}");
try
{
await closedAwaiter.Task;
}
catch (Exception ex)
{
logger.LogError(ex, "");
}
finally
{
context.Transport.Input.Complete();
context.Transport.Output.Complete();
logger.LogInformation($"=====================Swap End:{requestId}================== ");
}
}
/// <summary>

View File

@ -122,8 +122,12 @@ internal class DuplexPipeStream : Stream
{
while (true)
{
var result = await _input.ReadAsync(cancellationToken);
var readableBuffer = result.Buffer;
ReadResult result;
ReadOnlySequence<byte> readableBuffer;
result = await _input.ReadAsync(cancellationToken);
readableBuffer = result.Buffer;
try
{
if (_throwOnCancelled && result.IsCanceled && _cancelCalled)
@ -138,10 +142,6 @@ internal class DuplexPipeStream : Stream
// buffer.Count is int
var count = (int)Math.Min(readableBuffer.Length, destination.Length);
readableBuffer = readableBuffer.Slice(0, count);
var str = Encoding.UTF8.GetString(readableBuffer);
Console.WriteLine($"[ReadAsyncInternal]:{str}");
readableBuffer.CopyTo(destination.Span);
return count;
}

View File

@ -1,4 +1,4 @@
// Copyright (c) 2019-2022 Gui.H. https://github.com/FastTunnel/FastTunnel
// Copyright (c) 2019-2022 Gui.H. https://github.com/FastTunnel/FastTunnel
// The FastTunnel licenses this file to you under the Apache License Version 2.0.
// For more details,You may obtain License file at: https://github.com/FastTunnel/FastTunnel/blob/v2/LICENSE
@ -13,7 +13,7 @@ using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
namespace FastTunnel.Core.MiddleWares
namespace FastTunnel.Core.Forwarder.MiddleWare
{
public class FastTunnelClientHandler
{
@ -91,7 +91,7 @@ namespace FastTunnel.Core.MiddleWares
private bool checkToken(HttpContext context)
{
bool checkToken = false;
var checkToken = false;
if (fastTunnelServer.ServerOption.CurrentValue.Tokens != null && fastTunnelServer.ServerOption.CurrentValue.Tokens.Count != 0)
{
checkToken = true;

View File

@ -1,6 +1,5 @@
using FastTunnel.Core.Client;
using FastTunnel.Core.Client;
using FastTunnel.Core.Extensions;
using FastTunnel.Core.MiddleWares;
using Microsoft.AspNetCore.Connections.Features;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

View File

@ -38,7 +38,18 @@ namespace FastTunnel.Core.Handlers.Client
var taskX = serverStream.CopyToAsync(localStream, cancellationToken);
var taskY = localStream.CopyToAsync(serverStream, cancellationToken);
await Task.WhenAny(taskX, taskY);
try
{
await Task.WhenAll(taskX, taskY);
}
catch (Exception ex)
{
}
finally
{
_logger.LogError($"=====================Swap End:{requestId}================== ");
}
}
}
catch (Exception ex)
@ -66,6 +77,8 @@ namespace FastTunnel.Core.Handlers.Client
}
var reverse = $"PROXY /{requestId} HTTP/1.1\r\n";
//var reverse = $"PROXY /{requestId} HTTP/1.1\r\nHost: {cleint.Server.ServerAddr}:{cleint.Server.ServerPort}\r\n\r\n";
var requestMsg = Encoding.UTF8.GetBytes(reverse);
await serverStream.WriteAsync(requestMsg, cancellationToken);
return serverStream;

View File

@ -5,7 +5,6 @@
// Copyright (c) 2019 Gui.H
using FastTunnel.Core.Client;
using FastTunnel.Core.Dispatchers;
using FastTunnel.Core.Exceptions;
using FastTunnel.Core.Extensions;
using FastTunnel.Core.Models;
@ -21,7 +20,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace FastTunnel.Core.Dispatchers
namespace FastTunnel.Core.Handlers.Server
{
public class ForwardDispatcher
{

View File

@ -13,7 +13,7 @@ using System.Net.WebSockets;
using System.Text;
using System.Threading.Tasks;
namespace FastTunnel.Core.Handlers
namespace FastTunnel.Core.Handlers.Server
{
public interface IClientMessageHandler
{

View File

@ -5,10 +5,11 @@
// Copyright (c) 2019 Gui.H
using FastTunnel.Core.Client;
using FastTunnel.Core.Dispatchers;
using FastTunnel.Core.Extensions;
using FastTunnel.Core.Forwarder;
using FastTunnel.Core.Listener;
using FastTunnel.Core.Models;
using FastTunnel.Core.Models.Massage;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
@ -16,7 +17,6 @@ using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Yarp.ReverseProxy.Configuration;
using Yarp.Sample;
namespace FastTunnel.Core.Handlers.Server
{

View File

@ -4,7 +4,7 @@
// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE
// Copyright (c) 2019 Gui.H
using FastTunnel.Core.Dispatchers;
using FastTunnel.Core.Handlers.Server;
using Microsoft.Extensions.Logging;
using System;
using System.Net;

View File

@ -6,7 +6,7 @@
using System.Collections.Generic;
namespace FastTunnel.Core.Models
namespace FastTunnel.Core.Models.Massage
{
public class LogInMassage : TunnelMassage
{

View File

@ -4,7 +4,7 @@
// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE
// Copyright (c) 2019 Gui.H
namespace FastTunnel.Core.Models
namespace FastTunnel.Core.Models.Massage
{
public class TunnelMassage
{

View File

@ -65,8 +65,7 @@ public class Program
var basePort = context.Configuration.GetValue<int?>("BASE_PORT") ?? 1270;
options.ListenAnyIP(basePort, listenOptions =>
{
//listenOptions.UseConnectionLogging();
listenOptions.UseFastTunnelSwap();
listenOptions.UseConnectionFastTunnel();
});
});

View File

@ -4,7 +4,6 @@
// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE
// Copyright (c) 2019 Gui.H
using FastTunnel.Core;
using FastTunnel.Core.Extensions;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;