예제 #1
0
    void FileIoThreadPool::registerOp(FileIoRequestPtr opPtr)
    {
        RCF::Lock lock(mOpsMutex);

        // Lazy start of the thread pool.
        if (!mThreadPool.isStarted())
        {
            mStopFlag = false;
            mThreadPool.start(mStopFlag);
        }

        if (    std::find(mOpsQueued.begin(), mOpsQueued.end(), opPtr) 
            !=  mOpsQueued.end())
        {
            RCF_ASSERT(0);
        }
        else if (       std::find(mOpsInProgress.begin(), mOpsInProgress.end(), opPtr) 
                    !=  mOpsInProgress.end())
        {
            RCF_ASSERT(0);
        }
        else
        {
            mOpsQueued.push_back(opPtr);
            mOpsCondition.notify_all();
        }
    }
예제 #2
0
    void ClientStub::onTimerExpired()
    {
        AsyncOpType opType = mAsyncOpType;
        mAsyncOpType = None;

        if (opType == Wait)
        {
            scheduleAmiNotification();
        }
        else
        {
            switch(opType)
            {
            case Connect:
                RCF_ASSERT(mEndpoint.get());
                
                onError(RCF::Exception(_RcfError_ClientConnectTimeout(
                    mConnectTimeoutMs, 
                    mEndpoint->asString())));

                break;

            case Write:
                onError(RCF::Exception(_RcfError_ClientWriteTimeout()));
                break;

            case Read: 
                onError(RCF::Exception(_RcfError_ClientReadTimeout()));
                break;

            default:
                RCF_ASSERT(0)(opType);
            };
        }        
    }
예제 #3
0
    void ClientStub::createFilterSequence(
        std::vector<FilterPtr> & filters)
    {
        filters.clear();
    
        // Setup compression if configured.
        if (mEnableCompression)
        {
#if RCF_FEATURE_ZLIB==1
            FilterPtr filterPtr( new ZlibStatefulCompressionFilter() );
            filters.push_back(filterPtr);
#else
            RCF_ASSERT(0);
#endif
        }

        FilterPtr filterPtr;
        if (mTransportProtocol != Tp_Clear && mTransportProtocol != Tp_Unspecified)
        {
            switch (mTransportProtocol)
            {
#if RCF_FEATURE_SSPI==1
            case Tp_Ntlm:       filterPtr.reset( new NtlmFilter(this) ); break;
            case Tp_Kerberos:   filterPtr.reset( new KerberosFilter(this) ); break;
            case Tp_Negotiate:  filterPtr.reset( new NegotiateFilter(this) ); break;
#endif

#if RCF_FEATURE_OPENSSL==1 && RCF_FEATURE_SSPI==1
            case Tp_Ssl:        if (mSslImplementation == Si_Schannel)
                                {
                                    filterPtr.reset( new SchannelFilter(this) ); 
                                }
                                else
                                {
                                    RCF_ASSERT(mSslImplementation == Si_OpenSsl);
                                    filterPtr.reset( new OpenSslEncryptionFilter(this) ); 
                                }
                                break;
#elif RCF_FEATURE_OPENSSL==1
            case Tp_Ssl:        filterPtr.reset( new OpenSslEncryptionFilter(this) ); break;
#elif RCF_FEATURE_SSPI==1
            case Tp_Ssl:        filterPtr.reset( new SchannelFilter(this) ); break;
#else
            // Single case just to keep the compiler warnings quiet.
            case Tp_Ssl:
#endif

            default:
                RCF_THROW( Exception( _RcfError_TransportProtocolNotSupported( getTransportProtocolName(mTransportProtocol)) ) );
            }
        }
        if (filterPtr)
        {
            filters.push_back(filterPtr);
        }
    }
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);
    }
}
예제 #5
0
    void ObjectPool::put(VecPtr & vecPtr)
    {
        RCF_ASSERT(vecPtr);
        RCF_ASSERT(vecPtr.unique());

        vecPtr->resize(0);

        Lock lock(mVecPtrPoolMutex);
        mVecPtrPool.push_back(vecPtr);
        vecPtr.reset();
    }
    HttpsClientTransport::HttpsClientTransport(const HttpsEndpoint & httpsEndpoint) : 
        TcpClientTransport(httpsEndpoint.getIp(), httpsEndpoint.getPort())
    {
        std::vector<FilterPtr> wireFilters;

        // HTTP framing.
        wireFilters.push_back( FilterPtr( new HttpFrameFilter(
            getRemoteAddr().getIp(), 
            getRemoteAddr().getPort())));

        // SSL.
        ClientStub * pClientStub = getTlsClientStubPtr();
        RCF_ASSERT(pClientStub);

        FilterPtr sslFilterPtr;

#if RCF_FEATURE_SSPI==1 && RCF_FEATURE_OPENSSL==1

        if (pClientStub->getSslImplementation() == Si_Schannel)
        {
            sslFilterPtr.reset( new SchannelFilter(pClientStub) );
        }
        else
        {
            RCF_ASSERT(pClientStub->getSslImplementation() == Si_OpenSsl);
            sslFilterPtr.reset( new OpenSslEncryptionFilter(pClientStub) );
        }

#elif RCF_FEATURE_SSPI==1

        sslFilterPtr.reset( new SchannelFilter(pClientStub) );

#elif RCF_FEATURE_OPENSSL==1

        sslFilterPtr.reset( new OpenSslEncryptionFilter(pClientStub) );

#endif

        if (!sslFilterPtr)
        {
            RCF_THROW( Exception(_RcfError_SslNotSupported()) );
        }

        wireFilters.push_back(sslFilterPtr);

        // HTTP CONNECT filter for passing through a proxy.
        wireFilters.push_back( FilterPtr( new HttpConnectFilter(
            getRemoteAddr().getIp(), 
            getRemoteAddr().getPort())));

        setWireFilters(wireFilters);
    }
예제 #7
0
    void ServerObjectService::customDeleter(const std::string & objectKey, void * pt)
    {
        RCF_UNUSED_VARIABLE(pt);

        Lock lock(mMutex);

        ServerObjectMap::iterator iter = mServerObjectMap.find(objectKey);
        RCF_ASSERT(iter != mServerObjectMap.end());
        ServerObjectHolder & holder = iter->second;
        RCF_ASSERT(holder.mUseCount > 0);
        --holder.mUseCount;
        holder.mLastTouchMs = getCurrentTimeMs();
    }
예제 #8
0
    void ObjectPool::put(OstrStreamPtr & ostrStreamPtr)
    {
        RCF_ASSERT(ostrStreamPtr);
        RCF_ASSERT(ostrStreamPtr.unique());

        ostrStreamPtr->clear(); // freezing may have set error state
        ostrStreamPtr->rdbuf()->freeze(false);
        ostrStreamPtr->rdbuf()->pubseekoff(0, std::ios::beg, std::ios::out);

        Lock lock(mOstrStreamPtrPoolMutex);
        mOstrStreamPtrPool.push_back(ostrStreamPtr);
        ostrStreamPtr.reset();
    }
    bool AsioServerTransport::cycle(
        int timeoutMs,
        const volatile bool &,// stopFlag
        bool returnEarly)
    {
        RCF2_TRACE("Entering cycle()");

        RCF_ASSERT(timeoutMs >= -1)(timeoutMs);

        mInterrupt = returnEarly;
        if (timeoutMs != -1)
        {
            mCycleTimerPtr->mImpl.cancel();

            mCycleTimerPtr->mImpl.expires_from_now(
                boost::posix_time::milliseconds(timeoutMs));

            mCycleTimerPtr->mImpl.async_wait( boost::bind(
                &AsioServerTransport::stopCycle, 
                this, 
                boost::asio::placeholders::error));
        }

        mDemuxerPtr->reset();
        mDemuxerPtr->run();

        RCF2_TRACE("Exiting cycle()");

        return false;
    }
    void AsioSessionState::read(
        const ByteBuffer &byteBuffer,
        std::size_t bytesRequested)
    {

        RCF2_TRACE("")(this);

        if (byteBuffer.getLength() == 0)
        {
            std::vector<char> &vec = getUniqueReadBufferSecondary();
            vec.resize(bytesRequested);
            mTempByteBuffer = getReadByteBufferSecondary();
        }
        else
        {
            mTempByteBuffer = ByteBuffer(byteBuffer, 0, bytesRequested);
        }

        RCF_ASSERT(
            bytesRequested <= mTempByteBuffer.getLength())
            (bytesRequested)(mTempByteBuffer.getLength());

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

        Lock lock(mMutex);
        if (!mHasBeenClosed)
        {
            implRead(buffer, bufferLen);
        }
    }
예제 #11
0
    void SubscriptionService::onServerStop(RcfServer &server)
    {
        RCF_UNUSED_VARIABLE(server);

        mPeriodicTimer.stop();

        Subscriptions subs;

        {
            Lock writeLock(mSubscriptionsMutex);
            subs = mSubscriptions;
        }

        for (Subscriptions::iterator iter = subs.begin();
            iter != subs.end();
            ++iter)
        {
            SubscriptionPtr subscriptionPtr = iter->lock();
            if (subscriptionPtr)
            {
                subscriptionPtr->close();
            }
        }

        {
            Lock writeLock(mSubscriptionsMutex);
            RCF_ASSERT(mSubscriptions.empty());
        }

        mSubscriptions.clear();
        subs.clear();

        mpServer = NULL;
    }
    void Win32NamedPipeSessionState::reconnect()
    {
        RCF_ASSERT(mEnableReconnect && mOwnFd);

        BOOL ok = DisconnectNamedPipe(mhPipe);
        DWORD dwErr = GetLastError();
        RCF_ASSERT(ok)(dwErr);
        
        mSessionPtr.reset();
        mSessionPtr = mTransport.mpSessionManager->createSession();
        mSessionPtr->setProactor(*this);

        resetState();

        accept();
    }
예제 #13
0
std::string getWorkingDir()
{
    std::vector<char> vec(1024);
    char * szRet = getcwd(&vec[0], static_cast<int>( vec.size() ));
    RCF_ASSERT(szRet);
    return std::string(&vec[0]);
}
    std::size_t Win32NamedPipeClientTransport::implWrite(
        const std::vector<ByteBuffer> &byteBuffers)
    {
        // For now, can't go back to sync calls after doing an async call.
        // Limitations with Windows IOCP.
        RCF_ASSERT(!mAsyncMode);

        // Not using overlapped I/O here because it interferes with the
        // server session that might be coupled to this transport.

        const ByteBuffer & byteBuffer = byteBuffers.front();

        DWORD count = 0;
        DWORD dwBytesToWrite = static_cast<DWORD>(byteBuffer.getLength());

        BOOL ok = WriteFile( 
            mhPipe,
            byteBuffer.getPtr(),
            dwBytesToWrite,
            &count,
            NULL);

        DWORD dwErr = GetLastError();

        RCF_VERIFY(ok, Exception(_RcfError_ClientWriteFail(), dwErr));

        // Strangely, WriteFile() sometimes returns 1, but at the same time a much too big value in count.
        RCF_VERIFY(count <= dwBytesToWrite, Exception(_RcfError_ClientWriteFail(), dwErr))(count)(dwBytesToWrite);

        RCF_VERIFY(count > 0, Exception(_RcfError_ClientWriteFail(), dwErr))(count)(dwBytesToWrite);

        onTimedSendCompleted( RCF_MIN(count, dwBytesToWrite), 0);

        return count;
    }
예제 #15
0
    void SubscriptionService::createSubscriptionImplBegin(
        RcfClientPtr rcfClientPtr, 
        const SubscriptionParms & parms,
        const std::string & defaultPublisherName)
    {
        ClientStub & clientStub = const_cast<ClientStub &>(parms.mClientStub);
        OnSubscriptionDisconnect onDisconnect = parms.mOnDisconnect;
        std::string publisherName = parms.mPublisherName;
        OnAsyncSubscribeCompleted onCompletion = parms.mOnAsyncSubscribeCompleted;

        if (publisherName.empty())
        {
            publisherName = defaultPublisherName;
        }
        
        RCF_ASSERT(onCompletion);

        if (clientStub.getRuntimeVersion() <= 11)
        {
            doRequestSubscriptionAsync_Legacy(
                clientStub, 
                publisherName, 
                rcfClientPtr,
                parms);
        }
        else
        {
            doRequestSubscriptionAsync(
                clientStub, 
                publisherName, 
                rcfClientPtr,
                parms);
        }
    }
예제 #16
0
 T & createSessionObject()
 {
     deleteSessionObject<T>();
     T * pt = getSessionObjectImpl<T>(true);
     RCF_ASSERT(pt);
     return *pt; 
 }
        void read(T &t)
        {
            try
            {
                switch (mProtocol)
                {
                case 1: mInProtocol1 >> t; break;
                case 2: mInProtocol2 >> t; break;
                case 3: mInProtocol3 >> t; break;
                case 4: mInProtocol4 >> t; break;

#ifdef RCF_USE_BOOST_XML_SERIALIZATION
                case 5: mInProtocol5 >> boost::serialization::make_nvp("Dummy", t); break;
#else
                case 5: mInProtocol5 >> t; break;
#endif

                default: RCF_ASSERT(0)(mProtocol);
                }
            }
            catch(const RCF::Exception &e)
            {
                RCF_UNUSED_VARIABLE(e);
                throw;
            }
            catch(const std::exception &e)
            {
                RCF::SerializationException se( _RcfError_Deserialization(
                    typeid(t).name(), 
                    typeid(e).name(), 
                    e.what()));

                RCF_THROW(se);
            }
        }
예제 #18
0
        T * getSessionObjectImpl(bool createIfDoesntExist)
        {
            typedef boost::shared_ptr<T> TPtr;

            const std::type_info & whichType = typeid(T);
            const std::type_info * pWhichType = &whichType;

            SessionObjectMap::iterator iter = mSessionObjects.find(pWhichType);
            if (iter != mSessionObjects.end())
            {
                boost::any & a = iter->second;
                TPtr * ptPtr = boost::any_cast<TPtr>(&a);
                RCF_ASSERT(ptPtr && *ptPtr);
                return ptPtr->get();
            }
            else if (createIfDoesntExist)
            {
                TPtr tPtr( new T() );
                mSessionObjects[pWhichType] = tPtr;
                return tPtr.get();
            }
            else
            {
                return NULL;
            }
        }
    void PublishingService::onServerStop(RcfServer &server)
    {
        RCF_UNUSED_VARIABLE(server);
        mPeriodicTimer.stop();

        // Close all publishers.

        Publishers publishers;
        {
            Lock writeLock(mPublishersMutex);
            publishers = mPublishers;
        }

        Publishers::iterator iter;
        for (iter = publishers.begin(); iter != publishers.end(); ++iter)
        {
            PublisherPtr publisherPtr = iter->second.lock();
            if (publisherPtr)
            {
                publisherPtr->close();
            }
        }

        {
            Lock writeLock(mPublishersMutex);
            RCF_ASSERT(mPublishers.empty());
        }
    }
예제 #20
0
 UInt32 IStream::read_int(UInt32 &n)
 {
     if (mRuntimeVersion < 9)
     {
         UInt32 bytesRead = read( reinterpret_cast<SF::Byte8 *>(&n), 4);
         RCF::networkToMachineOrder( &n, 4, 1);
         return bytesRead;
     }
     else
     {
         // Integers less than 128 are stored as a single byte.
         Byte8 byte = 0;
         boost::uint8_t ubyte = 0;
         UInt32 bytesRead = read_byte(byte);
         ubyte = byte;
         if (ubyte < 128)
         {
             n = ubyte;
         }
         else
         {
             RCF_ASSERT(ubyte == 128);
             bytesRead += read( reinterpret_cast<SF::Byte8 *>(&n), 4);
             RCF::networkToMachineOrder( &n, 4, 1);
         }
         return bytesRead;
     }
 }
        void read(T &t)
        {
            try
            {
                switch (mProtocol)
                {
                case 1: mInProtocol1 >> t; break;
                case 2: mInProtocol2 >> t; break;
                case 3: mInProtocol3 >> t; break;
                case 4: mInProtocol4 >> t; break;
                case 5: mInProtocol5 >> t; break;

                default: RCF_ASSERT(0)(mProtocol);
                }
            }
            catch(const RCF::Exception &e)
            {
                RCF_UNUSED_VARIABLE(e);
                throw;
            }
            catch(const std::exception &e)
            {
                RCF::SerializationException se( _RcfError_Deserialization(
                    typeid(t).name(), 
                    typeid(e).name(), 
                    e.what()));

                RCF_THROW(se);
            }
        }
예제 #22
0
 std::auto_ptr<I_ServerTransport> TcpEndpoint::createServerTransport() const
 {
     // On non Windows platforms, server side RCF code requires 
     // RCF_USE_BOOST_ASIO to be defined, and the Boost.Asio library to 
     // be available.
     RCF_ASSERT(0);
     return std::auto_ptr<I_ServerTransport>();
 }
예제 #23
0
    void CallbackConnectionService::CreateCallbackConnection()
    {
        // TODO: regular error message.
        // ...
        RCF_ASSERT( mOnCallbackConnectionCreated );

        RCF::convertRcfSessionToRcfClient( mOnCallbackConnectionCreated );
    }
 void InProcessTransport::setTimer(
     boost::uint32_t timeoutMs,
     I_ClientTransportCallback * pClientStub)
 {
     RCF_ASSERT(0);
     RCF_UNUSED_VARIABLE(timeoutMs);
     RCF_UNUSED_VARIABLE(pClientStub);
 }
예제 #25
0
        boost::shared_ptr<T> getServerObjectImpl(
            const std::string & objectKey, 
            boost::uint32_t timeoutMs, 
            bool createIfDoesntExist)
        {
            typedef boost::shared_ptr<T> TPtr;

            Lock lock(mMutex);

            ServerObjectMap::iterator iter = mServerObjectMap.find(objectKey);
            if (iter != mServerObjectMap.end())
            {
                ServerObjectHolder & holder = iter->second;
                boost::any & a = holder.mServerObject;
                TPtr * ptPtr = boost::any_cast<TPtr>(&a);
                RCF_ASSERT(ptPtr);
                TPtr tPtr = *ptPtr;
                T * pt = tPtr.get();
                RCF_ASSERT(pt);

                // Return shared_ptr with custom deleter.
                holder.mLastTouchMs = getCurrentTimeMs();
                RCF_ASSERT(holder.mUseCount >= 0);
                ++holder.mUseCount;
                TPtr ptr(pt, boost::bind(&ServerObjectService::customDeleter, this, objectKey, _1));
                return ptr;
            }
            else if (createIfDoesntExist)
            {
                T * pt = new T();
                TPtr tPtr(pt);
                mServerObjectMap[objectKey] = ServerObjectHolder(boost::any(tPtr), timeoutMs);
                ServerObjectHolder & holder = mServerObjectMap[objectKey];

                // Return shared_ptr with custom deleter.
                holder.mLastTouchMs = getCurrentTimeMs();
                RCF_ASSERT(holder.mUseCount >= 0);
                ++holder.mUseCount;
                TPtr ptr(pt, boost::bind(&ServerObjectService::customDeleter, this, objectKey, _1));
                return ptr;
            }
            else
            {
                return TPtr();
            }
        }
예제 #26
0
std::string getRelativeTestDataPath()
{
    std::string checkoutRoot = getRelativePathToCheckoutRoot();
    RCF_ASSERT(checkoutRoot.size() > 0)(checkoutRoot);

    std::string testDataPath = checkoutRoot + "/RCF/test/data/";
    return testDataPath;
}
예제 #27
0
 void UdpClientTransport::setTransportFilters(
     const std::vector<FilterPtr> &filters)
 {
     if (!filters.empty())
     {
         RCF_ASSERT(0);
     }
 }
예제 #28
0
    static void initZlibCompressionFilterDescriptions()
    {
        RCF_ASSERT(!ZlibStatelessCompressionFilter::spFilterDescription);
        RCF_ASSERT(!ZlibStatefulCompressionFilter::spFilterDescription);

        ZlibStatelessCompressionFilter::spFilterDescription =
            new FilterDescription(
                "Zlib stateless compression filter",
                RcfFilter_ZlibCompressionStateless,
                false);

        ZlibStatefulCompressionFilter::spFilterDescription =
            new FilterDescription(
                "Zlib stateful compression filter",
                RcfFilter_ZlibCompressionStateful,
                false);
    }
    void AsioSessionState::onAccept(
        const boost::system::error_code& error)
    {
        RCF2_TRACE("")(this);

        if (mTransport.mStopFlag)
        {
            return;
        }

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

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

            // set current RCF session
            SetCurrentSessionGuard guard(mSessionPtr);

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

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

                if (allowConnect)
                {
                    // start things rolling by faking a completed write operation
                    onReadWrite(0, boost::system::error_code());
                }
                else
                {
                    sendServerError(RcfError_ConnectionLimitExceeded);
                }
            }
        }
        else if (
            error == boost::asio::error::connection_aborted ||
            error == boost::asio::error::operation_aborted)
        {
            invokeAsyncAccept();
        }
    }
예제 #30
0
 void ContextRead::add(void *ptr, const std::type_info &objType, void *pObj)
 {
     RCF_ASSERT(mEnabled);
     if (mTypeToObjMap.get() == NULL)
     {
         mTypeToObjMap.reset( new std::map<std::string, std::map< void *, void * > >() );
     }
     (*mTypeToObjMap)[ objType.name() ][ ptr ] = pObj;
 }