aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2015-08-09 15:30:06 +0200
committerShauren <shauren.trinity@gmail.com>2015-10-31 16:04:14 +0100
commit60da7c6552735c62f8b1aba5634ba5177ef06d44 (patch)
tree437baa73ef4867d6393eb00c8093bceb1c84a101 /src
parent97fe2283346e102742366fdd2f7be4398d27d641 (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.cpp23
-rw-r--r--src/server/game/Server/WorldSocket.h10
-rw-r--r--src/server/shared/Networking/MessageBuffer.h4
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)