Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
## [1.0.0-pre.7] - 2021-10-21

### Changes
* Some public APIs that should have always been internal are now internal (`Base64`, `SHA256`, `HMACSHA256`, `NetworkEventQueue`, `UdpCHeader`, `UdpCProtocol`, `SessionIdToken`, `NativeMultiQueue`).

### Fixes
* Fixed: Couldn't send a payload of the configured payload size on fragmented pipelines
  • Loading branch information
Unity Technologies committed Oct 21, 2021
1 parent f7eb546 commit 542f92e
Show file tree
Hide file tree
Showing 21 changed files with 90 additions and 86 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
# Change log

## [1.0.0-pre.7] - 2021-10-21

### Changes
* Some public APIs that should have always been internal are now internal (`Base64`, `SHA256`, `HMACSHA256`, `NetworkEventQueue`, `UdpCHeader`, `UdpCProtocol`, `SessionIdToken`, `NativeMultiQueue`).

### Fixes
* Fixed: Couldn't send a payload of the configured payload size on fragmented pipelines

## [1.0.0-pre.6] - 2021-10-14

### New features
* Added heartbeats functionality to all protocols (enabled by default). If there's no traffic on a connection for some time, a heartbeat is automatically sent to keep the connection alive. The inactivity timeout is controlled by the new parameter `heartbeatTimeoutMS` in `NetworkConfigParameter`. Setting it to 0 disables the feature.

### Changes
* Added `heartbeatTimeoutMS` in `NetworkConfigParameter` to support heartbeats (see above).
* `NetworkDriver.Bind` is now synchronous when using Relay (matches behavior of other protocols).
Expand All @@ -12,12 +21,14 @@
* MTU decreased to 1384 (from 1400) on Xbox platforms.
* `Connect` will automatically bind the driver if not already bound. This was already done implicitly before, but now it's explicit (the `NetworkDriver.Bound` property will be true after a successful call to `Connect`).
* Added `DataStream.ReadLong`

### Fixes
* Fixed: Receiving a Disconnect message on DTLS would crash the receive job
* Fixed: TLS server name might be set to nothing in Relay+DTLS, causing the handshake to fail
* Fixed: Couldn't send large messages on fragmented pipeline if `requiredPayloadSize` was not provided to `BeginSend`
* Fixed: DTLS handshake messages were never resent if lost
* Fixed: Clients wouldn't honor the endpoint their were bound to

### Known issues
* Function pointers (for instance in `BeginSend` and `EndSend`) generate GC allocations in non-Burst use cases. The issue will be fixed in the next releases
* XboxOne(S/X) crash when using fragmentation pipeline when the size of the packet is within 100 bytes of the MTU. This will be fixed in the next release
Expand Down
2 changes: 2 additions & 0 deletions Runtime/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Unity.Networking.Transport.EditorTests")]
[assembly: InternalsVisibleTo("Unity.Networking.Transport.PlayTests")]
[assembly: InternalsVisibleTo("Unity.Networking.Transport.PlayTests.Performance")]

// We are making certain things visible for certain projects that require
// access to Network Protocols thus not requiring the API be visible
Expand Down
2 changes: 1 addition & 1 deletion Runtime/Base64.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Unity.Networking.Transport
/// <summary>
/// Utility class used to Decode a base64 string
/// </summary>
public static class Base64
internal static class Base64
{
/// <summary>
/// Decode characters representing a Base64 encoding into bytes.
Expand Down
2 changes: 1 addition & 1 deletion Runtime/HMACSHA256.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Unity.Networking.Transport
/// <summary>
/// Utility class used to compute HMACSHA256 hash
/// </summary>
public static class HMACSHA256
internal static class HMACSHA256
{
/// <summary>
/// Writes 32 bytes to result using key and message
Expand Down
45 changes: 34 additions & 11 deletions Runtime/NetworkDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,27 +191,50 @@ public unsafe int BeginSend(NetworkPipeline pipe, NetworkConnection id,

var pipelineHeader = (pipe.Id > 0) ? m_PipelineProcessor.SendHeaderCapacity(pipe) + 1 : 0;
var pipelinePayloadCapacity = m_PipelineProcessor.PayloadCapacity(pipe);
var payloadCapacity = requiredPayloadSize > 0 ? math.min(requiredPayloadSize + pipelineHeader, pipelinePayloadCapacity) : pipelinePayloadCapacity;

// This will set the payloadCapacity value to the actual capacity provided by the protocol
var packetAllocationSize = m_NetworkProtocolInterface.ComputePacketAllocationSize.Ptr.Invoke(ref connection, m_NetworkProtocolInterface.UserData, ref payloadCapacity, out var payloadOffset);

payloadCapacity -= pipelineHeader;

var protocolOverhead = m_NetworkProtocolInterface.ComputePacketOverhead.Ptr.Invoke(ref connection, out var payloadOffset);

// If the pipeline doesn't have an explicity payload capacity, then use whatever
// will fit inside the MTU (considering protocol and pipeline overhead). If there is
// an explicity pipeline payload capacity we use that directly. Right now only
// fragmented pipelines have an explicity capacity, and we want users to be able to
// rely on this configured value.
var payloadCapacity = pipelinePayloadCapacity == 0
? NetworkParameterConstants.MTU - protocolOverhead - pipelineHeader
: pipelinePayloadCapacity;

// Total capacity is the full size of the buffer we'll allocate. Without an explicit
// pipeline payload capacity, this is the MTU. Otherwise it's the pipeline payload
// capacity plus whatever overhead we need to transmit the packet.
var totalCapacity = pipelinePayloadCapacity == 0
? NetworkParameterConstants.MTU
: pipelinePayloadCapacity + protocolOverhead + pipelineHeader;

// Check if we can accomodate the user's required payload size.
if (payloadCapacity < requiredPayloadSize)
{
return (int)Error.StatusCode.NetworkPacketOverflow;
}

// Allocate less memory if user doesn't require our full capacity.
if (requiredPayloadSize > 0 && payloadCapacity > requiredPayloadSize)
{
var extraCapacity = payloadCapacity - requiredPayloadSize;
payloadCapacity -= extraCapacity;
totalCapacity -= extraCapacity;
}

var result = 0;
if ((result = m_NetworkSendInterface.BeginSendMessage.Ptr.Invoke(out var sendHandle, m_NetworkSendInterface.UserData, packetAllocationSize)) != 0)
if ((result = m_NetworkSendInterface.BeginSendMessage.Ptr.Invoke(out var sendHandle, m_NetworkSendInterface.UserData, totalCapacity)) != 0)
{
sendHandle.data = (IntPtr)UnsafeUtility.Malloc(packetAllocationSize, 8, Allocator.Temp);
sendHandle.capacity = packetAllocationSize;
sendHandle.data = (IntPtr)UnsafeUtility.Malloc(totalCapacity, 8, Allocator.Temp);
sendHandle.capacity = totalCapacity;
sendHandle.id = 0;
sendHandle.size = 0;
sendHandle.flags = SendHandleFlags.AllocatedByDriver;
}

if (sendHandle.capacity < packetAllocationSize)
if (sendHandle.capacity < totalCapacity)
return (int)Error.StatusCode.NetworkPacketOverflow;

var slice = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<byte>((byte*)sendHandle.data + payloadOffset + pipelineHeader, payloadCapacity, Allocator.Invalid);
Expand Down Expand Up @@ -620,7 +643,7 @@ internal NetworkDriver(INetworkInterface netIf, INetworkProtocol netProtocol, pa

m_NetworkSendInterface = netIf.CreateSendInterface();

m_PipelineProcessor = new NetworkPipelineProcessor(NetworkParameterConstants.MTU - m_NetworkProtocolInterface.PaddingSize, param);
m_PipelineProcessor = new NetworkPipelineProcessor(param);
m_ParallelSendQueue = new NativeQueue<QueuedSendMessage>(Allocator.Persistent);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
m_PendingBeginSend = new NativeArray<int>(JobsUtility.MaxJobThreadCount * JobsUtility.CacheLineSize / 4, Allocator.Persistent);
Expand Down
14 changes: 7 additions & 7 deletions Runtime/NetworkEventQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,26 @@ public enum Type : short
}

/// <summary>The type of the event.</summary>
[FieldOffset(0)] public Type type;
[FieldOffset(0)] internal Type type;

/// <summary>The pipeline on which the event was received (for Data events).</summary>
[FieldOffset(2)] public short pipelineId;
[FieldOffset(2)] internal short pipelineId;

/// <summary>Internal ID of the connection.</summary>
[FieldOffset(4)] public int connectionId;
[FieldOffset(4)] internal int connectionId;

/// <summary>Status of the event. Used to store the Disconnect reason.</summary>
[FieldOffset(8)] public int status;
[FieldOffset(8)] internal int status;

/// <summary>Offset of the event's data in the internal data stream.</summary>
[FieldOffset(8)] public int offset;
[FieldOffset(8)] internal int offset;

/// <summary>Size of the event's data.</summary>
[FieldOffset(12)] public int size;
[FieldOffset(12)] internal int size;
}

/// <summary>A queue to store <see cref="NetworkEvent"> per connection.</summary>
public struct NetworkEventQueue : IDisposable
internal struct NetworkEventQueue : IDisposable
{
private int MaxEvents
{
Expand Down
15 changes: 4 additions & 11 deletions Runtime/NetworkPipeline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ public int PayloadCapacity(NetworkPipeline pipeline)
var p = m_Pipelines[pipeline.Id - 1];
return p.payloadCapacity;
}
return m_MTU;
return 0;
}

public Concurrent ToConcurrent()
Expand All @@ -443,7 +443,6 @@ public Concurrent ToConcurrent()
sendBuffer = m_SendBuffer,
sharedBuffer = m_SharedBuffer,
m_timestamp = m_timestamp,
m_MTU = m_MTU,
};
return concurrent;
}
Expand All @@ -461,7 +460,6 @@ public struct Concurrent
[ReadOnly] internal NativeList<byte> sharedBuffer;
[ReadOnly] internal NativeList<byte> sendBuffer;
[ReadOnly] internal NativeArray<long> m_timestamp;
[ReadOnly] internal int m_MTU;

public int SendHeaderCapacity(NetworkPipeline pipeline)
{
Expand All @@ -476,7 +474,7 @@ public int PayloadCapacity(NetworkPipeline pipeline)
var p = m_Pipelines[pipeline.Id - 1];
return p.payloadCapacity;
}
return m_MTU;
return 0;
}

public unsafe int Send(NetworkDriver.Concurrent driver, NetworkPipeline pipeline, NetworkConnection connection, NetworkInterfaceSendHandle sendHandle, int headerSize)
Expand Down Expand Up @@ -724,8 +722,6 @@ private unsafe int ProcessSendStage(int startStage, int internalBufferOffset, in

private NativeArray<long> m_timestamp;

private int m_MTU;

private const int SendSizeOffset = 0;
private const int RecveiveSizeOffset = 1;
private const int SharedSizeOffset = 2;
Expand All @@ -742,8 +738,7 @@ internal struct PipelineImpl
public int payloadCapacity;
}

// The mtu parameter should already consider the protocol part, removing its header/footer
public unsafe NetworkPipelineProcessor(int mtu, params INetworkParameter[] param)
public unsafe NetworkPipelineProcessor(params INetworkParameter[] param)
{
NetworkPipelineParams config = default(NetworkPipelineParams);
for (int i = 0; i < param.Length; ++i)
Expand Down Expand Up @@ -771,7 +766,6 @@ public unsafe NetworkPipelineProcessor(int mtu, params INetworkParameter[] param
staticBufferSize = (staticBufferSize + 15) & (~15);
}

m_MTU = mtu;
m_StageList = new NativeList<int>(16, Allocator.Persistent);
m_AccumulatedHeaderCapacity = new NativeList<int>(16, Allocator.Persistent);
m_Pipelines = new NativeList<PipelineImpl>(16, Allocator.Persistent);
Expand Down Expand Up @@ -917,8 +911,7 @@ public NetworkPipeline CreatePipeline(params Type[] stages)
sizePerConnection[SharedSizeOffset] = sizePerConnection[SharedSizeOffset] + sharedCap;

pipeline.headerCapacity = headerCap;
// If no stage explicitly supports more tha MTU the pipeline as a whole does not support more than one MTU
pipeline.payloadCapacity = (payloadCap != 0) ? payloadCap : m_MTU;
pipeline.payloadCapacity = payloadCap;

m_Pipelines.Add(pipeline);
return new NetworkPipeline {Id = m_Pipelines.Length};
Expand Down
8 changes: 4 additions & 4 deletions Runtime/NetworkProtocol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ internal struct NetworkProtocol
/// to be stored in the packet.
/// </summary>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int ComputePacketAllocationSizeDelegate(ref NetworkDriver.Connection connection, IntPtr userData, ref int dataCapacity, out int payloadOffset);
public delegate int ComputePacketOverheadDelegate(ref NetworkDriver.Connection connection, out int payloadOffset);

/// <summary>
/// Process a receiving packet and returns a ProcessPacketCommand that will indicate to the NetworkDriver what actions
Expand Down Expand Up @@ -100,7 +100,7 @@ internal struct NetworkProtocol
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void UpdateDelegate(long updateTime, ref NetworkSendInterface sendInterface, ref NetworkSendQueueHandle queueHandle, IntPtr userData);

public TransportFunctionPointer<ComputePacketAllocationSizeDelegate> ComputePacketAllocationSize;
public TransportFunctionPointer<ComputePacketOverheadDelegate> ComputePacketOverhead;
public TransportFunctionPointer<ProcessReceiveDelegate> ProcessReceive;
public TransportFunctionPointer<ProcessSendDelegate> ProcessSend;
public TransportFunctionPointer<ProcessSendConnectionAcceptDelegate> ProcessSendConnectionAccept;
Expand Down Expand Up @@ -136,7 +136,7 @@ internal struct NetworkProtocol
public bool NeedsUpdate;

public NetworkProtocol(
TransportFunctionPointer<ComputePacketAllocationSizeDelegate> computePacketAllocationSize,
TransportFunctionPointer<ComputePacketOverheadDelegate> computePacketOverhead,
TransportFunctionPointer<ProcessReceiveDelegate> processReceive,
TransportFunctionPointer<ProcessSendDelegate> processSend,
TransportFunctionPointer<ProcessSendConnectionAcceptDelegate> processSendConnectionAccept,
Expand All @@ -151,7 +151,7 @@ public NetworkProtocol(
int maxFooterSize
)
{
ComputePacketAllocationSize = computePacketAllocationSize;
ComputePacketOverhead = computePacketOverhead;
ProcessReceive = processReceive;
ProcessSend = processSend;
ProcessSendConnectionAccept = processSendConnectionAccept;
Expand Down
4 changes: 2 additions & 2 deletions Runtime/NetworkProtocols.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Unity.Networking.Transport.Protocols
{
public enum UdpCProtocol
internal enum UdpCProtocol
{
ConnectionRequest,
ConnectionReject,
Expand All @@ -15,7 +15,7 @@ public enum UdpCProtocol
}

[StructLayout(LayoutKind.Sequential)]
public unsafe struct UdpCHeader
internal unsafe struct UdpCHeader
{
[Flags]
public enum HeaderFlags : byte
Expand Down
18 changes: 5 additions & 13 deletions Runtime/Relay/RelayNetworkProtocol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ public NetworkEndPoint GetRemoteEndPoint(INetworkInterface networkInterface, Net
public NetworkProtocol CreateProtocolInterface()
{
return new NetworkProtocol(
computePacketAllocationSize: new TransportFunctionPointer<NetworkProtocol.ComputePacketAllocationSizeDelegate>(ComputePacketAllocationSize),
computePacketOverhead: new TransportFunctionPointer<NetworkProtocol.ComputePacketOverheadDelegate>(ComputePacketOverhead),
processReceive: new TransportFunctionPointer<NetworkProtocol.ProcessReceiveDelegate>(ProcessReceive),
processSend: new TransportFunctionPointer<NetworkProtocol.ProcessSendDelegate>(ProcessSend),
processSendConnectionAccept: new TransportFunctionPointer<NetworkProtocol.ProcessSendConnectionAcceptDelegate>(ProcessSendConnectionAccept),
Expand All @@ -247,18 +247,12 @@ public NetworkProtocol CreateProtocolInterface()
}

[BurstCompile(DisableDirectCall = true)]
[MonoPInvokeCallback(typeof(NetworkProtocol.ComputePacketAllocationSizeDelegate))]
public static int ComputePacketAllocationSize(ref NetworkDriver.Connection connection, IntPtr userData, ref int dataCapacity, out int dataOffset)
[MonoPInvokeCallback(typeof(NetworkProtocol.ComputePacketOverheadDelegate))]
public static int ComputePacketOverhead(ref NetworkDriver.Connection connection, out int dataOffset)
{
var capacityCost = dataCapacity == 0 ? RelayMessageRelay.Length : 0;
var extraSize = dataCapacity == 0 ? 0 : RelayMessageRelay.Length;

var size = UnityTransportProtocol.ComputePacketAllocationSize(ref connection, userData, ref dataCapacity, out dataOffset);

var utpOverhead = UnityTransportProtocol.ComputePacketOverhead(ref connection, out dataOffset);
dataOffset += RelayMessageRelay.Length;
dataCapacity -= capacityCost;

return size + extraSize;
return utpOverhead + RelayMessageRelay.Length;
}

[BurstCompile(DisableDirectCall = true)]
Expand Down Expand Up @@ -688,8 +682,6 @@ public static void Connect(ref NetworkDriver.Connection connection, ref NetworkS
unsafe
{
var relayProtocolData = (RelayProtocolData*)userData;

relayProtocolData->ServerData.ConnectionSessionId = connection.ReceiveToken;
relayProtocolData->ConnectionReceiveToken = connection.ReceiveToken;

// If we're not bound, either we're still binding (and we can't attempt to connect
Expand Down
7 changes: 0 additions & 7 deletions Runtime/Relay/RelayServerData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ public unsafe struct RelayServerData
/// </summary>
public ushort Nonce;
/// <summary>
/// The Session Id for the connection with the Relay Server.
/// </summary>
public SessionIdToken ConnectionSessionId;
/// <summary>
/// The data that describes the client presence on the Relay Server.
/// </summary>
public RelayConnectionData ConnectionData;
Expand Down Expand Up @@ -62,7 +58,6 @@ public RelayServerData(ref NetworkEndPoint endpoint, ushort nonce, RelayAllocati
Endpoint = endpoint;
AllocationId = allocationId;
Nonce = nonce;
ConnectionSessionId = default;

IsSecure = isSecure ? (byte)1 : (byte)0;

Expand Down Expand Up @@ -103,8 +98,6 @@ public RelayServerData(ref NetworkEndPoint endpoint, ushort nonce, ref RelayAllo

IsSecure = isSecure ? (byte)1 : (byte)0;

ConnectionSessionId = default;

fixed(byte* hmacPtr = HMAC)
{
ComputeBindHMAC(hmacPtr, Nonce, ref connectionData, ref key);
Expand Down
2 changes: 1 addition & 1 deletion Runtime/SHA256.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Unity.Networking.Transport
/// <summary>
/// Utility class that provides the ability to generate a SHA256 Hash
/// </summary>
public static class SHA256
internal static class SHA256
{
internal unsafe struct SHA256State
{
Expand Down
Loading

0 comments on commit 542f92e

Please sign in to comment.