mirror of
https://github.com/rehlds/rehlds.git
synced 2025-01-04 02:55:50 +03:00
Fixed stringcmd flood
Fixed const qualifiers in sdk Exported sv_version cvar
This commit is contained in:
parent
5a8aa9ce8b
commit
317a9dc3ba
@ -2426,7 +2426,6 @@ void Host_Changelevel2_f(void)
|
|||||||
void Host_Version_f(void)
|
void Host_Version_f(void)
|
||||||
{
|
{
|
||||||
Con_Printf("Protocol version %i\nExe version %s (%s)\n", PROTOCOL_VERSION, gpszVersionString, gpszProductString);
|
Con_Printf("Protocol version %i\nExe version %s (%s)\n", PROTOCOL_VERSION, gpszVersionString, gpszProductString);
|
||||||
Con_Printf("ReHLDS API version %i.%i\n", REHLDS_API_VERSION_MAJOR, REHLDS_API_VERSION_MINOR);
|
|
||||||
#ifdef REHLDS_FIXES
|
#ifdef REHLDS_FIXES
|
||||||
Con_Printf("Exe build: " __TIME__ " " __DATE__ " (%i)\n", build_number());
|
Con_Printf("Exe build: " __TIME__ " " __DATE__ " (%i)\n", build_number());
|
||||||
#else // REHLDS_FIXES
|
#else // REHLDS_FIXES
|
||||||
@ -2436,6 +2435,7 @@ void Host_Version_f(void)
|
|||||||
Con_Printf("Exe build: 10:03:21 Aug 8 2013 (%i)\n", build_number());
|
Con_Printf("Exe build: 10:03:21 Aug 8 2013 (%i)\n", build_number());
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
#endif // REHLDS_FIXES
|
#endif // REHLDS_FIXES
|
||||||
|
Con_Printf("ReHLDS API version %i.%i\n", REHLDS_API_VERSION_MAJOR, REHLDS_API_VERSION_MINOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* <3d516> ../engine/host_cmd.c:3382 */
|
/* <3d516> ../engine/host_cmd.c:3382 */
|
||||||
|
@ -314,7 +314,7 @@ qboolean NET_IsReservedAdr(netadr_t& a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* <d3352> ../engine/net_ws.c:332 */
|
/* <d3352> ../engine/net_ws.c:332 */
|
||||||
qboolean NET_CompareBaseAdr(netadr_t& a, netadr_t& b)
|
qboolean NET_CompareBaseAdr(const netadr_t& a, const netadr_t& b)
|
||||||
{
|
{
|
||||||
if (a.type != b.type)
|
if (a.type != b.type)
|
||||||
{
|
{
|
||||||
|
@ -234,7 +234,7 @@ NOXREF short unsigned int NET_HostToNetShort(short unsigned int us_in);
|
|||||||
qboolean NET_CompareAdr(netadr_t& a, netadr_t& b);
|
qboolean NET_CompareAdr(netadr_t& a, netadr_t& b);
|
||||||
qboolean NET_CompareClassBAdr(netadr_t& a, netadr_t& b);
|
qboolean NET_CompareClassBAdr(netadr_t& a, netadr_t& b);
|
||||||
qboolean NET_IsReservedAdr(netadr_t& a);
|
qboolean NET_IsReservedAdr(netadr_t& a);
|
||||||
qboolean NET_CompareBaseAdr(netadr_t& a, netadr_t& b);
|
qboolean NET_CompareBaseAdr(const netadr_t& a, const netadr_t& b);
|
||||||
char *NET_AdrToString(const netadr_t& a);
|
char *NET_AdrToString(const netadr_t& a);
|
||||||
char *NET_BaseAdrToString(netadr_t& a);
|
char *NET_BaseAdrToString(netadr_t& a);
|
||||||
qboolean NET_StringToSockaddr(const char *s, struct sockaddr *sadr);
|
qboolean NET_StringToSockaddr(const char *s, struct sockaddr *sadr);
|
||||||
|
@ -652,7 +652,7 @@ int SV_FindEmptySlot(netadr_t *adr, int *pslot, client_t ** ppClient);
|
|||||||
void SV_ConnectClient(void);
|
void SV_ConnectClient(void);
|
||||||
void SV_ConnectClient_internal(void);
|
void SV_ConnectClient_internal(void);
|
||||||
void SVC_Ping(void);
|
void SVC_Ping(void);
|
||||||
int SV_GetChallenge(netadr_t& adr);
|
int SV_GetChallenge(const netadr_t& adr);
|
||||||
void SVC_GetChallenge(void);
|
void SVC_GetChallenge(void);
|
||||||
void SVC_ServiceChallenge(void);
|
void SVC_ServiceChallenge(void);
|
||||||
void SV_ResetModInfo(void);
|
void SV_ResetModInfo(void);
|
||||||
|
@ -194,7 +194,11 @@ cvar_t max_queries_window = { "max_queries_window", "60", FCVAR_SERVER | FCVAR_P
|
|||||||
cvar_t sv_logblocks = { "sv_logblocks", "0", FCVAR_SERVER, 0.0f, NULL };
|
cvar_t sv_logblocks = { "sv_logblocks", "0", FCVAR_SERVER, 0.0f, NULL };
|
||||||
cvar_t sv_downloadurl = { "sv_downloadurl", "", FCVAR_PROTECTED, 0.0f, NULL };
|
cvar_t sv_downloadurl = { "sv_downloadurl", "", FCVAR_PROTECTED, 0.0f, NULL };
|
||||||
cvar_t sv_allow_dlfile = { "sv_allow_dlfile", "1", 0, 0.0f, NULL };
|
cvar_t sv_allow_dlfile = { "sv_allow_dlfile", "1", 0, 0.0f, NULL };
|
||||||
cvar_t sv_version = { "sv_version", "", 0, 0.0f, NULL };
|
#ifdef REHLDS_FIXES
|
||||||
|
cvar_t sv_version = { "sv_version", "", FCVAR_SERVER, 0.0f, NULL };
|
||||||
|
#else
|
||||||
|
cvar_t sv_version = {"sv_version", "", 0, 0.0f, NULL};
|
||||||
|
#endif
|
||||||
|
|
||||||
cvar_t sv_rcon_minfailures = { "sv_rcon_minfailures", "5", 0, 0.0f, NULL };
|
cvar_t sv_rcon_minfailures = { "sv_rcon_minfailures", "5", 0, 0.0f, NULL };
|
||||||
cvar_t sv_rcon_maxfailures = { "sv_rcon_maxfailures", "10", 0, 0.0f, NULL };
|
cvar_t sv_rcon_maxfailures = { "sv_rcon_maxfailures", "10", 0, 0.0f, NULL };
|
||||||
@ -2418,7 +2422,7 @@ void SVC_Ping(void)
|
|||||||
NET_SendPacket(NS_SERVER, sizeof(data), data, net_from);
|
NET_SendPacket(NS_SERVER, sizeof(data), data, net_from);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SV_GetChallenge(netadr_t& adr)
|
int SV_GetChallenge(const netadr_t& adr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
#ifndef REHLDS_OPT_PEDANTIC
|
#ifndef REHLDS_OPT_PEDANTIC
|
||||||
|
@ -1404,12 +1404,23 @@ void SV_RestoreMove(client_t *_host_client)
|
|||||||
/* <bf8bd> ../engine/sv_user.c:1736 */
|
/* <bf8bd> ../engine/sv_user.c:1736 */
|
||||||
void SV_ParseStringCommand(client_t *pSenderClient)
|
void SV_ParseStringCommand(client_t *pSenderClient)
|
||||||
{
|
{
|
||||||
|
//check string commands rate for this player
|
||||||
|
#ifdef REHLDS_FIXES
|
||||||
|
g_StringCommandsRateLimiter.StringCommandIssued(pSenderClient - g_psvs.clients);
|
||||||
|
|
||||||
|
if (!pSenderClient->active) {
|
||||||
|
return; //return if player was kicked
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
char *s = MSG_ReadString();
|
char *s = MSG_ReadString();
|
||||||
int ret = SV_ValidateClientCommand(s);
|
int ret = SV_ValidateClientCommand(s);
|
||||||
switch (ret)
|
switch (ret)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
#ifndef REHLDS_OPT_PEDANTIC
|
||||||
if (Q_strlen(s) > 127)
|
if (Q_strlen(s) > 127)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
s[127] = 0;
|
s[127] = 0;
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ struct RehldsFuncs_t {
|
|||||||
void(*MSG_EndBitWriting)(sizebuf_t *buf);
|
void(*MSG_EndBitWriting)(sizebuf_t *buf);
|
||||||
void*(*SZ_GetSpace)(sizebuf_t *buf, int length);
|
void*(*SZ_GetSpace)(sizebuf_t *buf, int length);
|
||||||
cvar_t*(*GetCvarVars)();
|
cvar_t*(*GetCvarVars)();
|
||||||
int (*SV_GetChallenge)(netadr_t& adr);
|
int (*SV_GetChallenge)(const netadr_t& adr);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IRehldsApi {
|
class IRehldsApi {
|
||||||
|
@ -2,17 +2,19 @@
|
|||||||
|
|
||||||
cvar_t sv_rehlds_movecmdrate_max_avg = { "sv_rehlds_movecmdrate_max_avg", "750", 0, 750.0f, NULL };
|
cvar_t sv_rehlds_movecmdrate_max_avg = { "sv_rehlds_movecmdrate_max_avg", "750", 0, 750.0f, NULL };
|
||||||
cvar_t sv_rehlds_movecmdrate_max_burst = { "sv_rehlds_movecmdrate_max_burst", "3500", 0, 3500.0f, NULL };
|
cvar_t sv_rehlds_movecmdrate_max_burst = { "sv_rehlds_movecmdrate_max_burst", "3500", 0, 3500.0f, NULL };
|
||||||
|
cvar_t sv_rehlds_stringcmdrate_max_avg = {"sv_rehlds_stringcmdrate_max_avg", "32", 0, 32.0f, NULL};
|
||||||
|
cvar_t sv_rehlds_stringcmdrate_max_burst = {"sv_rehlds_stringcmdrate_max_burst", "80", 0, 80.0f, NULL};
|
||||||
|
|
||||||
CMoveCommandRateLimiter g_MoveCommandRateLimiter;
|
CMoveCommandRateLimiter g_MoveCommandRateLimiter;
|
||||||
|
CStringCommandsRateLimiter g_StringCommandsRateLimiter;
|
||||||
|
|
||||||
CMoveCommandRateLimiter::CMoveCommandRateLimiter() {
|
CMoveCommandRateLimiter::CMoveCommandRateLimiter() {
|
||||||
memset(m_AverageMoveCmdRate, 0, sizeof(m_AverageMoveCmdRate));
|
memset(m_AverageMoveCmdRate, 0, sizeof(m_AverageMoveCmdRate));
|
||||||
memset(m_CurrentMoveCmds, 0, sizeof(m_CurrentMoveCmds));
|
memset(m_CurrentMoveCmds, 0, sizeof(m_CurrentMoveCmds));
|
||||||
m_LastCheckTime = 0;
|
m_LastCheckTime = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMoveCommandRateLimiter::UpdateAverageRates(double currentTime) {
|
void CMoveCommandRateLimiter::UpdateAverageRates(double dt) {
|
||||||
double dt = currentTime - m_LastCheckTime;
|
|
||||||
for (unsigned int i = 0; i < MAX_CLIENTS; i++) {
|
for (unsigned int i = 0; i < MAX_CLIENTS; i++) {
|
||||||
m_AverageMoveCmdRate[i] = (2.0 * m_AverageMoveCmdRate[i] / 3.0) + m_CurrentMoveCmds[i] / dt / 3.0;
|
m_AverageMoveCmdRate[i] = (2.0 * m_AverageMoveCmdRate[i] / 3.0) + m_CurrentMoveCmds[i] / dt / 3.0;
|
||||||
m_CurrentMoveCmds[i] = 0;
|
m_CurrentMoveCmds[i] = 0;
|
||||||
@ -29,24 +31,16 @@ void CMoveCommandRateLimiter::Frame() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateAverageRates(currentTime);
|
UpdateAverageRates(dt);
|
||||||
m_LastCheckTime = currentTime;
|
m_LastCheckTime = currentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMoveCommandRateLimiter::ClientConnected(unsigned int clientId) {
|
void CMoveCommandRateLimiter::ClientConnected(unsigned int clientId) {
|
||||||
if (clientId >= (unsigned)g_psvs.maxclients) {
|
|
||||||
rehlds_syserror(__FUNCTION__": Invalid clientId %u", clientId);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_CurrentMoveCmds[clientId] = 0;
|
m_CurrentMoveCmds[clientId] = 0;
|
||||||
m_AverageMoveCmdRate[clientId] = 0.0f;
|
m_AverageMoveCmdRate[clientId] = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMoveCommandRateLimiter::MoveCommandsIssued(unsigned int clientId, unsigned int numCmds) {
|
void CMoveCommandRateLimiter::MoveCommandsIssued(unsigned int clientId, unsigned int numCmds) {
|
||||||
if (clientId >= (unsigned)g_psvs.maxclients) {
|
|
||||||
rehlds_syserror(__FUNCTION__": Invalid clientId %u", clientId);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_CurrentMoveCmds[clientId] += numCmds;
|
m_CurrentMoveCmds[clientId] += numCmds;
|
||||||
CheckBurstRate(clientId);
|
CheckBurstRate(clientId);
|
||||||
}
|
}
|
||||||
@ -79,10 +73,77 @@ void CMoveCommandRateLimiter::CheckAverageRate(unsigned int clientId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CStringCommandsRateLimiter::CStringCommandsRateLimiter() {
|
||||||
|
memset(m_AverageStringCmdRate, 0, sizeof(m_AverageStringCmdRate));
|
||||||
|
memset(m_CurrentStringCmds, 0, sizeof(m_CurrentStringCmds));
|
||||||
|
m_LastCheckTime = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStringCommandsRateLimiter::UpdateAverageRates(double dt) {
|
||||||
|
for (unsigned int i = 0; i < MAX_CLIENTS; i++) {
|
||||||
|
m_AverageStringCmdRate[i] = (2.0 * m_AverageStringCmdRate[i] / 3.0) + m_CurrentStringCmds[i] / dt / 3.0;
|
||||||
|
m_CurrentStringCmds[i] = 0;
|
||||||
|
|
||||||
|
CheckAverageRate(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStringCommandsRateLimiter::Frame() {
|
||||||
|
double currentTime = realtime;
|
||||||
|
double dt = currentTime - m_LastCheckTime;
|
||||||
|
|
||||||
|
if (dt < 0.5) { //refresh avg. rate every 0.5 sec
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateAverageRates(dt);
|
||||||
|
m_LastCheckTime = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStringCommandsRateLimiter::ClientConnected(unsigned int clientId) {
|
||||||
|
m_CurrentStringCmds[clientId] = 0;
|
||||||
|
m_AverageStringCmdRate[clientId] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStringCommandsRateLimiter::StringCommandIssued(unsigned int clientId) {
|
||||||
|
m_CurrentStringCmds[clientId]++;
|
||||||
|
CheckBurstRate(clientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStringCommandsRateLimiter::CheckBurstRate(unsigned int clientId) {
|
||||||
|
client_t* cl = &g_psvs.clients[clientId];
|
||||||
|
if (!cl->active || sv_rehlds_stringcmdrate_max_burst.value <= 0.0f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double dt = realtime - m_LastCheckTime;
|
||||||
|
if (dt < 0.2) {
|
||||||
|
dt = 0.2; //small intervals may give too high rates
|
||||||
|
}
|
||||||
|
if ((m_CurrentStringCmds[clientId] / dt) > sv_rehlds_stringcmdrate_max_burst.value) {
|
||||||
|
Cbuf_AddText(va("addip %i %s\n", 5, NET_BaseAdrToString(cl->netchan.remote_address)));
|
||||||
|
SV_DropClient(cl, false, "Banned for string commands flooding (burst)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStringCommandsRateLimiter::CheckAverageRate(unsigned int clientId) {
|
||||||
|
client_t* cl = &g_psvs.clients[clientId];
|
||||||
|
if (!cl->active || sv_rehlds_stringcmdrate_max_burst.value <= 0.0f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_AverageStringCmdRate[clientId] > sv_rehlds_stringcmdrate_max_avg.value) {
|
||||||
|
Cbuf_AddText(va("addip %i %s\n", 5, NET_BaseAdrToString(cl->netchan.remote_address)));
|
||||||
|
SV_DropClient(cl, false, "Banned for string commands flooding (Avg)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Rehlds_Security_Init() {
|
void Rehlds_Security_Init() {
|
||||||
#ifdef REHLDS_FIXES
|
#ifdef REHLDS_FIXES
|
||||||
Cvar_RegisterVariable(&sv_rehlds_movecmdrate_max_avg);
|
Cvar_RegisterVariable(&sv_rehlds_movecmdrate_max_avg);
|
||||||
Cvar_RegisterVariable(&sv_rehlds_movecmdrate_max_burst);
|
Cvar_RegisterVariable(&sv_rehlds_movecmdrate_max_burst);
|
||||||
|
Cvar_RegisterVariable(&sv_rehlds_stringcmdrate_max_avg);
|
||||||
|
Cvar_RegisterVariable(&sv_rehlds_stringcmdrate_max_burst);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,11 +153,13 @@ void Rehlds_Security_Shutdown() {
|
|||||||
void Rehlds_Security_Frame() {
|
void Rehlds_Security_Frame() {
|
||||||
#ifdef REHLDS_FIXES
|
#ifdef REHLDS_FIXES
|
||||||
g_MoveCommandRateLimiter.Frame();
|
g_MoveCommandRateLimiter.Frame();
|
||||||
|
g_StringCommandsRateLimiter.Frame();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rehlds_Security_ClientConnected(unsigned int clientId) {
|
void Rehlds_Security_ClientConnected(unsigned int clientId) {
|
||||||
#ifdef REHLDS_FIXES
|
#ifdef REHLDS_FIXES
|
||||||
g_MoveCommandRateLimiter.ClientConnected(clientId);
|
g_MoveCommandRateLimiter.ClientConnected(clientId);
|
||||||
|
g_StringCommandsRateLimiter.ClientConnected(clientId);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
@ -22,6 +22,26 @@ private:
|
|||||||
|
|
||||||
extern CMoveCommandRateLimiter g_MoveCommandRateLimiter;
|
extern CMoveCommandRateLimiter g_MoveCommandRateLimiter;
|
||||||
|
|
||||||
|
class CStringCommandsRateLimiter {
|
||||||
|
public:
|
||||||
|
CStringCommandsRateLimiter();
|
||||||
|
void Frame();
|
||||||
|
void StringCommandIssued(unsigned int clientId);
|
||||||
|
void ClientConnected(unsigned int clientId);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void UpdateAverageRates(double currentTime);
|
||||||
|
void CheckBurstRate(unsigned int clientId);
|
||||||
|
void CheckAverageRate(unsigned int clientId);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float m_AverageStringCmdRate[MAX_CLIENTS];
|
||||||
|
int m_CurrentStringCmds[MAX_CLIENTS];
|
||||||
|
double m_LastCheckTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern CStringCommandsRateLimiter g_StringCommandsRateLimiter;
|
||||||
|
|
||||||
extern void Rehlds_Security_Init();
|
extern void Rehlds_Security_Init();
|
||||||
extern void Rehlds_Security_Shutdown();
|
extern void Rehlds_Security_Shutdown();
|
||||||
extern void Rehlds_Security_Frame();
|
extern void Rehlds_Security_Frame();
|
||||||
|
Loading…
Reference in New Issue
Block a user