From 4f1eeecc2f167932b8dece7ca56a96fe946cd709 Mon Sep 17 00:00:00 2001 From: Roxanne Skelly Date: Thu, 23 May 2019 11:00:43 -0700 Subject: [PATCH 01/11] Revert "Merge pull request #15620 from highfidelity/revert-15612-domaincheckin" This reverts commit 4735b9f19a894f1dc9a79826ccece3ec3f06c588, reversing changes made to bc4a88beb7dfba609aa1e48a9e1087eed2981e7e. --- domain-server/src/DomainGatekeeper.cpp | 5 +- domain-server/src/DomainServer.cpp | 6 ++ domain-server/src/DomainServerNodeData.h | 5 +- domain-server/src/NodeConnectionData.cpp | 2 + domain-server/src/NodeConnectionData.h | 1 + libraries/networking/src/NodeList.cpp | 82 ++++++++++++------- .../networking/src/udt/PacketHeaders.cpp | 4 +- libraries/networking/src/udt/PacketHeaders.h | 6 +- 8 files changed, 77 insertions(+), 34 deletions(-) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 29656f4465..75399d1a9b 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -358,7 +358,7 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo nodeData->setNodeVersion(it->second.getNodeVersion()); nodeData->setHardwareAddress(nodeConnection.hardwareAddress); nodeData->setMachineFingerprint(nodeConnection.machineFingerprint); - + nodeData->setLastDomainCheckinTimestamp(nodeConnection.lastPingTimestamp); nodeData->setWasAssigned(true); // cleanup the PendingAssignedNodeData for this assignment now that it's connecting @@ -499,6 +499,9 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect // set the machine fingerprint passed in the connect request nodeData->setMachineFingerprint(nodeConnection.machineFingerprint); + // set the last ping timestamp passed in the connect request + nodeData->setLastDomainCheckinTimestamp(nodeConnection.lastPingTimestamp); + // also add an interpolation to DomainServerNodeData so that servers can get username in stats nodeData->addOverrideForKey(USERNAME_UUID_REPLACEMENT_STATS_KEY, uuidStringWithoutCurlyBraces(newNode->getUUID()), username); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 051dd989f5..37643cc372 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1068,6 +1068,8 @@ void DomainServer::processListRequestPacket(QSharedPointer mess // update the connecting hostname in case it has changed nodeData->setPlaceName(nodeRequestData.placeName); + nodeData->setLastDomainCheckinTimestamp(nodeRequestData.lastPingTimestamp); + sendDomainListToNode(sendingNode, message->getSenderSockAddr()); } @@ -1174,6 +1176,10 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif DomainServerNodeData* nodeData = static_cast(node->getLinkedData()); + domainListStream << nodeData->getLastDomainCheckinTimestamp(); + + domainListStream << usecTimestampNow(); + // store the nodeInterestSet on this DomainServerNodeData, in case it has changed auto& nodeInterestSet = nodeData->getNodeInterestSet(); diff --git a/domain-server/src/DomainServerNodeData.h b/domain-server/src/DomainServerNodeData.h index f465cceb96..370886cbce 100644 --- a/domain-server/src/DomainServerNodeData.h +++ b/domain-server/src/DomainServerNodeData.h @@ -61,6 +61,9 @@ public: void setMachineFingerprint(const QUuid& machineFingerprint) { _machineFingerprint = machineFingerprint; } const QUuid& getMachineFingerprint() { return _machineFingerprint; } + void setLastDomainCheckinTimestamp(quint64 lastDomainCheckinTimestamp) { _lastDomainCheckinTimestamp = lastDomainCheckinTimestamp; } + quint64 getLastDomainCheckinTimestamp() { return _lastDomainCheckinTimestamp; } + void addOverrideForKey(const QString& key, const QString& value, const QString& overrideValue); void removeOverrideForKey(const QString& key, const QString& value); @@ -93,7 +96,7 @@ private: QString _nodeVersion; QString _hardwareAddress; QUuid _machineFingerprint; - + quint64 _lastDomainCheckinTimestamp; QString _placeName; bool _wasAssigned { false }; diff --git a/domain-server/src/NodeConnectionData.cpp b/domain-server/src/NodeConnectionData.cpp index 0a3782d79b..b3ea005bd1 100644 --- a/domain-server/src/NodeConnectionData.cpp +++ b/domain-server/src/NodeConnectionData.cpp @@ -36,6 +36,8 @@ NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, c // now the machine fingerprint dataStream >> newHeader.machineFingerprint; } + + dataStream >> newHeader.lastPingTimestamp; dataStream >> newHeader.nodeType >> newHeader.publicSockAddr >> newHeader.localSockAddr diff --git a/domain-server/src/NodeConnectionData.h b/domain-server/src/NodeConnectionData.h index dd9ca6b650..779411d11e 100644 --- a/domain-server/src/NodeConnectionData.h +++ b/domain-server/src/NodeConnectionData.h @@ -22,6 +22,7 @@ public: bool isConnectRequest = true); QUuid connectUUID; + quint64 lastPingTimestamp{ 0 }; NodeType_t nodeType; HifiSockAddr publicSockAddr; HifiSockAddr localSockAddr; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 4f0e3ca9bd..31576ff8d9 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -412,6 +412,8 @@ void NodeList::sendDomainServerCheckIn() { packetStream << FingerprintUtils::getMachineFingerprint(); } + packetStream << usecTimestampNow(); + // pack our data to send to the domain-server including // the hostname information (so the domain-server can see which place name we came in on) packetStream << _ownerType.load() << publicSockAddr << localSockAddr << _nodeTypesOfInterest.toList(); @@ -618,32 +620,14 @@ void NodeList::processDomainServerConnectionTokenPacket(QSharedPointer message) { - if (_domainHandler.getSockAddr().isNull()) { - qWarning() << "IGNORING DomainList packet while not connected to a Domain Server"; - // refuse to process this packet if we aren't currently connected to the DS - return; - } - - // this is a packet from the domain server, reset the count of un-replied check-ins - _domainHandler.clearPendingCheckins(); - - // emit our signal so listeners know we just heard from the DS - emit receivedDomainServerList(); - - DependencyManager::get()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveDSList); + // parse header information QDataStream packetStream(message->getMessage()); // grab the domain's ID from the beginning of the packet QUuid domainUUID; packetStream >> domainUUID; - if (_domainHandler.isConnected() && _domainHandler.getUUID() != domainUUID) { - // Recieved packet from different domain. - qWarning() << "IGNORING DomainList packet from" << domainUUID << "while connected to" << _domainHandler.getUUID(); - return; - } - Node::LocalID domainLocalID; packetStream >> domainLocalID; @@ -654,6 +638,57 @@ void NodeList::processDomainServerList(QSharedPointer message) packetStream >> newUUID; packetStream >> newLocalID; + // pull the permissions/right/privileges for this node out of the stream + NodePermissions newPermissions; + packetStream >> newPermissions; + setPermissions(newPermissions); + // Is packet authentication enabled? + bool isAuthenticated; + packetStream >> isAuthenticated; + setAuthenticatePackets(isAuthenticated); + + quint64 connectRequestTimestamp; + quint64 now = usecTimestampNow(); + packetStream >> connectRequestTimestamp; + quint64 pingLagTime = (now - connectRequestTimestamp) / USECS_PER_MSEC; + quint64 domainServerPingReceiveTime; + + packetStream >> domainServerPingReceiveTime; + quint64 domainServerRequestLag = (domainServerPingReceiveTime - connectRequestTimestamp) / USECS_PER_MSEC; + quint64 domainServerResponseLag = (now - domainServerPingReceiveTime) / USECS_PER_MSEC; + + if (_domainHandler.getSockAddr().isNull()) { + qWarning(networking) << "IGNORING DomainList packet while not connected to a Domain Server: sent " << pingLagTime << " msec ago."; + qWarning(networking) << "DomainList request lag (with skew): " << domainServerRequestLag << "msec"; + qWarning(networking) << "DomainList response lag (with skew): " << domainServerResponseLag << "msec"; + // refuse to process this packet if we aren't currently connected to the DS + return; + } + + // warn if ping lag is getting long + if (pingLagTime > MSECS_PER_SECOND) { + qCDebug(networking) << "DomainList ping is lagging: " << pingLagTime << "msec"; + qCDebug(networking) << "DomainList request lag (with skew): " << domainServerRequestLag << "msec"; + qCDebug(networking) << "DomainList response lag (with skew): " << domainServerResponseLag << "msec"; + } + + // this is a packet from the domain server, reset the count of un-replied check-ins + _domainHandler.clearPendingCheckins(); + + // emit our signal so listeners know we just heard from the DS + emit receivedDomainServerList(); + + DependencyManager::get()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveDSList); + + if (_domainHandler.isConnected() && _domainHandler.getUUID() != domainUUID) { + // Recieved packet from different domain. + qWarning() << "IGNORING DomainList packet from" << domainUUID << "while connected to" + << _domainHandler.getUUID() << ": sent " << pingLagTime << " msec ago."; + qWarning(networking) << "DomainList request lag (with skew): " << domainServerRequestLag << "msec"; + qWarning(networking) << "DomainList response lag (with skew): " << domainServerResponseLag << "msec"; + return; + } + // when connected, if the session ID or local ID were not null and changed, we should reset auto currentLocalID = getSessionLocalID(); auto currentSessionID = getSessionUUID(); @@ -684,15 +719,6 @@ void NodeList::processDomainServerList(QSharedPointer message) DependencyManager::get()->lookupShareableNameForDomainID(domainUUID); } - // pull the permissions/right/privileges for this node out of the stream - NodePermissions newPermissions; - packetStream >> newPermissions; - setPermissions(newPermissions); - // Is packet authentication enabled? - bool isAuthenticated; - packetStream >> isAuthenticated; - setAuthenticatePackets(isAuthenticated); - // pull each node in the packet while (packetStream.device()->pos() < message->getSize()) { parseNodeFromPacketStream(packetStream); diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index f8574b3b94..566e1e4946 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -27,7 +27,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::StunResponse: return 17; case PacketType::DomainList: - return static_cast(DomainListVersion::AuthenticationOptional); + return static_cast(DomainListVersion::HasTimestamp); case PacketType::EntityAdd: case PacketType::EntityClone: case PacketType::EntityEdit: @@ -72,7 +72,7 @@ PacketVersion versionForPacketType(PacketType packetType) { return static_cast(DomainConnectionDeniedVersion::IncludesExtraInfo); case PacketType::DomainConnectRequest: - return static_cast(DomainConnectRequestVersion::AlwaysHasMachineFingerprint); + return static_cast(DomainConnectRequestVersion::HasTimestamp); case PacketType::DomainServerAddedNode: return static_cast(DomainServerAddedNodeVersion::PermissionsGrid); diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 5deadd8c43..903c1f4c93 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -344,7 +344,8 @@ enum class DomainConnectRequestVersion : PacketVersion { HasProtocolVersions, HasMACAddress, HasMachineFingerprint, - AlwaysHasMachineFingerprint + AlwaysHasMachineFingerprint, + HasTimestamp }; enum class DomainConnectionDeniedVersion : PacketVersion { @@ -363,7 +364,8 @@ enum class DomainListVersion : PacketVersion { PermissionsGrid, GetUsernameFromUUIDSupport, GetMachineFingerprintFromUUIDSupport, - AuthenticationOptional + AuthenticationOptional, + HasTimestamp }; enum class AudioVersion : PacketVersion { From 9c39d064167d742133b90ec1729eea8dda9b638f Mon Sep 17 00:00:00 2001 From: Roxanne Skelly Date: Thu, 23 May 2019 11:42:51 -0700 Subject: [PATCH 02/11] Don't set permissions / is authenticated when DomainServerList checkin should be ignored. --- libraries/networking/src/NodeList.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 31576ff8d9..e269499938 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -641,11 +641,9 @@ void NodeList::processDomainServerList(QSharedPointer message) // pull the permissions/right/privileges for this node out of the stream NodePermissions newPermissions; packetStream >> newPermissions; - setPermissions(newPermissions); // Is packet authentication enabled? bool isAuthenticated; packetStream >> isAuthenticated; - setAuthenticatePackets(isAuthenticated); quint64 connectRequestTimestamp; quint64 now = usecTimestampNow(); @@ -689,6 +687,9 @@ void NodeList::processDomainServerList(QSharedPointer message) return; } + setPermissions(newPermissions); + setAuthenticatePackets(isAuthenticated); + // when connected, if the session ID or local ID were not null and changed, we should reset auto currentLocalID = getSessionLocalID(); auto currentSessionID = getSessionUUID(); From 1c6cf3df0dd20e77ad6fa00b1806a1a73866e9fb Mon Sep 17 00:00:00 2001 From: Roxanne Skelly Date: Thu, 23 May 2019 14:19:36 -0700 Subject: [PATCH 03/11] Move DomainList timestamps to the extended header And. Lag notifications now use signed values --- domain-server/src/DomainServer.cpp | 10 +++------- libraries/networking/src/NodeList.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 37643cc372..028bfdb9aa 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1160,7 +1160,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif // this data is at the beginning of each of the domain list packets QByteArray extendedHeader(NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES, 0); QDataStream extendedHeaderStream(&extendedHeader, QIODevice::WriteOnly); - + DomainServerNodeData* nodeData = static_cast(node->getLinkedData()); auto limitedNodeList = DependencyManager::get(); extendedHeaderStream << limitedNodeList->getSessionUUID(); @@ -1169,17 +1169,13 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif extendedHeaderStream << node->getLocalID(); extendedHeaderStream << node->getPermissions(); extendedHeaderStream << limitedNodeList->getAuthenticatePackets(); + extendedHeaderStream << nodeData->getLastDomainCheckinTimestamp(); + extendedHeaderStream << usecTimestampNow(); auto domainListPackets = NLPacketList::create(PacketType::DomainList, extendedHeader); // always send the node their own UUID back QDataStream domainListStream(domainListPackets.get()); - DomainServerNodeData* nodeData = static_cast(node->getLinkedData()); - - domainListStream << nodeData->getLastDomainCheckinTimestamp(); - - domainListStream << usecTimestampNow(); - // store the nodeInterestSet on this DomainServerNodeData, in case it has changed auto& nodeInterestSet = nodeData->getNodeInterestSet(); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index e269499938..01c28dd5bb 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -646,14 +646,14 @@ void NodeList::processDomainServerList(QSharedPointer message) packetStream >> isAuthenticated; quint64 connectRequestTimestamp; - quint64 now = usecTimestampNow(); + qint64 now = (qint64)usecTimestampNow(); packetStream >> connectRequestTimestamp; - quint64 pingLagTime = (now - connectRequestTimestamp) / USECS_PER_MSEC; + qint64 pingLagTime = (now - (qint64)connectRequestTimestamp) / (qint64)USECS_PER_MSEC; quint64 domainServerPingReceiveTime; packetStream >> domainServerPingReceiveTime; - quint64 domainServerRequestLag = (domainServerPingReceiveTime - connectRequestTimestamp) / USECS_PER_MSEC; - quint64 domainServerResponseLag = (now - domainServerPingReceiveTime) / USECS_PER_MSEC; + qint64 domainServerRequestLag = ((qint64)domainServerPingReceiveTime - (qint64)connectRequestTimestamp) / (qint64)USECS_PER_MSEC; + qint64 domainServerResponseLag = (now - (qint64)domainServerPingReceiveTime) / (qint64)USECS_PER_MSEC; if (_domainHandler.getSockAddr().isNull()) { qWarning(networking) << "IGNORING DomainList packet while not connected to a Domain Server: sent " << pingLagTime << " msec ago."; From 7fdbbe5b77ee8bdb976fd064be17fc72eecfb967 Mon Sep 17 00:00:00 2001 From: Roxanne Skelly Date: Thu, 23 May 2019 14:45:49 -0700 Subject: [PATCH 04/11] CR: Use functional type conversion instead of c-style casting --- libraries/networking/src/NodeList.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 01c28dd5bb..608af5c764 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -646,14 +646,17 @@ void NodeList::processDomainServerList(QSharedPointer message) packetStream >> isAuthenticated; quint64 connectRequestTimestamp; - qint64 now = (qint64)usecTimestampNow(); + qint64 now = qint64(usecTimestampNow()); + packetStream >> connectRequestTimestamp; - qint64 pingLagTime = (now - (qint64)connectRequestTimestamp) / (qint64)USECS_PER_MSEC; + + qint64 pingLagTime = (now - qint64(connectRequestTimestamp)) / qint64(USECS_PER_MSEC); quint64 domainServerPingReceiveTime; packetStream >> domainServerPingReceiveTime; - qint64 domainServerRequestLag = ((qint64)domainServerPingReceiveTime - (qint64)connectRequestTimestamp) / (qint64)USECS_PER_MSEC; - qint64 domainServerResponseLag = (now - (qint64)domainServerPingReceiveTime) / (qint64)USECS_PER_MSEC; + + qint64 domainServerRequestLag = (qint64(domainServerPingReceiveTime) - qint64(connectRequestTimestamp)) / qint64(USECS_PER_MSEC); + qint64 domainServerResponseLag = (now - qint64(domainServerPingReceiveTime)) / qint64(USECS_PER_MSEC); if (_domainHandler.getSockAddr().isNull()) { qWarning(networking) << "IGNORING DomainList packet while not connected to a Domain Server: sent " << pingLagTime << " msec ago."; From cc3ce9622708121328f513586ed7fb2fed39705d Mon Sep 17 00:00:00 2001 From: Roxanne Skelly Date: Thu, 23 May 2019 15:24:41 -0700 Subject: [PATCH 05/11] fix ubuntu build issue --- libraries/networking/src/NodeList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 608af5c764..d858711e33 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -667,7 +667,7 @@ void NodeList::processDomainServerList(QSharedPointer message) } // warn if ping lag is getting long - if (pingLagTime > MSECS_PER_SECOND) { + if (pingLagTime > qint64(MSECS_PER_SECOND)) { qCDebug(networking) << "DomainList ping is lagging: " << pingLagTime << "msec"; qCDebug(networking) << "DomainList request lag (with skew): " << domainServerRequestLag << "msec"; qCDebug(networking) << "DomainList response lag (with skew): " << domainServerResponseLag << "msec"; From c6de86a80c16fae6246582d426c5a9bc4bc55072 Mon Sep 17 00:00:00 2001 From: Roxanne Skelly Date: Fri, 24 May 2019 14:52:55 -0700 Subject: [PATCH 06/11] Log packet processing time for domain server list request packets --- domain-server/src/DomainGatekeeper.cpp | 5 ++- domain-server/src/DomainGatekeeper.h | 2 +- domain-server/src/DomainServer.cpp | 15 ++++--- domain-server/src/DomainServer.h | 4 +- domain-server/src/NodeConnectionData.h | 2 +- libraries/networking/src/NodeList.cpp | 45 ++++++++++++-------- libraries/networking/src/ReceivedMessage.cpp | 14 +++++- libraries/networking/src/ReceivedMessage.h | 3 ++ libraries/networking/src/udt/Packet.cpp | 1 + libraries/networking/src/udt/PacketList.cpp | 9 ++++ libraries/networking/src/udt/PacketList.h | 3 ++ libraries/networking/src/udt/Socket.cpp | 1 + 12 files changed, 75 insertions(+), 29 deletions(-) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 75399d1a9b..f5705a570b 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -128,7 +128,7 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointergetFirstPacketReceiveTime()); } else { qDebug() << "Refusing connection from node at" << message->getSenderSockAddr() << "with hardware address" << nodeConnection.hardwareAddress @@ -358,6 +358,7 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo nodeData->setNodeVersion(it->second.getNodeVersion()); nodeData->setHardwareAddress(nodeConnection.hardwareAddress); nodeData->setMachineFingerprint(nodeConnection.machineFingerprint); + // client-side send time of last connect/domain list request nodeData->setLastDomainCheckinTimestamp(nodeConnection.lastPingTimestamp); nodeData->setWasAssigned(true); @@ -499,7 +500,7 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect // set the machine fingerprint passed in the connect request nodeData->setMachineFingerprint(nodeConnection.machineFingerprint); - // set the last ping timestamp passed in the connect request + // set client-side send time of last connect/domain list request nodeData->setLastDomainCheckinTimestamp(nodeConnection.lastPingTimestamp); // also add an interpolation to DomainServerNodeData so that servers can get username in stats diff --git a/domain-server/src/DomainGatekeeper.h b/domain-server/src/DomainGatekeeper.h index f8d79179d6..92b400882e 100644 --- a/domain-server/src/DomainGatekeeper.h +++ b/domain-server/src/DomainGatekeeper.h @@ -64,7 +64,7 @@ public slots: signals: void killNode(SharedNodePointer node); - void connectedNode(SharedNodePointer node); + void connectedNode(SharedNodePointer node, quint64 requestReceiveTime); public slots: void updateNodePermissions(); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 028bfdb9aa..e8401c64c7 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -57,6 +58,8 @@ #include +using namespace std::chrono; + Q_LOGGING_CATEGORY(domain_server, "hifi.domain_server") Q_LOGGING_CATEGORY(domain_server_ice, "hifi.domain_server.ice") @@ -1068,9 +1071,10 @@ void DomainServer::processListRequestPacket(QSharedPointer mess // update the connecting hostname in case it has changed nodeData->setPlaceName(nodeRequestData.placeName); + // client-side send time of last connect/domain list request nodeData->setLastDomainCheckinTimestamp(nodeRequestData.lastPingTimestamp); - sendDomainListToNode(sendingNode, message->getSenderSockAddr()); + sendDomainListToNode(sendingNode, message->getFirstPacketReceiveTime(), message->getSenderSockAddr()); } bool DomainServer::isInInterestSet(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB) { @@ -1132,11 +1136,11 @@ QUrl DomainServer::oauthAuthorizationURL(const QUuid& stateUUID) { return authorizationURL; } -void DomainServer::handleConnectedNode(SharedNodePointer newNode) { +void DomainServer::handleConnectedNode(SharedNodePointer newNode, quint64 requestReceiveTime) { DomainServerNodeData* nodeData = static_cast(newNode->getLinkedData()); // reply back to the user with a PacketType::DomainList - sendDomainListToNode(newNode, nodeData->getSendingSockAddr()); + sendDomainListToNode(newNode, requestReceiveTime, nodeData->getSendingSockAddr()); // if this node is a user (unassigned Agent), signal if (newNode->getType() == NodeType::Agent && !nodeData->wasAssigned()) { @@ -1152,7 +1156,7 @@ void DomainServer::handleConnectedNode(SharedNodePointer newNode) { broadcastNewNode(newNode); } -void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr &senderSockAddr) { +void DomainServer::sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const HifiSockAddr &senderSockAddr) { 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; @@ -1170,7 +1174,8 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif extendedHeaderStream << node->getPermissions(); extendedHeaderStream << limitedNodeList->getAuthenticatePackets(); extendedHeaderStream << nodeData->getLastDomainCheckinTimestamp(); - extendedHeaderStream << usecTimestampNow(); + extendedHeaderStream << requestPacketReceiveTime; + extendedHeaderStream << duration_cast(p_high_resolution_clock::now().time_since_epoch()).count(); auto domainListPackets = NLPacketList::create(PacketType::DomainList, extendedHeader); // always send the node their own UUID back diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 8276566233..704650e594 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -111,7 +111,7 @@ private slots: void sendHeartbeatToMetaverse() { sendHeartbeatToMetaverse(QString()); } void sendHeartbeatToIceServer(); - void handleConnectedNode(SharedNodePointer newNode); + void handleConnectedNode(SharedNodePointer newNode, quint64 requestReceiveTime); void handleTempDomainSuccess(QNetworkReply* requestReply); void handleTempDomainError(QNetworkReply* requestReply); @@ -172,7 +172,7 @@ private: void handleKillNode(SharedNodePointer nodeToKill); void broadcastNodeDisconnect(const SharedNodePointer& disconnnectedNode); - void sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr& senderSockAddr); + void sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const HifiSockAddr& senderSockAddr); bool isInInterestSet(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB); diff --git a/domain-server/src/NodeConnectionData.h b/domain-server/src/NodeConnectionData.h index 779411d11e..43661f9caf 100644 --- a/domain-server/src/NodeConnectionData.h +++ b/domain-server/src/NodeConnectionData.h @@ -22,7 +22,7 @@ public: bool isConnectRequest = true); QUuid connectUUID; - quint64 lastPingTimestamp{ 0 }; + quint64 lastPingTimestamp{ 0 }; // client-side send time of last connect/domain list request NodeType_t nodeType; HifiSockAddr publicSockAddr; HifiSockAddr localSockAddr; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index d858711e33..aabeabbbf5 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -11,6 +11,8 @@ #include "NodeList.h" +#include + #include #include #include @@ -37,6 +39,8 @@ #include "SharedUtil.h" #include +using namespace std::chrono; + const int KEEPALIVE_PING_INTERVAL_MS = 1000; NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) : @@ -412,7 +416,7 @@ void NodeList::sendDomainServerCheckIn() { packetStream << FingerprintUtils::getMachineFingerprint(); } - packetStream << usecTimestampNow(); + packetStream << duration_cast(p_high_resolution_clock::now().time_since_epoch()).count(); // pack our data to send to the domain-server including // the hostname information (so the domain-server can see which place name we came in on) @@ -645,23 +649,28 @@ void NodeList::processDomainServerList(QSharedPointer message) bool isAuthenticated; packetStream >> isAuthenticated; - quint64 connectRequestTimestamp; - qint64 now = qint64(usecTimestampNow()); + qint64 now = qint64(duration_cast(p_high_resolution_clock::now().time_since_epoch()).count()); + quint64 connectRequestTimestamp; packetStream >> connectRequestTimestamp; + quint64 domainServerRequestReceiveTime; + packetStream >> domainServerRequestReceiveTime; + + quint64 domainServerPingSendTime; + packetStream >> domainServerPingSendTime; + qint64 pingLagTime = (now - qint64(connectRequestTimestamp)) / qint64(USECS_PER_MSEC); - quint64 domainServerPingReceiveTime; - packetStream >> domainServerPingReceiveTime; - - qint64 domainServerRequestLag = (qint64(domainServerPingReceiveTime) - qint64(connectRequestTimestamp)) / qint64(USECS_PER_MSEC); - qint64 domainServerResponseLag = (now - qint64(domainServerPingReceiveTime)) / qint64(USECS_PER_MSEC); + qint64 domainServerRequestLag = (qint64(connectRequestTimestamp) - qint64(connectRequestTimestamp)) / qint64(USECS_PER_MSEC); + quint64 domainServerCheckinProcessingTime = domainServerPingSendTime - domainServerRequestReceiveTime; + qint64 domainServerResponseLag = (now - qint64(domainServerPingSendTime)) / qint64(USECS_PER_MSEC); if (_domainHandler.getSockAddr().isNull()) { qWarning(networking) << "IGNORING DomainList packet while not connected to a Domain Server: sent " << pingLagTime << " msec ago."; - qWarning(networking) << "DomainList request lag (with skew): " << domainServerRequestLag << "msec"; - qWarning(networking) << "DomainList response lag (with skew): " << domainServerResponseLag << "msec"; + qWarning(networking) << "DomainList request lag (interface->ds): " << domainServerRequestLag << "msec"; + qWarning(networking) << "DomainList server processing time: " << domainServerCheckinProcessingTime << "usec"; + qWarning(networking) << "DomainList response lag (ds->interface): " << domainServerResponseLag << "msec"; // refuse to process this packet if we aren't currently connected to the DS return; } @@ -669,8 +678,9 @@ void NodeList::processDomainServerList(QSharedPointer message) // warn if ping lag is getting long if (pingLagTime > qint64(MSECS_PER_SECOND)) { qCDebug(networking) << "DomainList ping is lagging: " << pingLagTime << "msec"; - qCDebug(networking) << "DomainList request lag (with skew): " << domainServerRequestLag << "msec"; - qCDebug(networking) << "DomainList response lag (with skew): " << domainServerResponseLag << "msec"; + qCDebug(networking) << "DomainList request lag (interface->ds): " << domainServerRequestLag << "msec"; + qCDebug(networking) << "DomainList server processing time: " << domainServerCheckinProcessingTime << "usec"; + qCDebug(networking) << "DomainList response lag (ds->interface): " << domainServerResponseLag << "msec"; } // this is a packet from the domain server, reset the count of un-replied check-ins @@ -685,14 +695,12 @@ void NodeList::processDomainServerList(QSharedPointer message) // Recieved packet from different domain. qWarning() << "IGNORING DomainList packet from" << domainUUID << "while connected to" << _domainHandler.getUUID() << ": sent " << pingLagTime << " msec ago."; - qWarning(networking) << "DomainList request lag (with skew): " << domainServerRequestLag << "msec"; - qWarning(networking) << "DomainList response lag (with skew): " << domainServerResponseLag << "msec"; + qWarning(networking) << "DomainList request lag (interface->ds): " << domainServerRequestLag << "msec"; + qWarning(networking) << "DomainList server processing time: " << domainServerCheckinProcessingTime << "usec"; + qWarning(networking) << "DomainList response lag (ds->interface): " << domainServerResponseLag << "msec"; return; } - setPermissions(newPermissions); - setAuthenticatePackets(isAuthenticated); - // when connected, if the session ID or local ID were not null and changed, we should reset auto currentLocalID = getSessionLocalID(); auto currentSessionID = getSessionUUID(); @@ -723,6 +731,9 @@ void NodeList::processDomainServerList(QSharedPointer message) DependencyManager::get()->lookupShareableNameForDomainID(domainUUID); } + setPermissions(newPermissions); + setAuthenticatePackets(isAuthenticated); + // pull each node in the packet while (packetStream.device()->pos() < message->getSize()) { parseNodeFromPacketStream(packetStream); diff --git a/libraries/networking/src/ReceivedMessage.cpp b/libraries/networking/src/ReceivedMessage.cpp index e70301dab1..86fd3da9ad 100644 --- a/libraries/networking/src/ReceivedMessage.cpp +++ b/libraries/networking/src/ReceivedMessage.cpp @@ -12,6 +12,7 @@ #include "ReceivedMessage.h" #include +#include #include "QSharedPointer" @@ -20,6 +21,8 @@ int sharedPtrReceivedMessageMetaTypeId = qRegisterMetaType(packetList.getFirstPacketReceiveTime().time_since_epoch()).count(); } ReceivedMessage::ReceivedMessage(NLPacket& packet) @@ -41,12 +45,14 @@ ReceivedMessage::ReceivedMessage(NLPacket& packet) _senderSockAddr(packet.getSenderSockAddr()), _isComplete(packet.getPacketPosition() == NLPacket::ONLY) { + _firstPacketReceiveTime = duration_cast(packet.getReceiveTime().time_since_epoch()).count(); } ReceivedMessage::ReceivedMessage(QByteArray byteArray, PacketType packetType, PacketVersion packetVersion, const HifiSockAddr& senderSockAddr, NLPacket::LocalID sourceID) : _data(byteArray), _headData(_data.mid(0, HEAD_DATA_SIZE)), + _firstPacketReceiveTime(0), _numPackets(1), _sourceID(sourceID), _packetType(packetType), @@ -77,7 +83,13 @@ void ReceivedMessage::appendPacket(NLPacket& packet) { emit progress(getSize()); } - if (packet.getPacketPosition() == NLPacket::PacketPosition::LAST) { + auto packetPosition = packet.getPacketPosition(); + if ((packetPosition == NLPacket::PacketPosition::FIRST) || + (packetPosition == NLPacket::PacketPosition::ONLY)) { + _firstPacketReceiveTime = duration_cast(packet.getReceiveTime().time_since_epoch()).count(); + } + + if (packetPosition == NLPacket::PacketPosition::LAST) { _isComplete = true; emit completed(); } diff --git a/libraries/networking/src/ReceivedMessage.h b/libraries/networking/src/ReceivedMessage.h index af87ef75af..c864616635 100644 --- a/libraries/networking/src/ReceivedMessage.h +++ b/libraries/networking/src/ReceivedMessage.h @@ -48,6 +48,8 @@ public: // Get the number of packets that were used to send this message qint64 getNumPackets() const { return _numPackets; } + qint64 getFirstPacketReceiveTime() const { return _firstPacketReceiveTime; } + qint64 getSize() const { return _data.size(); } qint64 getBytesLeftToRead() const { return _data.size() - _position; } @@ -92,6 +94,7 @@ private: std::atomic _position { 0 }; std::atomic _numPackets { 0 }; + std::atomic _firstPacketReceiveTime { 0 }; NLPacket::LocalID _sourceID { NLPacket::NULL_LOCAL_ID }; PacketType _packetType; diff --git a/libraries/networking/src/udt/Packet.cpp b/libraries/networking/src/udt/Packet.cpp index 0456fa1223..f8b74cea37 100644 --- a/libraries/networking/src/udt/Packet.cpp +++ b/libraries/networking/src/udt/Packet.cpp @@ -171,6 +171,7 @@ void Packet::copyMembers(const Packet& other) { _packetPosition = other._packetPosition; _messageNumber = other._messageNumber; _messagePartNumber = other._messagePartNumber; + _receiveTime = other._receiveTime; } void Packet::readHeader() const { diff --git a/libraries/networking/src/udt/PacketList.cpp b/libraries/networking/src/udt/PacketList.cpp index d69ff39197..f6ea12242e 100644 --- a/libraries/networking/src/udt/PacketList.cpp +++ b/libraries/networking/src/udt/PacketList.cpp @@ -13,6 +13,7 @@ #include "../NetworkLogging.h" +#include #include using namespace udt; @@ -261,3 +262,11 @@ qint64 PacketList::writeData(const char* data, qint64 maxSize) { return maxSize; } + +p_high_resolution_clock::time_point PacketList::getFirstPacketReceiveTime() const { + using namespace std::chrono;; + if (!_packets.empty()) { + return _packets.front()->getReceiveTime(); + } + return p_high_resolution_clock::time_point(); +} \ No newline at end of file diff --git a/libraries/networking/src/udt/PacketList.h b/libraries/networking/src/udt/PacketList.h index b9bd6a8c15..8d3ffb2783 100644 --- a/libraries/networking/src/udt/PacketList.h +++ b/libraries/networking/src/udt/PacketList.h @@ -59,6 +59,9 @@ public: virtual qint64 size() const override { return getDataSize(); } qint64 writeString(const QString& string); + + p_high_resolution_clock::time_point getFirstPacketReceiveTime() const; + protected: PacketList(PacketType packetType, QByteArray extendedHeader = QByteArray(), bool isReliable = false, bool isOrdered = false); diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index 7829e3727c..6f93281b2a 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -334,6 +334,7 @@ void Socket::readPendingDatagrams() { if (system_clock::now() > abortTime) { // We've been running for too long, stop processing packets for now // Once we've processed the event queue, we'll come back to packet processing + qCDebug(networking) << "Socket::readPendingDatagrams() running too long, aborting to process event queue"; break; } From 41be22a7bb3b4f78beae017a8cb823591c08fad5 Mon Sep 17 00:00:00 2001 From: Roxanne Skelly Date: Fri, 24 May 2019 15:22:33 -0700 Subject: [PATCH 07/11] ubuntu build fix and CR fix --- domain-server/src/DomainServer.cpp | 2 +- libraries/networking/src/NodeList.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index e8401c64c7..9a2aaca18b 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1175,7 +1175,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, quint64 r extendedHeaderStream << limitedNodeList->getAuthenticatePackets(); extendedHeaderStream << nodeData->getLastDomainCheckinTimestamp(); extendedHeaderStream << requestPacketReceiveTime; - extendedHeaderStream << duration_cast(p_high_resolution_clock::now().time_since_epoch()).count(); + extendedHeaderStream << quint64(duration_cast(p_high_resolution_clock::now().time_since_epoch()).count()); auto domainListPackets = NLPacketList::create(PacketType::DomainList, extendedHeader); // always send the node their own UUID back diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index aabeabbbf5..ae2a495431 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -416,7 +416,7 @@ void NodeList::sendDomainServerCheckIn() { packetStream << FingerprintUtils::getMachineFingerprint(); } - packetStream << duration_cast(p_high_resolution_clock::now().time_since_epoch()).count(); + packetStream << quint64(duration_cast(p_high_resolution_clock::now().time_since_epoch()).count()); // pack our data to send to the domain-server including // the hostname information (so the domain-server can see which place name we came in on) @@ -662,7 +662,7 @@ void NodeList::processDomainServerList(QSharedPointer message) qint64 pingLagTime = (now - qint64(connectRequestTimestamp)) / qint64(USECS_PER_MSEC); - qint64 domainServerRequestLag = (qint64(connectRequestTimestamp) - qint64(connectRequestTimestamp)) / qint64(USECS_PER_MSEC); + qint64 domainServerRequestLag = (qint64(domainServerRequestReceiveTime) - qint64(connectRequestTimestamp)) / qint64(USECS_PER_MSEC); quint64 domainServerCheckinProcessingTime = domainServerPingSendTime - domainServerRequestReceiveTime; qint64 domainServerResponseLag = (now - qint64(domainServerPingSendTime)) / qint64(USECS_PER_MSEC); From 82f8687e9fbe77fd01ab2351930d5b832fc31ef2 Mon Sep 17 00:00:00 2001 From: Roxanne Skelly Date: Fri, 24 May 2019 15:47:30 -0700 Subject: [PATCH 08/11] ubuntu builds are picky (fix initializer order issue) --- libraries/networking/src/ReceivedMessage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/ReceivedMessage.cpp b/libraries/networking/src/ReceivedMessage.cpp index 86fd3da9ad..7ae408ef7a 100644 --- a/libraries/networking/src/ReceivedMessage.cpp +++ b/libraries/networking/src/ReceivedMessage.cpp @@ -52,8 +52,8 @@ ReceivedMessage::ReceivedMessage(QByteArray byteArray, PacketType packetType, Pa const HifiSockAddr& senderSockAddr, NLPacket::LocalID sourceID) : _data(byteArray), _headData(_data.mid(0, HEAD_DATA_SIZE)), - _firstPacketReceiveTime(0), _numPackets(1), + _firstPacketReceiveTime(0), _sourceID(sourceID), _packetType(packetType), _packetVersion(packetVersion), From 1894951f54adddfbe184eed049d67f7121d2e10f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 28 May 2019 16:15:00 -0700 Subject: [PATCH 09/11] Add ignorePickIntersection to Create --- scripts/system/assets/data/createAppTooltips.json | 3 +++ scripts/system/html/js/entityProperties.js | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/scripts/system/assets/data/createAppTooltips.json b/scripts/system/assets/data/createAppTooltips.json index cc622c2184..b59797fca7 100644 --- a/scripts/system/assets/data/createAppTooltips.json +++ b/scripts/system/assets/data/createAppTooltips.json @@ -492,6 +492,9 @@ "canCastShadow": { "tooltip": "If enabled, this geometry of this entity casts shadows when a shadow-casting light source shines on it." }, + "ignorePickIntersection": { + "tooltip": "If enabled, this entity will not be considered for ray picks, and will also not occlude other entities when picking." + }, "parentID": { "tooltip": "The ID of the entity or avatar that this entity is parented to." }, diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index d7800ada5d..e64543d41f 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -1329,7 +1329,7 @@ const GROUPS = [ propertyID: "grab.grabFollowsController", }, { - label: "Cast shadows", + label: "Cast Shadows", type: "bool", propertyID: "canCastShadow", }, @@ -1339,6 +1339,11 @@ const GROUPS = [ propertyID: "href", placeholder: "URL", }, + { + label: "Ignore Pick Intersection", + type: "bool", + propertyID: "ignorePickIntersection", + }, { label: "Script", type: "string", From 568d3ab1f9788ce6e6f9f1ee5e25d5311d984266 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 29 May 2019 09:19:11 -0700 Subject: [PATCH 10/11] Fix release build zip name --- tools/ci-scripts/postbuild.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ci-scripts/postbuild.py b/tools/ci-scripts/postbuild.py index e735083bda..ab01e7c795 100644 --- a/tools/ci-scripts/postbuild.py +++ b/tools/ci-scripts/postbuild.py @@ -32,7 +32,7 @@ elif sys.platform == "darwin": def computeArchiveName(): RELEASE_TYPE = os.getenv("RELEASE_TYPE", "DEV") RELEASE_NUMBER = os.getenv("RELEASE_NUMBER", "") - GIT_PR_COMMIT_SHORT = os.getenv("GIT_PR_COMMIT_SHORT", "") + GIT_PR_COMMIT_SHORT = os.getenv("SHA7", "") if RELEASE_TYPE == "PRODUCTION": BUILD_VERSION = "{}-{}".format(RELEASE_NUMBER, GIT_PR_COMMIT_SHORT) From ecc331211410b3f5b6be44a0dc0d62ee4fff0392 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 29 May 2019 12:17:07 -0700 Subject: [PATCH 11/11] Use unique_ptr for temp signature array --- interface/src/commerce/Wallet.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index aa50b42075..5af7a357b0 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -654,7 +654,7 @@ QString Wallet::signWithKey(const QByteArray& text, const QString& key) { EC_KEY* ecPrivateKey = NULL; if ((ecPrivateKey = readPrivateKey(keyFilePath()))) { - unsigned char* sig = new unsigned char[ECDSA_size(ecPrivateKey)]; + const auto sig = std::make_unique(ECDSA_size(ecPrivateKey)); unsigned int signatureBytes = 0; @@ -663,10 +663,10 @@ QString Wallet::signWithKey(const QByteArray& text, const QString& key) { QByteArray hashedPlaintext = QCryptographicHash::hash(text, QCryptographicHash::Sha256); int retrn = ECDSA_sign(0, reinterpret_cast(hashedPlaintext.constData()), hashedPlaintext.size(), - sig, &signatureBytes, ecPrivateKey); + sig.get(), &signatureBytes, ecPrivateKey); EC_KEY_free(ecPrivateKey); - QByteArray signature(reinterpret_cast(sig), signatureBytes); + QByteArray signature(reinterpret_cast(sig.get()), signatureBytes); if (retrn != -1) { return signature.toBase64(); }