feat: Upgrades networking to use io_uring. (#2315)
> [!IMPORTANT] > **Breaking Changes** > - DecodePacket and EncodePacket delegates replaced with IClientEncryption interface > - NetState.Connection (Socket) replaced with internal RingSocket management > - NetState.RecvPipe and NetState.SendPipe removed (buffers managed internally) ## Summary Upgrades the networking stack from PollGroup-based I/O to io_uring, significantly improving I/O performance on Linux. This also adds native client encryption support for encrypted UO clients. ## Major Changes io_uring Networking Architecture - Replaced PollGroup with IORingGroup for async socket I/O operations - Removed Pipe.cs (mirrored ring buffer) and TcpServer.cs in favor of RingSocketManager - Added NetState.Network.cs - centralized network infrastructure handling accept, recv, send, and disconnect completions - Added SocketHelper.cs - platform-specific socket utilities for raw socket handle operations (getpeername, getsockname) - Buffer management now handled by RingSocketManager with configurable slab allocation ### Client Encryption Support - Added full encryption stack in Network/Encryption/: - EncryptionConfig.cs - configurable encryption modes (None, Unencrypted, Encrypted, Both) - EncryptionManager.cs - encryption detection and initialization for login/game packets - LoginEncryption.cs - handles login packet encryption with version-derived keys - GameEncryption.cs - handles game server encryption using Twofish - TwofishEngine.cs - optimized Twofish block cipher implementation - LoginKeys.cs - encryption key table for client versions - IClientEncryption.cs - interface for client encryption implementations ### NetState Improvements - Replaced Socket Connection with RingSocket _socket for managed socket lifecycle - Changed from GCHandle polling to event-based completion processing - Disconnect handling now properly waits for pending sends to flush - Simplified connecting socket management using lazy queue removal ### Configuration - New settings: network.encryptionMode and network.encryptionDebug - Encryption mode flags: Unencrypted, Encrypted, or Both ### Dependencies - Replaced PollGroup NuGet package with IORingGroup - Linux requires liburing-dev / liburing-devel package ### Test plan - Verify server starts and accepts connections on Linux with io_uring - Verify server starts and accepts connections on Windows (fallback to IOCP) - Test unencrypted client connections (ClassicUO with encryption disabled) - Test encrypted client connections if available - Verify graceful disconnect flushes pending data - Confirm CI builds pass on all target platforms
This commit is contained in:
parent
91a553b0bc
commit
3c0d6cb9d6
70 changed files with 2227 additions and 1468 deletions
|
|
@ -17,7 +17,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendDeathAnimation(killed, corpse);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendBondedStatus(petSerial, bonded);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ public class MobilePacketTests
|
|||
|
||||
ns.SendMobileMoving(m, noto);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendMobileName(m);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +102,7 @@ public class MobilePacketTests
|
|||
delay
|
||||
);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ public class MobilePacketTests
|
|||
delay
|
||||
);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +148,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendMobileHealthbar(m, Healthbar.Poison);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +169,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendMobileHealthbar(m, Healthbar.Yellow);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -192,7 +192,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendMobileStatusCompact(m, canBeRenamed);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -225,7 +225,7 @@ public class MobilePacketTests
|
|||
var expected = new MobileStatus(beholder, beheld, ns).Compile();
|
||||
ns.SendMobileStatus(beholder, beheld);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -263,7 +263,7 @@ public class MobilePacketTests
|
|||
var expected = new MobileStatusExtended(m, ns).Compile();
|
||||
ns.SendMobileStatus(m, m);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
Core.Expansion = oldExpansion;
|
||||
expansionInfo.MobileStatusVersion = oldVersion;
|
||||
|
|
@ -284,7 +284,7 @@ public class MobilePacketTests
|
|||
var expected = new MobileUpdate(m, ns.StygianAbyss).Compile();
|
||||
ns.SendMobileUpdate(m);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -339,7 +339,7 @@ public class MobilePacketTests
|
|||
var expected = new MobileIncoming(ns, beholder, beheld).Compile();
|
||||
ns.SendMobileIncoming(beholder, beheld);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -356,7 +356,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendMobileHits(m);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -373,7 +373,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendMobileHits(m, true);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -390,7 +390,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendMobileMana(m);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -407,7 +407,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendMobileMana(m, true);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -424,7 +424,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendMobileStam(m);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -441,7 +441,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendMobileStam(m, true);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -462,7 +462,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendMobileAttributes(m);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -483,7 +483,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendMobileAttributes(m, true);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
|
||||
|
|
@ -496,7 +496,7 @@ public class MobilePacketTests
|
|||
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendRemoveEntity(e);
|
||||
|
||||
var result = ns.SendPipe.Reader.AvailableToRead();
|
||||
var result = ns.SendBuffer.GetReadSpan();
|
||||
AssertThat.Equal(result, expected);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue