From 09ee688ba07bf112ba85010e106b8ae3d1888cb7 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, 22 Jul 2021 15:00:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84DnscryptProxy=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DnscryptProxyHostedService.cs | 73 +++-------- .../DnscryptProxyService.cs | 116 ++++++++++++++++++ ...nscryptProxyServiceCollectionExtensions.cs | 4 +- FastGithub.Dns.DnscryptProxy/TomlUtil.cs | 78 ++++++++++++ FastGithub.Upgrade/ReverseProxyHttpHandler.cs | 5 +- FastGithub/FastGithub.csproj | 75 ++++++----- 6 files changed, 253 insertions(+), 98 deletions(-) create mode 100644 FastGithub.Dns.DnscryptProxy/DnscryptProxyService.cs create mode 100644 FastGithub.Dns.DnscryptProxy/TomlUtil.cs diff --git a/FastGithub.Dns.DnscryptProxy/DnscryptProxyHostedService.cs b/FastGithub.Dns.DnscryptProxy/DnscryptProxyHostedService.cs index 19fe7af..f5b34b0 100644 --- a/FastGithub.Dns.DnscryptProxy/DnscryptProxyHostedService.cs +++ b/FastGithub.Dns.DnscryptProxy/DnscryptProxyHostedService.cs @@ -1,8 +1,6 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System; -using System.Diagnostics; -using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -14,15 +12,19 @@ namespace FastGithub.Dns.DnscryptProxy sealed class DnscryptProxyHostedService : BackgroundService { private bool isStopped = false; - private const string dnscryptProxyFile = "dnscrypt-proxy"; + private readonly DnscryptProxyService dnscryptProxyService; private readonly ILogger logger; /// /// DnscryptProxy后台服务 /// + /// /// - public DnscryptProxyHostedService(ILogger logger) + public DnscryptProxyHostedService( + DnscryptProxyService dnscryptProxyService, + ILogger logger) { + this.dnscryptProxyService = dnscryptProxyService; this.logger = logger; } @@ -31,27 +33,19 @@ namespace FastGithub.Dns.DnscryptProxy /// /// /// - public override Task StartAsync(CancellationToken cancellationToken) + public override async Task StartAsync(CancellationToken cancellationToken) { try { - if (OperatingSystem.IsWindows()) - { - StartDnscryptProxy("-service install", waitForExit: true); - StartDnscryptProxy("-service start", waitForExit: true); - } - else - { - StartDnscryptProxy(string.Empty, waitForExit: false); - } - this.logger.LogInformation($"{dnscryptProxyFile}启动成功"); + await this.dnscryptProxyService.StartAsync(cancellationToken); + this.logger.LogInformation($"{this.dnscryptProxyService}启动成功"); } catch (Exception ex) { - this.logger.LogWarning($"{dnscryptProxyFile}启动失败:{ex.Message}"); + this.logger.LogWarning($"{this.dnscryptProxyService}启动失败:{ex.Message}"); } - return base.StartAsync(cancellationToken); + await base.StartAsync(cancellationToken); } /// @@ -63,14 +57,10 @@ namespace FastGithub.Dns.DnscryptProxy { await Task.Yield(); - var process = Process.GetProcessesByName(dnscryptProxyFile).FirstOrDefault(); - if (process != null) - { - process.WaitForExit(); - } + this.dnscryptProxyService.WaitForExit(); if (this.isStopped == false) { - this.logger.LogCritical($"{dnscryptProxyFile}已停止运行,{nameof(FastGithub)}将无法解析域名。你可以把配置文件的{nameof(FastGithubOptions.PureDns)}修改为其它可用的DNS以临时使用。"); + this.logger.LogCritical($"{this.dnscryptProxyService}已停止运行,{nameof(FastGithub)}将无法解析域名。你可以把配置文件的{nameof(FastGithubOptions.PureDns)}修改为其它可用的DNS以临时使用。"); } } @@ -84,45 +74,14 @@ namespace FastGithub.Dns.DnscryptProxy try { this.isStopped = true; - if (OperatingSystem.IsWindows()) - { - StartDnscryptProxy("-service stop", waitForExit: true); - StartDnscryptProxy("-service uninstall", waitForExit: true); - } - - foreach (var process in Process.GetProcessesByName(dnscryptProxyFile)) - { - process.Kill(); - } - this.logger.LogInformation($"{dnscryptProxyFile}已停止"); + this.dnscryptProxyService.Stop(); + this.logger.LogInformation($"{this.dnscryptProxyService}已停止"); } catch (Exception ex) { - this.logger.LogWarning($"{dnscryptProxyFile}停止失败:{ex.Message}"); + this.logger.LogWarning($"{this.dnscryptProxyService}停止失败:{ex.Message}"); } return base.StopAsync(cancellationToken); } - - /// - /// 启动DnscryptProxy进程 - /// - /// - /// - private static void StartDnscryptProxy(string arguments, bool waitForExit) - { - var process = Process.Start(new ProcessStartInfo - { - FileName = OperatingSystem.IsWindows() ? $"{dnscryptProxyFile}.exe" : dnscryptProxyFile, - Arguments = arguments, - UseShellExecute = true, - CreateNoWindow = true, - WindowStyle = ProcessWindowStyle.Hidden - }); - - if (waitForExit && process != null) - { - process.WaitForExit(); - } - } } } diff --git a/FastGithub.Dns.DnscryptProxy/DnscryptProxyService.cs b/FastGithub.Dns.DnscryptProxy/DnscryptProxyService.cs new file mode 100644 index 0000000..d6be7d6 --- /dev/null +++ b/FastGithub.Dns.DnscryptProxy/DnscryptProxyService.cs @@ -0,0 +1,116 @@ +using System; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace FastGithub.Dns.DnscryptProxy +{ + /// + /// DnscryptProxy服务 + /// + sealed class DnscryptProxyService + { + private readonly FastGithubConfig fastGithubConfig; + + /// + /// 获取文件名 + /// + public string Name => "dnscrypt-proxy"; + + /// + /// DnscryptProxy服务 + /// + /// + public DnscryptProxyService(FastGithubConfig fastGithubConfig) + { + this.fastGithubConfig = fastGithubConfig; + } + + /// + /// 启动dnscrypt-proxy + /// + /// + /// + public async Task StartAsync(CancellationToken cancellationToken) + { + var tomlPath = $"{this.Name}.toml"; + await TomlUtil.SetListensAsync(tomlPath, this.fastGithubConfig.PureDns, cancellationToken); + + foreach (var process in Process.GetProcessesByName(this.Name)) + { + process.Kill(); + } + + if (OperatingSystem.IsWindows()) + { + this.StartDnscryptProxy("-service install", waitForExit: true); + this.StartDnscryptProxy("-service start", waitForExit: true); + } + else + { + this.StartDnscryptProxy(string.Empty, waitForExit: false); + } + } + + /// + /// 停止dnscrypt-proxy + /// + public void Stop() + { + if (OperatingSystem.IsWindows()) + { + this.StartDnscryptProxy("-service stop", waitForExit: true); + this.StartDnscryptProxy("-service uninstall", waitForExit: true); + } + + foreach (var process in Process.GetProcessesByName(this.Name)) + { + process.Kill(); + } + } + + /// + /// 等待退出 + /// + public void WaitForExit() + { + var process = Process.GetProcessesByName(this.Name).FirstOrDefault(); + if (process != null) + { + process.WaitForExit(); + } + } + + /// + /// 启动DnscryptProxy进程 + /// + /// + /// + private void StartDnscryptProxy(string arguments, bool waitForExit) + { + var process = Process.Start(new ProcessStartInfo + { + FileName = OperatingSystem.IsWindows() ? $"{this.Name}.exe" : this.Name, + Arguments = arguments, + UseShellExecute = true, + CreateNoWindow = true, + WindowStyle = ProcessWindowStyle.Hidden + }); + + if (waitForExit && process != null) + { + process.WaitForExit(); + } + } + + /// + /// 转换为字符串 + /// + /// + public override string ToString() + { + return this.Name; + } + } +} diff --git a/FastGithub.Dns.DnscryptProxy/DnscryptProxyServiceCollectionExtensions.cs b/FastGithub.Dns.DnscryptProxy/DnscryptProxyServiceCollectionExtensions.cs index 1dd6e59..6ddfc1e 100644 --- a/FastGithub.Dns.DnscryptProxy/DnscryptProxyServiceCollectionExtensions.cs +++ b/FastGithub.Dns.DnscryptProxy/DnscryptProxyServiceCollectionExtensions.cs @@ -15,7 +15,9 @@ namespace FastGithub /// public static IServiceCollection AddDnscryptProxy(this IServiceCollection services) { - return services.AddHostedService(); + return services + .AddSingleton() + .AddHostedService(); } } } diff --git a/FastGithub.Dns.DnscryptProxy/TomlUtil.cs b/FastGithub.Dns.DnscryptProxy/TomlUtil.cs new file mode 100644 index 0000000..ec7d54d --- /dev/null +++ b/FastGithub.Dns.DnscryptProxy/TomlUtil.cs @@ -0,0 +1,78 @@ +using System; +using System.IO; +using System.Net; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FastGithub.Dns.DnscryptProxy +{ + /// + /// doml配置工具 + /// + static class TomlUtil + { + /// + /// 设置监听地址 + /// + /// + /// + /// + public static Task SetListensAsync(string tomlPath, IPEndPoint endpoint, CancellationToken cancellationToken = default) + { + return SetAsync(tomlPath, "listen_addresses", $"['{endpoint}']"); + } + + /// + /// 设置指定键的值 + /// + /// + /// + /// + public static async Task SetAsync(string tomlPath, string key, object? value, CancellationToken cancellationToken = default) + { + var lines = await File.ReadAllLinesAsync(tomlPath, cancellationToken); + var toml = Set(lines, key, value); + await File.WriteAllTextAsync(tomlPath, toml, cancellationToken); + } + + /// + /// 设置值 + /// + /// + /// + /// + /// + private static string Set(string[] lines, string key, object? value) + { + var updated = false; + var builder = new StringBuilder(); + + foreach (var line in lines) + { + var span = line.AsSpan(); + if (span.IsEmpty || span[0] == '#') + { + builder.AppendLine(line); + continue; + } + + var index = span.IndexOf('='); + if (index <= 0 || span.Slice(0, index).Trim().SequenceEqual(key) == false) + { + builder.AppendLine(line); + continue; + } + + builder.Append(key).Append(" = ").AppendLine(value?.ToString()); + updated = true; + } + + if (updated == false) + { + builder.Append(key).Append(" = ").AppendLine(value?.ToString()); + } + return builder.ToString(); + } + } +} diff --git a/FastGithub.Upgrade/ReverseProxyHttpHandler.cs b/FastGithub.Upgrade/ReverseProxyHttpHandler.cs index 48d43ce..60b0e5d 100644 --- a/FastGithub.Upgrade/ReverseProxyHttpHandler.cs +++ b/FastGithub.Upgrade/ReverseProxyHttpHandler.cs @@ -16,7 +16,10 @@ namespace FastGithub.Upgrade /// public ReverseProxyHttpHandler() { - this.InnerHandler = new HttpClientHandler(); + this.InnerHandler = new HttpClientHandler + { + ServerCertificateCustomValidationCallback = delegate { return true; } + }; } /// diff --git a/FastGithub/FastGithub.csproj b/FastGithub/FastGithub.csproj index a097389..8c80348 100644 --- a/FastGithub/FastGithub.csproj +++ b/FastGithub/FastGithub.csproj @@ -1,46 +1,43 @@  - - Exe - net5.0;net6.0 - MIT - app.ico - true - + + Exe + net5.0;net6.0 + MIT + true + app.ico + app.manifest + - - true - + + true + - - app.manifest - + + + + + + + + - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + +