示例#1
0
    void encodeInt(int value, std::vector<char> &vec, std::size_t &pos)
    {
        RCF_ASSERT_LTEQ(pos , vec.size());
        if (pos + 5 > vec.size())
        {
            vec.resize(vec.size()+5);
        }

        if (0 <= value && value < 255)
        {
            RCF_ASSERT_LTEQ(pos+1 , vec.size());
            vec[pos] = static_cast<char>(value);
            pos += 1;
        }
        else
        {
            RCF_ASSERT_LTEQ(pos+1 , vec.size());
            vec[pos] = (unsigned char)(255);
            pos += 1;

            RCF_ASSERT_LTEQ(pos+4 , vec.size());
            BOOST_STATIC_ASSERT(sizeof(int) == 4);
            RCF::machineToNetworkOrder(&value, 4, 1);
            memcpy(&vec[pos], &value, 4);
            pos += 4;
        }
    }
示例#2
0
 void ByteBuffer::expandIntoLeftMargin(std::size_t len)
 {
     RCF_ASSERT_LTEQ(len , mLeftMargin);
     mPv -= len;
     mPvlen += len;
     mLeftMargin -= len;
 }
示例#3
0
    void ByteBuffer::setLeftMargin(std::size_t len)
    {
        RCF_ASSERT_LTEQ(len , mLeftMargin + mPvlen);

        mPv                     = mPv - mLeftMargin + len;
        mPvlen                  = mPvlen + mLeftMargin - len;
        mLeftMargin             = len;
    }
示例#4
0
    void encodeBool(bool value, const RCF::ByteBuffer &byteBuffer, std::size_t &pos)
    {
        RCF_ASSERT_LTEQ(pos+1 , byteBuffer.getLength());

        value ?
            byteBuffer.getPtr()[pos] = 1 :
            byteBuffer.getPtr()[pos] = 0;
        pos += 1;
    }
void AsioSessionState::onAppReadWriteCompleted(
    size_t bytesTransferred)
{
    RCF_ASSERT(!mReflecting);
    switch(mState)
    {
    case ReadingDataCount:
    case ReadingData:

        if (mTransport.mCustomFraming)
        {
            doCustomFraming(bytesTransferred);
        }
        else
        {
            doRegularFraming(bytesTransferred);
        }

        break;

    case WritingData:

        RCF_ASSERT_LTEQ(bytesTransferred , mWriteBufferRemaining);

        mWriteBufferRemaining -= bytesTransferred;
        if (mWriteBufferRemaining > 0)
        {
            beginWrite();
        }
        else
        {
            if (mCloseAfterWrite)
            {
                // For TCP sockets, call shutdown() so client receives
                // the message before we close the connection.

                implCloseAfterWrite();
            }
            else
            {
                mState = Ready;

                mSlicedWriteByteBuffers.resize(0);
                mWriteByteBuffers.resize(0);

                mTransport.getSessionManager().onWriteCompleted(
                    getSessionPtr());
            }
        }
        break;

    default:
        RCF_ASSERT(0);
    }
}
void AsioSessionState::doRegularFraming(size_t bytesTransferred)
{
    RCF_ASSERT_LTEQ(bytesTransferred , mReadBufferRemaining);
    mReadBufferRemaining -= bytesTransferred;
    if (mReadBufferRemaining > 0)
    {
        beginRead();
    }
    else if (mReadBufferRemaining == 0 && mIssueZeroByteRead)
    {
        if (!mAppReadBufferPtr || !mAppReadBufferPtr.unique())
        {
            mAppReadBufferPtr = getObjectPool().getReallocBufferPtr();
        }
        mAppReadBufferPtr->resize(4);

        mReadBufferRemaining = 4;
        mIssueZeroByteRead = false;
        beginRead();
    }
    else
    {
        RCF_ASSERT_EQ(mReadBufferRemaining , 0);
        if (mState == ReadingDataCount)
        {
            ReallocBuffer & readBuffer = *mAppReadBufferPtr;
            RCF_ASSERT_EQ(readBuffer.size() , 4);

            unsigned int packetLength = 0;
            memcpy(&packetLength, &readBuffer[0], 4);
            networkToMachineOrder(&packetLength, 4, 1);

            if (    mTransport.getMaxMessageLength()
                    &&  packetLength > mTransport.getMaxMessageLength())
            {
                sendServerError(RcfError_ServerMessageLength);
            }
            else
            {
                readBuffer.resize(packetLength);
                mReadBufferRemaining = packetLength;
                mState = ReadingData;
                beginRead();
            }
        }
        else if (mState == ReadingData)
        {
            mState = Ready;

            mTransport.getSessionManager().onReadCompleted(
                getSessionPtr());
        }
    }
}
示例#7
0
    void encodeInt(int value, const RCF::ByteBuffer &byteBuffer, std::size_t &pos)
    {
        if (0 <= value && value < 255)
        {
            RCF_ASSERT_LTEQ(pos+1 , byteBuffer.getLength());
            byteBuffer.getPtr()[pos] = static_cast<char>(value);
            pos += 1;
        }
        else
        {
            RCF_ASSERT_LTEQ(pos+1 , byteBuffer.getLength());
            byteBuffer.getPtr()[pos] = (unsigned char)(255);
            pos += 1;

            RCF_ASSERT_LTEQ(pos+4 , byteBuffer.getLength());
            BOOST_STATIC_ASSERT(sizeof(int) == 4);
            RCF::machineToNetworkOrder(&value, 4, 1);
            memcpy(&byteBuffer.getPtr()[pos], &value, 4);
            pos += 4;
        }
    }
void AsioSessionState::doCustomFraming(size_t bytesTransferred)
{
    RCF_ASSERT_LTEQ(bytesTransferred , mReadBufferRemaining);
    mReadBufferRemaining -= bytesTransferred;
    if (mReadBufferRemaining > 0)
    {
        beginRead();
    }
    else if (mReadBufferRemaining == 0 && mIssueZeroByteRead)
    {
        if (!mAppReadBufferPtr || !mAppReadBufferPtr.unique())
        {
            mAppReadBufferPtr = getObjectPool().getReallocBufferPtr();
        }
        mAppReadBufferPtr->resize(4);

        mReadBufferRemaining = 4;
        mIssueZeroByteRead = false;
        beginRead();
    }
    else
    {
        RCF_ASSERT_EQ(mReadBufferRemaining , 0);
        if (mState == ReadingDataCount)
        {
            ReallocBuffer & readBuffer = *mAppReadBufferPtr;
            RCF_ASSERT_EQ(readBuffer.size() , 4);

            std::size_t messageLength = mTransportFilters[0]->getFrameSize();

            if (    mTransport.getMaxMessageLength()
                    &&  messageLength > mTransport.getMaxMessageLength())
            {
                sendServerError(RcfError_ServerMessageLength);
            }
            else
            {
                RCF_ASSERT( messageLength > 4 );
                readBuffer.resize(messageLength);
                mReadBufferRemaining = messageLength - 4;
                mState = ReadingData;
                beginRead();
            }
        }
        else if (mState == ReadingData)
        {
            mState = Ready;

            mTransport.getSessionManager().onReadCompleted(
                getSessionPtr());
        }
    }
}
示例#9
0
    void encodeBool(bool value, std::vector<char> &vec, std::size_t &pos)
    {
        RCF_ASSERT_LTEQ(pos , vec.size());
        if (pos + 1 > vec.size())
        {
            vec.resize(vec.size()+1);
        }

        value ?
            vec[pos] = 1 :
            vec[pos] = 0;
        pos += 1;
    }
示例#10
0
    void encodeByteBuffer(
        RCF::ByteBuffer             value, 
        std::vector<char> &         vec, 
        std::size_t &               pos)
    {
        int len = static_cast<int>(value.getLength());
        SF::encodeInt(len, vec, pos);

        RCF_ASSERT_LTEQ(pos , vec.size());
        if (pos + len > vec.size())
        {
            vec.resize(vec.size()+len);
        }
        memcpy(&vec[pos], value.getPtr(), len);
        pos += len;
    }
示例#11
0
    void encodeString(
        const std::string &value,
        std::vector<char> &vec,
        std::size_t &pos)
    {
        int len = static_cast<int>(value.length());
        SF::encodeInt(len, vec, pos);

        RCF_ASSERT_LTEQ(pos , vec.size());
        if (pos + len > vec.size())
        {
            vec.resize(vec.size()+len);
        }
        memcpy(&vec[pos], value.c_str(), len);
        pos += len;
    }
示例#12
0
    ByteBuffer::ByteBuffer(
        const ByteBuffer &byteBuffer,
        std::size_t offset,
        std::size_t len) :
            mSpvc(byteBuffer.mSpvc),
            mSpos(byteBuffer.mSpos),
            mSprb(byteBuffer.mSprb),
            mPv(byteBuffer.mPv + offset),
            mPvlen( len == npos ? byteBuffer.mPvlen-offset : len),
            mLeftMargin( offset ? 0 : byteBuffer.mLeftMargin),
            mReadOnly(byteBuffer.mReadOnly)
            
    {
        RCF_ASSERT_LTEQ(offset , byteBuffer.mPvlen);

        RCF_ASSERT(
            len == npos || offset+len <= byteBuffer.mPvlen)
            (offset)(len)(byteBuffer.mPvlen);
    }
void AsioSessionState::read(
    const ByteBuffer &byteBuffer,
    std::size_t bytesRequested)
{
    if (byteBuffer.getLength() == 0 && bytesRequested > 0)
    {
        if (!mNetworkReadBufferPtr || mNetworkReadBufferPtr.unique())
        {
            mNetworkReadBufferPtr = getObjectPool().getReallocBufferPtr();
        }
        mNetworkReadBufferPtr->resize(bytesRequested);
        mNetworkReadByteBuffer = ByteBuffer(mNetworkReadBufferPtr);
    }
    else
    {
        mNetworkReadByteBuffer = ByteBuffer(byteBuffer, 0, bytesRequested);
    }

    RCF_ASSERT_LTEQ(bytesRequested, mNetworkReadByteBuffer.getLength());

    char *buffer = mNetworkReadByteBuffer.getPtr();
    std::size_t bufferLen = mNetworkReadByteBuffer.getLength();

    Lock lock(mSessionPtr->mDisableIoMutex);
    if (!mSessionPtr->mDisableIo)
    {
        if (mSocketOpsMutexPtr)
        {
            Lock lock(*mSocketOpsMutexPtr);
            implRead(buffer, bufferLen);
        }
        else
        {
            implRead(buffer, bufferLen);
        }
    }
}
    void ZlibCompressionWriteFilter::onWriteCompleted(
        std::size_t bytesTransferred)
    {
        // 1. if partial buffer was written -> write remaining part of buffer
        // 2. if whole buffer was written -> check if any more compression or writing is needed
        // 3. if no more compression or writing needed, notify previous filter of completion

        RCF_ASSERT_LTEQ(bytesTransferred , lengthByteBuffers(mPostBuffers));

        if (bytesTransferred < lengthByteBuffers(mPostBuffers))
        {
            // TODO: optimize
            std::vector<ByteBuffer> slicedBuffers;
            sliceByteBuffers(slicedBuffers, mPostBuffers, bytesTransferred);
            mPostBuffers = slicedBuffers;
            mFilter.getPostFilter().write(mPostBuffers);
        }
        else
        {
            mPreBuffers.resize(0);
            mPostBuffers.resize(0);
            mFilter.getPreFilter().onWriteCompleted(mTotalBytesIn);
        }
    }
示例#15
0
    // returns -2 for timeout, -1 for error, otherwise number of bytes sent (> 0)
    int timedSend(
        I_PollingFunctor &pollingFunctor,
        int &err,
        int fd,
        const std::vector<ByteBuffer> &byteBuffers,
        std::size_t maxSendSize,
        int flags)
    {
        RCF_UNUSED_VARIABLE(flags);
        std::size_t bytesRemaining = lengthByteBuffers(byteBuffers);
        std::size_t bytesSent = 0;
        while (true)
        {
            std::size_t bytesToSend = RCF_MIN(bytesRemaining, maxSendSize);

            ThreadLocalCached< std::vector<WSABUF> > tlcWsabufs;
            std::vector<WSABUF> &wsabufs = tlcWsabufs.get();

            forEachByteBuffer(
                boost::bind(&appendWsabuf, boost::ref(wsabufs), _1),
                byteBuffers,
                bytesSent,
                bytesToSend);

            int count = 0;
            int myErr = 0;

#ifdef BOOST_WINDOWS
            {
                DWORD cbSent = 0;
                int ret = WSASend(
                    fd, 
                    &wsabufs[0], 
                    static_cast<DWORD>(wsabufs.size()), 
                    &cbSent, 
                    0, 
                    NULL, 
                    NULL);

                count = (ret == 0) ? cbSent : -1;
                myErr = Platform::OS::BsdSockets::GetLastError();
            }            
#else
            {
                msghdr hdr = {0};
                hdr.msg_iov = &wsabufs[0];
                hdr.msg_iovlen = wsabufs.size();
                count = sendmsg(fd, &hdr, 0);
                myErr = Platform::OS::BsdSockets::GetLastError();
            }
#endif

            if (count >= 0)
            {
                RCF_ASSERT_LTEQ(count , static_cast<int>(bytesRemaining));

                bytesRemaining -= count;
                bytesSent += count;
                err = 0;
                return static_cast<int>(bytesSent);
            }
            else if (myErr == Platform::OS::BsdSockets::ERR_EWOULDBLOCK)
            {
                // can't get WSA_IO_PENDING here, since the socket isn't overlapped
                int ret = pollingFunctor(fd, myErr, false);
                if (ret  != 0)
                {
                    err = myErr;
                    return ret;
                }
            }
            else
            {
                err = myErr;
                return -1;
            }


        }
    }
void AsioSessionState::onAcceptCompleted(
    const AsioErrorCode & error)
{
    RCF_LOG_4()(error.value())
            << "AsioSessionState - onAccept().";

    if (mTransport.mStopFlag)
    {
        RCF_LOG_4()(error.value())
                << "AsioSessionState - onAccept(). Returning early, stop flag is set.";

        return;
    }

    //if (
    //    error == ASIO_NS::error::connection_aborted ||
    //    error == ASIO_NS::error::operation_aborted)
    //{
    //    beginAccept();
    //    return;
    //}

    // create a new SessionState, and do an accept on that
    mTransport.createSessionState()->beginAccept();

    if (!error)
    {
        // save the remote address in the SessionState object
        bool clientAddrAllowed = implOnAccept();
        mState = WritingData;

        // set current RCF session
        CurrentRcfSessionSentry guard(*mSessionPtr);

        mSessionPtr->touch();

        if (clientAddrAllowed)
        {
            // Check the connection limit.
            bool allowConnect = true;
            std::size_t connectionLimit = mTransport.getConnectionLimit();
            if (connectionLimit)
            {
                Lock lock(mTransport.mSessionsMutex);

                RCF_ASSERT_LTEQ(
                    mTransport.mSessions.size() , 1+1+connectionLimit);

                if (mTransport.mSessions.size() == 1+1+connectionLimit)
                {
                    allowConnect = false;
                }
            }

            if (allowConnect)
            {
                time_t now = 0;
                now = time(NULL);
                mSessionPtr->setConnectedAtTime(now);

                // start things rolling by faking a completed write operation
                onAppReadWriteCompleted(0);
            }
            else
            {
                sendServerError(RcfError_ConnectionLimitExceeded);
            }
        }
    }
}