Browse Source

分解项目

xljiulang 4 years ago
parent
commit
c5c5443922
34 changed files with 489 additions and 163 deletions
  1. 12 0
      FastGithub.Core/FastGithub.Core.csproj
  2. 29 0
      FastGithub.Core/OptionsAttribute.cs
  3. 32 0
      FastGithub.Core/ServiceAttribute.cs
  4. 118 0
      FastGithub.Core/ServiceCollectionExtensions.cs
  5. 38 0
      FastGithub.Dns/DnsHostedService.cs
  6. 3 2
      FastGithub.Dns/DnsOptions.cs
  7. 27 0
      FastGithub.Dns/DnsServiceCollectionExtensions.cs
  8. 15 0
      FastGithub.Dns/FastGithub.Dns.csproj
  9. 48 0
      FastGithub.Dns/GithubRequestResolver.cs
  10. 18 0
      FastGithub.Scanner/FastGithub.Scanner.csproj
  11. 2 2
      FastGithub.Scanner/GithubContext.cs
  12. 1 1
      FastGithub.Scanner/GithubContextHashSet.cs
  13. 6 5
      FastGithub.Scanner/GithubFullScanHostedService.cs
  14. 4 2
      FastGithub.Scanner/GithubMetaService.cs
  15. 2 1
      FastGithub.Scanner/GithubOptions.cs
  16. 6 5
      FastGithub.Scanner/GithubResultScanHostedService.cs
  17. 1 1
      FastGithub.Scanner/GithubScanBuilder.cs
  18. 1 1
      FastGithub.Scanner/GithubScanBuilderExtensions.cs
  19. 1 1
      FastGithub.Scanner/GithubScanDelegate.cs
  20. 17 7
      FastGithub.Scanner/GithubScanService.cs
  21. 1 1
      FastGithub.Scanner/IGithubScanBuilder.cs
  22. 1 1
      FastGithub.Scanner/IGithubScanMiddleware.cs
  23. 13 0
      FastGithub.Scanner/IGithubScanService.cs
  24. 1 1
      FastGithub.Scanner/IPRange.cs
  25. 1 1
      FastGithub.Scanner/Meta.cs
  26. 4 2
      FastGithub.Scanner/Middlewares/ConcurrentMiddleware.cs
  27. 4 2
      FastGithub.Scanner/Middlewares/HttpsScanMiddleware.cs
  28. 4 2
      FastGithub.Scanner/Middlewares/PortScanMiddleware.cs
  29. 4 2
      FastGithub.Scanner/Middlewares/ScanOkLogMiddleware.cs
  30. 40 0
      FastGithub.Scanner/ScannerServiceCollectionExtensions.cs
  31. 18 0
      FastGithub.sln
  32. 0 76
      FastGithub/DnsHostedService.cs
  33. 15 18
      FastGithub/FastGithub.csproj
  34. 2 29
      FastGithub/Program.cs

+ 12 - 0
FastGithub.Core/FastGithub.Core.csproj

@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+	<PropertyGroup>
+		<TargetFramework>net5.0</TargetFramework>
+		<Nullable>enable</Nullable>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" />
+	</ItemGroup>
+
+</Project>

+ 29 - 0
FastGithub.Core/OptionsAttribute.cs

@@ -0,0 +1,29 @@
+using System;
+
+namespace FastGithub
+{
+    /// <summary>
+    /// 表示选项特性
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Class)]
+    public sealed class OptionsAttribute : Attribute
+    {
+        public string? SessionKey { get; }
+
+        /// <summary>
+        /// 选项特性
+        /// </summary>
+        public OptionsAttribute()
+        {
+        }
+
+        /// <summary>
+        /// 选项特性
+        /// </summary>
+        /// <param name="sessionKey"></param>
+        public OptionsAttribute(string sessionKey)
+        {
+            this.SessionKey = sessionKey;
+        }
+    }
+}

+ 32 - 0
FastGithub.Core/ServiceAttribute.cs

@@ -0,0 +1,32 @@
+using Microsoft.Extensions.DependencyInjection;
+using System;
+
+namespace FastGithub
+{
+    /// <summary>
+    /// 表示服务特性
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
+    public sealed class ServiceAttribute : Attribute
+    {
+        /// <summary>
+        /// 获取服务的生命周期
+        /// </summary>
+        public ServiceLifetime Lifetime { get; }
+
+        /// <summary>
+        /// 获取或设置注册的服务类型
+        /// 为null直接使得当前类型
+        /// </summary>
+        public Type? ServiceType { get; set; }
+
+        /// <summary>
+        /// 将当前实现类型注册为服务的特性
+        /// </summary>
+        /// <param name="lifetime">生命周期</param>
+        public ServiceAttribute(ServiceLifetime lifetime)
+        {
+            Lifetime = lifetime;
+        }
+    }
+}

+ 118 - 0
FastGithub.Core/ServiceCollectionExtensions.cs

@@ -0,0 +1,118 @@
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Linq;
+using System.Reflection;
+
+namespace FastGithub
+{
+    /// <summary>
+    /// 服务注册扩展
+    /// </summary>
+    public static class ServiceCollectionExtensions
+    {
+        /// <summary>
+        /// 注册程序集下所有服务下选项
+        /// </summary>
+        /// <param name="services"></param>
+        /// <param name="configuration">配置</param>  
+        /// <returns></returns>
+        public static IServiceCollection AddServiceAndOptions(this IServiceCollection services, Assembly assembly, IConfiguration configuration)
+        { 
+            services.AddAttributeServices(assembly);
+            services.AddAttributeOptions(assembly, configuration); 
+
+            return services;
+        }
+
+        /// <summary>
+        /// 添加程序集下ServiceAttribute标记的服务
+        /// </summary>
+        /// <param name="services"></param>
+        /// <param name="assembly"></param> 
+        /// <returns></returns>
+        private static IServiceCollection AddAttributeServices(this IServiceCollection services, Assembly assembly)
+        {
+            var implTypes = assembly
+                .GetTypes()
+                .Where(item => item.IsClass && item.IsAbstract == false)
+                .ToArray();
+
+            foreach (var implType in implTypes)
+            {
+                var attributes = implType.GetCustomAttributes<ServiceAttribute>(false);
+                foreach (var attr in attributes)
+                {
+                    var serviceType = attr.ServiceType ?? implType;
+                    if (services.Any(item => item.ServiceType == serviceType && item.ImplementationType == implType) == false)
+                    {
+                        var descriptor = ServiceDescriptor.Describe(serviceType, implType, attr.Lifetime);
+                        services.Add(descriptor);
+                    }
+                }
+            }
+            return services;
+        }
+
+
+        /// <summary>
+        /// 添加程序集下OptionsAttribute标记的服务 
+        /// </summary>
+        /// <param name="services"></param>
+        /// <param name="assembly"></param> 
+        /// <param name="configuration"></param>
+        private static IServiceCollection AddAttributeOptions(this IServiceCollection services, Assembly assembly, IConfiguration configuration)
+        {
+            foreach (var optionsType in assembly.GetTypes())
+            {
+                var optionsAttribute = optionsType.GetCustomAttribute<OptionsAttribute>();
+                if (optionsAttribute != null)
+                {
+                    var key = optionsAttribute.SessionKey ?? optionsType.Name;
+                    var section = configuration.GetSection(key);
+                    OptionsBinder.Create(services, optionsType).Bind(section);
+                }
+            }
+            return services;
+        }
+
+        /// <summary>
+        /// options绑定器
+        /// </summary>
+        private abstract class OptionsBinder
+        {
+            public abstract void Bind(IConfiguration configuration);
+
+            /// <summary>
+            /// 创建OptionsBinder实例
+            /// </summary>
+            /// <param name="services"></param>
+            /// <param name="optionsType"></param>
+            /// <returns></returns>
+            public static OptionsBinder Create(IServiceCollection services, Type optionsType)
+            {
+                var binderType = typeof(OptionsBinderImpl<>).MakeGenericType(optionsType);
+                var binder = Activator.CreateInstance(binderType, new object[] { services });
+
+                return binder is OptionsBinder optionsBinder
+                    ? optionsBinder
+                    : throw new TypeInitializationException(binderType.FullName, null);
+            }
+
+            private class OptionsBinderImpl<TOptions> : OptionsBinder where TOptions : class
+            {
+                private readonly IServiceCollection services;
+
+                public OptionsBinderImpl(IServiceCollection services)
+                {
+                    this.services = services;
+                }
+
+                public override void Bind(IConfiguration configuration)
+                {
+                    this.services.AddOptions<TOptions>().Bind(configuration);
+                }
+            }
+        }
+    }
+}

+ 38 - 0
FastGithub.Dns/DnsHostedService.cs

@@ -0,0 +1,38 @@
+using DNS.Server;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FastGithub.Dns
+{
+    sealed class DnsHostedService : IHostedService
+    {
+        private readonly DnsServer dnsServer; 
+        private readonly ILogger<DnsHostedService> logger;
+
+        public DnsHostedService(
+            GithubRequestResolver githubRequestResolver,
+            IOptions<DnsOptions> options,
+            ILogger<DnsHostedService> logger)
+        {
+            this.dnsServer = new DnsServer(githubRequestResolver, options.Value.UpStream); 
+            this.logger = logger;
+        } 
+
+        public Task StartAsync(CancellationToken cancellationToken)
+        {
+            this.dnsServer.Listen();
+            this.logger.LogInformation("dns服务启用成功");
+            return Task.CompletedTask;
+        }
+
+        public Task StopAsync(CancellationToken cancellationToken)
+        {
+            this.dnsServer.Dispose();
+            this.logger.LogInformation("dns服务已终止");
+            return Task.CompletedTask;
+        }
+    }
+}

+ 3 - 2
FastGithub/DnsOptions.cs → FastGithub.Dns/DnsOptions.cs

@@ -1,8 +1,9 @@
 using System.Net;
 using System.Net;
 
 
-namespace FastGithub
+namespace FastGithub.Dns
 {
 {
-    class DnsOptions
+    [Options("Dns")]
+    sealed class DnsOptions
     {
     {
         public IPAddress UpStream { get; set; } = IPAddress.Parse("114.114.114.114");
         public IPAddress UpStream { get; set; } = IPAddress.Parse("114.114.114.114");
     }
     }

+ 27 - 0
FastGithub.Dns/DnsServiceCollectionExtensions.cs

@@ -0,0 +1,27 @@
+using FastGithub.Dns;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace FastGithub
+{
+    /// <summary>
+    /// 服务注册扩展
+    /// </summary>
+    public static class DnsServiceCollectionExtensions
+    {
+        /// <summary>
+        /// 注册github的dns服务
+        /// </summary>
+        /// <param name="services"></param>
+        /// <param name="configuration">配置</param>  
+        /// <returns></returns>
+        public static IServiceCollection AddGithubDns(this IServiceCollection services, IConfiguration configuration)
+        {
+            var assembly = typeof(DnsServiceCollectionExtensions).Assembly;
+            return services
+                .AddGithubScanner(configuration)
+                .AddServiceAndOptions(assembly, configuration)
+                .AddHostedService<DnsHostedService>();
+        }
+    }
+}

+ 15 - 0
FastGithub.Dns/FastGithub.Dns.csproj

@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+	<PropertyGroup>
+		<TargetFramework>net5.0</TargetFramework>
+		<Nullable>enable</Nullable>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<PackageReference Include="DNS" Version="6.1.0" />
+	</ItemGroup>
+
+	<ItemGroup>
+	  <ProjectReference Include="..\FastGithub.Scanner\FastGithub.Scanner.csproj" />
+	</ItemGroup>
+</Project>

+ 48 - 0
FastGithub.Dns/GithubRequestResolver.cs

@@ -0,0 +1,48 @@
+using DNS.Client.RequestResolver;
+using DNS.Protocol;
+using DNS.Protocol.ResourceRecords;
+using FastGithub.Scanner;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FastGithub.Dns
+{
+    [Service(ServiceLifetime.Singleton)]
+    sealed class GithubRequestResolver : IRequestResolver
+    {
+        private readonly IGithubScanService githubScanService;
+        private readonly ILogger<GithubRequestResolver> logger;
+
+        public GithubRequestResolver(
+            IGithubScanService githubScanService,
+            ILogger<GithubRequestResolver> logger)
+        {
+            this.githubScanService = githubScanService;
+            this.logger = logger;
+        }
+
+        public Task<IResponse> Resolve(IRequest request, CancellationToken cancellationToken = default)
+        {
+            var response = Response.FromRequest(request);
+            var question = request.Questions.FirstOrDefault();
+
+            if (question != null && question.Type == RecordType.A)
+            {
+                var domain = question.Name.ToString();
+                var fastAddress = this.githubScanService.FindFastAddress(domain);
+
+                if (fastAddress != null)
+                {
+                    var record = new IPAddressResourceRecord(question.Name, fastAddress);
+                    response.AnswerRecords.Add(record);
+                    this.logger.LogInformation(record.ToString());
+                }
+            }
+
+            return Task.FromResult<IResponse>(response);
+        }
+    }
+}

+ 18 - 0
FastGithub.Scanner/FastGithub.Scanner.csproj

@@ -0,0 +1,18 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+	<PropertyGroup>
+		<TargetFramework>net5.0</TargetFramework>
+		<Nullable>enable</Nullable>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<PackageReference Include="IPNetwork2" Version="2.5.320" />
+		<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
+		<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
+	</ItemGroup>
+
+	<ItemGroup>
+	  <ProjectReference Include="..\FastGithub.Core\FastGithub.Core.csproj" />
+	</ItemGroup>
+
+</Project>

+ 2 - 2
FastGithub/GithubContext.cs → FastGithub.Scanner/GithubContext.cs

@@ -1,9 +1,9 @@
 using System;
 using System;
 using System.Net;
 using System.Net;
 
 
-namespace FastGithub
+namespace FastGithub.Scanner
 {
 {
-    class GithubContext : IEquatable<GithubContext>
+    sealed class GithubContext : IEquatable<GithubContext>
     {
     {
         public string Domain { get; }
         public string Domain { get; }
 
 

+ 1 - 1
FastGithub/GithubContextHashSet.cs → FastGithub.Scanner/GithubContextHashSet.cs

@@ -1,6 +1,6 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 
 
-namespace FastGithub
+namespace FastGithub.Scanner
 {
 {
     class GithubContextHashSet : HashSet<GithubContext>
     class GithubContextHashSet : HashSet<GithubContext>
     {
     {

+ 6 - 5
FastGithub/GithubScanAllHostedService.cs → FastGithub.Scanner/GithubFullScanHostedService.cs

@@ -1,17 +1,18 @@
-using Microsoft.Extensions.Hosting;
+using FastGithub.Scanner;
+using Microsoft.Extensions.Hosting;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
 namespace FastGithub
 namespace FastGithub
 {
 {
-    sealed class GithubScanAllHostedService : BackgroundService
+    sealed class GithubFullScanHostedService : BackgroundService
     {
     {
-        private readonly GithubScanService githubScanService;
+        private readonly IGithubScanService githubScanService;
         private readonly IOptionsMonitor<GithubOptions> options;
         private readonly IOptionsMonitor<GithubOptions> options;
 
 
-        public GithubScanAllHostedService(
-            GithubScanService githubScanService,
+        public GithubFullScanHostedService(
+            IGithubScanService githubScanService,
             IOptionsMonitor<GithubOptions> options)
             IOptionsMonitor<GithubOptions> options)
         {
         {
             this.githubScanService = githubScanService;
             this.githubScanService = githubScanService;

+ 4 - 2
FastGithub/GithubMetaService.cs → FastGithub.Scanner/GithubMetaService.cs

@@ -1,4 +1,5 @@
-using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
 using System;
 using System;
 using System.Net.Http;
 using System.Net.Http;
@@ -6,8 +7,9 @@ using System.Net.Http.Json;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
-namespace FastGithub
+namespace FastGithub.Scanner
 {
 {
+    [Service(ServiceLifetime.Singleton)]
     sealed class GithubMetaService
     sealed class GithubMetaService
     {
     {
         private readonly IHttpClientFactory httpClientFactory;
         private readonly IHttpClientFactory httpClientFactory;

+ 2 - 1
FastGithub/GithubOptions.cs → FastGithub.Scanner/GithubOptions.cs

@@ -1,7 +1,8 @@
 using System;
 using System;
 
 
-namespace FastGithub
+namespace FastGithub.Scanner
 {
 {
+    [Options("Github")]
     class GithubOptions
     class GithubOptions
     {
     {
         public TimeSpan ScanAllInterval { get; set; } = TimeSpan.FromHours(12d);
         public TimeSpan ScanAllInterval { get; set; } = TimeSpan.FromHours(12d);

+ 6 - 5
FastGithub/GithubScanResultHostedService.cs → FastGithub.Scanner/GithubResultScanHostedService.cs

@@ -1,17 +1,18 @@
-using Microsoft.Extensions.Hosting;
+using FastGithub.Scanner;
+using Microsoft.Extensions.Hosting;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
 namespace FastGithub
 namespace FastGithub
 {
 {
-    sealed class GithubScanResultHostedService : BackgroundService
+    sealed class GithubResultScanHostedService : BackgroundService
     {
     {
-        private readonly GithubScanService githubScanService;
+        private readonly IGithubScanService githubScanService;
         private readonly IOptionsMonitor<GithubOptions> options;
         private readonly IOptionsMonitor<GithubOptions> options;
 
 
-        public GithubScanResultHostedService(
-            GithubScanService githubScanService,
+        public GithubResultScanHostedService(
+            IGithubScanService githubScanService,
             IOptionsMonitor<GithubOptions> options)
             IOptionsMonitor<GithubOptions> options)
         {
         {
             this.githubScanService = githubScanService;
             this.githubScanService = githubScanService;

+ 1 - 1
FastGithub/GithubScanBuilder.cs → FastGithub.Scanner/GithubScanBuilder.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
-namespace FastGithub
+namespace FastGithub.Scanner
 {
 {
     /// <summary>
     /// <summary>
     /// 表示中间件创建者
     /// 表示中间件创建者

+ 1 - 1
FastGithub/GithubScanBuilderExtensions.cs → FastGithub.Scanner/GithubScanBuilderExtensions.cs

@@ -1,7 +1,7 @@
 using System;
 using System;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
-namespace FastGithub
+namespace FastGithub.Scanner
 {
 {
     /// <summary>
     /// <summary>
     /// 中间件创建者扩展
     /// 中间件创建者扩展

+ 1 - 1
FastGithub/GithubScanDelegate.cs → FastGithub.Scanner/GithubScanDelegate.cs

@@ -1,6 +1,6 @@
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
-namespace FastGithub
+namespace FastGithub.Scanner
 {
 {
     /// <summary>
     /// <summary>
     /// 表示所有中间件执行委托
     /// 表示所有中间件执行委托

+ 17 - 7
FastGithub/GithubScanService.cs → FastGithub.Scanner/GithubScanService.cs

@@ -1,12 +1,15 @@
-using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using System;
 using System.Linq;
 using System.Linq;
 using System.Net;
 using System.Net;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
-namespace FastGithub
+namespace FastGithub.Scanner
 {
 {
-    sealed class GithubScanService
+    [Service(ServiceLifetime.Singleton, ServiceType = typeof(IGithubScanService))]
+    sealed class GithubScanService : IGithubScanService
     {
     {
         private readonly GithubMetaService metaService;
         private readonly GithubMetaService metaService;
         private readonly GithubScanDelegate scanDelegate;
         private readonly GithubScanDelegate scanDelegate;
@@ -25,6 +28,7 @@ namespace FastGithub
 
 
         public async Task ScanAllAsync(CancellationToken cancellationToken = default)
         public async Task ScanAllAsync(CancellationToken cancellationToken = default)
         {
         {
+            this.logger.LogInformation("完整扫描开始");
             var meta = await this.metaService.GetMetaAsync(cancellationToken);
             var meta = await this.metaService.GetMetaAsync(cancellationToken);
             if (meta != null)
             if (meta != null)
             {
             {
@@ -32,7 +36,7 @@ namespace FastGithub
                 await Task.WhenAll(scanTasks);
                 await Task.WhenAll(scanTasks);
             }
             }
 
 
-            this.logger.LogInformation("完全扫描完成");
+            this.logger.LogInformation("完整扫描结束");
 
 
             async Task ScanAsync(GithubContext context)
             async Task ScanAsync(GithubContext context)
             {
             {
@@ -49,6 +53,7 @@ namespace FastGithub
 
 
         public async Task ScanResultAsync()
         public async Task ScanResultAsync()
         {
         {
+            this.logger.LogInformation("结果扫描开始");
             GithubContext[] contexts;
             GithubContext[] contexts;
             lock (this.results.SyncRoot)
             lock (this.results.SyncRoot)
             {
             {
@@ -61,18 +66,23 @@ namespace FastGithub
                 await this.scanDelegate(context);
                 await this.scanDelegate(context);
             }
             }
 
 
-            this.logger.LogInformation("结果扫描完成");
+            this.logger.LogInformation("结果扫描结束");
         }
         }
 
 
-        public IPAddress[] FindAddress(string domain)
+        public IPAddress? FindFastAddress(string domain)
         {
         {
+            if (domain.Contains("github", StringComparison.OrdinalIgnoreCase))
+            {
+                return default;
+            }
+
             lock (this.results.SyncRoot)
             lock (this.results.SyncRoot)
             {
             {
                 return this.results
                 return this.results
                     .Where(item => item.Domain == domain && item.HttpElapsed != null)
                     .Where(item => item.Domain == domain && item.HttpElapsed != null)
                     .OrderBy(item => item.HttpElapsed)
                     .OrderBy(item => item.HttpElapsed)
                     .Select(item => item.Address)
                     .Select(item => item.Address)
-                    .ToArray();
+                    .FirstOrDefault();
             }
             }
         }
         }
     }
     }

+ 1 - 1
FastGithub/IGithubScanBuilder.cs → FastGithub.Scanner/IGithubScanBuilder.cs

@@ -1,6 +1,6 @@
 using System;
 using System;
 
 
-namespace FastGithub
+namespace FastGithub.Scanner
 {
 {
     /// <summary>
     /// <summary>
     /// 定义中间件管道创建者的接口
     /// 定义中间件管道创建者的接口

+ 1 - 1
FastGithub/IGithubScanMiddleware.cs → FastGithub.Scanner/IGithubScanMiddleware.cs

@@ -1,7 +1,7 @@
 using System;
 using System;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
-namespace FastGithub
+namespace FastGithub.Scanner
 {
 {
     /// <summary>
     /// <summary>
     /// 定义中间件的接口
     /// 定义中间件的接口

+ 13 - 0
FastGithub.Scanner/IGithubScanService.cs

@@ -0,0 +1,13 @@
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FastGithub.Scanner
+{
+    public interface IGithubScanService
+    {
+        Task ScanAllAsync(CancellationToken cancellationToken = default);
+        Task ScanResultAsync(); 
+        IPAddress? FindFastAddress(string domain);
+    }
+}

+ 1 - 1
FastGithub/IPRange.cs → FastGithub.Scanner/IPRange.cs

@@ -6,7 +6,7 @@ using System.Diagnostics.CodeAnalysis;
 using System.Net;
 using System.Net;
 using System.Net.Sockets;
 using System.Net.Sockets;
 
 
-namespace FastGithub
+namespace FastGithub.Scanner
 {
 {
     sealed class IPRange : IEnumerable<IPAddress>
     sealed class IPRange : IEnumerable<IPAddress>
     {
     {

+ 1 - 1
FastGithub/Meta.cs → FastGithub.Scanner/Meta.cs

@@ -4,7 +4,7 @@ using System.Linq;
 using System.Net.Sockets;
 using System.Net.Sockets;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
 
 
-namespace FastGithub
+namespace FastGithub.Scanner
 {
 {
     class Meta
     class Meta
     {
     {

+ 4 - 2
FastGithub/Middlewares/ConcurrentMiddleware.cs → FastGithub.Scanner/Middlewares/ConcurrentMiddleware.cs

@@ -1,9 +1,11 @@
-using System;
+using Microsoft.Extensions.DependencyInjection;
+using System;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
-namespace FastGithub.Middlewares
+namespace FastGithub.Scanner.Middlewares
 {
 {
+    [Service(ServiceLifetime.Singleton)]
     sealed class ConcurrentMiddleware : IGithubScanMiddleware
     sealed class ConcurrentMiddleware : IGithubScanMiddleware
     {
     {
         private readonly SemaphoreSlim semaphoreSlim = new(Environment.ProcessorCount * 4);
         private readonly SemaphoreSlim semaphoreSlim = new(Environment.ProcessorCount * 4);

+ 4 - 2
FastGithub/Middlewares/HttpsScanMiddleware.cs → FastGithub.Scanner/Middlewares/HttpsScanMiddleware.cs

@@ -1,4 +1,5 @@
-using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
 using System;
 using System;
 using System.Linq;
 using System.Linq;
@@ -6,8 +7,9 @@ using System.Net.Http;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
-namespace FastGithub.Middlewares
+namespace FastGithub.Scanner.Middlewares
 {
 {
+    [Service(ServiceLifetime.Singleton)]
     sealed class HttpsScanMiddleware : IGithubScanMiddleware
     sealed class HttpsScanMiddleware : IGithubScanMiddleware
     {
     {
         private readonly IOptionsMonitor<GithubOptions> options;
         private readonly IOptionsMonitor<GithubOptions> options;

+ 4 - 2
FastGithub/Middlewares/PortScanMiddleware.cs → FastGithub.Scanner/Middlewares/PortScanMiddleware.cs

@@ -1,12 +1,14 @@
-using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
 using System;
 using System;
 using System.Net.Sockets;
 using System.Net.Sockets;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
-namespace FastGithub.Middlewares
+namespace FastGithub.Scanner.Middlewares
 {
 {
+    [Service(ServiceLifetime.Singleton)]
     sealed class PortScanMiddleware : IGithubScanMiddleware
     sealed class PortScanMiddleware : IGithubScanMiddleware
     {
     {
         private const int PORT = 443;
         private const int PORT = 443;

+ 4 - 2
FastGithub/Middlewares/ScanOkLogMiddleware.cs → FastGithub.Scanner/Middlewares/ScanOkLogMiddleware.cs

@@ -1,9 +1,11 @@
-using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
 using System;
 using System;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
-namespace FastGithub.Middlewares
+namespace FastGithub.Scanner.Middlewares
 {
 {
+    [Service(ServiceLifetime.Singleton)]
     sealed class ScanOkLogMiddleware : IGithubScanMiddleware
     sealed class ScanOkLogMiddleware : IGithubScanMiddleware
     {
     {
         private readonly ILogger<ScanOkLogMiddleware> logger;
         private readonly ILogger<ScanOkLogMiddleware> logger;

+ 40 - 0
FastGithub.Scanner/ScannerServiceCollectionExtensions.cs

@@ -0,0 +1,40 @@
+using FastGithub.Scanner;
+using FastGithub.Scanner.Middlewares;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using System.Threading.Tasks;
+
+namespace FastGithub
+{
+    /// <summary>
+    /// 服务注册扩展
+    /// </summary>
+    public static class ScannerServiceCollectionExtensions
+    {
+        /// <summary>
+        /// 注册程序集下所有服务下选项
+        /// </summary>
+        /// <param name="services"></param>
+        /// <param name="configuration">配置</param>  
+        /// <returns></returns>
+        public static IServiceCollection AddGithubScanner(this IServiceCollection services, IConfiguration configuration)
+        {
+            var assembly = typeof(ScannerServiceCollectionExtensions).Assembly;
+            return services
+                .AddHttpClient()
+                .AddSingleton(serviceProvider =>
+                {
+                    return new GithubScanBuilder(serviceProvider, ctx => Task.CompletedTask)
+                        .Use<ConcurrentMiddleware>()
+                        .Use<PortScanMiddleware>()
+                        .Use<HttpsScanMiddleware>()
+                        .Use<ScanOkLogMiddleware>()
+                        .Build();
+                })
+                .AddServiceAndOptions(assembly, configuration)
+                .AddHostedService<GithubFullScanHostedService>()
+                .AddHostedService<GithubResultScanHostedService>()
+                ;
+        }
+    }
+}

+ 18 - 0
FastGithub.sln

@@ -5,6 +5,12 @@ VisualStudioVersion = 16.0.31320.298
 MinimumVisualStudioVersion = 10.0.40219.1
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub", "FastGithub\FastGithub.csproj", "{C1099390-6103-4917-A740-A3002B542FE0}"
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub", "FastGithub\FastGithub.csproj", "{C1099390-6103-4917-A740-A3002B542FE0}"
 EndProject
 EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.Core", "FastGithub.Core\FastGithub.Core.csproj", "{4E4841D2-F743-40BB-BE28-729DB53775CC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.Dns", "FastGithub.Dns\FastGithub.Dns.csproj", "{43FF9C79-51D5-4037-AA0B-CA3006E2A7E6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.Scanner", "FastGithub.Scanner\FastGithub.Scanner.csproj", "{7F24CD2F-07C0-4002-A534-80688DE95ECF}"
+EndProject
 Global
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
 		Debug|Any CPU = Debug|Any CPU
@@ -15,6 +21,18 @@ Global
 		{C1099390-6103-4917-A740-A3002B542FE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{C1099390-6103-4917-A740-A3002B542FE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{C1099390-6103-4917-A740-A3002B542FE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{C1099390-6103-4917-A740-A3002B542FE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{C1099390-6103-4917-A740-A3002B542FE0}.Release|Any CPU.Build.0 = Release|Any CPU
 		{C1099390-6103-4917-A740-A3002B542FE0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{4E4841D2-F743-40BB-BE28-729DB53775CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4E4841D2-F743-40BB-BE28-729DB53775CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{4E4841D2-F743-40BB-BE28-729DB53775CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{4E4841D2-F743-40BB-BE28-729DB53775CC}.Release|Any CPU.Build.0 = Release|Any CPU
+		{43FF9C79-51D5-4037-AA0B-CA3006E2A7E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{43FF9C79-51D5-4037-AA0B-CA3006E2A7E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{43FF9C79-51D5-4037-AA0B-CA3006E2A7E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{43FF9C79-51D5-4037-AA0B-CA3006E2A7E6}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7F24CD2F-07C0-4002-A534-80688DE95ECF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7F24CD2F-07C0-4002-A534-80688DE95ECF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7F24CD2F-07C0-4002-A534-80688DE95ECF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7F24CD2F-07C0-4002-A534-80688DE95ECF}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 		HideSolutionNode = FALSE

+ 0 - 76
FastGithub/DnsHostedService.cs

@@ -1,76 +0,0 @@
-using DNS.Client.RequestResolver;
-using DNS.Protocol;
-using DNS.Protocol.ResourceRecords;
-using DNS.Server;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using System;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace FastGithub
-{
-    sealed class DnsHostedService : IHostedService, IRequestResolver
-    {
-        private readonly DnsServer dnsServer;
-        private readonly GithubScanService githubScanService;
-        private readonly ILogger<DnsHostedService> logger;
-
-        public DnsHostedService(
-            GithubScanService githubScanService,
-            IOptions<DnsOptions> options,
-            ILogger<DnsHostedService> logger)
-        {
-            this.dnsServer = new DnsServer(this, options.Value.UpStream);
-            this.githubScanService = githubScanService;
-            this.logger = logger;
-        }
-
-        /// <summary>
-        /// 解析dns
-        /// </summary>
-        /// <param name="request"></param>
-        /// <param name="cancellationToken"></param>
-        /// <returns></returns>
-        Task<IResponse> IRequestResolver.Resolve(IRequest request, CancellationToken cancellationToken)
-        {
-            var response = Response.FromRequest(request);
-            var question = request.Questions.FirstOrDefault();
-
-            if (question != null && question.Type == RecordType.A)
-            {
-                var domain = question.Name.ToString();
-                if (domain.Contains("github", StringComparison.OrdinalIgnoreCase))
-                {
-                    var addressArray = this.githubScanService.FindAddress(domain);
-                    foreach (var address in addressArray)
-                    {
-                        var record = new IPAddressResourceRecord(question.Name, address);
-                        response.AnswerRecords.Add(record);
-                    }
-
-                    var addressString = string.Join(',', addressArray.Select(a => a.ToString()));
-                    this.logger.LogInformation($"{domain}=>{addressString}");
-                }
-            }
-
-            return Task.FromResult<IResponse>(response);
-        }
-
-        public Task StartAsync(CancellationToken cancellationToken)
-        {
-            this.dnsServer.Listen();
-            this.logger.LogInformation("dns服务启用成功");
-            return Task.CompletedTask;
-        }
-
-        public Task StopAsync(CancellationToken cancellationToken)
-        {
-            this.dnsServer.Dispose();
-            this.logger.LogInformation("dns服务已终止");
-            return Task.CompletedTask;
-        }
-    }
-}

+ 15 - 18
FastGithub/FastGithub.csproj

@@ -1,24 +1,21 @@
 <Project Sdk="Microsoft.NET.Sdk">
 <Project Sdk="Microsoft.NET.Sdk">
 
 
-  <PropertyGroup>
-    <OutputType>Exe</OutputType>
-    <Nullable>enable</Nullable>
-    <TargetFramework>net5.0</TargetFramework>
-    <EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
-    <Version>1.0.2</Version>
-  </PropertyGroup> 
+	<PropertyGroup>
+		<OutputType>Exe</OutputType>
+		<Nullable>enable</Nullable>
+		<TargetFramework>net5.0</TargetFramework>
+		<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
+		<Version>1.0.2</Version>
+	</PropertyGroup>
 
 
-  <ItemGroup>
-    <PackageReference Include="DNS" Version="6.1.0" />
-    <PackageReference Include="IPNetwork2" Version="2.5.320" />
-    <PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
-    <PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
-  </ItemGroup>
+	<ItemGroup>
+		<ProjectReference Include="..\FastGithub.Dns\FastGithub.Dns.csproj" />
+	</ItemGroup>
 
 
-  <ItemGroup>
-    <None Update="appsettings.json">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-  </ItemGroup>
+	<ItemGroup>
+		<None Update="appsettings.json">
+			<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+		</None>
+	</ItemGroup>
 
 
 </Project>
 </Project>

+ 2 - 29
FastGithub/Program.cs

@@ -1,7 +1,4 @@
-using FastGithub.Middlewares;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using System.Threading.Tasks;
+using Microsoft.Extensions.Hosting;
 
 
 namespace FastGithub
 namespace FastGithub
 {
 {
@@ -27,32 +24,8 @@ namespace FastGithub
                 .CreateDefaultBuilder(args)
                 .CreateDefaultBuilder(args)
                 .ConfigureServices((ctx, services) =>
                 .ConfigureServices((ctx, services) =>
                 {
                 {
-                    services
-                        .Configure<DnsOptions>(ctx.Configuration.GetSection("Dns"))
-                        .Configure<GithubOptions>(ctx.Configuration.GetSection("Github"))
-                        .AddHttpClient()
-                        .AddSingleton<GithubMetaService>()
-                        .AddSingleton<GithubScanService>()
-
-                        .AddSingleton<PortScanMiddleware>()
-                        .AddSingleton<HttpsScanMiddleware>()
-                        .AddSingleton<ConcurrentMiddleware>()
-                        .AddSingleton<ScanOkLogMiddleware>()
-                        .AddSingleton(serviceProvider =>
-                        {
-                            return new GithubScanBuilder(serviceProvider, ctx => Task.CompletedTask)
-                                .Use<ConcurrentMiddleware>()
-                                .Use<PortScanMiddleware>()
-                                .Use<HttpsScanMiddleware>()
-                                .Use<ScanOkLogMiddleware>()
-                                .Build();
-                        })
-                        .AddHostedService<DnsHostedService>()
-                        .AddHostedService<GithubScanAllHostedService>()
-                        .AddHostedService<GithubScanResultHostedService>()
-                        ;
+                    services.AddGithubDns(ctx.Configuration);
                 });
                 });
-
         }
         }
     }
     }
 }
 }