Skip to content

Commit

Permalink
Network: Rework reconnection case to fix slow cpu race conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
killerwife committed Feb 14, 2024
1 parent 98c85db commit 019f160
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 44 deletions.
11 changes: 3 additions & 8 deletions src/game/Server/WorldSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ void WorldSession::SetInCharSelection()

bool WorldSession::RequestNewSocket(WorldSocket* socket)
{
std::lock_guard<std::mutex> guard(m_recvQueueLock);
if (m_requestSocket)
return false;

Expand Down Expand Up @@ -482,6 +481,7 @@ bool WorldSession::Update(uint32 /*diff*/)
{
if (m_requestSocket)
{
std::lock_guard<std::mutex> guard(m_recvQueueLock);
if (!IsOffline())
SetOffline();

Expand Down Expand Up @@ -1282,14 +1282,9 @@ void WorldSession::InitializeAnticheat(const BigNumber& K)
m_anticheat = sAnticheatLib->NewSession(this, K);
}

void WorldSession::AssignAnticheat()
void WorldSession::AssignAnticheat(std::unique_ptr<SessionAnticheatInterface>&& anticheat)
{
m_anticheat = std::move(m_delayedAnticheat);
}

void WorldSession::SetDelayedAnticheat(std::unique_ptr<SessionAnticheatInterface>&& anticheat)
{
m_delayedAnticheat = std::move(anticheat);
m_anticheat = std::move(anticheat);
}

#ifdef BUILD_PLAYERBOT
Expand Down
4 changes: 1 addition & 3 deletions src/game/Server/WorldSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,7 @@ class WorldSession
void SetExpansion(uint8 expansion);

void InitializeAnticheat(const BigNumber& K);
void AssignAnticheat();
void SetDelayedAnticheat(std::unique_ptr<SessionAnticheatInterface>&& anticheat);
void AssignAnticheat(std::unique_ptr<SessionAnticheatInterface>&& anticheat);
SessionAnticheatInterface* GetAnticheat() const { return m_anticheat.get(); }

#ifdef BUILD_PLAYERBOT
Expand Down Expand Up @@ -949,7 +948,6 @@ class WorldSession
uint32 m_accountMaxLevel;
uint32 m_orderCounter;
uint32 m_lastAnticheatUpdate;
std::unique_ptr<SessionAnticheatInterface> m_delayedAnticheat;
std::unique_ptr<SessionAnticheatInterface> m_anticheat;

time_t _logoutTime; // when logout will be processed after a logout request
Expand Down
58 changes: 25 additions & 33 deletions src/game/Server/WorldSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,45 +503,37 @@ bool WorldSocket::HandleAuthSession(WorldPacket& recvPacket)

if (m_session)
{
// Session exist so player is reconnecting
// check if we can request a new socket
if (!m_session->RequestNewSocket(this))
return false;

uint32 counter = 0;
DEBUG_LOG("WorldSocket::HandleAuthSession reconnecting for account '%s' from %s", account.c_str(), address.c_str());

// wait session going to be ready
while (m_session->GetState() != WORLD_SESSION_STATE_CHAR_SELECTION)
// defer operation to session thread context to avoid any race conditions
auto self = shared_from_this();
m_session->GetMessager().AddMessage([self, ClientBuild, clientOS, clientPlatform, account, address = address, K, id, recvPacket = recvPacket](WorldSession* session)
{
++counter;
// just wait
std::this_thread::sleep_for(std::chrono::milliseconds(1));

if (IsClosed() || counter > 20)
return false;
}
// Session exist so player is reconnecting
// check if we can request a new socket
if (!session->RequestNewSocket(self.get()))
return;

m_session->SetGameBuild(ClientBuild);
m_session->SetOS(clientOS);
m_session->SetPlatform(clientPlatform);
DEBUG_LOG("WorldSocket::HandleAuthSession reconnect loading data for account '%s' from %s", account.c_str(), address.c_str());
session->SetGameBuild(ClientBuild);
session->SetOS(clientOS);
session->SetPlatform(clientPlatform);

std::unique_ptr<SessionAnticheatInterface> anticheat = sAnticheatLib->NewSession(m_session, K);
std::unique_ptr<SessionAnticheatInterface> anticheat = sAnticheatLib->NewSession(session, K);

// when false, the client sent invalid addon data. kick!
WorldPacket addonPacket; // yes its copypasted atm cos of reconnect
if (!anticheat->ReadAddonInfo(&recvPacket, addonPacket))
{
sLog.outBasic("WorldSocket::HandleAuthSession: Account %s (id %u) IP %s sent bad addon info. Kicking.",
account.c_str(), id, address.c_str());
return false;
}
else
SendPacket(addonPacket);
// when false, the client sent invalid addon data. kick!
WorldPacket addonPacket; // yes its copypasted atm cos of reconnect
if (!anticheat->ReadAddonInfo(const_cast<WorldPacket*>(&recvPacket), addonPacket))
{
sLog.outBasic("WorldSocket::HandleAuthSession: Account %s (id %u) IP %s sent bad addon info. Kicking.",
account.c_str(), id, address.c_str());
return;
}
else
self->SendPacket(addonPacket);

m_session->SetDelayedAnticheat(std::move(anticheat));
m_session->GetMessager().AddMessage([](WorldSession* session)
{
session->AssignAnticheat();
DEBUG_LOG("WorldSocket::HandleAuthSession assigning anticheat for '%s' from %s", account.c_str(), address.c_str());
session->AssignAnticheat(std::move(anticheat));
});
}
else
Expand Down

0 comments on commit 019f160

Please sign in to comment.