Skip to content

Commit b4a1e56

Browse files
fix: Address packet overflow issues in the UTP adapter (#1403)
* Remove maximum packet size setting It doesn't mean anything now. Anything sent on fragmented pipelines will be broken up at 1400 bytes boundaries, and everything sent on a non-fragmented pipeline is limited to a maximum size of 1400 bytes (including overhead from the underlying protocols). Allowing to set that limit can only lead to confusion among users. * Send all reliable data on a fragmented pipeline This is not the cleanest of solution, but until we figure out something better in UTP, this can at least unblock Boss Room. The core issue being fixed here is that we'd allow sending payloads up to the MTU in size on a non-fragmented pipeline. But that's incorrect since UTP must add its own overhead to the payload. If sending a payload close to the MTU in size, the overhead would bring the total packet size over the limit of the MTU. Since UTP lacks a good way of figuring out what's the actual maximum payload size that can be sent, for now we patch over the issue by sending everything on a fragmented pipeline. The exception is the unreliable messages. The fragmentation pipeline doesn't cleanly handle having multiple fragmented payloads in flight (and possibly arriving out of order). The reliable pipeline stage fixes that, but for unreliable traffic it's better not to fragment it. * Update adapter's CHANGELOG to reflect latest fixes * Set baselib's maximum payload size to its default Which is 2000 bytes. We won't need to hardcode that default value when the new NetworkSettings API lands. So having a magical number floating like that in the code is a temporary thing.
1 parent 940ee90 commit b4a1e56

File tree

2 files changed

+15
-24
lines changed

2 files changed

+15
-24
lines changed

com.unity.netcode.adapter.utp/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
# Changelog
22
All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
33

4+
## [Unreleased]
5+
6+
### Changed
7+
8+
- Removed 'Maximum Packet Size' configuration field in the inspector. This would cause confusion since the maximum packet size is in effect always the MTU (1400 bytes on most platforms).
9+
10+
### Fixed
11+
12+
- Fixed packet overflow errors when sending payloads too close to the MTU (was mostly visible when using Relay).
13+
414
## [1.0.0-pre.3] - 2021-10-22
515

616
#### Added

com.unity.netcode.adapter.utp/Runtime/UnityTransport.cs

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace Unity.Netcode
1616
/// </summary>
1717
public interface INetworkStreamDriverConstructor
1818
{
19-
void CreateDriver(UnityTransport transport, out NetworkDriver driver, out NetworkPipeline unreliableSequencedPipeline, out NetworkPipeline reliableSequencedPipeline, out NetworkPipeline reliableSequencedFragmentedPipeline);
19+
void CreateDriver(UnityTransport transport, out NetworkDriver driver, out NetworkPipeline unreliableSequencedPipeline, out NetworkPipeline reliableSequencedFragmentedPipeline);
2020
}
2121

2222
public static class ErrorUtilities
@@ -78,7 +78,6 @@ private enum State
7878
}
7979

8080
public const int InitialBatchQueueSize = 6 * 1024;
81-
public const int InitialMaxPacketSize = NetworkParameterConstants.MTU;
8281

8382
private static ConnectionAddressData s_DefaultConnectionAddressData = new ConnectionAddressData()
8483
{ Address = "127.0.0.1", Port = 7777 };
@@ -91,9 +90,6 @@ private enum State
9190
[Tooltip("Which protocol should be selected Relay/Non-Relay")]
9291
[SerializeField] private ProtocolType m_ProtocolType;
9392

94-
[Tooltip("Maximum size in bytes for a given packet")]
95-
[SerializeField] private int m_MaximumPacketSize = InitialMaxPacketSize;
96-
9793
[Tooltip("The maximum amount of packets that can be in the send/recv queues")]
9894
[SerializeField] private int m_MaxPacketQueueSize = 128;
9995

@@ -146,7 +142,6 @@ public static implicit operator ConnectionAddressData(NetworkEndPoint d) =>
146142
private ulong m_ServerClientId;
147143

148144
private NetworkPipeline m_UnreliableSequencedPipeline;
149-
private NetworkPipeline m_ReliableSequencedPipeline;
150145
private NetworkPipeline m_ReliableSequencedFragmentedPipeline;
151146

152147
public override ulong ServerClientId => m_ServerClientId;
@@ -199,7 +194,7 @@ public SimulatorUtility.Parameters ClientSimulatorParameters
199194

200195
private void InitDriver()
201196
{
202-
DriverConstructor.CreateDriver(this, out m_Driver, out m_UnreliableSequencedPipeline, out m_ReliableSequencedPipeline, out m_ReliableSequencedFragmentedPipeline);
197+
DriverConstructor.CreateDriver(this, out m_Driver, out m_UnreliableSequencedPipeline, out m_ReliableSequencedFragmentedPipeline);
203198
}
204199

205200
private void DisposeDriver()
@@ -222,15 +217,7 @@ private NetworkPipeline SelectSendPipeline(NetworkDelivery delivery, int size)
222217

223218
case NetworkDelivery.Reliable:
224219
case NetworkDelivery.ReliableSequenced:
225-
return m_ReliableSequencedPipeline;
226-
227220
case NetworkDelivery.ReliableFragmentedSequenced:
228-
// No need to send on the fragmented pipeline if data is smaller than MTU.
229-
if (size < NetworkParameterConstants.MTU)
230-
{
231-
return m_ReliableSequencedPipeline;
232-
}
233-
234221
return m_ReliableSequencedFragmentedPipeline;
235222

236223
default:
@@ -607,7 +594,6 @@ public override void Initialize()
607594
{
608595
Debug.Assert(sizeof(ulong) == UnsafeUtility.SizeOf<NetworkConnection>(),
609596
"Netcode connection id size does not match UTP connection id size");
610-
Debug.Assert(m_MaximumPacketSize > 5, "Message buffer size must be greater than 5");
611597

612598
m_NetworkParameters = new List<INetworkParameter>();
613599

@@ -620,7 +606,7 @@ public override void Initialize()
620606

621607
m_NetworkParameters.Add(new BaselibNetworkParameter()
622608
{
623-
maximumPayloadSize = (uint)m_MaximumPacketSize,
609+
maximumPayloadSize = 2000, // Default value in UTP.
624610
receiveQueueCapacity = m_MaxPacketQueueSize,
625611
sendQueueCapacity = m_MaxPacketQueueSize
626612
});
@@ -743,7 +729,7 @@ private void SendBatchedMessageAndClearQueue(SendTarget sendTarget, SendQueue se
743729
var payloadSize = sendQueue.Count + 1; // 1 extra byte to tell whether the message is batched or not
744730
if (payloadSize > NetworkParameterConstants.MTU) // If this is bigger than MTU then force it to be sent via the FragmentedReliableSequencedPipeline
745731
{
746-
pipeline = SelectSendPipeline(NetworkDelivery.ReliableFragmentedSequenced, payloadSize);
732+
pipeline = m_ReliableSequencedFragmentedPipeline;
747733
}
748734

749735
var sendBuffer = sendQueue.GetData();
@@ -805,7 +791,7 @@ public override void Shutdown()
805791
m_ServerClientId = 0;
806792
}
807793

808-
public void CreateDriver(UnityTransport transport, out NetworkDriver driver, out NetworkPipeline unreliableSequencedPipeline, out NetworkPipeline reliableSequencedPipeline, out NetworkPipeline reliableSequencedFragmentedPipeline)
794+
public void CreateDriver(UnityTransport transport, out NetworkDriver driver, out NetworkPipeline unreliableSequencedPipeline, out NetworkPipeline reliableSequencedFragmentedPipeline)
809795
{
810796
var netParams = new NetworkConfigParameter
811797
{
@@ -839,10 +825,6 @@ public void CreateDriver(UnityTransport transport, out NetworkDriver driver, out
839825
typeof(UnreliableSequencedPipelineStage),
840826
typeof(SimulatorPipelineStage),
841827
typeof(SimulatorPipelineStageInSend));
842-
reliableSequencedPipeline = driver.CreatePipeline(
843-
typeof(ReliableSequencedPipelineStage),
844-
typeof(SimulatorPipelineStage),
845-
typeof(SimulatorPipelineStageInSend));
846828
reliableSequencedFragmentedPipeline = driver.CreatePipeline(
847829
typeof(FragmentationPipelineStage),
848830
typeof(ReliableSequencedPipelineStage),
@@ -853,7 +835,6 @@ public void CreateDriver(UnityTransport transport, out NetworkDriver driver, out
853835
#endif
854836
{
855837
unreliableSequencedPipeline = driver.CreatePipeline(typeof(UnreliableSequencedPipelineStage));
856-
reliableSequencedPipeline = driver.CreatePipeline(typeof(ReliableSequencedPipelineStage));
857838
reliableSequencedFragmentedPipeline = driver.CreatePipeline(
858839
typeof(FragmentationPipelineStage), typeof(ReliableSequencedPipelineStage)
859840
);

0 commit comments

Comments
 (0)