20 #pragma warning(disable:4355)
64 LOG(
"RCON Client \"%s\" connected!", a_RemoteIPAddress.c_str());
65 return std::make_shared<cRCONServer::cConnection>(
m_RCONServer, a_RemoteIPAddress);
70 LOGWARNING(
"RCON server error on port %d: %d (%s)",
m_Port, a_ErrorCode, a_ErrorMsg.c_str());
148 LOGWARNING(
"RCON is requested, but the password is not set. RCON is now disabled.");
156 for (
const auto & port: Ports)
161 LOGINFO(
"Invalid RCON port value: \"%s\". Ignoring.", port.c_str());
164 auto Handle =
cNetwork::Listen(PortNum, std::make_shared<cRCONListenCallbacks>(*
this, PortNum));
165 if (Handle->IsListening())
173 LOGWARNING(
"RCON is enabled but no valid ports were found. RCON is not accessible.");
185 m_IsAuthenticated(false),
186 m_RCONServer(a_RCONServer),
187 m_IPAddress(a_IPAddress)
206 ASSERT(m_Link !=
nullptr);
209 m_Buffer.append(a_Data, a_Size);
212 while (m_Buffer.size() >= 14)
214 UInt32 Length = UIntFromBuffer(m_Buffer.data());
218 LOGWARNING(
"Received an invalid RCON packet length (%d), dropping RCON connection to %s.",
219 Length, m_IPAddress.c_str()
225 if (Length >
static_cast<UInt32>(m_Buffer.size() + 4))
231 UInt32 RequestID = UIntFromBuffer(m_Buffer.data() + 4);
232 UInt32 PacketType = UIntFromBuffer(m_Buffer.data() + 8);
233 if (!ProcessPacket(RequestID, PacketType, Length - 10, m_Buffer.data() + 12))
239 m_Buffer.erase(0, Length + 4);
258 LOGD(
"Error in RCON connection %s: %d (%s)", m_IPAddress.c_str(), a_ErrorCode, a_ErrorMsg.c_str());
268 switch (a_PacketType)
272 if (strncmp(a_Payload, m_RCONServer.m_Password.c_str(), a_PayloadLength) != 0)
274 LOGINFO(
"RCON: Invalid password from client %s, dropping connection.", m_IPAddress.c_str());
278 m_IsAuthenticated =
true;
280 LOGD(
"RCON: Client at %s has successfully authenticated", m_IPAddress.c_str());
289 if (!m_IsAuthenticated)
291 char AuthNeeded[] =
"You need to authenticate first!";
296 AString cmd(a_Payload, a_PayloadLength);
297 LOGD(
"RCON command from %s: \"%s\"", m_IPAddress.c_str(), cmd.c_str());
307 LOGWARNING(
"RCON: Client at %s has sent an unknown packet type %d, dropping connection.",
308 m_IPAddress.c_str(), a_PacketType
319 const Byte * Buffer =
reinterpret_cast<const Byte *
>(a_Buffer);
320 return static_cast<UInt32>((Buffer[3] << 24) | (Buffer[2] << 16) | (Buffer[1] << 8) | Buffer[0]);
329 a_Buffer[0] =
static_cast<char>(a_Value & 0xff);
330 a_Buffer[1] =
static_cast<char>((a_Value >> 8) & 0xff);
331 a_Buffer[2] =
static_cast<char>((a_Value >> 16) & 0xff);
332 a_Buffer[3] =
static_cast<char>((a_Value >> 24) & 0xff);
341 ASSERT((a_PayloadLength == 0) || (a_Payload !=
nullptr));
342 ASSERT(m_Link !=
nullptr);
345 UInt32 Length = a_PayloadLength + 10;
346 UIntToBuffer(Length, Buffer);
347 UIntToBuffer(a_RequestID, Buffer + 4);
348 UIntToBuffer(a_PacketType, Buffer + 8);
349 m_Link->Send(Buffer, 12);
350 if (a_PayloadLength > 0)
352 m_Link->Send(a_Payload, a_PayloadLength);
354 m_Link->Send(
"\0", 2);
AStringVector ReadUpgradeIniPorts(cSettingsRepositoryInterface &a_Settings, const AString &a_KeyName, const AString &a_PortsValueName, const AString &a_OldIPv4ValueName, const AString &a_OldIPv6ValueName, const AString &a_DefaultValue)
Reads the list of ports from the INI file, possibly upgrading from IPv4 / IPv6-specific values into n...
void LOGWARNING(std::string_view a_Format, const Args &... args)
void LOG(std::string_view a_Format, const Args &... args)
void LOGINFO(std::string_view a_Format, const Args &... args)
std::shared_ptr< cTCPLink > cTCPLinkPtr
std::vector< AString > AStringVector
bool StringToInteger(const AString &a_str, T &a_Num)
Parses any integer type.
Interface for a callback that receives command output The Out() function is called for any output the...
Interface that provides the methods available on a single TCP connection.
std::shared_ptr< cCallbacks > cCallbacksPtr
static cServerHandlePtr Listen(UInt16 a_Port, cListenCallbacksPtr a_ListenCallbacks)
Opens up the specified port for incoming connections.
Callbacks used when listening for incoming connections as a server.
virtual cTCPLink::cCallbacksPtr OnIncomingConnection(const AString &a_RemoteIPAddress, UInt16 a_RemotePort) override
Called when the TCP server created with Listen() receives a new incoming connection.
cRCONListenCallbacks(cRCONServer &a_RCONServer, UInt16 a_Port)
cRCONServer & m_RCONServer
The RCON server instance that we're attached to.
virtual void OnAccepted(cTCPLink &a_Link) override
Called when the TCP server created with Listen() creates a new link for an incoming connection.
UInt16 m_Port
The port for which this instance is responsible.
virtual void OnError(int a_ErrorCode, const AString &a_ErrorMsg) override
Called when the socket fails to listen on the specified port.
virtual void Finished(void) override
Called when the command processing has been finished.
cRCONServer::cConnection & m_Connection
virtual void Out(const AString &a_Text) override
Called when the command wants to output anything; may be called multiple times.
cRCONCommandOutput(cRCONServer::cConnection &a_Connection, UInt32 a_RequestID)
cServerHandlePtrs m_ListenServers
The sockets for accepting RCON connections (one socket per port).
AString m_Password
Password for authentication.
void Initialize(cSettingsRepositoryInterface &a_Settings)
cRCONServer(cServer &a_Server)
friend class cRCONCommandOutput
virtual void OnLinkCreated(cTCPLinkPtr a_Link) override
Called when the cTCPLink for the connection is created.
virtual void OnReceivedData(const char *a_Data, size_t a_Length) override
Called when there's data incoming from the remote peer.
bool ProcessPacket(UInt32 a_RequestID, UInt32 a_PacketType, UInt32 a_PayloadLength, const char *a_Payload)
Processes the given packet and sends the response; returns true if successful, false if the connectio...
void SendResponse(UInt32 a_RequestID, UInt32 a_PacketType, UInt32 a_PayloadLength, const char *a_Payload)
Sends a RCON packet back to the client.
void UIntToBuffer(UInt32 a_Value, char *a_Buffer)
Puts 4 bytes representing the int into the buffer.
cConnection(cRCONServer &a_RCONServer, const AString &a_IPAddress)
virtual void OnError(int a_ErrorCode, const AString &a_ErrorMsg) override
Called when an error is detected on the connection.
virtual void OnRemoteClosed(void) override
Called when the remote end closes the connection.
UInt32 UIntFromBuffer(const char *a_Buffer)
Reads 4 bytes from a_Buffer and returns the LE UInt32 they represent.
void QueueExecuteConsoleCommand(const AString &a_Cmd, cCommandOutputCallback &a_Output)
Queues a console command for execution through the cServer class.
virtual bool GetValueSetB(const AString &keyname, const AString &valuename, const bool defValue=false)=0
virtual AString GetValueSet(const AString &keyname, const AString &valuename, const AString &defValue="")=0
Gets the value; if not found, write the default to the repository.