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.

This commit is contained in:
vis2k 2020-11-07 17:24:17 +01:00
parent a857707321
commit 87e884c234
10 changed files with 26 additions and 23 deletions

View File

@ -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;
}

View File

@ -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()
{

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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.
/// </summary>
/// <param name="channelId">channel id</param>
/// <returns>the size in bytes that can be sent via the provided channel</returns>
public abstract int GetMaxPacketSize(int channelId = Channels.DefaultReliable);
public abstract ushort GetMaxPacketSize(int channelId = Channels.DefaultReliable);
/// <summary>
/// Shut down the transport, both as client and server

View File

@ -29,7 +29,7 @@ public Message(int connectionId, EventType eventType, byte[] data)
Queue<Message> serverIncoming = new Queue<Message>();
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)

View File

@ -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<int>()).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<ArraySegment<byte>>(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<int>(x => x != id), Arg.Any<int>(), Arg.Any<ArraySegment<byte>>());
}