Skip to content

Commit 20f8f45

Browse files
fix!: MTT-1425 Resolving overflow issue with UTP Adapter (#1300)
* fix: Fixing issue with adapter bugs * feat!: Adding some error message resolution and cleanup serializedfields * fix: Adding a ConnectionAddressData wraper because NetworkEndpoint is not serializable. Co-authored-by: Matt Walsh <[email protected]>
1 parent 3720b3b commit 20f8f45

File tree

2 files changed

+102
-38
lines changed

2 files changed

+102
-38
lines changed

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

Lines changed: 101 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,49 @@ public interface INetworkStreamDriverConstructor
1919
void CreateDriver(UnityTransport transport, out NetworkDriver driver, out NetworkPipeline unreliableSequencedPipeline, out NetworkPipeline reliableSequencedPipeline, out NetworkPipeline reliableSequencedFragmentedPipeline);
2020
}
2121

22+
public static class ErrorUtilities
23+
{
24+
private const string k_NetworkSuccess = "Success";
25+
private const string k_NetworkIdMismatch = "NetworkId is invalid, likely caused by stale connection {0}.";
26+
private const string k_NetworkVersionMismatch = "NetworkVersion is invalid, likely caused by stale connection {0}.";
27+
private const string k_NetworkStateMismatch = "Sending data while connecting on connectionId{0} is now allowed";
28+
private const string k_NetworkPacketOverflow = "Unable to allocate packet due to buffer overflow.";
29+
private const string k_NetworkSendQueueFull = "Currently unable to queue packet as there is too many inflight packets.";
30+
private const string k_NetworkHeaderInvalid = "Invalid Unity Transport Protocol header.";
31+
private const string k_NetworkDriverParallelForErr = "The parallel network driver needs to process a single unique connection per job, processing a single connection multiple times in a parallel for is not supported.";
32+
private const string k_NetworkSendHandleInvalid = "Invalid NetworkInterface Send Handle. Likely caused by pipeline send data corruption.";
33+
private const string k_NetworkArgumentMismatch = "Invalid NetworkEndpoint Arguments.";
34+
35+
public static string ErrorToString(Networking.Transport.Error.StatusCode error, ulong connectionId)
36+
{
37+
switch (error)
38+
{
39+
case Networking.Transport.Error.StatusCode.Success:
40+
return k_NetworkSuccess;
41+
case Networking.Transport.Error.StatusCode.NetworkIdMismatch:
42+
return string.Format(k_NetworkIdMismatch, connectionId);
43+
case Networking.Transport.Error.StatusCode.NetworkVersionMismatch:
44+
return string.Format(k_NetworkVersionMismatch, connectionId);
45+
case Networking.Transport.Error.StatusCode.NetworkStateMismatch:
46+
return string.Format(k_NetworkStateMismatch, connectionId);
47+
case Networking.Transport.Error.StatusCode.NetworkPacketOverflow:
48+
return k_NetworkPacketOverflow;
49+
case Networking.Transport.Error.StatusCode.NetworkSendQueueFull:
50+
return k_NetworkSendQueueFull;
51+
case Networking.Transport.Error.StatusCode.NetworkHeaderInvalid:
52+
return k_NetworkHeaderInvalid;
53+
case Networking.Transport.Error.StatusCode.NetworkDriverParallelForErr:
54+
return k_NetworkDriverParallelForErr;
55+
case Networking.Transport.Error.StatusCode.NetworkSendHandleInvalid:
56+
return k_NetworkSendHandleInvalid;
57+
case Networking.Transport.Error.StatusCode.NetworkArgumentMismatch:
58+
return k_NetworkArgumentMismatch;
59+
}
60+
61+
return $"Unknown ErrorCode {Enum.GetName(typeof(Networking.Transport.Error.StatusCode), error)}";
62+
}
63+
}
64+
2265
public class UnityTransport : NetworkTransport, INetworkStreamDriverConstructor
2366
{
2467
public enum ProtocolType
@@ -34,23 +77,43 @@ private enum State
3477
Connected,
3578
}
3679

37-
public const int MaximumMessageLength = 6 * 1024;
80+
public const int InitialBatchQueueSize = 6 * 1024;
81+
public const int InitialMaxPacketSize = NetworkParameterConstants.MTU;
82+
83+
private static ConnectionAddressData s_DefaultConnectionAddressData = new ConnectionAddressData()
84+
{ Address = "127.0.0.1", Port = 7777 };
3885

3986
#pragma warning disable IDE1006 // Naming Styles
4087
public static INetworkStreamDriverConstructor s_DriverConstructor;
4188
#pragma warning restore IDE1006 // Naming Styles
4289
public INetworkStreamDriverConstructor DriverConstructor => s_DriverConstructor != null ? s_DriverConstructor : this;
4390

91+
[Tooltip("Which protocol should be selected Relay/Non-Relay")]
4492
[SerializeField] private ProtocolType m_ProtocolType;
45-
[SerializeField] private int m_MessageBufferSize = MaximumMessageLength;
46-
[SerializeField] private int m_ReciveQueueSize = 128;
47-
[SerializeField] private int m_SendQueueSize = 128;
4893

49-
[Tooltip("The maximum size of the send queue for batching Netcode events")]
50-
[SerializeField] private int m_SendQueueBatchSize = 4096;
94+
[Tooltip("Maximum size in bytes for a given packet")]
95+
[SerializeField] private int m_MaximumPacketSize = InitialMaxPacketSize;
96+
97+
[Tooltip("The maximum amount of packets that can be in the send/recv queues")]
98+
[SerializeField] private int m_MaxPacketQueueSize = 128;
99+
100+
[Tooltip("The maximum size in bytes of the send queue for batching Netcode events")]
101+
[SerializeField] private int m_SendQueueBatchSize = InitialBatchQueueSize;
51102

52-
[SerializeField] private string m_ServerAddress = "127.0.0.1";
53-
[SerializeField] private ushort m_ServerPort = 7777;
103+
[Serializable]
104+
public struct ConnectionAddressData
105+
{
106+
[SerializeField] public string Address;
107+
[SerializeField] public int Port;
108+
109+
public static implicit operator NetworkEndPoint(ConnectionAddressData d) =>
110+
NetworkEndPoint.Parse(d.Address, (ushort)d.Port);
111+
112+
public static implicit operator ConnectionAddressData(NetworkEndPoint d) =>
113+
new ConnectionAddressData() { Address = d.Address.Split(':')[0], Port = d.Port };
114+
}
115+
116+
public ConnectionAddressData ConnectionData = s_DefaultConnectionAddressData;
54117

55118
private State m_State = State.Disconnected;
56119
private NetworkDriver m_Driver;
@@ -171,7 +234,7 @@ private bool ClientBindAndConnect()
171234
}
172235
else
173236
{
174-
serverEndpoint = NetworkEndPoint.Parse(m_ServerAddress, m_ServerPort);
237+
serverEndpoint = ConnectionData;
175238
}
176239

177240
InitDriver();
@@ -273,8 +336,16 @@ public void SetRelayServerData(string ipv4Address, ushort port, byte[] allocatio
273336
/// </summary>
274337
public void SetConnectionData(string ipv4Address, ushort port)
275338
{
276-
m_ServerAddress = ipv4Address;
277-
m_ServerPort = port;
339+
ConnectionData.Address = ipv4Address;
340+
ConnectionData.Port = port;
341+
}
342+
343+
/// <summary>
344+
/// Sets IP and Port information. This will be ignored if using the Unity Relay and you should call <see cref="SetRelayServerData"/>
345+
/// </summary>
346+
public void SetConnectionData(NetworkEndPoint endPoint)
347+
{
348+
ConnectionData = endPoint;
278349
}
279350

280351
private bool StartRelayServer()
@@ -372,25 +443,23 @@ private bool ProcessEvent()
372443

373444
private unsafe void ReadData(int size, ref DataStreamReader reader, ref NetworkConnection networkConnection)
374445
{
375-
if (size > m_MessageBufferSize)
446+
if (size > m_SendQueueBatchSize)
376447
{
377-
Debug.LogError("The received message does not fit into the message buffer");
448+
Debug.LogError($"The received message does not fit into the message buffer: {size} {m_SendQueueBatchSize}");
378449
}
379450
else
380451
{
381452
unsafe
382453
{
383-
fixed (byte* buffer = &m_MessageBuffer[0])
384-
{
385-
reader.ReadBytes(buffer, size);
386-
}
454+
using var data = new NativeArray<byte>(size, Allocator.Temp);
455+
reader.ReadBytes(data);
456+
457+
InvokeOnTransportEvent(NetcodeNetworkEvent.Data,
458+
ParseClientId(networkConnection),
459+
new ArraySegment<byte>(data.ToArray(), 0, size),
460+
Time.realtimeSinceStartup
461+
);
387462
}
388-
389-
InvokeOnTransportEvent(NetcodeNetworkEvent.Data,
390-
ParseClientId(networkConnection),
391-
new ArraySegment<byte>(m_MessageBuffer, 0, size),
392-
Time.realtimeSinceStartup
393-
);
394463
}
395464
}
396465

@@ -438,7 +507,6 @@ public override void DisconnectLocalClient()
438507

439508
m_State = State.Disconnected;
440509

441-
442510
// If we successfully disconnect we dispatch a local disconnect message
443511
// this how uNET and other transports worked and so this is just keeping with the old behavior
444512
// should be also noted on the client this will call shutdown on the NetworkManager and the Transport
@@ -491,23 +559,20 @@ public override void Initialize()
491559
{
492560
Debug.Assert(sizeof(ulong) == UnsafeUtility.SizeOf<NetworkConnection>(),
493561
"Netcode connection id size does not match UTP connection id size");
494-
Debug.Assert(m_MessageBufferSize > 5, "Message buffer size must be greater than 5");
562+
Debug.Assert(m_MaximumPacketSize > 5, "Message buffer size must be greater than 5");
495563

496564
m_NetworkParameters = new List<INetworkParameter>();
497565

498566
// If we want to be able to actually handle messages MaximumMessageLength bytes in
499567
// size, we need to allow a bit more than that in FragmentationUtility since this needs
500568
// to account for headers and such. 128 bytes is plenty enough for such overhead.
501-
var maxFragmentationCapacity = MaximumMessageLength + 128;
502-
m_NetworkParameters.Add(new FragmentationUtility.Parameters() { PayloadCapacity = maxFragmentationCapacity });
569+
m_NetworkParameters.Add(new FragmentationUtility.Parameters() { PayloadCapacity = m_SendQueueBatchSize });
503570
m_NetworkParameters.Add(new BaselibNetworkParameter()
504571
{
505-
maximumPayloadSize = (uint)m_MessageBufferSize,
506-
receiveQueueCapacity = m_ReciveQueueSize,
507-
sendQueueCapacity = m_SendQueueSize
572+
maximumPayloadSize = (uint)m_MaximumPacketSize,
573+
receiveQueueCapacity = m_MaxPacketQueueSize,
574+
sendQueueCapacity = m_MaxPacketQueueSize
508575
});
509-
510-
m_MessageBuffer = new byte[m_MessageBufferSize];
511576
}
512577

513578
public override NetcodeNetworkEvent PollEvent(out ulong clientId, out ArraySegment<byte> payload, out float receiveTime)
@@ -556,7 +621,6 @@ private unsafe void SendBatchedMessage(ulong clientId, ref NativeArray<byte> dat
556621
{
557622
var payloadSize = data.Length + 1; // One extra byte to mark whether this message is batched or not
558623
var result = m_Driver.BeginSend(pipeline, ParseClientId(clientId), out var writer, payloadSize);
559-
560624
if (result == 0)
561625
{
562626
if (data.IsCreated)
@@ -573,13 +637,14 @@ private unsafe void SendBatchedMessage(ulong clientId, ref NativeArray<byte> dat
573637
}
574638
}
575639

576-
Debug.LogError($"Error sending the message {result}");
640+
Debug.LogError($"Error sending the message: {ErrorUtilities.ErrorToString((Networking.Transport.Error.StatusCode)result, clientId)}");
577641
}
578642

579643
private unsafe void SendMessageInstantly(ulong clientId, ArraySegment<byte> data, NetworkPipeline pipeline)
580644
{
581645
var payloadSize = data.Count + 1 + 4; // 1 byte to indicate if the message is batched and 4 for the payload size
582646
var result = m_Driver.BeginSend(pipeline, ParseClientId(clientId), out var writer, payloadSize);
647+
583648
if (result == 0)
584649
{
585650
if (data.Array != null)
@@ -604,7 +669,7 @@ private unsafe void SendMessageInstantly(ulong clientId, ArraySegment<byte> data
604669
}
605670
}
606671

607-
Debug.LogError($"Error sending the message {result}");
672+
Debug.LogError($"Error sending the message: {ErrorUtilities.ErrorToString((Networking.Transport.Error.StatusCode)result, clientId)}");
608673
}
609674

610675
/// <summary>
@@ -657,7 +722,7 @@ public override bool StartServer()
657722
switch (m_ProtocolType)
658723
{
659724
case ProtocolType.UnityTransport:
660-
return ServerBindAndListen(NetworkEndPoint.Parse(m_ServerAddress, m_ServerPort));
725+
return ServerBindAndListen(ConnectionData);
661726
case ProtocolType.RelayUnityTransport:
662727
return StartRelayServer();
663728
default:
@@ -743,7 +808,6 @@ public void CreateDriver(UnityTransport transport, out NetworkDriver driver, out
743808
}
744809
}
745810

746-
747811
// -------------- Utility Types -------------------------------------------------------------------------------
748812

749813
/// <summary>

com.unity.netcode.adapter.utp/Tests/Runtime/Helpers/DriverClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public class DriverClient : MonoBehaviour
3535

3636
private void Awake()
3737
{
38-
var maxCap = UnityTransport.MaximumMessageLength + 128;
38+
var maxCap = UnityTransport.InitialBatchQueueSize + 128;
3939
var fragParams = new FragmentationUtility.Parameters() { PayloadCapacity = maxCap };
4040

4141
m_Driver = NetworkDriver.Create(fragParams);

0 commit comments

Comments
 (0)