net.RandomizeSequence

net.RandomizeSequence

#Overview

name: net.RandomizeSequence

This variable is created as a Console Variable (cvar).

It is referenced in 5 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of net.RandomizeSequence is to randomize the initial packet sequence for network connections in Unreal Engine 5. This setting is part of the networking system and is primarily used for providing some level of obfuscation in network communications.

This setting variable is primarily relied upon by the networking subsystem of Unreal Engine, specifically within the UNetConnection class. It’s used in the Engine module, as evidenced by its location in the NetConnection.cpp file.

The value of this variable is set through a console variable (CVarRandomizeSequence) with a default value of 1, meaning it’s enabled by default. It can be changed at runtime through console commands.

The associated variable CVarRandomizeSequence directly interacts with net.RandomizeSequence. They share the same value and are used interchangeably in the code.

Developers must be aware of several things when using this variable:

  1. It affects the initialization of packet sequences in network connections.
  2. When enabled, it adds a layer of obfuscation to network communications, which can potentially make certain types of network attacks more difficult.
  3. It’s used in checks to ensure proper network handshake procedures are followed.

Best practices when using this variable include:

  1. Generally, leave it enabled (default value of 1) for added security through obfuscation.
  2. Be aware that disabling it (setting to 0) might make network traffic patterns more predictable, which could be useful for debugging but potentially less secure in production.
  3. When implementing custom networking code, respect this setting and use it consistently with how the engine uses it.

Regarding the associated variable CVarRandomizeSequence:

The purpose of CVarRandomizeSequence is to provide a runtime-configurable way to control the net.RandomizeSequence setting. It’s part of the networking system, specifically for controlling packet sequence randomization.

This console variable is used within the UNetConnection class in the Engine module. It’s referenced in several key networking functions.

The value of CVarRandomizeSequence is set when the console variable is created, with a default value of 1. It can be changed at runtime using console commands.

CVarRandomizeSequence directly interacts with the net.RandomizeSequence setting. They essentially represent the same configuration option.

Developers should be aware that:

  1. This variable controls a networking security feature.
  2. Changes to this variable at runtime will affect new connections but not existing ones.
  3. It’s used in critical networking code paths, so changing it could have significant effects on network behavior.

Best practices for CVarRandomizeSequence include:

  1. Use GetValueOnAnyThread() to safely read its value from any thread.
  2. Consider the security implications before disabling this feature in production environments.
  3. If you’re extending the networking code, maintain consistency with how the engine uses this variable.

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/NetConnection.cpp:70

Scope: file

Source code excerpt:

	TEXT("If nonzero, each net connection will tick all of its open channels every tick. Leaving this off will improve performance."));

static TAutoConsoleVariable<int32> CVarRandomizeSequence(TEXT("net.RandomizeSequence"), 1,
	TEXT("Randomize initial packet sequence, can provide some obfuscation"));

static TAutoConsoleVariable<int32> CVarMaxChannelSize(TEXT("net.MaxChannelSize"), 0,
	TEXT("The maximum number of network channels allowed across the entire server, if <= 0 the connection DefaultMaxChannelSize will be used."));

#if !UE_BUILD_SHIPPING

#Associated Variable and Callsites

This variable is associated with another variable named CVarRandomizeSequence. They share the same value. See the following C++ source code.

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/NetConnection.cpp:70

Scope: file

Source code excerpt:

	TEXT("If nonzero, each net connection will tick all of its open channels every tick. Leaving this off will improve performance."));

static TAutoConsoleVariable<int32> CVarRandomizeSequence(TEXT("net.RandomizeSequence"), 1,
	TEXT("Randomize initial packet sequence, can provide some obfuscation"));

static TAutoConsoleVariable<int32> CVarMaxChannelSize(TEXT("net.MaxChannelSize"), 0,
	TEXT("The maximum number of network channels allowed across the entire server, if <= 0 the connection DefaultMaxChannelSize will be used."));

#if !UE_BUILD_SHIPPING

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/NetConnection.cpp:756

Scope (from outer to inner):

file
function     void UNetConnection::InitSequence

Source code excerpt:

	check(InPacketId == -1 || Driver->ServerConnection != nullptr);

	if (InPacketId == -1 && CVarRandomizeSequence.GetValueOnAnyThread() > 0)
	{
		// Initialize the base UNetConnection packet sequence (not very useful/effective at preventing attacks)
		InPacketId = IncomingSequence - 1;
		OutPacketId = OutgoingSequence;
		OutAckPacketId = OutgoingSequence - 1;
		LastNotifiedPacketId = OutAckPacketId;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/NetConnection.cpp:2125

Scope: file

Source code excerpt:

		// Due to the PacketHandler handshake code, servers must never send the client data,
		// before first receiving a client control packet (which is taken as an indication of a complete handshake).
		if (!HasReceivedClientPacket() && CVarRandomizeSequence.GetValueOnAnyThread() != 0)
		{
			UE_LOG(LogNet, Log, TEXT("Attempting to send data before handshake is complete. %s"), *Describe());

			Close(ENetCloseResult::PrematureSend);
			InitSendBuffer();

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/NetConnection.cpp:3904

Scope (from outer to inner):

file
function     void UNetConnection::PrepareWriteBitsToSendBuffer

Source code excerpt:

	// Now that the stateless handshake is responsible for initializing the packet sequence numbers,
	//	we can't allow any packets to be written to the send buffer until after this has completed
	if (CVarRandomizeSequence.GetValueOnAnyThread() > 0)
	{
		checkf(!Handler.IsValid() || Handler->IsFullyInitialized(), TEXT("Attempted to write to send buffer before packet handler was fully initialized. Connection: %s"), *Describe());
	}
#endif

	const int32 TotalSizeInBits = SizeInBits + ExtraSizeInBits;