mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-12 19:18:20 +00:00
Merge pull request #411 from heinrich5991/pr_ddnet_serverbrowse_dos_prot
Add DoS protection to server info requests
This commit is contained in:
commit
ac9356c0f0
|
@ -317,6 +317,10 @@ CServer::CServer()
|
||||||
m_RconRestrict = -1;
|
m_RconRestrict = -1;
|
||||||
m_GeneratedRconPassword = 0;
|
m_GeneratedRconPassword = 0;
|
||||||
|
|
||||||
|
m_ServerInfoFirstRequest = 0;
|
||||||
|
m_ServerInfoNumRequests = 0;
|
||||||
|
m_ServerInfoHighLoad = false;
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1266,12 +1270,35 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServer::SendServerInfo(const NETADDR *pAddr, int Token, bool Extended, int Offset)
|
void CServer::SendServerInfoConnless(const NETADDR *pAddr, int Token, bool Extended)
|
||||||
|
{
|
||||||
|
const int MaxRequests = g_Config.m_SvServerInfoPerSecond;
|
||||||
|
int64 Now = Tick();
|
||||||
|
if(Now <= m_ServerInfoFirstRequest + TickSpeed())
|
||||||
|
{
|
||||||
|
m_ServerInfoNumRequests++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ServerInfoHighLoad = m_ServerInfoNumRequests > MaxRequests;
|
||||||
|
m_ServerInfoNumRequests = 1;
|
||||||
|
m_ServerInfoFirstRequest = Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Short = m_ServerInfoNumRequests > MaxRequests || m_ServerInfoHighLoad;
|
||||||
|
SendServerInfo(pAddr, Token, Extended, 0, Short);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CServer::SendServerInfo(const NETADDR *pAddr, int Token, bool Extended, int Offset, bool Short)
|
||||||
{
|
{
|
||||||
CNetChunk Packet;
|
CNetChunk Packet;
|
||||||
CPacker p;
|
CPacker p;
|
||||||
char aBuf[128];
|
char aBuf[128];
|
||||||
|
|
||||||
|
Packet.m_ClientID = -1;
|
||||||
|
Packet.m_Address = *pAddr;
|
||||||
|
Packet.m_Flags = NETSENDFLAG_CONNLESS;
|
||||||
|
|
||||||
// count the players
|
// count the players
|
||||||
int PlayerCount = 0, ClientCount = 0;
|
int PlayerCount = 0, ClientCount = 0;
|
||||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||||
|
@ -1346,6 +1373,14 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token, bool Extended, int
|
||||||
if (Extended)
|
if (Extended)
|
||||||
p.AddInt(Offset);
|
p.AddInt(Offset);
|
||||||
|
|
||||||
|
if(Short)
|
||||||
|
{
|
||||||
|
Packet.m_DataSize = p.Size();
|
||||||
|
Packet.m_pData = p.Data();
|
||||||
|
m_NetServer.Send(&Packet);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int ClientsPerPacket = Extended ? 24 : VANILLA_MAX_CLIENTS;
|
int ClientsPerPacket = Extended ? 24 : VANILLA_MAX_CLIENTS;
|
||||||
int Skip = Offset;
|
int Skip = Offset;
|
||||||
int Take = ClientsPerPacket;
|
int Take = ClientsPerPacket;
|
||||||
|
@ -1368,9 +1403,6 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token, bool Extended, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet.m_ClientID = -1;
|
|
||||||
Packet.m_Address = *pAddr;
|
|
||||||
Packet.m_Flags = NETSENDFLAG_CONNLESS;
|
|
||||||
Packet.m_DataSize = p.Size();
|
Packet.m_DataSize = p.Size();
|
||||||
Packet.m_pData = p.Data();
|
Packet.m_pData = p.Data();
|
||||||
m_NetServer.Send(&Packet);
|
m_NetServer.Send(&Packet);
|
||||||
|
@ -1406,15 +1438,25 @@ void CServer::PumpNetwork()
|
||||||
// stateless
|
// stateless
|
||||||
if(!m_Register.RegisterProcessPacket(&Packet))
|
if(!m_Register.RegisterProcessPacket(&Packet))
|
||||||
{
|
{
|
||||||
|
bool ServerInfo = false;
|
||||||
|
bool Extended = false;
|
||||||
|
|
||||||
if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETINFO)+1 &&
|
if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETINFO)+1 &&
|
||||||
mem_comp(Packet.m_pData, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO)) == 0)
|
mem_comp(Packet.m_pData, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO)) == 0)
|
||||||
{
|
{
|
||||||
SendServerInfo(&Packet.m_Address, ((unsigned char *)Packet.m_pData)[sizeof(SERVERBROWSE_GETINFO)]);
|
ServerInfo = true;
|
||||||
|
Extended = false;
|
||||||
}
|
}
|
||||||
else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETINFO64)+1 &&
|
else if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETINFO64)+1 &&
|
||||||
mem_comp(Packet.m_pData, SERVERBROWSE_GETINFO64, sizeof(SERVERBROWSE_GETINFO64)) == 0)
|
mem_comp(Packet.m_pData, SERVERBROWSE_GETINFO64, sizeof(SERVERBROWSE_GETINFO64)) == 0)
|
||||||
{
|
{
|
||||||
SendServerInfo(&Packet.m_Address, ((unsigned char *)Packet.m_pData)[sizeof(SERVERBROWSE_GETINFO64)], true);
|
ServerInfo = true;
|
||||||
|
Extended = true;
|
||||||
|
}
|
||||||
|
if(ServerInfo)
|
||||||
|
{
|
||||||
|
int Token = ((unsigned char *)Packet.m_pData)[sizeof(SERVERBROWSE_GETINFO)];
|
||||||
|
SendServerInfoConnless(&Packet.m_Address, Token, Extended);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,6 +184,10 @@ public:
|
||||||
|
|
||||||
int m_RconRestrict;
|
int m_RconRestrict;
|
||||||
|
|
||||||
|
bool m_ServerInfoHighLoad;
|
||||||
|
int64 m_ServerInfoFirstRequest;
|
||||||
|
int m_ServerInfoNumRequests;
|
||||||
|
|
||||||
CServer();
|
CServer();
|
||||||
|
|
||||||
int TrySetClientName(int ClientID, const char *pName);
|
int TrySetClientName(int ClientID, const char *pName);
|
||||||
|
@ -238,7 +242,8 @@ public:
|
||||||
|
|
||||||
void ProcessClientPacket(CNetChunk *pPacket);
|
void ProcessClientPacket(CNetChunk *pPacket);
|
||||||
|
|
||||||
void SendServerInfo(const NETADDR *pAddr, int Token, bool Extended=false, int Offset=0);
|
void SendServerInfoConnless(const NETADDR *pAddr, int Token, bool Extended);
|
||||||
|
void SendServerInfo(const NETADDR *pAddr, int Token, bool Extended=false, int Offset=0, bool Short=false);
|
||||||
void UpdateServerInfo();
|
void UpdateServerInfo();
|
||||||
|
|
||||||
void PumpNetwork();
|
void PumpNetwork();
|
||||||
|
|
|
@ -150,6 +150,7 @@ MACRO_CONFIG_INT(SvVanillaAntiSpoof, sv_vanilla_antispoof, 1, 0, 1, CFGFLAG_SERV
|
||||||
|
|
||||||
MACRO_CONFIG_INT(SvPlayerDemoRecord, sv_player_demo_record, 0, 0, 1, CFGFLAG_SERVER, "Automatically record demos for each player")
|
MACRO_CONFIG_INT(SvPlayerDemoRecord, sv_player_demo_record, 0, 0, 1, CFGFLAG_SERVER, "Automatically record demos for each player")
|
||||||
MACRO_CONFIG_INT(SvDemoChat, sv_demo_chat, 0, 0, 1, CFGFLAG_SERVER, "Record chat for demos")
|
MACRO_CONFIG_INT(SvDemoChat, sv_demo_chat, 0, 0, 1, CFGFLAG_SERVER, "Record chat for demos")
|
||||||
|
MACRO_CONFIG_INT(SvServerInfoPerSecond, sv_server_info_per_second, 10, 1, 1000, CFGFLAG_SERVER, "Maximum number of complete server info responses that are sent out per second")
|
||||||
|
|
||||||
MACRO_CONFIG_STR(EcBindaddr, ec_bindaddr, 128, "localhost", CFGFLAG_ECON, "Address to bind the external console to. Anything but 'localhost' is dangerous")
|
MACRO_CONFIG_STR(EcBindaddr, ec_bindaddr, 128, "localhost", CFGFLAG_ECON, "Address to bind the external console to. Anything but 'localhost' is dangerous")
|
||||||
MACRO_CONFIG_INT(EcPort, ec_port, 0, 0, 0, CFGFLAG_ECON, "Port to use for the external console")
|
MACRO_CONFIG_INT(EcPort, ec_port, 0, 0, 0, CFGFLAG_ECON, "Port to use for the external console")
|
||||||
|
|
Loading…
Reference in a new issue