Esempio n. 1
0
 ReadWriteMutex::ReadWriteMutex(ReadWritePriority rwsp) :
     readerCount()
 {
     RCF_UNUSED_VARIABLE(rwsp);
 }
    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));
                SessionPtr sessionPtr = getSessionManager().createSession();
                sessionPtr->setSessionState(*sessionStatePtr);
                sessionStatePtr->mSessionPtr = sessionPtr;
                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 * asio_handler_allocate(std::size_t size, AmiTimerHandler * pHandler)
 {
     RCF_UNUSED_VARIABLE(pHandler);
     return gpAmiTimerHandlerCache->allocate(size);
 }
 void ServerObjectService::onServerStop(RcfServer & server)
 {
     RCF_UNUSED_VARIABLE(server);
     mpRcfServer = NULL;
     mPeriodicTimer.stop();
 }
Esempio n. 5
0
 void PublishingService::onServerStart(RcfServer &server)
 {
     RCF_UNUSED_VARIABLE(server);
     mPeriodicTimer.setIntervalMs(mPingIntervalMs);
     mPeriodicTimer.start();
 }
 void asio_handler_deallocate(void * pointer, std::size_t size, AmiIoHandler * pHandler)
 {
     RCF_UNUSED_VARIABLE(pHandler);
     return gpAmiIoHandlerCache->deallocate(pointer, size);
 }
 void MulticastClientTransport::disconnect(unsigned int timeoutMs)
 {
     RCF_UNUSED_VARIABLE(timeoutMs);
 }
Esempio n. 8
0
 read_write_mutex(read_write_scheduling_policy rwsp) :
     readerCount(RCF_DEFAULT_INIT)
 {
     RCF_UNUSED_VARIABLE(rwsp);
 }
    int MulticastClientTransport::send(
        ClientTransportCallback &           clientStub,
        const std::vector<ByteBuffer> &     data,
        unsigned int                        timeoutMs)
    {
        // NB: As the same buffer is sent on all transports, the transports and
        // filters should never modify the buffer. Any transport that transforms
        // data needs to do so in a separate per-transport buffer.

        RCF_UNUSED_VARIABLE(timeoutMs);

        RCF_LOG_2()(lengthByteBuffers(data))(timeoutMs) 
            << "MulticastClientTransport::send() - entry.";

        mLastRequestSize = lengthByteBuffers(data);
        mRunningTotalBytesSent += mLastRequestSize;

        bringInNewTransports();

        Lock lock(mClientTransportsMutex);

        std::size_t transportsInitial = mClientTransports.size();

        PublishCompletionInfo info( mClientTransports.size() );

        // Setup completion handlers.
        std::vector<PublishCompletionHandler> handlers( mClientTransports.size() );
        for (std::size_t i=0; i<mClientTransports.size(); ++i)
        {
            ClientTransport * pTransport = (*mClientTransports[i]).get();
            handlers[i] = PublishCompletionHandler(pTransport, &info);
        }

        // Async send on all transports.
        for (std::size_t i=0; i<handlers.size(); ++i)
        {
            try
            {

                handlers[i].mpClientTransport->setAsync(true);
                handlers[i].mpClientTransport->send(handlers[i], data, 0);
            }
            catch(const Exception &e)
            {
                Exception err( _RcfError_SyncPublishError(e.what()) );
                handlers[i].onError(err);
            }
        }

        // Wait for async completions.
        boost::uint32_t completionDurationMs = 0;
        {
            Timer timer;
            info.wait(timeoutMs);
            completionDurationMs = timer.getDurationMs();
        }

        // Cancel any outstanding sends.
        for (std::size_t i=0; i<handlers.size(); ++i)
        {
            if (!handlers[i].mCompleted)
            {
                (*mClientTransports[i])->cancel();

                RCF_LOG_2()(i)
                    << "MulticastClientTransport::send() - cancel send.";
            }
        }

        // Wait for canceled ops to complete.
        boost::uint32_t cancelDurationMs = 0;
        {
            Timer timer;
            info.wait(timeoutMs);
            cancelDurationMs = timer.getDurationMs();
        }

        RCF_ASSERT(info.getCompletionCount() == handlers.size());

        // Close and remove any subscriber transports with errors.
        std::size_t transportsRemoved = 0;
        for (std::size_t i=0; i<handlers.size(); ++i)
        {
            RCF_ASSERT(handlers[i].mCompleted);
            if (!handlers[i].mOk)
            {
                mClientTransports[i] = ClientTransportAutoPtrPtr();
                ++transportsRemoved;

                RCF_LOG_2()(i)(handlers[i].mCompleted)(handlers[i].mOk)(handlers[i].mError) 
                    << "MulticastClientTransport::send() - remove subscriber transport.";
            }
        }
        eraseRemove(mClientTransports, ClientTransportAutoPtrPtr());

        clientStub.onSendCompleted();

        std::size_t transportsFinal = transportsInitial - transportsRemoved;

        RCF_LOG_2()
            (lengthByteBuffers(data))(completionDurationMs)(cancelDurationMs)(transportsInitial)(transportsFinal)
            << "MulticastClientTransport::send() - exit.";

        return 1;
    }
 void MulticastClientTransport::connect(ClientTransportCallback &clientStub, unsigned int timeoutMs)
 {
     RCF_UNUSED_VARIABLE(clientStub);
     RCF_UNUSED_VARIABLE(timeoutMs);
     clientStub.onConnectCompleted(true);
 }
 void onConnectCompleted(bool alreadyConnected = false)
 {
     RCF_UNUSED_VARIABLE(alreadyConnected);
     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);
        }

    }
Esempio n. 13
0
 void XorFilter::onWriteCompleted(std::size_t bytesTransferred, int error)
 {
     RCF_UNUSED_VARIABLE(error);
     // TODO: error handling
     getPreFilter().onWriteCompleted(bytesTransferred, 0);
 }
Esempio n. 14
0
 void UdpSessionState::getTransportFilters(std::vector<FilterPtr> &filters)
 {
     RCF_UNUSED_VARIABLE(filters);
     RCF_ASSERT(0);
 }
Esempio n. 15
0
        void cancelConnect(int fd)
        {
			RCF_UNUSED_VARIABLE(fd);
        }
Esempio n. 16
0
 void PingBackService::onServiceRemoved(RcfServer &server)
 {
     RCF_UNUSED_VARIABLE(server);
 }
Esempio n. 17
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

            //int myErr = WSAGetLastError();
            //int myErr = Platform::OS::BsdSockets::GetLastError()
            //if (ret == 0)
            if (count >= 0)
            {
                RCF_ASSERT_LTEQ(count , static_cast<int>(bytesRemaining));

                bytesRemaining -= count;//cbSent;
                bytesSent += count;//cbSent;
                err = 0;
                return static_cast<int>(bytesSent);
            }
            //else if (myErr == WSAEWOULDBLOCK)
            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;
            }


        }
    }