分解项目
This commit is contained in:
parent
0ee36f0ae1
commit
c5c5443922
12
FastGithub.Core/FastGithub.Core.csproj
Normal file
12
FastGithub.Core/FastGithub.Core.csproj
Normal file
@ -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
FastGithub.Core/OptionsAttribute.cs
Normal file
29
FastGithub.Core/OptionsAttribute.cs
Normal file
@ -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
FastGithub.Core/ServiceAttribute.cs
Normal file
32
FastGithub.Core/ServiceAttribute.cs
Normal file
@ -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
FastGithub.Core/ServiceCollectionExtensions.cs
Normal file
118
FastGithub.Core/ServiceCollectionExtensions.cs
Normal file
@ -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
FastGithub.Dns/DnsHostedService.cs
Normal file
38
FastGithub.Dns/DnsHostedService.cs
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,9 @@
|
||||
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");
|
||||
}
|
||||
27
FastGithub.Dns/DnsServiceCollectionExtensions.cs
Normal file
27
FastGithub.Dns/DnsServiceCollectionExtensions.cs
Normal file
@ -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
FastGithub.Dns/FastGithub.Dns.csproj
Normal file
15
FastGithub.Dns/FastGithub.Dns.csproj
Normal file
@ -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
FastGithub.Dns/GithubRequestResolver.cs
Normal file
48
FastGithub.Dns/GithubRequestResolver.cs
Normal file
@ -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
FastGithub.Scanner/FastGithub.Scanner.csproj
Normal file
18
FastGithub.Scanner/FastGithub.Scanner.csproj
Normal file
@ -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>
|
||||
@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
|
||||
namespace FastGithub
|
||||
namespace FastGithub.Scanner
|
||||
{
|
||||
class GithubContext : IEquatable<GithubContext>
|
||||
sealed class GithubContext : IEquatable<GithubContext>
|
||||
{
|
||||
public string Domain { get; }
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FastGithub
|
||||
namespace FastGithub.Scanner
|
||||
{
|
||||
class GithubContextHashSet : HashSet<GithubContext>
|
||||
{
|
||||
@ -1,17 +1,18 @@
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using FastGithub.Scanner;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
sealed class GithubScanAllHostedService : BackgroundService
|
||||
sealed class GithubFullScanHostedService : BackgroundService
|
||||
{
|
||||
private readonly GithubScanService githubScanService;
|
||||
private readonly IGithubScanService githubScanService;
|
||||
private readonly IOptionsMonitor<GithubOptions> options;
|
||||
|
||||
public GithubScanAllHostedService(
|
||||
GithubScanService githubScanService,
|
||||
public GithubFullScanHostedService(
|
||||
IGithubScanService githubScanService,
|
||||
IOptionsMonitor<GithubOptions> options)
|
||||
{
|
||||
this.githubScanService = githubScanService;
|
||||
@ -1,4 +1,5 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
@ -6,8 +7,9 @@ using System.Net.Http.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub
|
||||
namespace FastGithub.Scanner
|
||||
{
|
||||
[Service(ServiceLifetime.Singleton)]
|
||||
sealed class GithubMetaService
|
||||
{
|
||||
private readonly IHttpClientFactory httpClientFactory;
|
||||
@ -1,7 +1,8 @@
|
||||
using System;
|
||||
|
||||
namespace FastGithub
|
||||
namespace FastGithub.Scanner
|
||||
{
|
||||
[Options("Github")]
|
||||
class GithubOptions
|
||||
{
|
||||
public TimeSpan ScanAllInterval { get; set; } = TimeSpan.FromHours(12d);
|
||||
@ -1,17 +1,18 @@
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using FastGithub.Scanner;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
sealed class GithubScanResultHostedService : BackgroundService
|
||||
sealed class GithubResultScanHostedService : BackgroundService
|
||||
{
|
||||
private readonly GithubScanService githubScanService;
|
||||
private readonly IGithubScanService githubScanService;
|
||||
private readonly IOptionsMonitor<GithubOptions> options;
|
||||
|
||||
public GithubScanResultHostedService(
|
||||
GithubScanService githubScanService,
|
||||
public GithubResultScanHostedService(
|
||||
IGithubScanService githubScanService,
|
||||
IOptionsMonitor<GithubOptions> options)
|
||||
{
|
||||
this.githubScanService = githubScanService;
|
||||
@ -2,7 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub
|
||||
namespace FastGithub.Scanner
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示中间件创建者
|
||||
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub
|
||||
namespace FastGithub.Scanner
|
||||
{
|
||||
/// <summary>
|
||||
/// 中间件创建者扩展
|
||||
@ -1,6 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub
|
||||
namespace FastGithub.Scanner
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示所有中间件执行委托
|
||||
@ -1,12 +1,15 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
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 GithubScanDelegate scanDelegate;
|
||||
@ -25,6 +28,7 @@ namespace FastGithub
|
||||
|
||||
public async Task ScanAllAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
this.logger.LogInformation("完整扫描开始");
|
||||
var meta = await this.metaService.GetMetaAsync(cancellationToken);
|
||||
if (meta != null)
|
||||
{
|
||||
@ -32,7 +36,7 @@ namespace FastGithub
|
||||
await Task.WhenAll(scanTasks);
|
||||
}
|
||||
|
||||
this.logger.LogInformation("完全扫描完成");
|
||||
this.logger.LogInformation("完整扫描结束");
|
||||
|
||||
async Task ScanAsync(GithubContext context)
|
||||
{
|
||||
@ -49,6 +53,7 @@ namespace FastGithub
|
||||
|
||||
public async Task ScanResultAsync()
|
||||
{
|
||||
this.logger.LogInformation("结果扫描开始");
|
||||
GithubContext[] contexts;
|
||||
lock (this.results.SyncRoot)
|
||||
{
|
||||
@ -61,18 +66,23 @@ namespace FastGithub
|
||||
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)
|
||||
{
|
||||
return this.results
|
||||
.Where(item => item.Domain == domain && item.HttpElapsed != null)
|
||||
.OrderBy(item => item.HttpElapsed)
|
||||
.Select(item => item.Address)
|
||||
.ToArray();
|
||||
.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace FastGithub
|
||||
namespace FastGithub.Scanner
|
||||
{
|
||||
/// <summary>
|
||||
/// 定义中间件管道创建者的接口
|
||||
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub
|
||||
namespace FastGithub.Scanner
|
||||
{
|
||||
/// <summary>
|
||||
/// 定义中间件的接口
|
||||
13
FastGithub.Scanner/IGithubScanService.cs
Normal file
13
FastGithub.Scanner/IGithubScanService.cs
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace FastGithub
|
||||
namespace FastGithub.Scanner
|
||||
{
|
||||
sealed class IPRange : IEnumerable<IPAddress>
|
||||
{
|
||||
@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace FastGithub
|
||||
namespace FastGithub.Scanner
|
||||
{
|
||||
class Meta
|
||||
{
|
||||
@ -1,9 +1,11 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub.Middlewares
|
||||
namespace FastGithub.Scanner.Middlewares
|
||||
{
|
||||
[Service(ServiceLifetime.Singleton)]
|
||||
sealed class ConcurrentMiddleware : IGithubScanMiddleware
|
||||
{
|
||||
private readonly SemaphoreSlim semaphoreSlim = new(Environment.ProcessorCount * 4);
|
||||
@ -1,4 +1,5 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Linq;
|
||||
@ -6,8 +7,9 @@ using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub.Middlewares
|
||||
namespace FastGithub.Scanner.Middlewares
|
||||
{
|
||||
[Service(ServiceLifetime.Singleton)]
|
||||
sealed class HttpsScanMiddleware : IGithubScanMiddleware
|
||||
{
|
||||
private readonly IOptionsMonitor<GithubOptions> options;
|
||||
@ -1,12 +1,14 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub.Middlewares
|
||||
namespace FastGithub.Scanner.Middlewares
|
||||
{
|
||||
[Service(ServiceLifetime.Singleton)]
|
||||
sealed class PortScanMiddleware : IGithubScanMiddleware
|
||||
{
|
||||
private const int PORT = 443;
|
||||
@ -1,9 +1,11 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub.Middlewares
|
||||
namespace FastGithub.Scanner.Middlewares
|
||||
{
|
||||
[Service(ServiceLifetime.Singleton)]
|
||||
sealed class ScanOkLogMiddleware : IGithubScanMiddleware
|
||||
{
|
||||
private readonly ILogger<ScanOkLogMiddleware> logger;
|
||||
40
FastGithub.Scanner/ScannerServiceCollectionExtensions.cs
Normal file
40
FastGithub.Scanner/ScannerServiceCollectionExtensions.cs
Normal file
@ -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>()
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,12 @@ VisualStudioVersion = 16.0.31320.298
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub", "FastGithub\FastGithub.csproj", "{C1099390-6103-4917-A740-A3002B542FE0}"
|
||||
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
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
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}.Release|Any CPU.ActiveCfg = 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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,24 +1,21 @@
|
||||
<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>
|
||||
|
||||
@ -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
|
||||
{
|
||||
@ -27,32 +24,8 @@ namespace FastGithub
|
||||
.CreateDefaultBuilder(args)
|
||||
.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);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user