EscalateQuotaTimePeriod
EscalateQuotaTimePeriod
#Overview
name: EscalateQuotaTimePeriod
The value of this variable can be defined or overridden in .ini config files. 5
.ini config files referencing this setting variable.
It is referenced in 14
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of EscalateQuotaTimePeriod is to define the time period used for determining RPC (Remote Procedure Call) count and time escalation quotas in Unreal Engine’s networking system, specifically for DoS (Denial of Service) detection and prevention.
This setting variable is primarily used by the networking subsystem of Unreal Engine, particularly in the RPC DoS detection module. It’s referenced in the Engine and Net Core modules.
The value of this variable is typically set in configuration files or through code initialization. It’s often applied in the ApplyImpliedValues() and ApplyState() functions of the RPC DoS detection system.
EscalateQuotaTimePeriod interacts with several other variables, including EscalateQuotaRPCsPerPeriod, EscalateTimeQuotaMSPerPeriod, and various counters used for tracking RPC calls over time.
Developers must be aware that:
- The value is capped at a maximum of 16 (as indicated by comments in the code).
- A value of -1 indicates that the quota system is disabled for this particular time period.
- It’s used in conjunction with other quota-related variables to determine when to escalate DoS prevention measures.
Best practices when using this variable include:
- Carefully tuning it along with other quota variables to balance between security and performance.
- Ensuring it’s set to a positive value when using related quota systems (EscalateQuotaRPCsPerPeriod or EscalateTimeQuotaMSPerPeriod).
- Validating its value in conjunction with other time period settings to maintain consistency in the DoS prevention system.
- Consider the implications on network performance and security when adjusting this value.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEngine.ini:1737, section: [RPCDoSDetection.Hitch]
- INI Section:
RPCDoSDetection.Hitch
- Raw value:
2
- Is Array:
False
Location: <Workspace>/Engine/Config/BaseEngine.ini:1745, section: [RPCDoSDetection.Burst]
- INI Section:
RPCDoSDetection.Burst
- Raw value:
8
- Is Array:
False
Location: <Workspace>/Engine/Config/BaseEngine.ini:1756, section: [RPCDoSDetection.PersistentBurst]
- INI Section:
RPCDoSDetection.PersistentBurst
- Raw value:
8
- Is Array:
False
Location: <Workspace>/Engine/Config/BaseEngine.ini:1769, section: [RPCDoSDetection.DoS]
- INI Section:
RPCDoSDetection.DoS
- Raw value:
8
- Is Array:
False
Location: <Workspace>/Engine/Config/BaseEngine.ini:1785, section: [RPCDoSDetection.ExpensiveDoS]
- INI Section:
RPCDoSDetection.ExpensiveDoS
- Raw value:
16
- Is Array:
False
#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:124
Scope (from outer to inner):
file
function void FRPCDoSState::ApplyImpliedValues
Source code excerpt:
void FRPCDoSState::ApplyImpliedValues()
{
EscalateQuotaTimePeriod = (EscalateQuotaRPCsPerPeriod != -1 || EscalateTimeQuotaMSPerPeriod != -1) ? EscalateQuotaTimePeriod : -1;
RPCRepeatLimitTimePeriod = (RPCRepeatLimitPerPeriod != -1 || RPCRepeatLimitMSPerPeriod != -1) ? RPCRepeatLimitTimePeriod : -1;
bTrackRecentRPCs = bTrackRecentRPCs || (RPCRepeatLimitPerPeriod != -1 && RPCRepeatLimitTimePeriod != -1);
EscalateTimeQuotaSecsPerFrame = (EscalateTimeQuotaMSPerFrame != -1 ? (EscalateTimeQuotaMSPerFrame / 1000.0) : 0.0);
EscalateTimeQuotaSecsPerPeriod = (EscalateTimeQuotaMSPerPeriod != -1 ? (EscalateTimeQuotaMSPerPeriod / 1000.0) : 0.0);
RPCRepeatLimitSecsPerPeriod = (RPCRepeatLimitMSPerPeriod != -1 ? (RPCRepeatLimitMSPerPeriod / 1000.0) : 0.0);
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Net/RPCDoSDetection.cpp:145
Scope (from outer to inner):
file
function bool FRPCDoSState::HasHitQuota_Count
Source code excerpt:
if (EscalateQuotaRPCsPerPeriod > 0 && !bReturnVal)
{
const FRPCDoSCounters& PeriodCounter = PerPeriodHistory[EscalateQuotaTimePeriod - 1];
bReturnVal = PeriodCounter.RPCCounter + InFrameCounter.RPCCounter >= EscalateQuotaRPCsPerPeriod;
#if RPC_QUOTA_DEBUG
UE_CLOG(bReturnVal, LogNet, Log, TEXT("HasHitQuota_Count: Hit Period Quota: RPCsPerPeriodCounter: %i, Limit: %i"),
(PeriodCounter.RPCCounter + InFrameCounter.RPCCounter), EscalateQuotaRPCsPerPeriod);
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Net/RPCDoSDetection.cpp:178
Scope (from outer to inner):
file
function bool FRPCDoSState::HasHitQuota_Time
Source code excerpt:
if (EscalateTimeQuotaMSPerPeriod > 0 && !bReturnVal)
{
const FRPCDoSCounters& PeriodCounter = PerPeriodHistory[EscalateQuotaTimePeriod - 1];
bReturnVal = (PeriodCounter.AccumRPCTime + InFrameCounter.AccumRPCTime) >= EscalateTimeQuotaSecsPerPeriod;
#if RPC_QUOTA_DEBUG
bDebugReturnVal = (PeriodCounter.DebugAccumRPCTime + InFrameCounter.DebugAccumRPCTime) >=
EscalateTimeQuotaSecsPerPeriod;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Net/RPCDoSDetection.cpp:213
Scope (from outer to inner):
file
function void FRPCDoSStateConfig::ApplyImpliedValues
Source code excerpt:
FRPCDoSState::ApplyImpliedValues();
if (EscalateQuotaTimePeriod > 0)
{
AllTimePeriods.AddUnique(EscalateQuotaTimePeriod);
}
if (RPCRepeatLimitTimePeriod > 0)
{
AllTimePeriods.AddUnique(RPCRepeatLimitTimePeriod);
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Net/RPCDoSDetection.cpp:285
Scope (from outer to inner):
file
function void FRPCDoSStateConfig::ValidateConfig
Source code excerpt:
};
ValidateTimePeriod(EscalateQuotaTimePeriod, TEXT("EscalateQuotaTimePeriod"),
(EscalateQuotaRPCsPerPeriod > 0 || EscalateTimeQuotaMSPerPeriod > 0));
ValidateTimePeriod(RPCRepeatLimitTimePeriod, TEXT("RPCRepeatLimitTimePeriod"),
(RPCRepeatLimitPerPeriod > 0 || RPCRepeatLimitMSPerPeriod > 0));
if (AutoEscalateTime > 0 && AutoEscalateTime < CooloffTime)
{
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Net/RPCDoSDetection.cpp:317
Scope (from outer to inner):
file
function void FRPCDoSStateConfig::ApplyState
Source code excerpt:
Target.EscalateQuotaRPCsPerPeriod = EscalateQuotaRPCsPerPeriod;
Target.EscalateTimeQuotaMSPerPeriod = EscalateTimeQuotaMSPerPeriod;
Target.EscalateQuotaTimePeriod = EscalateQuotaTimePeriod;
Target.RPCRepeatLimitPerPeriod = RPCRepeatLimitPerPeriod;
Target.RPCRepeatLimitMSPerPeriod = RPCRepeatLimitMSPerPeriod;
Target.RPCRepeatLimitTimePeriod = RPCRepeatLimitTimePeriod;
Target.CooloffTime = CooloffTime;
Target.AutoEscalateTime = AutoEscalateTime;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Net/RPCDoSDetection.cpp:663
Scope (from outer to inner):
file
function void FRPCDoSDetection::UpdateSeverity_Private
Source code excerpt:
double WorstTimePerSec = 0.0;
for (int32 SecIdx=0; SecIdx<OldState.EscalateQuotaTimePeriod; SecIdx++)
{
int32 PerSecHistoryIdx = LastCounterPerSecHistoryIdx - SecIdx;
PerSecHistoryIdx = (PerSecHistoryIdx < 0 ? CounterPerSecHistory.Num() + PerSecHistoryIdx : PerSecHistoryIdx);
WorstCountPerSec = FMath::Max(CounterPerSecHistory[PerSecHistoryIdx].RPCCounter, WorstCountPerSec);
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/Net/RPCDoSDetection.h:208
Scope: file
Source code excerpt:
/** The time period to use for determining RPC count and time escalation quotas (Max: 16) */
UPROPERTY(config)
int8 EscalateQuotaTimePeriod = -1;
/** Escalation monitoring - for setting thresholds for triggering analytics (does not affect escalation quota's and RPC limiting) */
/** The number of times this stage must be escalated to, before it is 'confirmed' as having been escalated to (for analytics) */
UPROPERTY(config)
#Loc: <Workspace>/Engine/Source/Runtime/Net/Core/Private/Net/Core/Connection/NetConnectionFaultRecoveryBase.cpp:44
Scope (from outer to inner):
file
function EInitStateDefaultsResult FNetFaultState::InitConfigDefaultsInternal
Source code excerpt:
bDormant = true;
EscalateQuotaFaultsPerPeriod = 1;
EscalateQuotaTimePeriod = 1;
}
else if (SeverityCategory == TEXT("Fault"))
{
EscalateQuotaFaultsPerPeriod = 8;
DescalateQuotaFaultsPerPeriod = 6;
EscalateQuotaTimePeriod = 8;
CooloffTime = 10;
AutoEscalateTime = 11;
}
else if (SeverityCategory == TEXT("PersistentFault"))
{
EscalateQuotaFaultsPerPeriod = 64;
#Loc: <Workspace>/Engine/Source/Runtime/Net/Core/Private/Net/Core/Connection/NetConnectionFaultRecoveryBase.cpp:60
Scope (from outer to inner):
file
function EInitStateDefaultsResult FNetFaultState::InitConfigDefaultsInternal
Source code excerpt:
DescalateQuotaFaultsPerPeriod = 48;
DescalateQuotaFaultPercentPerPeriod = 40;
EscalateQuotaTimePeriod = 8;
CooloffTime = 10;
AutoEscalateTime = 20;
bLogEscalate = true;
}
else if (SeverityCategory == TEXT("DisconnectCountdown"))
{
EscalateQuotaFaultPercentPerPeriod = 70;
DescalateQuotaFaultPercentPerPeriod = 56;
EscalateQuotaTimePeriod = 16;
CooloffTime = 10;
AutoEscalateTime = 60;
bLogEscalate = true;
}
else if (SeverityCategory == TEXT("Disconnect"))
{
bCloseConnection = true;
bLogEscalate = true;
EscalateQuotaTimePeriod = 0;
}
else
{
ReturnVal = EInitStateDefaultsResult::NotInitialized;
}
#Loc: <Workspace>/Engine/Source/Runtime/Net/Core/Private/Net/Core/Connection/NetConnectionFaultRecoveryBase.cpp:111
Scope (from outer to inner):
file
function void FNetFaultState::ApplyImpliedValuesInternal
Source code excerpt:
if (EscalateQuotaTimePeriod > 0)
{
AllTimePeriods.AddUnique(EscalateQuotaTimePeriod);
}
HighestTimePeriod = FMath::Max(AllTimePeriods);
}
void FNetFaultState::ValidateConfigInternal()
#Loc: <Workspace>/Engine/Source/Runtime/Net/Core/Private/Net/Core/Connection/NetConnectionFaultRecoveryBase.cpp:125
Scope (from outer to inner):
file
function void FNetFaultState::ValidateConfigInternal
Source code excerpt:
Super::ValidateConfigInternal();
ValidateTimePeriod(EscalateQuotaTimePeriod, TEXT("EscalateQuotaTimePeriod"),
((EscalateQuotaFaultsPerPeriod > 0 || EscalateQuotaFaultPercentPerPeriod > 0) ? EValidateTime::MustBeSet : EValidateTime::Optional));
}
bool FNetFaultState::HasHitAnyQuota(FHasHitAnyQuotaParms Parms) const
{
using namespace UE::Net;
#Loc: <Workspace>/Engine/Source/Runtime/Net/Core/Private/Net/Core/Connection/NetConnectionFaultRecoveryBase.cpp:145
Scope (from outer to inner):
file
function bool FNetFaultState::HasHitAnyQuota
Source code excerpt:
const TArrayView<FEscalationCounter>& SecondCounters = Parms.SecondCounters;
const TArrayView<FEscalationCounter>& FrameCounters = Parms.FrameCounters;
const TArrayView<FEscalationCounter>& CurHistory = Parms.PerPeriodHistory[EscalateQuotaTimePeriod - 1];
int32 HighestFaultCount = 0;
const uint8 PacketCountIdx = ToInt(ENetFaultCounters::PacketCount);
const int32 FullPacketCount = CurHistory[PacketCountIdx].Counter + SecondCounters[PacketCountIdx].Counter +
FrameCounters[PacketCountIdx].Counter;
for (const int32 CounterIdx : NetCorruptionCounters)
#Loc: <Workspace>/Engine/Source/Runtime/Net/Core/Public/Net/Core/Connection/NetConnectionFaultRecoveryBase.h:68
Scope: file
Source code excerpt:
/** The time period to use for determining escalation/de-escalation quotas (Max: 16) */
UPROPERTY(config)
int8 EscalateQuotaTimePeriod = -1;
public:
static NETCORE_API const TCHAR* GetConfigSection();
static NETCORE_API UClass* GetBaseConfigClass();