1
0
mirror of https://github.com/Mauler125/r5sdk.git synced 2025-02-09 19:15:03 +01:00

Add change callback for 'sv_rcon_maxconnections'

If 'sv_rcon_maxconnections' is set higher than current auth socket count, reopen listen socket. If its set lower, close all sockets until auth socket count matches 'sv_rcon_maxconnections'. Sockets are getting closed in reverse order, so the netcon that connected last will be disconnected first.
This commit is contained in:
Kawe Mazidjatari 2023-04-22 16:51:18 +02:00
parent 9b65c7e59c
commit 50b3273101
5 changed files with 70 additions and 7 deletions

@ -526,15 +526,23 @@ bool CRConServer::CheckForBan(CConnectedNetConsoleData* pData)
}
//-----------------------------------------------------------------------------
// Purpose: close specific connection
// Purpose: close connection on current index
//-----------------------------------------------------------------------------
void CRConServer::Disconnect(const char* szReason) // NETMGR
{
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(m_nConnIndex);
Disconnect(m_nConnIndex, szReason);
}
//-----------------------------------------------------------------------------
// Purpose: close specific connection by index
//-----------------------------------------------------------------------------
void CRConServer::Disconnect(const int nIndex, const char* szReason) // NETMGR
{
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(nIndex);
if (pData->m_bAuthorized || sv_rcon_debug->GetBool())
{
// Inform server owner when authenticated connection has been closed.
netadr_t netAdr = m_Socket.GetAcceptedSocketAddress(m_nConnIndex);
netadr_t netAdr = m_Socket.GetAcceptedSocketAddress(nIndex);
if (!szReason)
{
szReason = "unknown reason";
@ -544,7 +552,7 @@ void CRConServer::Disconnect(const char* szReason) // NETMGR
m_nAuthConnections--;
}
m_Socket.CloseAcceptedSocket(m_nConnIndex);
m_Socket.CloseAcceptedSocket(nIndex);
}
//-----------------------------------------------------------------------------
@ -597,6 +605,14 @@ bool CRConServer::IsInitialized(void) const
return m_bInitialized;
}
//-----------------------------------------------------------------------------
// Purpose: returns the number of authenticated connections
//-----------------------------------------------------------------------------
int CRConServer::GetAuthenticatedCount(void) const
{
return m_nAuthConnections;
}
///////////////////////////////////////////////////////////////////////////////
CRConServer g_RCONServer;
CRConServer* RCONServer() // Singleton RCON Server.

@ -34,7 +34,6 @@ public:
const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const;
bool SendToAll(const char* pMsgBuf, const int nMsgLen) const;
bool Serialize(vector<char>& vecBuf, const char* pResponseMsg, const char* pResponseVal, const sv_rcon::response_t responseType,
const int nMessageId = static_cast<int>(eDLL_T::NETCON), const int nMessageType = static_cast<int>(LogType_t::LOG_NET)) const;
@ -47,11 +46,14 @@ public:
bool CheckForBan(CConnectedNetConsoleData* pData);
virtual void Disconnect(const char* szReason = nullptr) override;
void Disconnect(const int nIndex, const char* szReason = nullptr);
void CloseNonAuthConnection(void);
bool ShouldSend(const sv_rcon::response_t responseType) const;
bool IsInitialized(void) const;
int GetAuthenticatedCount(void) const;
private:
int m_nConnIndex;
int m_nAuthConnections;

@ -350,7 +350,7 @@ void ConVar::StaticInit(void)
sv_rcon_maxfailures = ConVar::StaticCreate("sv_rcon_maxfailures", "10", FCVAR_RELEASE, "Max number of times a user can fail rcon authentication before being banned.", true, 1.f, false, 0.f, nullptr, nullptr);
sv_rcon_maxignores = ConVar::StaticCreate("sv_rcon_maxignores" , "15", FCVAR_RELEASE, "Max number of times a user can ignore the instruction message before being banned.", true, 1.f, false, 0.f, nullptr, nullptr);
sv_rcon_maxsockets = ConVar::StaticCreate("sv_rcon_maxsockets" , "32", FCVAR_RELEASE, "Max number of accepted sockets before the server starts closing redundant sockets.", true, 1.f, false, 0.f, nullptr, nullptr);
sv_rcon_maxconnections = ConVar::StaticCreate("sv_rcon_maxconnections" , "1" , FCVAR_RELEASE, "Max number of authenticated connections before the server closes the listen socket.", true, 1.f, false, 0.f, nullptr, nullptr);
sv_rcon_maxconnections = ConVar::StaticCreate("sv_rcon_maxconnections" , "1" , FCVAR_RELEASE, "Max number of authenticated connections before the server closes the listen socket.", true, 1.f, false, 0.f, &RCON_ConnectionCountChanged_f, nullptr);
sv_rcon_maxpacketsize = ConVar::StaticCreate("sv_rcon_maxpacketsize" , "1024", FCVAR_RELEASE, "Max number of bytes allowed in a command packet from a non-authenticated net console.", true, 0.f, false, 0.f, nullptr, nullptr);
sv_rcon_whitelist_address = ConVar::StaticCreate("sv_rcon_whitelist_address", "" , FCVAR_RELEASE, "This address is not considered a 'redundant' socket and will never be banned for failed authentication attempts.", false, 0.f, false, 0.f, &RCON_WhiteListAddresChanged_f, "Format: '::ffff:127.0.0.1'");

@ -979,7 +979,51 @@ void RCON_WhiteListAddresChanged_f(IConVar* pConVar, const char* pOldString, flo
if (!RCONServer()->SetWhiteListAddress(pConVarRef->GetString()))
{
Warning(eDLL_T::COMMON, "Failed to set RCON whitelist address: %s\n", pConVarRef->GetString());
Warning(eDLL_T::SERVER, "Failed to set RCON whitelist address: %s\n", pConVarRef->GetString());
}
}
}
/*
=====================
RCON_ConnectionCountChanged_f
Change max connection
count on RCON server
=====================
*/
void RCON_ConnectionCountChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue)
{
if (!RCONServer()->IsInitialized())
return; // Not initialized; no sockets at this point.
if (ConVar* pConVarRef = g_pCVar->FindVar(pConVar->GetCommandName()))
{
if (strcmp(pOldString, pConVarRef->GetString()) == NULL)
return; // Same count.
const int maxCount = pConVarRef->GetInt();
int count = RCONServer()->GetAuthenticatedCount();
CSocketCreator* pCreator = RCONServer()->GetSocketCreator();
if (count < maxCount)
{
if (!pCreator->IsListening())
{
pCreator->CreateListenSocket(*RCONServer()->GetNetAddress());
}
}
else
{
while (count > maxCount)
{
RCONServer()->Disconnect(count-1, "too many authenticated sockets");
count = RCONServer()->GetAuthenticatedCount();
}
pCreator->CloseListenSocket();
RCONServer()->CloseNonAuthConnection();
}
}
}

@ -53,6 +53,7 @@ void RCON_Disconnect_f(const CCommand& args);
void RCON_PasswordChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);
#ifndef CLIENT_DLL
void RCON_WhiteListAddresChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);
void RCON_ConnectionCountChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);
void SQVM_ServerScript_f(const CCommand& args);
#endif // !CLIENT_DLL
#ifndef DEDICATED