RCON system light refactor

* Used 'htonl'/'ntohl' for constructing the length prefix.
* Used static socket/address members instead of pointers.
* Used const qualifier where possible.
* Changed length prefix field type to 'u_long'.
* Removed extraneous include.
* Properly escaped percentage characters on the RCON game client for the ImGui console.
This commit is contained in:
Kawe Mazidjatari 2022-11-14 21:00:41 +01:00
parent 9533afc628
commit 4b1c5dd5a3
8 changed files with 148 additions and 170 deletions

View File

@ -31,14 +31,14 @@ class CConnectedNetConsoleData
{
public:
SocketHandle_t m_hSocket;
int m_nPayloadLen; // Num bytes for this message.
int m_nPayloadRead; // Num read bytes from input buffer.
u_long m_nPayloadLen; // Num bytes for this message.
u_long m_nPayloadRead; // Num read bytes from input buffer.
int m_nFailedAttempts; // Num failed authentication attempts.
int m_nIgnoredMessage; // Count how many times client ignored the no-auth message.
bool m_bValidated; // Revalidates netconsole if false.
bool m_bAuthorized; // Set to true after successful netconsole auth.
bool m_bInputOnly; // If set, don't send spew to this net console.
std::vector<uint8_t> m_RecvBuffer;
vector<uint8_t> m_RecvBuffer;
CConnectedNetConsoleData(SocketHandle_t hSocket = -1)
{
@ -50,7 +50,7 @@ public:
m_bValidated = false;
m_bAuthorized = false;
m_bInputOnly = false;
m_RecvBuffer.resize(sizeof(int)); // Reserve enough for length-prefix.
m_RecvBuffer.resize(sizeof(u_long)); // Reserve enough for length-prefix.
}
};

View File

@ -22,9 +22,8 @@
CRConClient::CRConClient()
: m_bInitialized(false)
, m_bConnEstablished(false)
, m_NetAdr2("localhost", "37015")
{
m_pNetAdr2 = new CNetAdr2("localhost", "37015");
m_pSocket = new CSocketCreator();
}
//-----------------------------------------------------------------------------
@ -32,8 +31,6 @@ CRConClient::CRConClient()
//-----------------------------------------------------------------------------
CRConClient::~CRConClient(void)
{
delete m_pNetAdr2;
delete m_pSocket;
}
//-----------------------------------------------------------------------------
@ -66,7 +63,7 @@ void CRConClient::Shutdown(void)
//-----------------------------------------------------------------------------
bool CRConClient::SetPassword(const char* pszPassword)
{
size_t nLen = std::strlen(pszPassword);
const size_t nLen = std::strlen(pszPassword);
if (nLen < 8)
{
if (nLen > 0)
@ -98,15 +95,15 @@ bool CRConClient::Connect(void)
if (strlen(rcon_address->GetString()) > 0)
{
// Default is [127.0.0.1]:37015
m_pNetAdr2->SetIPAndPort(rcon_address->GetString());
m_NetAdr2.SetIPAndPort(rcon_address->GetString());
}
if (m_pSocket->ConnectSocket(*m_pNetAdr2, true) == SOCKET_ERROR)
if (m_Socket.ConnectSocket(m_NetAdr2, true) == SOCKET_ERROR)
{
Warning(eDLL_T::CLIENT, "Connection to RCON server failed: (SOCKET_ERROR)\n");
Warning(eDLL_T::CLIENT, "Connection to RCON server failed: (%s)\n", "SOCKET_ERROR");
return false;
}
DevMsg(eDLL_T::CLIENT, "Connected to: %s\n", m_pNetAdr2->GetIPAndPort().c_str());
DevMsg(eDLL_T::CLIENT, "Connected to: %s\n", m_NetAdr2.GetIPAndPort().c_str());
m_bConnEstablished = true;
return true;
@ -123,15 +120,15 @@ bool CRConClient::Connect(const std::string& svInAdr, const std::string& svInPor
if (!svInAdr.empty() && !svInPort.empty())
{
// Default is [127.0.0.1]:37015
m_pNetAdr2->SetIPAndPort(svInAdr, svInPort);
m_NetAdr2.SetIPAndPort(svInAdr, svInPort);
}
if (m_pSocket->ConnectSocket(*m_pNetAdr2, true) == SOCKET_ERROR)
if (m_Socket.ConnectSocket(m_NetAdr2, true) == SOCKET_ERROR)
{
Warning(eDLL_T::CLIENT, "Connection to RCON server failed: (SOCKET_ERROR)\n");
Warning(eDLL_T::CLIENT, "Connection to RCON server failed: (%s)\n", "SOCKET_ERROR");
return false;
}
DevMsg(eDLL_T::CLIENT, "Connected to: %s\n", m_pNetAdr2->GetIPAndPort().c_str());
DevMsg(eDLL_T::CLIENT, "Connected to: %s\n", m_NetAdr2.GetIPAndPort().c_str());
m_bConnEstablished = true;
return true;
@ -142,7 +139,7 @@ bool CRConClient::Connect(const std::string& svInAdr, const std::string& svInPor
//-----------------------------------------------------------------------------
void CRConClient::Disconnect(void)
{
m_pSocket->CloseAcceptedSocket(0);
m_Socket.CloseAcceptedSocket(0);
m_bConnEstablished = false;
}
@ -153,18 +150,16 @@ void CRConClient::Disconnect(void)
void CRConClient::Send(const std::string& svMessage) const
{
std::ostringstream ssSendBuf;
const u_long nLen = htonl(svMessage.size());
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 24);
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 16);
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 8 );
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()));
ssSendBuf << svMessage;
ssSendBuf.write(reinterpret_cast<const char*>(&nLen), sizeof(u_long));
ssSendBuf.write(svMessage.data(), svMessage.size());
int nSendResult = ::send(m_pSocket->GetAcceptedSocketData(0)->m_hSocket,
int nSendResult = ::send(m_Socket.GetAcceptedSocketData(0)->m_hSocket,
ssSendBuf.str().data(), static_cast<int>(ssSendBuf.str().size()), MSG_NOSIGNAL);
if (nSendResult == SOCKET_ERROR)
{
Warning(eDLL_T::CLIENT, "Failed to send RCON message: (SOCKET_ERROR)\n");
Warning(eDLL_T::CLIENT, "Failed to send RCON message: (%s)\n", "SOCKET_ERROR");
}
}
@ -174,11 +169,11 @@ void CRConClient::Send(const std::string& svMessage) const
void CRConClient::Recv(void)
{
static char szRecvBuf[1024];
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(0);
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(0);
{//////////////////////////////////////////////
int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
if (nPendingLen == SOCKET_ERROR && m_pSocket->IsSocketBlocking())
const int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
if (nPendingLen == SOCKET_ERROR && m_Socket.IsSocketBlocking())
{
return;
}
@ -195,14 +190,14 @@ void CRConClient::Recv(void)
while (nReadLen > 0)
{
int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
const int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
if (nRecvLen == 0 && m_bConnEstablished) // Socket was closed.
{
this->Disconnect();
DevMsg(eDLL_T::CLIENT, "Server closed RCON connection\n");
break;
}
if (nRecvLen < 0 && !m_pSocket->IsSocketBlocking())
if (nRecvLen < 0 && !m_Socket.IsSocketBlocking())
{
Error(eDLL_T::CLIENT, NO_ERROR, "RCON Cmd: recv error (%s)\n", NET_ErrorString(WSAGetLastError()));
break;
@ -241,7 +236,7 @@ void CRConClient::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNe
pData->m_nPayloadRead = 0;
}
}
else if (pData->m_nPayloadRead < sizeof(int)) // Read size field.
else if (pData->m_nPayloadRead < sizeof(u_long)) // Read size field.
{
pData->m_RecvBuffer[pData->m_nPayloadRead++] = *pRecvBuf;
@ -250,11 +245,7 @@ void CRConClient::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNe
}
else // Build prefix.
{
pData->m_nPayloadLen = static_cast<int>(
pData->m_RecvBuffer[0] << 24 |
pData->m_RecvBuffer[1] << 16 |
pData->m_RecvBuffer[2] << 8 |
pData->m_RecvBuffer[3]);
pData->m_nPayloadLen = ntohl(*reinterpret_cast<u_long*>(&pData->m_RecvBuffer[0]));
pData->m_nPayloadRead = 0;
if (pData->m_nPayloadLen < 0 ||
@ -279,15 +270,13 @@ void CRConClient::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNe
//-----------------------------------------------------------------------------
void CRConClient::ProcessMessage(const sv_rcon::response& sv_response) const
{
std::string svOut = sv_response.responsebuf();
switch (sv_response.responsetype())
{
case sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH:
{
if (!sv_response.responseval().empty())
{
long i = strtol(sv_response.responseval().c_str(), NULL, NULL);
const long i = strtol(sv_response.responseval().c_str(), NULL, NULL);
if (!i) // sv_rcon_sendlogs is not set.
{
if (cl_rcon_request_sendlogs->GetBool())
@ -298,12 +287,12 @@ void CRConClient::ProcessMessage(const sv_rcon::response& sv_response) const
}
}
DevMsg(eDLL_T::NETCON, "%s", svOut.c_str());
DevMsg(eDLL_T::NETCON, "%s", PrintPercentageEscape(sv_response.responsebuf()).c_str());
break;
}
case sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG:
{
NetMsg(static_cast<EGlobalContext_t>(sv_response.responseid()), svOut.c_str());
NetMsg(static_cast<EGlobalContext_t>(sv_response.responseid()), PrintPercentageEscape(sv_response.responsebuf()).c_str());
break;
}
default:
@ -320,7 +309,7 @@ void CRConClient::ProcessMessage(const sv_rcon::response& sv_response) const
// request_t -
// Output : serialized results as string
//-----------------------------------------------------------------------------
std::string CRConClient::Serialize(const std::string& svReqBuf, const std::string& svReqVal, cl_rcon::request_t request_t) const
std::string CRConClient::Serialize(const std::string& svReqBuf, const std::string& svReqVal, const cl_rcon::request_t request_t) const
{
cl_rcon::request cl_request;
@ -376,8 +365,8 @@ bool CRConClient::IsConnected(void) const
return m_bConnEstablished;
}
///////////////////////////////////////////////////////////////////////////////
CRConClient* g_pRConClient = new CRConClient();
CRConClient* RCONClient()
CRConClient g_RCONClient;
CRConClient* RCONClient() // Singleton RCON Client.
{
return g_pRConClient;
return &g_RCONClient;
}

View File

@ -26,18 +26,18 @@ public:
void ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetConsoleData* pData);
void ProcessMessage(const sv_rcon::response& sv_response) const;
std::string Serialize(const std::string& svReqBuf, const std::string& svReqVal, cl_rcon::request_t request_t) const;
std::string Serialize(const std::string& svReqBuf, const std::string& svReqVal, const cl_rcon::request_t request_t) const;
sv_rcon::response Deserialize(const std::string& svBuf) const;
bool IsInitialized(void) const;
bool IsConnected(void) const;
private:
CNetAdr2* m_pNetAdr2;
CSocketCreator* m_pSocket;
bool m_bInitialized = false;
bool m_bConnEstablished = false;
CNetAdr2 m_NetAdr2;
CSocketCreator m_Socket;
};
extern CRConClient* g_pRConClient;
CRConClient* RCONClient();

View File

@ -25,8 +25,6 @@ CRConServer::CRConServer(void)
: m_bInitialized(false)
, m_nConnIndex(0)
{
m_pAdr2 = new CNetAdr2();
m_pSocket = new CSocketCreator();
}
//-----------------------------------------------------------------------------
@ -34,8 +32,6 @@ CRConServer::CRConServer(void)
//-----------------------------------------------------------------------------
CRConServer::~CRConServer(void)
{
delete m_pAdr2;
delete m_pSocket;
}
//-----------------------------------------------------------------------------
@ -51,8 +47,8 @@ void CRConServer::Init(void)
}
}
m_pAdr2->SetIPAndPort(rcon_address->GetString(), hostport->GetString());
m_pSocket->CreateListenSocket(*m_pAdr2, false);
m_Adr2.SetIPAndPort(rcon_address->GetString(), hostport->GetString());
m_Socket.CreateListenSocket(m_Adr2, false);
DevMsg(eDLL_T::SERVER, "Remote server access initialized\n");
m_bInitialized = true;
@ -63,9 +59,9 @@ void CRConServer::Init(void)
//-----------------------------------------------------------------------------
void CRConServer::Shutdown(void)
{
if (m_pSocket->IsListening())
if (m_Socket.IsListening())
{
m_pSocket->CloseListenSocket();
m_Socket.CloseListenSocket();
}
m_bInitialized = false;
}
@ -75,17 +71,17 @@ void CRConServer::Shutdown(void)
//-----------------------------------------------------------------------------
void CRConServer::Think(void)
{
int nCount = m_pSocket->GetAcceptedSocketCount();
const int nCount = m_Socket.GetAcceptedSocketCount();
// Close redundant sockets if there are too many except for whitelisted and authenticated.
if (nCount >= sv_rcon_maxsockets->GetInt())
{
for (m_nConnIndex = nCount - 1; m_nConnIndex >= 0; m_nConnIndex--)
{
CNetAdr2 netAdr2 = m_pSocket->GetAcceptedSocketAddress(m_nConnIndex);
const CNetAdr2 netAdr2 = m_Socket.GetAcceptedSocketAddress(m_nConnIndex);
if (netAdr2.GetIP(true).compare(sv_rcon_whitelist_address->GetString()) != 0)
{
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(m_nConnIndex);
const CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(m_nConnIndex);
if (!pData->m_bAuthorized)
{
this->CloseConnection();
@ -97,9 +93,9 @@ void CRConServer::Think(void)
// Create a new listen socket if authenticated connection is closed.
if (nCount == 0)
{
if (!m_pSocket->IsListening())
if (!m_Socket.IsListening())
{
m_pSocket->CreateListenSocket(*m_pAdr2, false);
m_Socket.CreateListenSocket(m_Adr2, false);
}
}
}
@ -112,9 +108,9 @@ void CRConServer::Think(void)
bool CRConServer::SetPassword(const char* pszPassword)
{
m_bInitialized = false;
m_pSocket->CloseAllAcceptedSockets();
m_Socket.CloseAllAcceptedSockets();
size_t nLen = std::strlen(pszPassword);
const size_t nLen = std::strlen(pszPassword);
if (nLen < 8)
{
if (nLen > 0)
@ -140,7 +136,7 @@ void CRConServer::RunFrame(void)
{
if (m_bInitialized)
{
m_pSocket->RunFrame();
m_Socket.RunFrame();
this->Think();
this->Recv();
}
@ -152,19 +148,17 @@ void CRConServer::RunFrame(void)
//-----------------------------------------------------------------------------
void CRConServer::Send(const std::string& svMessage) const
{
if (int nCount = m_pSocket->GetAcceptedSocketCount())
if (const int nCount = m_Socket.GetAcceptedSocketCount())
{
std::ostringstream ssSendBuf;
const u_long nLen = htonl(svMessage.size());
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 24);
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 16);
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 8 );
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()));
ssSendBuf << svMessage;
ssSendBuf.write(reinterpret_cast<const char*>(&nLen), sizeof(u_long));
ssSendBuf.write(svMessage.data(), svMessage.size());
for (int i = nCount - 1; i >= 0; i--)
{
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(i);
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(i);
if (pData->m_bAuthorized)
{
@ -179,15 +173,13 @@ void CRConServer::Send(const std::string& svMessage) const
// Input : hSocket -
// *svMessage -
//-----------------------------------------------------------------------------
void CRConServer::Send(SocketHandle_t hSocket, const std::string& svMessage) const
void CRConServer::Send(const SocketHandle_t hSocket, const std::string& svMessage) const
{
std::ostringstream ssSendBuf;
const u_long nLen = htonl(svMessage.size());
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 24);
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 16);
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 8 );
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()));
ssSendBuf << svMessage;
ssSendBuf.write(reinterpret_cast<const char*>(&nLen), sizeof(u_long));
ssSendBuf.write(svMessage.data(), svMessage.size());
::send(hSocket, ssSendBuf.str().data(), static_cast<int>(ssSendBuf.str().size()), MSG_NOSIGNAL);
}
@ -199,7 +191,7 @@ void CRConServer::Send(SocketHandle_t hSocket, const std::string& svMessage) con
// responseType -
// nResponseId -
//-----------------------------------------------------------------------------
void CRConServer::Send(const std::string& svRspBuf, const std::string& svRspVal, sv_rcon::response_t responseType, int nResponseId)
void CRConServer::Send(const std::string& svRspBuf, const std::string& svRspVal, const sv_rcon::response_t responseType, const int nResponseId)
{
if (responseType == sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG)
{
@ -219,7 +211,7 @@ void CRConServer::Send(const std::string& svRspBuf, const std::string& svRspVal,
// responseType -
// nResponseId -
//-----------------------------------------------------------------------------
void CRConServer::Send(SocketHandle_t hSocket, const std::string& svRspBuf, const std::string& svRspVal, sv_rcon::response_t responseType, int nResponseId)
void CRConServer::Send(const SocketHandle_t hSocket, const std::string& svRspBuf, const std::string& svRspVal, const sv_rcon::response_t responseType, const int nResponseId)
{
if (responseType == sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG)
{
@ -236,12 +228,12 @@ void CRConServer::Send(SocketHandle_t hSocket, const std::string& svRspBuf, cons
//-----------------------------------------------------------------------------
void CRConServer::Recv(void)
{
int nCount = m_pSocket->GetAcceptedSocketCount();
const int nCount = m_Socket.GetAcceptedSocketCount();
static char szRecvBuf[1024];
for (m_nConnIndex = nCount - 1; m_nConnIndex >= 0; m_nConnIndex--)
{
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(m_nConnIndex);
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(m_nConnIndex);
{//////////////////////////////////////////////
if (this->CheckForBan(pData))
{
@ -250,8 +242,8 @@ void CRConServer::Recv(void)
continue;
}
int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
if (nPendingLen == SOCKET_ERROR && m_pSocket->IsSocketBlocking())
const int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
if (nPendingLen == SOCKET_ERROR && m_Socket.IsSocketBlocking())
{
continue;
}
@ -267,13 +259,13 @@ void CRConServer::Recv(void)
while (nReadLen > 0)
{
int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
const int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
if (nRecvLen == 0) // Socket was closed.
{
this->CloseConnection();
break;
}
if (nRecvLen < 0 && !m_pSocket->IsSocketBlocking())
if (nRecvLen < 0 && !m_Socket.IsSocketBlocking())
{
Error(eDLL_T::SERVER, NO_ERROR, "RCON Cmd: recv error (%s)\n", NET_ErrorString(WSAGetLastError()));
break;
@ -292,7 +284,7 @@ void CRConServer::Recv(void)
// responseType -
// Output : serialized results as string
//-----------------------------------------------------------------------------
std::string CRConServer::Serialize(const std::string& svRspBuf, const std::string& svRspVal, sv_rcon::response_t responseType, int nResponseId) const
std::string CRConServer::Serialize(const std::string& svRspBuf, const std::string& svRspVal, const sv_rcon::response_t responseType, const int nResponseId) const
{
sv_rcon::response sv_response;
@ -350,14 +342,14 @@ void CRConServer::Authenticate(const cl_rcon::request& cl_request, CConnectedNet
if (this->Comparator(cl_request.requestbuf()))
{
pData->m_bAuthorized = true;
m_pSocket->CloseListenSocket();
m_Socket.CloseListenSocket();
this->CloseNonAuthConnection();
this->Send(pData->m_hSocket, this->Serialize(s_pszAuthMessage, sv_rcon_sendlogs->GetString(), sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(EGlobalContext_t::NETCON_S)));
}
else // Bad password.
{
CNetAdr2 netAdr2 = m_pSocket->GetAcceptedSocketAddress(m_nConnIndex);
const CNetAdr2 netAdr2 = m_Socket.GetAcceptedSocketAddress(m_nConnIndex);
if (sv_rcon_debug->GetBool())
{
DevMsg(eDLL_T::SERVER, "Bad RCON password attempt from '%s'\n", netAdr2.GetIPAndPort().c_str());
@ -422,7 +414,7 @@ void CRConServer::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNe
pData->m_nPayloadRead = 0;
}
}
else if (pData->m_nPayloadRead < sizeof(int)) // Read size field.
else if (pData->m_nPayloadRead < sizeof(u_long)) // Read size field.
{
pData->m_RecvBuffer[pData->m_nPayloadRead++] = *pRecvBuf;
@ -431,11 +423,7 @@ void CRConServer::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNe
}
else // Build prefix.
{
pData->m_nPayloadLen = static_cast<int>(
pData->m_RecvBuffer[0] << 24 |
pData->m_RecvBuffer[1] << 16 |
pData->m_RecvBuffer[2] << 8 |
pData->m_RecvBuffer[3]);
pData->m_nPayloadLen = ntohl(*reinterpret_cast<u_long*>(&pData->m_RecvBuffer[0]));
pData->m_nPayloadRead = 0;
if (!pData->m_bAuthorized)
@ -469,7 +457,7 @@ void CRConServer::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNe
//-----------------------------------------------------------------------------
void CRConServer::ProcessMessage(const cl_rcon::request& cl_request)
{
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(m_nConnIndex);
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(m_nConnIndex);
if (!pData->m_bAuthorized
&& cl_request.requesttype() != cl_rcon::request_t::SERVERDATA_REQUEST_AUTH)
@ -524,7 +512,7 @@ void CRConServer::ProcessMessage(const cl_rcon::request& cl_request)
// Input : *cl_request -
// bConVar -
//-----------------------------------------------------------------------------
void CRConServer::Execute(const cl_rcon::request& cl_request, bool bConVar) const
void CRConServer::Execute(const cl_rcon::request& cl_request, const bool bConVar) const
{
if (bConVar)
{
@ -552,20 +540,20 @@ bool CRConServer::CheckForBan(CConnectedNetConsoleData* pData)
}
pData->m_bValidated = true;
CNetAdr2 netAdr2 = m_pSocket->GetAcceptedSocketAddress(m_nConnIndex);
CNetAdr2 netAdr2 = m_Socket.GetAcceptedSocketAddress(m_nConnIndex);
// Check if IP is in the ban vector.
if (std::find(m_vBannedAddress.begin(), m_vBannedAddress.end(),
netAdr2.GetIP(true)) != m_vBannedAddress.end())
// Check if IP is in the banned list.
if (std::find(m_vBannedList.begin(), m_vBannedList.end(),
netAdr2.GetIP(true)) != m_vBannedList.end())
{
return true;
}
// Check if net console has reached maximum number of attempts and add to ban vector.
// Check if net console has reached maximum number of attempts > add to banned list.
if (pData->m_nFailedAttempts >= sv_rcon_maxfailures->GetInt()
|| pData->m_nIgnoredMessage >= sv_rcon_maxignores->GetInt())
{
// Don't add whitelisted address to ban vector.
// Don't add white listed address to banned list.
if (netAdr2.GetIP(true).compare(sv_rcon_whitelist_address->GetString()) == 0)
{
pData->m_nFailedAttempts = 0;
@ -574,7 +562,7 @@ bool CRConServer::CheckForBan(CConnectedNetConsoleData* pData)
}
DevMsg(eDLL_T::SERVER, "Banned '%s' for RCON hacking attempts\n", netAdr2.GetIPAndPort().c_str());
m_vBannedAddress.push_back(netAdr2.GetIP(true));
m_vBannedList.push_back(netAdr2.GetIP(true));
return true;
}
return false;
@ -585,14 +573,14 @@ bool CRConServer::CheckForBan(CConnectedNetConsoleData* pData)
//-----------------------------------------------------------------------------
void CRConServer::CloseConnection(void) // NETMGR
{
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(m_nConnIndex);
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(m_nConnIndex);
if (pData->m_bAuthorized)
{
// Inform server owner when authenticated connection has been closed.
CNetAdr2 netAdr2 = m_pSocket->GetAcceptedSocketAddress(m_nConnIndex);
CNetAdr2 netAdr2 = m_Socket.GetAcceptedSocketAddress(m_nConnIndex);
DevMsg(eDLL_T::SERVER, "Net console '%s' closed RCON connection\n", netAdr2.GetIPAndPort().c_str());
}
m_pSocket->CloseAcceptedSocket(m_nConnIndex);
m_Socket.CloseAcceptedSocket(m_nConnIndex);
}
//-----------------------------------------------------------------------------
@ -600,14 +588,14 @@ void CRConServer::CloseConnection(void) // NETMGR
//-----------------------------------------------------------------------------
void CRConServer::CloseNonAuthConnection(void)
{
int nCount = m_pSocket->GetAcceptedSocketCount();
int nCount = m_Socket.GetAcceptedSocketCount();
for (int i = nCount - 1; i >= 0; i--)
{
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(i);
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(i);
if (!pData->m_bAuthorized)
{
m_pSocket->CloseAcceptedSocket(i);
m_Socket.CloseAcceptedSocket(i);
}
}
}
@ -622,8 +610,8 @@ bool CRConServer::IsInitialized(void) const
}
///////////////////////////////////////////////////////////////////////////////
CRConServer* g_pRConServer = new CRConServer();
CRConServer* RCONServer()
CRConServer g_RCONServer;
CRConServer* RCONServer() // Singleton RCON Server.
{
return g_pRConServer;
return &g_RCONServer;
}

View File

@ -23,12 +23,12 @@ public:
void RunFrame(void);
void Send(const std::string& svMessage) const;
void Send(SocketHandle_t hSocket, const std::string& svMessage) const;
void Send(const std::string& svRspBuf, const std::string& svRspVal, sv_rcon::response_t responseType, int nResponseId = -4);
void Send(SocketHandle_t hSocket, const std::string& svRspBuf, const std::string& svRspVal, sv_rcon::response_t responseType, int nResponseId = -4);
void Send(const SocketHandle_t hSocket, const std::string& svMessage) const;
void Send(const std::string& svRspBuf, const std::string& svRspVal, const sv_rcon::response_t responseType, const int nResponseId = -4);
void Send(const SocketHandle_t hSocket, const std::string& svRspBuf, const std::string& svRspVal, const sv_rcon::response_t responseType, const int nResponseId = -4);
void Recv(void);
std::string Serialize(const std::string& svRspBuf, const std::string& svRspVal, sv_rcon::response_t responseType, int nResponseId = -4) const;
std::string Serialize(const std::string& svRspBuf, const std::string& svRspVal, const sv_rcon::response_t responseType, const int nResponseId = -4) const;
cl_rcon::request Deserialize(const std::string& svBuf) const;
void Authenticate(const cl_rcon::request& cl_request, CConnectedNetConsoleData* pData);
@ -37,7 +37,7 @@ public:
void ProcessBuffer(const char* pszIn, int nRecvLen, CConnectedNetConsoleData* pData);
void ProcessMessage(const cl_rcon::request& cl_request);
void Execute(const cl_rcon::request& cl_request, bool bConVar) const;
void Execute(const cl_rcon::request& cl_request, const bool bConVar) const;
bool CheckForBan(CConnectedNetConsoleData* pData);
void CloseConnection(void);
@ -49,10 +49,10 @@ private:
bool m_bInitialized;
int m_nConnIndex;
CNetAdr2* m_pAdr2;
CSocketCreator* m_pSocket;
std::vector<std::string> m_vBannedAddress;
std::vector<std::string> m_vBannedList;
std::string m_svPasswordHash;
CNetAdr2 m_Adr2;
CSocketCreator m_Socket;
};
extern CRConServer* g_pRConServer;
CRConServer* RCONServer();

View File

@ -23,9 +23,8 @@ CNetCon::CNetCon(void)
, m_bQuitApplication(false)
, m_abPromptConnect(true)
, m_abConnEstablished(false)
, m_NetAdr2("localhost", "37015")
{
m_pNetAdr2 = new CNetAdr2("localhost", "37015");
m_pSocket = new CSocketCreator();
}
//-----------------------------------------------------------------------------
@ -33,8 +32,6 @@ CNetCon::CNetCon(void)
//-----------------------------------------------------------------------------
CNetCon::~CNetCon(void)
{
delete m_pNetAdr2;
delete m_pSocket;
}
//-----------------------------------------------------------------------------
@ -43,8 +40,8 @@ CNetCon::~CNetCon(void)
//-----------------------------------------------------------------------------
bool CNetCon::Init(void)
{
WSAData wsaData{};
int nError = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
WSAData wsaData;
const int nError = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
if (nError != 0)
{
@ -72,10 +69,10 @@ bool CNetCon::Init(void)
//-----------------------------------------------------------------------------
bool CNetCon::Shutdown(void)
{
m_pSocket->CloseAllAcceptedSockets();
m_Socket.CloseAllAcceptedSockets();
m_abConnEstablished = false;
int nError = ::WSACleanup();
const int nError = ::WSACleanup();
if (nError != 0)
{
std::cerr << "Failed to stop Winsock via WSACleanup: (" << NET_ErrorString(WSAGetLastError()) << ")" << std::endl;
@ -114,7 +111,6 @@ void CNetCon::TermSetup(void)
}
CONSOLE_SCREEN_BUFFER_INFOEX sbInfoEx{};
COLORREF storedBG = sbInfoEx.ColorTable[0];
sbInfoEx.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
GetConsoleScreenBufferInfoEx(hOutput, &sbInfoEx);
@ -146,7 +142,7 @@ void CNetCon::UserInput(void)
return;
}
vector<string> vSubStrings = StringSplit(svInput, ' ', 2);
const std::vector<std::string> vSubStrings = StringSplit(svInput, ' ', 2);
if (vSubStrings.size() > 1)
{
if (vSubStrings[0].compare("PASS") == 0) // Auth with RCON server.
@ -178,7 +174,7 @@ void CNetCon::UserInput(void)
{
if (!svInput.empty())
{
string::size_type nPos = svInput.find(' ');
const string::size_type nPos = svInput.find(' ');
if (nPos > 0
&& nPos < svInput.size()
&& nPos != svInput.size())
@ -244,15 +240,15 @@ bool CNetCon::Connect(const std::string& svInAdr, const std::string& svInPort)
if (!svInAdr.empty() && !svInPort.empty())
{
// Default is [127.0.0.1]:37015
m_pNetAdr2->SetIPAndPort(svInAdr, svInPort);
m_NetAdr2.SetIPAndPort(svInAdr, svInPort);
}
if (m_pSocket->ConnectSocket(*m_pNetAdr2, true) == SOCKET_ERROR)
if (m_Socket.ConnectSocket(m_NetAdr2, true) == SOCKET_ERROR)
{
std::cerr << "Failed to connect. Error: (SOCKET_ERROR). Verify IP and PORT." << std::endl;
return false;
}
std::cout << "Connected to: " << m_pNetAdr2->GetIPAndPort() << std::endl;
std::cout << "Connected to: " << m_NetAdr2.GetIPAndPort() << std::endl;
m_abConnEstablished = true;
return true;
@ -263,7 +259,7 @@ bool CNetCon::Connect(const std::string& svInAdr, const std::string& svInPort)
//-----------------------------------------------------------------------------
void CNetCon::Disconnect(void)
{
m_pSocket->CloseAcceptedSocket(0);
m_Socket.CloseAcceptedSocket(0);
m_abPromptConnect = true;
m_abConnEstablished = false;
}
@ -275,14 +271,12 @@ void CNetCon::Disconnect(void)
void CNetCon::Send(const std::string& svMessage) const
{
std::ostringstream ssSendBuf;
const u_long nLen = htonl(svMessage.size());
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 24);
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 16);
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()) >> 8 );
ssSendBuf << static_cast<uint8_t>(static_cast<int>(svMessage.size()));
ssSendBuf << svMessage;
ssSendBuf.write(reinterpret_cast<const char*>(&nLen), sizeof(u_long));
ssSendBuf.write(svMessage.data(), svMessage.size());
int nSendResult = ::send(m_pSocket->GetAcceptedSocketData(0)->m_hSocket,
const int nSendResult = ::send(m_Socket.GetAcceptedSocketData(0)->m_hSocket,
ssSendBuf.str().data(), static_cast<int>(ssSendBuf.str().size()), MSG_NOSIGNAL);
if (nSendResult == SOCKET_ERROR)
{
@ -296,11 +290,11 @@ void CNetCon::Send(const std::string& svMessage) const
void CNetCon::Recv(void)
{
static char szRecvBuf[1024];
CConnectedNetConsoleData* pData = m_pSocket->GetAcceptedSocketData(0);
CConnectedNetConsoleData* pData = m_Socket.GetAcceptedSocketData(0);
{//////////////////////////////////////////////
int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
if (nPendingLen == SOCKET_ERROR && m_pSocket->IsSocketBlocking())
const int nPendingLen = ::recv(pData->m_hSocket, szRecvBuf, sizeof(char), MSG_PEEK);
if (nPendingLen == SOCKET_ERROR && m_Socket.IsSocketBlocking())
{
return;
}
@ -317,14 +311,14 @@ void CNetCon::Recv(void)
while (nReadLen > 0)
{
int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
const int nRecvLen = ::recv(pData->m_hSocket, szRecvBuf, MIN(sizeof(szRecvBuf), nReadLen), MSG_NOSIGNAL);
if (nRecvLen == 0 && m_abConnEstablished) // Socket was closed.
{
this->Disconnect();
std::cout << "Server closed connection" << std::endl;
break;
}
if (nRecvLen < 0 && !m_pSocket->IsSocketBlocking())
if (nRecvLen < 0 && !m_Socket.IsSocketBlocking())
{
std::cout << "RCON Cmd: recv error (" << NET_ErrorString(WSAGetLastError()) << ")" << std::endl;
break;
@ -372,11 +366,7 @@ void CNetCon::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetCon
}
else // Build prefix.
{
pData->m_nPayloadLen = static_cast<int>(
pData->m_RecvBuffer[0] << 24 |
pData->m_RecvBuffer[1] << 16 |
pData->m_RecvBuffer[2] << 8 |
pData->m_RecvBuffer[3]);
pData->m_nPayloadLen = ntohl(*reinterpret_cast<u_long*>(&pData->m_RecvBuffer[0]));
pData->m_nPayloadRead = 0;
if (pData->m_nPayloadLen < 0 ||
@ -401,14 +391,13 @@ void CNetCon::ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetCon
//-----------------------------------------------------------------------------
void CNetCon::ProcessMessage(const sv_rcon::response& sv_response) const
{
static std::regex rxAnsiExp("\\\033\\[.*?m");
switch (sv_response.responsetype())
{
case sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH:
{
if (!sv_response.responseval().empty())
{
long i = strtol(sv_response.responseval().c_str(), NULL, NULL);
const long i = strtol(sv_response.responseval().c_str(), NULL, NULL);
if (!i) // sv_rcon_sendlogs is not set.
{
string svLogQuery = this->Serialize("", "", cl_rcon::request_t::SERVERDATA_REQUEST_SEND_CONSOLE_LOG);
@ -422,7 +411,7 @@ void CNetCon::ProcessMessage(const sv_rcon::response& sv_response) const
std::string svOut = sv_response.responsebuf();
if (m_bNoColor)
{
svOut = std::regex_replace(svOut, rxAnsiExp, "");
svOut = std::regex_replace(svOut, std::regex("\\\033\\[.*?m"), "");
}
else
{
@ -445,7 +434,7 @@ void CNetCon::ProcessMessage(const sv_rcon::response& sv_response) const
// request_t -
// Output : serialized results as string
//-----------------------------------------------------------------------------
std::string CNetCon::Serialize(const std::string& svReqBuf, const std::string& svReqVal, cl_rcon::request_t request_t) const
std::string CNetCon::Serialize(const std::string& svReqBuf, const std::string& svReqVal, const cl_rcon::request_t request_t) const
{
cl_rcon::request cl_request;
@ -490,31 +479,39 @@ sv_rcon::response CNetCon::Deserialize(const std::string& svBuf) const
//-----------------------------------------------------------------------------
int main(int argc, char* argv[])
{
CNetCon* pNetCon = new CNetCon();
std::cout << "R5Reloaded TCP net console [Version " << NETCON_VERSION << "]" << std::endl;
if (!pNetCon->Init())
if (!NetConsole()->Init())
{
return EXIT_FAILURE;
}
if (argc >= 3) // Get IP and Port from command line.
{
if (!pNetCon->Connect(argv[1], argv[2]))
if (!NetConsole()->Connect(argv[1], argv[2]))
{
return EXIT_FAILURE;
}
}
while (!pNetCon->ShouldQuit())
while (!NetConsole()->ShouldQuit())
{
pNetCon->UserInput();
NetConsole()->UserInput();
}
if (!pNetCon->Shutdown())
if (!NetConsole()->Shutdown())
{
return EXIT_FAILURE;
}
return ERROR_SUCCESS;
}
//-----------------------------------------------------------------------------
// singleton
//-----------------------------------------------------------------------------
CNetCon g_NetCon;
inline CNetCon* NetConsole()
{
return &g_NetCon;
}

View File

@ -33,18 +33,23 @@ public:
void ProcessBuffer(const char* pRecvBuf, int nRecvLen, CConnectedNetConsoleData* pData);
void ProcessMessage(const sv_rcon::response& sv_response) const;
std::string Serialize(const std::string& svReqBuf, const std::string& svReqVal, cl_rcon::request_t request_t) const;
std::string Serialize(const std::string& svReqBuf, const std::string& svReqVal, const cl_rcon::request_t request_t) const;
sv_rcon::response Deserialize(const std::string& svBuf) const;
private:
CNetAdr2* m_pNetAdr2;
CSocketCreator* m_pSocket;
bool m_bInitialized;
bool m_bNoColor;
bool m_bQuitApplication;
std::atomic<bool> m_abPromptConnect;
std::atomic<bool> m_abConnEstablished;
CNetAdr2 m_NetAdr2;
CSocketCreator m_Socket;
mutable std::mutex m_Mutex;
};
//-----------------------------------------------------------------------------
// singleton
//-----------------------------------------------------------------------------
extern CNetCon* NetConsole();

View File

@ -11,7 +11,6 @@
#include <engine/sys_utils.h>
#endif // !NETCONSOLE
#include <engine/net.h>
#include <netconsole/netconsole.h>
//-----------------------------------------------------------------------------
// Purpose: Constructor