aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/game/Server/WorldSocket.cpp25
-rw-r--r--src/server/game/Server/WorldSocket.h8
2 files changed, 25 insertions, 8 deletions
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index 0b0eeda6b86..3e22c91e2a1 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -71,11 +71,11 @@ uint8 const WorldSocket::EncryptionKeySeed[16] = { 0xE9, 0x75, 0x3C, 0x50, 0x90,
WorldSocket::WorldSocket(tcp::socket&& socket) : Socket(std::move(socket)),
_type(CONNECTION_TYPE_REALM), _key(0), _OverSpeedPings(0),
- _worldSession(nullptr), _authed(false), _sendBufferSize(4096), _compressionStream(nullptr)
+ _worldSession(nullptr), _authed(false), _canRequestHotfixes(true), _sendBufferSize(4096), _compressionStream(nullptr)
{
Trinity::Crypto::GetRandomBytes(_serverChallenge);
_encryptKey.fill(0);
- _headerBuffer.Resize(sizeof(PacketHeader));
+ _headerBuffer.Resize(sizeof(IncomingPacketHeader));
}
WorldSocket::~WorldSocket()
@@ -324,18 +324,26 @@ void WorldSocket::SetWorldSession(WorldSession* session)
bool WorldSocket::ReadHeaderHandler()
{
- ASSERT(_headerBuffer.GetActiveSize() == sizeof(PacketHeader), "Header size " SZFMTD " different than expected " SZFMTD, _headerBuffer.GetActiveSize(), sizeof(PacketHeader));
+ ASSERT(_headerBuffer.GetActiveSize() == sizeof(IncomingPacketHeader), "Header size " SZFMTD " different than expected " SZFMTD, _headerBuffer.GetActiveSize(), sizeof(IncomingPacketHeader));
- PacketHeader* header = reinterpret_cast<PacketHeader*>(_headerBuffer.GetReadPointer());
+ IncomingPacketHeader* header = reinterpret_cast<IncomingPacketHeader*>(_headerBuffer.GetReadPointer());
+ uint16 encryptedOpcode = header->EncryptedOpcode;
if (!header->IsValidSize())
{
- TC_LOG_ERROR("network", "WorldSocket::ReadHeaderHandler(): client %s sent malformed packet (size: %u)",
- GetRemoteIpAddress().to_string().c_str(), header->Size);
- return false;
+ _authCrypt.PeekDecryptRecv(reinterpret_cast<uint8*>(&header->EncryptedOpcode), sizeof(encryptedOpcode));
+
+ // CMSG_HOTFIX_REQUEST can be much larger than normal packets, allow receiving it once per session
+ if (header->EncryptedOpcode != CMSG_HOTFIX_REQUEST || header->Size > 0x100000 || !_canRequestHotfixes)
+ {
+ TC_LOG_ERROR("network", "WorldSocket::ReadHeaderHandler(): client %s sent malformed packet (size: %u, opcode %u)",
+ GetRemoteIpAddress().to_string().c_str(), header->Size, uint32(header->EncryptedOpcode));
+ return false;
+ }
}
_packetBuffer.Resize(header->Size);
+ _packetBuffer.Write(&encryptedOpcode, sizeof(encryptedOpcode));
return true;
}
@@ -453,6 +461,9 @@ WorldSocket::ReadDataHandlerResult WorldSocket::ReadDataHandler()
LogOpcodeText(opcode, sessionGuard);
HandleEnterEncryptedModeAck();
break;
+ case CMSG_HOTFIX_REQUEST:
+ _canRequestHotfixes = false;
+ /* fallthrough */
default:
{
sessionGuard.lock();
diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h
index da7890d4b07..5327db10ed6 100644
--- a/src/server/game/Server/WorldSocket.h
+++ b/src/server/game/Server/WorldSocket.h
@@ -57,7 +57,12 @@ struct PacketHeader
uint32 Size;
uint8 Tag[12];
- bool IsValidSize() { return Size < 0x40000; }
+ bool IsValidSize() { return Size < 0x10000; }
+};
+
+struct IncomingPacketHeader : PacketHeader
+{
+ uint16 EncryptedOpcode;
};
#pragma pack(pop)
@@ -142,6 +147,7 @@ private:
std::mutex _worldSessionLock;
WorldSession* _worldSession;
bool _authed;
+ bool _canRequestHotfixes;
MessageBuffer _headerBuffer;
MessageBuffer _packetBuffer;