fix: Fixes networking issues (#1958)

### Summary
- Puts back `EventSink.SocketConnect`.
- Reverts networking change to push the networking to a separate thread.
- Reverts changes to the firewall by removing the firewall queue.
- Fixes listeners not shutting down with the server.
- Fixes race condition causing connections to get stuck even after they are disposed.

> [!NOTE]
> **Developer Note**
> Networking has been reverted back to using the main thread instead of a background thread. This alleviated complexity and the requirement for concurrent queues all over the place.
This commit is contained in:
Kamron Batman 2024-09-19 16:54:49 -07:00 • committed by GitHub
parent 97c53e656e
commit e0fcde885c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 211 additions and 340 deletions

View file

@ -14,83 +14,21 @@
*************************************************************************/
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Server.Logging;
namespace Server.Network;
public static class Firewall
{
private static readonly ILogger logger = LogFactory.GetLogger(typeof(Firewall));
private static InternalValidationEntry _validationEntry;
private static readonly Dictionary<IPAddress, bool> _isBlockedCache = new();
private static readonly ConcurrentQueue<(IFirewallEntry FirewallyEntry, bool Remove)> _firewallQueue = new();
private static readonly SortedSet<IFirewallEntry> _firewallSet = new();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IFirewallEntry RequestAddSingleIPEntry(string entry)
{
try
{
var firewallEntry = new SingleIpFirewallEntry(entry);
_firewallQueue.Enqueue((firewallEntry, false));
return firewallEntry;
}
catch (Exception e)
{
logger.Warning(e, "Failed to add firewall entry: {Pattern}", entry);
return null;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IFirewallEntry RequestAddCIDREntry(string entry)
{
try
{
var firewallEntry = new CidrFirewallEntry(entry);
_firewallQueue.Enqueue((firewallEntry, false));
return firewallEntry;
}
catch (Exception e)
{
logger.Warning(e, "Failed to add firewall entry: {Pattern}", entry);
return null;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void RequestAddEntry(IFirewallEntry entry)
{
_firewallQueue.Enqueue((entry, false));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void RequestRemoveEntry(IFirewallEntry entry)
{
_firewallQueue.Enqueue((entry, true));
}
internal static void ProcessQueue()
{
while (_firewallQueue.TryDequeue(out var entry))
{
if (entry.Remove)
{
RemoveEntry(entry.FirewallyEntry);
}
else
{
AddEntry(entry.FirewallyEntry);
}
}
}
public static SortedSet<IFirewallEntry> FirewallSet => _firewallSet;
internal static bool IsBlocked(IPAddress address)
{
@ -128,22 +66,32 @@ public static class Firewall
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AddEntry(IFirewallEntry firewallEntry)
public static bool Add(IFirewallEntry firewallEntry)
{
_firewallSet.Add(firewallEntry);
_isBlockedCache.Clear();
if (_firewallSet.Add(firewallEntry))
{
_isBlockedCache.Clear();
return true;
}
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void RemoveEntry(IFirewallEntry entry)
public static bool Remove(IFirewallEntry entry)
{
if (entry == null)
{
return;
return false;
}
_firewallSet.Remove(entry);
_isBlockedCache.Clear();
if (_firewallSet.Remove(entry))
{
_isBlockedCache.Clear();
return true;
}
return false;
}
private class InternalValidationEntry : BaseFirewallEntry