Merge pull request #12743 from SimonWalton-HiFi/short-id

Use 16-bit local IDs for Nodes in NL packets
This commit is contained in:
John Conklin II 2018-04-20 15:28:18 -07:00 committed by GitHub
commit 39ad8be1b8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 209 additions and 94 deletions

View file

@ -901,7 +901,7 @@ void AssetServer::handleAssetUpload(QSharedPointer<ReceivedMessage> message, Sha
if (canWriteToAssetServer) { if (canWriteToAssetServer) {
qCDebug(asset_server) << "Starting an UploadAssetTask for upload from" << uuidStringWithoutCurlyBraces(message->getSourceID()); qCDebug(asset_server) << "Starting an UploadAssetTask for upload from" << message->getSourceID();
auto task = new UploadAssetTask(message, senderNode, _filesDirectory, _filesizeLimit); auto task = new UploadAssetTask(message, senderNode, _filesDirectory, _filesizeLimit);
_transferTaskPool.start(task); _transferTaskPool.start(task);

View file

@ -118,11 +118,12 @@ void AudioMixer::queueReplicatedAudioPacket(QSharedPointer<ReceivedMessage> mess
// make sure we have a replicated node for the original sender of the packet // make sure we have a replicated node for the original sender of the packet
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
// Node ID is now part of user data, since replicated audio packets are non-sourced.
QUuid nodeID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); QUuid nodeID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
auto replicatedNode = nodeList->addOrUpdateNode(nodeID, NodeType::Agent, auto replicatedNode = nodeList->addOrUpdateNode(nodeID, NodeType::Agent,
message->getSenderSockAddr(), message->getSenderSockAddr(), message->getSenderSockAddr(), message->getSenderSockAddr(),
true, true); Node::NULL_LOCAL_ID, true, true);
replicatedNode->setLastHeardMicrostamp(usecTimestampNow()); replicatedNode->setLastHeardMicrostamp(usecTimestampNow());
// construct a "fake" audio received message from the byte array and packet list information // construct a "fake" audio received message from the byte array and packet list information
@ -136,7 +137,7 @@ void AudioMixer::queueReplicatedAudioPacket(QSharedPointer<ReceivedMessage> mess
auto replicatedMessage = QSharedPointer<ReceivedMessage>::create(audioData, rewrittenType, auto replicatedMessage = QSharedPointer<ReceivedMessage>::create(audioData, rewrittenType,
versionForPacketType(rewrittenType), versionForPacketType(rewrittenType),
message->getSenderSockAddr(), nodeID); message->getSenderSockAddr(), Node::NULL_LOCAL_ID);
getOrCreateClientData(replicatedNode.data())->queuePacket(replicatedMessage, replicatedNode); getOrCreateClientData(replicatedNode.data())->queuePacket(replicatedMessage, replicatedNode);
} }

View file

@ -74,7 +74,7 @@ SharedNodePointer addOrUpdateReplicatedNode(const QUuid& nodeID, const HifiSockA
auto replicatedNode = DependencyManager::get<NodeList>()->addOrUpdateNode(nodeID, NodeType::Agent, auto replicatedNode = DependencyManager::get<NodeList>()->addOrUpdateNode(nodeID, NodeType::Agent,
senderSockAddr, senderSockAddr,
senderSockAddr, senderSockAddr,
true, true); Node::NULL_LOCAL_ID, true, true);
replicatedNode->setLastHeardMicrostamp(usecTimestampNow()); replicatedNode->setLastHeardMicrostamp(usecTimestampNow());
@ -112,8 +112,8 @@ void AvatarMixer::handleReplicatedPacket(QSharedPointer<ReceivedMessage> message
void AvatarMixer::handleReplicatedBulkAvatarPacket(QSharedPointer<ReceivedMessage> message) { void AvatarMixer::handleReplicatedBulkAvatarPacket(QSharedPointer<ReceivedMessage> message) {
while (message->getBytesLeftToRead()) { while (message->getBytesLeftToRead()) {
// first, grab the node ID for this replicated avatar // first, grab the node ID for this replicated avatar
// Node ID is now part of user data, since ReplicatedBulkAvatarPacket is non-sourced.
auto nodeID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); auto nodeID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
// make sure we have an upstream replicated node that matches // make sure we have an upstream replicated node that matches
auto replicatedNode = addOrUpdateReplicatedNode(nodeID, message->getSenderSockAddr()); auto replicatedNode = addOrUpdateReplicatedNode(nodeID, message->getSenderSockAddr());
@ -127,7 +127,7 @@ void AvatarMixer::handleReplicatedBulkAvatarPacket(QSharedPointer<ReceivedMessag
// construct a "fake" avatar data received message from the byte array and packet list information // construct a "fake" avatar data received message from the byte array and packet list information
auto replicatedMessage = QSharedPointer<ReceivedMessage>::create(avatarByteArray, PacketType::AvatarData, auto replicatedMessage = QSharedPointer<ReceivedMessage>::create(avatarByteArray, PacketType::AvatarData,
versionForPacketType(PacketType::AvatarData), versionForPacketType(PacketType::AvatarData),
message->getSenderSockAddr(), nodeID); message->getSenderSockAddr(), Node::NULL_LOCAL_ID);
// queue up the replicated avatar data with the client data for the replicated node // queue up the replicated avatar data with the client data for the replicated node
auto start = usecTimestampNow(); auto start = usecTimestampNow();

View file

@ -14,6 +14,7 @@
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/rsa.h> #include <openssl/rsa.h>
#include <openssl/x509.h> #include <openssl/x509.h>
#include <random>
#include <AccountManager.h> #include <AccountManager.h>
#include <Assignment.h> #include <Assignment.h>
@ -26,7 +27,7 @@ using SharedAssignmentPointer = QSharedPointer<Assignment>;
DomainGatekeeper::DomainGatekeeper(DomainServer* server) : DomainGatekeeper::DomainGatekeeper(DomainServer* server) :
_server(server) _server(server)
{ {
initLocalIDManagement();
} }
void DomainGatekeeper::addPendingAssignedNode(const QUuid& nodeUUID, const QUuid& assignmentUUID, void DomainGatekeeper::addPendingAssignedNode(const QUuid& nodeUUID, const QUuid& assignmentUUID,
@ -529,8 +530,10 @@ SharedNodePointer DomainGatekeeper::addVerifiedNodeFromConnectRequest(const Node
auto limitedNodeList = DependencyManager::get<LimitedNodeList>(); auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
Node::LocalID newLocalID = findOrCreateLocalID(nodeID);
SharedNodePointer newNode = limitedNodeList->addOrUpdateNode(nodeID, nodeConnection.nodeType, SharedNodePointer newNode = limitedNodeList->addOrUpdateNode(nodeID, nodeConnection.nodeType,
nodeConnection.publicSockAddr, nodeConnection.localSockAddr); nodeConnection.publicSockAddr, nodeConnection.localSockAddr,
newLocalID);
// So that we can send messages to this node at will - we need to activate the correct socket on this node now // So that we can send messages to this node at will - we need to activate the correct socket on this node now
newNode->activateMatchingOrNewSymmetricSocket(discoveredSocket); newNode->activateMatchingOrNewSymmetricSocket(discoveredSocket);
@ -1020,3 +1023,31 @@ void DomainGatekeeper::refreshGroupsCache() {
_server->_settingsManager.debugDumpGroupsState(); _server->_settingsManager.debugDumpGroupsState();
#endif #endif
} }
void DomainGatekeeper::initLocalIDManagement() {
std::uniform_int_distribution<quint16> sixteenBitRand;
std::random_device randomDevice;
std::default_random_engine engine { randomDevice() };
_currentLocalID = sixteenBitRand(engine);
// Ensure increment is odd.
_idIncrement = sixteenBitRand(engine) | 1;
}
Node::LocalID DomainGatekeeper::findOrCreateLocalID(const QUuid& uuid) {
auto existingLocalIDIt = _uuidToLocalID.find(uuid);
if (existingLocalIDIt != _uuidToLocalID.end()) {
return existingLocalIDIt->second;
}
assert(_localIDs.size() < std::numeric_limits<LocalIDs::value_type>::max() - 2);
Node::LocalID newLocalID;
do {
newLocalID = _currentLocalID;
_currentLocalID += _idIncrement;
} while (newLocalID == Node::NULL_LOCAL_ID || _localIDs.find(newLocalID) != _localIDs.end());
_uuidToLocalID.emplace(uuid, newLocalID);
_localIDs.insert(newLocalID);
return newLocalID;
}

View file

@ -15,6 +15,7 @@
#define hifi_DomainGatekeeper_h #define hifi_DomainGatekeeper_h
#include <unordered_map> #include <unordered_map>
#include <unordered_set>
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtNetwork/QNetworkReply> #include <QtNetwork/QNetworkReply>
@ -41,6 +42,8 @@ public:
void removeICEPeer(const QUuid& peerUUID) { _icePeers.remove(peerUUID); } void removeICEPeer(const QUuid& peerUUID) { _icePeers.remove(peerUUID); }
Node::LocalID findOrCreateLocalID(const QUuid& uuid);
static void sendProtocolMismatchConnectionDenial(const HifiSockAddr& senderSockAddr); static void sendProtocolMismatchConnectionDenial(const HifiSockAddr& senderSockAddr);
public slots: public slots:
void processConnectRequestPacket(QSharedPointer<ReceivedMessage> message); void processConnectRequestPacket(QSharedPointer<ReceivedMessage> message);
@ -120,6 +123,16 @@ private:
void getGroupMemberships(const QString& username); void getGroupMemberships(const QString& username);
// void getIsGroupMember(const QString& username, const QUuid groupID); // void getIsGroupMember(const QString& username, const QUuid groupID);
void getDomainOwnerFriendsList(); void getDomainOwnerFriendsList();
// Local ID management.
void initLocalIDManagement();
using UUIDToLocalID = std::unordered_map<QUuid, Node::LocalID> ;
using LocalIDs = std::unordered_set<Node::LocalID>;
LocalIDs _localIDs;
UUIDToLocalID _uuidToLocalID;
Node::LocalID _currentLocalID;
Node::LocalID _idIncrement;
}; };

View file

@ -593,8 +593,8 @@ bool DomainServer::isPacketVerified(const udt::Packet& packet) {
if (!PacketTypeEnum::getNonSourcedPackets().contains(headerType)) { if (!PacketTypeEnum::getNonSourcedPackets().contains(headerType)) {
// this is a sourced packet - first check if we have a node that matches // this is a sourced packet - first check if we have a node that matches
QUuid sourceID = NLPacket::sourceIDInHeader(packet); Node::LocalID localSourceID = NLPacket::sourceIDInHeader(packet);
SharedNodePointer sourceNode = nodeList->nodeWithUUID(sourceID); SharedNodePointer sourceNode = nodeList->nodeWithLocalID(localSourceID);
if (sourceNode) { if (sourceNode) {
// unverified DS packets (due to a lack of connection secret between DS + node) // unverified DS packets (due to a lack of connection secret between DS + node)
@ -612,14 +612,12 @@ bool DomainServer::isPacketVerified(const udt::Packet& packet) {
return nodeList->isPacketVerifiedWithSource(packet, sourceNode.data()); return nodeList->isPacketVerifiedWithSource(packet, sourceNode.data());
} else { } else {
HIFI_FDEBUG("Packet of type" << headerType HIFI_FDEBUG("Packet of type" << headerType
<< "received from unmatched IP for UUID" << uuidStringWithoutCurlyBraces(sourceID)); << "received from unmatched IP for UUID" << uuidStringWithoutCurlyBraces(sourceNode->getUUID()));
return false; return false;
} }
} else { } else {
HIFI_FDEBUG("Packet of type" << headerType HIFI_FDEBUG("Packet of type" << headerType
<< "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceID)); << "received from unknown node with UUID" << uuidStringWithoutCurlyBraces(sourceNode->getUUID()));
return false; return false;
} }
} }
@ -683,6 +681,10 @@ void DomainServer::setupNodeListAndAssignments() {
} }
} }
// Create our own short session ID.
Node::LocalID serverSessionLocalID = _gatekeeper.findOrCreateLocalID(nodeList->getSessionUUID());
nodeList->setSessionLocalID(serverSessionLocalID);
if (isMetaverseDomain) { if (isMetaverseDomain) {
// see if we think we're a temp domain (we have an API key) or a full domain // see if we think we're a temp domain (we have an API key) or a full domain
const auto& temporaryDomainKey = DependencyManager::get<AccountManager>()->getTemporaryDomainKey(getID()); const auto& temporaryDomainKey = DependencyManager::get<AccountManager>()->getTemporaryDomainKey(getID());
@ -1112,7 +1114,8 @@ void DomainServer::handleConnectedNode(SharedNodePointer newNode) {
} }
void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr &senderSockAddr) { void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr &senderSockAddr) {
const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + NUM_BYTES_RFC4122_UUID + 2; const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID +
NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID + 4;
// setup the extended header for the domain list packets // setup the extended header for the domain list packets
// this data is at the beginning of each of the domain list packets // this data is at the beginning of each of the domain list packets
@ -1122,7 +1125,9 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
auto limitedNodeList = DependencyManager::get<LimitedNodeList>(); auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
extendedHeaderStream << limitedNodeList->getSessionUUID(); extendedHeaderStream << limitedNodeList->getSessionUUID();
extendedHeaderStream << limitedNodeList->getSessionLocalID();
extendedHeaderStream << node->getUUID(); extendedHeaderStream << node->getUUID();
extendedHeaderStream << node->getLocalID();
extendedHeaderStream << node->getPermissions(); extendedHeaderStream << node->getPermissions();
auto domainListPackets = NLPacketList::create(PacketType::DomainList, extendedHeader); auto domainListPackets = NLPacketList::create(PacketType::DomainList, extendedHeader);
@ -2841,7 +2846,7 @@ void DomainServer::updateReplicationNodes(ReplicationServerDirection direction)
// manually add the replication node to our node list // manually add the replication node to our node list
auto node = nodeList->addOrUpdateNode(QUuid::createUuid(), replicationServer.nodeType, auto node = nodeList->addOrUpdateNode(QUuid::createUuid(), replicationServer.nodeType,
replicationServer.sockAddr, replicationServer.sockAddr, replicationServer.sockAddr, replicationServer.sockAddr,
false, direction == Upstream); Node::NULL_LOCAL_ID, false, direction == Upstream);
node->setIsForcedNeverSilent(true); node->setIsForcedNeverSilent(true);
qDebug() << "Adding" << (direction == Upstream ? "upstream" : "downstream") qDebug() << "Adding" << (direction == Upstream ? "upstream" : "downstream")
@ -3141,13 +3146,12 @@ void DomainServer::processNodeDisconnectRequestPacket(QSharedPointer<ReceivedMes
// This packet has been matched to a source node and they're asking not to be in the domain anymore // This packet has been matched to a source node and they're asking not to be in the domain anymore
auto limitedNodeList = DependencyManager::get<LimitedNodeList>(); auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
const QUuid& nodeUUID = message->getSourceID(); auto localID = message->getSourceID();
qDebug() << "Received a disconnect request from node with local ID" << localID;
qDebug() << "Received a disconnect request from node with UUID" << nodeUUID;
// we want to check what type this node was before going to kill it so that we can avoid sending the RemovedNode // we want to check what type this node was before going to kill it so that we can avoid sending the RemovedNode
// packet to nodes that don't care about this type // packet to nodes that don't care about this type
auto nodeToKill = limitedNodeList->nodeWithUUID(nodeUUID); auto nodeToKill = limitedNodeList->nodeWithLocalID(localID);
if (nodeToKill) { if (nodeToKill) {
handleKillNode(nodeToKill); handleKillNode(nodeToKill);
@ -3415,7 +3419,7 @@ void DomainServer::handleDomainContentReplacementFromURLRequest(QSharedPointer<R
} }
void DomainServer::handleOctreeFileReplacementRequest(QSharedPointer<ReceivedMessage> message) { void DomainServer::handleOctreeFileReplacementRequest(QSharedPointer<ReceivedMessage> message) {
auto node = DependencyManager::get<NodeList>()->nodeWithUUID(message->getSourceID()); auto node = DependencyManager::get<NodeList>()->nodeWithLocalID(message->getSourceID());
if (node->getCanReplaceContent()) { if (node->getCanReplaceContent()) {
handleOctreeFileReplacement(message->readAll()); handleOctreeFileReplacement(message->readAll());
} }

View file

@ -71,7 +71,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer<ReceivedMessage> messag
if (message->getVersion() != versionForPacketType(message->getType())) { if (message->getVersion() != versionForPacketType(message->getType())) {
static QMultiMap<QUuid, PacketType> versionDebugSuppressMap; static QMultiMap<QUuid, PacketType> versionDebugSuppressMap;
const QUuid& senderUUID = message->getSourceID(); const QUuid& senderUUID = sendingNode->getUUID();
if (!versionDebugSuppressMap.contains(senderUUID, packetType)) { if (!versionDebugSuppressMap.contains(senderUUID, packetType)) {
qDebug() << "Was stats packet? " << wasStatsPacket; qDebug() << "Was stats packet? " << wasStatsPacket;

View file

@ -120,8 +120,8 @@ int InboundAudioStream::parseData(ReceivedMessage& message) {
// parse sequence number and track it // parse sequence number and track it
quint16 sequence; quint16 sequence;
message.readPrimitive(&sequence); message.readPrimitive(&sequence);
SequenceNumberStats::ArrivalInfo arrivalInfo = _incomingSequenceNumberStats.sequenceNumberReceived(sequence, SequenceNumberStats::ArrivalInfo arrivalInfo =
message.getSourceID()); _incomingSequenceNumberStats.sequenceNumberReceived(sequence, message.getSourceID());
QString codecInPacket = message.readString(); QString codecInPacket = message.readString();
packetReceivedUpdateTimingStats(); packetReceivedUpdateTimingStats();
@ -186,7 +186,7 @@ int InboundAudioStream::parseData(ReceivedMessage& message) {
_mismatchedAudioCodecCount = 0; _mismatchedAudioCodecCount = 0;
// inform others of the mismatch // inform others of the mismatch
auto sendingNode = DependencyManager::get<NodeList>()->nodeWithUUID(message.getSourceID()); auto sendingNode = DependencyManager::get<NodeList>()->nodeWithLocalID(message.getSourceID());
if (sendingNode) { if (sendingNode) {
emit mismatchedAudioCodec(sendingNode, _selectedCodecName, codecInPacket); emit mismatchedAudioCodec(sendingNode, _selectedCodecName, codecInPacket);
qDebug(audio) << "Codec mismatch threshold exceeded, SelectedAudioFormat(" << _selectedCodecName << " ) sent"; qDebug(audio) << "Codec mismatch threshold exceeded, SelectedAudioFormat(" << _selectedCodecName << " ) sent";

View file

@ -45,6 +45,9 @@ public:
const QUuid& getUUID() const { return _uuid; } const QUuid& getUUID() const { return _uuid; }
void setUUID(const QUuid& uuid); void setUUID(const QUuid& uuid);
Node::LocalID getLocalID() const { return _localID; }
void setLocalID(Node::LocalID localID) { _localID = localID; }
QString getHostname() const { return _domainURL.host(); } QString getHostname() const { return _domainURL.host(); }
const QHostAddress& getIP() const { return _sockAddr.getAddress(); } const QHostAddress& getIP() const { return _sockAddr.getAddress(); }
@ -185,6 +188,7 @@ private:
void hardReset(); void hardReset();
QUuid _uuid; QUuid _uuid;
Node::LocalID _localID;
QUrl _domainURL; QUrl _domainURL;
HifiSockAddr _sockAddr; HifiSockAddr _sockAddr;
QUuid _assignmentUUID; QUuid _assignmentUUID;

View file

@ -132,6 +132,16 @@ void LimitedNodeList::setSessionUUID(const QUuid& sessionUUID) {
} }
} }
Node::LocalID LimitedNodeList::getSessionLocalID() const {
QReadLocker readLock { &_sessionUUIDLock };
return _sessionLocalID;
}
void LimitedNodeList::setSessionLocalID(Node::LocalID sessionLocalID) {
QWriteLocker lock { &_sessionUUIDLock };
_sessionLocalID = sessionLocalID;
}
void LimitedNodeList::setPermissions(const NodePermissions& newPermissions) { void LimitedNodeList::setPermissions(const NodePermissions& newPermissions) {
NodePermissions originalPermissions = _permissions; NodePermissions originalPermissions = _permissions;
@ -230,7 +240,9 @@ bool LimitedNodeList::packetVersionMatch(const udt::Packet& packet) {
senderString = QString("%1:%2").arg(senderSockAddr.getAddress().toString()).arg(senderSockAddr.getPort()); senderString = QString("%1:%2").arg(senderSockAddr.getAddress().toString()).arg(senderSockAddr.getPort());
} }
} else { } else {
sourceID = NLPacket::sourceIDInHeader(packet); SharedNodePointer sourceNode = nodeWithLocalID(NLPacket::sourceIDInHeader(packet));
if (sourceNode) {
sourceID = sourceNode->getUUID();
hasBeenOutput = sourcedVersionDebugSuppressMap.contains(sourceID, headerType); hasBeenOutput = sourcedVersionDebugSuppressMap.contains(sourceID, headerType);
@ -239,6 +251,7 @@ bool LimitedNodeList::packetVersionMatch(const udt::Packet& packet) {
senderString = uuidStringWithoutCurlyBraces(sourceID.toString()); senderString = uuidStringWithoutCurlyBraces(sourceID.toString());
} }
} }
}
if (!hasBeenOutput) { if (!hasBeenOutput) {
qCDebug(networking) << "Packet version mismatch on" << headerType << "- Sender" qCDebug(networking) << "Packet version mismatch on" << headerType << "- Sender"
@ -289,17 +302,20 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe
return true; return true;
} }
} else { } else {
QUuid sourceID = NLPacket::sourceIDInHeader(packet); NLPacket::LocalID sourceLocalID = Node::NULL_LOCAL_ID;
// check if we were passed a sourceNode hint or if we need to look it up // check if we were passed a sourceNode hint or if we need to look it up
if (!sourceNode) { if (!sourceNode) {
// figure out which node this is from // figure out which node this is from
SharedNodePointer matchingNode = nodeWithUUID(sourceID); sourceLocalID = NLPacket::sourceIDInHeader(packet);
SharedNodePointer matchingNode = nodeWithLocalID(sourceLocalID);
sourceNode = matchingNode.data(); sourceNode = matchingNode.data();
} }
QUuid sourceID = sourceNode ? sourceNode->getUUID() : QUuid();
if (!sourceNode && if (!sourceNode &&
sourceID == getDomainUUID() && sourceLocalID == getDomainLocalID() &&
packet.getSenderSockAddr() == getDomainSockAddr() && packet.getSenderSockAddr() == getDomainSockAddr() &&
PacketTypeEnum::getDomainSourcedPackets().contains(headerType)) { PacketTypeEnum::getDomainSourcedPackets().contains(headerType)) {
// This is a packet sourced by the domain server // This is a packet sourced by the domain server
@ -357,7 +373,7 @@ void LimitedNodeList::collectPacketStats(const NLPacket& packet) {
void LimitedNodeList::fillPacketHeader(const NLPacket& packet, HMACAuth* hmacAuth) { void LimitedNodeList::fillPacketHeader(const NLPacket& packet, HMACAuth* hmacAuth) {
if (!PacketTypeEnum::getNonSourcedPackets().contains(packet.getType())) { if (!PacketTypeEnum::getNonSourcedPackets().contains(packet.getType())) {
packet.writeSourceID(getSessionUUID()); packet.writeSourceID(getSessionLocalID());
} }
if (hmacAuth if (hmacAuth
@ -541,6 +557,13 @@ SharedNodePointer LimitedNodeList::nodeWithUUID(const QUuid& nodeUUID) {
return it == _nodeHash.cend() ? SharedNodePointer() : it->second; return it == _nodeHash.cend() ? SharedNodePointer() : it->second;
} }
SharedNodePointer LimitedNodeList::nodeWithLocalID(Node::LocalID localID) const {
QReadLocker readLocker(&_nodeMutex);
LocalIDMapping::const_iterator idIter = _localIDMap.find(localID);
return idIter == _localIDMap.cend() ? nullptr : idIter->second;
}
void LimitedNodeList::eraseAllNodes() { void LimitedNodeList::eraseAllNodes() {
QSet<SharedNodePointer> killedNodes; QSet<SharedNodePointer> killedNodes;
@ -549,6 +572,8 @@ void LimitedNodeList::eraseAllNodes() {
// and then remove them from the hash // and then remove them from the hash
QWriteLocker writeLocker(&_nodeMutex); QWriteLocker writeLocker(&_nodeMutex);
_localIDMap.clear();
if (_nodeHash.size() > 0) { if (_nodeHash.size() > 0) {
qCDebug(networking) << "LimitedNodeList::eraseAllNodes() removing all nodes from NodeList."; qCDebug(networking) << "LimitedNodeList::eraseAllNodes() removing all nodes from NodeList.";
@ -624,7 +649,7 @@ void LimitedNodeList::handleNodeKill(const SharedNodePointer& node, ConnectionID
SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
bool isReplicated, bool isUpstream, Node::LocalID localID, bool isReplicated, bool isUpstream,
const QUuid& connectionSecret, const NodePermissions& permissions) { const QUuid& connectionSecret, const NodePermissions& permissions) {
QReadLocker readLocker(&_nodeMutex); QReadLocker readLocker(&_nodeMutex);
NodeHash::const_iterator it = _nodeHash.find(uuid); NodeHash::const_iterator it = _nodeHash.find(uuid);
@ -638,6 +663,7 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t
matchingNode->setConnectionSecret(connectionSecret); matchingNode->setConnectionSecret(connectionSecret);
matchingNode->setIsReplicated(isReplicated); matchingNode->setIsReplicated(isReplicated);
matchingNode->setIsUpstream(isUpstream || NodeType::isUpstream(nodeType)); matchingNode->setIsUpstream(isUpstream || NodeType::isUpstream(nodeType));
matchingNode->setLocalID(localID);
return matchingNode; return matchingNode;
} else { } else {
@ -652,6 +678,7 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t
newNode->setIsUpstream(isUpstream || NodeType::isUpstream(nodeType)); newNode->setIsUpstream(isUpstream || NodeType::isUpstream(nodeType));
newNode->setConnectionSecret(connectionSecret); newNode->setConnectionSecret(connectionSecret);
newNode->setPermissions(permissions); newNode->setPermissions(permissions);
newNode->setLocalID(localID);
// move the newly constructed node to the LNL thread // move the newly constructed node to the LNL thread
newNode->moveToThread(thread()); newNode->moveToThread(thread());
@ -677,6 +704,7 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t
auto oldSoloNode = previousSoloIt->second; auto oldSoloNode = previousSoloIt->second;
_localIDMap.unsafe_erase(oldSoloNode->getLocalID());
_nodeHash.unsafe_erase(previousSoloIt); _nodeHash.unsafe_erase(previousSoloIt);
handleNodeKill(oldSoloNode); handleNodeKill(oldSoloNode);
@ -692,6 +720,7 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t
#else #else
_nodeHash.emplace(newNode->getUUID(), newNodePointer); _nodeHash.emplace(newNode->getUUID(), newNodePointer);
#endif #endif
_localIDMap.emplace(localID, newNodePointer);
readLocker.unlock(); readLocker.unlock();
qCDebug(networking) << "Added" << *newNode; qCDebug(networking) << "Added" << *newNode;
@ -819,6 +848,7 @@ void LimitedNodeList::removeSilentNodes() {
if (!node->isForcedNeverSilent() if (!node->isForcedNeverSilent()
&& (usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * USECS_PER_MSEC)) { && (usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * USECS_PER_MSEC)) {
// call the NodeHash erase to get rid of this node // call the NodeHash erase to get rid of this node
_localIDMap.unsafe_erase(node->getLocalID());
it = _nodeHash.unsafe_erase(it); it = _nodeHash.unsafe_erase(it);
killedNodes.insert(node); killedNodes.insert(node);

View file

@ -110,6 +110,8 @@ public:
Q_ENUM(ConnectionStep); Q_ENUM(ConnectionStep);
QUuid getSessionUUID() const; QUuid getSessionUUID() const;
void setSessionUUID(const QUuid& sessionUUID); void setSessionUUID(const QUuid& sessionUUID);
Node::LocalID getSessionLocalID() const;
void setSessionLocalID(Node::LocalID localID);
void setPermissions(const NodePermissions& newPermissions); void setPermissions(const NodePermissions& newPermissions);
bool isAllowedEditor() const { return _permissions.can(NodePermissions::Permission::canAdjustLocks); } bool isAllowedEditor() const { return _permissions.can(NodePermissions::Permission::canAdjustLocks); }
@ -130,6 +132,7 @@ public:
virtual bool isDomainServer() const { return true; } virtual bool isDomainServer() const { return true; }
virtual QUuid getDomainUUID() const { assert(false); return QUuid(); } virtual QUuid getDomainUUID() const { assert(false); return QUuid(); }
virtual Node::LocalID getDomainLocalID() const { assert(false); return Node::NULL_LOCAL_ID; }
virtual HifiSockAddr getDomainSockAddr() const { assert(false); return HifiSockAddr(); } virtual HifiSockAddr getDomainSockAddr() const { assert(false); return HifiSockAddr(); }
// use sendUnreliablePacket to send an unreliable packet (that you do not need to move) // use sendUnreliablePacket to send an unreliable packet (that you do not need to move)
@ -157,11 +160,12 @@ public:
size_t size() const { QReadLocker readLock(&_nodeMutex); return _nodeHash.size(); } size_t size() const { QReadLocker readLock(&_nodeMutex); return _nodeHash.size(); }
SharedNodePointer nodeWithUUID(const QUuid& nodeUUID); SharedNodePointer nodeWithUUID(const QUuid& nodeUUID);
SharedNodePointer nodeWithLocalID(Node::LocalID localID) const;
SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
bool isReplicated = false, bool isUpstream = false, Node::LocalID localID = Node::NULL_LOCAL_ID, bool isReplicated = false,
const QUuid& connectionSecret = QUuid(), bool isUpstream = false, const QUuid& connectionSecret = QUuid(),
const NodePermissions& permissions = DEFAULT_AGENT_PERMISSIONS); const NodePermissions& permissions = DEFAULT_AGENT_PERMISSIONS);
static bool parseSTUNResponse(udt::BasePacket* packet, QHostAddress& newPublicAddress, uint16_t& newPublicPort); static bool parseSTUNResponse(udt::BasePacket* packet, QHostAddress& newPublicAddress, uint16_t& newPublicPort);
@ -430,6 +434,9 @@ private slots:
private: private:
mutable QReadWriteLock _sessionUUIDLock; mutable QReadWriteLock _sessionUUIDLock;
QUuid _sessionUUID; QUuid _sessionUUID;
using LocalIDMapping = tbb::concurrent_unordered_map<Node::LocalID, SharedNodePointer>;
LocalIDMapping _localIDMap;
Node::LocalID _sessionLocalID { 0 };
}; };
#endif // hifi_LimitedNodeList_h #endif // hifi_LimitedNodeList_h

View file

@ -16,7 +16,7 @@
int NLPacket::localHeaderSize(PacketType type) { int NLPacket::localHeaderSize(PacketType type) {
bool nonSourced = PacketTypeEnum::getNonSourcedPackets().contains(type); bool nonSourced = PacketTypeEnum::getNonSourcedPackets().contains(type);
bool nonVerified = PacketTypeEnum::getNonVerifiedPackets().contains(type); bool nonVerified = PacketTypeEnum::getNonVerifiedPackets().contains(type);
qint64 optionalSize = (nonSourced ? 0 : NUM_BYTES_RFC4122_UUID) + ((nonSourced || nonVerified) ? 0 : NUM_BYTES_MD5_HASH); qint64 optionalSize = (nonSourced ? 0 : NUM_BYTES_LOCALID) + ((nonSourced || nonVerified) ? 0 : NUM_BYTES_MD5_HASH);
return sizeof(PacketType) + sizeof(PacketVersion) + optionalSize; return sizeof(PacketType) + sizeof(PacketVersion) + optionalSize;
} }
int NLPacket::totalHeaderSize(PacketType type, bool isPartOfMessage) { int NLPacket::totalHeaderSize(PacketType type, bool isPartOfMessage) {
@ -141,19 +141,22 @@ PacketVersion NLPacket::versionInHeader(const udt::Packet& packet) {
return *reinterpret_cast<const PacketVersion*>(packet.getData() + headerOffset + sizeof(PacketType)); return *reinterpret_cast<const PacketVersion*>(packet.getData() + headerOffset + sizeof(PacketType));
} }
QUuid NLPacket::sourceIDInHeader(const udt::Packet& packet) { NLPacket::LocalID NLPacket::sourceIDInHeader(const udt::Packet& packet) {
int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion); int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion);
return QUuid::fromRfc4122(QByteArray::fromRawData(packet.getData() + offset, NUM_BYTES_RFC4122_UUID)); return *reinterpret_cast<const LocalID*>(packet.getData() + offset);
} }
QByteArray NLPacket::verificationHashInHeader(const udt::Packet& packet) { QByteArray NLPacket::verificationHashInHeader(const udt::Packet& packet) {
int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID; int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) +
sizeof(PacketVersion) + NUM_BYTES_LOCALID;
return QByteArray(packet.getData() + offset, NUM_BYTES_MD5_HASH); return QByteArray(packet.getData() + offset, NUM_BYTES_MD5_HASH);
} }
QByteArray NLPacket::hashForPacketAndHMAC(const udt::Packet& packet, HMACAuth& hash) { QByteArray NLPacket::hashForPacketAndHMAC(const udt::Packet& packet, HMACAuth& hash) {
int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion)
+ NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH; + NUM_BYTES_LOCALID + NUM_BYTES_MD5_HASH;
// add the packet payload and the connection UUID
hash.addData(packet.getData() + offset, packet.getDataSize() - offset); hash.addData(packet.getData() + offset, packet.getDataSize() - offset);
auto hashResult { hash.result() }; auto hashResult { hash.result() };
return QByteArray((const char*) hashResult.data(), (int) hashResult.size()); return QByteArray((const char*) hashResult.data(), (int) hashResult.size());
@ -199,11 +202,12 @@ void NLPacket::readSourceID() {
} }
} }
void NLPacket::writeSourceID(const QUuid& sourceID) const { void NLPacket::writeSourceID(LocalID sourceID) const {
Q_ASSERT(!PacketTypeEnum::getNonSourcedPackets().contains(_type)); Q_ASSERT(!PacketTypeEnum::getNonSourcedPackets().contains(_type));
auto offset = Packet::totalHeaderSize(isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion); auto offset = Packet::totalHeaderSize(isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion);
memcpy(_packet.get() + offset, sourceID.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID);
memcpy(_packet.get() + offset, &sourceID, sizeof(sourceID));
_sourceID = sourceID; _sourceID = sourceID;
} }
@ -213,7 +217,7 @@ void NLPacket::writeVerificationHash(HMACAuth& hmacAuth) const {
!PacketTypeEnum::getNonVerifiedPackets().contains(_type)); !PacketTypeEnum::getNonVerifiedPackets().contains(_type));
auto offset = Packet::totalHeaderSize(isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) auto offset = Packet::totalHeaderSize(isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion)
+ NUM_BYTES_RFC4122_UUID; + NUM_BYTES_LOCALID;
QByteArray verificationHash = hashForPacketAndHMAC(*this, hmacAuth); QByteArray verificationHash = hashForPacketAndHMAC(*this, hmacAuth);

View file

@ -24,31 +24,29 @@ class NLPacket : public udt::Packet {
Q_OBJECT Q_OBJECT
public: public:
// //
// | BYTE | BYTE | BYTE | BYTE | // NLPacket format:
// //
// | BYTE | BYTE | BYTE | BYTE |
// 0 1 2 3 // 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Packet Type | Version | | // | Packet Type | Version | Local Node ID - sourced only |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | |
// | Node UUID - 16 bytes |
// | (ONLY FOR SOURCED PACKETS) |
// | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | | |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
// | | // | |
// | MD5 Verification - 16 bytes | // | MD5 Verification - 16 bytes |
// | (ONLY FOR VERIFIED PACKETS) | // | (ONLY FOR VERIFIED PACKETS) |
// | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | |
// | | | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | //
// NLPacket Header Format
using LocalID = NetworkLocalID;
static const LocalID NULL_LOCAL_ID = 0;
static const int NUM_BYTES_LOCALID = sizeof(LocalID);
// this is used by the Octree classes - must be known at compile time // this is used by the Octree classes - must be known at compile time
static const int MAX_PACKET_HEADER_SIZE = static const int MAX_PACKET_HEADER_SIZE =
sizeof(udt::Packet::SequenceNumberAndBitField) + sizeof(udt::Packet::MessageNumberAndBitField) + sizeof(udt::Packet::SequenceNumberAndBitField) + sizeof(udt::Packet::MessageNumberAndBitField) +
sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH; sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_LOCALID + NUM_BYTES_MD5_HASH;
static std::unique_ptr<NLPacket> create(PacketType type, qint64 size = -1, static std::unique_ptr<NLPacket> create(PacketType type, qint64 size = -1,
bool isReliable = false, bool isPartOfMessage = false, PacketVersion version = 0); bool isReliable = false, bool isPartOfMessage = false, PacketVersion version = 0);
@ -71,7 +69,7 @@ public:
static PacketType typeInHeader(const udt::Packet& packet); static PacketType typeInHeader(const udt::Packet& packet);
static PacketVersion versionInHeader(const udt::Packet& packet); static PacketVersion versionInHeader(const udt::Packet& packet);
static QUuid sourceIDInHeader(const udt::Packet& packet); static LocalID sourceIDInHeader(const udt::Packet& packet);
static QByteArray verificationHashInHeader(const udt::Packet& packet); static QByteArray verificationHashInHeader(const udt::Packet& packet);
static QByteArray hashForPacketAndHMAC(const udt::Packet& packet, HMACAuth& hash); static QByteArray hashForPacketAndHMAC(const udt::Packet& packet, HMACAuth& hash);
@ -81,9 +79,9 @@ public:
PacketVersion getVersion() const { return _version; } PacketVersion getVersion() const { return _version; }
void setVersion(PacketVersion version); void setVersion(PacketVersion version);
const QUuid& getSourceID() const { return _sourceID; } LocalID getSourceID() const { return _sourceID; }
void writeSourceID(const QUuid& sourceID) const; void writeSourceID(LocalID sourceID) const;
void writeVerificationHash(HMACAuth& hmacAuth) const; void writeVerificationHash(HMACAuth& hmacAuth) const;
protected: protected:
@ -108,7 +106,7 @@ protected:
PacketType _type; PacketType _type;
PacketVersion _version; PacketVersion _version;
mutable QUuid _sourceID; mutable LocalID _sourceID;
}; };
#endif // hifi_NLPacket_h #endif // hifi_NLPacket_h

View file

@ -22,7 +22,7 @@ public:
bool isReliable = false, bool isOrdered = false); bool isReliable = false, bool isOrdered = false);
PacketVersion getVersion() const { return _packetVersion; } PacketVersion getVersion() const { return _packetVersion; }
const QUuid& getSourceID() const { return _sourceID; } NLPacket::LocalID getSourceID() const { return _sourceID; }
qint64 getMaxSegmentSize() const override { return NLPacket::maxPayloadSize(_packetType, _isOrdered); } qint64 getMaxSegmentSize() const override { return NLPacket::maxPayloadSize(_packetType, _isOrdered); }
@ -37,7 +37,7 @@ private:
PacketVersion _packetVersion; PacketVersion _packetVersion;
QUuid _sourceID; NLPacket::LocalID _sourceID;
}; };
Q_DECLARE_METATYPE(QSharedPointer<NLPacketList>) Q_DECLARE_METATYPE(QSharedPointer<NLPacketList>)

View file

@ -23,6 +23,7 @@
#include <Trace.h> #include <Trace.h>
#include "NodeType.h" #include "NodeType.h"
const NetworkPeer::LocalID NetworkPeer::NULL_LOCAL_ID;
NetworkPeer::NetworkPeer(QObject* parent) : NetworkPeer::NetworkPeer(QObject* parent) :
QObject(parent), QObject(parent),

View file

@ -18,6 +18,7 @@
#include <QtCore/QTimer> #include <QtCore/QTimer>
#include <QtCore/QUuid> #include <QtCore/QUuid>
#include "UUID.h"
#include "HifiSockAddr.h" #include "HifiSockAddr.h"
const QString ICE_SERVER_HOSTNAME = "localhost"; const QString ICE_SERVER_HOSTNAME = "localhost";
@ -39,6 +40,12 @@ public:
const QUuid& getUUID() const { return _uuid; } const QUuid& getUUID() const { return _uuid; }
void setUUID(const QUuid& uuid) { _uuid = uuid; } void setUUID(const QUuid& uuid) { _uuid = uuid; }
using LocalID = NetworkLocalID;
static const LocalID NULL_LOCAL_ID = 0;
LocalID getLocalID() const { return _localID; }
void setLocalID(LocalID localID) { _localID = localID; }
void softReset(); void softReset();
void reset(); void reset();
@ -99,6 +106,7 @@ protected:
void setActiveSocket(HifiSockAddr* discoveredSocket); void setActiveSocket(HifiSockAddr* discoveredSocket);
QUuid _uuid; QUuid _uuid;
LocalID _localID { 0 };
HifiSockAddr _publicSocket; HifiSockAddr _publicSocket;
HifiSockAddr _localSocket; HifiSockAddr _localSocket;

View file

@ -169,6 +169,7 @@ QDataStream& operator<<(QDataStream& out, const Node& node) {
out << node._localSocket; out << node._localSocket;
out << node._permissions; out << node._permissions;
out << node._isReplicated; out << node._isReplicated;
out << node._localID;
return out; return out;
} }
@ -179,6 +180,7 @@ QDataStream& operator>>(QDataStream& in, Node& node) {
in >> node._localSocket; in >> node._localSocket;
in >> node._permissions; in >> node._permissions;
in >> node._isReplicated; in >> node._isReplicated;
in >> node._localID;
return in; return in;
} }
@ -189,7 +191,7 @@ QDebug operator<<(QDebug debug, const Node& node) {
} else { } else {
debug.nospace() << " (" << node.getType() << ")"; debug.nospace() << " (" << node.getType() << ")";
} }
debug << " " << node.getUUID().toString().toLocal8Bit().constData() << " "; debug << " " << node.getUUID().toString().toLocal8Bit().constData() << "(" << node.getLocalID() << ") ";
debug.nospace() << node.getPublicSocket() << "/" << node.getLocalSocket(); debug.nospace() << node.getPublicSocket() << "/" << node.getLocalSocket();
return debug.nospace(); return debug.nospace();
} }

View file

@ -624,13 +624,21 @@ void NodeList::processDomainServerList(QSharedPointer<ReceivedMessage> message)
return; return;
} }
// pull our owner UUID from the packet, it's always the first thing Node::LocalID domainLocalID;
packetStream >> domainLocalID;
// pull our owner (ie. session) UUID from the packet, it's always the first thing
// The short (16 bit) ID comes next.
QUuid newUUID; QUuid newUUID;
Node::LocalID newLocalID;
packetStream >> newUUID; packetStream >> newUUID;
packetStream >> newLocalID;
setSessionLocalID(newLocalID);
setSessionUUID(newUUID); setSessionUUID(newUUID);
// if this was the first domain-server list from this domain, we've now connected // if this was the first domain-server list from this domain, we've now connected
if (!_domainHandler.isConnected()) { if (!_domainHandler.isConnected()) {
_domainHandler.setLocalID(newLocalID);
_domainHandler.setUUID(domainUUID); _domainHandler.setUUID(domainUUID);
_domainHandler.setIsConnected(true); _domainHandler.setIsConnected(true);
@ -668,12 +676,14 @@ void NodeList::processDomainServerRemovedNode(QSharedPointer<ReceivedMessage> me
void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) { void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) {
// setup variables to read into from QDataStream // setup variables to read into from QDataStream
qint8 nodeType; qint8 nodeType;
QUuid nodeUUID, connectionUUID; QUuid nodeUUID, connectionSecretUUID;
HifiSockAddr nodePublicSocket, nodeLocalSocket; HifiSockAddr nodePublicSocket, nodeLocalSocket;
NodePermissions permissions; NodePermissions permissions;
bool isReplicated; bool isReplicated;
Node::LocalID sessionLocalID;
packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket >> permissions >> isReplicated; packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket >> permissions
>> isReplicated >> sessionLocalID;
// if the public socket address is 0 then it's reachable at the same IP // if the public socket address is 0 then it's reachable at the same IP
// as the domain server // as the domain server
@ -681,10 +691,10 @@ void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) {
nodePublicSocket.setAddress(_domainHandler.getIP()); nodePublicSocket.setAddress(_domainHandler.getIP());
} }
packetStream >> connectionUUID; packetStream >> connectionSecretUUID;
SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, nodeLocalSocket,
nodeLocalSocket, isReplicated, false, connectionUUID, permissions); sessionLocalID, isReplicated, false, connectionSecretUUID, permissions);
// nodes that are downstream or upstream of our own type are kept alive when we hear about them from the domain server // nodes that are downstream or upstream of our own type are kept alive when we hear about them from the domain server
// and always have their public socket as their active socket // and always have their public socket as their active socket

View file

@ -94,6 +94,7 @@ public:
virtual bool isDomainServer() const override { return false; } virtual bool isDomainServer() const override { return false; }
virtual QUuid getDomainUUID() const override { return _domainHandler.getUUID(); } virtual QUuid getDomainUUID() const override { return _domainHandler.getUUID(); }
virtual Node::LocalID getDomainLocalID() const override { return _domainHandler.getLocalID(); }
virtual HifiSockAddr getDomainSockAddr() const override { return _domainHandler.getSockAddr(); } virtual HifiSockAddr getDomainSockAddr() const override { return _domainHandler.getSockAddr(); }
public slots: public slots:

View file

@ -261,10 +261,9 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer<ReceivedMessage> recei
SharedNodePointer matchingNode; SharedNodePointer matchingNode;
if (!receivedMessage->getSourceID().isNull()) { if (receivedMessage->getSourceID() != Node::NULL_LOCAL_ID) {
matchingNode = nodeList->nodeWithUUID(receivedMessage->getSourceID()); matchingNode = nodeList->nodeWithLocalID(receivedMessage->getSourceID());
} }
QMutexLocker packetListenerLocker(&_packetListenerLock); QMutexLocker packetListenerLocker(&_packetListenerLock);
auto it = _messageListenerMap.find(receivedMessage->getType()); auto it = _messageListenerMap.find(receivedMessage->getType());

View file

@ -43,7 +43,7 @@ ReceivedMessage::ReceivedMessage(NLPacket& packet)
} }
ReceivedMessage::ReceivedMessage(QByteArray byteArray, PacketType packetType, PacketVersion packetVersion, ReceivedMessage::ReceivedMessage(QByteArray byteArray, PacketType packetType, PacketVersion packetVersion,
const HifiSockAddr& senderSockAddr, QUuid sourceID) : const HifiSockAddr& senderSockAddr, NLPacket::LocalID sourceID) :
_data(byteArray), _data(byteArray),
_headData(_data.mid(0, HEAD_DATA_SIZE)), _headData(_data.mid(0, HEAD_DATA_SIZE)),
_numPackets(1), _numPackets(1),

View file

@ -25,7 +25,7 @@ public:
ReceivedMessage(const NLPacketList& packetList); ReceivedMessage(const NLPacketList& packetList);
ReceivedMessage(NLPacket& packet); ReceivedMessage(NLPacket& packet);
ReceivedMessage(QByteArray byteArray, PacketType packetType, PacketVersion packetVersion, ReceivedMessage(QByteArray byteArray, PacketType packetType, PacketVersion packetVersion,
const HifiSockAddr& senderSockAddr, QUuid sourceID = QUuid()); const HifiSockAddr& senderSockAddr, NLPacket::LocalID sourceID = NLPacket::NULL_LOCAL_ID);
QByteArray getMessage() const { return _data; } QByteArray getMessage() const { return _data; }
const char* getRawMessage() const { return _data.constData(); } const char* getRawMessage() const { return _data.constData(); }
@ -40,7 +40,7 @@ public:
bool failed() const { return _failed; } bool failed() const { return _failed; }
bool isComplete() const { return _isComplete; } bool isComplete() const { return _isComplete; }
const QUuid& getSourceID() const { return _sourceID; } NLPacket::LocalID getSourceID() const { return _sourceID; }
const HifiSockAddr& getSenderSockAddr() { return _senderSockAddr; } const HifiSockAddr& getSenderSockAddr() { return _senderSockAddr; }
qint64 getPosition() const { return _position; } qint64 getPosition() const { return _position; }
@ -93,7 +93,7 @@ private:
std::atomic<qint64> _position { 0 }; std::atomic<qint64> _position { 0 };
std::atomic<qint64> _numPackets { 0 }; std::atomic<qint64> _numPackets { 0 };
QUuid _sourceID; NLPacket::LocalID _sourceID { NLPacket::NULL_LOCAL_ID };
PacketType _packetType; PacketType _packetType;
PacketVersion _packetVersion; PacketVersion _packetVersion;
HifiSockAddr _senderSockAddr; HifiSockAddr _senderSockAddr;

View file

@ -25,7 +25,7 @@ SequenceNumberStats::SequenceNumberStats(int statsHistoryLength, bool canDetectO
: _lastReceivedSequence(0), : _lastReceivedSequence(0),
_missingSet(), _missingSet(),
_stats(), _stats(),
_lastSenderUUID(), _lastSenderID(NULL_LOCAL_ID),
_statsHistory(statsHistoryLength), _statsHistory(statsHistoryLength),
_lastUnreasonableSequence(0), _lastUnreasonableSequence(0),
_consecutiveUnreasonableOnTime(0) _consecutiveUnreasonableOnTime(0)
@ -35,7 +35,7 @@ SequenceNumberStats::SequenceNumberStats(int statsHistoryLength, bool canDetectO
void SequenceNumberStats::reset() { void SequenceNumberStats::reset() {
_missingSet.clear(); _missingSet.clear();
_stats = PacketStreamStats(); _stats = PacketStreamStats();
_lastSenderUUID = QUuid(); _lastSenderID = NULL_LOCAL_ID;
_statsHistory.clear(); _statsHistory.clear();
_lastUnreasonableSequence = 0; _lastUnreasonableSequence = 0;
_consecutiveUnreasonableOnTime = 0; _consecutiveUnreasonableOnTime = 0;
@ -43,18 +43,18 @@ void SequenceNumberStats::reset() {
static const int UINT16_RANGE = std::numeric_limits<uint16_t>::max() + 1; static const int UINT16_RANGE = std::numeric_limits<uint16_t>::max() + 1;
SequenceNumberStats::ArrivalInfo SequenceNumberStats::sequenceNumberReceived(quint16 incoming, QUuid senderUUID, const bool wantExtraDebugging) { SequenceNumberStats::ArrivalInfo SequenceNumberStats::sequenceNumberReceived(quint16 incoming, NetworkLocalID senderID, const bool wantExtraDebugging) {
SequenceNumberStats::ArrivalInfo arrivalInfo; SequenceNumberStats::ArrivalInfo arrivalInfo;
// if the sender node has changed, reset all stats // if the sender node has changed, reset all stats
if (senderUUID != _lastSenderUUID) { if (senderID != _lastSenderID) {
if (_stats._received > 0) { if (_stats._received > 0) {
qCDebug(networking) << "sequence number stats was reset due to new sender node"; qCDebug(networking) << "sequence number stats was reset due to new sender node";
qCDebug(networking) << "previous:" << _lastSenderUUID << "current:" << senderUUID; qCDebug(networking) << "previous:" << _lastSenderID << "current:" << senderID;
reset(); reset();
} }
_lastSenderUUID = senderUUID; _lastSenderID = senderID;
} }
// determine our expected sequence number... handle rollover appropriately // determine our expected sequence number... handle rollover appropriately

View file

@ -14,7 +14,7 @@
#include "SharedUtil.h" #include "SharedUtil.h"
#include "RingBufferHistory.h" #include "RingBufferHistory.h"
#include <quuid.h> #include "UUID.h"
const int MAX_REASONABLE_SEQUENCE_GAP = 1000; const int MAX_REASONABLE_SEQUENCE_GAP = 1000;
@ -73,7 +73,7 @@ public:
SequenceNumberStats(int statsHistoryLength = 0, bool canDetectOutOfSync = true); SequenceNumberStats(int statsHistoryLength = 0, bool canDetectOutOfSync = true);
void reset(); void reset();
ArrivalInfo sequenceNumberReceived(quint16 incoming, QUuid senderUUID = QUuid(), const bool wantExtraDebugging = false); ArrivalInfo sequenceNumberReceived(quint16 incoming, NetworkLocalID senderID = NULL_LOCAL_ID, const bool wantExtraDebugging = false);
void pruneMissingSet(const bool wantExtraDebugging = false); void pruneMissingSet(const bool wantExtraDebugging = false);
void pushStatsToHistory() { _statsHistory.insert(_stats); } void pushStatsToHistory() { _statsHistory.insert(_stats); }
@ -100,7 +100,8 @@ private:
PacketStreamStats _stats; PacketStreamStats _stats;
QUuid _lastSenderUUID; NetworkLocalID _lastSenderID;
static const NetworkLocalID NULL_LOCAL_ID = (NetworkLocalID) 0;
RingBufferHistory<PacketStreamStats> _statsHistory; RingBufferHistory<PacketStreamStats> _statsHistory;

View file

@ -91,7 +91,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
case PacketType::Ping: case PacketType::Ping:
return static_cast<PacketVersion>(PingVersion::IncludeConnectionID); return static_cast<PacketVersion>(PingVersion::IncludeConnectionID);
default: default:
return 18; return 19;
} }
} }

View file

@ -96,7 +96,7 @@ void OctreeProcessor::processDatagram(ReceivedMessage& message, SharedNodePointe
quint64 totalUncompress = 0; quint64 totalUncompress = 0;
quint64 totalReadBitsteam = 0; quint64 totalReadBitsteam = 0;
const QUuid& sourceUUID = message.getSourceID(); const QUuid& sourceUUID = sourceNode->getUUID();
int subsection = 1; int subsection = 1;

View file

@ -15,6 +15,7 @@
#include <QtCore/QUuid> #include <QtCore/QUuid>
const int NUM_BYTES_RFC4122_UUID = 16; const int NUM_BYTES_RFC4122_UUID = 16;
using NetworkLocalID = quint16;
QString uuidStringWithoutCurlyBraces(const QUuid& uuid); QString uuidStringWithoutCurlyBraces(const QUuid& uuid);