Example #1
0
void WorldSocket::ProcessIncomingPacket(WorldPacket *recvPacket)
{
    uint16 msgCode = recvPacket->getMsgCode();

    switch (msgCode)
    {
        case MSG_CONNECTION:
        {
            HandleConnection(*recvPacket);
            break;
        }
        case MSG_PING:
        {
            HandlePing(*recvPacket);
            break;
        }
        case CMSG_AUTH_SESSION:
        {
            if (m_pSession)
            {
                cout << "Client try to auth again!" << endl;
                return;
            }
            HandleAuthSession(*recvPacket);
            break;
        }
        default:
        {
            if (m_pSession)
            {
                const MsgCodeHandler msghandler = msgCodeTable[msgCode];

                (m_pSession->*msghandler.handler)(*recvPacket);
            }
            else
                cout << "ERROR: Client not authed! Remote Host: " << getRemoteHost() << ", MsgCode: "<< msgCode << "(" << LookupMsgCodeName(msgCode) << ")" << endl;
        }
    }

    SAFE_DELETE(recvPacket);
}
Example #2
0
bool WorldSocket::ProcessIncomingData()
{
    ClientPktHeader header;

    if (m_useExistingHeader)
    {
        m_useExistingHeader = false;
        header = m_existingHeader;

        ReadSkip(sizeof(ClientPktHeader));
    }
    else
    {
        if (!Read((char *)&header, sizeof(ClientPktHeader)))
        {
            errno = EBADMSG;
            return false;
        }

        m_crypt.DecryptRecv((uint8 *)&header, sizeof(ClientPktHeader));

        EndianConvertReverse(header.size);
        EndianConvert(header.cmd);
    }

    // there must always be at least four bytes for the opcode,
    // and 0x2800 is the largest supported buffer in the client
    if ((header.size < 4) || (header.size > 0x2800) || (header.cmd >= NUM_MSG_TYPES))
    {
        sLog.outError("WorldSocket::ProcessIncomingData: client sent malformed packet size = %u , cmd = %u", header.size, header.cmd);
    
        errno = EINVAL;
        return false;
    }

    // the minus four is because we've already read the four byte opcode value
    const uint16 validBytesRemaining = header.size - 4;

    // check if the client has told us that there is more data than there is
    if (validBytesRemaining > ReadLengthRemaining())
    {
        // we must preserve the decrypted header so as not to corrupt the crypto state, and to prevent duplicating work
        m_useExistingHeader = true;
        m_existingHeader = header;

        // we move the read pointer backward because it will be skipped again later.  this is a slight kludge, but to solve
        // it more elegantly would require introducing protocol awareness into the socket library, which we want to avoid
        ReadSkip(-static_cast<int>(sizeof(ClientPktHeader)));

        errno = EBADMSG;
        return false;
    }

    Opcodes x;
    const OpcodesList opcode = static_cast<OpcodesList>(header.cmd);

    if (IsClosed())
        return false;

    std::unique_ptr<WorldPacket> pct(new WorldPacket(opcode, validBytesRemaining));

    if (validBytesRemaining)
    {
        pct->append(InPeak(), validBytesRemaining);
        ReadSkip(validBytesRemaining);
    }

    sLog.outWorldPacketDump(GetRemoteEndpoint().c_str(), pct->GetOpcode(), pct->GetOpcodeName(), *pct, true);

    try
    {
        switch (opcode)
        {
            case CMSG_AUTH_SESSION:
                if (m_session)
                {
                    sLog.outError("WorldSocket::ProcessIncomingData: Player send CMSG_AUTH_SESSION again");
                    return false;
                }

                return HandleAuthSession(*pct);

            case CMSG_PING:
                return HandlePing(*pct);

            case CMSG_KEEP_ALIVE:
                DEBUG_LOG("CMSG_KEEP_ALIVE ,size: " SIZEFMTD " ", pct->size());

                return true;

            default:
            {
                if (!m_session)
                {
                    sLog.outError("WorldSocket::ProcessIncomingData: Client not authed opcode = %u", uint32(opcode));
                    return false;
                }

                m_session->QueuePacket(std::move(pct));

                return true;
            }
        }
    }
    catch (ByteBufferException&)
    {
        sLog.outError("WorldSocket::ProcessIncomingData ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i.",
                      opcode, GetRemoteAddress().c_str(), m_session ? m_session->GetAccountId() : -1);

        if (sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
        {
            DEBUG_LOG("Dumping error-causing packet:");
            pct->hexlike();
        }

        if (sWorld.getConfig(CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET))
        {
            DETAIL_LOG("Disconnecting session [account id %i / address %s] for badly formatted packet.",
                       m_session ? m_session->GetAccountId() : -1, GetRemoteAddress().c_str());
            return false;
        }
    }

    return true;
}
Example #3
0
int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
{
    MANGOS_ASSERT(new_pct);

    // manage memory ;)
    ACE_Auto_Ptr<WorldPacket> aptr(new_pct);

    const ACE_UINT16 opcode = new_pct->GetOpcode();

    if (opcode >= NUM_MSG_TYPES)
    {
        sLog.outError("SESSION: received nonexistent opcode 0x%.4X", opcode);
        return -1;
    }

    if (closing_)
        { return -1; }

    // Dump received packet.
    sLog.outWorldPacketDump(uint32(get_handle()), new_pct->GetOpcode(), new_pct->GetOpcodeName(), new_pct, true);

    try
    {
        switch (opcode)
        {
            case CMSG_PING:
                return HandlePing(*new_pct);
            case CMSG_AUTH_SESSION:
                if (m_Session)
                {
                    sLog.outError("WorldSocket::ProcessIncoming: Player send CMSG_AUTH_SESSION again");
                    return -1;
                }

                if (!sEluna->OnPacketReceive(m_Session, *new_pct))
                    return 0;
                return HandleAuthSession(*new_pct);
            case CMSG_KEEP_ALIVE:
                DEBUG_LOG("CMSG_KEEP_ALIVE ,size: " SIZEFMTD " ", new_pct->size());

                sEluna->OnPacketReceive(m_Session, *new_pct);
                return 0;
            default:
            {
                ACE_GUARD_RETURN(LockType, Guard, m_SessionLock, -1);

                if (m_Session != NULL)
                {
                    // OK ,give the packet to WorldSession
                    aptr.release();
                    // WARNING here we call it with locks held.
                    // Its possible to cause deadlock if QueuePacket calls back
                    m_Session->QueuePacket(new_pct);
                    return 0;
                }
                else
                {
                    sLog.outError("WorldSocket::ProcessIncoming: Client not authed opcode = %u", uint32(opcode));
                    return -1;
                }
            }
        }
    }
    catch (ByteBufferException&)
    {
        sLog.outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i.",
                      opcode, GetRemoteAddress().c_str(), m_Session ? m_Session->GetAccountId() : -1);
        if (sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
        {
            DEBUG_LOG("Dumping error-causing packet:");
            new_pct->hexlike();
        }

        if (sWorld.getConfig(CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET))
        {
            DETAIL_LOG("Disconnecting session [account id %i / address %s] for badly formatted packet.",
                       m_Session ? m_Session->GetAccountId() : -1, GetRemoteAddress().c_str());

            return -1;
        }
        else
            { return 0; }
    }

    ACE_NOTREACHED(return 0);
}
Example #4
0
int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
{
    ACE_ASSERT (new_pct);

    // manage memory ;)
    ACE_Auto_Ptr<WorldPacket> aptr (new_pct);

    const ACE_UINT16 opcode = new_pct->GetOpcode();

    if (closing_)
        return -1;

    // Dump received packet.
    if (sWorldLog.LogWorld())
    {
        sWorldLog.outTimestampLog ("CLIENT:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
                                   (uint32) get_handle(),
                                   new_pct->size(),
                                   LookupOpcodeName (new_pct->GetOpcode()),
                                   new_pct->GetOpcode());

        uint32 p = 0;
        while (p < new_pct->size())
        {
            for (uint32 j = 0; j < 16 && p < new_pct->size(); j++)
                sWorldLog.outLog ("%.2X ", (*new_pct)[p++]);

            sWorldLog.outLog ("\n");
        }
        sWorldLog.outLog ("\n");
    }

    try
    {
        switch(opcode)
        {
        case CMSG_PING:
            return HandlePing (*new_pct);
        case CMSG_AUTH_SESSION:
            if (m_Session)
            {
                sLog.outError ("WorldSocket::ProcessIncoming: Player send CMSG_AUTH_SESSION again");
                return -1;
            }

            return HandleAuthSession (*new_pct);
        case CMSG_KEEP_ALIVE:
            DEBUG_LOG ("CMSG_KEEP_ALIVE ,size: %d", new_pct->size());

            return 0;
        default:
        {
            ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);

            if (m_Session != NULL)
            {
                // Our Idle timer will reset on any non PING opcodes.
                // Catches people idling on the login screen and any lingering ingame connections.
                m_Session->ResetTimeOutTime();

                // OK ,give the packet to WorldSession
                aptr.release();
                // WARNINIG here we call it with locks held.
                // Its possible to cause deadlock if QueuePacket calls back
                m_Session->QueuePacket (new_pct);
                return 0;
            }
            else
            {
                sLog.outError ("WorldSocket::ProcessIncoming: Client not authed opcode = %u", uint32(opcode));
                return -1;
            }
        }
        }
    }
    catch(ByteBufferException &)
    {
        sLog.outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i. Disconnected client.",
                      opcode, GetRemoteAddress().c_str(), m_Session?m_Session->GetAccountId():-1);
        if (sLog.IsOutDebug())
        {
            sLog.outDebug("Dumping error causing packet:");
            new_pct->hexlike();
        }

        return -1;
    }

    ACE_NOTREACHED (return 0);
}
Example #5
0
int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
{
    ACE_ASSERT (new_pct);

    // manage memory ;)
    ACE_Auto_Ptr<WorldPacket> aptr (new_pct);

    const ACE_UINT16 opcode = new_pct->GetOpcode ();

    if (closing_)
        return -1;

    // Dump received packet.
    if (sWorldLog.LogWorld ())
    {
        sWorldLog.Log ("CLIENT:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
                     (uint32) get_handle (),
                     new_pct->size (),
                     LookupOpcodeName (new_pct->GetOpcode ()),
                     new_pct->GetOpcode ());

        uint32 p = 0;
        while (p < new_pct->size ())
        {
            for (uint32 j = 0; j < 16 && p < new_pct->size (); j++)
                sWorldLog.Log ("%.2X ", (*new_pct)[p++]);
            sWorldLog.Log ("\n");
        }
        sWorldLog.Log ("\n\n");
    }

    // like one switch ;)
    if (opcode == CMSG_PING)
    {
        return HandlePing (*new_pct);
    }
    else if (opcode == CMSG_AUTH_SESSION)
    {
        if (m_Session)
        {
            sLog.outError ("WorldSocket::ProcessIncoming: Player send CMSG_AUTH_SESSION again");
            return -1;
        }

        return HandleAuthSession (*new_pct);
    }
    else if (opcode == CMSG_KEEP_ALIVE)
    {
        DEBUG_LOG ("CMSG_KEEP_ALIVE ,size: %d", new_pct->size ());

        return 0;
    }
    else
    {
        ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);

        if (m_Session != NULL)
        {
            // OK ,give the packet to WorldSession
            aptr.release ();
            // WARNINIG here we call it with locks held.
            // Its possible to cause deadlock if QueuePacket calls back
            m_Session->QueuePacket (new_pct);
            return 0;
        }
        else
        {
            sLog.outError ("WorldSocket::ProcessIncoming: Client not authed opcode = ", opcode);
            return -1;
        }
    }

    ACE_NOTREACHED (return 0);
}
Example #6
0
int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
{
    ACE_ASSERT (new_pct);

    // manage memory ;)
    ACE_Auto_Ptr<WorldPacket> aptr (new_pct);

    const ACE_UINT16 opcode = new_pct->GetOpcode ();

    if (opcode >= NUM_MSG_TYPES)
    {
        sLog.outError( "SESSION: received non-existed opcode 0x%.4X", opcode);
        return -1;
    }

    if (closing_)
        return -1;

    // Dump received packet.
    sLog.outWorldPacketDump(uint32(get_handle()), new_pct->GetOpcode(), LookupOpcodeName(new_pct->GetOpcode()), new_pct, true);

    try
    {
        switch(opcode)
        {
            case CMSG_PING:
                return HandlePing (*new_pct);
            case CMSG_AUTH_SESSION:
                if (m_Session)
                {
                    sLog.outError ("WorldSocket::ProcessIncoming: Player send CMSG_AUTH_SESSION again");
                    return -1;
                }

                return HandleAuthSession (*new_pct);
            case CMSG_KEEP_ALIVE:
                DEBUG_LOG ("CMSG_KEEP_ALIVE ,size: %d", new_pct->size ());

                return 0;
            default:
            {
                ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);

                if (m_Session != NULL)
                {
                    // OK ,give the packet to WorldSession
                    aptr.release ();
                    // WARNINIG here we call it with locks held.
                    // Its possible to cause deadlock if QueuePacket calls back
                    m_Session->QueuePacket (new_pct);
                    return 0;
                }
                else
                {
                    sLog.outError ("WorldSocket::ProcessIncoming: Client not authed opcode = %u", uint32(opcode));
                    return -1;
                }
            }
        }
    }
    catch (ByteBufferException &)
    {
        sLog.outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i. Disconnected client.",
                opcode, GetRemoteAddress().c_str(), m_Session?m_Session->GetAccountId():-1);
        if(sLog.IsOutDebug())
        {
            sLog.outDebug("Dumping error-causing packet:");
            new_pct->hexlike();
        }

        return -1;
    }

    ACE_NOTREACHED (return 0);
}
Example #7
0
bool WorldSocket::ProcessPacket(WorldPacket* new_pct)
{
    MANGOS_ASSERT(new_pct);

    // manage memory ;)
    std::auto_ptr<WorldPacket> aptr(new_pct);

    const uint16 opcode = new_pct->GetOpcode();

    if (opcode >= NUM_MSG_TYPES)
    {
        sLog.outError("SESSION: received nonexistent opcode 0x%.4X", opcode);
        return false;
    }

    if (IsClosed())
        return false;

    // Dump received packet.
    sLog.outWorldPacketDump(native_handle(), new_pct->GetOpcode(), new_pct->GetOpcodeName(), new_pct, true);

    try
    {
        switch (opcode)
        {
            case CMSG_PING:
                return HandlePing(*new_pct);
            case CMSG_AUTH_SESSION:
                if (session_)
                {
                    sLog.outError("WorldSocket::ProcessIncoming: Player send CMSG_AUTH_SESSION again");
                    return false;
                }
                return HandleAuthSession(*new_pct);
            case CMSG_KEEP_ALIVE:
                DEBUG_LOG("CMSG_KEEP_ALIVE ,size: " SIZEFMTD " ", new_pct->size());
                return true;
            default:
            {
                GuardType Guard(session_lock_);

                if (session_ != NULL)
                {
                    // OK ,give the packet to WorldSession
                    aptr.release();
                    // WARNING here we call it with locks held.
                    // Its possible to cause deadlock if QueuePacket calls back
                    session_->QueuePacket(new_pct);
                    return true;
                }
                else
                {
                    sLog.outError("WorldSocket::ProcessIncoming: Client not authed opcode = %u", uint32(opcode));
                    return false;
                }
            }
        }
    }
    catch (ByteBufferException&)
    {
        sLog.outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i.",
                      opcode, GetRemoteAddress().c_str(), session_ ? session_->GetAccountId() : -1);

        if (sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
        {
            DEBUG_LOG("Dumping error-causing packet:");
            new_pct->hexlike();
        }

        if (sWorld.getConfig(CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET))
        {
            DETAIL_LOG("Disconnecting session [account id %i / address %s] for badly formatted packet.",
                       session_ ? session_->GetAccountId() : -1, GetRemoteAddress().c_str());
            return false;
        }
    }

    packet_ = nullptr;

    return true;
}
Example #8
0
int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
{
    ACE_ASSERT (new_pct);

    // manage memory ;)
    ACE_Auto_Ptr<WorldPacket> aptr (new_pct);

    const ACE_UINT16 opcode = new_pct->GetOpcode();

    if (closing_)
        return -1;

    // Dump received packet.
    if (sPacketLog->CanLogPacket())
        sPacketLog->LogPacket(*new_pct, CLIENT_TO_SERVER);

    try
    {
        switch (opcode)
        {
            case CMSG_PING:
                return HandlePing (*new_pct);
            case CMSG_AUTH_SESSION:
                if (m_Session)
                {
                    sLog->outError("WorldSocket::ProcessIncoming: Player send CMSG_AUTH_SESSION again");
                    return -1;
                }

                sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct));

                return HandleAuthSession(*new_pct);

            case CMSG_KEEP_ALIVE:
                sLog->outStaticDebug ("CMSG_KEEP_ALIVE, size: " UI64FMTD, uint64(new_pct->size()));
                sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct));
                return 0;
            default:
            {
                ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);

                if (m_Session != NULL)
                {
                    // Our Idle timer will reset on any non PING opcodes.
                    // Catches people idling on the login screen and any lingering ingame connections.
                    m_Session->ResetTimeOutTime();

                    // OK, give the packet to WorldSession
                    aptr.release();
                    // WARNINIG here we call it with locks held.
                    // Its possible to cause deadlock if QueuePacket calls back
                    m_Session->QueuePacket (new_pct);
                    return 0;
                }
                else
                {
                    sLog->outError("WorldSocket::ProcessIncoming: Client not authed opcode = %u", uint32(opcode));
                    return -1;
                }
            }
        }
    }
    catch (ByteBufferException &)
    {
        sLog->outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i. Disconnected client.",
                opcode, GetRemoteAddress().c_str(), m_Session?m_Session->GetAccountId():-1);
        if (sLog->IsOutDebug())
        {
            sLog->outDebug(LOG_FILTER_NETWORKIO, "Dumping error causing packet:");
            new_pct->hexlike();
        }

        return -1;
    }

    ACE_NOTREACHED (return 0);
}
Example #9
0
int PoolSocket::ProcessIncoming (WorldPacket* new_pct)
{
    ACE_ASSERT (new_pct);

    // manage memory ;)
    ACE_Auto_Ptr<WorldPacket> aptr (new_pct);

    const ACE_UINT16 opcode = new_pct->GetOpcode();

    if (closing_)
        return -1;

    // Dump received packet.
    if (sPacketLog->CanLogPacket())
        sPacketLog->LogPacket(*new_pct, CLIENT_TO_SERVER);

    try
    {
        switch (opcode)
        {
            case CMSG_PING:
                return HandlePing (*new_pct);
            case LOGON_AUTH_MASTER:
                if (m_Session)
                {
                    sLog->outError ("PoolSocket::ProcessIncoming: Player send CMSG_AUTH_SESSION again");
                    return -1;
                }
                return HandleAuthSession (*new_pct);
            case CMSG_KEEP_ALIVE:
                sLog->outStaticDebug ("CMSG_KEEP_ALIVE, size: " UI64FMTD, uint64(new_pct->size()));
                return 0;
            default:
            {
                ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);

                if (m_Session != NULL)
                {
                    // OK, give the packet to WorldSession
                    aptr.release();
                    // WARNINIG here we call it with locks held.
                    // Its possible to cause deadlock if QueuePacket calls back
                    m_Session->QueueServerPacket (new_pct);
                    return 0;
                }
                else
                {
                    new_pct->Initialize(SMSG_AUTH_RESPONSE, 1);
                    *new_pct << uint8(AUTH_REJECT);
                    SendPacket(*new_pct);

                    sLog->outError ("PoolSocket::ProcessIncoming: Client not authed opcode = %u => rejected", uint32(opcode));
                    return -1;
                }
            }
        }
    }
    catch (ByteBufferException &)
    {
        sLog->outError("PoolSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i. Disconnected client.",
                opcode, GetRemoteAddress().c_str(), m_Session?m_Session->GetServerId():-1);
        if (sLog->IsOutDebug())
        {
            sLog->outDebug(LOG_FILTER_NETWORKIO, "Dumping error causing packet:");
            new_pct->hexlike();
        }

        return -1;
    }

    ACE_NOTREACHED (return 0);
}