diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 5750a33faf..35be97d610 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -927,15 +927,22 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif const NodeSet& nodeInterestSet) { auto limitedNodeList = DependencyManager::get(); - auto listPacket = NodeListPacket::make(PacketType::DomainList); + PacketList domainListPackets(PacketType::DomainList); // always send the node their own UUID back - QDataStream broadcastDataStream(&listPacket.payload(), QIODevice::Append); - broadcastDataStream << node->getUUID(); - broadcastDataStream << node->getCanAdjustLocks(); - broadcastDataStream << node->getCanRez(); + QDataStream domainListStream(&domainListPackets); - int numBroadcastPacketLeadBytes = broadcastDataStream.device()->pos(); + const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + 2; + + // setup the extended header for the domain list packets + // this data is at the beginning of each of the domain list packets + QByteArray extendedHeader(NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES, 0); + extendedHeader.replace(0, NUM_BYTES_RFC4122_UUID, node->getUUID().toRfc4122()); + + extendedHeader[NUM_BYTES_RFC4122_UUID] = (char) node->getCanAdjustLocks(); + extendedHeader[NUM_BYTES_RFC4122_UUID + 1] = (char) node->getCanRez(); + + domainListPackets.setExtendedHeader(extendedHeader); DomainServerNodeData* nodeData = reinterpret_cast(node->getLinkedData()); @@ -944,44 +951,29 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif if (nodeInterestSet.size() > 0) { -// DTLSServerSession* dtlsSession = _isUsingDTLS ? _dtlsSessions[senderSockAddr] : NULL; - int dataMTU = MAX_PACKET_SIZE; - + // DTLSServerSession* dtlsSession = _isUsingDTLS ? _dtlsSessions[senderSockAddr] : NULL; if (nodeData->isAuthenticated()) { // if this authenticated node has any interest types, send back those nodes as well limitedNodeList->eachNode([&](const SharedNodePointer& otherNode){ - // reset our nodeByteArray and nodeDataStream - QByteArray nodeByteArray; - QDataStream nodeDataStream(&nodeByteArray, QIODevice::Append); - if (otherNode->getUUID() != node->getUUID() && nodeInterestSet.contains(otherNode->getType())) { + // since we're about to add a node to the packet we start a segment + domainListStream.startSegment(); // don't send avatar nodes to other avatars, that will come from avatar mixer - nodeDataStream << *otherNode.data(); + domainListStream << *otherNode.data(); // pack the secret that these two nodes will use to communicate with each other - nodeDataStream << connectionSecretForNodes(node, otherNode); + domainListStream << connectionSecretForNodes(node, otherNode); - if (broadcastPacket.size() + nodeByteArray.size() > dataMTU) { - // we need to break here and start a new packet - // so send the current one - - limitedNodeList->writeUnverifiedDatagram(broadcastPacket, node, senderSockAddr); - - // reset the broadcastPacket structure - broadcastPacket.resize(numBroadcastPacketLeadBytes); - broadcastDataStream.device()->seek(numBroadcastPacketLeadBytes); - } - - // append the nodeByteArray to the current state of broadcastDataStream - broadcastPacket.append(nodeByteArray); + // we've added the node we wanted so end the segment now + domainListStream.endSegment(); } }); } } - // always write the last broadcastPacket - limitedNodeList->writeUnverifiedDatagram(broadcastPacket, node); + // write the PacketList to this node + limitedNodeList->sendPacketList(domainListPackets, node); } QUuid DomainServer::connectionSecretForNodes(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB) { diff --git a/libraries/networking/src/PacketList.cpp b/libraries/networking/src/PacketList.cpp index 3dcdf5a799..2161af679a 100644 --- a/libraries/networking/src/PacketList.cpp +++ b/libraries/networking/src/PacketList.cpp @@ -18,10 +18,21 @@ PacketList::PacketList(PacketType::Value packetType, bool isOrdered) : } +void PacketList::createPacketWithExtendedHeader() { + // use the static create method to create a new packet + _currentPacket = T::create(_packetType); + + // add the extended header to the front of the packet + if (_currentPacket.write(_extendedHeader) == -1) { + qDebug() << "Could not write extendedHeader in PacketList::createPacketWithExtendedHeader" + << "- make sure that _extendedHeader is not larger than the payload capacity."; + } +} + qint64 writeData(const char* data, qint64 maxSize) { if (!_currentPacket) { // we don't have a current packet, time to set one up - _currentPacket = T::create(_packetType); + createPacketWithExtendedHeader(); } // check if this block of data can fit into the currentPacket @@ -36,13 +47,13 @@ qint64 writeData(const char* data, qint64 maxSize) { if (!_isOrdered) { auto newPacket = T::create(_packetType); - PacketPayload& newPayload = newPacket.payload(); + PacketPayload& newPayload = newPacket.getPayload(); if (_segmentStartIndex >= 0) { // We in the process of writing a segment for an unordered PacketList. // We need to try and pull the first part of the segment out to our new packet - PacketPayload& currentPayload = _currentPacket->payload(); + PacketPayload& currentPayload = _currentPacket->getPayload(); // check now to see if this is an unsupported write int numBytesToEnd = currentPayload.size() - _segmentStartIndex; @@ -82,7 +93,7 @@ qint64 writeData(const char* data, qint64 maxSize) { } else { // we're an ordered PacketList - let's fit what we can into the current packet and then put the leftover // into a new packet - PacketPayload& currentPayload = _currentPacket.payload(); + PacketPayload& currentPayload = _currentPacket.getPayload(); int numBytesToEnd = _currentPayload.size() - _currentPayload.pos(); _currentPacket.write(data, numBytesToEnd); @@ -96,3 +107,11 @@ qint64 writeData(const char* data, qint64 maxSize) { } } +void PacketList::closeCurrentPacket() { + // shrink the current payload to the actual size of the packet + _currentPacket.getPayload().trim(); + + // move the current packet to our list of packets + _packets.insert(std::move(_currentPacket)); +} + diff --git a/libraries/networking/src/PacketList.h b/libraries/networking/src/PacketList.h index 3fffb328d2..1b0905a1c8 100644 --- a/libraries/networking/src/PacketList.h +++ b/libraries/networking/src/PacketList.h @@ -22,10 +22,16 @@ public: void startSegment() { _segmentStartIndex = currentPacket->payload().pos(); } void endSegment() { _segmentStartIndex = -1; } + + void closeCurrentPacket(); + + void setExtendedHeader(const QByteArray& extendedHeader) { _extendedHeader = extendedHeader; } protected: qint64 writeData(const char* data, qint64 maxSize); qint64 readData(const char* data, qint64 maxSize) { return 0 }; private: + void createPacketWithExtendedHeader(); + PacketType::Value _packetType; bool isOrdered; @@ -33,6 +39,8 @@ private: std::list> _packets; int _segmentStartIndex = -1; + + QByteArray _extendedHeader = extendedHeader; } #endif // hifi_PacketList_h