From 87e884c2340945aa6ef0978923fc7f3490af2504 Mon Sep 17 00:00:00 2001 From: vis2k Date: Sat, 7 Nov 2020 17:24:17 +0100 Subject: [PATCH] breaking: Transport.GetMaxPacketSize changed to ushort. Limits us to 64KB max size which realistically is almost too much for multiplayer games. This will make pooling significantly easier because we can pool all readers/writers with ushort.max size and don't need resizing/buffer swapping anymore. --- Assets/Mirror/Runtime/Transport/FallbackTransport.cs | 8 ++++---- .../Transport/KCP/MirrorTransport/KcpTransport.cs | 2 +- Assets/Mirror/Runtime/Transport/LLAPITransport.cs | 2 +- Assets/Mirror/Runtime/Transport/MiddlewareTransport.cs | 2 +- Assets/Mirror/Runtime/Transport/MultiplexTransport.cs | 8 ++++---- .../Transport/SimpleWebTransport/SimpleWebTransport.cs | 4 ++-- Assets/Mirror/Runtime/Transport/TelepathyTransport.cs | 6 +++--- Assets/Mirror/Runtime/Transport/Transport.cs | 5 ++++- Assets/Mirror/Tests/Common/MemoryTransport.cs | 2 +- Assets/Mirror/Tests/Editor/MiddlewareTransportTest.cs | 10 +++++----- 10 files changed, 26 insertions(+), 23 deletions(-) diff --git a/Assets/Mirror/Runtime/Transport/FallbackTransport.cs b/Assets/Mirror/Runtime/Transport/FallbackTransport.cs index fbb4cedd4..c63d5d25a 100644 --- a/Assets/Mirror/Runtime/Transport/FallbackTransport.cs +++ b/Assets/Mirror/Runtime/Transport/FallbackTransport.cs @@ -158,7 +158,7 @@ public override void Shutdown() available.Shutdown(); } - public override int GetMaxPacketSize(int channelId = 0) + public override ushort GetMaxPacketSize(int channelId = 0) { // finding the max packet size in a fallback environment has to be // done very carefully: @@ -171,11 +171,11 @@ public override int GetMaxPacketSize(int channelId = 0) // different platforms seeing a different game state. // => the safest solution is to use the smallest max size for all // transports. that will never fail. - int mininumAllowedSize = int.MaxValue; + ushort mininumAllowedSize = ushort.MaxValue; foreach (Transport transport in transports) { - int size = transport.GetMaxPacketSize(channelId); - mininumAllowedSize = Mathf.Min(size, mininumAllowedSize); + ushort size = transport.GetMaxPacketSize(channelId); + mininumAllowedSize = Math.Min(size, mininumAllowedSize); } return mininumAllowedSize; } diff --git a/Assets/Mirror/Runtime/Transport/KCP/MirrorTransport/KcpTransport.cs b/Assets/Mirror/Runtime/Transport/KCP/MirrorTransport/KcpTransport.cs index 63066c415..af213b4cf 100644 --- a/Assets/Mirror/Runtime/Transport/KCP/MirrorTransport/KcpTransport.cs +++ b/Assets/Mirror/Runtime/Transport/KCP/MirrorTransport/KcpTransport.cs @@ -120,7 +120,7 @@ public override bool ServerDisconnect(int connectionId) public override void Shutdown() {} // MTU - public override int GetMaxPacketSize(int channelId = Channels.DefaultReliable) => Kcp.MTU_DEF; + public override ushort GetMaxPacketSize(int channelId = Channels.DefaultReliable) => Kcp.MTU_DEF; public override string ToString() { diff --git a/Assets/Mirror/Runtime/Transport/LLAPITransport.cs b/Assets/Mirror/Runtime/Transport/LLAPITransport.cs index a10304ca2..ad23598df 100644 --- a/Assets/Mirror/Runtime/Transport/LLAPITransport.cs +++ b/Assets/Mirror/Runtime/Transport/LLAPITransport.cs @@ -360,7 +360,7 @@ public override void Shutdown() Debug.Log("LLAPITransport.Shutdown"); } - public override int GetMaxPacketSize(int channelId) + public override ushort GetMaxPacketSize(int channelId) { return globalConfig.MaxPacketSize; } diff --git a/Assets/Mirror/Runtime/Transport/MiddlewareTransport.cs b/Assets/Mirror/Runtime/Transport/MiddlewareTransport.cs index b8463c4e1..0ec301d10 100644 --- a/Assets/Mirror/Runtime/Transport/MiddlewareTransport.cs +++ b/Assets/Mirror/Runtime/Transport/MiddlewareTransport.cs @@ -27,7 +27,7 @@ public virtual void Awake() } public override bool Available() => inner.Available(); - public override int GetMaxPacketSize(int channelId = 0) => inner.GetMaxPacketSize(channelId); + public override ushort GetMaxPacketSize(int channelId = 0) => inner.GetMaxPacketSize(channelId); public override void Shutdown() => inner.Shutdown(); #region Client diff --git a/Assets/Mirror/Runtime/Transport/MultiplexTransport.cs b/Assets/Mirror/Runtime/Transport/MultiplexTransport.cs index aa93769ea..07b0e3486 100644 --- a/Assets/Mirror/Runtime/Transport/MultiplexTransport.cs +++ b/Assets/Mirror/Runtime/Transport/MultiplexTransport.cs @@ -235,7 +235,7 @@ public override void ServerStop() } #endregion - public override int GetMaxPacketSize(int channelId = 0) + public override ushort GetMaxPacketSize(int channelId = 0) { // finding the max packet size in a multiplex environment has to be // done very carefully: @@ -248,11 +248,11 @@ public override int GetMaxPacketSize(int channelId = 0) // different platforms seeing a different game state. // => the safest solution is to use the smallest max size for all // transports. that will never fail. - int mininumAllowedSize = int.MaxValue; + ushort mininumAllowedSize = ushort.MaxValue; foreach (Transport transport in transports) { - int size = transport.GetMaxPacketSize(channelId); - mininumAllowedSize = Mathf.Min(size, mininumAllowedSize); + ushort size = transport.GetMaxPacketSize(channelId); + mininumAllowedSize = Math.Min(size, mininumAllowedSize); } return mininumAllowedSize; } diff --git a/Assets/Mirror/Runtime/Transport/SimpleWebTransport/SimpleWebTransport.cs b/Assets/Mirror/Runtime/Transport/SimpleWebTransport/SimpleWebTransport.cs index c111c558a..6cf558169 100644 --- a/Assets/Mirror/Runtime/Transport/SimpleWebTransport/SimpleWebTransport.cs +++ b/Assets/Mirror/Runtime/Transport/SimpleWebTransport/SimpleWebTransport.cs @@ -16,7 +16,7 @@ public class SimpleWebTransport : Transport [Tooltip("Protect against allocation attacks by keeping the max message size small. Otherwise an attacker might send multiple fake packets with 2GB headers, causing the server to run out of memory after allocating multiple large packets.")] - public int maxMessageSize = 16 * 1024; + public ushort maxMessageSize = 16 * 1024; [Tooltip("Max size for http header send as handshake for websockets")] public int handshakeMaxSize = 3000; @@ -81,7 +81,7 @@ public override bool Available() { return true; } - public override int GetMaxPacketSize(int channelId = 0) + public override ushort GetMaxPacketSize(int channelId = 0) { return maxMessageSize; } diff --git a/Assets/Mirror/Runtime/Transport/TelepathyTransport.cs b/Assets/Mirror/Runtime/Transport/TelepathyTransport.cs index 8ba3bc730..515ab8c14 100644 --- a/Assets/Mirror/Runtime/Transport/TelepathyTransport.cs +++ b/Assets/Mirror/Runtime/Transport/TelepathyTransport.cs @@ -23,14 +23,14 @@ public class TelepathyTransport : Transport [Header("Server")] [Tooltip("Protect against allocation attacks by keeping the max message size small. Otherwise an attacker might send multiple fake packets with 2GB headers, causing the server to run out of memory after allocating multiple large packets.")] - [FormerlySerializedAs("MaxMessageSize")] public int serverMaxMessageSize = 16 * 1024; + [FormerlySerializedAs("MaxMessageSize")] public ushort serverMaxMessageSize = 16 * 1024; [Tooltip("Server processes a limit amount of messages per tick to avoid a deadlock where it might end up processing forever if messages come in faster than we can process them.")] public int serverMaxReceivesPerTick = 10000; [Header("Client")] [Tooltip("Protect against allocation attacks by keeping the max message size small. Otherwise an attacker host might send multiple fake packets with 2GB headers, causing the connected clients to run out of memory after allocating multiple large packets.")] - [FormerlySerializedAs("MaxMessageSize")] public int clientMaxMessageSize = 16 * 1024; + [FormerlySerializedAs("MaxMessageSize")] public ushort clientMaxMessageSize = 16 * 1024; [Tooltip("Client processes a limit amount of messages per tick to avoid a deadlock where it might end up processing forever if messages come in faster than we can process them.")] public int clientMaxReceivesPerTick = 1000; @@ -232,7 +232,7 @@ public override void Shutdown() server.Stop(); } - public override int GetMaxPacketSize(int channelId) + public override ushort GetMaxPacketSize(int channelId) { return serverMaxMessageSize; } diff --git a/Assets/Mirror/Runtime/Transport/Transport.cs b/Assets/Mirror/Runtime/Transport/Transport.cs index 86a481976..91cb417f8 100644 --- a/Assets/Mirror/Runtime/Transport/Transport.cs +++ b/Assets/Mirror/Runtime/Transport/Transport.cs @@ -175,10 +175,13 @@ public virtual void ClientConnect(Uri uri) /// Transport isn't running, or isn't Available(). This is because /// Fallback and Multiplex transports need to find the smallest possible /// packet size at runtime. + /// + /// ushort limit of 64KB is more than enough for any multiplayer game + /// and allows Mirror to easily pool writers. /// /// channel id /// the size in bytes that can be sent via the provided channel - public abstract int GetMaxPacketSize(int channelId = Channels.DefaultReliable); + public abstract ushort GetMaxPacketSize(int channelId = Channels.DefaultReliable); /// /// Shut down the transport, both as client and server diff --git a/Assets/Mirror/Tests/Common/MemoryTransport.cs b/Assets/Mirror/Tests/Common/MemoryTransport.cs index f1d789ff9..1b025409c 100644 --- a/Assets/Mirror/Tests/Common/MemoryTransport.cs +++ b/Assets/Mirror/Tests/Common/MemoryTransport.cs @@ -29,7 +29,7 @@ public Message(int connectionId, EventType eventType, byte[] data) Queue serverIncoming = new Queue(); public override bool Available() => true; - public override int GetMaxPacketSize(int channelId) => int.MaxValue; + public override ushort GetMaxPacketSize(int channelId) => ushort.MaxValue; public override void Shutdown() { } public override bool ClientConnected() => clientConnected; public override void ClientConnect(string address) diff --git a/Assets/Mirror/Tests/Editor/MiddlewareTransportTest.cs b/Assets/Mirror/Tests/Editor/MiddlewareTransportTest.cs index 506dba645..8ab655e35 100644 --- a/Assets/Mirror/Tests/Editor/MiddlewareTransportTest.cs +++ b/Assets/Mirror/Tests/Editor/MiddlewareTransportTest.cs @@ -46,10 +46,10 @@ public void TestAvailable(bool available) } [Test] - [TestCase(Channels.DefaultReliable, 4000)] - [TestCase(Channels.DefaultReliable, 2000)] - [TestCase(Channels.DefaultUnreliable, 4000)] - public void TestGetMaxPacketSize(int channel, int packageSize) + [TestCase(Channels.DefaultReliable, (ushort)4000)] + [TestCase(Channels.DefaultReliable, (ushort)2000)] + [TestCase(Channels.DefaultUnreliable, (ushort)4000)] + public void TestGetMaxPacketSize(int channel, ushort packageSize) { inner.GetMaxPacketSize(Arg.Any()).Returns(packageSize); @@ -159,7 +159,7 @@ public void TestServerSend(int id, int channel) middleware.ServerSend(id, channel, segment); inner.Received(1).ServerSend(id, channel, Arg.Is>(x => x.Array == array && x.Offset == offset && x.Count == count)); - // only need to check first arg, + // only need to check first arg, inner.Received(0).ServerSend(Arg.Is(x => x != id), Arg.Any(), Arg.Any>()); }