Skip to content

Commit 13f1873

Browse files
committed
Core/Authserver: Refactor auth cmd handler table to avoid msvc compiler bug that initializes half of it to garbage as of version 19.44.35211
1 parent 9ffc854 commit 13f1873

File tree

2 files changed

+76
-65
lines changed

2 files changed

+76
-65
lines changed

src/server/authserver/Server/AuthSession.cpp

Lines changed: 70 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,6 @@ enum eAuthCmd : uint8
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-
5852
#pragma pack(push, 1)
5953

6054
typedef struct AUTH_LOGON_CHALLENGE_C
@@ -126,50 +120,56 @@ std::array<uint8, 16> VersionChallenge = { { 0xBA, 0xA3, 0x1E, 0x99, 0xA0, 0x0B,
126120
#define AUTH_LOGON_CHALLENGE_INITIAL_SIZE 4
127121
#define REALM_LIST_PACKET_SIZE 5
128122

129-
consteval std::array<AuthHandler, 10> AuthSession::InitHandlers()
123+
struct AuthHandler
130124
{
131-
std::array<AuthHandler, 10> handlers = { };
125+
eAuthCmd cmd = { };
126+
AuthStatus status = STATUS_CLOSED;
127+
size_t packetSize = 0;
128+
bool (*handler)(AuthSession*) = nullptr;
129+
};
132130

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)] =
131+
class AuthHandlerTable
132+
{
133+
public:
134+
consteval AuthHandlerTable()
148135
{
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)] =
136+
InitializeHandler(AUTH_LOGON_CHALLENGE, STATUS_CHALLENGE, AUTH_LOGON_CHALLENGE_INITIAL_SIZE, [](AuthSession* session) { return session->HandleLogonChallenge(); });
137+
InitializeHandler(AUTH_LOGON_PROOF, STATUS_LOGON_PROOF, sizeof(AUTH_LOGON_PROOF_C), [](AuthSession* session) { return session->HandleLogonProof(); });
138+
InitializeHandler(AUTH_RECONNECT_CHALLENGE, STATUS_CHALLENGE, AUTH_LOGON_CHALLENGE_INITIAL_SIZE, [](AuthSession* session) { return session->HandleReconnectChallenge(); });
139+
InitializeHandler(AUTH_RECONNECT_PROOF, STATUS_RECONNECT_PROOF, sizeof(AUTH_RECONNECT_PROOF_C), [](AuthSession* session) { return session->HandleReconnectProof(); });
140+
InitializeHandler(REALM_LIST, STATUS_AUTHED, REALM_LIST_PACKET_SIZE, [](AuthSession* session) { return session->HandleRealmList(); });
141+
InitializeHandler(XFER_ACCEPT, STATUS_XFER, 1, [](AuthSession* session) { return session->HandleXferAccept(); });
142+
InitializeHandler(XFER_RESUME, STATUS_XFER, 9, [](AuthSession* session) { return session->HandleXferResume(); });
143+
InitializeHandler(XFER_CANCEL, STATUS_XFER, 1, [](AuthSession* session) { return session->HandleXferCancel(); });
144+
}
145+
146+
constexpr AuthHandler const* operator[](eAuthCmd cmd) const
155147
{
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)] =
148+
std::size_t index = GetOpcodeArrayIndex(cmd);
149+
if (index >= _handlers.size())
150+
return nullptr;
151+
152+
AuthHandler const& handler = _handlers[index];
153+
if (handler.cmd != cmd)
154+
return nullptr;
155+
156+
return &handler;
157+
}
158+
159+
private:
160+
// perfect hash function for all valid values of eAuthCmd
161+
inline static constexpr std::size_t GetOpcodeArrayIndex(eAuthCmd c)
162162
{
163-
.cmd = REALM_LIST,
164-
.status = STATUS_AUTHED,
165-
.packetSize = REALM_LIST_PACKET_SIZE,
166-
.handler = &AuthSession::HandleRealmList
167-
};
163+
return (c & 0x7) + ((c & 0x10) >> 2) + ((c & 0x20) >> 5);
164+
}
168165

169-
return handlers;
170-
}
166+
constexpr void InitializeHandler(eAuthCmd cmd, AuthStatus status, std::size_t packetSize, bool (*handler)(AuthSession*))
167+
{
168+
_handlers[GetOpcodeArrayIndex(cmd)] = { .cmd = cmd, .status = status, .packetSize = packetSize, .handler = handler, };
169+
}
171170

172-
constexpr std::array<AuthHandler, 10> Handlers = AuthSession::InitHandlers();
171+
std::array<AuthHandler, 10> _handlers;
172+
} inline constexpr Handlers;
173173

174174
void AccountInfo::LoadResult(Field* fields)
175175
{
@@ -253,16 +253,8 @@ void AuthSession::ReadHandler()
253253
while (packet.GetActiveSize())
254254
{
255255
eAuthCmd cmd = eAuthCmd(packet.GetReadPointer()[0]);
256-
std::size_t index = GetOpcodeArrayIndex(cmd);
257-
if (index >= Handlers.size() || Handlers[index].cmd != cmd)
258-
{
259-
// well we dont handle this, lets just ignore it
260-
packet.Reset();
261-
break;
262-
}
263-
264-
AuthHandler const* itr = &Handlers[index];
265-
if (_status != itr->status)
256+
AuthHandler const* itr = Handlers[cmd];
257+
if (!itr || _status != itr->status)
266258
{
267259
CloseSocket();
268260
return;
@@ -286,7 +278,7 @@ void AuthSession::ReadHandler()
286278
if (packet.GetActiveSize() < size)
287279
break;
288280

289-
if (!(this->*itr->handler)())
281+
if (!itr->handler(this))
290282
{
291283
CloseSocket();
292284
return;
@@ -870,6 +862,30 @@ void AuthSession::RealmListCallback(PreparedQueryResult result)
870862
_status = STATUS_AUTHED;
871863
}
872864

865+
bool AuthSession::HandleXferAccept()
866+
{
867+
TC_LOG_DEBUG("server.authserver", "Entering _HandleXferAccept");
868+
869+
// empty handler meant to close the connection if received
870+
return false;
871+
}
872+
873+
bool AuthSession::HandleXferResume()
874+
{
875+
TC_LOG_DEBUG("server.authserver", "Entering _HandleXferResume");
876+
877+
// empty handler meant to close the connection if received
878+
return false;
879+
}
880+
881+
bool AuthSession::HandleXferCancel()
882+
{
883+
TC_LOG_DEBUG("server.authserver", "Entering _HandleXferCancel");
884+
885+
// empty handler meant to close the connection if received
886+
return false;
887+
}
888+
873889
bool AuthSession::VerifyVersion(uint8 const* a, int32 aLength, Trinity::Crypto::SHA1::Digest const& versionProof, bool isReconnect)
874890
{
875891
if (!sConfigMgr->GetBoolDefault("StrictVersionCheck", false))

src/server/authserver/Server/AuthSession.h

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030

3131
using boost::asio::ip::tcp;
3232

33+
class AuthHandlerTable;
3334
class ByteBuffer;
34-
struct AuthHandler;
3535
enum eAuthCmd : uint8;
3636

3737
enum AuthStatus
@@ -41,6 +41,7 @@ enum AuthStatus
4141
STATUS_RECONNECT_PROOF,
4242
STATUS_AUTHED,
4343
STATUS_WAITING_FOR_REALM_LIST,
44+
STATUS_XFER,
4445
STATUS_CLOSED
4546
};
4647

@@ -64,8 +65,6 @@ class AuthSession : public Socket<AuthSession>
6465
typedef Socket<AuthSession> AuthSocket;
6566

6667
public:
67-
static consteval std::array<AuthHandler, 10> InitHandlers();
68-
6968
AuthSession(tcp::socket&& socket);
7069

7170
void Start() override;
@@ -77,11 +76,15 @@ class AuthSession : public Socket<AuthSession>
7776
void ReadHandler() override;
7877

7978
private:
79+
friend AuthHandlerTable;
8080
bool HandleLogonChallenge();
8181
bool HandleLogonProof();
8282
bool HandleReconnectChallenge();
8383
bool HandleReconnectProof();
8484
bool HandleRealmList();
85+
bool HandleXferAccept();
86+
bool HandleXferResume();
87+
bool HandleXferCancel();
8588

8689
void CheckIpCallback(PreparedQueryResult result);
8790
void LogonChallengeCallback(PreparedQueryResult result);
@@ -107,12 +110,4 @@ class AuthSession : public Socket<AuthSession>
107110
QueryCallbackProcessor _queryProcessor;
108111
};
109112

110-
struct AuthHandler
111-
{
112-
eAuthCmd cmd;
113-
AuthStatus status;
114-
size_t packetSize;
115-
bool (AuthSession::*handler)();
116-
};
117-
118113
#endif

0 commit comments

Comments
 (0)