Core/Networking: Fixed possible crashes happening if async query retrieving account data takes too long
Closes #14944 (cherry picked from commit 590c6e399d778db459fc8417322c80549081440a)
This commit is contained in:
1 parent
97fe228334
commit
60da7c6552
3 files changed
+24
-13
No files matched your search
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user