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; } }
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; } } } } } }
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()); }
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 } }
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; } } } }
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(); } }
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; } } }