移除IPV4Cidr类型

This commit is contained in:
陈国伟 2021-06-15 10:07:56 +08:00
parent 60d5ed76ac
commit ba3b981217
8 changed files with 170 additions and 109 deletions

View File

@ -8,13 +8,14 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="IPNetwork2" Version="2.5.320" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0-preview.4.21253.7" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0-preview.4.21253.7" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

View File

@ -8,17 +8,23 @@ namespace FastGithub
sealed class GithubHostedService : IHostedService
{
private readonly IServiceScopeFactory serviceScopeFactory;
private readonly IHostApplicationLifetime hostApplicationLifetime;
public GithubHostedService(IServiceScopeFactory serviceScopeFactory)
public GithubHostedService(
IServiceScopeFactory serviceScopeFactory,
IHostApplicationLifetime hostApplicationLifetime)
{
this.serviceScopeFactory = serviceScopeFactory;
this.hostApplicationLifetime = hostApplicationLifetime;
}
public Task StartAsync(CancellationToken cancellationToken)
public async Task StartAsync(CancellationToken cancellationToken)
{
var scope = this.serviceScopeFactory.CreateScope();
var service = scope.ServiceProvider.GetRequiredService<GithubService>();
return service.ScanAddressAsync(cancellationToken);
await service.ScanAddressAsync(cancellationToken);
this.hostApplicationLifetime.StopApplication();
}
public Task StopAsync(CancellationToken cancellationToken)

View File

@ -28,13 +28,13 @@ namespace FastGithub
var meta = await this.githubMetaService.GetMetaAsync(cancellationToken);
if (meta != null)
{
var contexts = new List<GithubContext>();
var scanTasks = this.GetMetaScanTasks(meta, contexts);
await Task.WhenAll(scanTasks);
var scanTasks = this.GetMetaScanTasks(meta);
var contexts = await Task.WhenAll(scanTasks);
var sortedContexts = contexts
.Where(item => item.HttpElapsed != null)
.OrderBy(item => item.HttpElapsed);
.OrderBy(item => item.Domain)
.ThenBy(item => item.HttpElapsed);
using var fileStream = File.OpenWrite("github.txt");
using var fileWriter = new StreamWriter(fileStream);
@ -42,7 +42,6 @@ namespace FastGithub
foreach (var context in sortedContexts)
{
var message = context.ToString();
this.logger.LogInformation(message);
await fileWriter.WriteLineAsync(message);
}
}
@ -51,7 +50,7 @@ namespace FastGithub
}
private IEnumerable<Task> GetMetaScanTasks(Meta meta, IList<GithubContext> contexts)
private IEnumerable<Task<GithubContext>> GetMetaScanTasks(Meta meta)
{
foreach (var item in meta.ToDomainAddress())
{
@ -60,8 +59,14 @@ namespace FastGithub
Domain = item.Domain,
Address = item.Address,
};
contexts.Add(context);
yield return this.githubDelegate(context);
yield return InvokeAsync(context);
}
async Task<GithubContext> InvokeAsync(GithubContext context)
{
await this.githubDelegate(context);
return context;
}
}
}

118
FastGithub/IPRange.cs Normal file
View File

@ -0,0 +1,118 @@
using System;
using System.Buffers.Binary;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Net.Sockets;
namespace FastGithub
{
sealed class IPRange : IEnumerable<IPAddress>
{
private readonly IPNetwork network;
public AddressFamily AddressFamily => this.network.AddressFamily;
public int Size => (int)this.network.Total;
private IPRange(IPNetwork network)
{
this.network = network;
}
public IEnumerator<IPAddress> GetEnumerator()
{
return new Enumerator(this.network);
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
private class Enumerator : IEnumerator<IPAddress>
{
private IPAddress? currrent;
private readonly IPNetwork network;
private readonly IPAddress maxAddress;
public Enumerator(IPNetwork network)
{
this.network = network;
this.maxAddress = Add(network.LastUsable, 1);
}
public IPAddress Current => this.currrent ?? throw new NotImplementedException();
object IEnumerator.Current => this.Current;
public void Dispose()
{
}
public bool MoveNext()
{
var value = this.currrent == null
? this.network.FirstUsable
: Add(this.currrent, 1);
if (value.Equals(maxAddress))
{
return false;
}
this.currrent = value;
return true;
}
public void Reset()
{
this.currrent = null;
}
}
/// <summary>
/// 添加值
/// </summary>
/// <param name="ip"></param>
/// <param name="value"></param>
/// <returns></returns>
private static IPAddress Add(IPAddress ip, int value)
{
var span = ip.GetAddressBytes().AsSpan();
var hostValue = BinaryPrimitives.ReadInt32BigEndian(span);
BinaryPrimitives.WriteInt32BigEndian(span, hostValue + value);
return new IPAddress(span);
}
public static IEnumerable<IPRange> From(IEnumerable<string> networks)
{
foreach (var item in networks)
{
if (TryParse(item, out var value))
{
yield return value;
}
}
}
public static bool TryParse(ReadOnlySpan<char> network, [MaybeNullWhen(false)] out IPRange value)
{
if (network.IsEmpty == false && IPNetwork.TryParse(network.ToString(), out var ipNetwork))
{
value = new IPRange(ipNetwork);
return true;
}
value = null;
return false;
}
public override string ToString()
{
return this.network.ToString();
}
}
}

View File

@ -1,90 +0,0 @@
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Net.Sockets;
namespace FastGithub
{
sealed class IPv4CIDR
{
public IPAddress IPAddress { get; }
public int Mask { get; }
public int Size { get; }
public IPv4CIDR(IPAddress ipAddress, int mask)
{
this.IPAddress = ipAddress;
this.Mask = mask;
this.Size = Math.Abs((int)(uint.MaxValue << mask >> mask));
}
public IEnumerable<IPAddress> GetAllIPAddress()
{
for (var i = 0; i < this.Size; i++)
{
var value = i;
yield return Add(this.IPAddress, value);
}
}
/// <summary>
/// 添加值
/// </summary>
/// <param name="ip"></param>
/// <param name="value"></param>
/// <returns></returns>
private static IPAddress Add(IPAddress ip, int value)
{
var span = ip.GetAddressBytes().AsSpan();
var hostValue = BinaryPrimitives.ReadInt32BigEndian(span);
BinaryPrimitives.WriteInt32BigEndian(span, hostValue + value);
return new IPAddress(span);
}
public static IEnumerable<IPv4CIDR> From(IEnumerable<string> cidrs)
{
foreach (var item in cidrs)
{
if (TryParse(item, out var value))
{
yield return value;
}
}
}
public static bool TryParse(ReadOnlySpan<char> cidr, [MaybeNullWhen(false)] out IPv4CIDR value)
{
value = null;
var index = cidr.IndexOf('/');
if (index <= 0)
{
return false;
}
var addressSpan = cidr.Slice(0, index);
if (IPAddress.TryParse(addressSpan, out var address) == false
|| address.AddressFamily != AddressFamily.InterNetwork)
{
return false;
}
var maskSpan = cidr.Slice(index + 1);
if (int.TryParse(maskSpan, out var mask) == false)
{
return false;
}
value = new IPv4CIDR(address, mask);
return true;
}
public override string ToString()
{
return $"{this.IPAddress}/{this.Mask}";
}
}
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text.Json.Serialization;
namespace FastGithub
@ -38,19 +39,25 @@ namespace FastGithub
public IEnumerable<DomainAddress> ToDomainAddress()
{
foreach (var cidr in IPv4CIDR.From(this.Web).OrderBy(item => item.Size))
foreach (var range in IPRange.From(this.Web).OrderBy(item => item.Size))
{
foreach (var address in cidr.GetAllIPAddress())
if (range.AddressFamily == AddressFamily.InterNetwork)
{
yield return new DomainAddress("github.com", address);
foreach (var address in range)
{
yield return new DomainAddress("github.com", address);
}
}
}
foreach (var cidr in IPv4CIDR.From(this.Api).OrderBy(item => item.Size))
foreach (var range in IPRange.From(this.Api).OrderBy(item => item.Size))
{
foreach (var address in cidr.GetAllIPAddress())
if (range.AddressFamily == AddressFamily.InterNetwork)
{
yield return new DomainAddress("api.github.com", address);
foreach (var address in range)
{
yield return new DomainAddress("api.github.com", address);
}
}
}
}

View File

@ -0,0 +1,14 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"FastGithub": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development",
"Logging__LogLevel__Default": "Information"
}
}
}
}

View File

@ -6,7 +6,7 @@
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Default": "Warning",
"System": "Warning",
"Microsoft": "Warning"
}