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 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
|
||||
/// <returns></returns>
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// 启动DnscryptProxy进程
|
||||
/// </summary>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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<IOptions<FastGithubOptions>>().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
|
||||
/// <param name="kestrel"></param>
|
||||
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
|
||||
/// <param name="kestrel"></param>
|
||||
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
|
||||
/// <param name="kestrel"></param>
|
||||
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<ILoggerFactory>();
|
||||
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>
|
||||
/// <param name="logger"></param>
|
||||
public GitInterceptor(ILogger<HttpInterceptor> logger)
|
||||
: base(9418, ReverseProxyPort.Git, logger)
|
||||
: base(9418, GlobalListener.GitPort, logger)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ namespace FastGithub.PacketIntercept.Tcp
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
public HttpInterceptor(ILogger<HttpInterceptor> logger)
|
||||
: base(80, ReverseProxyPort.Http, logger)
|
||||
: base(80, GlobalListener.HttpPort, logger)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ namespace FastGithub.PacketIntercept.Tcp
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
public HttpsInterceptor(ILogger<HttpsInterceptor> logger)
|
||||
: base(443, ReverseProxyPort.Https, logger)
|
||||
: base(443, GlobalListener.HttpsPort, logger)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ namespace FastGithub.PacketIntercept.Tcp
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
public SshInterceptor(ILogger<HttpInterceptor> logger)
|
||||
: base(22, ReverseProxyPort.Ssh, logger)
|
||||
: base(22, GlobalListener.SshPort, logger)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user