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 UdpServerTransport::cycle(int timeoutMs) { RCF::ThreadInfoPtr tiPtr = getTlsThreadInfoPtr(); RCF::ThreadPool & threadPool = tiPtr->getThreadPool(); if (threadPool.shouldStop()) { return; } // poll the UDP socket for messages, and read a message if one is available fd_set fdSet; FD_ZERO(&fdSet); FD_SET( static_cast<SOCKET>(mFd), &fdSet); timeval timeout; timeout.tv_sec = timeoutMs/1000; timeout.tv_usec = 1000*(timeoutMs%1000); int ret = Platform::OS::BsdSockets::select( mFd+1, &fdSet, NULL, NULL, timeoutMs < 0 ? NULL : &timeout); int err = Platform::OS::BsdSockets::GetLastError(); if (ret == 1) { SessionStatePtr sessionStatePtr = getTlsUdpSessionStatePtr(); if (sessionStatePtr.get() == NULL) { sessionStatePtr = SessionStatePtr(new SessionState(*this)); sessionStatePtr->mSessionPtr = getSessionManager().createSession(); sessionStatePtr->mSessionPtr->setSessionState(*sessionStatePtr); setTlsUdpSessionStatePtr(sessionStatePtr); } { // read a message ReallocBufferPtr &readVecPtr = sessionStatePtr->mReadVecPtr; if (readVecPtr.get() == NULL || !readVecPtr.unique()) { readVecPtr.reset( new ReallocBuffer()); } ReallocBuffer &buffer = *readVecPtr; SockAddrStorage from; int fromlen = sizeof(from); memset(&from, 0, sizeof(from)); buffer.resize(4); int len = Platform::OS::BsdSockets::recvfrom( mFd, &buffer[0], 4, MSG_PEEK, (sockaddr *) &from, &fromlen); err = Platform::OS::BsdSockets::GetLastError(); sessionStatePtr->mRemoteAddress.init( (sockaddr&) from, fromlen, mIpAddress.getType()); if (!isIpAllowed(sessionStatePtr->mRemoteAddress)) { RCF_LOG_2()(sessionStatePtr->mRemoteAddress.getIp()) << "Client IP does not match server's IP access rules. Closing connection."; discardPacket(mFd); } else if ( len == 4 || (len == -1 && err == Platform::OS::BsdSockets::ERR_EMSGSIZE)) { unsigned int dataLength = 0; memcpy(&dataLength, &buffer[0], 4); networkToMachineOrder(&dataLength, 4, 1); if (getMaxMessageLength() && dataLength > getMaxMessageLength()) { ByteBuffer byteBuffer; encodeServerError(getSessionManager(), byteBuffer, RcfError_ServerMessageLength); byteBuffer.expandIntoLeftMargin(4); * (boost::uint32_t *) ( byteBuffer.getPtr() ) = static_cast<boost::uint32_t>(byteBuffer.getLength()-4); RCF::machineToNetworkOrder(byteBuffer.getPtr(), 4, 1); char *buffer = byteBuffer.getPtr(); std::size_t bufferLen = byteBuffer.getLength(); sockaddr * pRemoteAddr = NULL; Platform::OS::BsdSockets::socklen_t remoteAddrSize = 0; sessionStatePtr->mRemoteAddress.getSockAddr(pRemoteAddr, remoteAddrSize); int len = sendto( mFd, buffer, static_cast<int>(bufferLen), 0, pRemoteAddr, remoteAddrSize); RCF_UNUSED_VARIABLE(len); discardPacket(mFd); } else { buffer.resize(4+dataLength); memset(&from, 0, sizeof(from)); fromlen = sizeof(from); len = Platform::OS::BsdSockets::recvfrom( mFd, &buffer[0], 4+dataLength, 0, (sockaddr *) &from, &fromlen); if (static_cast<unsigned int>(len) == 4+dataLength) { getSessionManager().onReadCompleted(sessionStatePtr->mSessionPtr); } } } else { discardPacket(mFd); } } } else if (ret == 0) { //RCF_LOG_4()(mFd)(mPort)(timeoutMs) << "UdpServerTransport - no messages received within polling interval."; } else if (ret == -1) { Exception e( _RcfError_Socket("select()"), err, RcfSubsystem_Os); RCF_THROW(e)(mFd)(mIpAddress.string())(err); } }
void AsioSessionState::onReadWrite( size_t bytesTransferred, const boost::system::error_code& error) { RCF_ASSERT(!error); RCF_ASSERT(!mReflecting); { switch(mState) { case ReadingDataCount: case ReadingData: RCF_ASSERT( bytesTransferred <= mReadBufferRemaining) (bytesTransferred)(mReadBufferRemaining); mReadBufferRemaining -= bytesTransferred; if (mReadBufferRemaining > 0) { invokeAsyncRead(); } else { RCF_ASSERT(mReadBufferRemaining == 0)(mReadBufferRemaining); if (mState == ReadingDataCount) { std::vector<char> &readBuffer = getReadBuffer(); RCF_ASSERT(readBuffer.size() == 4)(readBuffer.size()); unsigned int packetLength = 0; memcpy(&packetLength, &readBuffer[0], 4); networkToMachineOrder(&packetLength, 4, 1); if (packetLength <= mTransport.getMaxMessageLength()) { readBuffer.resize(packetLength); mReadBufferRemaining = packetLength; mState = ReadingData; invokeAsyncRead(); } else { sendServerError(RcfError_ServerMessageLength); } } else if (mState == ReadingData) { mState = Ready; mTransport.getSessionManager().onReadCompleted( getSessionPtr()); if (mTransport.mInterrupt) { mTransport.mInterrupt = false; mTransport.mDemuxerPtr->stop(); } } } break; case WritingData: RCF_ASSERT( bytesTransferred <= mWriteBufferRemaining) (bytesTransferred)(mWriteBufferRemaining); mWriteBufferRemaining -= bytesTransferred; if (mWriteBufferRemaining > 0) { invokeAsyncWrite(); } else { if (mCloseAfterWrite) { int fd = implGetNative(); const int BufferSize = 8*1024; char buffer[BufferSize]; while (recv(fd, buffer, BufferSize, 0) > 0); } else { mState = Ready; mSlicedWriteByteBuffers.resize(0); mWriteByteBuffers.resize(0); mTransport.getSessionManager().onWriteCompleted( getSessionPtr()); if (mTransport.mInterrupt) { mTransport.mInterrupt = false; mTransport.mDemuxerPtr->stop(); } } } break; default: RCF_ASSERT(0); } } }
void UdpServerTransport::cycle( int timeoutMs, const volatile bool &) //stopFlag { // poll the UDP socket for messages, and read a message if one is available fd_set fdSet; FD_ZERO(&fdSet); FD_SET( static_cast<SOCKET>(mFd), &fdSet); timeval timeout; timeout.tv_sec = timeoutMs/1000; timeout.tv_usec = 1000*(timeoutMs%1000); int ret = Platform::OS::BsdSockets::select( mFd+1, &fdSet, NULL, NULL, timeoutMs < 0 ? NULL : &timeout); int err = Platform::OS::BsdSockets::GetLastError(); if (ret == 1) { SessionStatePtr sessionStatePtr = getCurrentUdpSessionStatePtr(); if (sessionStatePtr.get() == NULL) { sessionStatePtr = SessionStatePtr(new SessionState(*this)); SessionPtr sessionPtr = getSessionManager().createSession(); sessionPtr->setProactor(*sessionStatePtr); sessionStatePtr->mSessionPtr = sessionPtr; setCurrentUdpSessionStatePtr(sessionStatePtr); RcfSessionPtr rcfSessionPtr = boost::static_pointer_cast<RcfSession>(sessionPtr); rcfSessionPtr->mIoState = RcfSession::Reading; } { // read a message boost::shared_ptr<std::vector<char> > &readVecPtr = sessionStatePtr->mReadVecPtr; if (readVecPtr.get() == NULL || !readVecPtr.unique()) { readVecPtr.reset( new std::vector<char>()); } std::vector<char> &buffer = *readVecPtr; sockaddr from; int fromlen = sizeof(from); memset(&from, 0, sizeof(from)); buffer.resize(4); int len = Platform::OS::BsdSockets::recvfrom( mFd, &buffer[0], 4, MSG_PEEK, &from, &fromlen); err = Platform::OS::BsdSockets::GetLastError(); if (isClientAddrAllowed( *(sockaddr_in *) &from ) && (len == 4 || (len == -1 && err == Platform::OS::BsdSockets::ERR_EMSGSIZE))) { sockaddr_in *remoteAddr = reinterpret_cast<sockaddr_in*>(&from); sessionStatePtr->remoteAddress = IpAddress(*remoteAddr); unsigned int dataLength = 0; memcpy(&dataLength, &buffer[0], 4); networkToMachineOrder(&dataLength, 4, 1); if (dataLength <= static_cast<unsigned int>(getMaxMessageLength())) { buffer.resize(4+dataLength); memset(&from, 0, sizeof(from)); fromlen = sizeof(from); len = Platform::OS::BsdSockets::recvfrom( mFd, &buffer[0], 4+dataLength, 0, &from, &fromlen); if (static_cast<unsigned int>(len) == 4+dataLength) { getSessionManager().onReadCompleted(sessionStatePtr->mSessionPtr); } } else { ByteBuffer byteBuffer; encodeServerError(byteBuffer, RcfError_ServerMessageLength); byteBuffer.expandIntoLeftMargin(4); * (boost::uint32_t *) ( byteBuffer.getPtr() ) = static_cast<boost::uint32_t>(byteBuffer.getLength()-4); RCF::machineToNetworkOrder(byteBuffer.getPtr(), 4, 1); char *buffer = byteBuffer.getPtr(); std::size_t bufferLen = byteBuffer.getLength(); const sockaddr_in &remoteAddr = sessionStatePtr->remoteAddress.getSockAddr(); int len = sendto( mFd, buffer, static_cast<int>(bufferLen), 0, (const sockaddr *) &remoteAddr, sizeof(remoteAddr)); RCF_UNUSED_VARIABLE(len); discardPacket(mFd); } } else { // discard the message (sender ip not allowed, or message format bad) discardPacket(mFd); } } } else if (ret == 0) { RCF_TRACE("server udp poll - no messages")(mFd)(mPort); } else if (ret == -1) { RCF_THROW( Exception( RcfError_Socket, err, RcfSubsystem_Os, "udp server select() failed ")) (mFd)(mPort)(err); } }