From 9e7fb9ae1609d19957f39a6509f40d2911d155fd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 23 Jul 2015 13:56:47 -0700 Subject: [PATCH] shuffle Packet headers, use static enum for PacketType --- assignment-client/src/audio/AudioMixer.cpp | 2 +- .../src/audio/AudioMixerClientData.cpp | 2 +- .../src/audio/AvatarAudioStream.cpp | 2 +- .../src/audio/AvatarAudioStream.h | 2 +- .../src/entities/EntityNodeData.h | 2 +- assignment-client/src/entities/EntityServer.h | 4 +- .../octree/OctreeInboundPacketProcessor.cpp | 2 +- .../src/octree/OctreeQueryNode.h | 4 +- assignment-client/src/octree/OctreeServer.h | 4 +- ice-server/src/IceServer.cpp | 28 ++-- ice-server/src/IceServer.h | 4 +- interface/src/Application.cpp | 2 +- interface/src/Application.h | 2 +- .../src/octree/OctreePacketProcessor.cpp | 8 +- libraries/audio/src/InboundAudioStream.cpp | 4 +- libraries/audio/src/InboundAudioStream.h | 4 +- libraries/audio/src/InjectedAudioStream.cpp | 2 +- libraries/audio/src/InjectedAudioStream.h | 2 +- .../audio/src/MixedProcessedAudioStream.cpp | 2 +- .../audio/src/MixedProcessedAudioStream.h | 2 +- .../src/EntityTreeRenderer.h | 4 +- .../entities/src/EntityEditPacketSender.cpp | 4 +- .../entities/src/EntityEditPacketSender.h | 4 +- .../entities/src/EntityItemProperties.cpp | 2 +- libraries/entities/src/EntityItemProperties.h | 2 +- .../entities/src/EntityScriptingInterface.cpp | 2 +- .../entities/src/EntityScriptingInterface.h | 2 +- libraries/entities/src/EntityTree.cpp | 2 +- libraries/entities/src/EntityTree.h | 4 +- .../entities/src/EntityTreeHeadlessViewer.h | 4 +- libraries/networking/src/LimitedNodeList.cpp | 46 +++--- libraries/networking/src/LimitedNodeList.h | 4 +- libraries/networking/src/NLPacket.cpp | 81 ++++++++--- libraries/networking/src/NLPacket.h | 37 +++-- libraries/networking/src/NLPacketList.cpp | 2 +- libraries/networking/src/NLPacketList.h | 2 +- libraries/networking/src/Node.h | 2 +- libraries/networking/src/NodeList.cpp | 4 +- libraries/networking/src/PacketReceiver.cpp | 26 ++-- libraries/networking/src/PacketReceiver.h | 14 +- libraries/networking/src/udt/Packet.cpp | 108 ++++++-------- libraries/networking/src/udt/Packet.h | 52 +++---- .../networking/src/udt/PacketHeaders.cpp | 134 ++++++++++-------- libraries/networking/src/udt/PacketHeaders.h | 112 ++++++++------- libraries/networking/src/udt/PacketList.cpp | 5 +- libraries/networking/src/udt/PacketList.h | 6 +- libraries/octree/src/Octree.cpp | 10 +- libraries/octree/src/Octree.h | 4 +- .../octree/src/OctreeEditPacketSender.cpp | 4 +- libraries/octree/src/OctreeEditPacketSender.h | 8 +- libraries/octree/src/OctreeHeadlessViewer.cpp | 2 +- libraries/octree/src/OctreePacketData.h | 2 +- libraries/octree/src/OctreeRenderer.h | 4 +- 53 files changed, 426 insertions(+), 357 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index aa8e405d34..0cf5ffb3ca 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -97,7 +97,7 @@ AudioMixer::AudioMixer(NLPacket& packet) : auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - QSet nodeAudioPackets { + QSet nodeAudioPackets { PacketType::MicrophoneAudioNoEcho, PacketType::MicrophoneAudioWithEcho, PacketType::InjectAudio, PacketType::SilentAudioFrame, PacketType::AudioStreamStats diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index 10a5992fd8..e27682de68 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -50,7 +50,7 @@ AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() const { } int AudioMixerClientData::parseData(NLPacket& packet) { - PacketType::Value packetType = packet.getType(); + PacketType packetType = packet.getType(); if (packetType == PacketType::AudioStreamStats) { diff --git a/assignment-client/src/audio/AvatarAudioStream.cpp b/assignment-client/src/audio/AvatarAudioStream.cpp index 4c71777d01..da995c999d 100644 --- a/assignment-client/src/audio/AvatarAudioStream.cpp +++ b/assignment-client/src/audio/AvatarAudioStream.cpp @@ -18,7 +18,7 @@ AvatarAudioStream::AvatarAudioStream(bool isStereo, const InboundAudioStream::Se { } -int AvatarAudioStream::parseStreamProperties(PacketType::Value type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) { +int AvatarAudioStream::parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) { int readBytes = 0; if (type == PacketType::SilentAudioFrame) { diff --git a/assignment-client/src/audio/AvatarAudioStream.h b/assignment-client/src/audio/AvatarAudioStream.h index 7dc87f7d41..cc2ff1aca7 100644 --- a/assignment-client/src/audio/AvatarAudioStream.h +++ b/assignment-client/src/audio/AvatarAudioStream.h @@ -25,7 +25,7 @@ private: AvatarAudioStream(const AvatarAudioStream&); AvatarAudioStream& operator= (const AvatarAudioStream&); - int parseStreamProperties(PacketType::Value type, const QByteArray& packetAfterSeqNum, int& numAudioSamples); + int parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples); }; #endif // hifi_AvatarAudioStream_h diff --git a/assignment-client/src/entities/EntityNodeData.h b/assignment-client/src/entities/EntityNodeData.h index d779a0b58d..e4008fcb03 100644 --- a/assignment-client/src/entities/EntityNodeData.h +++ b/assignment-client/src/entities/EntityNodeData.h @@ -22,7 +22,7 @@ public: OctreeQueryNode(), _lastDeletedEntitiesSentAt(0) { } - virtual PacketType::Value getMyPacketType() const { return PacketType::EntityData; } + virtual PacketType getMyPacketType() const { return PacketType::EntityData; } quint64 getLastDeletedEntitiesSentAt() const { return _lastDeletedEntitiesSentAt; } void setLastDeletedEntitiesSentAt(quint64 sentAt) { _lastDeletedEntitiesSentAt = sentAt; } diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index 1c4eda3cc0..159fc04bf5 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -28,11 +28,11 @@ public: // Subclasses must implement these methods virtual OctreeQueryNode* createOctreeQueryNode(); virtual char getMyNodeType() const { return NodeType::EntityServer; } - virtual PacketType::Value getMyQueryMessageType() const { return PacketType::EntityQuery; } + virtual PacketType getMyQueryMessageType() const { return PacketType::EntityQuery; } virtual const char* getMyServerName() const { return MODEL_SERVER_NAME; } virtual const char* getMyLoggingServerTargetName() const { return MODEL_SERVER_LOGGING_TARGET_NAME; } virtual const char* getMyDefaultPersistFilename() const { return LOCAL_MODELS_PERSIST_FILE; } - virtual PacketType::Value getMyEditNackType() const { return PacketType::EntityEditNack; } + virtual PacketType getMyEditNackType() const { return PacketType::EntityEditNack; } virtual QString getMyDomainSettingsKey() const { return QString("entity_server_settings"); } // subclass may implement these method diff --git a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp index fe61a3945c..d664b35ead 100644 --- a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp +++ b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp @@ -89,7 +89,7 @@ void OctreeInboundPacketProcessor::processPacket(QSharedPointer packet } // Ask our tree subclass if it can handle the incoming packet... - PacketType::Value packetType = packet->getType(); + PacketType packetType = packet->getType(); if (_myServer->getOctree()->handlesEditPacketType(packetType)) { PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE", debugProcessPacket); diff --git a/assignment-client/src/octree/OctreeQueryNode.h b/assignment-client/src/octree/OctreeQueryNode.h index 5982eeb4bc..0c691a06a2 100644 --- a/assignment-client/src/octree/OctreeQueryNode.h +++ b/assignment-client/src/octree/OctreeQueryNode.h @@ -34,7 +34,7 @@ public: virtual ~OctreeQueryNode(); void init(); // called after creation to set up some virtual items - virtual PacketType::Value getMyPacketType() const = 0; + virtual PacketType getMyPacketType() const = 0; void resetOctreePacket(); // resets octree packet to after "V" header @@ -150,7 +150,7 @@ private: quint64 _lastRootTimestamp; - PacketType::Value _myPacketType; + PacketType _myPacketType; bool _isShuttingDown; SentPacketHistory _sentPacketHistory; diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index 419cdabc58..edaf6283f7 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -63,11 +63,11 @@ public: // Subclasses must implement these methods virtual OctreeQueryNode* createOctreeQueryNode() = 0; virtual char getMyNodeType() const = 0; - virtual PacketType::Value getMyQueryMessageType() const = 0; + virtual PacketType getMyQueryMessageType() const = 0; virtual const char* getMyServerName() const = 0; virtual const char* getMyLoggingServerTargetName() const = 0; virtual const char* getMyDefaultPersistFilename() const = 0; - virtual PacketType::Value getMyEditNackType() const = 0; + virtual PacketType getMyEditNackType() const = 0; virtual QString getMyDomainSettingsKey() const { return QString("octree_server_settings"); } // subclass may implement these method diff --git a/ice-server/src/IceServer.cpp b/ice-server/src/IceServer.cpp index 0545e0d274..9ddb67677d 100644 --- a/ice-server/src/IceServer.cpp +++ b/ice-server/src/IceServer.cpp @@ -49,26 +49,30 @@ IceServer::IceServer(int argc, char* argv[]) : } bool IceServer::packetVersionMatch(const udt::Packet& packet) { - if (packet.getVersion() == versionForPacketType(packet.getType())) { + PacketType headerType = NLPacket::typeInHeader(packet); + PacketVersion headerVersion = NLPacket::versionInHeader(packet); + + if (headerVersion == versionForPacketType(headerType)) { return true; } else { - qDebug() << "Packet version mismatch for packet" << packet.getType() - << "(" << nameForPacketType(packet.getType()) << ") from" << packet.getSenderSockAddr(); + qDebug() << "Packet version mismatch for packet" << headerType + << "(" << nameForPacketType(headerType) << ") from" << packet.getSenderSockAddr(); return false; } } void IceServer::processPacket(std::unique_ptr packet) { - PacketType::Value packetType = packet->getType(); - if (packetType == PacketType::ICEServerHeartbeat) { - SharedNetworkPeer peer = addOrUpdateHeartbeatingPeer(*packet); + auto nlPacket = NLPacket::fromBase(std::move(packet)); + + if (nlPacket->getType() == PacketType::ICEServerHeartbeat) { + SharedNetworkPeer peer = addOrUpdateHeartbeatingPeer(*nlPacket); // so that we can send packets to the heartbeating peer when we need, we need to activate a socket now - peer->activateMatchingOrNewSymmetricSocket(packet->getSenderSockAddr()); - } else if (packetType == PacketType::ICEServerQuery) { - QDataStream heartbeatStream(packet.get()); + peer->activateMatchingOrNewSymmetricSocket(nlPacket->getSenderSockAddr()); + } else if (nlPacket->getType() == PacketType::ICEServerQuery) { + QDataStream heartbeatStream(nlPacket.get()); // this is a node hoping to connect to a heartbeating peer - do we have the heartbeating peer? QUuid senderUUID; @@ -89,7 +93,7 @@ void IceServer::processPacket(std::unique_ptr packet) { qDebug() << "Sending information for peer" << connectRequestID << "to peer" << senderUUID; // we have the peer they want to connect to - send them pack the information for that peer - sendPeerInformationPacket(*matchingPeer, &packet->getSenderSockAddr()); + sendPeerInformationPacket(*matchingPeer, &nlPacket->getSenderSockAddr()); // we also need to send them to the active peer they are hoping to connect to // create a dummy peer object we can pass to sendPeerInformationPacket @@ -102,7 +106,7 @@ void IceServer::processPacket(std::unique_ptr packet) { } } -SharedNetworkPeer IceServer::addOrUpdateHeartbeatingPeer(udt::Packet& packet) { +SharedNetworkPeer IceServer::addOrUpdateHeartbeatingPeer(NLPacket& packet) { // pull the UUID, public and private sock addrs for this peer QUuid senderUUID; @@ -135,7 +139,7 @@ SharedNetworkPeer IceServer::addOrUpdateHeartbeatingPeer(udt::Packet& packet) { } void IceServer::sendPeerInformationPacket(const NetworkPeer& peer, const HifiSockAddr* destinationSockAddr) { - auto peerPacket = udt::Packet::create(PacketType::ICEServerPeerInformation); + auto peerPacket = NLPacket::create(PacketType::ICEServerPeerInformation); // get the byte array for this peer peerPacket->write(peer.toByteArray()); diff --git a/ice-server/src/IceServer.h b/ice-server/src/IceServer.h index 3ab6df9044..f1c2c06b65 100644 --- a/ice-server/src/IceServer.h +++ b/ice-server/src/IceServer.h @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include typedef QHash NetworkPeerHash; @@ -35,7 +35,7 @@ private: bool packetVersionMatch(const udt::Packet& packet); void processPacket(std::unique_ptr packet); - SharedNetworkPeer addOrUpdateHeartbeatingPeer(udt::Packet& incomingPacket); + SharedNetworkPeer addOrUpdateHeartbeatingPeer(NLPacket& incomingPacket); void sendPeerInformationPacket(const NetworkPeer& peer, const HifiSockAddr* destinationSockAddr); QUuid _id; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7c3b5a620e..8a9042ad51 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2706,7 +2706,7 @@ int Application::sendNackPackets() { return packetsSent; } -void Application::queryOctree(NodeType_t serverType, PacketType::Value packetType, NodeToJurisdictionMap& jurisdictions) { +void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) { //qCDebug(interfaceapp) << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView(); bool wantExtraDebugging = getLogger()->extraDebugging(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 3a07fb656d..220ef04abc 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -478,7 +478,7 @@ private: void renderLookatIndicator(glm::vec3 pointOfInterest); - void queryOctree(NodeType_t serverType, PacketType::Value packetType, NodeToJurisdictionMap& jurisdictions); + void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions); void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum); glm::vec3 getSunDirection(); diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 386ebacc6d..e35e841a7b 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -19,7 +19,7 @@ OctreePacketProcessor::OctreePacketProcessor() { auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - QSet types { + QSet types { PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase, PacketType::OctreeStats }; @@ -44,7 +44,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer packet, Share Application* app = Application::getInstance(); bool wasStatsPacket = false; - PacketType::Value octreePacketType = packet->getType(); + PacketType octreePacketType = packet->getType(); // note: PacketType_OCTREE_STATS can have PacketType_VOXEL_DATA // immediately following them inside the same packet. So, we process the PacketType_OCTREE_STATS first @@ -68,11 +68,11 @@ void OctreePacketProcessor::processPacket(QSharedPointer packet, Share } } // fall through to piggyback message - PacketType::Value packetType = packet->getType(); + PacketType packetType = packet->getType(); // check version of piggyback packet against expected version if (packet->getVersion() != versionForPacketType(packet->getType())) { - static QMultiMap versionDebugSuppressMap; + static QMultiMap versionDebugSuppressMap; const QUuid& senderUUID = packet->getSourceID(); if (!versionDebugSuppressMap.contains(senderUUID, packetType)) { diff --git a/libraries/audio/src/InboundAudioStream.cpp b/libraries/audio/src/InboundAudioStream.cpp index 8888c9bae5..d3b5600166 100644 --- a/libraries/audio/src/InboundAudioStream.cpp +++ b/libraries/audio/src/InboundAudioStream.cpp @@ -164,7 +164,7 @@ int InboundAudioStream::parseData(NLPacket& packet) { return packet.pos(); } -int InboundAudioStream::parseStreamProperties(PacketType::Value type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) { +int InboundAudioStream::parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) { if (type == PacketType::SilentAudioFrame) { quint16 numSilentSamples = 0; memcpy(&numSilentSamples, packetAfterSeqNum.constData(), sizeof(quint16)); @@ -177,7 +177,7 @@ int InboundAudioStream::parseStreamProperties(PacketType::Value type, const QByt } } -int InboundAudioStream::parseAudioData(PacketType::Value type, const QByteArray& packetAfterStreamProperties, int numAudioSamples) { +int InboundAudioStream::parseAudioData(PacketType type, const QByteArray& packetAfterStreamProperties, int numAudioSamples) { return _ringBuffer.writeData(packetAfterStreamProperties.data(), numAudioSamples * sizeof(int16_t)); } diff --git a/libraries/audio/src/InboundAudioStream.h b/libraries/audio/src/InboundAudioStream.h index a0994e42bd..5dfb75272b 100644 --- a/libraries/audio/src/InboundAudioStream.h +++ b/libraries/audio/src/InboundAudioStream.h @@ -194,11 +194,11 @@ protected: /// parses the info between the seq num and the audio data in the network packet and calculates /// how many audio samples this packet contains (used when filling in samples for dropped packets). /// default implementation assumes no stream properties and raw audio samples after stream propertiess - virtual int parseStreamProperties(PacketType::Value type, const QByteArray& packetAfterSeqNum, int& networkSamples); + virtual int parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& networkSamples); /// parses the audio data in the network packet. /// default implementation assumes packet contains raw audio samples after stream properties - virtual int parseAudioData(PacketType::Value type, const QByteArray& packetAfterStreamProperties, int networkSamples); + virtual int parseAudioData(PacketType type, const QByteArray& packetAfterStreamProperties, int networkSamples); /// writes silent samples to the buffer that may be dropped to reduce latency caused by the buffer virtual int writeDroppableSilentSamples(int silentSamples); diff --git a/libraries/audio/src/InjectedAudioStream.cpp b/libraries/audio/src/InjectedAudioStream.cpp index e7633c49e7..54e0f92bea 100644 --- a/libraries/audio/src/InjectedAudioStream.cpp +++ b/libraries/audio/src/InjectedAudioStream.cpp @@ -30,7 +30,7 @@ InjectedAudioStream::InjectedAudioStream(const QUuid& streamIdentifier, const bo const uchar MAX_INJECTOR_VOLUME = 255; -int InjectedAudioStream::parseStreamProperties(PacketType::Value type, +int InjectedAudioStream::parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) { // setup a data stream to read from this packet diff --git a/libraries/audio/src/InjectedAudioStream.h b/libraries/audio/src/InjectedAudioStream.h index 2460f83f40..60c36dfb12 100644 --- a/libraries/audio/src/InjectedAudioStream.h +++ b/libraries/audio/src/InjectedAudioStream.h @@ -31,7 +31,7 @@ private: InjectedAudioStream& operator= (const InjectedAudioStream&); AudioStreamStats getAudioStreamStats() const; - int parseStreamProperties(PacketType::Value type, const QByteArray& packetAfterSeqNum, int& numAudioSamples); + int parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples); const QUuid _streamIdentifier; float _radius; diff --git a/libraries/audio/src/MixedProcessedAudioStream.cpp b/libraries/audio/src/MixedProcessedAudioStream.cpp index f596c3a8b3..d236ac7aad 100644 --- a/libraries/audio/src/MixedProcessedAudioStream.cpp +++ b/libraries/audio/src/MixedProcessedAudioStream.cpp @@ -42,7 +42,7 @@ int MixedProcessedAudioStream::writeLastFrameRepeatedWithFade(int samples) { return deviceSamplesWritten; } -int MixedProcessedAudioStream::parseAudioData(PacketType::Value type, const QByteArray& packetAfterStreamProperties, int networkSamples) { +int MixedProcessedAudioStream::parseAudioData(PacketType type, const QByteArray& packetAfterStreamProperties, int networkSamples) { emit addedStereoSamples(packetAfterStreamProperties); diff --git a/libraries/audio/src/MixedProcessedAudioStream.h b/libraries/audio/src/MixedProcessedAudioStream.h index 265095597b..5ea0157421 100644 --- a/libraries/audio/src/MixedProcessedAudioStream.h +++ b/libraries/audio/src/MixedProcessedAudioStream.h @@ -35,7 +35,7 @@ public: protected: int writeDroppableSilentSamples(int silentSamples); int writeLastFrameRepeatedWithFade(int samples); - int parseAudioData(PacketType::Value type, const QByteArray& packetAfterStreamProperties, int networkSamples); + int parseAudioData(PacketType type, const QByteArray& packetAfterStreamProperties, int networkSamples); private: int networkToDeviceSamples(int networkSamples); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 39f088f06d..051776d380 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -43,8 +43,8 @@ public: virtual ~EntityTreeRenderer(); virtual char getMyNodeType() const { return NodeType::EntityServer; } - virtual PacketType::Value getMyQueryMessageType() const { return PacketType::EntityQuery; } - virtual PacketType::Value getExpectedPacketType() const { return PacketType::EntityData; } + virtual PacketType getMyQueryMessageType() const { return PacketType::EntityQuery; } + virtual PacketType getExpectedPacketType() const { return PacketType::EntityData; } virtual void renderElement(OctreeElement* element, RenderArgs* args); virtual float getSizeScale() const; virtual int getBoundaryLevelAdjust() const; diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index 5905f7924c..48809287a3 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -28,13 +28,13 @@ void EntityEditPacketSender::processEntityEditNackPacket(QSharedPointer packet, SharedNodePointer sendingNode); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 61253ba6ba..d71a69ae7d 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -618,7 +618,7 @@ void EntityItemPropertiesFromScriptValueHonorReadOnly(const QScriptValue &object // // TODO: Implement support for script and visible properties. // -bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, EntityItemID id, const EntityItemProperties& properties, +bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItemID id, const EntityItemProperties& properties, QByteArray& buffer) { OctreePacketData ourDataPacket(false, buffer.size()); // create a packetData object to add out packet details too. OctreePacketData* packetData = &ourDataPacket; // we want a pointer to this so we can use our APPEND_ENTITY_PROPERTY macro diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 4532ffd67b..4cfcf9a0ab 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -174,7 +174,7 @@ public: void setGlowLevel(float value) { _glowLevel = value; _glowLevelChanged = true; } void setLocalRenderAlpha(float value) { _localRenderAlpha = value; _localRenderAlphaChanged = true; } - static bool encodeEntityEditPacket(PacketType::Value command, EntityItemID id, const EntityItemProperties& properties, + static bool encodeEntityEditPacket(PacketType command, EntityItemID id, const EntityItemProperties& properties, QByteArray& buffer); static bool encodeEraseEntityMessage(const EntityItemID& entityItemID, QByteArray& buffer); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 36fcc17a71..7db55f9c84 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -32,7 +32,7 @@ EntityScriptingInterface::EntityScriptingInterface() : connect(nodeList.data(), &NodeList::canRezChanged, this, &EntityScriptingInterface::canRezChanged); } -void EntityScriptingInterface::queueEntityMessage(PacketType::Value packetType, +void EntityScriptingInterface::queueEntityMessage(PacketType packetType, EntityItemID entityID, const EntityItemProperties& properties) { getEntityPacketSender()->queueEditEntityMessage(packetType, entityID, properties); } diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index c232437757..5c1e4141a6 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -164,7 +164,7 @@ private: bool actionWorker(const QUuid& entityID, std::function actor); bool setVoxels(QUuid entityID, std::function actor); bool setPoints(QUuid entityID, std::function actor); - void queueEntityMessage(PacketType::Value packetType, EntityItemID entityID, const EntityItemProperties& properties); + void queueEntityMessage(PacketType packetType, EntityItemID entityID, const EntityItemProperties& properties); /// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index ba2691aa3b..d72e075bf2 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -63,7 +63,7 @@ void EntityTree::eraseAllOctreeElements(bool createNewRoot) { resetClientEditStats(); } -bool EntityTree::handlesEditPacketType(PacketType::Value packetType) const { +bool EntityTree::handlesEditPacketType(PacketType packetType) const { // we handle these types of "edit" packets switch (packetType) { case PacketType::EntityAdd: diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 4ade0afc6d..e82e715d69 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -62,10 +62,10 @@ public: // These methods will allow the OctreeServer to send your tree inbound edit packets of your // own definition. Implement these to allow your octree based server to support editing virtual bool getWantSVOfileVersions() const { return true; } - virtual PacketType::Value expectedDataPacketType() const { return PacketType::EntityData; } + virtual PacketType expectedDataPacketType() const { return PacketType::EntityData; } virtual bool canProcessVersion(PacketVersion thisVersion) const { return thisVersion >= VERSION_ENTITIES_USE_METERS_AND_RADIANS; } - virtual bool handlesEditPacketType(PacketType::Value packetType) const; + virtual bool handlesEditPacketType(PacketType packetType) const; virtual int processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode); diff --git a/libraries/entities/src/EntityTreeHeadlessViewer.h b/libraries/entities/src/EntityTreeHeadlessViewer.h index a14fe14a71..2f6483ae19 100644 --- a/libraries/entities/src/EntityTreeHeadlessViewer.h +++ b/libraries/entities/src/EntityTreeHeadlessViewer.h @@ -31,8 +31,8 @@ public: virtual ~EntityTreeHeadlessViewer(); virtual char getMyNodeType() const { return NodeType::EntityServer; } - virtual PacketType::Value getMyQueryMessageType() const { return PacketType::EntityQuery; } - virtual PacketType::Value getExpectedPacketType() const { return PacketType::EntityData; } + virtual PacketType getMyQueryMessageType() const { return PacketType::EntityQuery; } + virtual PacketType getExpectedPacketType() const { return PacketType::EntityData; } void update(); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 2760ed8277..acac81f8ff 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -157,40 +157,42 @@ bool LimitedNodeList::isPacketVerified(const udt::Packet& packet) { } bool LimitedNodeList::packetVersionMatch(const udt::Packet& packet) { + PacketType headerType = NLPacket::typeInHeader(packet); + PacketVersion headerVersion = NLPacket::versionInHeader(packet); - if (packet.getVersion() != versionForPacketType(packet.getType())) { + if (headerVersion != versionForPacketType(headerType)) { - static QMultiHash sourcedVersionDebugSuppressMap; - static QMultiHash versionDebugSuppressMap; + static QMultiHash sourcedVersionDebugSuppressMap; + static QMultiHash versionDebugSuppressMap; bool hasBeenOutput = false; QString senderString; - if (NON_SOURCED_PACKETS.contains(packet.getType())) { + if (NON_SOURCED_PACKETS.contains(headerType)) { const HifiSockAddr& senderSockAddr = packet.getSenderSockAddr(); - hasBeenOutput = versionDebugSuppressMap.contains(senderSockAddr, packet.getType()); + hasBeenOutput = versionDebugSuppressMap.contains(senderSockAddr, headerType); if (!hasBeenOutput) { - versionDebugSuppressMap.insert(senderSockAddr, packet.getType()); + versionDebugSuppressMap.insert(senderSockAddr, headerType); senderString = QString("%1:%2").arg(senderSockAddr.getAddress().toString()).arg(senderSockAddr.getPort()); } } else { - QUuid sourceID = QUuid::fromRfc4122(QByteArray::fromRawData(packet.getPayload(), NUM_BYTES_RFC4122_UUID)); + QUuid sourceID = NLPacket::sourceIDInHeader(packet); - hasBeenOutput = sourcedVersionDebugSuppressMap.contains(sourceID, packet.getType()); + hasBeenOutput = sourcedVersionDebugSuppressMap.contains(sourceID, headerType); if (!hasBeenOutput) { - sourcedVersionDebugSuppressMap.insert(sourceID, packet.getType()); + sourcedVersionDebugSuppressMap.insert(sourceID, headerType); senderString = uuidStringWithoutCurlyBraces(sourceID.toString()); } } if (!hasBeenOutput) { - qCDebug(networking) << "Packet version mismatch on" << packet.getType() << "- Sender" - << senderString << "sent" << qPrintable(QString::number(packet.getVersion())) << "but" - << qPrintable(QString::number(versionForPacketType(packet.getType()))) << "expected."; + qCDebug(networking) << "Packet version mismatch on" << headerType << "- Sender" + << senderString << "sent" << qPrintable(QString::number(headerVersion)) << "but" + << qPrintable(QString::number(versionForPacketType(headerType))) << "expected."; - emit packetVersionMismatch(packet.getType()); + emit packetVersionMismatch(headerType); } return false; @@ -201,7 +203,9 @@ bool LimitedNodeList::packetVersionMatch(const udt::Packet& packet) { bool LimitedNodeList::packetSourceAndHashMatch(const udt::Packet& packet) { - if (NON_SOURCED_PACKETS.contains(packet.getType())) { + PacketType headerType = NLPacket::typeInHeader(packet); + + if (NON_SOURCED_PACKETS.contains(headerType)) { return true; } else { QUuid sourceID = NLPacket::sourceIDInHeader(packet); @@ -210,19 +214,19 @@ bool LimitedNodeList::packetSourceAndHashMatch(const udt::Packet& packet) { SharedNodePointer matchingNode = nodeWithUUID(sourceID); if (matchingNode) { - if (!NON_VERIFIED_PACKETS.contains(packet.getType())) { + if (!NON_VERIFIED_PACKETS.contains(headerType)) { QByteArray packetHeaderHash = NLPacket::verificationHashInHeader(packet); QByteArray expectedHash = NLPacket::hashForPacketAndSecret(packet, matchingNode->getConnectionSecret()); // check if the md5 hash in the header matches the hash we would expect if (packetHeaderHash != expectedHash) { - static QMultiMap hashDebugSuppressMap; + static QMultiMap hashDebugSuppressMap; - if (!hashDebugSuppressMap.contains(sourceID, packet.getType())) { - qCDebug(networking) << "Packet hash mismatch on" << packet.getType() << "- Sender" << sourceID; + if (!hashDebugSuppressMap.contains(sourceID, headerType)) { + qCDebug(networking) << "Packet hash mismatch on" << headerType << "- Sender" << sourceID; - hashDebugSuppressMap.insert(sourceID, packet.getType()); + hashDebugSuppressMap.insert(sourceID, headerType); } return false; @@ -235,7 +239,7 @@ bool LimitedNodeList::packetSourceAndHashMatch(const udt::Packet& packet) { static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("Packet of type \\d+ \\([\\sa-zA-Z]+\\) received from unknown node with UUID"); - qCDebug(networking) << "Packet of type" << packet.getType() << "(" << qPrintable(nameForPacketType(packet.getType())) << ")" + qCDebug(networking) << "Packet of type" << headerType << "(" << qPrintable(nameForPacketType(headerType)) << ")" << "received from unknown node with UUID" << qPrintable(uuidStringWithoutCurlyBraces(sourceID)); } } @@ -786,7 +790,7 @@ void LimitedNodeList::sendPeerQueryToIceServer(const HifiSockAddr& iceServerSock sendPacketToIceServer(PacketType::ICEServerQuery, iceServerSockAddr, clientID, peerID); } -void LimitedNodeList::sendPacketToIceServer(PacketType::Value packetType, const HifiSockAddr& iceServerSockAddr, +void LimitedNodeList::sendPacketToIceServer(PacketType packetType, const HifiSockAddr& iceServerSockAddr, const QUuid& clientID, const QUuid& peerID) { auto icePacket = NLPacket::create(packetType); diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index ead858a239..4047668350 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -231,7 +231,7 @@ public slots: signals: void dataSent(quint8 channelType, int bytes); - void packetVersionMismatch(PacketType::Value type); + void packetVersionMismatch(PacketType type); void uuidChanged(const QUuid& ownerUUID, const QUuid& oldUUID); void nodeAdded(SharedNodePointer); @@ -261,7 +261,7 @@ protected: void stopInitialSTUNUpdate(bool success); - void sendPacketToIceServer(PacketType::Value packetType, const HifiSockAddr& iceServerSockAddr, const QUuid& clientID, + void sendPacketToIceServer(PacketType packetType, const HifiSockAddr& iceServerSockAddr, const QUuid& clientID, const QUuid& peerRequestID = QUuid()); qint64 sendPacket(std::unique_ptr packet, const Node& destinationNode, diff --git a/libraries/networking/src/NLPacket.cpp b/libraries/networking/src/NLPacket.cpp index 39dc296f85..7d2726d9c0 100644 --- a/libraries/networking/src/NLPacket.cpp +++ b/libraries/networking/src/NLPacket.cpp @@ -11,14 +11,18 @@ #include "NLPacket.h" -qint64 NLPacket::localHeaderSize(PacketType::Value type) { +qint64 NLPacket::maxPayloadSize(PacketType type) { + return Packet::maxPayloadSize(false) - localHeaderSize(type); +} + +qint64 NLPacket::localHeaderSize(PacketType type) { qint64 size = ((NON_SOURCED_PACKETS.contains(type)) ? 0 : NUM_BYTES_RFC4122_UUID) + - ((NON_SOURCED_PACKETS.contains(type) || NON_VERIFIED_PACKETS.contains(type)) ? 0 : NUM_BYTES_MD5_HASH); + ((NON_SOURCED_PACKETS.contains(type) || NON_VERIFIED_PACKETS.contains(type)) ? 0 : NUM_BYTES_MD5_HASH); return size; } -qint64 NLPacket::maxPayloadSize(PacketType::Value type) { - return Packet::maxPayloadSize(type) - localHeaderSize(type); +qint64 NLPacket::maxPayloadSize() const { + return Packet::maxPayloadSize() - localHeaderSize(); } qint64 NLPacket::totalHeadersSize() const { @@ -29,7 +33,7 @@ qint64 NLPacket::localHeaderSize() const { return localHeaderSize(_type); } -std::unique_ptr NLPacket::create(PacketType::Value type, qint64 size) { +std::unique_ptr NLPacket::create(PacketType type, qint64 size) { std::unique_ptr packet; if (size == -1) { @@ -75,17 +79,21 @@ std::unique_ptr NLPacket::createCopy(const NLPacket& other) { return std::unique_ptr(new NLPacket(other)); } -NLPacket::NLPacket(PacketType::Value type, qint64 size) : - Packet(type, localHeaderSize(type) + size) +NLPacket::NLPacket(PacketType type, bool isReliable, bool isPartOfMessage) : + Packet(-1, isReliable, isPartOfMessage), + _type(type), + _version(versionForPacketType(type)) { - Q_ASSERT(size >= 0); - adjustPayloadStartAndCapacity(); } -NLPacket::NLPacket(PacketType::Value type) : - Packet(type, -1) +NLPacket::NLPacket(PacketType type, qint64 size, bool isReliable, bool isPartOfMessage) : + Packet(localHeaderSize(type) + size, isReliable, isPartOfMessage), + _type(type), + _version(versionForPacketType(type)) { + Q_ASSERT(size >= 0); + adjustPayloadStartAndCapacity(); } @@ -103,12 +111,14 @@ NLPacket::NLPacket(const NLPacket& other) : Packet(other) { NLPacket::NLPacket(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr) : Packet(std::move(data), size, senderSockAddr) -{ +{ // sanity check before we decrease the payloadSize with the payloadCapacity Q_ASSERT(_payloadSize == _payloadCapacity); adjustPayloadStartAndCapacity(_payloadSize > 0); - + + readType(); + readVersion(); readSourceID(); } @@ -135,20 +145,29 @@ NLPacket& NLPacket::operator=(NLPacket&& other) { return *this; } +PacketType NLPacket::typeInHeader(const udt::Packet& packet) { + return *reinterpret_cast(packet.getData()); +} + +PacketVersion NLPacket::versionInHeader(const udt::Packet& packet) { + return *reinterpret_cast(packet.getData() + sizeof(PacketType)); +} + QUuid NLPacket::sourceIDInHeader(const udt::Packet& packet) { - int offset = packet.Packet::localHeaderSize(); + int offset = packet.Packet::localHeaderSize() + sizeof(PacketType) + sizeof(PacketVersion); return QUuid::fromRfc4122(QByteArray::fromRawData(packet.getData() + offset, NUM_BYTES_RFC4122_UUID)); } QByteArray NLPacket::verificationHashInHeader(const udt::Packet& packet) { - int offset = packet.Packet::localHeaderSize() + NUM_BYTES_RFC4122_UUID; + int offset = packet.Packet::localHeaderSize() + sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID; return QByteArray(packet.getData() + offset, NUM_BYTES_MD5_HASH); } QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret) { QCryptographicHash hash(QCryptographicHash::Md5); - int offset = packet.Packet::localHeaderSize() + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH; + int offset = packet.Packet::localHeaderSize() + sizeof(PacketType) + sizeof(PacketVersion) + + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH; // add the packet payload and the connection UUID hash.addData(packet.getData() + offset, packet.getDataSize() - offset); @@ -158,6 +177,36 @@ QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, const QUu return hash.result(); } +void NLPacket::writePacketTypeAndVersion() { + // Pack the packet type + memcpy(_packet.get(), &_type, sizeof(PacketType)); + + // Pack the packet version + auto version = versionForPacketType(_type); + memcpy(_packet.get() + sizeof(PacketType), &version, sizeof(version)); +} + +void NLPacket::setType(PacketType type) { + auto currentHeaderSize = totalHeadersSize(); + + _type = type; + _version = versionForPacketType(_type); + + writePacketTypeAndVersion(); + + // Setting new packet type with a different header size not currently supported + Q_ASSERT(currentHeaderSize == totalHeadersSize()); + Q_UNUSED(currentHeaderSize); +} + +void NLPacket::readType() { + _type = NLPacket::typeInHeader(*this); +} + +void NLPacket::readVersion() { + _version = NLPacket::versionInHeader(*this); +} + void NLPacket::adjustPayloadStartAndCapacity(bool shouldDecreasePayloadSize) { qint64 headerSize = localHeaderSize(_type); _payloadStart += headerSize; diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index 57c099764a..3045af3f09 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -19,7 +19,7 @@ class NLPacket : public udt::Packet { Q_OBJECT public: - static std::unique_ptr create(PacketType::Value type, qint64 size = -1); + static std::unique_ptr create(PacketType type, qint64 size = -1); static std::unique_ptr fromReceivedPacket(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr); static std::unique_ptr fromBase(std::unique_ptr packet); @@ -27,15 +27,24 @@ public: // Provided for convenience, try to limit use static std::unique_ptr createCopy(const NLPacket& other); + static PacketType typeInHeader(const udt::Packet& packet); + static PacketVersion versionInHeader(const udt::Packet& packet); + static QUuid sourceIDInHeader(const udt::Packet& packet); static QByteArray verificationHashInHeader(const udt::Packet& packet); static QByteArray hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret); - - static qint64 localHeaderSize(PacketType::Value type); - static qint64 maxPayloadSize(PacketType::Value type); - + + static qint64 maxPayloadSize(PacketType type); + static qint64 localHeaderSize(PacketType type); + + virtual qint64 maxPayloadSize() const; // The maximum payload size this packet can use to fit in MTU virtual qint64 totalHeadersSize() const; // Cumulated size of all the headers virtual qint64 localHeaderSize() const; // Current level's header size + + PacketType getType() const { return _type; } + void setType(PacketType type); + + PacketVersion getVersion() const { return _version; } const QUuid& getSourceID() const { return _sourceID; } @@ -44,10 +53,8 @@ public: protected: - void adjustPayloadStartAndCapacity(bool shouldDecreasePayloadSize = false); - - NLPacket(PacketType::Value type); - NLPacket(PacketType::Value type, qint64 size); + NLPacket(PacketType type, bool forceReliable = false, bool isPartOfMessage = false); + NLPacket(PacketType type, qint64 size, bool forceReliable = false, bool isPartOfMessage = false); NLPacket(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr); NLPacket(std::unique_ptr packet); NLPacket(const NLPacket& other); @@ -55,9 +62,19 @@ protected: NLPacket& operator=(const NLPacket& other); NLPacket& operator=(NLPacket&& other); + + void adjustPayloadStartAndCapacity(bool shouldDecreasePayloadSize = false); + + // Header writers + void writePacketTypeAndVersion(); + // Header readers, used to set member variables after getting a packet from the network + void readType(); + void readVersion(); void readSourceID(); - + + PacketType _type; + PacketVersion _version; QUuid _sourceID; }; diff --git a/libraries/networking/src/NLPacketList.cpp b/libraries/networking/src/NLPacketList.cpp index 6b7b53e8e9..df36228e7a 100644 --- a/libraries/networking/src/NLPacketList.cpp +++ b/libraries/networking/src/NLPacketList.cpp @@ -13,7 +13,7 @@ #include "NLPacket.h" -NLPacketList::NLPacketList(PacketType::Value packetType, QByteArray extendedHeader) : +NLPacketList::NLPacketList(PacketType packetType, QByteArray extendedHeader) : PacketList(packetType, extendedHeader) { diff --git a/libraries/networking/src/NLPacketList.h b/libraries/networking/src/NLPacketList.h index 33a8316f95..512ec23d22 100644 --- a/libraries/networking/src/NLPacketList.h +++ b/libraries/networking/src/NLPacketList.h @@ -16,7 +16,7 @@ class NLPacketList : public udt::PacketList { public: - NLPacketList(PacketType::Value packetType, QByteArray extendedHeader = QByteArray()); + NLPacketList(PacketType packetType, QByteArray extendedHeader = QByteArray()); private: NLPacketList(const NLPacketList& other) = delete; diff --git a/libraries/networking/src/Node.h b/libraries/networking/src/Node.h index c8106f5fd8..8cd524e539 100644 --- a/libraries/networking/src/Node.h +++ b/libraries/networking/src/Node.h @@ -85,7 +85,7 @@ private: bool _canAdjustLocks; bool _canRez; - std::map _lastSequenceNumbers; + std::map _lastSequenceNumbers; }; typedef QSharedPointer SharedNodePointer; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index dfa3ef86a5..1660312e5d 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -231,7 +231,7 @@ void NodeList::sendDomainServerCheckIn() { } else if (!_domainHandler.getIP().isNull()) { bool isUsingDTLS = false; - PacketType::Value domainPacketType = !_domainHandler.isConnected() + PacketType domainPacketType = !_domainHandler.isConnected() ? PacketType::DomainConnectRequest : PacketType::DomainListRequest; if (!_domainHandler.isConnected()) { @@ -525,7 +525,7 @@ void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) { void NodeList::sendAssignment(Assignment& assignment) { - PacketType::Value assignmentPacketType = assignment.getCommand() == Assignment::CreateCommand + PacketType assignmentPacketType = assignment.getCommand() == Assignment::CreateCommand ? PacketType::CreateAssignment : PacketType::RequestAssignment; diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 6fb34f05e7..1389f271bf 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -24,11 +24,11 @@ PacketReceiver::PacketReceiver(QObject* parent) : qRegisterMetaType>(); } -bool PacketReceiver::registerListenerForTypes(const QSet& types, QObject* listener, const char* slot) { - QSet nonSourcedTypes; - QSet sourcedTypes; +bool PacketReceiver::registerListenerForTypes(const QSet& types, QObject* listener, const char* slot) { + QSet nonSourcedTypes; + QSet sourcedTypes; - foreach(PacketType::Value type, types) { + foreach(PacketType type, types) { if (NON_SOURCED_PACKETS.contains(type)) { nonSourcedTypes << type; } else { @@ -41,7 +41,7 @@ bool PacketReceiver::registerListenerForTypes(const QSet& typ if (nonSourcedTypes.size() > 0) { QMetaMethod nonSourcedMethod = matchingMethodForListener(*nonSourcedTypes.begin(), listener, slot); if (nonSourcedMethod.isValid()) { - foreach(PacketType::Value type, nonSourcedTypes) { + foreach(PacketType type, nonSourcedTypes) { registerVerifiedListener(type, listener, nonSourcedMethod); } } else { @@ -52,7 +52,7 @@ bool PacketReceiver::registerListenerForTypes(const QSet& typ if (sourcedTypes.size() > 0) { QMetaMethod sourcedMethod = matchingMethodForListener(*sourcedTypes.begin(), listener, slot); if (sourcedMethod.isValid()) { - foreach(PacketType::Value type, sourcedTypes) { + foreach(PacketType type, sourcedTypes) { registerVerifiedListener(type, listener, sourcedMethod); } } else { @@ -63,7 +63,7 @@ bool PacketReceiver::registerListenerForTypes(const QSet& typ return true; } -void PacketReceiver::registerDirectListener(PacketType::Value type, QObject* listener, const char* slot) { +void PacketReceiver::registerDirectListener(PacketType type, QObject* listener, const char* slot) { bool success = registerListener(type, listener, slot); if (success) { _directConnectSetMutex.lock(); @@ -75,7 +75,7 @@ void PacketReceiver::registerDirectListener(PacketType::Value type, QObject* lis } } -void PacketReceiver::registerDirectListenerForTypes(const QSet& types, +void PacketReceiver::registerDirectListenerForTypes(const QSet& types, QObject* listener, const char* slot) { // just call register listener for types to start bool success = registerListenerForTypes(types, listener, slot); @@ -89,7 +89,7 @@ void PacketReceiver::registerDirectListenerForTypes(const QSet packet) { _directConnectSetMutex.unlock(); - PacketType::Value packetType = nlPacket->getType(); + PacketType packetType = nlPacket->getType(); if (matchingNode) { emit dataReceived(matchingNode->getType(), nlPacket->getDataSize()); @@ -311,7 +311,7 @@ void PacketReceiver::handleVerifiedPacket(std::unique_ptr packet) { qWarning() << "No listener found for packet type " << nameForPacketType(nlPacket->getType()); // insert a dummy listener so we don't print this again - _packetListenerMap.insert(packet->getType(), { nullptr, QMetaMethod() }); + _packetListenerMap.insert(nlPacket->getType(), { nullptr, QMetaMethod() }); } _packetListenerLock.unlock(); diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index 25bf9656be..531a8e60be 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -41,8 +41,8 @@ public: void resetCounters() { _inPacketCount = 0; _inByteCount = 0; } - bool registerListenerForTypes(const QSet& types, QObject* listener, const char* slot); - bool registerListener(PacketType::Value type, QObject* listener, const char* slot); + bool registerListenerForTypes(const QSet& types, QObject* listener, const char* slot); + bool registerListener(PacketType type, QObject* listener, const char* slot); void unregisterListener(QObject* listener); void handleVerifiedPacket(std::unique_ptr packet); @@ -53,16 +53,16 @@ signals: private: // these are brutal hacks for now - ideally GenericThread / ReceivedPacketProcessor // should be changed to have a true event loop and be able to handle our QMetaMethod::invoke - void registerDirectListenerForTypes(const QSet& types, QObject* listener, const char* slot); - void registerDirectListener(PacketType::Value type, QObject* listener, const char* slot); + void registerDirectListenerForTypes(const QSet& types, QObject* listener, const char* slot); + void registerDirectListener(PacketType type, QObject* listener, const char* slot); - QMetaMethod matchingMethodForListener(PacketType::Value type, QObject* object, const char* slot) const; - void registerVerifiedListener(PacketType::Value type, QObject* listener, const QMetaMethod& slot); + QMetaMethod matchingMethodForListener(PacketType type, QObject* object, const char* slot) const; + void registerVerifiedListener(PacketType type, QObject* listener, const QMetaMethod& slot); using ObjectMethodPair = std::pair, QMetaMethod>; QMutex _packetListenerLock; - QHash _packetListenerMap; + QHash _packetListenerMap; int _inPacketCount = 0; int _inByteCount = 0; bool _shouldDropPackets = false; diff --git a/libraries/networking/src/udt/Packet.cpp b/libraries/networking/src/udt/Packet.cpp index 154d526833..439b185661 100644 --- a/libraries/networking/src/udt/Packet.cpp +++ b/libraries/networking/src/udt/Packet.cpp @@ -15,18 +15,8 @@ using namespace udt; const qint64 Packet::PACKET_WRITE_ERROR = -1; -qint64 Packet::localHeaderSize(PacketType::Value type) { - // TODO: check the bitfield to see if the message is included - qint64 size = sizeof(SequenceNumberAndBitField); - return size; -} - -qint64 Packet::maxPayloadSize(PacketType::Value type) { - return MAX_PACKET_SIZE - localHeaderSize(type); -} - -std::unique_ptr Packet::create(PacketType::Value type, qint64 size) { - auto packet = std::unique_ptr(new Packet(type, size)); +std::unique_ptr Packet::create(qint64 size, bool isReliable, bool isPartOfMessage) { + auto packet = std::unique_ptr(new Packet(size, isReliable, isPartOfMessage)); packet->open(QIODevice::ReadWrite); @@ -49,25 +39,38 @@ std::unique_ptr Packet::createCopy(const Packet& other) { return std::unique_ptr(new Packet(other)); } +qint64 Packet::maxPayloadSize(bool isPartOfMessage) { + return MAX_PACKET_SIZE - localHeaderSize(isPartOfMessage); +} + +qint64 Packet::localHeaderSize(bool isPartOfMessage) { + return sizeof(SequenceNumberAndBitField) + (isPartOfMessage ? sizeof(MessageNumberAndBitField) : 0); +} + +qint64 Packet::maxPayloadSize() const { + return MAX_PACKET_SIZE - localHeaderSize(); +} + qint64 Packet::totalHeadersSize() const { return localHeaderSize(); } qint64 Packet::localHeaderSize() const { - return localHeaderSize(_type); + return localHeaderSize(_isPartOfMessage); } -Packet::Packet(PacketType::Value type, qint64 size) : - _type(type), - _version(0) +Packet::Packet(qint64 size, bool isReliable, bool isPartOfMessage) : + _isReliable(isReliable), + _isPartOfMessage(isPartOfMessage) { - auto maxPayload = maxPayloadSize(type); + auto maxPayload = maxPayloadSize(); + if (size == -1) { // default size of -1, means biggest packet possible size = maxPayload; } - _packetSize = localHeaderSize(type) + size; + _packetSize = localHeaderSize() + size; _packet.reset(new char[_packetSize]); _payloadCapacity = size; _payloadStart = _packet.get() + (_packetSize - _payloadCapacity); @@ -84,9 +87,11 @@ Packet::Packet(std::unique_ptr data, qint64 size, const HifiSockAddr& send _packet(std::move(data)), _senderSockAddr(senderSockAddr) { - _type = readType(); - _version = readVersion(); - _payloadCapacity = _packetSize - localHeaderSize(_type); + readIsReliable(); + readIsPartOfMessage(); + readSequenceNumber(); + + _payloadCapacity = _packetSize - localHeaderSize(); _payloadSize = _payloadCapacity; _payloadStart = _packet.get() + (_packetSize - _payloadCapacity); } @@ -98,9 +103,6 @@ Packet::Packet(const Packet& other) : } Packet& Packet::operator=(const Packet& other) { - _type = other._type; - _version = other._version; - _packetSize = other._packetSize; _packet = std::unique_ptr(new char[_packetSize]); memcpy(_packet.get(), other._packet.get(), _packetSize); @@ -124,9 +126,6 @@ Packet::Packet(Packet&& other) { } Packet& Packet::operator=(Packet&& other) { - _type = other._type; - _version = other._version; - _packetSize = other._packetSize; _packet = std::move(other._packet); @@ -164,55 +163,38 @@ bool Packet::reset() { return QIODevice::reset(); } -void Packet::setType(PacketType::Value type) { - auto currentHeaderSize = totalHeadersSize(); - _type = type; - writePacketTypeAndVersion(_type); - - // Setting new packet type with a different header size not currently supported - Q_ASSERT(currentHeaderSize == totalHeadersSize()); - Q_UNUSED(currentHeaderSize); -} - -PacketType::Value Packet::readType() const { - return (PacketType::Value)arithmeticCodingValueFromBuffer(_packet.get()); -} - -PacketVersion Packet::readVersion() const { - return *reinterpret_cast(_packet.get() + numBytesForArithmeticCodedPacketType(_type)); -} - static const uint32_t CONTROL_BIT_MASK = 1 << (sizeof(Packet::SequenceNumberAndBitField) - 1); static const uint32_t RELIABILITY_BIT_MASK = 1 << (sizeof(Packet::SequenceNumberAndBitField) - 2); static const uint32_t MESSAGE_BIT_MASK = 1 << (sizeof(Packet::SequenceNumberAndBitField) - 3); +static const int BIT_FIELD_LENGTH = 3; static const uint32_t BIT_FIELD_MASK = CONTROL_BIT_MASK | RELIABILITY_BIT_MASK | MESSAGE_BIT_MASK; - -Packet::SequenceNumber Packet::readSequenceNumber() const { +void Packet::readIsReliable() { SequenceNumberAndBitField seqNumBitField = *reinterpret_cast(_packet.get()); - return seqNumBitField & ~BIT_FIELD_MASK; // Remove the bit field + _isReliable = (bool) (seqNumBitField & RELIABILITY_BIT_MASK); // Only keep reliability bit } -bool Packet::readIsControlPacket() const { +void Packet::readIsPartOfMessage() { SequenceNumberAndBitField seqNumBitField = *reinterpret_cast(_packet.get()); - return seqNumBitField & CONTROL_BIT_MASK; // Only keep control bit + _isReliable = (bool) (seqNumBitField & MESSAGE_BIT_MASK); // Only keep message bit } -void Packet::writePacketTypeAndVersion(PacketType::Value type) { - // Pack the packet type - auto offset = packArithmeticallyCodedValue(type, _packet.get()); - - // Pack the packet version - auto version = versionForPacketType(type); - memcpy(_packet.get() + offset, &version, sizeof(version)); +void Packet::readSequenceNumber() { + SequenceNumberAndBitField seqNumBitField = *reinterpret_cast(_packet.get()); + _sequenceNumber = (seqNumBitField & ~BIT_FIELD_MASK); // Remove the bit field } -void Packet::writeSequenceNumber(SequenceNumber seqNum) { - // Here we are overriding the control bit to 0. - // But that is not an issue since we should only ever set the seqNum - // for data packets going out - memcpy(_packet.get() + numBytesForArithmeticCodedPacketType(_type) + sizeof(PacketVersion), - &seqNum, sizeof(seqNum)); +static const uint32_t MAX_SEQUENCE_NUMBER = UINT32_MAX >> BIT_FIELD_LENGTH; + +void Packet::writeSequenceNumber(SequenceNumber sequenceNumber) { + // make sure this is a sequence number <= 29 bit unsigned max (536,870,911) + Q_ASSERT(sequenceNumber <= MAX_SEQUENCE_NUMBER); + + // grab pointer to current SequenceNumberAndBitField + SequenceNumberAndBitField* seqNumBitField = reinterpret_cast(_packet.get()); + + // write new value by ORing (old value & BIT_FIELD_MASK) with new seqNum + *seqNumBitField = (*seqNumBitField & BIT_FIELD_MASK) | sequenceNumber; } QByteArray Packet::read(qint64 maxSize) { diff --git a/libraries/networking/src/udt/Packet.h b/libraries/networking/src/udt/Packet.h index b74834c82a..1bd9ee9619 100644 --- a/libraries/networking/src/udt/Packet.h +++ b/libraries/networking/src/udt/Packet.h @@ -24,25 +24,33 @@ namespace udt { class Packet : public QIODevice { Q_OBJECT public: - // NOTE: The SequenceNumber must actually only be 29 bits MAX to leave room for a bit field + // NOTE: The SequenceNumber is only actually 29 bits to leave room for a bit field using SequenceNumber = uint32_t; using SequenceNumberAndBitField = uint32_t; + // NOTE: The MessageNumber is only actually 29 bits to leave room for a bit field + using MessageNumber = uint32_t; + using MessageNumberAndBitField = uint32_t; + static const uint32_t DEFAULT_SEQUENCE_NUMBER = 0; static const qint64 PACKET_WRITE_ERROR; - static std::unique_ptr create(PacketType::Value type, qint64 size = -1); + static std::unique_ptr create(qint64 size = -1, bool isReliable = false, bool isPartOfMessage = false); static std::unique_ptr fromReceivedPacket(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr); // Provided for convenience, try to limit use static std::unique_ptr createCopy(const Packet& other); - - static qint64 localHeaderSize(PacketType::Value type); - static qint64 maxPayloadSize(PacketType::Value type); - + + // The maximum payload size this packet can use to fit in MTU + static qint64 maxPayloadSize(bool isPartOfMessage); + virtual qint64 maxPayloadSize() const; + + // Current level's header size + static qint64 localHeaderSize(bool isPartOfMessage); + virtual qint64 localHeaderSize() const; + virtual qint64 totalHeadersSize() const; // Cumulated size of all the headers - virtual qint64 localHeaderSize() const; // Current level's header size // Payload direct access to the payload, use responsibly! char* getPayload() { return _payloadStart; } @@ -51,11 +59,6 @@ public: // Return direct access to the entire packet, use responsibly! char* getData() { return _packet.get(); } const char* getData() const { return _packet.get(); } - - PacketType::Value getType() const { return _type; } - void setType(PacketType::Value type); - - PacketVersion getVersion() const { return _version; } // Returns the size of the packet, including the header qint64 getDataSize() const { return totalHeadersSize() + _payloadSize; } @@ -75,9 +78,7 @@ public: HifiSockAddr& getSenderSockAddr() { return _senderSockAddr; } const HifiSockAddr& getSenderSockAddr() const { return _senderSockAddr; } - void writeSequenceNumber(SequenceNumber seqNum); - SequenceNumber readSequenceNumber() const; - bool readIsControlPacket() const; + void writeSequenceNumber(SequenceNumber sequenceNumber); // QIODevice virtual functions // WARNING: Those methods all refer to the payload ONLY and NOT the entire packet @@ -93,26 +94,21 @@ public: template qint64 writePrimitive(const T& data); protected: - Packet(PacketType::Value type, qint64 size); + Packet(qint64 size, bool isReliable = false, bool isPartOfMessage = false); Packet(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr); Packet(const Packet& other); Packet& operator=(const Packet& other); Packet(Packet&& other); Packet& operator=(Packet&& other); - // Header readers - PacketType::Value readType() const; - PacketVersion readVersion() const; - // QIODevice virtual functions virtual qint64 writeData(const char* data, qint64 maxSize); virtual qint64 readData(char* data, qint64 maxSize); - - // Header writers - void writePacketTypeAndVersion(PacketType::Value type); - - PacketType::Value _type; // Packet type - PacketVersion _version; // Packet version + + // Header readers - these read data to member variables after pulling packet off wire + void readIsPartOfMessage(); + void readIsReliable(); + void readSequenceNumber(); qint64 _packetSize = 0; // Total size of the allocated memory std::unique_ptr _packet; // Allocated memory @@ -121,6 +117,10 @@ protected: qint64 _payloadCapacity = 0; // Total capacity of the payload qint64 _payloadSize = 0; // How much of the payload is actually used + + bool _isReliable { false }; + bool _isPartOfMessage { false }; + SequenceNumber _sequenceNumber { 0 }; HifiSockAddr _senderSockAddr; // sender address for packet (only used on receiving end) }; diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index b71f4107df..e3a8761e6d 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -15,22 +15,22 @@ #include -using namespace PacketType; +const QSet NON_VERIFIED_PACKETS = QSet() + << PacketType::NodeJsonStats << PacketType::EntityQuery + << PacketType::OctreeDataNack << PacketType::EntityEditNack + << PacketType::DomainListRequest << PacketType::StopNode; -const QSet NON_VERIFIED_PACKETS = QSet() - << NodeJsonStats << EntityQuery - << OctreeDataNack << EntityEditNack - << DomainListRequest << StopNode; +const QSet NON_SOURCED_PACKETS = QSet() + << PacketType::StunResponse << PacketType::CreateAssignment << PacketType::RequestAssignment + << PacketType::DomainServerRequireDTLS << PacketType::DomainConnectRequest + << PacketType::DomainList << PacketType::DomainConnectionDenied + << PacketType::DomainServerPathQuery << PacketType::DomainServerPathResponse + << PacketType::DomainServerAddedNode + << PacketType::ICEServerPeerInformation << PacketType::ICEServerQuery << PacketType::ICEServerHeartbeat + << PacketType::ICEPing << PacketType::ICEPingReply + << PacketType::AssignmentClientStatus << PacketType::StopNode; -const QSet NON_SOURCED_PACKETS = QSet() - << StunResponse << CreateAssignment << RequestAssignment - << DomainServerRequireDTLS << DomainConnectRequest - << DomainList << DomainConnectionDenied - << DomainServerPathQuery << DomainServerPathResponse - << DomainServerAddedNode - << ICEServerPeerInformation << ICEServerQuery << ICEServerHeartbeat - << ICEPing << ICEPingReply - << AssignmentClientStatus << StopNode; +const QSet RELIABLE_PACKETS = QSet(); int arithmeticCodingValueFromBuffer(const char* checkValue) { if (((uchar) *checkValue) < 255) { @@ -60,11 +60,11 @@ int packArithmeticallyCodedValue(int value, char* destination) { } } -PacketVersion versionForPacketType(PacketType::Value packetType) { +PacketVersion versionForPacketType(PacketType packetType) { switch (packetType) { - case EntityAdd: - case EntityEdit: - case EntityData: + case PacketType::EntityAdd: + case PacketType::EntityEdit: + case PacketType::EntityData: return VERSION_ENTITIES_NEW_PROTOCOL_LAYER; default: return 11; @@ -73,56 +73,66 @@ PacketVersion versionForPacketType(PacketType::Value packetType) { #define PACKET_TYPE_NAME_LOOKUP(x) case x: return QString(#x); -QString nameForPacketType(PacketType::Value packetType) { +QString nameForPacketType(PacketType packetType) { switch (packetType) { - PACKET_TYPE_NAME_LOOKUP(Unknown); - PACKET_TYPE_NAME_LOOKUP(StunResponse); - PACKET_TYPE_NAME_LOOKUP(DomainList); - PACKET_TYPE_NAME_LOOKUP(Ping); - PACKET_TYPE_NAME_LOOKUP(PingReply); - PACKET_TYPE_NAME_LOOKUP(KillAvatar); - PACKET_TYPE_NAME_LOOKUP(AvatarData); - PACKET_TYPE_NAME_LOOKUP(InjectAudio); - PACKET_TYPE_NAME_LOOKUP(MixedAudio); - PACKET_TYPE_NAME_LOOKUP(MicrophoneAudioNoEcho); - PACKET_TYPE_NAME_LOOKUP(MicrophoneAudioWithEcho); - PACKET_TYPE_NAME_LOOKUP(BulkAvatarData); - PACKET_TYPE_NAME_LOOKUP(SilentAudioFrame); - PACKET_TYPE_NAME_LOOKUP(DomainListRequest); - PACKET_TYPE_NAME_LOOKUP(RequestAssignment); - PACKET_TYPE_NAME_LOOKUP(CreateAssignment); - PACKET_TYPE_NAME_LOOKUP(DomainConnectionDenied); - PACKET_TYPE_NAME_LOOKUP(MuteEnvironment); - PACKET_TYPE_NAME_LOOKUP(AudioStreamStats); - PACKET_TYPE_NAME_LOOKUP(OctreeStats); - PACKET_TYPE_NAME_LOOKUP(Jurisdiction); - PACKET_TYPE_NAME_LOOKUP(JurisdictionRequest); - PACKET_TYPE_NAME_LOOKUP(AvatarIdentity); - PACKET_TYPE_NAME_LOOKUP(AvatarBillboard); - PACKET_TYPE_NAME_LOOKUP(DomainConnectRequest); - PACKET_TYPE_NAME_LOOKUP(DomainServerRequireDTLS); - PACKET_TYPE_NAME_LOOKUP(NodeJsonStats); - PACKET_TYPE_NAME_LOOKUP(EntityQuery); - PACKET_TYPE_NAME_LOOKUP(EntityData); - PACKET_TYPE_NAME_LOOKUP(EntityErase); - PACKET_TYPE_NAME_LOOKUP(OctreeDataNack); - PACKET_TYPE_NAME_LOOKUP(StopNode); - PACKET_TYPE_NAME_LOOKUP(AudioEnvironment); - PACKET_TYPE_NAME_LOOKUP(EntityEditNack); - PACKET_TYPE_NAME_LOOKUP(ICEServerHeartbeat); - PACKET_TYPE_NAME_LOOKUP(DomainServerAddedNode); - PACKET_TYPE_NAME_LOOKUP(ICEServerQuery); - PACKET_TYPE_NAME_LOOKUP(ICEServerPeerInformation); - PACKET_TYPE_NAME_LOOKUP(ICEPing); - PACKET_TYPE_NAME_LOOKUP(ICEPingReply); - PACKET_TYPE_NAME_LOOKUP(EntityAdd); - PACKET_TYPE_NAME_LOOKUP(EntityEdit); + PACKET_TYPE_NAME_LOOKUP(PacketType::Unknown); + PACKET_TYPE_NAME_LOOKUP(PacketType::StunResponse); + PACKET_TYPE_NAME_LOOKUP(PacketType::DomainList); + PACKET_TYPE_NAME_LOOKUP(PacketType::Ping); + PACKET_TYPE_NAME_LOOKUP(PacketType::PingReply); + PACKET_TYPE_NAME_LOOKUP(PacketType::KillAvatar); + PACKET_TYPE_NAME_LOOKUP(PacketType::AvatarData); + PACKET_TYPE_NAME_LOOKUP(PacketType::InjectAudio); + PACKET_TYPE_NAME_LOOKUP(PacketType::MixedAudio); + PACKET_TYPE_NAME_LOOKUP(PacketType::MicrophoneAudioNoEcho); + PACKET_TYPE_NAME_LOOKUP(PacketType::MicrophoneAudioWithEcho); + PACKET_TYPE_NAME_LOOKUP(PacketType::BulkAvatarData); + PACKET_TYPE_NAME_LOOKUP(PacketType::SilentAudioFrame); + PACKET_TYPE_NAME_LOOKUP(PacketType::DomainListRequest); + PACKET_TYPE_NAME_LOOKUP(PacketType::RequestAssignment); + PACKET_TYPE_NAME_LOOKUP(PacketType::CreateAssignment); + PACKET_TYPE_NAME_LOOKUP(PacketType::DomainConnectionDenied); + PACKET_TYPE_NAME_LOOKUP(PacketType::MuteEnvironment); + PACKET_TYPE_NAME_LOOKUP(PacketType::AudioStreamStats); + PACKET_TYPE_NAME_LOOKUP(PacketType::OctreeStats); + PACKET_TYPE_NAME_LOOKUP(PacketType::Jurisdiction); + PACKET_TYPE_NAME_LOOKUP(PacketType::JurisdictionRequest); + PACKET_TYPE_NAME_LOOKUP(PacketType::AvatarIdentity); + PACKET_TYPE_NAME_LOOKUP(PacketType::AvatarBillboard); + PACKET_TYPE_NAME_LOOKUP(PacketType::DomainConnectRequest); + PACKET_TYPE_NAME_LOOKUP(PacketType::DomainServerRequireDTLS); + PACKET_TYPE_NAME_LOOKUP(PacketType::NodeJsonStats); + PACKET_TYPE_NAME_LOOKUP(PacketType::EntityQuery); + PACKET_TYPE_NAME_LOOKUP(PacketType::EntityData); + PACKET_TYPE_NAME_LOOKUP(PacketType::EntityErase); + PACKET_TYPE_NAME_LOOKUP(PacketType::OctreeDataNack); + PACKET_TYPE_NAME_LOOKUP(PacketType::StopNode); + PACKET_TYPE_NAME_LOOKUP(PacketType::AudioEnvironment); + PACKET_TYPE_NAME_LOOKUP(PacketType::EntityEditNack); + PACKET_TYPE_NAME_LOOKUP(PacketType::ICEServerHeartbeat); + PACKET_TYPE_NAME_LOOKUP(PacketType::DomainServerAddedNode); + PACKET_TYPE_NAME_LOOKUP(PacketType::ICEServerQuery); + PACKET_TYPE_NAME_LOOKUP(PacketType::ICEServerPeerInformation); + PACKET_TYPE_NAME_LOOKUP(PacketType::ICEPing); + PACKET_TYPE_NAME_LOOKUP(PacketType::ICEPingReply); + PACKET_TYPE_NAME_LOOKUP(PacketType::EntityAdd); + PACKET_TYPE_NAME_LOOKUP(PacketType::EntityEdit); default: return QString("Type: ") + QString::number((int)packetType); } return QString("unexpected"); } -int numBytesForArithmeticCodedPacketType(PacketType::Value packetType) { +int numBytesForArithmeticCodedPacketType(PacketType packetType) { return (int) ceilf((float) packetType / 255); } + +uint qHash(const PacketType& key, uint seed) { + // seems odd that Qt couldn't figure out this cast itself, but this fixes a compile error after switch to + // strongly typed enum for PacketType + return qHash((quint8) key, seed); +} + +QDebug operator<<(QDebug debug, const PacketType& type) { + return debug.nospace() << (uint8_t) type << " (" << qPrintable(nameForPacketType(type)) << ")"; +} diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index d134125ca3..2d3f7f25fe 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -26,55 +26,53 @@ // NOTE: if adding a new packet packetType, you can replace one marked usable or add at the end // NOTE: if you want the name of the packet packetType to be available for debugging or logging, update nameForPacketType() as well -namespace PacketType { - enum Value { - Unknown, - StunResponse, - DomainList, - Ping, - PingReply, - KillAvatar, - AvatarData, - InjectAudio, - MixedAudio, - MicrophoneAudioNoEcho, - MicrophoneAudioWithEcho, - BulkAvatarData, - SilentAudioFrame, - DomainListRequest, - RequestAssignment, - CreateAssignment, - DomainConnectionDenied, - MuteEnvironment, - AudioStreamStats, - DomainServerPathQuery, - DomainServerPathResponse, - DomainServerAddedNode, - ICEServerPeerInformation, - ICEServerQuery, - OctreeStats, - Jurisdiction, - JurisdictionRequest, - AssignmentClientStatus, - NoisyMute, - AvatarIdentity, - AvatarBillboard, - DomainConnectRequest, - DomainServerRequireDTLS, - NodeJsonStats, - OctreeDataNack, - StopNode, - AudioEnvironment, - EntityEditNack, - ICEServerHeartbeat, - ICEPing, - ICEPingReply, - EntityData, - EntityQuery, - EntityAdd, - EntityErase, - EntityEdit - }; +enum class PacketType : uint8_t { + Unknown, + StunResponse, + DomainList, + Ping, + PingReply, + KillAvatar, + AvatarData, + InjectAudio, + MixedAudio, + MicrophoneAudioNoEcho, + MicrophoneAudioWithEcho, + BulkAvatarData, + SilentAudioFrame, + DomainListRequest, + RequestAssignment, + CreateAssignment, + DomainConnectionDenied, + MuteEnvironment, + AudioStreamStats, + DomainServerPathQuery, + DomainServerPathResponse, + DomainServerAddedNode, + ICEServerPeerInformation, + ICEServerQuery, + OctreeStats, + Jurisdiction, + JurisdictionRequest, + AssignmentClientStatus, + NoisyMute, + AvatarIdentity, + AvatarBillboard, + DomainConnectRequest, + DomainServerRequireDTLS, + NodeJsonStats, + OctreeDataNack, + StopNode, + AudioEnvironment, + EntityEditNack, + ICEServerHeartbeat, + ICEPing, + ICEPingReply, + EntityData, + EntityQuery, + EntityAdd, + EntityErase, + EntityEdit }; const int NUM_BYTES_MD5_HASH = 16; @@ -84,19 +82,23 @@ const int MAX_PACKET_HEADER_BYTES = 4 + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_H typedef char PacketVersion; -extern const QSet NON_VERIFIED_PACKETS; -extern const QSet NON_SOURCED_PACKETS; +extern const QSet NON_VERIFIED_PACKETS; +extern const QSet NON_SOURCED_PACKETS; +extern const QSet RELIABLE_PACKETS; -QString nameForPacketType(PacketType::Value packetType); -PacketVersion versionForPacketType(PacketType::Value packetType); +QString nameForPacketType(PacketType packetType); +PacketVersion versionForPacketType(PacketType packetType); -int numBytesForArithmeticCodedPacketType(PacketType::Value packetType); -int numBytesForPacketHeaderGivenPacketType(PacketType::Value packetType); +int numBytesForArithmeticCodedPacketType(PacketType packetType); +int numBytesForPacketHeaderGivenPacketType(PacketType packetType); int packArithmeticallyCodedValue(int value, char* destination); int arithmeticCodingValueFromBuffer(const char* checkValue); int numBytesArithmeticCodingFromBuffer(const char* checkValue); +uint qHash(const PacketType& key, uint seed); +QDebug operator<<(QDebug debug, const PacketType& type); + const PacketVersion VERSION_OCTREE_HAS_FILE_BREAKS = 1; const PacketVersion VERSION_ENTITIES_HAVE_ANIMATION = 1; const PacketVersion VERSION_ROOT_ELEMENT_HAS_DATA = 2; diff --git a/libraries/networking/src/udt/PacketList.cpp b/libraries/networking/src/udt/PacketList.cpp index 47545eb910..494587971b 100644 --- a/libraries/networking/src/udt/PacketList.cpp +++ b/libraries/networking/src/udt/PacketList.cpp @@ -17,7 +17,7 @@ using namespace udt; -PacketList::PacketList(PacketType::Value packetType, QByteArray extendedHeader) : +PacketList::PacketList(PacketType packetType, QByteArray extendedHeader) : _packetType(packetType), _extendedHeader(extendedHeader) { @@ -34,7 +34,8 @@ void PacketList::endSegment() { std::unique_ptr PacketList::createPacket() { // use the static create method to create a new packet - return Packet::create(getType()); + // TODO: create a packet with correct reliability and messaging + return Packet::create(); } std::unique_ptr PacketList::createPacketWithExtendedHeader() { diff --git a/libraries/networking/src/udt/PacketList.h b/libraries/networking/src/udt/PacketList.h index 3d1166149c..18acb7fa17 100644 --- a/libraries/networking/src/udt/PacketList.h +++ b/libraries/networking/src/udt/PacketList.h @@ -27,14 +27,14 @@ class Packet; class PacketList : public QIODevice { Q_OBJECT public: - PacketList(PacketType::Value packetType, QByteArray extendedHeader = QByteArray()); + PacketList(PacketType packetType, QByteArray extendedHeader = QByteArray()); virtual bool isSequential() const { return true; } void startSegment(); void endSegment(); - PacketType::Value getType() const { return _packetType; } + PacketType getType() const { return _packetType; } int getNumPackets() const { return _packets.size() + (_currentPacket ? 1 : 0); } void closeCurrentPacket(bool shouldSendEmpty = false); @@ -58,7 +58,7 @@ private: virtual std::unique_ptr createPacket(); std::unique_ptr createPacketWithExtendedHeader(); - PacketType::Value _packetType; + PacketType _packetType; bool _isOrdered = false; std::unique_ptr _currentPacket; diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 203ff2b072..a8a3f28f9a 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -1894,7 +1894,7 @@ bool Octree::readSVOFromStream(unsigned long streamLength, QDataStream& inputStr bool wantImportProgress = true; - PacketType::Value expectedType = expectedDataPacketType(); + PacketType expectedType = expectedDataPacketType(); PacketVersion expectedVersion = versionForPacketType(expectedType); bool hasBufferBreaks = versionHasSVOfileBreaks(expectedVersion); @@ -1902,7 +1902,7 @@ bool Octree::readSVOFromStream(unsigned long streamLength, QDataStream& inputStr if (getWantSVOfileVersions()) { // read just enough of the file to parse the header... - const unsigned long HEADER_LENGTH = sizeof(PacketType::Value) + sizeof(PacketVersion); + const unsigned long HEADER_LENGTH = sizeof(PacketType) + sizeof(PacketVersion); unsigned char fileHeader[HEADER_LENGTH]; inputStream.readRawData((char*)&fileHeader, HEADER_LENGTH); @@ -1912,7 +1912,7 @@ bool Octree::readSVOFromStream(unsigned long streamLength, QDataStream& inputStr unsigned long dataLength = HEADER_LENGTH; // if so, read the first byte of the file and see if it matches the expected version code - PacketType::Value gotType; + PacketType gotType; memcpy(&gotType, dataAt, sizeof(gotType)); dataAt += sizeof(expectedType); @@ -2055,7 +2055,7 @@ void Octree::writeToJSONFile(const char* fileName, OctreeElement* element) { } // include the "bitstream" version - PacketType::Value expectedType = expectedDataPacketType(); + PacketType expectedType = expectedDataPacketType(); PacketVersion expectedVersion = versionForPacketType(expectedType); entityDescription["Version"] = (int) expectedVersion; @@ -2076,7 +2076,7 @@ void Octree::writeToSVOFile(const char* fileName, OctreeElement* element) { if(file.is_open()) { qCDebug(octree, "Saving binary SVO to file %s...", fileName); - PacketType::Value expectedType = expectedDataPacketType(); + PacketType expectedType = expectedDataPacketType(); PacketVersion expectedVersion = versionForPacketType(expectedType); bool hasBufferBreaks = versionHasSVOfileBreaks(expectedVersion); diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index e00434be80..c8db9ba17a 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -228,11 +228,11 @@ public: // These methods will allow the OctreeServer to send your tree inbound edit packets of your // own definition. Implement these to allow your octree based server to support editing virtual bool getWantSVOfileVersions() const { return false; } - virtual PacketType::Value expectedDataPacketType() const { return PacketType::Unknown; } + virtual PacketType expectedDataPacketType() const { return PacketType::Unknown; } virtual bool canProcessVersion(PacketVersion thisVersion) const { return thisVersion == versionForPacketType(expectedDataPacketType()); } virtual PacketVersion expectedVersion() const { return versionForPacketType(expectedDataPacketType()); } - virtual bool handlesEditPacketType(PacketType::Value packetType) const { return false; } + virtual bool handlesEditPacketType(PacketType packetType) const { return false; } virtual int processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength, const SharedNodePointer& sourceNode) { return 0; } diff --git a/libraries/octree/src/OctreeEditPacketSender.cpp b/libraries/octree/src/OctreeEditPacketSender.cpp index e2e17a6606..0d67e2391d 100644 --- a/libraries/octree/src/OctreeEditPacketSender.cpp +++ b/libraries/octree/src/OctreeEditPacketSender.cpp @@ -194,7 +194,7 @@ void OctreeEditPacketSender::queuePacketToNodes(std::unique_ptr packet // NOTE: editMessage - is JUST the octcode/color and does not contain the packet header -void OctreeEditPacketSender::queueOctreeEditMessage(PacketType::Value type, QByteArray& editMessage) { +void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, QByteArray& editMessage) { if (!_shouldSend) { return; // bail early @@ -315,7 +315,7 @@ void OctreeEditPacketSender::releaseQueuedPacket(const QUuid& nodeID, std::uniqu _releaseQueuedPacketMutex.unlock(); } -std::unique_ptr OctreeEditPacketSender::initializePacket(PacketType::Value type, int nodeClockSkew) { +std::unique_ptr OctreeEditPacketSender::initializePacket(PacketType type, int nodeClockSkew) { auto newPacket = NLPacket::create(type); // skip over sequence number for now; will be packed when packet is ready to be sent out diff --git a/libraries/octree/src/OctreeEditPacketSender.h b/libraries/octree/src/OctreeEditPacketSender.h index 8c77a1e388..be44aec88d 100644 --- a/libraries/octree/src/OctreeEditPacketSender.h +++ b/libraries/octree/src/OctreeEditPacketSender.h @@ -36,7 +36,7 @@ public: /// Queues a single edit message. Will potentially send a pending multi-command packet. Determines which server /// node or nodes the packet should be sent to. Can be called even before servers are known, in which case up to /// MaxPendingMessages will be buffered and processed when servers are known. - void queueOctreeEditMessage(PacketType::Value type, QByteArray& editMessage); + void queueOctreeEditMessage(PacketType type, QByteArray& editMessage); /// Releases all queued messages even if those messages haven't filled an MTU packet. This will move the packed message /// packets onto the send queue. If running in threaded mode, the caller does not need to do any further processing to @@ -81,7 +81,7 @@ public: // you must override these... virtual char getMyNodeType() const = 0; - virtual void adjustEditPacketForClockSkew(PacketType::Value type, QByteArray& buffer, int clockSkew) { } + virtual void adjustEditPacketForClockSkew(PacketType type, QByteArray& buffer, int clockSkew) { } void processNackPacket(NLPacket& packet, SharedNodePointer sendingNode); @@ -89,13 +89,13 @@ public slots: void nodeKilled(SharedNodePointer node); protected: - using EditMessagePair = std::pair; + using EditMessagePair = std::pair; bool _shouldSend; void queuePacketToNode(const QUuid& nodeID, std::unique_ptr packet); void queuePendingPacketToNodes(std::unique_ptr packet); void queuePacketToNodes(std::unique_ptr packet); - std::unique_ptr initializePacket(PacketType::Value type, int nodeClockSkew); + std::unique_ptr initializePacket(PacketType type, int nodeClockSkew); void releaseQueuedPacket(const QUuid& nodeUUID, std::unique_ptr packetBuffer); // releases specific queued packet void processPreServerExistsPackets(); diff --git a/libraries/octree/src/OctreeHeadlessViewer.cpp b/libraries/octree/src/OctreeHeadlessViewer.cpp index 5714ddcb03..ca50fc001e 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.cpp +++ b/libraries/octree/src/OctreeHeadlessViewer.cpp @@ -33,7 +33,7 @@ void OctreeHeadlessViewer::init() { void OctreeHeadlessViewer::queryOctree() { char serverType = getMyNodeType(); - PacketType::Value packetType = getMyQueryMessageType(); + PacketType packetType = getMyQueryMessageType(); NodeToJurisdictionMap& jurisdictions = *_jurisdictionListener->getJurisdictions(); bool wantExtraDebugging = false; diff --git a/libraries/octree/src/OctreePacketData.h b/libraries/octree/src/OctreePacketData.h index 439a07087c..2c9d587254 100644 --- a/libraries/octree/src/OctreePacketData.h +++ b/libraries/octree/src/OctreePacketData.h @@ -42,7 +42,7 @@ typedef quint64 OCTREE_PACKET_SENT_TIME; typedef uint16_t OCTREE_PACKET_INTERNAL_SECTION_SIZE; const int MAX_OCTREE_PACKET_SIZE = MAX_PACKET_SIZE; -// this is overly conservative - sizeof(PacketType) is 8 bytes but a packed PacketType::Value could be as small as one byte +// this is overly conservative - sizeof(PacketType) is 8 bytes but a packed PacketType could be as small as one byte const unsigned int OCTREE_PACKET_EXTRA_HEADERS_SIZE = sizeof(OCTREE_PACKET_FLAGS) + sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME); diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index 85a193a3e6..032551d13e 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -36,8 +36,8 @@ public: virtual ~OctreeRenderer(); virtual char getMyNodeType() const = 0; - virtual PacketType::Value getMyQueryMessageType() const = 0; - virtual PacketType::Value getExpectedPacketType() const = 0; + virtual PacketType getMyQueryMessageType() const = 0; + virtual PacketType getExpectedPacketType() const = 0; virtual void renderElement(OctreeElement* element, RenderArgs* args) = 0; virtual float getSizeScale() const { return DEFAULT_OCTREE_SIZE_SCALE; } virtual int getBoundaryLevelAdjust() const { return 0; }