From 5c75863af43e1f511bc668dd8fb6afc3144419ea Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 28 May 2015 10:45:03 -0700 Subject: [PATCH] immediately send add packet from DS for new node --- domain-server/src/DomainServer.cpp | 87 +++++++++++++++++++----- domain-server/src/DomainServer.h | 3 + libraries/networking/src/PacketHeaders.h | 17 ++--- 3 files changed, 81 insertions(+), 26 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 2c784abe54..8eaf1a29f3 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -654,6 +654,19 @@ void DomainServer::handleConnectRequest(const QByteArray& packet, const HifiSock SharedNodePointer newNode = limitedNodeList->addOrUpdateNode(nodeUUID, nodeType, publicSockAddr, localSockAddr, canAdjustLocks, canRez); + + // So that we can send messages to this node at will - we need to activate the correct socket on this node now + if (senderSockAddr == publicSockAddr) { + newNode->activatePublicSocket(); + } else if (senderSockAddr == localSockAddr) { + newNode->activateLocalSocket(); + } else { + // set the Node's symmetric socket to the sender socket + newNode->setSymmetricSocket(senderSockAddr); + // activate that symmetric socket + newNode->activateSymmetricSocket(); + } + // when the newNode is created the linked data is also created // if this was a static assignment set the UUID, set the sendingSockAddr DomainServerNodeData* nodeData = reinterpret_cast(newNode->getLinkedData()); @@ -683,6 +696,9 @@ void DomainServer::handleConnectRequest(const QByteArray& packet, const HifiSock // reply back to the user with a PacketTypeDomainList sendDomainListToNode(newNode, senderSockAddr, nodeInterestList.toSet()); + + // send out this node to our other connected nodes + broadcastNewNode(newNode); } } @@ -699,9 +715,9 @@ unsigned int DomainServer::countConnectedUsers() { } -bool DomainServer::verifyUsersKey (const QString& username, - const QByteArray& usernameSignature, - QString& reasonReturn) { +bool DomainServer::verifyUsersKey(const QString& username, + const QByteArray& usernameSignature, + QString& reasonReturn) { // it's possible this user can be allowed to connect, but we need to check their username signature QByteArray publicKeyArray = _userPublicKeys.value(username); @@ -954,21 +970,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif nodeDataStream << *otherNode.data(); // pack the secret that these two nodes will use to communicate with each other - QUuid secretUUID = nodeData->getSessionSecretHash().value(otherNode->getUUID()); - if (secretUUID.isNull()) { - // generate a new secret UUID these two nodes can use - secretUUID = QUuid::createUuid(); - - // set that on the current Node's sessionSecretHash - nodeData->getSessionSecretHash().insert(otherNode->getUUID(), secretUUID); - - // set it on the other Node's sessionSecretHash - reinterpret_cast(otherNode->getLinkedData()) - ->getSessionSecretHash().insert(node->getUUID(), secretUUID); - - } - - nodeDataStream << secretUUID; + nodeDataStream << connectionSecretForNodes(node, otherNode); if (broadcastPacket.size() + nodeByteArray.size() > dataMTU) { // we need to break here and start a new packet @@ -992,6 +994,55 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif limitedNodeList->writeUnverifiedDatagram(broadcastPacket, node, senderSockAddr); } +QUuid DomainServer::connectionSecretForNodes(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB) { + DomainServerNodeData* nodeAData = dynamic_cast(nodeA->getLinkedData()); + DomainServerNodeData* nodeBData = dynamic_cast(nodeB->getLinkedData()); + + if (nodeAData && nodeBData) { + QUuid& secretUUID = nodeAData->getSessionSecretHash()[nodeB->getUUID()]; + + if (secretUUID.isNull()) { + // generate a new secret UUID these two nodes can use + secretUUID = QUuid::createUuid(); + + // set it on the other Node's sessionSecretHash + reinterpret_cast(nodeBData)->getSessionSecretHash().insert(nodeA->getUUID(), secretUUID); + } + + return secretUUID; + } + + return QUuid(); +} + +void DomainServer::broadcastNewNode(const SharedNodePointer& addedNode) { + + auto limitedNodeList = DependencyManager::get(); + + // setup the add packet for this new node + QByteArray addNodePacket = limitedNodeList->byteArrayWithPopulatedHeader(PacketTypeDomainServerAddedNode); + QDataStream addNodeStream(&addNodePacket, QIODevice::Append); + + addNodeStream << *addedNode.data(); + + int connectionSecretIndex = addNodePacket.size(); + + limitedNodeList->eachMatchingNode( + [&](const SharedNodePointer& node)->bool { + return (node->getLinkedData() && node->getActiveSocket() && node != addedNode); + }, + [&](const SharedNodePointer& node) { + QByteArray rfcConnectionSecret = connectionSecretForNodes(node, addedNode).toRfc4122(); + + // replace the bytes at the end of the packet for the connection secret between these nodes + addNodePacket.replace(connectionSecretIndex, NUM_BYTES_RFC4122_UUID, rfcConnectionSecret); + + // send off this packet to the node + limitedNodeList->writeUnverifiedDatagram(addNodePacket, node); + } + ); +} + void DomainServer::readAvailableDatagrams() { auto limitedNodeList = DependencyManager::get(); diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 22e3efa378..c70c9cec13 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -101,6 +101,9 @@ private: void sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr& senderSockAddr, const NodeSet& nodeInterestList); + QUuid connectionSecretForNodes(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB); + void broadcastNewNode(const SharedNodePointer& node); + void parseAssignmentConfigs(QSet& excludedTypes); void addStaticAssignmentToAssignmentHash(Assignment* newAssignment); void createStaticAssignmentsForType(Assignment::Type type, const QVariantList& configList); diff --git a/libraries/networking/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h index 56045be1c3..a702df7798 100644 --- a/libraries/networking/src/PacketHeaders.h +++ b/libraries/networking/src/PacketHeaders.h @@ -91,14 +91,15 @@ const PacketSequenceNumber DEFAULT_SEQUENCE_NUMBER = 0; typedef std::map PacketTypeSequenceMap; const QSet NON_VERIFIED_PACKETS = QSet() -<< PacketTypeDomainServerRequireDTLS << PacketTypeDomainConnectRequest -<< PacketTypeDomainList << PacketTypeDomainListRequest << PacketTypeDomainConnectionDenied -<< PacketTypeCreateAssignment << PacketTypeRequestAssignment << PacketTypeStunResponse -<< PacketTypeNodeJsonStats << PacketTypeEntityQuery -<< PacketTypeOctreeDataNack << PacketTypeEntityEditNack -<< PacketTypeIceServerHeartbeat << PacketTypeIceServerHeartbeatResponse -<< PacketTypeUnverifiedPing << PacketTypeUnverifiedPingReply << PacketTypeStopNode -<< PacketTypeDomainServerPathQuery << PacketTypeDomainServerPathResponse; + << PacketTypeDomainServerRequireDTLS << PacketTypeDomainConnectRequest + << PacketTypeDomainList << PacketTypeDomainListRequest << PacketTypeDomainConnectionDenied + << PacketTypeCreateAssignment << PacketTypeRequestAssignment << PacketTypeStunResponse + << PacketTypeNodeJsonStats << PacketTypeEntityQuery + << PacketTypeOctreeDataNack << PacketTypeEntityEditNack + << PacketTypeIceServerHeartbeat << PacketTypeIceServerHeartbeatResponse + << PacketTypeUnverifiedPing << PacketTypeUnverifiedPingReply << PacketTypeStopNode + << PacketTypeDomainServerPathQuery << PacketTypeDomainServerPathResponse + << PacketTypeDomainServerAddedNode; const QSet SEQUENCE_NUMBERED_PACKETS = QSet() << PacketTypeAvatarData;