From d39cccde774c0b26f801533fb451de16953b4134 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Feb 2014 10:32:16 -0800 Subject: [PATCH 01/10] add a method to find a node and upate based on packet --- assignment-client/src/audio/AudioMixer.cpp | 16 +------ assignment-client/src/avatars/AvatarMixer.cpp | 10 +---- assignment-client/src/octree/OctreeServer.cpp | 10 +---- libraries/shared/src/NodeList.cpp | 42 +++++++++---------- libraries/shared/src/NodeList.h | 3 +- 5 files changed, 26 insertions(+), 55 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 3a736fd51c..6dbfb58f9a 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -213,20 +213,8 @@ void AudioMixer::processDatagram(const QByteArray& dataByteArray, const HifiSock if (mixerPacketType == PacketTypeMicrophoneAudioNoEcho || mixerPacketType == PacketTypeMicrophoneAudioWithEcho || mixerPacketType == PacketTypeInjectAudio) { - - NodeList* nodeList = NodeList::getInstance(); - - SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(dataByteArray); - - if (matchingNode) { - nodeList->updateNodeWithData(matchingNode.data(), senderSockAddr, dataByteArray); - - if (!matchingNode->getActiveSocket()) { - // we don't have an active socket for this node, but they're talking to us - // this means they've heard from us and can reply, let's assume public is active - matchingNode->activatePublicSocket(); - } - } + + NodeList::getInstance()->findNodeAndUpdateWithDataFromPacket(dataByteArray); } else { // let processNodeData handle it. NodeList::getInstance()->processNodeData(senderSockAddr, dataByteArray); diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 9971bb51af..5e0da14a59 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -142,15 +142,7 @@ void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSoc switch (packetTypeForPacket(dataByteArray)) { case PacketTypeAvatarData: { - - // add or update the node in our list - SharedNodePointer avatarNode = nodeList->sendingNodeForPacket(dataByteArray); - - if (avatarNode) { - // parse positional data from an node - nodeList->updateNodeWithData(avatarNode.data(), senderSockAddr, dataByteArray); - - } + nodeList->findNodeAndUpdateWithDataFromPacket(dataByteArray); break; } case PacketTypeAvatarIdentity: { diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 4eff13f658..48fd0b0a8d 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -473,15 +473,9 @@ void OctreeServer::processDatagram(const QByteArray& dataByteArray, const HifiSo // If we got a PacketType_VOXEL_QUERY, then we're talking to an NodeType_t_AVATAR, and we // need to make sure we have it in our nodeList. - - if (matchingNode) { - nodeList->updateNodeWithData(matchingNode.data(), senderSockAddr, dataByteArray); - if (!matchingNode->getActiveSocket()) { - // we don't have an active socket for this node, but they're talking to us - // this means they've heard from us and can reply, let's assume public is active - matchingNode->activatePublicSocket(); - } + nodeList->updateNodeWithDataFromPacket(matchingNode, dataByteArray); + OctreeQueryNode* nodeData = (OctreeQueryNode*) matchingNode->getLinkedData(); if (nodeData && !nodeData->isOctreeSendThreadInitalized()) { nodeData->initializeOctreeSendThread(this, matchingNode->getUUID()); diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index c30c6de56a..46234c510f 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -219,32 +219,28 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteAr } } -int NodeList::updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, const QByteArray& packet) { - QMutexLocker locker(&node->getMutex()); - - node->setLastHeardMicrostamp(usecTimestampNow()); - - if (!senderSockAddr.isNull() && !node->getActiveSocket()) { - if (senderSockAddr == node->getPublicSocket()) { - node->activatePublicSocket(); - } else if (senderSockAddr == node->getLocalSocket()) { - node->activateLocalSocket(); - } +int NodeList::updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, const QByteArray &packet) { + QMutexLocker locker(&matchingNode->getMutex()); + + matchingNode->setLastHeardMicrostamp(usecTimestampNow()); + matchingNode->recordBytesReceived(packet.size()); + + if (!matchingNode->getLinkedData() && linkedDataCreateCallback) { + linkedDataCreateCallback(matchingNode.data()); } + + return matchingNode->getLinkedData()->parseData(packet); +} - if (node->getActiveSocket() || senderSockAddr.isNull()) { - node->recordBytesReceived(packet.size()); - - if (!node->getLinkedData() && linkedDataCreateCallback) { - linkedDataCreateCallback(node); - } - - int numParsedBytes = node->getLinkedData()->parseData(packet); - return numParsedBytes; - } else { - // we weren't able to match the sender address to the address we have for this node, unlock and don't parse - return 0; +int NodeList::findNodeAndUpdateWithDataFromPacket(const QByteArray& packet) { + SharedNodePointer matchingNode = sendingNodeForPacket(packet); + + if (matchingNode) { + updateNodeWithDataFromPacket(matchingNode, packet); } + + // we weren't able to match the sender address to the address we have for this node, unlock and don't parse + return 0; } SharedNodePointer NodeList::nodeWithUUID(const QUuid& nodeUUID) { diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 3a71ee7620..2e89395d3e 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -119,7 +119,8 @@ public: void processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet); void processKillNode(const QByteArray& datagram); - int updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, const QByteArray& packet); + int updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, const QByteArray& packet); + int findNodeAndUpdateWithDataFromPacket(const QByteArray& packet); unsigned broadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes); SharedNodePointer soloNodeOfType(char nodeType); From 997bea708df5b0c47a94b8134c13617bfe7639fa Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Feb 2014 10:32:48 -0800 Subject: [PATCH 02/10] fix a PacketTypeVoxelQuery typo --- assignment-client/src/octree/OctreeServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 48fd0b0a8d..1b66c9ddba 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -468,7 +468,7 @@ void OctreeServer::processDatagram(const QByteArray& dataByteArray, const HifiSo if (packetType == getMyQueryMessageType()) { bool debug = false; if (debug) { - qDebug() << "Got PacketType_VOXEL_QUERY at" << usecTimestampNow(); + qDebug() << "Got PacketTypeVoxelQuery at" << usecTimestampNow(); } // If we got a PacketType_VOXEL_QUERY, then we're talking to an NodeType_t_AVATAR, and we From 66d4eeb8059755b9a7f1615f8f2194b57b0e2fae Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Feb 2014 11:10:38 -0800 Subject: [PATCH 03/10] enforce both a version and hash match for packets --- animation-server/src/AnimationServer.cpp | 2 +- assignment-client/src/AssignmentClient.cpp | 2 +- data-server/src/DataServer.cpp | 2 +- domain-server/src/DomainServer.cpp | 2 +- interface/src/DatagramProcessor.cpp | 2 +- interface/src/VoxelPacketProcessor.cpp | 2 +- libraries/shared/src/NodeList.cpp | 81 ++++++++++++++++------ libraries/shared/src/NodeList.h | 2 + libraries/shared/src/PacketHeaders.cpp | 34 ++++----- libraries/shared/src/PacketHeaders.h | 7 +- 10 files changed, 86 insertions(+), 50 deletions(-) diff --git a/animation-server/src/AnimationServer.cpp b/animation-server/src/AnimationServer.cpp index 78966da2b5..3151445794 100644 --- a/animation-server/src/AnimationServer.cpp +++ b/animation-server/src/AnimationServer.cpp @@ -830,7 +830,7 @@ void AnimationServer::readPendingDatagrams() { receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize()); nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(), nodeSockAddr.getAddressPointer(), nodeSockAddr.getPortPointer()); - if (packetVersionMatch(receivedPacket)) { + if (nodeList->packetVersionAndHashMatch(receivedPacket)) { if (packetTypeForPacket(receivedPacket) == PacketTypeJurisdiction) { int headerBytes = numBytesForPacketHeader(receivedPacket); // PacketType_JURISDICTION, first byte is the node type... diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index b294f48fac..8add7d90f8 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -111,7 +111,7 @@ void AssignmentClient::readPendingDatagrams() { nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(), senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); - if (packetVersionMatch(receivedPacket)) { + if (nodeList->packetVersionAndHashMatch(receivedPacket)) { if (_currentAssignment) { // have the threaded current assignment handle this datagram QMetaObject::invokeMethod(_currentAssignment, "processDatagram", Qt::QueuedConnection, diff --git a/data-server/src/DataServer.cpp b/data-server/src/DataServer.cpp index 43fc52fb06..97228b67a3 100644 --- a/data-server/src/DataServer.cpp +++ b/data-server/src/DataServer.cpp @@ -66,7 +66,7 @@ void DataServer::readPendingDatagrams() { PacketType requestType = packetTypeForPacket(receivedPacket); if ((requestType == PacketTypeDataServerPut || requestType == PacketTypeDataServerGet) && - packetVersionMatch(receivedPacket)) { + receivedPacket[numBytesArithmeticCodingFromBuffer(receivedPacket.data())] == versionForPacketType(requestType)) { QDataStream packetStream(receivedPacket); int numReceivedHeaderBytes = numBytesForPacketHeader(receivedPacket); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 6ce71cae01..2a98c9b8b0 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -236,7 +236,7 @@ void DomainServer::readAvailableDatagrams() { nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(), senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); - if (packetVersionMatch(receivedPacket)) { + if (nodeList->packetVersionAndHashMatch(receivedPacket)) { PacketType requestType = packetTypeForPacket(receivedPacket); if (requestType == PacketTypeDomainListRequest) { diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index 36f03c39f0..6271ef5fde 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -40,7 +40,7 @@ void DatagramProcessor::processDatagrams() { _packetCount++; _byteCount += incomingPacket.size(); - if (packetVersionMatch(incomingPacket)) { + if (nodeList->packetVersionAndHashMatch(incomingPacket)) { // only process this packet if we have a match on the packet version switch (packetTypeForPacket(incomingPacket)) { case PacketTypeTransmitterData: diff --git a/interface/src/VoxelPacketProcessor.cpp b/interface/src/VoxelPacketProcessor.cpp index b5ec4247f2..dce391e587 100644 --- a/interface/src/VoxelPacketProcessor.cpp +++ b/interface/src/VoxelPacketProcessor.cpp @@ -48,7 +48,7 @@ void VoxelPacketProcessor::processPacket(const SharedNodePointer& sendingNode, c wasStatsPacket = true; if (messageLength > statsMessageLength) { mutablePacket = mutablePacket.mid(statsMessageLength); - if (!packetVersionMatch(packet)) { + if (!NodeList::getInstance()->packetVersionAndHashMatch(packet)) { return; // bail since piggyback data doesn't match our versioning } } else { diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 46234c510f..ba890564ce 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -80,30 +80,64 @@ NodeList::~NodeList() { clear(); } -qint64 NodeList::writeDatagram(const QByteArray& datagram, const SharedNodePointer& destinationNode, - const HifiSockAddr& overridenSockAddr) { +bool NodeList::packetVersionAndHashMatch(const QByteArray& packet) { + // currently this just checks if the version in the packet matches our return from versionForPacketType + // may need to be expanded in the future for types and versions that take > than 1 byte - // setup the MD5 hash for source verification in the header - int numBytesPacketHeader = numBytesForPacketHeader(datagram); - QByteArray dataSecretHash = QCryptographicHash::hash(datagram.mid(numBytesPacketHeader) - + destinationNode->getConnectionSecret().toRfc4122(), - QCryptographicHash::Md5); - QByteArray datagramWithHash = datagram; - datagramWithHash.replace(numBytesPacketHeader - NUM_BYTES_MD5_HASH, NUM_BYTES_MD5_HASH, dataSecretHash); + if (packet[1] != versionForPacketType(packetTypeForPacket(packet)) + && packetTypeForPacket(packet) != PacketTypeStunResponse) { + PacketType mismatchType = packetTypeForPacket(packet); + int numPacketTypeBytes = arithmeticCodingValueFromBuffer(packet.data()); + + qDebug() << "Packet version mismatch on" << packetTypeForPacket(packet) << "- Sender" + << uuidFromPacketHeader(packet) << "sent" << qPrintable(QString::number(packet[numPacketTypeBytes])) << "but" + << qPrintable(QString::number(versionForPacketType(mismatchType))) << "expected."; + } - // if we don't have an ovveriden address, assume they want to send to the node's active socket - const HifiSockAddr* destinationSockAddr = &overridenSockAddr; - if (overridenSockAddr.isNull()) { - if (getNodeActiveSocketOrPing(destinationNode)) { - // use the node's active socket as the destination socket - destinationSockAddr = destinationNode->getActiveSocket(); + if (packetTypeForPacket(packet) != PacketTypeDomainList && packetTypeForPacket(packet) != PacketTypeDomainListRequest) { + // figure out which node this is from + SharedNodePointer sendingNode = sendingNodeForPacket(packet); + if (sendingNode) { + // check if the md5 hash in the header matches the hash we would expect + if (hashFromPacketHeader(packet) == hashForPacketAndConnectionUUID(packet, sendingNode->getConnectionSecret())) { + return true; + } else { + qDebug() << "Packet hash mismatch" << packetTypeForPacket(packet) << "received from known node with UUID" + << uuidFromPacketHeader(packet); + } } else { - // we don't have a socket to send to, return 0 - return 0; + qDebug() << "Packet of type" << packetTypeForPacket(packet) << "received from unknown node with UUID" + << uuidFromPacketHeader(packet); } } - return _nodeSocket.writeDatagram(datagramWithHash, destinationSockAddr->getAddress(), destinationSockAddr->getPort()); + return false; +} + +qint64 NodeList::writeDatagram(const QByteArray& datagram, const SharedNodePointer& destinationNode, + const HifiSockAddr& overridenSockAddr) { + if (destinationNode) { + // if we don't have an ovveriden address, assume they want to send to the node's active socket + const HifiSockAddr* destinationSockAddr = &overridenSockAddr; + if (overridenSockAddr.isNull()) { + if (getNodeActiveSocketOrPing(destinationNode)) { + // use the node's active socket as the destination socket + destinationSockAddr = destinationNode->getActiveSocket(); + } else { + // we don't have a socket to send to, return 0 + return 0; + } + } + + QByteArray datagramCopy = datagram; + // setup the MD5 hash for source verification in the header + replaceHashInPacketGivenConnectionUUID(datagramCopy, destinationNode->getConnectionSecret()); + + return _nodeSocket.writeDatagram(datagramCopy, destinationSockAddr->getAddress(), destinationSockAddr->getPort()); + } + + // didn't have a destinationNode to send to, return 0 + return 0; } qint64 NodeList::writeDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode, @@ -191,8 +225,11 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteAr } case PacketTypePing: { // send back a reply - QByteArray replyPacket = constructPingReplyPacket(packet); - writeDatagram(replyPacket, sendingNodeForPacket(packet), senderSockAddr); + if (sendingNodeForPacket(packet)) { + QByteArray replyPacket = constructPingReplyPacket(packet); + writeDatagram(replyPacket, sendingNodeForPacket(packet), senderSockAddr); + } + break; } case PacketTypePingReply: { @@ -716,9 +753,9 @@ void NodeList::activateSocketFromNodeCommunication(const QByteArray& packet, con // if this is a local or public ping then we can activate a socket // we do nothing with agnostic pings, those are simply for timing - if (pingType == PingType::Local) { + if (pingType == PingType::Local && sendingNode->getActiveSocket() != &sendingNode->getLocalSocket()) { sendingNode->activateLocalSocket(); - } else if (pingType == PingType::Public) { + } else if (pingType == PingType::Public && !sendingNode->getActiveSocket()) { sendingNode->activatePublicSocket(); } } diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 2e89395d3e..408459e51f 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -84,6 +84,8 @@ public: QUdpSocket& getNodeSocket() { return _nodeSocket; } + bool packetVersionAndHashMatch(const QByteArray& packet); + qint64 writeDatagram(const QByteArray& datagram, const SharedNodePointer& destinationNode, const HifiSockAddr& overridenSockAddr = HifiSockAddr()); qint64 writeDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode, diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index 16e1b3ce78..7193b6f648 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -85,26 +85,6 @@ int populatePacketHeader(char* packet, PacketType type, const QUuid& connectionU return position - packet; } -bool packetVersionMatch(const QByteArray& packet) { - // currently this just checks if the version in the packet matches our return from versionForPacketType - // may need to be expanded in the future for types and versions that take > than 1 byte - - if (packet[1] == versionForPacketType(packetTypeForPacket(packet)) || packetTypeForPacket(packet) == PacketTypeStunResponse) { - return true; - } else { - PacketType mismatchType = packetTypeForPacket(packet); - int numPacketTypeBytes = arithmeticCodingValueFromBuffer(packet.data()); - - QUuid nodeUUID = uuidFromPacketHeader(packet); - - qDebug() << "Packet mismatch on" << packetTypeForPacket(packet) << "- Sender" - << nodeUUID << "sent" << qPrintable(QString::number(packet[numPacketTypeBytes])) << "but" - << qPrintable(QString::number(versionForPacketType(mismatchType))) << "expected."; - - return false; - } -} - int numBytesForPacketHeader(const QByteArray& packet) { // returns the number of bytes used for the type, version, and UUID return numBytesArithmeticCodingFromBuffer(packet.data()) + NUM_STATIC_HEADER_BYTES; @@ -124,6 +104,20 @@ QUuid uuidFromPacketHeader(const QByteArray& packet) { NUM_BYTES_RFC4122_UUID)); } +QByteArray hashFromPacketHeader(const QByteArray& packet) { + return packet.mid(NUM_STATIC_HEADER_BYTES - NUM_BYTES_MD5_HASH, NUM_BYTES_MD5_HASH); +} + +QByteArray hashForPacketAndConnectionUUID(const QByteArray& packet, const QUuid& connectionUUID) { + return QCryptographicHash::hash(packet.mid(numBytesForPacketHeader(packet)) + + connectionUUID.toRfc4122(), QCryptographicHash::Md5); +} + +void replaceHashInPacketGivenConnectionUUID(QByteArray& packet, const QUuid& connectionUUID) { + packet.replace(numBytesForPacketHeader(packet) - NUM_BYTES_MD5_HASH, NUM_BYTES_MD5_HASH, + hashForPacketAndConnectionUUID(packet, connectionUUID)); +} + PacketType packetTypeForPacket(const QByteArray& packet) { return (PacketType) arithmeticCodingValueFromBuffer(packet.data()); } diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index ad669daece..c1a5a34114 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -70,17 +70,20 @@ QByteArray byteArrayWithPopluatedHeader(PacketType type, const QUuid& connection int populatePacketHeader(QByteArray& packet, PacketType type, const QUuid& connectionUUID = nullUUID); int populatePacketHeader(char* packet, PacketType type, const QUuid& connectionUUID = nullUUID); -bool packetVersionMatch(const QByteArray& packet); - int numBytesForPacketHeader(const QByteArray& packet); int numBytesForPacketHeader(const char* packet); int numBytesForPacketHeaderGivenPacketType(PacketType type); QUuid uuidFromPacketHeader(const QByteArray& packet); +QByteArray hashFromPacketHeader(const QByteArray& packet); +QByteArray hashForPacketAndConnectionUUID(const QByteArray& packet, const QUuid& connectionUUID); +void replaceHashInPacketGivenConnectionUUID(QByteArray& packet, const QUuid& connectionUUID); + PacketType packetTypeForPacket(const QByteArray& packet); PacketType packetTypeForPacket(const char* packet); int arithmeticCodingValueFromBuffer(const char* checkValue); +int numBytesArithmeticCodingFromBuffer(const char* checkValue); #endif From a5636d2dc029e49a812f50a5ecb84ca30b3da9d1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Feb 2014 11:52:37 -0800 Subject: [PATCH 04/10] make ThreadedAssignment subclasses handle QUdpSocket readyRead, closes #1895 --- assignment-client/src/Agent.cpp | 63 ++++++++------ assignment-client/src/Agent.h | 2 +- assignment-client/src/AssignmentClient.cpp | 86 +++++++++---------- assignment-client/src/audio/AudioMixer.cpp | 30 ++++--- assignment-client/src/audio/AudioMixer.h | 2 +- assignment-client/src/avatars/AvatarMixer.cpp | 73 ++++++++-------- assignment-client/src/avatars/AvatarMixer.h | 2 +- .../src/metavoxels/MetavoxelServer.cpp | 27 ++++-- .../src/metavoxels/MetavoxelServer.h | 2 +- assignment-client/src/octree/OctreeServer.cpp | 59 +++++++------ assignment-client/src/octree/OctreeServer.h | 2 +- libraries/shared/src/NodeList.cpp | 15 +++- libraries/shared/src/ThreadedAssignment.cpp | 13 +++ libraries/shared/src/ThreadedAssignment.h | 4 +- 14 files changed, 218 insertions(+), 162 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index eff573216a..0030e3ffb8 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -31,36 +31,43 @@ Agent::Agent(const QByteArray& packet) : _scriptEngine.getParticlesScriptingInterface()->setPacketSender(&_particleEditSender); } -void Agent::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) { - PacketType datagramPacketType = packetTypeForPacket(dataByteArray); - if (datagramPacketType == PacketTypeJurisdiction) { - int headerBytes = numBytesForPacketHeader(dataByteArray); - - QUuid nodeUUID; - SharedNodePointer matchedNode = NodeList::getInstance()->nodeWithUUID(nodeUUID); - - if (matchedNode) { - // PacketType_JURISDICTION, first byte is the node type... - switch (dataByteArray[headerBytes]) { - case NodeType::VoxelServer: - _scriptEngine.getVoxelsScriptingInterface()->getJurisdictionListener()->queueReceivedPacket(matchedNode, - dataByteArray); - break; - case NodeType::ParticleServer: - _scriptEngine.getParticlesScriptingInterface()->getJurisdictionListener()->queueReceivedPacket(matchedNode, - dataByteArray); - break; +void Agent::readPendingDatagrams() { + QByteArray receivedPacket; + HifiSockAddr senderSockAddr; + NodeList* nodeList = NodeList::getInstance(); + + while (readAvailableDatagram(receivedPacket, senderSockAddr)) { + if (nodeList->packetVersionAndHashMatch(receivedPacket)) { + PacketType datagramPacketType = packetTypeForPacket(receivedPacket); + if (datagramPacketType == PacketTypeJurisdiction) { + int headerBytes = numBytesForPacketHeader(receivedPacket); + + SharedNodePointer matchedNode = nodeList->sendingNodeForPacket(receivedPacket); + + if (matchedNode) { + // PacketType_JURISDICTION, first byte is the node type... + switch (receivedPacket[headerBytes]) { + case NodeType::VoxelServer: + _scriptEngine.getVoxelsScriptingInterface()->getJurisdictionListener()->queueReceivedPacket(matchedNode, + receivedPacket); + break; + case NodeType::ParticleServer: + _scriptEngine.getParticlesScriptingInterface()->getJurisdictionListener()->queueReceivedPacket(matchedNode, + receivedPacket); + break; + } + } + + } else if (datagramPacketType == PacketTypeParticleAddResponse) { + // this will keep creatorTokenIDs to IDs mapped correctly + Particle::handleAddParticleResponse(receivedPacket); + + // also give our local particle tree a chance to remap any internal locally created particles + _particleTree.handleAddParticleResponse(receivedPacket); + } else { + NodeList::getInstance()->processNodeData(senderSockAddr, receivedPacket); } } - - } else if (datagramPacketType == PacketTypeParticleAddResponse) { - // this will keep creatorTokenIDs to IDs mapped correctly - Particle::handleAddParticleResponse(dataByteArray); - - // also give our local particle tree a chance to remap any internal locally created particles - _particleTree.handleAddParticleResponse(dataByteArray); - } else { - NodeList::getInstance()->processNodeData(senderSockAddr, dataByteArray); } } diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index 7495fc06bf..bc6b4f65fe 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -35,7 +35,7 @@ public: public slots: void run(); - void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr); + void readPendingDatagrams(); signals: void willSendAudioDataCallback(); void willSendVisualDataCallback(); diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 8add7d90f8..978882f358 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -90,8 +90,7 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : timer->start(ASSIGNMENT_REQUEST_INTERVAL_MSECS); // connect our readPendingDatagrams method to the readyRead() signal of the socket - connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClient::readPendingDatagrams, - Qt::QueuedConnection); + connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClient::readPendingDatagrams); } void AssignmentClient::sendAssignmentRequest() { @@ -112,49 +111,44 @@ void AssignmentClient::readPendingDatagrams() { senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); if (nodeList->packetVersionAndHashMatch(receivedPacket)) { - if (_currentAssignment) { - // have the threaded current assignment handle this datagram - QMetaObject::invokeMethod(_currentAssignment, "processDatagram", Qt::QueuedConnection, - Q_ARG(QByteArray, receivedPacket), - Q_ARG(HifiSockAddr, senderSockAddr)); - } else if (packetTypeForPacket(receivedPacket) == PacketTypeCreateAssignment) { + if (packetTypeForPacket(receivedPacket) == PacketTypeCreateAssignment) { + // construct the deployed assignment from the packet data + _currentAssignment = AssignmentFactory::unpackAssignment(receivedPacket); if (_currentAssignment) { - qDebug() << "Dropping received assignment since we are currently running one."; - } else { - // construct the deployed assignment from the packet data - _currentAssignment = AssignmentFactory::unpackAssignment(receivedPacket); + qDebug() << "Received an assignment -" << *_currentAssignment; - if (_currentAssignment) { - qDebug() << "Received an assignment -" << *_currentAssignment; - - // switch our nodelist domain IP and port to whoever sent us the assignment - - nodeList->setDomainSockAddr(senderSockAddr); - nodeList->setSessionUUID(_currentAssignment->getUUID()); - - qDebug() << "Destination IP for assignment is" << nodeList->getDomainIP().toString(); - - // start the deployed assignment - QThread* workerThread = new QThread(this); - - connect(workerThread, SIGNAL(started()), _currentAssignment, SLOT(run())); - - connect(_currentAssignment, SIGNAL(finished()), this, SLOT(assignmentCompleted())); - connect(_currentAssignment, SIGNAL(finished()), workerThread, SLOT(quit())); - connect(_currentAssignment, SIGNAL(finished()), _currentAssignment, SLOT(deleteLater())); - connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater())); - - _currentAssignment->moveToThread(workerThread); - - // move the NodeList to the thread used for the _current assignment - nodeList->moveToThread(workerThread); - - // Starts an event loop, and emits workerThread->started() - workerThread->start(); - } else { - qDebug() << "Received an assignment that could not be unpacked. Re-requesting."; - } + // switch our nodelist domain IP and port to whoever sent us the assignment + + nodeList->setDomainSockAddr(senderSockAddr); + nodeList->setSessionUUID(_currentAssignment->getUUID()); + + qDebug() << "Destination IP for assignment is" << nodeList->getDomainIP().toString(); + + // start the deployed assignment + QThread* workerThread = new QThread(this); + + connect(workerThread, SIGNAL(started()), _currentAssignment, SLOT(run())); + + connect(_currentAssignment, SIGNAL(finished()), this, SLOT(assignmentCompleted())); + connect(_currentAssignment, SIGNAL(finished()), workerThread, SLOT(quit())); + connect(_currentAssignment, SIGNAL(finished()), _currentAssignment, SLOT(deleteLater())); + connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater())); + + _currentAssignment->moveToThread(workerThread); + + // move the NodeList to the thread used for the _current assignment + nodeList->moveToThread(workerThread); + + // let the assignment handle the incoming datagrams for its duration + disconnect(&nodeList->getNodeSocket(), 0, this, 0); + connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, _currentAssignment, + &ThreadedAssignment::readPendingDatagrams); + + // Starts an event loop, and emits workerThread->started() + workerThread->start(); + } else { + qDebug() << "Received an assignment that could not be unpacked. Re-requesting."; } } else { // have the NodeList attempt to handle it @@ -170,10 +164,14 @@ void AssignmentClient::assignmentCompleted() { qDebug("Assignment finished or never started - waiting for new assignment."); - _currentAssignment = NULL; - NodeList* nodeList = NodeList::getInstance(); + // have us handle incoming NodeList datagrams again + disconnect(&nodeList->getNodeSocket(), 0, _currentAssignment, 0); + connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClient::readPendingDatagrams); + + _currentAssignment = NULL; + // reset our NodeList by switching back to unassigned and clearing the list nodeList->setOwnerType(NodeType::Unassigned); nodeList->reset(); diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 6dbfb58f9a..30359f85c4 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -207,17 +207,25 @@ void AudioMixer::prepareMixForListeningNode(Node* node) { } -void AudioMixer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) { - // pull any new audio data from nodes off of the network stack - PacketType mixerPacketType = packetTypeForPacket(dataByteArray); - if (mixerPacketType == PacketTypeMicrophoneAudioNoEcho - || mixerPacketType == PacketTypeMicrophoneAudioWithEcho - || mixerPacketType == PacketTypeInjectAudio) { - - NodeList::getInstance()->findNodeAndUpdateWithDataFromPacket(dataByteArray); - } else { - // let processNodeData handle it. - NodeList::getInstance()->processNodeData(senderSockAddr, dataByteArray); +void AudioMixer::readPendingDatagrams() { + QByteArray receivedPacket; + HifiSockAddr senderSockAddr; + NodeList* nodeList = NodeList::getInstance(); + + while (readAvailableDatagram(receivedPacket, senderSockAddr)) { + if (nodeList->packetVersionAndHashMatch(receivedPacket)) { + // pull any new audio data from nodes off of the network stack + PacketType mixerPacketType = packetTypeForPacket(receivedPacket); + if (mixerPacketType == PacketTypeMicrophoneAudioNoEcho + || mixerPacketType == PacketTypeMicrophoneAudioWithEcho + || mixerPacketType == PacketTypeInjectAudio) { + + nodeList->findNodeAndUpdateWithDataFromPacket(receivedPacket); + } else { + // let processNodeData handle it. + nodeList->processNodeData(senderSockAddr, receivedPacket); + } + } } } diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h index 2d42a6b629..e120d19d32 100644 --- a/assignment-client/src/audio/AudioMixer.h +++ b/assignment-client/src/audio/AudioMixer.h @@ -25,7 +25,7 @@ public slots: /// threaded run of assignment void run(); - void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr); + void readPendingDatagrams(); private: /// adds one buffer to the mix for a listening node void addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuffer* bufferToAdd, diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 5e0da14a59..c7989bc9e9 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -136,47 +136,52 @@ void AvatarMixer::nodeKilled(SharedNodePointer killedNode) { } } -void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) { +void AvatarMixer::readPendingDatagrams() { + QByteArray receivedPacket; + HifiSockAddr senderSockAddr; NodeList* nodeList = NodeList::getInstance(); - switch (packetTypeForPacket(dataByteArray)) { - case PacketTypeAvatarData: { - nodeList->findNodeAndUpdateWithDataFromPacket(dataByteArray); - break; - } - case PacketTypeAvatarIdentity: { - - // check if we have a matching node in our list - SharedNodePointer avatarNode = nodeList->sendingNodeForPacket(dataByteArray); - - if (avatarNode && avatarNode->getLinkedData()) { - AvatarMixerClientData* nodeData = reinterpret_cast(avatarNode->getLinkedData()); - if (nodeData->hasIdentityChangedAfterParsing(dataByteArray) - && !nodeData->hasSentIdentityBetweenKeyFrames()) { - // this avatar changed their identity in some way and we haven't sent a packet in this keyframe - QByteArray identityPacket = byteArrayWithPopluatedHeader(PacketTypeAvatarIdentity); - - QByteArray individualByteArray = nodeData->identityByteArray(); - individualByteArray.replace(0, NUM_BYTES_RFC4122_UUID, avatarNode->getUUID().toRfc4122()); - - identityPacket.append(individualByteArray); - - nodeData->setHasSentIdentityBetweenKeyFrames(true); - nodeList->broadcastToNodes(identityPacket, NodeSet() << NodeType::Agent); + while (readAvailableDatagram(receivedPacket, senderSockAddr)) { + if (nodeList->packetVersionAndHashMatch(receivedPacket)) { + switch (packetTypeForPacket(receivedPacket)) { + case PacketTypeAvatarData: { + nodeList->findNodeAndUpdateWithDataFromPacket(receivedPacket); + break; } + case PacketTypeAvatarIdentity: { + + // check if we have a matching node in our list + SharedNodePointer avatarNode = nodeList->sendingNodeForPacket(receivedPacket); + + if (avatarNode && avatarNode->getLinkedData()) { + AvatarMixerClientData* nodeData = reinterpret_cast(avatarNode->getLinkedData()); + if (nodeData->hasIdentityChangedAfterParsing(receivedPacket) + && !nodeData->hasSentIdentityBetweenKeyFrames()) { + // this avatar changed their identity in some way and we haven't sent a packet in this keyframe + QByteArray identityPacket = byteArrayWithPopluatedHeader(PacketTypeAvatarIdentity); + + QByteArray individualByteArray = nodeData->identityByteArray(); + individualByteArray.replace(0, NUM_BYTES_RFC4122_UUID, avatarNode->getUUID().toRfc4122()); + + identityPacket.append(individualByteArray); + + nodeData->setHasSentIdentityBetweenKeyFrames(true); + nodeList->broadcastToNodes(identityPacket, NodeSet() << NodeType::Agent); + } + } + } + case PacketTypeKillAvatar: { + nodeList->processKillNode(receivedPacket); + break; + } + default: + // hand this off to the NodeList + nodeList->processNodeData(senderSockAddr, receivedPacket); + break; } } - case PacketTypeKillAvatar: { - nodeList->processKillNode(dataByteArray); - break; - } - default: - // hand this off to the NodeList - nodeList->processNodeData(senderSockAddr, dataByteArray); - break; } - } const qint64 AVATAR_IDENTITY_KEYFRAME_MSECS = 5000; diff --git a/assignment-client/src/avatars/AvatarMixer.h b/assignment-client/src/avatars/AvatarMixer.h index 61141411e6..acc5a178aa 100644 --- a/assignment-client/src/avatars/AvatarMixer.h +++ b/assignment-client/src/avatars/AvatarMixer.h @@ -23,7 +23,7 @@ public slots: void nodeAdded(SharedNodePointer nodeAdded); void nodeKilled(SharedNodePointer killedNode); - void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr); + void readPendingDatagrams(); }; #endif /* defined(__hifi__AvatarMixer__) */ diff --git a/assignment-client/src/metavoxels/MetavoxelServer.cpp b/assignment-client/src/metavoxels/MetavoxelServer.cpp index 3cd81d8ac7..4df72f5de9 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.cpp +++ b/assignment-client/src/metavoxels/MetavoxelServer.cpp @@ -41,15 +41,24 @@ void MetavoxelServer::run() { _sendTimer.start(SEND_INTERVAL); } -void MetavoxelServer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) { - switch (dataByteArray.at(0)) { - case PacketTypeMetavoxelData: - processData(dataByteArray, senderSockAddr); - break; - - default: - NodeList::getInstance()->processNodeData(senderSockAddr, dataByteArray); - break; +void MetavoxelServer::readPendingDatagrams() { + QByteArray receivedPacket; + HifiSockAddr senderSockAddr; + + NodeList* nodeList = NodeList::getInstance(); + + while (readAvailableDatagram(receivedPacket, senderSockAddr)) { + if (nodeList->packetVersionAndHashMatch(receivedPacket)) { + switch (packetTypeForPacket(receivedPacket)) { + case PacketTypeMetavoxelData: + processData(receivedPacket, senderSockAddr); + break; + + default: + NodeList::getInstance()->processNodeData(senderSockAddr, receivedPacket); + break; + } + } } } diff --git a/assignment-client/src/metavoxels/MetavoxelServer.h b/assignment-client/src/metavoxels/MetavoxelServer.h index f106bd3494..5ee861b75d 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.h +++ b/assignment-client/src/metavoxels/MetavoxelServer.h @@ -39,7 +39,7 @@ public: virtual void run(); - virtual void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr); + virtual void readPendingDatagrams(); private slots: diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 1b66c9ddba..7d237f46e2 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -458,36 +458,43 @@ void OctreeServer::parsePayload() { } } -void OctreeServer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) { - NodeList* nodeList = NodeList::getInstance(); - - PacketType packetType = packetTypeForPacket(dataByteArray); +void OctreeServer::readPendingDatagrams() { + QByteArray receivedPacket; + HifiSockAddr senderSockAddr; - SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(dataByteArray); - - if (packetType == getMyQueryMessageType()) { - bool debug = false; - if (debug) { - qDebug() << "Got PacketTypeVoxelQuery at" << usecTimestampNow(); - } - - // If we got a PacketType_VOXEL_QUERY, then we're talking to an NodeType_t_AVATAR, and we - // need to make sure we have it in our nodeList. - if (matchingNode) { - nodeList->updateNodeWithDataFromPacket(matchingNode, dataByteArray); + NodeList* nodeList = NodeList::getInstance(); + + while (readAvailableDatagram(receivedPacket, senderSockAddr)) { + if (nodeList->packetVersionAndHashMatch(receivedPacket)) { + PacketType packetType = packetTypeForPacket(receivedPacket); - OctreeQueryNode* nodeData = (OctreeQueryNode*) matchingNode->getLinkedData(); - if (nodeData && !nodeData->isOctreeSendThreadInitalized()) { - nodeData->initializeOctreeSendThread(this, matchingNode->getUUID()); + SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket); + + if (packetType == getMyQueryMessageType()) { + bool debug = false; + if (debug) { + qDebug() << "Got PacketTypeVoxelQuery at" << usecTimestampNow(); + } + + // If we got a PacketType_VOXEL_QUERY, then we're talking to an NodeType_t_AVATAR, and we + // need to make sure we have it in our nodeList. + if (matchingNode) { + nodeList->updateNodeWithDataFromPacket(matchingNode, receivedPacket); + + OctreeQueryNode* nodeData = (OctreeQueryNode*) matchingNode->getLinkedData(); + if (nodeData && !nodeData->isOctreeSendThreadInitalized()) { + nodeData->initializeOctreeSendThread(this, matchingNode->getUUID()); + } + } + } else if (packetType == PacketTypeJurisdictionRequest) { + _jurisdictionSender->queueReceivedPacket(matchingNode, receivedPacket); + } else if (_octreeInboundPacketProcessor && getOctree()->handlesEditPacketType(packetType)) { + _octreeInboundPacketProcessor->queueReceivedPacket(matchingNode, receivedPacket); + } else { + // let processNodeData handle it. + NodeList::getInstance()->processNodeData(senderSockAddr, receivedPacket); } } - } else if (packetType == PacketTypeJurisdictionRequest) { - _jurisdictionSender->queueReceivedPacket(matchingNode, dataByteArray); - } else if (_octreeInboundPacketProcessor && getOctree()->handlesEditPacketType(packetType)) { - _octreeInboundPacketProcessor->queueReceivedPacket(matchingNode, dataByteArray); - } else { - // let processNodeData handle it. - NodeList::getInstance()->processNodeData(senderSockAddr, dataByteArray); } } diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index 26c39d1a1d..e221011b76 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -67,7 +67,7 @@ public: public slots: /// runs the voxel server assignment void run(); - void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr); + void readPendingDatagrams(); protected: void parsePayload(); diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index ba890564ce..43f3240b12 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -94,7 +94,12 @@ bool NodeList::packetVersionAndHashMatch(const QByteArray& packet) { << qPrintable(QString::number(versionForPacketType(mismatchType))) << "expected."; } - if (packetTypeForPacket(packet) != PacketTypeDomainList && packetTypeForPacket(packet) != PacketTypeDomainListRequest) { + const QSet NON_VERIFIED_PACKETS = QSet() << PacketTypeDomainList + << PacketTypeDomainListRequest << PacketTypeStunResponse << PacketTypeDataServerConfirm + << PacketTypeDataServerGet << PacketTypeDataServerPut << PacketTypeDataServerSend + << PacketTypeCreateAssignment << PacketTypeRequestAssignment; + + if (!NON_VERIFIED_PACKETS.contains(packetTypeForPacket(packet))) { // figure out which node this is from SharedNodePointer sendingNode = sendingNodeForPacket(packet); if (sendingNode) { @@ -102,13 +107,15 @@ bool NodeList::packetVersionAndHashMatch(const QByteArray& packet) { if (hashFromPacketHeader(packet) == hashForPacketAndConnectionUUID(packet, sendingNode->getConnectionSecret())) { return true; } else { - qDebug() << "Packet hash mismatch" << packetTypeForPacket(packet) << "received from known node with UUID" - << uuidFromPacketHeader(packet); + qDebug() << "Packet hash mismatch on" << packetTypeForPacket(packet) << "- Sender" + << uuidFromPacketHeader(packet); } } else { qDebug() << "Packet of type" << packetTypeForPacket(packet) << "received from unknown node with UUID" - << uuidFromPacketHeader(packet); + << uuidFromPacketHeader(packet); } + } else { + return true; } return false; diff --git a/libraries/shared/src/ThreadedAssignment.cpp b/libraries/shared/src/ThreadedAssignment.cpp index 2c1110491b..5f66ae4a4e 100644 --- a/libraries/shared/src/ThreadedAssignment.cpp +++ b/libraries/shared/src/ThreadedAssignment.cpp @@ -60,3 +60,16 @@ void ThreadedAssignment::checkInWithDomainServerOrExit() { NodeList::getInstance()->sendDomainServerCheckIn(); } } + +bool ThreadedAssignment::readAvailableDatagram(QByteArray& destinationByteArray, HifiSockAddr& senderSockAddr) { + NodeList* nodeList = NodeList::getInstance(); + + if (nodeList->getNodeSocket().hasPendingDatagrams()) { + destinationByteArray.resize(nodeList->getNodeSocket().pendingDatagramSize()); + nodeList->getNodeSocket().readDatagram(destinationByteArray.data(), destinationByteArray.size(), + senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); + return true; + } else { + return false; + } +} diff --git a/libraries/shared/src/ThreadedAssignment.h b/libraries/shared/src/ThreadedAssignment.h index 7c7aa9a63e..c8aa1c419c 100644 --- a/libraries/shared/src/ThreadedAssignment.h +++ b/libraries/shared/src/ThreadedAssignment.h @@ -23,8 +23,10 @@ public slots: virtual void deleteLater(); - virtual void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) = 0; + virtual void readPendingDatagrams() = 0; protected: + bool readAvailableDatagram(QByteArray& destinationByteArray, HifiSockAddr& senderSockAddr); + void commonInit(const char* targetName, NodeType_t nodeType); bool _isFinished; private slots: From 3ad8e7260e68163057352c9b1acbeed9a387e643 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Feb 2014 13:42:52 -0800 Subject: [PATCH 05/10] fix an accidental DOS and remove getNodeActiveSocketOrPing API --- interface/src/Audio.cpp | 2 +- interface/src/ui/VoxelStatsDialog.cpp | 2 +- libraries/octree/src/JurisdictionListener.cpp | 2 +- .../octree/src/OctreeEditPacketSender.cpp | 22 +++++++++---------- libraries/shared/src/NodeList.cpp | 19 ++++++---------- libraries/shared/src/NodeList.h | 2 -- libraries/shared/src/PacketHeaders.cpp | 6 ++--- 7 files changed, 23 insertions(+), 32 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index e7fdcd32c7..9dd3c0377f 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -388,7 +388,7 @@ void Audio::handleAudioInput() { NodeList* nodeList = NodeList::getInstance(); SharedNodePointer audioMixer = nodeList->soloNodeOfType(NodeType::AudioMixer); - if (audioMixer && nodeList->getNodeActiveSocketOrPing(audioMixer)) { + if (audioMixer && audioMixer->getActiveSocket()) { MyAvatar* interfaceAvatar = Application::getInstance()->getAvatar(); glm::vec3 headPosition = interfaceAvatar->getHead().getPosition(); glm::quat headOrientation = interfaceAvatar->getHead().getOrientation(); diff --git a/interface/src/ui/VoxelStatsDialog.cpp b/interface/src/ui/VoxelStatsDialog.cpp index 1d94705504..0ac0a2b933 100644 --- a/interface/src/ui/VoxelStatsDialog.cpp +++ b/interface/src/ui/VoxelStatsDialog.cpp @@ -265,7 +265,7 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t serv std::stringstream extraDetails(""); std::stringstream linkDetails(""); - if (nodeList->getNodeActiveSocketOrPing(node)) { + if (node->getActiveSocket()) { serverDetails << "active "; } else { serverDetails << "inactive "; diff --git a/libraries/octree/src/JurisdictionListener.cpp b/libraries/octree/src/JurisdictionListener.cpp index a15c72cc5e..20e5af012f 100644 --- a/libraries/octree/src/JurisdictionListener.cpp +++ b/libraries/octree/src/JurisdictionListener.cpp @@ -45,7 +45,7 @@ bool JurisdictionListener::queueJurisdictionRequest() { NodeList* nodeList = NodeList::getInstance(); foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { - if (nodeList->getNodeActiveSocketOrPing(node) && node->getType() == getNodeType()) { + if (node->getType() == getNodeType() && node->getActiveSocket()) { _packetSender.queuePacketForSending(node, QByteArray(reinterpret_cast(bufferOut), sizeOut)); nodeCount++; } diff --git a/libraries/octree/src/OctreeEditPacketSender.cpp b/libraries/octree/src/OctreeEditPacketSender.cpp index ca3ffc707f..1c1ed13f8d 100644 --- a/libraries/octree/src/OctreeEditPacketSender.cpp +++ b/libraries/octree/src/OctreeEditPacketSender.cpp @@ -60,19 +60,17 @@ bool OctreeEditPacketSender::serversExist() const { foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { // only send to the NodeTypes that are getMyNodeType() - if (node->getType() == getMyNodeType()) { - if (nodeList->getNodeActiveSocketOrPing(node)) { - QUuid nodeUUID = node->getUUID(); - // If we've got Jurisdictions set, then check to see if we know the jurisdiction for this server - if (_serverJurisdictions) { - // lookup our nodeUUID in the jurisdiction map, if it's missing then we're - // missing at least one jurisdiction - if ((*_serverJurisdictions).find(nodeUUID) == (*_serverJurisdictions).end()) { - atLeastOnJurisdictionMissing = true; - } + if (node->getType() == getMyNodeType() && node->getActiveSocket()) { + QUuid nodeUUID = node->getUUID(); + // If we've got Jurisdictions set, then check to see if we know the jurisdiction for this server + if (_serverJurisdictions) { + // lookup our nodeUUID in the jurisdiction map, if it's missing then we're + // missing at least one jurisdiction + if ((*_serverJurisdictions).find(nodeUUID) == (*_serverJurisdictions).end()) { + atLeastOnJurisdictionMissing = true; } - hasServers = true; } + hasServers = true; } if (atLeastOnJurisdictionMissing) { break; // no point in looking further... @@ -91,7 +89,7 @@ void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned c // only send to the NodeTypes that are getMyNodeType() if (node->getType() == getMyNodeType() && ((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) { - if (nodeList->getNodeActiveSocketOrPing(node)) { + if (node->getActiveSocket()) { queuePacketForSending(node, QByteArray(reinterpret_cast(buffer), length)); // debugging output... diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 43f3240b12..0dc94a20b3 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -127,7 +127,7 @@ qint64 NodeList::writeDatagram(const QByteArray& datagram, const SharedNodePoint // if we don't have an ovveriden address, assume they want to send to the node's active socket const HifiSockAddr* destinationSockAddr = &overridenSockAddr; if (overridenSockAddr.isNull()) { - if (getNodeActiveSocketOrPing(destinationNode)) { + if (destinationNode->getActiveSocket()) { // use the node's active socket as the destination socket destinationSockAddr = destinationNode->getActiveSocket(); } else { @@ -140,6 +140,8 @@ qint64 NodeList::writeDatagram(const QByteArray& datagram, const SharedNodePoint // setup the MD5 hash for source verification in the header replaceHashInPacketGivenConnectionUUID(datagramCopy, destinationNode->getConnectionSecret()); + qDebug() << "Sending a packet of type" << packetTypeForPacket(datagram); + return _nodeSocket.writeDatagram(datagramCopy, destinationSockAddr->getAddress(), destinationSockAddr->getPort()); } @@ -680,8 +682,11 @@ SharedNodePointer NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType, Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket); SharedNodePointer newNodeSharedPointer(newNode, &QObject::deleteLater); + // try and ping the new node right away to open a connection + pingPublicAndLocalSocketsForInactiveNode(newNodeSharedPointer); + _nodeHash.insert(newNode->getUUID(), newNodeSharedPointer); - + _nodeHashMutex.unlock(); qDebug() << "Added" << *newNode; @@ -740,16 +745,6 @@ void NodeList::pingInactiveNodes() { } } -const HifiSockAddr* NodeList::getNodeActiveSocketOrPing(const SharedNodePointer& node) { - if (node && node->getActiveSocket()) { - return node->getActiveSocket(); - } else if (node) { - pingPublicAndLocalSocketsForInactiveNode(node); - } - - return NULL; -} - void NodeList::activateSocketFromNodeCommunication(const QByteArray& packet, const SharedNodePointer& sendingNode) { // deconstruct this ping packet to see if it is a public or local reply QDataStream packetStream(packet); diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 408459e51f..b6afd21451 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -129,8 +129,6 @@ public: void loadData(QSettings* settings); void saveData(QSettings* settings); - - const HifiSockAddr* getNodeActiveSocketOrPing(const SharedNodePointer& node); public slots: void sendDomainServerCheckIn(); void pingInactiveNodes(); diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index 7193b6f648..d4049e7310 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -105,12 +105,12 @@ QUuid uuidFromPacketHeader(const QByteArray& packet) { } QByteArray hashFromPacketHeader(const QByteArray& packet) { - return packet.mid(NUM_STATIC_HEADER_BYTES - NUM_BYTES_MD5_HASH, NUM_BYTES_MD5_HASH); + return packet.mid(numBytesForPacketHeader(packet) - NUM_BYTES_MD5_HASH, NUM_BYTES_MD5_HASH); } QByteArray hashForPacketAndConnectionUUID(const QByteArray& packet, const QUuid& connectionUUID) { - return QCryptographicHash::hash(packet.mid(numBytesForPacketHeader(packet)) - + connectionUUID.toRfc4122(), QCryptographicHash::Md5); + return QCryptographicHash::hash(packet.mid(numBytesForPacketHeader(packet)) + connectionUUID.toRfc4122(), + QCryptographicHash::Md5); } void replaceHashInPacketGivenConnectionUUID(QByteArray& packet, const QUuid& connectionUUID) { From 72a3e6f22c4ccf6e2b163284ae77d050cb781540 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Feb 2014 13:49:59 -0800 Subject: [PATCH 06/10] fix long column in NodeList --- libraries/shared/src/NodeList.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 257c4a0ea7..ca4e8ab7b4 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -114,7 +114,8 @@ public: SharedNodePointer nodeWithUUID(const QUuid& nodeUUID); SharedNodePointer sendingNodeForPacket(const QByteArray& packet); - SharedNodePointer addOrUpdateNode(const QUuid& uuid, char nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); + SharedNodePointer addOrUpdateNode(const QUuid& uuid, char nodeType, + const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); void processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet); void processKillNode(const QByteArray& datagram); From dd4d944dea44a639742ce9193a4e363363fb2971 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Feb 2014 14:06:42 -0800 Subject: [PATCH 07/10] ping inactive nodes in conjunction with domain server check in --- assignment-client/src/Agent.cpp | 4 ---- assignment-client/src/octree/OctreeServer.cpp | 4 ---- interface/src/DatagramProcessor.cpp | 2 +- libraries/shared/src/NodeList.cpp | 14 +++++++------- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 0030e3ffb8..cc0ddd59f2 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -107,10 +107,6 @@ void Agent::run() { connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000); - QTimer* pingNodesTimer = new QTimer(this); - connect(pingNodesTimer, SIGNAL(timeout()), nodeList, SLOT(pingInactiveNodes())); - pingNodesTimer->start(PING_INACTIVE_NODE_INTERVAL_USECS / 1000); - // tell our script engine about our local particle tree _scriptEngine.getParticlesScriptingInterface()->setParticleTree(&_particleTree); diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 7d237f46e2..1fb858c884 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -655,8 +655,4 @@ void OctreeServer::run() { QTimer* silentNodeTimer = new QTimer(this); connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000); - - QTimer* pingNodesTimer = new QTimer(this); - connect(pingNodesTimer, SIGNAL(timeout()), nodeList, SLOT(pingInactiveNodes())); - pingNodesTimer->start(PING_INACTIVE_NODE_INTERVAL_USECS / 1000); } diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index 6271ef5fde..d8447168cd 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -121,7 +121,7 @@ void DatagramProcessor::processDatagrams() { DataServerClient::processMessageFromDataServer(incomingPacket); break; default: - NodeList::getInstance()->processNodeData(senderSockAddr, incomingPacket); + nodeList->processNodeData(senderSockAddr, incomingPacket); break; } } diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 0dc94a20b3..2e78537734 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -140,8 +140,6 @@ qint64 NodeList::writeDatagram(const QByteArray& datagram, const SharedNodePoint // setup the MD5 hash for source verification in the header replaceHashInPacketGivenConnectionUUID(datagramCopy, destinationNode->getConnectionSecret()); - qDebug() << "Sending a packet of type" << packetTypeForPacket(datagram); - return _nodeSocket.writeDatagram(datagramCopy, destinationSockAddr->getAddress(), destinationSockAddr->getPort()); } @@ -234,9 +232,10 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteAr } case PacketTypePing: { // send back a reply - if (sendingNodeForPacket(packet)) { + SharedNodePointer matchingNode = sendingNodeForPacket(packet); + if (matchingNode) { QByteArray replyPacket = constructPingReplyPacket(packet); - writeDatagram(replyPacket, sendingNodeForPacket(packet), senderSockAddr); + writeDatagram(replyPacket, matchingNode, senderSockAddr); } break; @@ -608,6 +607,10 @@ int NodeList::processDomainServerList(const QByteArray& packet) { packetStream >> connectionUUID; node->setConnectionSecret(connectionUUID); } + + // ping inactive nodes in conjunction with receipt of list from domain-server + // this makes it happen every second and also pings any newly added nodes + pingInactiveNodes(); return readNodes; } @@ -681,9 +684,6 @@ SharedNodePointer NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType, // we didn't have this node, so add them Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket); SharedNodePointer newNodeSharedPointer(newNode, &QObject::deleteLater); - - // try and ping the new node right away to open a connection - pingPublicAndLocalSocketsForInactiveNode(newNodeSharedPointer); _nodeHash.insert(newNode->getUUID(), newNodeSharedPointer); From 3bf0ed719cac007807bf279fe7dff091ca9dc8c1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Feb 2014 14:08:42 -0800 Subject: [PATCH 08/10] remove a comment in HifiSockAddr --- libraries/shared/src/HifiSockAddr.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/shared/src/HifiSockAddr.cpp b/libraries/shared/src/HifiSockAddr.cpp index 44eedc6b17..cc031525d8 100644 --- a/libraries/shared/src/HifiSockAddr.cpp +++ b/libraries/shared/src/HifiSockAddr.cpp @@ -45,8 +45,6 @@ HifiSockAddr::HifiSockAddr(const QString& hostname, quint16 hostOrderPort) { } HifiSockAddr& HifiSockAddr::operator=(const HifiSockAddr& rhsSockAddr) { - //HifiSockAddr temp(rhsSockAddr); - //swap(temp); _address = rhsSockAddr._address; _port = rhsSockAddr._port; From a1a4a3db8a1aa7cce6ca5c5075bd3fcfa86a2732 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Feb 2014 14:27:10 -0800 Subject: [PATCH 09/10] HifiSockAddr to SharedNodePointer changes in MetavoxelServer --- .../src/metavoxels/MetavoxelServer.cpp | 34 +++++++++++-------- .../src/metavoxels/MetavoxelServer.h | 8 ++--- interface/src/MetavoxelSystem.cpp | 4 +-- interface/src/MetavoxelSystem.h | 2 +- libraries/metavoxels/src/MetavoxelUtil.cpp | 4 +-- libraries/metavoxels/src/MetavoxelUtil.h | 3 +- libraries/shared/src/DataServerClient.cpp | 2 +- 7 files changed, 31 insertions(+), 26 deletions(-) diff --git a/assignment-client/src/metavoxels/MetavoxelServer.cpp b/assignment-client/src/metavoxels/MetavoxelServer.cpp index 4df72f5de9..fa934142d3 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.cpp +++ b/assignment-client/src/metavoxels/MetavoxelServer.cpp @@ -50,10 +50,13 @@ void MetavoxelServer::readPendingDatagrams() { while (readAvailableDatagram(receivedPacket, senderSockAddr)) { if (nodeList->packetVersionAndHashMatch(receivedPacket)) { switch (packetTypeForPacket(receivedPacket)) { - case PacketTypeMetavoxelData: - processData(receivedPacket, senderSockAddr); + case PacketTypeMetavoxelData: { + SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket); + if (matchingNode) { + processData(receivedPacket, matchingNode); + } break; - + } default: NodeList::getInstance()->processNodeData(senderSockAddr, receivedPacket); break; @@ -76,10 +79,10 @@ void MetavoxelServer::sendDeltas() { _sendTimer.start(qMax(0, 2 * SEND_INTERVAL - elapsed)); } -void MetavoxelServer::processData(const QByteArray& data, const HifiSockAddr& sender) { +void MetavoxelServer::processData(const QByteArray& data, const SharedNodePointer& sendingNode) { // read the session id int headerPlusIDSize; - QUuid sessionID = readSessionID(data, sender, headerPlusIDSize); + QUuid sessionID = readSessionID(data, sendingNode, headerPlusIDSize); if (sessionID.isNull()) { return; } @@ -87,18 +90,19 @@ void MetavoxelServer::processData(const QByteArray& data, const HifiSockAddr& se // forward to session, creating if necessary MetavoxelSession*& session = _sessions[sessionID]; if (!session) { - session = new MetavoxelSession(this, sessionID, QByteArray::fromRawData(data.constData(), headerPlusIDSize), sender); + session = new MetavoxelSession(this, sessionID, QByteArray::fromRawData(data.constData(), headerPlusIDSize), + sendingNode); } - session->receivedData(data, sender); + session->receivedData(data, sendingNode); } MetavoxelSession::MetavoxelSession(MetavoxelServer* server, const QUuid& sessionId, - const QByteArray& datagramHeader, const HifiSockAddr& sender) : + const QByteArray& datagramHeader, const SharedNodePointer& sendingNode) : QObject(server), _server(server), _sessionId(sessionId), _sequencer(datagramHeader), - _sender(sender) { + _sendingNode(sendingNode) { const int TIMEOUT_INTERVAL = 30 * 1000; _timeoutTimer.setInterval(TIMEOUT_INTERVAL); @@ -114,15 +118,15 @@ MetavoxelSession::MetavoxelSession(MetavoxelServer* server, const QUuid& session SendRecord record = { 0 }; _sendRecords.append(record); - qDebug() << "Opened session [sessionId=" << _sessionId << ", sender=" << _sender << "]"; + qDebug() << "Opened session [sessionId=" << _sessionId << ", sendingNode=" << sendingNode << "]"; } -void MetavoxelSession::receivedData(const QByteArray& data, const HifiSockAddr& sender) { +void MetavoxelSession::receivedData(const QByteArray& data, const SharedNodePointer& sendingNode) { // reset the timeout timer _timeoutTimer.start(); // save the most recent sender - _sender = sender; + _sendingNode = sendingNode; // process through sequencer _sequencer.receivedDatagram(data); @@ -140,12 +144,12 @@ void MetavoxelSession::sendDelta() { } void MetavoxelSession::timedOut() { - qDebug() << "Session timed out [sessionId=" << _sessionId << ", sender=" << _sender << "]"; + qDebug() << "Session timed out [sessionId=" << _sessionId << ", sendingNode=" << _sendingNode << "]"; _server->removeSession(_sessionId); } void MetavoxelSession::sendData(const QByteArray& data) { - NodeList::getInstance()->getNodeSocket().writeDatagram(data, _sender.getAddress(), _sender.getPort()); + NodeList::getInstance()->writeDatagram(data, _sendingNode); } void MetavoxelSession::readPacket(Bitstream& in) { @@ -161,7 +165,7 @@ void MetavoxelSession::clearSendRecordsBefore(int index) { void MetavoxelSession::handleMessage(const QVariant& message) { int userType = message.userType(); if (userType == CloseSessionMessage::Type) { - qDebug() << "Session closed [sessionId=" << _sessionId << ", sender=" << _sender << "]"; + qDebug() << "Session closed [sessionId=" << _sessionId << ", sendingNode=" << _sendingNode << "]"; _server->removeSession(_sessionId); } else if (userType == ClientStateMessage::Type) { diff --git a/assignment-client/src/metavoxels/MetavoxelServer.h b/assignment-client/src/metavoxels/MetavoxelServer.h index 5ee861b75d..60fdeca5a5 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.h +++ b/assignment-client/src/metavoxels/MetavoxelServer.h @@ -47,7 +47,7 @@ private slots: private: - void processData(const QByteArray& data, const HifiSockAddr& sender); + void processData(const QByteArray& data, const SharedNodePointer& sendingNode); QTimer _sendTimer; qint64 _lastSend; @@ -64,9 +64,9 @@ class MetavoxelSession : public QObject { public: MetavoxelSession(MetavoxelServer* server, const QUuid& sessionId, - const QByteArray& datagramHeader, const HifiSockAddr& sender); + const QByteArray& datagramHeader, const SharedNodePointer& sendingNode); - void receivedData(const QByteArray& data, const HifiSockAddr& sender); + void receivedData(const QByteArray& data, const SharedNodePointer& sendingNode); void sendDelta(); @@ -96,7 +96,7 @@ private: QTimer _timeoutTimer; DatagramSequencer _sequencer; - HifiSockAddr _sender; + SharedNodePointer _sendingNode; glm::vec3 _position; diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index b6b45a2f99..34c3be5308 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -144,9 +144,9 @@ void MetavoxelSystem::removeClient(const QUuid& uuid) { delete client; } -void MetavoxelSystem::receivedData(const QByteArray& data, const HifiSockAddr& sender) { +void MetavoxelSystem::receivedData(const QByteArray& data, const SharedNodePointer& sendingNode) { int headerPlusIDSize; - QUuid sessionID = readSessionID(data, sender, headerPlusIDSize); + QUuid sessionID = readSessionID(data, sendingNode, headerPlusIDSize); if (sessionID.isNull()) { return; } diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index 0956a9d0d3..7bb7935e4d 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -52,7 +52,7 @@ private: Q_INVOKABLE void addClient(const SharedNodePointer& node); Q_INVOKABLE void removeClient(const QUuid& uuid); - Q_INVOKABLE void receivedData(const QByteArray& data, const HifiSockAddr& sender); + Q_INVOKABLE void receivedData(const QByteArray& data, const SharedNodePointer& sendingNode); class Point { public: diff --git a/libraries/metavoxels/src/MetavoxelUtil.cpp b/libraries/metavoxels/src/MetavoxelUtil.cpp index e762fd06e0..e59cf0fe21 100644 --- a/libraries/metavoxels/src/MetavoxelUtil.cpp +++ b/libraries/metavoxels/src/MetavoxelUtil.cpp @@ -106,7 +106,7 @@ static QItemEditorCreatorBase* qColorEditorCreator = createQColorEditorCreator() static QItemEditorCreatorBase* vec3EditorCreator = createVec3EditorCreator(); static QItemEditorCreatorBase* parameterizedURLEditorCreator = createParameterizedURLEditorCreator(); -QUuid readSessionID(const QByteArray& data, const HifiSockAddr& sender, int& headerPlusIDSize) { +QUuid readSessionID(const QByteArray& data, const SharedNodePointer& sendingNode, int& headerPlusIDSize) { // get the header size int headerSize = numBytesForPacketHeader(data); @@ -114,7 +114,7 @@ QUuid readSessionID(const QByteArray& data, const HifiSockAddr& sender, int& hea const int UUID_BYTES = 16; headerPlusIDSize = headerSize + UUID_BYTES; if (data.size() < headerPlusIDSize) { - qWarning() << "Metavoxel data too short [size=" << data.size() << ", sender=" << sender << "]\n"; + qWarning() << "Metavoxel data too short [size=" << data.size() << ", sendingNode=" << sendingNode << "]\n"; return QUuid(); } return QUuid::fromRfc4122(QByteArray::fromRawData(data.constData() + headerSize, UUID_BYTES)); diff --git a/libraries/metavoxels/src/MetavoxelUtil.h b/libraries/metavoxels/src/MetavoxelUtil.h index 117825be64..9fa721d21c 100644 --- a/libraries/metavoxels/src/MetavoxelUtil.h +++ b/libraries/metavoxels/src/MetavoxelUtil.h @@ -15,6 +15,7 @@ #include #include +#include #include #include "Bitstream.h" @@ -30,7 +31,7 @@ class NetworkProgram; /// Reads and returns the session ID from a datagram. /// \param[out] headerPlusIDSize the size of the header (including the session ID) within the data /// \return the session ID, or a null ID if invalid (in which case a warning will be logged) -QUuid readSessionID(const QByteArray& data, const HifiSockAddr& sender, int& headerPlusIDSize); +QUuid readSessionID(const QByteArray& data, const SharedNodePointer& sendingNode, int& headerPlusIDSize); /// A streamable axis-aligned bounding box. class Box { diff --git a/libraries/shared/src/DataServerClient.cpp b/libraries/shared/src/DataServerClient.cpp index fd003aa3bb..7ca951ba29 100644 --- a/libraries/shared/src/DataServerClient.cpp +++ b/libraries/shared/src/DataServerClient.cpp @@ -21,7 +21,7 @@ quint8 DataServerClient::_sequenceNumber = 0; const char MULTI_KEY_VALUE_SEPARATOR = '|'; -const char DATA_SERVER_HOSTNAME[] = "data.highfidelity.io"; +const char DATA_SERVER_HOSTNAME[] = "localhost"; const unsigned short DATA_SERVER_PORT = 3282; const HifiSockAddr& DataServerClient::dataServerSockAddr() { From f945aac5cd5e7a51133431aac96c507169ce7b35 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 7 Feb 2014 14:32:09 -0800 Subject: [PATCH 10/10] bump version on unverified packets whose header format has changed --- libraries/shared/src/PacketHeaders.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index d4049e7310..b46a57d4aa 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -46,6 +46,17 @@ PacketVersion versionForPacketType(PacketType type) { switch (type) { case PacketTypeParticleData: return 1; + case PacketTypeDomainList: + case PacketTypeDomainListRequest: + return 1; + case PacketTypeCreateAssignment: + case PacketTypeRequestAssignment: + return 1; + case PacketTypeDataServerGet: + case PacketTypeDataServerPut: + case PacketTypeDataServerConfirm: + case PacketTypeDataServerSend: + return 1; default: return 0; }