// Returns the set of all nodes between tail and head, assuming // head and tail form a single entry and exit point. // Possible is there just for debugging. There should be no nodes outside possible NodeSet CollectNodesBetween(ControlFlowNode *head, ControlFlowNode *tail, NodeSet possible) { NodeSet collection; stack<ControlFlowNode*> toProcess; toProcess.push(tail); while (!toProcess.empty()) { ControlFlowNode *node = toProcess.top(); toProcess.pop(); collection.insert(node); if (node != head) { for (ControlFlowNode *pred : node->Predecessors()) { if (!collection.contains(pred)) // Haven't already visited it { assert(possible.contains(pred));// We could just filter these, but let's assert for now to catch bad callers. toProcess.push(pred); } } } } return collection; }
void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessage> message) { if (message->getSize() == 0) { return; } QDataStream packetStream(message->getMessage()); // read a NodeConnectionData object from the packet so we can pass around this data while we're inspecting it NodeConnectionData nodeConnection = NodeConnectionData::fromDataStream(packetStream, message->getSenderSockAddr()); QByteArray myProtocolVersion = protocolVersionsSignature(); if (nodeConnection.protocolVersion != myProtocolVersion) { sendProtocolMismatchConnectionDenial(message->getSenderSockAddr()); return; } if (nodeConnection.localSockAddr.isNull() || nodeConnection.publicSockAddr.isNull()) { qDebug() << "Unexpected data received for node local socket or public socket. Will not allow connection."; return; } static const NodeSet VALID_NODE_TYPES { NodeType::AudioMixer, NodeType::AvatarMixer, NodeType::AssetServer, NodeType::EntityServer, NodeType::Agent, NodeType::MessagesMixer, NodeType::EntityScriptServer }; if (!VALID_NODE_TYPES.contains(nodeConnection.nodeType)) { qDebug() << "Received an invalid node type with connect request. Will not allow connection from" << nodeConnection.senderSockAddr << ": " << nodeConnection.nodeType; return; } // check if this connect request matches an assignment in the queue auto pendingAssignment = _pendingAssignedNodes.find(nodeConnection.connectUUID); SharedNodePointer node; if (pendingAssignment != _pendingAssignedNodes.end()) { node = processAssignmentConnectRequest(nodeConnection, pendingAssignment->second); } else if (!STATICALLY_ASSIGNED_NODES.contains(nodeConnection.nodeType)) { QString username; QByteArray usernameSignature; if (message->getBytesLeftToRead() > 0) { // read username from packet packetStream >> username; if (message->getBytesLeftToRead() > 0) { // read user signature from packet packetStream >> usernameSignature; }
bool IsReachable(ControlFlowNode *head, ControlFlowNode *tail) { if (head == tail) { return true; } NodeSet visited; visited.insert(tail); stack<ControlFlowNode*> toProcess; toProcess.push(tail); while (!toProcess.empty()) { ControlFlowNode *node = toProcess.top(); toProcess.pop(); for (ControlFlowNode *pred : node->Predecessors()) { if (pred == head) { return true; } if (!visited.contains(pred)) { visited.insert(pred); toProcess.push(pred); } } } return false; }
unsigned LimitedNodeList::broadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) { unsigned n = 0; foreach (const SharedNodePointer& node, getNodeHash()) { // only send to the NodeTypes we are asked to send to. if (destinationNodeTypes.contains(node->getType())) { writeDatagram(packet, node); ++n; } } return n; }