HitchTimeQuotaMS

HitchTimeQuotaMS

#Overview

name: HitchTimeQuotaMS

The value of this variable can be defined or overridden in .ini config files. 3 .ini config files referencing this setting variable.

It is referenced in 9 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of HitchTimeQuotaMS is to detect frame hitches in Unreal Engine’s networking system, specifically for preventing false positives in DDoS (Distributed Denial of Service) and RPC (Remote Procedure Call) DoS detection.

This setting variable is primarily used in the networking subsystem of Unreal Engine, particularly in the DDoS detection and RPC DoS detection modules. It’s referenced in the Engine and Net/Core modules.

The value of this variable is typically set through configuration files. It’s loaded from the game’s configuration (GEngineIni) in the FDDoSDetection::InitConfig function and from a configuration object in the FRPCDoSDetection::InitConfig function.

HitchTimeQuotaMS interacts with several other variables, including:

Developers must be aware that this variable is crucial for balancing between detecting actual DoS attacks and preventing false positives due to normal network or performance issues. Setting it too low might lead to false positives, while setting it too high might allow actual attacks to go undetected.

Best practices when using this variable include:

  1. Carefully tuning the value based on your game’s performance characteristics and network environment.
  2. Monitoring its effectiveness in conjunction with other DoS detection metrics.
  3. Considering the target platforms and their typical performance characteristics when setting this value.
  4. Regularly reviewing and adjusting this value as part of your game’s network security strategy.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEngine.ini:1650, section: [DDoSDetection]

Location: <Workspace>/Engine/Config/BaseEngine.ini:1700, section: [GameNetDriver RPCDoSDetection]

Location: <Workspace>/Engine/Config/BaseEngine.ini:1717, section: [BeaconNetDriver RPCDoSDetection]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Net/RPCDoSDetection.cpp:373

Scope (from outer to inner):

file
function     void FRPCDoSDetection::InitConfig

Source code excerpt:

		bRPCDoSDetection = CurConfigObj->bRPCDoSDetection;
		bRPCDoSAnalytics = CurConfigObj->bRPCDoSAnalytics;
		HitchTimeQuotaMS = CurConfigObj->HitchTimeQuotaMS;
		HitchSuspendDetectionTimeMS = CurConfigObj->HitchSuspendDetectionTimeMS;

		if (NextTimeQuotaCheck == 0.0 && CurConfigObj->InitialConnectToleranceMS > 0)
		{
			NextTimeQuotaCheck = FPlatformTime::Seconds() + (CurConfigObj->InitialConnectToleranceMS / 1000.0);
		}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Net/RPCDoSDetection.cpp:764

Scope (from outer to inner):

file
function     void FRPCDoSDetection::PreTickDispatch

Source code excerpt:

		NextTimeQuotaCheck = FMath::Max(TimeSeconds + TimeQuotaCheckInterval, NextTimeQuotaCheck);

		if (HitchTimeQuotaMS > 0 && ReceivedPacketEndTime != 0.0)
		{
			// Timing is approximate to reduce timestamp retrieval, and packets aren't received each frame
			if (LastPreTickDispatchTime > ReceivedPacketEndTime)
			{
				ReceivedPacketEndTime = LastPreTickDispatchTime;
			}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Net/RPCDoSDetection.cpp:774

Scope (from outer to inner):

file
function     void FRPCDoSDetection::PreTickDispatch

Source code excerpt:

			double EstHitchTimeMS = (TimeSeconds - ReceivedPacketEndTime) * 1000.0;

			if ((int32)EstHitchTimeMS >= HitchTimeQuotaMS)
			{
				bHitchSuspendDetection = true;
				HitchSuspendDetectionStartTime = TimeSeconds;
			}
			else if (bHitchSuspendDetection && (int32)((TimeSeconds - HitchSuspendDetectionStartTime) * 1000.0) > HitchSuspendDetectionTimeMS)
			{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Net/RPCDoSDetectionConfig.h:66

Scope (from outer to inner):

file
class        class URPCDoSDetectionConfig : public UObject

Source code excerpt:

	/** The amount of time since the previous frame, for detecting hitches, to prevent false positives from built-up packets */
	UPROPERTY(config)
	int32 HitchTimeQuotaMS;

	/** The amount of time to suspend RPC DoS Detection, once a hitch is encountered, prevent false positives from built-up packets */
	UPROPERTY(config)
	int32 HitchSuspendDetectionTimeMS;

	/** Names of the different RPC DoS detection states, for escalating severity, depending on the amount of RPC spam */

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/Net/RPCDoSDetection.h:1131

Scope (from outer to inner):

file
class        class FRPCDoSDetection : protected FRPCDoSState

Source code excerpt:


	/** The amount of time since the previous frame, for detecting hitches, to prevent false positives from built-up packets */
	int32 HitchTimeQuotaMS											= 0;

	/** The amount of time to suspend RPC DoS Detection, once a hitch is encountered, to prevent false positives from built-up packets */
	int32 HitchSuspendDetectionTimeMS								= 0;

	/** List of RPC's which should never be blocked */
	TArray<FName> RPCBlockAllowList;

#Loc: <Workspace>/Engine/Source/Runtime/Net/Core/Private/Net/Core/Misc/DDoSDetection.cpp:75

Scope (from outer to inner):

file
function     FDDoSDetection::FDDoSDetection

Source code excerpt:

	, DDoSLogSpamLimit(0)
	, LogHitCounter(0)
	, HitchTimeQuotaMS(-1)
	, HitchFrameTolerance(-1)
	, HitchFrameCount(0)
	, LastPerSecQuotaBegin(0.0)
	, CounterPerSecHistory()
	, LastCounterPerSecHistoryIdx(0)
	, StartFrameRecvTimestamp(0.0)

#Loc: <Workspace>/Engine/Source/Runtime/Net/Core/Private/Net/Core/Misc/DDoSDetection.cpp:105

Scope (from outer to inner):

file
function     void FDDoSDetection::InitConfig

Source code excerpt:

	GConfig->GetBool(DDoSSection, TEXT("bDDoSAnalytics"), bDDoSAnalytics, GEngineIni);
	GConfig->GetInt(DDoSSection, TEXT("DDoSLogSpamLimit"), DDoSLogSpamLimit, GEngineIni);
	GConfig->GetInt(DDoSSection, TEXT("HitchTimeQuotaMS"), HitchTimeQuotaMS, GEngineIni);
	GConfig->GetInt(DDoSSection, TEXT("HitchFrameTolerance"), HitchFrameTolerance32, GEngineIni);

	HitchFrameTolerance = IntCastChecked<int8>(HitchFrameTolerance32);
	DDoSLogSpamLimit = DDoSLogSpamLimit > 0 ? DDoSLogSpamLimit : 64;

	DetectionSeverity.Empty();

#Loc: <Workspace>/Engine/Source/Runtime/Net/Core/Private/Net/Core/Misc/DDoSDetection.cpp:266

Scope (from outer to inner):

file
function     void FDDoSDetection::PreFrameReceive

Source code excerpt:

		bMetEscalationConditionsThisFrame = false;

		if (HitchTimeQuotaMS > 0 && EndFrameRecvTimestamp != 0.0)
		{
			const double HitchTimeMS = (StartFrameRecvTimestamp - EndFrameRecvTimestamp) * 1000.0;

			if ((((int32)HitchTimeMS) - HitchTimeQuotaMS) > 0)
			{
				HitchFrameCount++;

				UE_LOG(LogNetCore, Verbose, TEXT("Detected '%i' successive hitches outside NetDriver Tick. Last Hitch: %fms (Max: %ims)"),
						HitchFrameCount, HitchTimeMS, HitchTimeQuotaMS);
			}
			else
			{
				HitchFrameCount = 0;
			}
		}

#Loc: <Workspace>/Engine/Source/Runtime/Net/Core/Public/Net/Core/Misc/DDoSDetection.h:330

Scope (from outer to inner):

file
class        class FDDoSDetection : protected FDDoSPacketCounters, protected FDDoSState

Source code excerpt:


	/** The amount of time since the previous frame, for detecting frame hitches, to prevent DDoS detection false positives */
	int32 HitchTimeQuotaMS;

	/** The number of frames spent hitching, before disabling false positive detection, and treating packet buildup as potential DDoS */
	int8 HitchFrameTolerance;

	/** The number of consecutive frames spent hitching */
	int32 HitchFrameCount;