From 402b7c5f2a3d9c40264ced6155f954d2d7ed6043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=9B=BD=E4=BC=9F?= <366193849@qq.com> Date: Thu, 25 Nov 2021 11:37:55 +0800 Subject: [PATCH] add GlobalListener --- FastGithub.Configuration/GlobalListener.cs | 137 ++++++++++++++++++ FastGithub.Configuration/ReverseProxyPort.cs | 82 ----------- FastGithub.DomainResolve/DnscryptProxy.cs | 36 +---- FastGithub.HttpServer/HttpProxyMiddleware.cs | 4 +- .../KestrelServerOptionsExtensions.cs | 23 +-- .../Tcp/GitInterceptor.cs | 2 +- .../Tcp/HttpInterceptor.cs | 2 +- .../Tcp/HttpsInterceptor.cs | 2 +- .../Tcp/SshInterceptor.cs | 2 +- 9 files changed, 149 insertions(+), 141 deletions(-) create mode 100644 FastGithub.Configuration/GlobalListener.cs delete mode 100644 FastGithub.Configuration/ReverseProxyPort.cs diff --git a/FastGithub.Configuration/GlobalListener.cs b/FastGithub.Configuration/GlobalListener.cs new file mode 100644 index 0000000..9724f05 --- /dev/null +++ b/FastGithub.Configuration/GlobalListener.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.NetworkInformation; + +namespace FastGithub.Configuration +{ + /// + /// 监听器 + /// + public static class GlobalListener + { + private static readonly IPGlobalProperties global = IPGlobalProperties.GetIPGlobalProperties(); + private static readonly HashSet tcpListenPorts = GetListenPorts(global.GetActiveTcpListeners); + private static readonly HashSet udpListenPorts = GetListenPorts(global.GetActiveUdpListeners); + + /// + /// ssh端口 + /// + public static int SshPort { get; } = GetAvailableTcpPort(22); + + /// + /// git端口 + /// + public static int GitPort { get; } = GetAvailableTcpPort(9418); + + /// + /// http端口 + /// + public static int HttpPort { get; } = OperatingSystem.IsWindows() ? GetAvailableTcpPort(80) : GetAvailableTcpPort(3880); + + /// + /// https端口 + /// + public static int HttpsPort { get; } = OperatingSystem.IsWindows() ? GetAvailableTcpPort(443) : GetAvailableTcpPort(38443); + + /// + /// 获取已监听的端口 + /// + /// + /// + private static HashSet GetListenPorts(Func func) + { + var hashSet = new HashSet(); + try + { + foreach (var endpoint in func()) + { + hashSet.Add(endpoint.Port); + } + } + catch (Exception) + { + } + return hashSet; + } + + /// + /// 是可以监听TCP + /// + /// + /// + public static bool CanListenTcp(int port) + { + return tcpListenPorts.Contains(port) == false; + } + + /// + /// 是可以监听UDP + /// + /// + /// + public static bool CanListenUdp(int port) + { + return udpListenPorts.Contains(port) == false; + } + + /// + /// 是可以监听TCP和Udp + /// + /// + /// + public static bool CanListen(int port) + { + return CanListenTcp(port) && CanListenUdp(port); + } + + /// + /// 获取可用的随机Tcp端口 + /// + /// + /// + public static int GetAvailableTcpPort(int minPort) + { + return GetAvailablePort(CanListenTcp, minPort); + } + + /// + /// 获取可用的随机Udp端口 + /// + /// + /// + public static int GetAvailableUdpPort(int minPort) + { + return GetAvailablePort(CanListenUdp, minPort); + } + + /// + /// 获取可用的随机端口 + /// + /// + /// + public static int GetAvailablePort(int minPort) + { + return GetAvailablePort(CanListen, minPort); + } + + /// + /// 获取可用端口 + /// + /// + /// + /// + /// + private static int GetAvailablePort(Func canFunc, int minPort) + { + for (var port = minPort; port < IPEndPoint.MaxPort; port++) + { + if (canFunc(port) == true) + { + return port; + } + } + throw new FastGithubException("当前无可用的端口"); + } + } +} diff --git a/FastGithub.Configuration/ReverseProxyPort.cs b/FastGithub.Configuration/ReverseProxyPort.cs deleted file mode 100644 index 488d27d..0000000 --- a/FastGithub.Configuration/ReverseProxyPort.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.NetworkInformation; - -namespace FastGithub.Configuration -{ - /// - /// 反向代理端口 - /// - public static class ReverseProxyPort - { - /// - /// ssh端口 - /// - public static int Ssh { get; } - - /// - /// git端口 - /// - public static int Git { get; } - - /// - /// http端口 - /// - public static int Http { get; } - - /// - /// https端口 - /// - public static int Https { get; } - - /// - /// 反向代理端口 - /// - static ReverseProxyPort() - { - var ports = new TcpListenerPortCollection(); - Ssh = ports.GetAvailablePort(22); - Git = ports.GetAvailablePort(9418); - Http = OperatingSystem.IsWindows() ? ports.GetAvailablePort(80) : ports.GetAvailablePort(3880); - Https = OperatingSystem.IsWindows() ? ports.GetAvailablePort(443) : ports.GetAvailablePort(38443); - } - - /// - /// 已监听的tcp端口集合 - /// - private class TcpListenerPortCollection - { - private readonly HashSet tcpPorts = new(); - - /// - /// 已监听的tcp端口集合 - /// - public TcpListenerPortCollection() - { - var tcpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners(); - foreach (var endpoint in tcpListeners) - { - this.tcpPorts.Add(endpoint.Port); - } - } - - /// - /// 获取可用的随机Tcp端口 - /// - /// - /// - public int GetAvailablePort(int minValue) - { - for (var port = minValue; port < IPEndPoint.MaxPort; port++) - { - if (this.tcpPorts.Contains(port) == false) - { - return port; - } - } - throw new FastGithubException("当前无可用的端口"); - } - } - } -} diff --git a/FastGithub.DomainResolve/DnscryptProxy.cs b/FastGithub.DomainResolve/DnscryptProxy.cs index 98afa7f..6fd6207 100644 --- a/FastGithub.DomainResolve/DnscryptProxy.cs +++ b/FastGithub.DomainResolve/DnscryptProxy.cs @@ -1,13 +1,10 @@ using FastGithub.Configuration; using Microsoft.Extensions.Logging; using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; -using System.Net.NetworkInformation; -using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using static PInvoke.AdvApi32; @@ -75,7 +72,7 @@ namespace FastGithub.DomainResolve /// private async Task StartCoreAsync(CancellationToken cancellationToken) { - var port = GetAvailablePort(IPAddress.Loopback.AddressFamily); + var port = GlobalListener.GetAvailablePort(5533); var localEndPoint = new IPEndPoint(IPAddress.Loopback, port); await TomlUtil.SetListensAsync(this.tomlFilePath, localEndPoint, cancellationToken); @@ -129,37 +126,6 @@ namespace FastGithub.DomainResolve } } - /// - /// 获取可用的随机端口 - /// - /// - /// 最小值 - /// - private static int GetAvailablePort(AddressFamily addressFamily, int min = 5533) - { - var hashSet = new HashSet(); - var tcpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners(); - var udpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners(); - - foreach (var endPoint in tcpListeners.Concat(udpListeners)) - { - if (endPoint.AddressFamily == addressFamily) - { - hashSet.Add(endPoint.Port); - } - } - - for (var port = min; port < IPEndPoint.MaxPort; port++) - { - if (hashSet.Contains(port) == false) - { - return port; - } - } - - throw new FastGithubException("当前无可用的端口"); - } - /// /// 启动DnscryptProxy进程 /// diff --git a/FastGithub.HttpServer/HttpProxyMiddleware.cs b/FastGithub.HttpServer/HttpProxyMiddleware.cs index b58b526..230e7f3 100644 --- a/FastGithub.HttpServer/HttpProxyMiddleware.cs +++ b/FastGithub.HttpServer/HttpProxyMiddleware.cs @@ -212,13 +212,13 @@ namespace FastGithub.HttpServer if (targetPort == HTTP_PORT) { - yield return new IPEndPoint(IPAddress.Loopback, ReverseProxyPort.Http); + yield return new IPEndPoint(IPAddress.Loopback, GlobalListener.HttpPort); yield break; } if (targetPort == HTTPS_PORT) { - yield return new IPEndPoint(IPAddress.Loopback, ReverseProxyPort.Https); + yield return new IPEndPoint(IPAddress.Loopback, GlobalListener.HttpsPort); yield break; } diff --git a/FastGithub.HttpServer/KestrelServerOptionsExtensions.cs b/FastGithub.HttpServer/KestrelServerOptionsExtensions.cs index f9b890f..a9d46c7 100644 --- a/FastGithub.HttpServer/KestrelServerOptionsExtensions.cs +++ b/FastGithub.HttpServer/KestrelServerOptionsExtensions.cs @@ -7,8 +7,6 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; -using System.Linq; -using System.Net.NetworkInformation; namespace FastGithub { @@ -37,7 +35,7 @@ namespace FastGithub var options = kestrel.ApplicationServices.GetRequiredService>().Value; var httpProxyPort = options.HttpProxyPort; - if (CanListenTcp(httpProxyPort) == false) + if (GlobalListener.CanListenTcp(httpProxyPort) == false) { throw new FastGithubException($"tcp端口{httpProxyPort}已经被其它进程占用,请在配置文件更换{nameof(FastGithubOptions.HttpProxyPort)}为其它端口"); } @@ -53,7 +51,7 @@ namespace FastGithub /// public static void ListenSshReverseProxy(this KestrelServerOptions kestrel) { - var sshPort = ReverseProxyPort.Ssh; + var sshPort = GlobalListener.SshPort; kestrel.ListenLocalhost(sshPort, listen => { listen.UseFlowAnalyze(); @@ -69,7 +67,7 @@ namespace FastGithub /// public static void ListenGitReverseProxy(this KestrelServerOptions kestrel) { - var gitPort = ReverseProxyPort.Git; + var gitPort = GlobalListener.GitPort; kestrel.ListenLocalhost(gitPort, listen => { listen.UseFlowAnalyze(); @@ -85,7 +83,7 @@ namespace FastGithub /// public static void ListenHttpReverseProxy(this KestrelServerOptions kestrel) { - var httpPort = ReverseProxyPort.Http; + var httpPort = GlobalListener.HttpPort; kestrel.ListenLocalhost(httpPort); if (OperatingSystem.IsWindows()) @@ -105,7 +103,7 @@ namespace FastGithub certService.CreateCaCertIfNotExists(); certService.InstallAndTrustCaCert(); - var httpsPort = ReverseProxyPort.Https; + var httpsPort = GlobalListener.HttpsPort; kestrel.ListenLocalhost(httpsPort, listen => { if (OperatingSystem.IsWindows()) @@ -135,16 +133,5 @@ namespace FastGithub var loggerFactory = kestrel.ApplicationServices.GetRequiredService(); return loggerFactory.CreateLogger($"{nameof(FastGithub)}.{nameof(HttpServer)}"); } - - /// - /// 是否可以监听指定tcp端口 - /// - /// - /// - private static bool CanListenTcp(int port) - { - var tcpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners(); - return tcpListeners.Any(item => item.Port == port) == false; - } } } diff --git a/FastGithub.PacketIntercept/Tcp/GitInterceptor.cs b/FastGithub.PacketIntercept/Tcp/GitInterceptor.cs index fb2597b..d9a3cda 100644 --- a/FastGithub.PacketIntercept/Tcp/GitInterceptor.cs +++ b/FastGithub.PacketIntercept/Tcp/GitInterceptor.cs @@ -15,7 +15,7 @@ namespace FastGithub.PacketIntercept.Tcp /// /// public GitInterceptor(ILogger logger) - : base(9418, ReverseProxyPort.Git, logger) + : base(9418, GlobalListener.GitPort, logger) { } } diff --git a/FastGithub.PacketIntercept/Tcp/HttpInterceptor.cs b/FastGithub.PacketIntercept/Tcp/HttpInterceptor.cs index 88c99f9..6da13b2 100644 --- a/FastGithub.PacketIntercept/Tcp/HttpInterceptor.cs +++ b/FastGithub.PacketIntercept/Tcp/HttpInterceptor.cs @@ -15,7 +15,7 @@ namespace FastGithub.PacketIntercept.Tcp /// /// public HttpInterceptor(ILogger logger) - : base(80, ReverseProxyPort.Http, logger) + : base(80, GlobalListener.HttpPort, logger) { } } diff --git a/FastGithub.PacketIntercept/Tcp/HttpsInterceptor.cs b/FastGithub.PacketIntercept/Tcp/HttpsInterceptor.cs index 45157fa..c300a43 100644 --- a/FastGithub.PacketIntercept/Tcp/HttpsInterceptor.cs +++ b/FastGithub.PacketIntercept/Tcp/HttpsInterceptor.cs @@ -15,7 +15,7 @@ namespace FastGithub.PacketIntercept.Tcp /// /// public HttpsInterceptor(ILogger logger) - : base(443, ReverseProxyPort.Https, logger) + : base(443, GlobalListener.HttpsPort, logger) { } } diff --git a/FastGithub.PacketIntercept/Tcp/SshInterceptor.cs b/FastGithub.PacketIntercept/Tcp/SshInterceptor.cs index f74715f..9a39597 100644 --- a/FastGithub.PacketIntercept/Tcp/SshInterceptor.cs +++ b/FastGithub.PacketIntercept/Tcp/SshInterceptor.cs @@ -15,7 +15,7 @@ namespace FastGithub.PacketIntercept.Tcp /// /// public SshInterceptor(ILogger logger) - : base(22, ReverseProxyPort.Ssh, logger) + : base(22, GlobalListener.SshPort, logger) { } }