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; } }
void ByteBuffer::expandIntoLeftMargin(std::size_t len) { RCF_ASSERT_LTEQ(len , mLeftMargin); mPv -= len; mPvlen += len; mLeftMargin -= len; }
void ByteBuffer::setLeftMargin(std::size_t len) { RCF_ASSERT_LTEQ(len , mLeftMargin + mPvlen); mPv = mPv - mLeftMargin + len; mPvlen = mPvlen + mLeftMargin - len; mLeftMargin = len; }
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()); } } }
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()); } } }
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; }
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; }
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; }
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); } }
// 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); } } } }