diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index baac87df..3c100121 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -228,13 +228,17 @@ ServerLobbyThread::RemoveSessionFromGame(SessionWrapper session) void ServerLobbyThread::CloseSession(SessionWrapper session) { - LOG_VERBOSE("Closing session #" << session.sessionData->GetId() << "."); + if (session.sessionData && session.sessionData->GetState() != SessionData::Closed) // Make this call reentrant. + { + LOG_VERBOSE("Closing session #" << session.sessionData->GetId() << "."); + session.sessionData->SetState(SessionData::Closed); - m_sessionManager.RemoveSession(session.sessionData->GetId()); - m_gameSessionManager.RemoveSession(session.sessionData->GetId()); + m_sessionManager.RemoveSession(session.sessionData->GetId()); + m_gameSessionManager.RemoveSession(session.sessionData->GetId()); - // Update stats (if needed). - UpdateStatisticsNumberOfPlayers(); + // Update stats (if needed). + UpdateStatisticsNumberOfPlayers(); + } } void @@ -534,6 +538,8 @@ ServerLobbyThread::HandleRead(const boost::system::error_code &ec, SessionId ses if (!ec) { ReceiveBuffer &buf = session.sessionData->GetReceiveBuffer(); + if (buf.recvBufUsed + bytesRead > RECV_BUF_SIZE) + LOG_ERROR("Internal error: Receive buffer overflow!"); buf.recvBufUsed += bytesRead; GetReceiver().ScanPackets(buf); bool errorFlag = false; @@ -561,6 +567,11 @@ ServerLobbyThread::HandleRead(const boost::system::error_code &ec, SessionId ses else HandlePacket(session, packet); } + if (buf.recvBufUsed >= RECV_BUF_SIZE) + { + LOG_ERROR("Session " << session.sessionData->GetId() << " - Full receive buf but no valid packet."); + buf.recvBufUsed = 0; + } if (!errorFlag) { session.sessionData->GetAsioSocket()->async_read_some( @@ -573,7 +584,7 @@ ServerLobbyThread::HandleRead(const boost::system::error_code &ec, SessionId ses boost::asio::placeholders::bytes_transferred)); } } - else + else if (ec != boost::asio::error::operation_aborted) { // On error: Close this session. boost::shared_ptr game = InternalGetGameFromId(session.sessionData->GetGameId()); @@ -583,9 +594,9 @@ ServerLobbyThread::HandleRead(const boost::system::error_code &ec, SessionId ses CloseSession(session); } } - } catch (...) + } catch (const exception &e) { - LOG_ERROR("Session " << sessionId << " - unknown exception in HandleRead."); + LOG_ERROR("Session " << sessionId << " - unhandled exception in HandleRead: " << e.what()); } } diff --git a/src/net/sessiondata.h b/src/net/sessiondata.h index 53f57325..141a6aef 100644 --- a/src/net/sessiondata.h +++ b/src/net/sessiondata.h @@ -39,7 +39,7 @@ typedef unsigned SessionId; class SessionData { public: - enum State { Init, ReceivingAvatar, Established, Game }; + enum State { Init, ReceivingAvatar, Established, Game, Closed }; SessionData(boost::shared_ptr sock, SessionId id, SessionDataCallback &cb); ~SessionData();