add GlobalListener
This commit is contained in:
parent
a5d79b40db
commit
402b7c5f2a
137
FastGithub.Configuration/GlobalListener.cs
Normal file
137
FastGithub.Configuration/GlobalListener.cs
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
|
||||||
|
namespace FastGithub.Configuration
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 监听器
|
||||||
|
/// </summary>
|
||||||
|
public static class GlobalListener
|
||||||
|
{
|
||||||
|
private static readonly IPGlobalProperties global = IPGlobalProperties.GetIPGlobalProperties();
|
||||||
|
private static readonly HashSet<int> tcpListenPorts = GetListenPorts(global.GetActiveTcpListeners);
|
||||||
|
private static readonly HashSet<int> udpListenPorts = GetListenPorts(global.GetActiveUdpListeners);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ssh端口
|
||||||
|
/// </summary>
|
||||||
|
public static int SshPort { get; } = GetAvailableTcpPort(22);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// git端口
|
||||||
|
/// </summary>
|
||||||
|
public static int GitPort { get; } = GetAvailableTcpPort(9418);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// http端口
|
||||||
|
/// </summary>
|
||||||
|
public static int HttpPort { get; } = OperatingSystem.IsWindows() ? GetAvailableTcpPort(80) : GetAvailableTcpPort(3880);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// https端口
|
||||||
|
/// </summary>
|
||||||
|
public static int HttpsPort { get; } = OperatingSystem.IsWindows() ? GetAvailableTcpPort(443) : GetAvailableTcpPort(38443);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取已监听的端口
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static HashSet<int> GetListenPorts(Func<IPEndPoint[]> func)
|
||||||
|
{
|
||||||
|
var hashSet = new HashSet<int>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var endpoint in func())
|
||||||
|
{
|
||||||
|
hashSet.Add(endpoint.Port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return hashSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是可以监听TCP
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="port"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool CanListenTcp(int port)
|
||||||
|
{
|
||||||
|
return tcpListenPorts.Contains(port) == false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是可以监听UDP
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="port"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool CanListenUdp(int port)
|
||||||
|
{
|
||||||
|
return udpListenPorts.Contains(port) == false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是可以监听TCP和Udp
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="port"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool CanListen(int port)
|
||||||
|
{
|
||||||
|
return CanListenTcp(port) && CanListenUdp(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取可用的随机Tcp端口
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="minPort"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static int GetAvailableTcpPort(int minPort)
|
||||||
|
{
|
||||||
|
return GetAvailablePort(CanListenTcp, minPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取可用的随机Udp端口
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="minPort"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static int GetAvailableUdpPort(int minPort)
|
||||||
|
{
|
||||||
|
return GetAvailablePort(CanListenUdp, minPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取可用的随机端口
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="minPort"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static int GetAvailablePort(int minPort)
|
||||||
|
{
|
||||||
|
return GetAvailablePort(CanListen, minPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取可用端口
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="canFunc"></param>
|
||||||
|
/// <param name="minPort"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="FastGithubException"></exception>
|
||||||
|
private static int GetAvailablePort(Func<int, bool> canFunc, int minPort)
|
||||||
|
{
|
||||||
|
for (var port = minPort; port < IPEndPoint.MaxPort; port++)
|
||||||
|
{
|
||||||
|
if (canFunc(port) == true)
|
||||||
|
{
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new FastGithubException("当前无可用的端口");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,82 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.NetworkInformation;
|
|
||||||
|
|
||||||
namespace FastGithub.Configuration
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 反向代理端口
|
|
||||||
/// </summary>
|
|
||||||
public static class ReverseProxyPort
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// ssh端口
|
|
||||||
/// </summary>
|
|
||||||
public static int Ssh { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// git端口
|
|
||||||
/// </summary>
|
|
||||||
public static int Git { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// http端口
|
|
||||||
/// </summary>
|
|
||||||
public static int Http { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// https端口
|
|
||||||
/// </summary>
|
|
||||||
public static int Https { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 反向代理端口
|
|
||||||
/// </summary>
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 已监听的tcp端口集合
|
|
||||||
/// </summary>
|
|
||||||
private class TcpListenerPortCollection
|
|
||||||
{
|
|
||||||
private readonly HashSet<int> tcpPorts = new();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 已监听的tcp端口集合
|
|
||||||
/// </summary>
|
|
||||||
public TcpListenerPortCollection()
|
|
||||||
{
|
|
||||||
var tcpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners();
|
|
||||||
foreach (var endpoint in tcpListeners)
|
|
||||||
{
|
|
||||||
this.tcpPorts.Add(endpoint.Port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取可用的随机Tcp端口
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="minValue"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public int GetAvailablePort(int minValue)
|
|
||||||
{
|
|
||||||
for (var port = minValue; port < IPEndPoint.MaxPort; port++)
|
|
||||||
{
|
|
||||||
if (this.tcpPorts.Contains(port) == false)
|
|
||||||
{
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new FastGithubException("当前无可用的端口");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +1,10 @@
|
|||||||
using FastGithub.Configuration;
|
using FastGithub.Configuration;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
|
||||||
using System.Net.Sockets;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using static PInvoke.AdvApi32;
|
using static PInvoke.AdvApi32;
|
||||||
@ -75,7 +72,7 @@ namespace FastGithub.DomainResolve
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task StartCoreAsync(CancellationToken cancellationToken)
|
private async Task StartCoreAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var port = GetAvailablePort(IPAddress.Loopback.AddressFamily);
|
var port = GlobalListener.GetAvailablePort(5533);
|
||||||
var localEndPoint = new IPEndPoint(IPAddress.Loopback, port);
|
var localEndPoint = new IPEndPoint(IPAddress.Loopback, port);
|
||||||
|
|
||||||
await TomlUtil.SetListensAsync(this.tomlFilePath, localEndPoint, cancellationToken);
|
await TomlUtil.SetListensAsync(this.tomlFilePath, localEndPoint, cancellationToken);
|
||||||
@ -129,37 +126,6 @@ namespace FastGithub.DomainResolve
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取可用的随机端口
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="addressFamily"></param>
|
|
||||||
/// <param name="min">最小值</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private static int GetAvailablePort(AddressFamily addressFamily, int min = 5533)
|
|
||||||
{
|
|
||||||
var hashSet = new HashSet<int>();
|
|
||||||
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("当前无可用的端口");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 启动DnscryptProxy进程
|
/// 启动DnscryptProxy进程
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -212,13 +212,13 @@ namespace FastGithub.HttpServer
|
|||||||
|
|
||||||
if (targetPort == HTTP_PORT)
|
if (targetPort == HTTP_PORT)
|
||||||
{
|
{
|
||||||
yield return new IPEndPoint(IPAddress.Loopback, ReverseProxyPort.Http);
|
yield return new IPEndPoint(IPAddress.Loopback, GlobalListener.HttpPort);
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetPort == HTTPS_PORT)
|
if (targetPort == HTTPS_PORT)
|
||||||
{
|
{
|
||||||
yield return new IPEndPoint(IPAddress.Loopback, ReverseProxyPort.Https);
|
yield return new IPEndPoint(IPAddress.Loopback, GlobalListener.HttpsPort);
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,8 +7,6 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Net.NetworkInformation;
|
|
||||||
|
|
||||||
namespace FastGithub
|
namespace FastGithub
|
||||||
{
|
{
|
||||||
@ -37,7 +35,7 @@ namespace FastGithub
|
|||||||
var options = kestrel.ApplicationServices.GetRequiredService<IOptions<FastGithubOptions>>().Value;
|
var options = kestrel.ApplicationServices.GetRequiredService<IOptions<FastGithubOptions>>().Value;
|
||||||
var httpProxyPort = options.HttpProxyPort;
|
var httpProxyPort = options.HttpProxyPort;
|
||||||
|
|
||||||
if (CanListenTcp(httpProxyPort) == false)
|
if (GlobalListener.CanListenTcp(httpProxyPort) == false)
|
||||||
{
|
{
|
||||||
throw new FastGithubException($"tcp端口{httpProxyPort}已经被其它进程占用,请在配置文件更换{nameof(FastGithubOptions.HttpProxyPort)}为其它端口");
|
throw new FastGithubException($"tcp端口{httpProxyPort}已经被其它进程占用,请在配置文件更换{nameof(FastGithubOptions.HttpProxyPort)}为其它端口");
|
||||||
}
|
}
|
||||||
@ -53,7 +51,7 @@ namespace FastGithub
|
|||||||
/// <param name="kestrel"></param>
|
/// <param name="kestrel"></param>
|
||||||
public static void ListenSshReverseProxy(this KestrelServerOptions kestrel)
|
public static void ListenSshReverseProxy(this KestrelServerOptions kestrel)
|
||||||
{
|
{
|
||||||
var sshPort = ReverseProxyPort.Ssh;
|
var sshPort = GlobalListener.SshPort;
|
||||||
kestrel.ListenLocalhost(sshPort, listen =>
|
kestrel.ListenLocalhost(sshPort, listen =>
|
||||||
{
|
{
|
||||||
listen.UseFlowAnalyze();
|
listen.UseFlowAnalyze();
|
||||||
@ -69,7 +67,7 @@ namespace FastGithub
|
|||||||
/// <param name="kestrel"></param>
|
/// <param name="kestrel"></param>
|
||||||
public static void ListenGitReverseProxy(this KestrelServerOptions kestrel)
|
public static void ListenGitReverseProxy(this KestrelServerOptions kestrel)
|
||||||
{
|
{
|
||||||
var gitPort = ReverseProxyPort.Git;
|
var gitPort = GlobalListener.GitPort;
|
||||||
kestrel.ListenLocalhost(gitPort, listen =>
|
kestrel.ListenLocalhost(gitPort, listen =>
|
||||||
{
|
{
|
||||||
listen.UseFlowAnalyze();
|
listen.UseFlowAnalyze();
|
||||||
@ -85,7 +83,7 @@ namespace FastGithub
|
|||||||
/// <param name="kestrel"></param>
|
/// <param name="kestrel"></param>
|
||||||
public static void ListenHttpReverseProxy(this KestrelServerOptions kestrel)
|
public static void ListenHttpReverseProxy(this KestrelServerOptions kestrel)
|
||||||
{
|
{
|
||||||
var httpPort = ReverseProxyPort.Http;
|
var httpPort = GlobalListener.HttpPort;
|
||||||
kestrel.ListenLocalhost(httpPort);
|
kestrel.ListenLocalhost(httpPort);
|
||||||
|
|
||||||
if (OperatingSystem.IsWindows())
|
if (OperatingSystem.IsWindows())
|
||||||
@ -105,7 +103,7 @@ namespace FastGithub
|
|||||||
certService.CreateCaCertIfNotExists();
|
certService.CreateCaCertIfNotExists();
|
||||||
certService.InstallAndTrustCaCert();
|
certService.InstallAndTrustCaCert();
|
||||||
|
|
||||||
var httpsPort = ReverseProxyPort.Https;
|
var httpsPort = GlobalListener.HttpsPort;
|
||||||
kestrel.ListenLocalhost(httpsPort, listen =>
|
kestrel.ListenLocalhost(httpsPort, listen =>
|
||||||
{
|
{
|
||||||
if (OperatingSystem.IsWindows())
|
if (OperatingSystem.IsWindows())
|
||||||
@ -135,16 +133,5 @@ namespace FastGithub
|
|||||||
var loggerFactory = kestrel.ApplicationServices.GetRequiredService<ILoggerFactory>();
|
var loggerFactory = kestrel.ApplicationServices.GetRequiredService<ILoggerFactory>();
|
||||||
return loggerFactory.CreateLogger($"{nameof(FastGithub)}.{nameof(HttpServer)}");
|
return loggerFactory.CreateLogger($"{nameof(FastGithub)}.{nameof(HttpServer)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否可以监听指定tcp端口
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="port"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private static bool CanListenTcp(int port)
|
|
||||||
{
|
|
||||||
var tcpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners();
|
|
||||||
return tcpListeners.Any(item => item.Port == port) == false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ namespace FastGithub.PacketIntercept.Tcp
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger"></param>
|
/// <param name="logger"></param>
|
||||||
public GitInterceptor(ILogger<HttpInterceptor> logger)
|
public GitInterceptor(ILogger<HttpInterceptor> logger)
|
||||||
: base(9418, ReverseProxyPort.Git, logger)
|
: base(9418, GlobalListener.GitPort, logger)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ namespace FastGithub.PacketIntercept.Tcp
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger"></param>
|
/// <param name="logger"></param>
|
||||||
public HttpInterceptor(ILogger<HttpInterceptor> logger)
|
public HttpInterceptor(ILogger<HttpInterceptor> logger)
|
||||||
: base(80, ReverseProxyPort.Http, logger)
|
: base(80, GlobalListener.HttpPort, logger)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ namespace FastGithub.PacketIntercept.Tcp
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger"></param>
|
/// <param name="logger"></param>
|
||||||
public HttpsInterceptor(ILogger<HttpsInterceptor> logger)
|
public HttpsInterceptor(ILogger<HttpsInterceptor> logger)
|
||||||
: base(443, ReverseProxyPort.Https, logger)
|
: base(443, GlobalListener.HttpsPort, logger)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ namespace FastGithub.PacketIntercept.Tcp
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger"></param>
|
/// <param name="logger"></param>
|
||||||
public SshInterceptor(ILogger<HttpInterceptor> logger)
|
public SshInterceptor(ILogger<HttpInterceptor> logger)
|
||||||
: base(22, ReverseProxyPort.Ssh, logger)
|
: base(22, GlobalListener.SshPort, logger)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user