Exemple #1
0
std::map<std::string, int> _createPortMap(int argCount, char** arguments) {
    auto portMap = std::map<string, int>();
    for(auto i = 1; i < argCount; i++) {
        portMap.insert(_getPort(arguments[i]));
    }
    return portMap;
}
Exemple #2
0
    void ClientStore::_enumerateStreamBuffers(std::vector<BufferId>& out) const
    {
        Message response = {0};
        ClientPort& port = _getPort();

        port.call(&response, RpcApi::CCV_StreamBufferEnumerate);

        uint32_t n = response.parameter0;

        ThrowOn((response.payloadType != MessagePayloadType::MptData) ||
                ((response.data.payloadLength % sizeof(BufferId)) != 0) ||
                (response.data.payloadLength / sizeof(BufferId) != n),
                RpcMessageMalformedException);

        if (n > 0) {
            assert(response.data.payload != nullptr);
            assert(n <= SIMUTRACE_STORE_MAX_NUM_STREAMBUFFERS);
            BufferId* buffer = reinterpret_cast<BufferId*>(response.data.payload);

            std::vector<BufferId> ids(buffer, buffer + n);
            std::swap(ids, out);
        } else {
            out.clear();
        }
    }
Exemple #3
0
    ClientStore::~ClientStore()
    {
        try {
            // We first flush all streams to get any pending data to the server.
            // Afterwards, we can close the store. The server will process the
            // data we send here (and any other pending data), before closing
            // the server instance of the store.
            std::vector<Stream*> streams;
            this->Store::_enumerateStreams(streams, StreamEnumFilter::SefAll);

            for (auto i = 0; i < streams.size(); ++i) {
                assert(streams[i] != nullptr);
                ClientStream* stream = reinterpret_cast<ClientStream*>(streams[i]);

                stream->flush();
            }

            ClientPort& port = _getPort();

            port.call(nullptr, RpcApi::CCV_StoreClose);
        } catch (const std::exception& e) {
            // There is nothing we can do about it. So just log a message and
            // destroy the client store.
            LogError("Could not rundown store. Data may have been lost. "
                     "The exception is '%s'", e.what());
        }
    }
Exemple #4
0
    std::unique_ptr<StreamBuffer> ClientStore::_createStreamBuffer(
        size_t segmentSize, uint32_t numSegments)
    {
        Message response = {0};
        ClientPort& port = _getPort();
        std::unique_ptr<StreamBuffer> buffer = nullptr;

        port.call(&response, RpcApi::CCV_StreamBufferRegister, numSegments,
                  static_cast<uint64_t>(segmentSize));

        BufferId id = static_cast<BufferId>(response.parameter0);

        // If the payload contains handles, the connection between the
        // server and the client supports shared memory buffers.
        if (response.payloadType == MessagePayloadType::MptHandles) {
            assert(response.handles.handles != nullptr);
            assert(response.handles.handles->size() ==
                   response.handles.handleCount);

            ThrowOn(response.handles.handleCount != 1,
                    RpcMessageMalformedException);

            Handle& bufferHandle = response.handles.handles->at(0);

            buffer = std::unique_ptr<StreamBuffer>(
                     new StreamBuffer(id, segmentSize, numSegments,
                                      bufferHandle));
        } else {
            buffer = std::unique_ptr<StreamBuffer>(
                     new StreamBuffer(id, segmentSize, numSegments, false));
        }

        return buffer;
    }
Exemple #5
0
    Stream* ClientStore::_replicateStream(StreamId stream)
    {
        assert(stream < _dynamicStreamIdBoundary);

        Message response = {0};
        ClientPort& port = _getPort();

        port.call(&response, RpcApi::CCV_StreamQuery, stream);

        ThrowOn((response.payloadType != MessagePayloadType::MptData) ||
                (response.data.payloadLength != sizeof(StreamQueryInformation)),
                RpcMessageMalformedException);

        assert(response.data.payload != nullptr);

        StreamBuffer* buffer = _getStreamBuffer(response.parameter0);
        ThrowOnNull(buffer, NotFoundException,
                    stringFormat("stream buffer with id %d",
                     response.parameter0));

        StreamQueryInformation* desc =
            reinterpret_cast<StreamQueryInformation*>(response.data.payload);

        std::unique_ptr<Stream> str(new StaticStream(stream, desc->descriptor,
                                                     *buffer, getSession()));

        Stream* pstr = str.get(); // Make a shortcut for the return value
        _addStream(str);

        return pstr;
    }
BuddyPtr TCPAccountHandler::constructBuddy(const PropertyMap& props)
{
	UT_DEBUGMSG(("TCPAccountHandler::constructBuddy()\n"));

	PropertyMap::const_iterator hi = props.find("server");
	UT_return_val_if_fail(hi != props.end(), BuddyPtr());
	UT_return_val_if_fail(hi->second.size() > 0, BuddyPtr());

	UT_sint32 port = _getPort(props);
	UT_return_val_if_fail(port != -1, BuddyPtr());
	
	UT_DEBUGMSG(("Constructing TCP Buddy (host: %s, port: %d)\n", hi->second.c_str(), port));
	return boost::shared_ptr<TCPBuddy>(new TCPBuddy(this, hi->second, boost::lexical_cast<std::string>(port)));
}
Exemple #7
0
    std::unique_ptr<Stream> ClientStore::_createStream(StreamId id,
        StreamDescriptor& desc, BufferId buffer)
    {
        assert(id == INVALID_STREAM_ID);

        Message response = {0};
        ClientPort& port = _getPort();

        StreamBuffer* buf = _getStreamBuffer(buffer);
        ThrowOnNull(buf, NotFoundException,
                    stringFormat("stream buffer with id %d", buffer));

        if (IsSet(desc.flags, SfDynamic)) {
            const DynamicStreamDescriptor& dyndesc =
                reinterpret_cast<DynamicStreamDescriptor&>(desc);

            // For regular streams the server generates a valid id. For
            // dynamic streams we have to do this on our own, as dynamic
            // streams are local to the client. The ids must not collide!
            // The server generates ids for regular streams in the lower
            // positive integer range. We therefore generate the ids for
            // dynamic streams in the high positive integer range. The
            // limit for the number of streams (see Version.h) prevents a
            // collision.
            StreamId sid = --_dynamicStreamIdBoundary;

        #ifdef _DEBUG
            std::vector<StreamId> ids;
            _enumerateStreams(ids, StreamEnumFilter::SefRegular);

            StreamId max = *std::max_element(ids.cbegin(), ids.cend());
            assert(max < sid);
        #endif

            return std::unique_ptr<Stream>(
                    new DynamicStream(sid, dyndesc, *buf, getSession()));
        } else {
            port.call(&response, RpcApi::CCV_StreamRegister, &desc,
                      sizeof(StreamDescriptor), buffer);

            StreamId rid = static_cast<StreamId>(response.parameter0);

            return std::unique_ptr<Stream>(
                        new StaticStream(rid, desc, *buf, getSession()));
        }
    }
Exemple #8
0
    void ClientStore::_enumerateStreams(std::vector<StreamId>& out,
                                        StreamEnumFilter filter) const
    {
        std::vector<StreamId> ids;

        // Request the ids for the static streams. Since we are replicating
        // static streams on-demand, we cannot just query our local store but
        // must ask the server.
        Message response = {0};
        ClientPort& port = _getPort();

        port.call(&response, RpcApi::CCV_StreamEnumerate, filter);

        uint32_t n = response.parameter0;

        ThrowOn((response.payloadType != MessagePayloadType::MptData) ||
                ((response.data.payloadLength % sizeof(StreamId)) != 0) ||
                (response.data.payloadLength / sizeof(StreamId) != n),
                RpcMessageMalformedException);

        if (n > 0) {
            assert(response.data.payload != nullptr);
            assert(n <= SIMUTRACE_STORE_MAX_NUM_STREAMS);
            StreamId* buffer = reinterpret_cast<StreamId*>(response.data.payload);

            ids.assign(buffer, buffer + n);
        }

        // Now add the dynamic streams that this client session possesses.
        std::vector<Stream*> dynStreams;
        this->Store::_enumerateStreams(dynStreams, StreamEnumFilter::SefDynamic);
        for (auto stream : dynStreams) {
            assert(IsSet(stream->getFlags(), StreamFlags::SfDynamic));
            assert(!IsSet(stream->getFlags(), StreamFlags::SfHidden));

            ids.push_back(stream->getId());
        }

        std::swap(ids, out);
    }
Exemple #9
0
    ClientStore::ClientStore(ClientSession& session, const std::string& name,
                             bool alwaysCreate, bool open) :
        Store(CLIENT_STORE_ID, name),
        ClientObject(session),
        _dynamicStreamIdBoundary(INVALID_STREAM_ID)
    {
        Message response = {0};
        ClientPort& port = _getPort();

        // Send the request to open the store
        port.call(&response, RpcApi::CCV_StoreCreate, name,
                  (alwaysCreate && !open) ? _true : _false,
                  (open) ? _true : _false);

        try {
            _replicateConfiguration();

        } catch (...) {
            port.call(nullptr, RpcApi::CCV_StoreClose);

            throw;
        }
    }
Exemple #10
0
    StreamBuffer* ClientStore::_replicateStreamBuffer(BufferId buffer)
    {
        Message response = {0};
        ClientPort& port = _getPort();
        std::unique_ptr<StreamBuffer> buf;

        port.call(&response, RpcApi::CCV_StreamBufferQuery, buffer, _true);

        uint32_t numSegments = response.parameter0;
        size_t segmentSize   = response.handles.parameter1;

        // If the payload contains handles, the connection between the
        // server and the client supports shared memory buffers.
        if (response.payloadType == MessagePayloadType::MptHandles) {
            assert(response.handles.handles != nullptr);
            assert(response.handles.handles->size() ==
                   response.handles.handleCount);

            ThrowOn(response.handles.handleCount != 1,
                    RpcMessageMalformedException);

            Handle& bufferHandle = response.handles.handles->at(0);

            buf = std::unique_ptr<StreamBuffer>(
                    new StreamBuffer(buffer, segmentSize, numSegments,
                                     bufferHandle));
        } else {
            buf = std::unique_ptr<StreamBuffer>(
                    new StreamBuffer(buffer, segmentSize, numSegments, false));
        }

        StreamBuffer* pbuf = buf.get(); // Make a shortcut for the return value
        _addStreamBuffer(buf);

        return pbuf;
    }
Exemple #11
0
unsigned int _ossSocket::getPeerPort ()
{
   return _getPort ( &_peerAddress ) ;
}
Exemple #12
0
unsigned int _ossSocket::getLocalPort ()
{
   return _getPort ( &_sockAddress ) ;
}
ConnectResult TCPAccountHandler::connect()
{
	UT_DEBUGMSG(("TCPAccountHandler::connect()\n"));

	AbiCollabSessionManager* pManager = AbiCollabSessionManager::getManager();
	UT_return_val_if_fail(pManager, CONNECT_INTERNAL_ERROR);

	UT_return_val_if_fail(!m_pDelegator, CONNECT_INTERNAL_ERROR);
	UT_return_val_if_fail(!m_bConnected, CONNECT_ALREADY_CONNECTED);
	UT_return_val_if_fail(!m_thread, CONNECT_INTERNAL_ERROR);
	m_io_service.reset();
	m_thread = new asio::thread(boost::bind(&asio::io_service::run, &m_io_service));

	// set up the connection
	if (getProperty("server") == "")
	{
		UT_sint32 port = _getPort(getProperties());
		UT_DEBUGMSG(("Start accepting connections on port %d...\n", port));

		try
		{
			IOServerHandler* pDelegator = new IOServerHandler(port, 
						boost::bind(&TCPAccountHandler::_handleAccept, this, _1, _2),
						boost::bind(&TCPAccountHandler::handleEvent, this, _1), m_io_service);
			m_pDelegator = pDelegator;
			m_bConnected = true; // todo: ask it to the acceptor
			pDelegator->run();
		}
		catch (asio::system_error se)
		{
			UT_DEBUGMSG(("Failed to start accepting connections: %s\n", se.what()));
			_teardownAndDestroyHandler();
			return CONNECT_FAILED;
		}
		catch (...)
		{
			UT_DEBUGMSG(("Caught unhandled server exception!\n"));
			_teardownAndDestroyHandler();
			return CONNECT_FAILED;
		}
	}
	else
	{
		UT_DEBUGMSG(("Connecting to server %s on port %d...\n", getProperty("server").c_str(), _getPort(getProperties())));

		try
		{
			asio::ip::tcp::resolver resolver(m_io_service);
			asio::ip::tcp::resolver::query query(getProperty("server"), getProperty("port"));
			asio::ip::tcp::resolver::iterator iterator(resolver.resolve(query));

			bool connected = false;
			boost::shared_ptr<Session> session_ptr(new Session(m_io_service, boost::bind(&TCPAccountHandler::handleEvent, this, _1)));
			while (iterator != tcp::resolver::iterator())
			{
				try
				{
					UT_DEBUGMSG(("Attempting to connect...\n"));
					session_ptr->connect(iterator);
					UT_DEBUGMSG(("Connected!\n"));
					connected = true;
					break;
				}
				catch (asio::system_error se)
				{
					UT_DEBUGMSG(("Connection attempt failed: %s\n", se.what()));
					// make sure we close the socket after a failed attempt, as it
					// may have been opened by the connect() call.
					try { session_ptr->getSocket().close(); } catch(...) {}
				}
				iterator++;
			}

			if (!connected)
			{
				UT_DEBUGMSG(("Giving up to connecting to server!\n"));
				_teardownAndDestroyHandler();
				return CONNECT_FAILED;
			}

			session_ptr->asyncReadHeader();
			m_bConnected = true; // todo: ask it to the socket
			// Add a buddy
			TCPBuddyPtr pBuddy = boost::shared_ptr<TCPBuddy>(new TCPBuddy(this, 
						session_ptr->getRemoteAddress(),
						boost::lexical_cast<std::string>(session_ptr->getRemotePort())));
			addBuddy(pBuddy);
			m_clients.insert(std::pair<TCPBuddyPtr, boost::shared_ptr<Session> >(pBuddy, session_ptr));
		}
		catch (asio::system_error se)
		{
			UT_DEBUGMSG(("Failed to resolve %s:%d: %s\n", getProperty("server").c_str(), _getPort(getProperties()), se.what()));
			_teardownAndDestroyHandler();
			return CONNECT_FAILED;
		}
	}
	
	if (!m_bConnected)
		return CONNECT_FAILED;

	// we are connected now, time to start sending out messages (such as events)
	pManager->registerEventListener(this);
	// signal all listeners we are logged in
	AccountOnlineEvent event;
	// TODO: fill the event
	AbiCollabSessionManager::getManager()->signal(event);

	return CONNECT_SUCCESS;
}
Exemple #14
0
bool SocketConnection::listen()
{
    ConnectionDescriptionPtr description = _getDescription();
    LBASSERT( description->type == CONNECTIONTYPE_TCPIP ||
              description->type == CONNECTIONTYPE_SDP );

    if( !isClosed( ))
        return false;

    _setState( STATE_CONNECTING );

    sockaddr_in address;
    const size_t size = sizeof( sockaddr_in );

    if( !_parseAddress( description, address ))
    {
        LBWARN << "Can't parse connection parameters" << std::endl;
        return false;
    }

    if( !_createSocket())
        return false;

    const bool bound = (::bind( _readFD, (sockaddr *)&address, size ) == 0);

    if( !bound )
    {
        LBWARN << "Could not bind socket " << _readFD << ": "
               << lunchbox::sysError << " to " << inet_ntoa( address.sin_addr )
               << ":" << ntohs( address.sin_port ) << " AF "
               << (int)address.sin_family << std::endl;

        close();
        return false;
    }
    else if( address.sin_port == 0 )
        LBINFO << "Bound to port " << _getPort() << std::endl;

    const bool listening = (::listen( _readFD, SOMAXCONN ) == 0);

    if( !listening )
    {
        LBWARN << "Could not listen on socket: " << lunchbox::sysError
               << std::endl;
        close();
        return false;
    }

    // get socket parameters
    socklen_t used = size;
    getsockname( _readFD, (struct sockaddr *)&address, &used );

    description->port = ntohs( address.sin_port );

    std::string hostname = description->getHostname();
    if( hostname.empty( ))
    {
        if( address.sin_addr.s_addr == INADDR_ANY )
        {
            char cHostname[256] = {0};
            gethostname( cHostname, 256 );
            hostname = cHostname;

            description->setHostname( hostname );
        }
        else
            description->setHostname( inet_ntoa( address.sin_addr ));
    }
#ifndef _WIN32
    //fcntl( _readFD, F_SETFL, O_NONBLOCK );
#endif
    _initAIOAccept();
    _setState( STATE_LISTENING );

    LBINFO << "Listening on " << description->getHostname() << "["
           << inet_ntoa( address.sin_addr ) << "]:" << description->port
           << " (" << description->toString() << ")" << std::endl;

    return true;
}
Exemple #15
0
UINT32 _ossSocket::getPeerPort ()
{
   return _getPort ( &_peerAddress ) ;
}
Exemple #16
0
UINT32 _ossSocket::getLocalPort ()
{
   return _getPort ( &_sockAddress ) ;
}