Skip to content

Commit

Permalink
fix: MultiplexTransport GetMaxMessageSize NullReferenceException when…
Browse files Browse the repository at this point in the history
… called on server. And fixes potential exploits / out of sync issues where clients with different transports might see different game states because of different max message sizes. (#1332)
  • Loading branch information
miwarnec authored and paulpach committed Dec 21, 2019
1 parent 9a0127a commit b3127be
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
27 changes: 22 additions & 5 deletions Assets/Mirror/Runtime/Transport/MultiplexTransport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,6 @@ public override bool ClientSend(int channelId, ArraySegment<byte> segment)
return available.ClientSend(channelId, segment);
}

public override int GetMaxPacketSize(int channelId = 0)
{
return available.GetMaxPacketSize(channelId);
}

#endregion

#region Server
Expand Down Expand Up @@ -239,6 +234,28 @@ public override void ServerStop()
}
#endregion

public override int GetMaxPacketSize(int channelId = 0)
{
// finding the max packet size in a multiplex environment has to be
// done very carefully:
// * servers run multiple transports at the same time
// * different clients run different transports
// * there should only ever be ONE true max packet size for everyone,
// otherwise a spawn message might be sent to all tcp sockets, but
// be too big for some udp sockets. that would be a debugging
// nightmare and allow for possible exploits and players on
// 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;
foreach (Transport transport in transports)
{
int size = transport.GetMaxPacketSize(channelId);
mininumAllowedSize = Mathf.Min(size, mininumAllowedSize);
}
return mininumAllowedSize;
}

public override void Shutdown()
{
foreach (Transport transport in transports)
Expand Down
7 changes: 6 additions & 1 deletion Assets/Mirror/Runtime/Transport/Transport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,13 @@ public virtual bool GetConnectionInfo(int connectionId, out string address)

/// <summary>
/// The maximum packet size for a given channel. Unreliable transports
/// usually can only deliver small packets. Reliable fragmented channels
/// usually can only deliver small packets. Reliable fragmented channels
/// can usually deliver large ones.
///
/// GetMaxPacketSize needs to return a value at all times. Even if the
/// 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.
/// </summary>
/// <param name="channelId">channel id</param>
/// <returns>the size in bytes that can be sent via the provided channel</returns>
Expand Down

0 comments on commit b3127be

Please sign in to comment.