mirror of
https://github.com/FastTunnel/FastTunnel.git
synced 2025-02-08 02:39:29 +08:00
1
This commit is contained in:
parent
d22084f6ce
commit
401276cb6a
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
110
FastTunnel.Core/Forwarder/Kestrel/ClientConnectionMiddleware.cs
Normal file
110
FastTunnel.Core/Forwarder/Kestrel/ClientConnectionMiddleware.cs
Normal 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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FastTunnel.Core.Models
|
||||
namespace FastTunnel.Core.Models.Massage
|
||||
{
|
||||
public class LogInMassage : TunnelMassage
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user