Files
SocialPub/PrivaPub/Federation/Crawler/PeerHosts.cs
T

37 lines
1.3 KiB
C#
Raw Normal View History

using System.Globalization;
namespace PrivaPub.Federation.Crawler
{
public static class PeerHosts
{
static readonly IdnMapping Idn = new();
static readonly string[] Unreachable = { ".onion", ".i2p", ".local", ".localhost", ".internal" };
static readonly string[] Reserved = { ".test", ".invalid", ".example" };
//names from a peers list we could ever talk to: DNS names, ASCII (punycode), no addresses, ports or hidden services;
//the reserved test names only on a test network
public static IEnumerable<string> Filter(IEnumerable<string> names, Func<string, bool> allowed, bool testNetwork = false) =>
names
.Select(Normalise)
.Where(host => host != default && (testNetwork || !Reserved.Any(suffix => host.EndsWith(suffix, StringComparison.Ordinal))) && allowed(host))
.Distinct(StringComparer.Ordinal);
public static string Normalise(string name)
{
var host = name?.Trim().TrimEnd('.').ToLowerInvariant();
if (string.IsNullOrEmpty(host) || host.Length > 253 || !host.Contains('.') || host.Contains(':') || host.Contains('/'))
return default;
try
{
host = Idn.GetAscii(host);
}
catch (ArgumentException)
{
return default;
}
if (Uri.CheckHostName(host) != UriHostNameType.Dns || Unreachable.Any(suffix => host.EndsWith(suffix, StringComparison.Ordinal)))
return default;
return host;
}
}
}