Beispiel #1
0
void Connection::readyReadHandler()
{
    while (m_socket->bytesAvailable()) {
        if (!m_currentMessageSize) {
            size_t numberOfBytesRead = m_socket->read(reinterpret_cast<char*>(m_readBuffer.data()), sizeof(size_t));
            ASSERT_UNUSED(numberOfBytesRead, numberOfBytesRead);
            m_currentMessageSize = *reinterpret_cast<size_t*>(m_readBuffer.data());
        }

        if (m_socket->bytesAvailable() < m_currentMessageSize)
            return;

        if (m_readBuffer.size() < m_currentMessageSize)
            m_readBuffer.grow(m_currentMessageSize);

        size_t numberOfBytesRead = m_socket->read(reinterpret_cast<char*>(m_readBuffer.data()), m_currentMessageSize);
        ASSERT_UNUSED(numberOfBytesRead, numberOfBytesRead);

        // The messageID is encoded at the end of the buffer.
        size_t realBufferSize = m_currentMessageSize - sizeof(uint32_t);
        uint32_t messageID = *reinterpret_cast<uint32_t*>(m_readBuffer.data() + realBufferSize);

        processIncomingMessage(MessageID::fromInt(messageID), adoptPtr(new ArgumentDecoder(m_readBuffer.data(), realBufferSize)));

        m_currentMessageSize = 0;
    }
}
Beispiel #2
0
void Connection::processCompletedMessage()
{
    size_t realBufferSize = m_currentMessageSize - sizeof(MessageID);
    unsigned messageID = *reinterpret_cast<unsigned*>(m_readBuffer.data() + realBufferSize);

    processIncomingMessage(MessageID::fromInt(messageID), adoptPtr(new ArgumentDecoder(m_readBuffer.data(), realBufferSize)));

    // Prepare for the next message.
    m_currentMessageSize = 0;
    m_pendingBytes = 0;
}
void startFlushProcess()
{
	int status, sendStatus = 0, recvStatus = 0;
	boolean breakFl = FALSE;
	while (!breakFl)
	{
		sendStatus = 0;
		recvStatus = 0;

		recvStatus = processIncomingMessage();
		if (recvStatus == SOCKET_ERROR)
		{
			onHandleSocketError(recvStatus);
			break;
		}

		onChangeStatus(WAITING);
		status = syncInterface.onTryConsumerEntry(CONSUMER_WAIT_SECONDS * 1000);

		if (status == WAIT_OBJECT_0)
		{
			onChangeStatus(ACCUMULATING);
			MSG_LOCATION_ID id = syncInterface.onStartConsume();

			int totalMsg, totalMsgSize;
			char* msg;

			boolean pending = TRUE;
			
			onChangeStatus(NORMAL);
			while (pending)
			{
				pending = msgStore.retrieveMsg(id, &totalMsg, &totalMsgSize, &msg);

				if (totalMsg > 0)
				{
					sendStatus = onSendMessage(&msg, &totalMsgSize);
					free(msg);
					if (sendStatus == SOCKET_ERROR)
					{
						onHandleSocketError(sendStatus);
						breakFl = TRUE;
						break;
					}
				}
			}
		}
	}
}
Beispiel #4
0
void Connection::receiveSourceEventHandler()
{
    ReceiveBuffer buffer;

    mach_msg_header_t* header = readFromMachPort(m_receivePort, buffer);
    if (!header)
        return;

    MessageID messageID = MessageID::fromInt(header->msgh_id);
    OwnPtr<ArgumentDecoder> arguments = createArgumentDecoder(header);
    ASSERT(arguments);

    if (messageID == MessageID(CoreIPCMessage::InitializeConnection)) {
        ASSERT(m_isServer);
        ASSERT(!m_isConnected);
        ASSERT(!m_sendPort);

        MachPort port;
        if (!arguments->decode(port)) {
            // FIXME: Disconnect.
            return;
        }

        m_sendPort = port.port();
        
        // Set the dead name source if needed.
        if (m_sendPort)
            initializeDeadNameSource();
        
        m_isConnected = true;

        // Send any pending outgoing messages.
        sendOutgoingMessages();
        
        return;
    }

    if (messageID == MessageID(CoreIPCMessage::SetExceptionPort)) {
        MachPort exceptionPort;
        if (!arguments->decode(exceptionPort))
            return;

        setMachExceptionPort(exceptionPort.port());
        return;
    }

    processIncomingMessage(messageID, arguments.release());
}    
Beispiel #5
0
void Connection::receiveSourceEventHandler()
{
    char buffer[inlineMessageMaxSize];
    
    mach_msg_header_t* header = reinterpret_cast<mach_msg_header_t*>(&buffer);
    
    kern_return_t kr = mach_msg(header, MACH_RCV_MSG | MACH_RCV_LARGE | MACH_RCV_TIMEOUT, 0, sizeof(buffer), m_receivePort, 0, MACH_PORT_NULL);
    if (kr == MACH_RCV_TIMED_OUT)
        return;

    if (kr != MACH_MSG_SUCCESS) {

        ASSERT_NOT_REACHED();
        // FIXME: Handle MACH_RCV_MSG_TOO_LARGE.
        return;
    }
    
    MessageID messageID = MessageID::fromInt(header->msgh_id);
    std::auto_ptr<ArgumentDecoder> arguments = createArgumentDecoder(header);
    ASSERT(arguments.get());

    if (messageID == MessageID(CoreIPCMessage::InitializeConnection)) {
        ASSERT(m_isServer);
        ASSERT(!m_isConnected);
        ASSERT(!m_sendPort);

        MachPort port;
        if (!arguments->decode(port)) {
            // FIXME: Disconnect.
            return;
        }

        m_sendPort = port.port();
        
        // Set the dead name source if needed.
        if (m_sendPort)
            initializeDeadNameSource();
        
        m_isConnected = true;

        // Send any pending outgoing messages.
        sendOutgoingMessages();
        
        return;
    }
    
    processIncomingMessage(messageID, arguments);
}    
void NTStatsServer::run(void)
{
    int timeout = 1000;          // milliseconds
    while (this->wasTerminated() == PR_FALSE)
    {
        BOOL fWaitAny = FALSE; // Wait any of the poll items.
        DWORD dwWaitReturnVal = MsgWaitForMultipleObjects(nPollItems_,
                                                          pollEvents_,
                                                          fWaitAny,
                                                          timeout,
                                                          QS_ALLEVENTS);
        if (dwWaitReturnVal == WAIT_TIMEOUT)
        {
            // Timeout.
            updateTimeoutStats();
            continue;
        }
        int index = dwWaitReturnVal - WAIT_OBJECT_0;
        if (index == nPollItems_)
        {
            // Special case of return value
            // do nothing and just continue
            MSG msg;
            PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
            continue;
        }
        if ((index < 0) || (index > nPollItems_))
        {
            PR_ASSERT(0);
            return;
        }

        processIncomingMessage(index);
        removeInvalidItems();
        PR_ASSERT(nPollItems_ >= 0);
        if (nPollItems_ == 0)
        {
            // Create a new stats channel.
            if (createStatsChannel() != PR_TRUE)
            {
                ereport(LOG_FAILURE,
                        XP_GetAdminStr(DBT_NTStatsServer_ErrorChannelCreation));
                return;
            }
        }
    }
}
/**
 * parsePacket()
 * This function will be called after reading the incoming raw bytes on the socket
 * Input : pointer to source buffer, that was filled from socket
 * Output : parsing result.
 */
long CPlayer::parsePacket(unsigned char *pSrc, unsigned long nLen)
{
    tictacpacket thePacket;
    cout << "I am inside Function " << __func__ << endl;

    if(thePacket.ParseFromArray(pSrc, nLen))
    {
	// If parse is successful, then proceed to process the packet
	processIncomingMessage(thePacket);
	return 0; // success
    }
    else
    {
        cout << "ERROR: thePacket.ParseFromArray Failed in Function " << __func__ << "Line = " << __LINE__ << endl;
	return -1; // Failure
    }
}
Beispiel #8
0
void Communicator::onIncomingData()
{
    if (!mSocket.isValid()) {
        return;
    }

    QByteArray const &data = mSocket.readAll();
    mBuffer.append(data);

    while (!mBuffer.isEmpty()) {
        if (mExpectedBytes == 0) {
            // Determining the length of a message.
            int const delimiterIndex = mBuffer.indexOf(':');
            if (delimiterIndex == -1) {
                // We did not receive full message length yet.
                return;
            } else {
                QByteArray const length = mBuffer.left(delimiterIndex);
                mBuffer = mBuffer.mid(delimiterIndex + 1);
                bool ok;
                mExpectedBytes = length.toInt(&ok);
                if (!ok) {
                    qDebug() << "Malformed message, can not determine message length from this:" << length;
                    mExpectedBytes = 0;
                }
            }
        } else {
            if (mBuffer.size() >= mExpectedBytes) {
                QByteArray const message = mBuffer.left(mExpectedBytes);
                mBuffer = mBuffer.mid(mExpectedBytes);

                processIncomingMessage(message);

                mExpectedBytes = 0;
            } else {
                // We don't have all message yet.
                return;
            }
        }
    }
}
Beispiel #9
0
void Connection::readEventHandler()
{
    if (m_connectionPipe == INVALID_HANDLE_VALUE)
        return;

    while (true) {
        // Check if we got some data.
        DWORD numberOfBytesRead = 0;
        if (!::GetOverlappedResult(m_connectionPipe, &m_readState, &numberOfBytesRead, FALSE)) {
            DWORD error = ::GetLastError();

            switch (error) {
            case ERROR_BROKEN_PIPE:
                connectionDidClose();
                return;
            case ERROR_MORE_DATA: {
                // Read the rest of the message out of the pipe.

                DWORD bytesToRead = 0;
                if (!::PeekNamedPipe(m_connectionPipe, 0, 0, 0, 0, &bytesToRead)) {
                    DWORD error = ::GetLastError();
                    if (error == ERROR_BROKEN_PIPE) {
                        connectionDidClose();
                        return;
                    }
                    ASSERT_NOT_REACHED();
                    return;
                }

                // ::GetOverlappedResult told us there's more data. ::PeekNamedPipe shouldn't
                // contradict it!
                ASSERT(bytesToRead);
                if (!bytesToRead)
                    break;

                m_readBuffer.grow(m_readBuffer.size() + bytesToRead);
                if (!::ReadFile(m_connectionPipe, m_readBuffer.data() + numberOfBytesRead, bytesToRead, 0, &m_readState)) {
                    DWORD error = ::GetLastError();
                    ASSERT_NOT_REACHED();
                    return;
                }
                continue;
            }

            // FIXME: We should figure out why we're getting this error.
            case ERROR_IO_INCOMPLETE:
                return;
            default:
                ASSERT_NOT_REACHED();
            }
        }

        if (!m_readBuffer.isEmpty()) {
            // We have a message, let's dispatch it.

            // The messageID is encoded at the end of the buffer.
            // Note that we assume here that the message is the same size as m_readBuffer. We can
            // assume this because we always size m_readBuffer to exactly match the size of the message,
            // either when receiving ERROR_MORE_DATA from ::GetOverlappedResult above or when
            // ::PeekNamedPipe tells us the size below. We never set m_readBuffer to a size larger
            // than the message.
            ASSERT(m_readBuffer.size() >= sizeof(MessageID));
            size_t realBufferSize = m_readBuffer.size() - sizeof(MessageID);

            unsigned messageID = *reinterpret_cast<unsigned*>(m_readBuffer.data() + realBufferSize);

            OwnPtr<MessageDecoder> decoder = MessageDecoder::create(DataReference(m_readBuffer.data(), realBufferSize));
            processIncomingMessage(MessageID::fromInt(messageID), decoder.release());
        }

        // Find out the size of the next message in the pipe (if there is one) so that we can read
        // it all in one operation. (This is just an optimization to avoid an extra pass through the
        // loop (if we chose a buffer size that was too small) or allocating extra memory (if we
        // chose a buffer size that was too large).)
        DWORD bytesToRead = 0;
        if (!::PeekNamedPipe(m_connectionPipe, 0, 0, 0, 0, &bytesToRead)) {
            DWORD error = ::GetLastError();
            if (error == ERROR_BROKEN_PIPE) {
                connectionDidClose();
                return;
            }
            ASSERT_NOT_REACHED();
        }
        if (!bytesToRead) {
            // There's no message waiting in the pipe. Schedule a read of the first byte of the
            // next message. We'll find out the message's actual size when it arrives. (If we
            // change this to read more than a single byte for performance reasons, we'll have to
            // deal with m_readBuffer potentially being larger than the message we read after
            // calling ::GetOverlappedResult above.)
            bytesToRead = 1;
        }

        m_readBuffer.resize(bytesToRead);

        // Either read the next available message (which should occur synchronously), or start an
        // asynchronous read of the next message that becomes available.
        BOOL result = ::ReadFile(m_connectionPipe, m_readBuffer.data(), m_readBuffer.size(), 0, &m_readState);
        if (result) {
            // There was already a message waiting in the pipe, and we read it synchronously.
            // Process it.
            continue;
        }

        DWORD error = ::GetLastError();

        if (error == ERROR_IO_PENDING) {
            // There are no messages in the pipe currently. readEventHandler will be called again once there is a message.
            return;
        }

        if (error == ERROR_MORE_DATA) {
            // Either a message is available when we didn't think one was, or the message is larger
            // than ::PeekNamedPipe told us. The former seems far more likely. Probably the message
            // became available between our calls to ::PeekNamedPipe and ::ReadFile above. Go back
            // to the top of the loop to use ::GetOverlappedResult to retrieve the available data.
            continue;
        }

        // FIXME: We need to handle other errors here.
        ASSERT_NOT_REACHED();
    }
}
bool Connection::processMessage()
{
    if (m_readBufferSize < sizeof(MessageInfo))
        return false;

    uint8_t* messageData = m_readBuffer.data();
    MessageInfo messageInfo;
    memcpy(&messageInfo, messageData, sizeof(messageInfo));
    messageData += sizeof(messageInfo);

    size_t messageLength = sizeof(MessageInfo) + messageInfo.attachmentCount() * sizeof(AttachmentInfo) + (messageInfo.isMessageBodyIsOutOfLine() ? 0 : messageInfo.bodySize());
    if (m_readBufferSize < messageLength)
        return false;

    size_t attachmentFileDescriptorCount = 0;
    size_t attachmentCount = messageInfo.attachmentCount();
    std::unique_ptr<AttachmentInfo[]> attachmentInfo;

    if (attachmentCount) {
        attachmentInfo = std::make_unique<AttachmentInfo[]>(attachmentCount);
        memcpy(attachmentInfo.get(), messageData, sizeof(AttachmentInfo) * attachmentCount);
        messageData += sizeof(AttachmentInfo) * attachmentCount;

        for (size_t i = 0; i < attachmentCount; ++i) {
            switch (attachmentInfo[i].getType()) {
            case Attachment::MappedMemoryType:
            case Attachment::SocketType:
                if (!attachmentInfo[i].isNull())
                    attachmentFileDescriptorCount++;
                break;
            case Attachment::Uninitialized:
            default:
                ASSERT_NOT_REACHED();
                break;
            }
        }

        if (messageInfo.isMessageBodyIsOutOfLine())
            attachmentCount--;
    }

    Vector<Attachment> attachments(attachmentCount);
    AttachmentResourceGuard<Vector<Attachment>, Vector<Attachment>::iterator> attachementDisposer(attachments);
    RefPtr<WebKit::SharedMemory> oolMessageBody;

    size_t fdIndex = 0;
    for (size_t i = 0; i < attachmentCount; ++i) {
        int fd = -1;
        switch (attachmentInfo[i].getType()) {
        case Attachment::MappedMemoryType:
            if (!attachmentInfo[i].isNull())
                fd = m_fileDescriptors[fdIndex++];
            attachments[attachmentCount - i - 1] = Attachment(fd, attachmentInfo[i].getSize());
            break;
        case Attachment::SocketType:
            if (!attachmentInfo[i].isNull())
                fd = m_fileDescriptors[fdIndex++];
            attachments[attachmentCount - i - 1] = Attachment(fd);
            break;
        case Attachment::Uninitialized:
            attachments[attachmentCount - i - 1] = Attachment();
        default:
            break;
        }
    }

    if (messageInfo.isMessageBodyIsOutOfLine()) {
        ASSERT(messageInfo.bodySize());

        if (attachmentInfo[attachmentCount].isNull()) {
            ASSERT_NOT_REACHED();
            return false;
        }

        WebKit::SharedMemory::Handle handle;
        handle.adoptFromAttachment(m_fileDescriptors[attachmentFileDescriptorCount - 1], attachmentInfo[attachmentCount].getSize());

        oolMessageBody = WebKit::SharedMemory::create(handle, WebKit::SharedMemory::ReadOnly);
        if (!oolMessageBody) {
            ASSERT_NOT_REACHED();
            return false;
        }
    }

    ASSERT(attachments.size() == (messageInfo.isMessageBodyIsOutOfLine() ? messageInfo.attachmentCount() - 1 : messageInfo.attachmentCount()));

    uint8_t* messageBody = messageData;
    if (messageInfo.isMessageBodyIsOutOfLine())
        messageBody = reinterpret_cast<uint8_t*>(oolMessageBody->data());

    auto decoder = std::make_unique<MessageDecoder>(DataReference(messageBody, messageInfo.bodySize()), std::move(attachments));

    processIncomingMessage(std::move(decoder));

    if (m_readBufferSize > messageLength) {
        memmove(m_readBuffer.data(), m_readBuffer.data() + messageLength, m_readBufferSize - messageLength);
        m_readBufferSize -= messageLength;
    } else
        m_readBufferSize = 0;

    if (attachmentFileDescriptorCount) {
        if (m_fileDescriptorsSize > attachmentFileDescriptorCount) {
            size_t fileDescriptorsLength = attachmentFileDescriptorCount * sizeof(int);
            memmove(m_fileDescriptors.data(), m_fileDescriptors.data() + fileDescriptorsLength, m_fileDescriptorsSize - fileDescriptorsLength);
            m_fileDescriptorsSize -= fileDescriptorsLength;
        } else
            m_fileDescriptorsSize = 0;
    }


    return true;
}
void GatewayTask::processUserOnline(const XMPP::Jid& user, int showStatus)
{
    bool first_login = UserManager::instance()->getOption(user.bare(), "first_login").toBool();

    if ( d->icqHost.isEmpty() || !d->icqPort ) {
        qCritical("[GT] processLogin: icq host and/or port values are not set. Aborting...");
        return;
    }
    ICQ::Session::OnlineStatus icqStatus = xmmpToIcqStatus(XMPP::Presence::Show(showStatus));

    if ( d->jidIcqTable.contains( user.bare() ) ) {
        ICQ::Session *conn = d->jidIcqTable.value( user.bare() );
        conn->setOnlineStatus(icqStatus);
        d->jidResources.insert(user.bare(), user);
        return;
    }

    if ( UserManager::instance()->isRegistered(user.bare()) ) {
        QString uin = UserManager::instance()->getUin(user.bare());
        QString password = UserManager::instance()->getPassword(user.bare());

        ICQ::Session *conn = new ICQ::Session(this);
        conn->setUin(uin);
        conn->setPassword(password);
        conn->setServerHost(d->icqHost);
        conn->setServerPort(d->icqPort);
        conn->setOnlineStatus(ICQ::Session::Online);

        QObject::connect( conn, SIGNAL( statusChanged(int) ),
                          SLOT( processIcqStatus(int) ) );
        QObject::connect( conn, SIGNAL( userOnline(QString,int) ),
                          SLOT( processContactOnline(QString,int) ) );
        QObject::connect( conn, SIGNAL( userOffline(QString) ),
                          SLOT( processContactOffline(QString) ) );
        QObject::connect( conn, SIGNAL( authGranted(QString) ),
                          SLOT( processAuthGranted(QString) ) );
        QObject::connect( conn, SIGNAL( authDenied(QString) ),
                          SLOT( processAuthDenied(QString) ) );
        QObject::connect( conn, SIGNAL( authRequest(QString) ),
                          SLOT( processAuthRequest(QString) ) );
        QObject::connect( conn, SIGNAL( incomingMessage(QString,QString) ),
                          SLOT( processIncomingMessage(QString,QString) ) );
        QObject::connect( conn, SIGNAL( incomingMessage(QString,QString,QDateTime) ),
                          SLOT( processIncomingMessage(QString,QString,QDateTime) ) );
        QObject::connect( conn, SIGNAL( connected() ),
                          SLOT( processIcqSignOn() ) );
        QObject::connect( conn, SIGNAL( disconnected() ),
                          SLOT( processIcqSignOff() ) );
        QObject::connect( conn, SIGNAL( error(QString) ),
                          SLOT( processIcqError(QString) ) );
        QObject::connect( conn, SIGNAL( shortUserDetailsAvailable(QString) ),
                          SLOT( processShortUserDetails(QString) ) );

        if ( first_login ) {
            QObject::connect( conn, SIGNAL( rosterAvailable() ), SLOT( processIcqFirstLogin() ) );
        }

        d->jidIcqTable.insert(user.bare(), conn);
        d->icqJidTable.insert(conn, user.bare());
        d->jidResources.insert(user.bare(), user);

        QTextCodec *codec;
        if ( UserManager::instance()->hasOption(user.bare(), "encoding") ) {
            codec = QTextCodec::codecForName( UserManager::instance()->getOption(user.bare(), "encoding").toByteArray() );
            if ( codec == 0 ) {
                codec = QTextCodec::codecForName("windows-1251");
            }
        } else {
            codec = QTextCodec::codecForName("windows-1251");
        }
        Q_ASSERT( codec != 0 );
        conn->setCodecForMessages(codec);
        conn->connect();
    }
}
Beispiel #12
0
void RDPServerWorker::run()
{
    int ret = -1;
    zmq::pollitem_t item = {
            (void *) zsocket,
            0,
            ZMQ_POLLIN,
            0
    };

    while (true) {
        // check if we are terminating
        std::lock_guard<std::mutex> lock(stop_mutex);
        if (stop) {
            LOG(INFO) << "ServerWorker loop terminating on stop";
            initialized = false;
            return;
        }

        // send outgoing messages first
        while (!out_queue.isEmpty()) {
            QueueItem msg = out_queue.dequeue();
            auto vec = std::get<0>(msg);
            try {
                sendMessage(vec, std::get<1>(msg));
            } catch (zmq::error_t &ex) {
                LOG(WARNING) << "ZMQ EXCEPTION: " << ex.what();
                break;
            }
        }

        try {
            ret = zmq::poll(&item, 1, 5); // todo : determine reasonable poll interval
        } catch (zmq::error_t &ex) {
            LOG(WARNING) << "ZMQ EXCEPTION: " << ex.what();
            continue;
        }

        if (ret > 0) {

            if (item.revents & ZMQ_POLLIN) {
                zmq::multipart_t multi(zsocket);

                if (multi.size() != 3) {
                    LOG(WARNING) << "Possibly invalid message received! Message is: " << multi.str();
                    continue;
                }

                //VLOG(3) << multi.str();

                std::string id = multi.popstr();
                std::string uuid = multi.popstr();
                std::string data = multi.popstr();

                msgpack::unpacked unpacked;
                msgpack::unpack(&unpacked, data.data(), data.size());

                // deserialize msgpack message and pass to correct server
                try {
                    // so these two lines have to be in this order. if listener_map.at() fails, it'll skip the
                    // connection_map line, which will silently create and/or update if nothing exists.
                    auto server = listener_map.at(uuid);
                    connection_map[uuid] = id;

                    msgpack::object obj = unpacked.get();
                    std::vector<uint32_t> vec;
                    obj.convert(&vec);
                    server->processIncomingMessage(vec);
                } catch (std::out_of_range &e) {
                    LOG(WARNING) << "Listener with UUID " << uuid << " does not exist in map!";
                } catch (std::exception &e) {
                    LOG(ERROR) << "Msgpack conversion failed: " << e.what();
                    LOG(ERROR) << "Offending buffer is " << unpacked.get();
                }
            }
        } else if (ret == -1) {
            LOG(WARNING) << "Error polling socket: " << ret;
        }
    }
}