diff options
author | Shauren <shauren.trinity@gmail.com> | 2015-08-09 15:30:06 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2015-10-31 16:04:14 +0100 |
commit | 60da7c6552735c62f8b1aba5634ba5177ef06d44 (patch) | |
tree | 437baa73ef4867d6393eb00c8093bceb1c84a101 /src | |
parent | 97fe2283346e102742366fdd2f7be4398d27d641 (diff) |
Core/Networking: Fixed possible crashes happening if async query retrieving account data takes too long
Closes #14944
(cherry picked from commit 590c6e399d778db459fc8417322c80549081440a)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Server/WorldSocket.cpp | 23 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.h | 10 | ||||
-rw-r--r-- | src/server/shared/Networking/MessageBuffer.h | 4 |
3 files changed, 24 insertions, 13 deletions
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 6d7e41e8af8..1dc470744a1 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -166,13 +166,15 @@ void WorldSocket::ReadHandler() } // just received fresh new payload - if (!ReadDataHandler()) + ReadDataHandlerResult result = ReadDataHandler(); + _headerBuffer.Reset(); + if (result != ReadDataHandlerResult::Ok) { - CloseSocket(); + if (result != ReadDataHandlerResult::WaitingForQuery) + CloseSocket(); + return; } - - _headerBuffer.Reset(); } AsyncRead(); @@ -265,7 +267,7 @@ struct AccountInfo } }; -bool WorldSocket::ReadDataHandler() +WorldSocket::ReadDataHandlerResult WorldSocket::ReadDataHandler() { ClientPktHeader* header = reinterpret_cast<ClientPktHeader*>(_headerBuffer.GetReadPointer()); @@ -282,7 +284,7 @@ bool WorldSocket::ReadDataHandler() { case CMSG_PING: LogOpcodeText(opcode, sessionGuard); - return HandlePing(packet); + return HandlePing(packet) ? ReadDataHandlerResult::Ok : ReadDataHandlerResult::Error; case CMSG_AUTH_SESSION: LogOpcodeText(opcode, sessionGuard); if (_authed) @@ -290,11 +292,11 @@ bool WorldSocket::ReadDataHandler() // locking just to safely log offending user is probably overkill but we are disconnecting him anyway if (sessionGuard.try_lock()) TC_LOG_ERROR("network", "WorldSocket::ProcessIncoming: received duplicate CMSG_AUTH_SESSION from %s", _worldSession->GetPlayerInfo().c_str()); - return false; + return ReadDataHandlerResult::Error; } HandleAuthSession(packet); - break; + return ReadDataHandlerResult::WaitingForQuery; case CMSG_KEEP_ALIVE: LogOpcodeText(opcode, sessionGuard); break; @@ -306,7 +308,7 @@ bool WorldSocket::ReadDataHandler() { TC_LOG_ERROR("network.opcode", "ProcessIncoming: Client not authed opcode = %u", uint32(opcode)); CloseSocket(); - return false; + return ReadDataHandlerResult::Error; } // Our Idle timer will reset on any non PING opcodes. @@ -319,7 +321,7 @@ bool WorldSocket::ReadDataHandler() } } - return true; + return ReadDataHandlerResult::Ok; } void WorldSocket::LogOpcodeText(uint16 opcode, std::unique_lock<std::mutex> const& guard) const @@ -559,6 +561,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<AuthSession> authSes _queryCallback = io_service().wrap(std::bind(&WorldSocket::LoadSessionPermissionsCallback, this, std::placeholders::_1)); _queryFuture = _worldSession->LoadPermissionsAsync(); + AsyncRead(); } void WorldSocket::LoadSessionPermissionsCallback(PreparedQueryResult result) diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index 35941f15154..f0da520cf4c 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -66,7 +66,15 @@ protected: void OnClose() override; void ReadHandler() override; bool ReadHeaderHandler(); - bool ReadDataHandler(); + + enum class ReadDataHandlerResult + { + Ok = 0, + Error = 1, + WaitingForQuery = 2 + }; + + ReadDataHandlerResult ReadDataHandler(); private: void CheckIpCallback(PreparedQueryResult result); diff --git a/src/server/shared/Networking/MessageBuffer.h b/src/server/shared/Networking/MessageBuffer.h index 95e26974626..5f9af33a45d 100644 --- a/src/server/shared/Networking/MessageBuffer.h +++ b/src/server/shared/Networking/MessageBuffer.h @@ -84,9 +84,9 @@ public: // Ensures there's "some" free space, make sure to call Normalize() before this void EnsureFreeSpace() { - // Double the size of the buffer if it's already full + // resize buffer if it's already full if (GetRemainingSpace() == 0) - _storage.resize(_storage.size() * 2); + _storage.resize(_storage.size() * 3 / 2); } void Write(void const* data, std::size_t size) |