diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 9f7ad08456..82a42250a0 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -16,6 +16,7 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Fixed +- Fixed an issue in `UnityTransport` where the transport would accept sends on invalid connections, leading to a useless memory allocation and confusing error message. (#3383) - Fixed issue where `NetworkAnimator` would log an error if there was no destination transition information. (#3384) - Fixed initial `NetworkTransform` spawn, ensure it uses world space. (#3361) - Fixed issue where `AnticipatedNetworkVariable` previous value returned by `AnticipatedNetworkVariable.OnAuthoritativeValueChanged` is updated correctly on the non-authoritative side. (#3322) diff --git a/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs b/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs index 8a8afcdbac..c910b679f1 100644 --- a/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs +++ b/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs @@ -1342,8 +1342,13 @@ public override NetcodeNetworkEvent PollEvent(out ulong clientId, out ArraySegme /// The delivery type (QoS) to send data with public override void Send(ulong clientId, ArraySegment payload, NetworkDelivery networkDelivery) { - var pipeline = SelectSendPipeline(networkDelivery); + var connection = ParseClientId(clientId); + if (!m_Driver.IsCreated || m_Driver.GetConnectionState(connection) != NetworkConnection.State.Connected) + { + return; + } + var pipeline = SelectSendPipeline(networkDelivery); if (pipeline != m_ReliableSequencedPipeline && payload.Count > m_MaxPayloadSize) { Debug.LogError($"Unreliable payload of size {payload.Count} larger than configured 'Max Payload Size' ({m_MaxPayloadSize})."); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTestHelpers.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTestHelpers.cs index 75144f66c3..aeb25434fc 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTestHelpers.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTestHelpers.cs @@ -36,6 +36,23 @@ public static IEnumerator WaitForNetworkEvent(NetworkEvent type, List events, float timeout = MaxNetworkEventWaitTime) + { + int initialCount = events.Count; + float startTime = Time.realtimeSinceStartup; + + while (Time.realtimeSinceStartup - startTime < timeout) + { + if (events.Count > initialCount) + { + Assert.Fail("Received unexpected network event."); + } + + yield return new WaitForSeconds(0.01f); + } + } + // Common code to initialize a UnityTransport that logs its events. public static void InitializeTransport(out UnityTransport transport, out List events, int maxPayloadSize = UnityTransport.InitialMaxPayloadSize, int maxSendQueueSize = 0, NetworkFamily family = NetworkFamily.Ipv4) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTests.cs index 7d5b5c30f5..c33f268b2a 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTests.cs @@ -554,5 +554,22 @@ public IEnumerator DoesNotActAfterShutdown([Values] AfterShutdownAction afterShu m_Server.DisconnectLocalClient(); } } + + [UnityTest] + public IEnumerator DoesNotAttemptToSendOnInvalidConnections() + { + InitializeTransport(out m_Server, out m_ServerEvents); + InitializeTransport(out m_Client1, out m_Client1Events); + + m_Server.StartServer(); + m_Client1.StartClient(); + + yield return WaitForNetworkEvent(NetworkEvent.Connect, m_Client1Events); + + var data = new ArraySegment(new byte[42]); + m_Server.Send(0, data, NetworkDelivery.Reliable); + + yield return EnsureNoNetworkEvent(m_Client1Events); + } } } diff --git a/pvpExceptions.json b/pvpExceptions.json index 0a338d445a..d506649f88 100644 --- a/pvpExceptions.json +++ b/pvpExceptions.json @@ -2591,6 +2591,7 @@ "Unity.Netcode.RuntimeTests.UnityTransportTestHelpers: undocumented", "Unity.Netcode.RuntimeTests.UnityTransportTestHelpers: MaxNetworkEventWaitTime: undocumented", "Unity.Netcode.RuntimeTests.UnityTransportTestHelpers: IEnumerator WaitForNetworkEvent(NetworkEvent, List, float): undocumented", + "Unity.Netcode.RuntimeTests.UnityTransportTestHelpers: IEnumerator EnsureNoNetworkEvent(List, float): undocumented", "Unity.Netcode.RuntimeTests.UnityTransportTestHelpers: void InitializeTransport(out UnityTransport, out List, int, int, NetworkFamily): undocumented", "Unity.Netcode.RuntimeTests.UnityTransportTestHelpers.TransportEvent: undocumented", "Unity.Netcode.RuntimeTests.UnityTransportTestHelpers.TransportEvent: Type: undocumented", @@ -2617,6 +2618,7 @@ "Unity.Netcode.RuntimeTests.UnityTransportTests: IEnumerator SendQueuesFlushedOnRemoteClientDisconnect(NetworkDelivery): undocumented", "Unity.Netcode.RuntimeTests.UnityTransportTests: IEnumerator ReliablePayloadsCanBeLargerThanMaximum(): undocumented", "Unity.Netcode.RuntimeTests.UnityTransportTests: IEnumerator DoesNotActAfterShutdown(AfterShutdownAction): undocumented", + "Unity.Netcode.RuntimeTests.UnityTransportTests: IEnumerator DoesNotAttemptToSendOnInvalidConnections(): undocumented", "Unity.Netcode.RuntimeTests.UnityTransportTests.AfterShutdownAction: undocumented", "Unity.Netcode.RuntimeTests.UnityTransportTests.AfterShutdownAction: Send: undocumented", "Unity.Netcode.RuntimeTests.UnityTransportTests.AfterShutdownAction: DisconnectRemoteClient: undocumented",