Skip to content

Commit 359258c

Browse files
committed
Core/Authserver: Optimize auth packet handler lookup
1 parent 7760b8e commit 359258c

File tree

2 files changed

+55
-20
lines changed

2 files changed

+55
-20
lines changed

src/server/authserver/Server/AuthSession.cpp

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
using boost::asio::ip::tcp;
3737

38-
enum eAuthCmd
38+
enum eAuthCmd : uint8
3939
{
4040
AUTH_LOGON_CHALLENGE = 0x00,
4141
AUTH_LOGON_PROOF = 0x01,
@@ -49,6 +49,12 @@ enum eAuthCmd
4949
XFER_CANCEL = 0x34
5050
};
5151

52+
// perfect hash function for all valid values of eAuthCmd
53+
inline constexpr std::size_t GetOpcodeArrayIndex(eAuthCmd c)
54+
{
55+
return (c & 0x7) + ((c & 0x10) >> 2) + ((c & 0x20) >> 5);
56+
}
57+
5258
#pragma pack(push, 1)
5359

5460
typedef struct AUTH_LOGON_CHALLENGE_C
@@ -120,20 +126,50 @@ std::array<uint8, 16> VersionChallenge = { { 0xBA, 0xA3, 0x1E, 0x99, 0xA0, 0x0B,
120126
#define AUTH_LOGON_CHALLENGE_INITIAL_SIZE 4
121127
#define REALM_LIST_PACKET_SIZE 5
122128

123-
std::unordered_map<uint8, AuthHandler> AuthSession::InitHandlers()
129+
consteval std::array<AuthHandler, 10> AuthSession::InitHandlers()
124130
{
125-
std::unordered_map<uint8, AuthHandler> handlers;
131+
std::array<AuthHandler, 10> handlers = { };
126132

127-
handlers[AUTH_LOGON_CHALLENGE] = { STATUS_CHALLENGE, AUTH_LOGON_CHALLENGE_INITIAL_SIZE, &AuthSession::HandleLogonChallenge };
128-
handlers[AUTH_LOGON_PROOF] = { STATUS_LOGON_PROOF, sizeof(AUTH_LOGON_PROOF_C), &AuthSession::HandleLogonProof };
129-
handlers[AUTH_RECONNECT_CHALLENGE] = { STATUS_CHALLENGE, AUTH_LOGON_CHALLENGE_INITIAL_SIZE, &AuthSession::HandleReconnectChallenge };
130-
handlers[AUTH_RECONNECT_PROOF] = { STATUS_RECONNECT_PROOF, sizeof(AUTH_RECONNECT_PROOF_C), &AuthSession::HandleReconnectProof };
131-
handlers[REALM_LIST] = { STATUS_AUTHED, REALM_LIST_PACKET_SIZE, &AuthSession::HandleRealmList };
133+
handlers[GetOpcodeArrayIndex(AUTH_LOGON_CHALLENGE)] =
134+
{
135+
.cmd = AUTH_LOGON_CHALLENGE,
136+
.status = STATUS_CHALLENGE,
137+
.packetSize = AUTH_LOGON_CHALLENGE_INITIAL_SIZE,
138+
.handler = &AuthSession::HandleLogonChallenge
139+
};
140+
handlers[GetOpcodeArrayIndex(AUTH_LOGON_PROOF)] =
141+
{
142+
.cmd = AUTH_LOGON_PROOF,
143+
.status = STATUS_LOGON_PROOF,
144+
.packetSize = sizeof(AUTH_LOGON_PROOF_C),
145+
.handler = &AuthSession::HandleLogonProof
146+
};
147+
handlers[GetOpcodeArrayIndex(AUTH_RECONNECT_CHALLENGE)] =
148+
{
149+
.cmd = AUTH_RECONNECT_CHALLENGE,
150+
.status = STATUS_CHALLENGE,
151+
.packetSize = AUTH_LOGON_CHALLENGE_INITIAL_SIZE,
152+
.handler = &AuthSession::HandleReconnectChallenge
153+
};
154+
handlers[GetOpcodeArrayIndex(AUTH_RECONNECT_PROOF)] =
155+
{
156+
.cmd = AUTH_RECONNECT_PROOF,
157+
.status = STATUS_RECONNECT_PROOF,
158+
.packetSize = sizeof(AUTH_RECONNECT_PROOF_C),
159+
.handler = &AuthSession::HandleReconnectProof
160+
};
161+
handlers[GetOpcodeArrayIndex(REALM_LIST)] =
162+
{
163+
.cmd = REALM_LIST,
164+
.status = STATUS_AUTHED,
165+
.packetSize = REALM_LIST_PACKET_SIZE,
166+
.handler = &AuthSession::HandleRealmList
167+
};
132168

133169
return handlers;
134170
}
135171

136-
std::unordered_map<uint8, AuthHandler> const Handlers = AuthSession::InitHandlers();
172+
constexpr std::array<AuthHandler, 10> Handlers = AuthSession::InitHandlers();
137173

138174
void AccountInfo::LoadResult(Field* fields)
139175
{
@@ -216,22 +252,23 @@ void AuthSession::ReadHandler()
216252
MessageBuffer& packet = GetReadBuffer();
217253
while (packet.GetActiveSize())
218254
{
219-
uint8 cmd = packet.GetReadPointer()[0];
220-
auto itr = Handlers.find(cmd);
221-
if (itr == Handlers.end())
255+
eAuthCmd cmd = eAuthCmd(packet.GetReadPointer()[0]);
256+
std::size_t index = GetOpcodeArrayIndex(cmd);
257+
if (index >= Handlers.size() || Handlers[index].cmd != cmd)
222258
{
223259
// well we dont handle this, lets just ignore it
224260
packet.Reset();
225261
break;
226262
}
227263

228-
if (_status != itr->second.status)
264+
AuthHandler const* itr = &Handlers[index];
265+
if (_status != itr->status)
229266
{
230267
CloseSocket();
231268
return;
232269
}
233270

234-
uint16 size = uint16(itr->second.packetSize);
271+
std::size_t size = itr->packetSize;
235272
if (packet.GetActiveSize() < size)
236273
break;
237274

@@ -249,7 +286,7 @@ void AuthSession::ReadHandler()
249286
if (packet.GetActiveSize() < size)
250287
break;
251288

252-
if (!(*this.*itr->second.handler)())
289+
if (!(this->*itr->handler)())
253290
{
254291
CloseSocket();
255292
return;

src/server/authserver/Server/AuthSession.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ using boost::asio::ip::tcp;
3232

3333
class ByteBuffer;
3434
struct AuthHandler;
35+
enum eAuthCmd : uint8;
3536

3637
enum AuthStatus
3738
{
@@ -63,7 +64,7 @@ class AuthSession : public Socket<AuthSession>
6364
typedef Socket<AuthSession> AuthSocket;
6465

6566
public:
66-
static std::unordered_map<uint8, AuthHandler> InitHandlers();
67+
static consteval std::array<AuthHandler, 10> InitHandlers();
6768

6869
AuthSession(tcp::socket&& socket);
6970

@@ -106,15 +107,12 @@ class AuthSession : public Socket<AuthSession>
106107
QueryCallbackProcessor _queryProcessor;
107108
};
108109

109-
#pragma pack(push, 1)
110-
111110
struct AuthHandler
112111
{
112+
eAuthCmd cmd;
113113
AuthStatus status;
114114
size_t packetSize;
115115
bool (AuthSession::*handler)();
116116
};
117117

118-
#pragma pack(pop)
119-
120118
#endif

0 commit comments

Comments
 (0)