Core/Authserver: Optimize auth packet handler lookup

This commit is contained in:
Shauren
2025-07-12 18:55:51 +02:00
parent 7760b8e4ed
commit 359258cb07
2 changed files with 55 additions and 20 deletions

View File

@@ -35,7 +35,7 @@
using boost::asio::ip::tcp;
enum eAuthCmd
enum eAuthCmd : uint8
{
AUTH_LOGON_CHALLENGE = 0x00,
AUTH_LOGON_PROOF = 0x01,
@@ -49,6 +49,12 @@ enum eAuthCmd
XFER_CANCEL = 0x34
};
// perfect hash function for all valid values of eAuthCmd
inline constexpr std::size_t GetOpcodeArrayIndex(eAuthCmd c)
{
return (c & 0x7) + ((c & 0x10) >> 2) + ((c & 0x20) >> 5);
}
#pragma pack(push, 1)
typedef struct AUTH_LOGON_CHALLENGE_C
@@ -120,20 +126,50 @@ std::array<uint8, 16> VersionChallenge = { { 0xBA, 0xA3, 0x1E, 0x99, 0xA0, 0x0B,
#define AUTH_LOGON_CHALLENGE_INITIAL_SIZE 4
#define REALM_LIST_PACKET_SIZE 5
std::unordered_map<uint8, AuthHandler> AuthSession::InitHandlers()
consteval std::array<AuthHandler, 10> AuthSession::InitHandlers()
{
std::unordered_map<uint8, AuthHandler> handlers;
std::array<AuthHandler, 10> handlers = { };
handlers[AUTH_LOGON_CHALLENGE] = { STATUS_CHALLENGE, AUTH_LOGON_CHALLENGE_INITIAL_SIZE, &AuthSession::HandleLogonChallenge };
handlers[AUTH_LOGON_PROOF] = { STATUS_LOGON_PROOF, sizeof(AUTH_LOGON_PROOF_C), &AuthSession::HandleLogonProof };
handlers[AUTH_RECONNECT_CHALLENGE] = { STATUS_CHALLENGE, AUTH_LOGON_CHALLENGE_INITIAL_SIZE, &AuthSession::HandleReconnectChallenge };
handlers[AUTH_RECONNECT_PROOF] = { STATUS_RECONNECT_PROOF, sizeof(AUTH_RECONNECT_PROOF_C), &AuthSession::HandleReconnectProof };
handlers[REALM_LIST] = { STATUS_AUTHED, REALM_LIST_PACKET_SIZE, &AuthSession::HandleRealmList };
handlers[GetOpcodeArrayIndex(AUTH_LOGON_CHALLENGE)] =
{
.cmd = AUTH_LOGON_CHALLENGE,
.status = STATUS_CHALLENGE,
.packetSize = AUTH_LOGON_CHALLENGE_INITIAL_SIZE,
.handler = &AuthSession::HandleLogonChallenge
};
handlers[GetOpcodeArrayIndex(AUTH_LOGON_PROOF)] =
{
.cmd = AUTH_LOGON_PROOF,
.status = STATUS_LOGON_PROOF,
.packetSize = sizeof(AUTH_LOGON_PROOF_C),
.handler = &AuthSession::HandleLogonProof
};
handlers[GetOpcodeArrayIndex(AUTH_RECONNECT_CHALLENGE)] =
{
.cmd = AUTH_RECONNECT_CHALLENGE,
.status = STATUS_CHALLENGE,
.packetSize = AUTH_LOGON_CHALLENGE_INITIAL_SIZE,
.handler = &AuthSession::HandleReconnectChallenge
};
handlers[GetOpcodeArrayIndex(AUTH_RECONNECT_PROOF)] =
{
.cmd = AUTH_RECONNECT_PROOF,
.status = STATUS_RECONNECT_PROOF,
.packetSize = sizeof(AUTH_RECONNECT_PROOF_C),
.handler = &AuthSession::HandleReconnectProof
};
handlers[GetOpcodeArrayIndex(REALM_LIST)] =
{
.cmd = REALM_LIST,
.status = STATUS_AUTHED,
.packetSize = REALM_LIST_PACKET_SIZE,
.handler = &AuthSession::HandleRealmList
};
return handlers;
}
std::unordered_map<uint8, AuthHandler> const Handlers = AuthSession::InitHandlers();
constexpr std::array<AuthHandler, 10> Handlers = AuthSession::InitHandlers();
void AccountInfo::LoadResult(Field* fields)
{
@@ -216,22 +252,23 @@ void AuthSession::ReadHandler()
MessageBuffer& packet = GetReadBuffer();
while (packet.GetActiveSize())
{
uint8 cmd = packet.GetReadPointer()[0];
auto itr = Handlers.find(cmd);
if (itr == Handlers.end())
eAuthCmd cmd = eAuthCmd(packet.GetReadPointer()[0]);
std::size_t index = GetOpcodeArrayIndex(cmd);
if (index >= Handlers.size() || Handlers[index].cmd != cmd)
{
// well we dont handle this, lets just ignore it
packet.Reset();
break;
}
if (_status != itr->second.status)
AuthHandler const* itr = &Handlers[index];
if (_status != itr->status)
{
CloseSocket();
return;
}
uint16 size = uint16(itr->second.packetSize);
std::size_t size = itr->packetSize;
if (packet.GetActiveSize() < size)
break;
@@ -249,7 +286,7 @@ void AuthSession::ReadHandler()
if (packet.GetActiveSize() < size)
break;
if (!(*this.*itr->second.handler)())
if (!(this->*itr->handler)())
{
CloseSocket();
return;

View File

@@ -32,6 +32,7 @@ using boost::asio::ip::tcp;
class ByteBuffer;
struct AuthHandler;
enum eAuthCmd : uint8;
enum AuthStatus
{
@@ -63,7 +64,7 @@ class AuthSession : public Socket<AuthSession>
typedef Socket<AuthSession> AuthSocket;
public:
static std::unordered_map<uint8, AuthHandler> InitHandlers();
static consteval std::array<AuthHandler, 10> InitHandlers();
AuthSession(tcp::socket&& socket);
@@ -106,15 +107,12 @@ private:
QueryCallbackProcessor _queryProcessor;
};
#pragma pack(push, 1)
struct AuthHandler
{
eAuthCmd cmd;
AuthStatus status;
size_t packetSize;
bool (AuthSession::*handler)();
};
#pragma pack(pop)
#endif