Handle incomplete packets in cProtocolRecognizer
This commit is contained in:
parent
87af95b67c
commit
e0a44fb3bc
@ -83,46 +83,58 @@ void cProtocolRecognizer::DataReceived(const char * a_Data, size_t a_Size)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_InPingForUnrecognizedVersion)
|
if (!m_InPingForUnrecognizedVersion)
|
||||||
|
{
|
||||||
|
if (TryRecognizeProtocol())
|
||||||
|
{
|
||||||
|
// The protocol has just been recognized, dump the whole m_Buffer contents into it for parsing:
|
||||||
|
AString Dump;
|
||||||
|
m_Buffer.ResetRead();
|
||||||
|
m_Buffer.ReadAll(Dump);
|
||||||
|
m_Protocol->DataReceived(Dump.data(), Dump.size());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Buffer.ResetRead();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_InPingForUnrecognizedVersion)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle server list ping packets
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
// We already know the verison; handle it here.
|
|
||||||
UInt32 PacketLen;
|
UInt32 PacketLen;
|
||||||
UInt32 PacketID;
|
UInt32 PacketID;
|
||||||
if (!m_Buffer.ReadVarInt32(PacketLen))
|
if (
|
||||||
|
!m_Buffer.ReadVarInt32(PacketLen) ||
|
||||||
|
!m_Buffer.CanReadBytes(PacketLen) ||
|
||||||
|
!m_Buffer.ReadVarInt32(PacketID)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return;
|
// Not enough data
|
||||||
}
|
m_Buffer.ResetRead();
|
||||||
if (!m_Buffer.ReadVarInt32(PacketID))
|
break;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((PacketID != 0x01) || (PacketLen != 9))
|
|
||||||
{
|
|
||||||
// Not a Ping packet
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Int64 Data;
|
if ((PacketID == 0x00) && (PacketLen == 1)) // Request packet
|
||||||
if (!m_Buffer.ReadBEInt64(Data))
|
|
||||||
{
|
{
|
||||||
|
HandlePacketStatusRequest();
|
||||||
|
}
|
||||||
|
else if ((PacketID == 0x01) && (PacketLen == 9)) // Ping packet
|
||||||
|
{
|
||||||
|
HandlePacketStatusPing();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Client->Kick("Server list ping failed, unrecognized packet");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cPacketizer Pkt(*this, 0x01); // Pong packet
|
|
||||||
Pkt.WriteBEInt64(Data);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TryRecognizeProtocol())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The protocol has just been recognized, dump the whole m_Buffer contents into it for parsing:
|
|
||||||
AString Dump;
|
|
||||||
m_Buffer.ResetRead();
|
|
||||||
m_Buffer.ReadAll(Dump);
|
|
||||||
m_Protocol->DataReceived(Dump.data(), Dump.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1108,20 +1120,6 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_InPingForUnrecognizedVersion = true;
|
m_InPingForUnrecognizedVersion = true;
|
||||||
|
|
||||||
UInt32 PacketLen;
|
|
||||||
UInt32 PacketID;
|
|
||||||
if (!m_Buffer.ReadVarInt32(PacketLen))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!m_Buffer.ReadVarInt32(PacketID))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ASSERT(PacketID == 0x00); // Request packet
|
|
||||||
ASSERT(PacketLen == 1); // No payload except for packet ID
|
|
||||||
SendPingStatusResponse();
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1155,7 +1153,7 @@ void cProtocolRecognizer::SendPacket(cPacketizer & a_Pkt)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cProtocolRecognizer::SendPingStatusResponse(void)
|
void cProtocolRecognizer::HandlePacketStatusRequest(void)
|
||||||
{
|
{
|
||||||
cServer * Server = cRoot::Get()->GetServer();
|
cServer * Server = cRoot::Get()->GetServer();
|
||||||
AString ServerDescription = Server->GetDescription();
|
AString ServerDescription = Server->GetDescription();
|
||||||
@ -1200,3 +1198,18 @@ void cProtocolRecognizer::SendPingStatusResponse(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocolRecognizer::HandlePacketStatusPing()
|
||||||
|
{
|
||||||
|
Int64 Timestamp;
|
||||||
|
if (!m_Buffer.ReadBEInt64(Timestamp))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cPacketizer Pkt(*this, 0x01); // Pong packet
|
||||||
|
Pkt.WriteBEInt64(Timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,8 +143,6 @@ public:
|
|||||||
|
|
||||||
virtual void SendData(const char * a_Data, size_t a_Size) override;
|
virtual void SendData(const char * a_Data, size_t a_Size) override;
|
||||||
|
|
||||||
void SendPingStatusResponse(void);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** The recognized protocol */
|
/** The recognized protocol */
|
||||||
cProtocol * m_Protocol;
|
cProtocol * m_Protocol;
|
||||||
@ -155,6 +153,9 @@ protected:
|
|||||||
/** Is a server list ping for an unrecognized version currently occuring? */
|
/** Is a server list ping for an unrecognized version currently occuring? */
|
||||||
bool m_InPingForUnrecognizedVersion;
|
bool m_InPingForUnrecognizedVersion;
|
||||||
|
|
||||||
|
// Packet handlers while in status state (m_InPingForUnrecognizedVersion == true)
|
||||||
|
void HandlePacketStatusRequest();
|
||||||
|
void HandlePacketStatusPing();
|
||||||
|
|
||||||
/** Tries to recognize protocol based on m_Buffer contents; returns true if recognized */
|
/** Tries to recognize protocol based on m_Buffer contents; returns true if recognized */
|
||||||
bool TryRecognizeProtocol(void);
|
bool TryRecognizeProtocol(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user