Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new cvars "sv_invalid_length" and "sv_msg_badread" #937

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ This means that plugins that do binary code analysis (Orpheu for example) probab
<li>sv_rehlds_local_gametime <1|0> // A feature of local gametime which decrease "lags" if you run same map for a long time. Default: 0
<li>sv_use_entity_file // Use custom entity file for a map. Path to an entity file will be "maps/[map name].ent". 0 - use original entities. 1 - use .ent files from maps directory. 2 - use .ent files from maps directory and create new .ent file if not exist.
<li>sv_usercmd_custom_random_seed // When enabled server will populate an additional random seed independent of the client. Default: 0
<li>sv_invalid_length // Fix bug to fake players. Default: 0
<li>sv_msg_badread // Disable message flooding in console. Default: 0
</ul>
</details>

Expand Down
3 changes: 3 additions & 0 deletions rehlds/engine/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,9 @@ extern cvar_t sv_rehlds_local_gametime;
extern cvar_t sv_rehlds_send_mapcycle;
extern cvar_t sv_usercmd_custom_random_seed;
#endif
extern cvar_t sv_invalid_length;
extern cvar_t sv_msg_badread;

extern int sv_playermodel;

extern char outputbuf[MAX_ROUTEABLE_PACKET];
Expand Down
6 changes: 6 additions & 0 deletions rehlds/engine/sv_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ cvar_t sv_use_entity_file = { "sv_use_entity_file", "0", 0, 0.0f, nullptr };
cvar_t sv_usercmd_custom_random_seed = { "sv_usercmd_custom_random_seed", "0", 0, 0.0f, nullptr };
#endif

cvar_t sv_invalid_length = { "sv_invalid_length", "0", 0, 0.0f, nullptr };
cvar_t sv_msg_badread = { "sv_msg_badread", "0", 0, 0.0f, nullptr };

delta_t *SV_LookupDelta(char *name)
{
delta_info_t *p = g_sv_delta;
Expand Down Expand Up @@ -8068,6 +8071,9 @@ void SV_Init(void)
Cvar_RegisterVariable(&sv_usercmd_custom_random_seed);
#endif

Cvar_RegisterVariable(&sv_invalid_length);
Cvar_RegisterVariable(&sv_msg_badread);

for (int i = 0; i < MAX_MODELS; i++)
{
Q_snprintf(localmodels[i], sizeof(localmodels[i]), "*%i", i);
Expand Down
23 changes: 14 additions & 9 deletions rehlds/engine/sv_user.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,17 @@ void SV_ParseConsistencyResponse(client_t *pSenderClient)
int length = 0;
int c = 0;
Q_memset(nullbuffer, 0, sizeof(nullbuffer));
int value = MSG_ReadShort();
int mlen = MSG_ReadShort();

if (value <= 0 || !SZ_HasSomethingToRead(&net_message, value))
if (sv_invalid_length.value != 0.0f && mlen <= 0 || !SZ_HasSomethingToRead(&net_message, mlen))
{
msg_badread = TRUE;
Con_DPrintf("%s: %s:%s invalid length: %d\n", __func__, host_client->name, NET_AdrToString(host_client->netchan.remote_address), value);
Con_DPrintf("%s: %s:%s invalid length: %d\n", __func__, host_client->name, NET_AdrToString(host_client->netchan.remote_address), mlen);
SV_DropClient(host_client, FALSE, "Invalid length");
return;
}

COM_UnMunge(&net_message.data[msg_readcount], value, g_psvs.spawncount);
COM_UnMunge(&net_message.data[msg_readcount], mlen, g_psvs.spawncount);
MSG_StartBitReading(&net_message);

while (MSG_ReadBits(1))
Expand Down Expand Up @@ -1585,14 +1585,14 @@ void SV_ParseMove(client_t *pSenderClient)
mlen = MSG_ReadByte();
cbchecksum = MSG_ReadByte();

if (mlen <= 0 || !SZ_HasSpaceToRead(&net_message, mlen))
if (sv_invalid_length.value != 0.0f && mlen <= 0 || !SZ_HasSpaceToRead(&net_message, mlen))
{
msg_badread = TRUE;
Con_DPrintf("%s: %s:%s invalid length: %d\n", __func__, host_client->name, NET_AdrToString(host_client->netchan.remote_address), mlen);
SV_DropClient(host_client, FALSE, "Invalid length");
return;
}

COM_UnMunge(&net_message.data[placeholder + 1], mlen, host_client->netchan.incoming_sequence);

packetLossByte = MSG_ReadByte();
Expand Down Expand Up @@ -1800,7 +1800,11 @@ void EXT_FUNC SV_HandleClientMessage_api(IGameClient* client, uint8 opcode) {
static_assert(REHLDS_API_VERSION_MAJOR <= 3, "Bump major API DETECTED!! You shall rework the hookchain, make function returnable");
msg_badread = 1;

Con_Printf("SV_ReadClientMessage: unknown command char (%d)\n", opcode);
if (sv_msg_badread.value != 0.0f)
{
Con_Printf("SV_ReadClientMessage: unknown command char (%d)\n", opcode);
}

SV_DropClient(cl, FALSE, "Bad command character in client command");
return;
}
Expand All @@ -1816,7 +1820,7 @@ void EXT_FUNC SV_HandleClientMessage_api(IGameClient* client, uint8 opcode) {
func(cl);

#ifdef REHLDS_FIXES
if (msg_badread)
if (msg_badread && sv_msg_badread.value != 0.0f)
{
Con_Printf("SV_ReadClientMessage: badread on %s, opcode %s\n", name, sv_clcfuncs[opcode].pszname);
}
Expand Down Expand Up @@ -1844,10 +1848,11 @@ void SV_ExecuteClientMessage(client_t *cl)

while (1)
{
if (msg_badread)
if (msg_badread && sv_msg_badread.value != 0.0f)
{
#ifdef REHLDS_FIXES
Con_Printf("SV_ReadClientMessage: badread on %s\n", host_client->name);

if (host_client->active)
SV_ClientPrintf("Badread\n");
#else // REHLDS_FIXES
Expand Down