예제 #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;
}
예제 #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;
}
STDMETHODIMP GuestSessionEventListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent)
{
    switch (aType)
    {
    case VBoxEventType_OnGuestFileRegistered:
    {
        HRESULT rc;
        do
        {
            ComPtr<IGuestFileRegisteredEvent> pEvent = aEvent;
            Assert(!pEvent.isNull());

            ComPtr<IGuestFile> pFile;
            CHECK_ERROR_BREAK(pEvent, COMGETTER(File)(pFile.asOutParam()));
            AssertBreak(!pFile.isNull());
            BOOL fRegistered;
            CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered));
            Bstr strPath;
            CHECK_ERROR_BREAK(pFile, COMGETTER(FileName)(strPath.asOutParam()));

            RTPrintf("File \"%s\" %s\n",
                     Utf8Str(strPath).c_str(),
                     fRegistered ? "registered" : "unregistered");
            if (fRegistered)
            {
                if (mfVerbose)
                    RTPrintf("Registering ...\n");

                /* Register for IGuestFile events. */
                ComObjPtr<GuestFileEventListenerImpl> pListener;
                pListener.createObject();
                CHECK_ERROR_BREAK(pListener, init(new GuestFileEventListener()));

                ComPtr<IEventSource> es;
                CHECK_ERROR_BREAK(pFile, COMGETTER(EventSource)(es.asOutParam()));
                com::SafeArray<VBoxEventType_T> eventTypes;
                eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged);
                CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes),
                                                       true /* Active listener */));

                GuestFileStats fileStats(pListener);
                mFiles[pFile] = fileStats;
            }
            else
            {
                GuestEventFiles::iterator itFile = mFiles.find(pFile);
                if (itFile != mFiles.end())
                {
                    if (mfVerbose)
                        RTPrintf("Unregistering file ...\n");

                    if (!itFile->first.isNull())
                    {
                        /* Listener unregistration. */
                        ComPtr<IEventSource> pES;
                        CHECK_ERROR(itFile->first, COMGETTER(EventSource)(pES.asOutParam()));
                        if (!pES.isNull())
                            CHECK_ERROR(pES, UnregisterListener(itFile->second.mListener));
                        itFile->first->Release();
                    }

                    mFiles.erase(itFile);
                }
            }

        } while (0);
        break;
    }

    case VBoxEventType_OnGuestProcessRegistered:
    {
        HRESULT rc;
        do
        {
            ComPtr<IGuestProcessRegisteredEvent> pEvent = aEvent;
            Assert(!pEvent.isNull());

            ComPtr<IGuestProcess> pProcess;
            CHECK_ERROR_BREAK(pEvent, COMGETTER(Process)(pProcess.asOutParam()));
            AssertBreak(!pProcess.isNull());
            BOOL fRegistered;
            CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered));
            Bstr strPath;
            CHECK_ERROR_BREAK(pProcess, COMGETTER(ExecutablePath)(strPath.asOutParam()));

            RTPrintf("Process \"%s\" %s\n",
                     Utf8Str(strPath).c_str(),
                     fRegistered ? "registered" : "unregistered");
            if (fRegistered)
            {
                if (mfVerbose)
                    RTPrintf("Registering ...\n");

                /* Register for IGuestProcess events. */
                ComObjPtr<GuestProcessEventListenerImpl> pListener;
                pListener.createObject();
                CHECK_ERROR_BREAK(pListener, init(new GuestProcessEventListener()));

                ComPtr<IEventSource> es;
                CHECK_ERROR_BREAK(pProcess, COMGETTER(EventSource)(es.asOutParam()));
                com::SafeArray<VBoxEventType_T> eventTypes;
                eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged);
                CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes),
                                                       true /* Active listener */));

                GuestProcStats procStats(pListener);
                mProcs[pProcess] = procStats;
            }
            else
            {
                GuestEventProcs::iterator itProc = mProcs.find(pProcess);
                if (itProc != mProcs.end())
                {
                    if (mfVerbose)
                        RTPrintf("Unregistering process ...\n");

                    if (!itProc->first.isNull())
                    {
                        /* Listener unregistration. */
                        ComPtr<IEventSource> pES;
                        CHECK_ERROR(itProc->first, COMGETTER(EventSource)(pES.asOutParam()));
                        if (!pES.isNull())
                            CHECK_ERROR(pES, UnregisterListener(itProc->second.mListener));
                        itProc->first->Release();
                    }

                    mProcs.erase(itProc);
                }
            }

        } while (0);
        break;
    }

    case VBoxEventType_OnGuestSessionStateChanged:
    {
        HRESULT rc;
        do
        {
            ComPtr<IGuestSessionStateChangedEvent> pEvent = aEvent;
            Assert(!pEvent.isNull());
            ComPtr<IGuestSession> pSession;
            CHECK_ERROR_BREAK(pEvent, COMGETTER(Session)(pSession.asOutParam()));
            AssertBreak(!pSession.isNull());

            GuestSessionStatus_T sessSts;
            CHECK_ERROR_BREAK(pSession, COMGETTER(Status)(&sessSts));
            ULONG uID;
            CHECK_ERROR_BREAK(pSession, COMGETTER(Id)(&uID));
            Bstr strName;
            CHECK_ERROR_BREAK(pSession, COMGETTER(Name)(strName.asOutParam()));

            RTPrintf("Session ID=%RU32 \"%s\" changed status to [%s]\n",
                     uID, Utf8Str(strName).c_str(), gctlGuestSessionStatusToText(sessSts));

        } while (0);
        break;
    }

    default:
        AssertFailed();
    }

    return S_OK;
}