refactor(network): collapse Firewall to a single-threaded persisted store

Merge the old Firewall engine, AdminFirewall (parsing/persistence), and the
runtime TTL sweep into one single-threaded store: no locks/version-counter,
main-thread TTL expiry, and persistence to Configuration/firewall.json (with a
one-time firewall.cfg migration). Lookups go through a shared, coalesced
SortedRangeIndex<T> (binary search); IP conversion/parse helpers are collected
in IPAddressUtility. Firewall keeps IFirewallEntry for admin/gump/persistence.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kamron Batman 2026-07-23 20:37:19 -07:00
parent 858c1d18bc
commit 4ec488f59b
No known key found for this signature in database
GPG key ID: 7D81DF26D9A5D94A
8 changed files with 825 additions and 383 deletions

View file

@ -108,45 +108,6 @@ public static partial class Utility
}
}
// Converts an IPAddress to a UInt128 in IPv6 format
public static UInt128 ToUInt128(this IPAddress ip)
{
if (ip.AddressFamily == AddressFamily.InterNetwork && !ip.IsIPv4MappedToIPv6)
{
Span<byte> integer = stackalloc byte[4];
return !ip.TryWriteBytes(integer, out _)
? (UInt128)0
: new UInt128(0, 0xFFFF00000000UL | BinaryPrimitives.ReadUInt32BigEndian(integer));
}
Span<byte> bytes = stackalloc byte[16];
if (!ip.TryWriteBytes(bytes, out _))
{
return 0;
}
var high = BinaryPrimitives.ReadUInt64BigEndian(bytes[..8]);
var low = BinaryPrimitives.ReadUInt64BigEndian(bytes.Slice(8, 8));
return new UInt128(high, low);
}
// Converts a UInt128 in IPv6 format to an IPAddress
public static IPAddress ToIpAddress(this UInt128 value, bool mapToIpv6 = false)
{
// IPv4 mapped IPv6 address
if (!mapToIpv6 && value >= 0xFFFF00000000UL && value <= 0xFFFFFFFFFFFFUL)
{
var newAddress = IPAddress.HostToNetworkOrder((int)value);
return new IPAddress(unchecked((uint)newAddress));
}
Span<byte> bytes = stackalloc byte[16]; // 128 bits for IPv6 address
((IBinaryInteger<UInt128>)value).WriteBigEndian(bytes);
return new IPAddress(bytes);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static UInt128 CreateCidrAddress(ReadOnlySpan<byte> bytes, int prefixLength, bool isMax)
{