From 49ef21d6505c76fb26d50c99934e801ba6016049 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 17 Jan 2021 15:13:32 +0000 Subject: MultiVersionProtocol: fix two crashes First one: add missing exception handler in ProcessProtocolIn Second: remove faulty logic dealing with incomplete packets. `a_Data = a_Data.substr(m_Buffer.GetUsedSpace() - m_Buffer.GetReadableSpace());` was incorrect; it attempted to apply a length derived from m_Buffer to an unrelated a_Data. Its purpose was to give cProtocol the data the client sent, minus initial handshake bytes. However, we can use the knowledge that during initial handshake, there is no encryption and every byte can be written unchanged into m_Buffer, to just call cProtocol with a data length of zero. This will cause it to parse from m_Buffer - wherein we have already written everything the client sent - with no a_Data manipulation needed. Additionally, removed UnsupportedButPingableProtocolException (use of exception as control flow) and encode this state as m_Protocol == nullptr, id est "no protocol for this unsupported version", which is then handled by cMultiVersionProtocol itself. --- src/ClientHandle.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'src/ClientHandle.cpp') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index ffb968a0c..9d236e4d5 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1981,14 +1981,7 @@ void cClientHandle::Tick(float a_Dt) m_BreakProgress += m_Player->GetMiningProgressPerTick(Block); } - try - { - ProcessProtocolIn(); - } - catch (const std::exception & Oops) - { - Kick(Oops.what()); - } + ProcessProtocolIn(); if (IsDestroyed()) { @@ -3171,7 +3164,7 @@ void cClientHandle::PacketBufferFull(void) { // Too much data in the incoming queue, the server is probably too busy, kick the client: LOGERROR("Too much data in queue for client \"%s\" @ %s, kicking them.", m_Username.c_str(), m_IPString.c_str()); - SendDisconnect("Server busy"); + SendDisconnect("The server is busy; please try again later."); } @@ -3249,10 +3242,19 @@ void cClientHandle::ProcessProtocolIn(void) std::swap(IncomingData, m_IncomingData); } - if (!IncomingData.empty()) + if (IncomingData.empty()) + { + return; + } + + try { m_Protocol.HandleIncomingData(*this, IncomingData); } + catch (const std::exception & Oops) + { + Kick(Oops.what()); + } } -- cgit v1.2.3