Ejemplo n.º 1
0
INT4 COfRecvWorker::procRecvBuffer(INT4 sockfd, INT1* buffer, UINT4 len, CSmartPtr<CLoopBuffer>& recvBuffer)
{
    struct ofp_header* header = NULL;
    const UINT4 headerLen = sizeof(struct ofp_header);
    UINT2 lenTotal = 0;
    INT1* pdata = NULL, *pmsg = NULL;
    CMsg* ofmsg = NULL;
    CMsgTree& msgTree = CControl::getInstance()->getMsgTree();
    
    while (len >= headerLen)
    {
        header = (struct ofp_header*)buffer;
        lenTotal = ntohs(header->length);
        if (lenTotal < headerLen)
        {
            LOG_WARN_FMT("%s drop packet when invalid ofp_header.length %u !!!", toString(), lenTotal);
            return BNC_ERR;
        }
        if (len < lenTotal)
            break;

        procStats();

        pdata = (INT1*)m_memPool.alloc(lenTotal);
        if (NULL == pdata)
        {
            LOG_ERROR_FMT("alloc %u bytes failed!", lenTotal);
            return BNC_ERR;
        }
        memcpy(pdata, buffer, lenTotal);

        pmsg = (INT1*)m_memPool.alloc(sizeof(CMsg));
        if (NULL == pmsg)
        {
            LOG_ERROR_FMT("alloc CMsg failed !");
            m_memPool.release(pdata);
            return BNC_ERR;
        }
        ofmsg = new(pmsg) CMsg(sockfd, header->version, header->type, pdata, lenTotal);

        ofmsg->setPath();
        ofmsg->setKey();

        CSmartPtr<CMsgCommon> msg(ofmsg, deleteCmsg);
        if (msgTree.pushMsg(msg) != BNC_OK)
        {
            LOG_INFO_FMT("push msg[%s]key[%s] from sockfd[%d] into tree failed", 
                ofmsg->getPath().c_str(), ofmsg->getKey().c_str(), sockfd);
        }

        buffer += lenTotal;
        len -= lenTotal;
    }
    
    if (len > 0)
        recvBuffer->write(buffer, len);

    return BNC_OK;
}
Ejemplo n.º 2
0
INT4 COfRecvWorker::process(INT4 sockfd, INT1* buffer, UINT4 len)
{
    CSmartPtr<CLoopBuffer>& recvBuffer = m_recvBuffer[sockfd];
    if (recvBuffer.isNull())
    {
        LOG_WARN_FMT("m_recvBuffer[%d] is null !", sockfd);
        return BNC_ERR;
    }

    UINT4 recvBufLen = recvBuffer->length();
    if (0 == recvBufLen)
    {
        return procRecvBuffer(sockfd, buffer, len, recvBuffer);
    }
    else
    {
        if (recvBufLen + len < sizeof(struct ofp_header))
        {
            recvBuffer->write(buffer, len);
            return BNC_OK;
        }

        struct ofp_header header = {0};
        INT1* ptr = (INT1*)&header;
        if (recvBufLen < sizeof(struct ofp_header))
        {
            recvBuffer->read(ptr, recvBufLen, TRUE);
            memcpy(ptr+recvBufLen, buffer, sizeof(struct ofp_header)-recvBufLen);
        }
        else
        {
            recvBuffer->read(ptr, sizeof(struct ofp_header), TRUE);
        }
        UINT2 lenTotal = ntohs(header.length);

        if (recvBufLen + len < lenTotal)
        {
            recvBuffer->write(buffer, len);
        }
        else
        {
            procStats();

            INT1* pdata = (INT1*)m_memPool.alloc(lenTotal);
            if (NULL == pdata)
            {
                LOG_ERROR_FMT("alloc %u bytes failed!", lenTotal);
                return BNC_ERR;
            }
            recvBuffer->read(pdata, recvBufLen);
            memcpy(pdata+recvBufLen, buffer, lenTotal-recvBufLen);

            INT1* pmsg = (INT1*)m_memPool.alloc(sizeof(CMsg));
            if (NULL == pmsg)
            {
                LOG_ERROR_FMT("alloc CMsg failed !");
                m_memPool.release(pdata);
                return BNC_ERR;
            }
            CMsg* ofmsg = new(pmsg) CMsg(sockfd, header.version, header.type, pdata, lenTotal);

            ofmsg->setPath();
            ofmsg->setKey();

            CSmartPtr<CMsgCommon> msg(ofmsg, deleteCmsg);
            if (CControl::getInstance()->getMsgTree().pushMsg(msg) != BNC_OK)
            {
                LOG_INFO_FMT("push msg[%s]key[%s] from sockfd[%d] into tree failed", 
                    ofmsg->getPath().c_str(), ofmsg->getKey().c_str(), sockfd);
            }

            INT1* bufLeft = buffer + (lenTotal - recvBufLen);
            UINT4 lenLeft = len - (lenTotal - recvBufLen);
            if (lenLeft > 0)
                return procRecvBuffer(sockfd, bufLeft, lenLeft, recvBuffer);
        }    
    }

    return BNC_OK;
}