From 586c3512a77f6cc2739d898ad3ac32a9afc946a9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 24 Jan 2017 17:35:45 -0800 Subject: [PATCH 1/2] remove useless additional includeThisEntity sets --- libraries/entities/src/EntityTreeElement.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 5a7f0d2a87..525c1ec65f 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -309,16 +309,12 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData bool entityMatchesFilters = entity->matchesJSONFilters(jsonFilters); if (entityMatchesFilters) { - // we should include this entity unless it has already been excluded - includeThisEntity = true; - // make sure this entity is in the set of entities sent last frame entityNodeData->insertEntitySentLastFrame(entity->getID()); } else { // we might include this entity if it matched in the previous frame if (entityNodeData->sentEntityLastFrame(entity->getID())) { - includeThisEntity = true; entityNodeData->removeEntitySentLastFrame(entity->getID()); } else { From 9b8cbba53f33cccc634ba15f6b09e4c039d8fe5a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 24 Jan 2017 18:22:22 -0800 Subject: [PATCH 2/2] add isInInterestSet to DomainServer for extra checks --- domain-server/src/DomainServer.cpp | 87 +++++++++++++++++------------- domain-server/src/DomainServer.h | 2 + 2 files changed, 52 insertions(+), 37 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 8e44922424..1424091fdb 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -855,6 +855,44 @@ void DomainServer::processListRequestPacket(QSharedPointer mess sendDomainListToNode(sendingNode, message->getSenderSockAddr()); } +bool DomainServer::isInInterestSet(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB) { + auto nodeAData = static_cast(nodeA->getLinkedData()); + auto nodeBData = static_cast(nodeB->getLinkedData()); + + // if we have no linked data for node A then B can't possibly be in the interest set + if (!nodeAData) { + return false; + } + + // first check if the general interest set A contains the type for B + if (nodeAData->getNodeInterestSet().contains(nodeB->getType())) { + // given that there is a match in the general interest set, do any special checks + + // (1/19/17) Agents only need to connect to Entity Script Servers to perform administrative tasks + // related to entity server scripts. Only agents with rez permissions should be doing that, so + // if the agent does not have those permissions, we do not want them and the server to incur the + // overhead of connecting to one another. Additionally we exclude agents that do not care about the + // Entity Script Server and won't attempt to connect to it. + + bool isAgentWithoutRights = nodeA->getType() == NodeType::Agent + && nodeB->getType() == NodeType::EntityScriptServer + && !nodeA->getCanRez() && !nodeA->getCanRezTmp(); + + if (isAgentWithoutRights) { + return false; + } + + bool isScriptServerForIneffectiveAgent = + (nodeA->getType() == NodeType::EntityScriptServer && nodeB->getType() == NodeType::Agent) + && ((nodeBData && !nodeBData->getNodeInterestSet().contains(NodeType::EntityScriptServer)) + || (!nodeB->getCanRez() && !nodeB->getCanRezTmp())); + + return !isScriptServerForIneffectiveAgent; + } else { + return false; + } +} + unsigned int DomainServer::countConnectedUsers() { unsigned int result = 0; auto nodeList = DependencyManager::get(); @@ -954,40 +992,18 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif if (nodeData->isAuthenticated()) { // if this authenticated node has any interest types, send back those nodes as well limitedNodeList->eachNode([&](const SharedNodePointer& otherNode) { - if (otherNode->getUUID() != node->getUUID() - && nodeInterestSet.contains(otherNode->getType())) { + if (otherNode->getUUID() != node->getUUID() && isInInterestSet(node, otherNode)) { + // since we're about to add a node to the packet we start a segment + domainListPackets->startSegment(); - // (1/19/17) Agents only need to connect to Entity Script Servers to perform administrative tasks - // related to entity server scripts. Only agents with rez permissions should be doing that, so - // if the agent does not have those permissions, we do not want them and the server to incur the - // overhead of connecting to one another. Additionally we exclude agents that do not care about the - // Entity Script Server and won't attempt to connect to it. - auto otherNodeData = static_cast(otherNode->getLinkedData()); + // don't send avatar nodes to other avatars, that will come from avatar mixer + domainListStream << *otherNode.data(); - bool isAgentWithoutRights = node->getType() == NodeType::Agent - && otherNode->getType() == NodeType::EntityScriptServer - && !node->getCanRez() && !node->getCanRezTmp(); + // pack the secret that these two nodes will use to communicate with each other + domainListStream << connectionSecretForNodes(node, otherNode); - bool isScriptServerForIneffectiveAgent = - (node->getType() == NodeType::EntityScriptServer && otherNode->getType() == NodeType::Agent) - && (!otherNodeData->getNodeInterestSet().contains(NodeType::EntityServer) - || (!otherNode->getCanRez() && !otherNode->getCanRezTmp())); - - bool shouldNotConnect = isAgentWithoutRights || isScriptServerForIneffectiveAgent; - - if (!shouldNotConnect) { - // since we're about to add a node to the packet we start a segment - domainListPackets->startSegment(); - - // don't send avatar nodes to other avatars, that will come from avatar mixer - domainListStream << *otherNode.data(); - - // pack the secret that these two nodes will use to communicate with each other - domainListStream << connectionSecretForNodes(node, otherNode); - - // we've added the node we wanted so end the segment now - domainListPackets->endSegment(); - } + // we've added the node we wanted so end the segment now + domainListPackets->endSegment(); } }); } @@ -1038,8 +1054,7 @@ void DomainServer::broadcastNewNode(const SharedNodePointer& addedNode) { [&](const SharedNodePointer& node)->bool { if (node->getLinkedData() && node->getActiveSocket() && node != addedNode) { // is the added Node in this node's interest list? - DomainServerNodeData* nodeData = dynamic_cast(node->getLinkedData()); - return nodeData->getNodeInterestSet().contains(addedNode->getType()); + return isInInterestSet(node, addedNode); } else { return false; } @@ -2389,7 +2404,6 @@ void DomainServer::processNodeDisconnectRequestPacket(QSharedPointergetType(); auto limitedNodeList = DependencyManager::get(); const QUuid& nodeUUID = nodeToKill->getUUID(); @@ -2401,10 +2415,9 @@ void DomainServer::handleKillNode(SharedNodePointer nodeToKill) { removedNodePacket->write(nodeUUID.toRfc4122()); // broadcast out the DomainServerRemovedNode message - limitedNodeList->eachMatchingNode([&nodeType](const SharedNodePointer& otherNode) -> bool { + limitedNodeList->eachMatchingNode([this, &nodeToKill](const SharedNodePointer& otherNode) -> bool { // only send the removed node packet to nodes that care about the type of node this was - auto nodeLinkedData = dynamic_cast(otherNode->getLinkedData()); - return (nodeLinkedData != nullptr) && nodeLinkedData->getNodeInterestSet().contains(nodeType); + return isInInterestSet(otherNode, nodeToKill); }, [&limitedNodeList](const SharedNodePointer& otherNode){ limitedNodeList->sendUnreliablePacket(*removedNodePacket, *otherNode); }); diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 73135695eb..4c5c42acee 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -132,6 +132,8 @@ private: void sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr& senderSockAddr); + bool isInInterestSet(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB); + QUuid connectionSecretForNodes(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB); void broadcastNewNode(const SharedNodePointer& node);