From 717c12fe1696a41b01b123b62e38822f1eb67a4d Mon Sep 17 00:00:00 2001 From: Clement Date: Wed, 27 Feb 2019 18:22:49 -0800 Subject: [PATCH 1/5] Add new connection rate limitting Limit rate of connection for new Agents --- assignment-client/src/avatars/AvatarMixer.cpp | 8 +++ .../resources/describe-settings.json | 8 +++ domain-server/src/DomainServer.cpp | 11 ++- libraries/networking/src/NodeList.cpp | 68 ++++++++++++++----- libraries/networking/src/NodeList.h | 24 +++++++ 5 files changed, 96 insertions(+), 23 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 500772c1b5..7c21daefc3 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -904,6 +904,14 @@ void AvatarMixer::parseDomainServerSettings(const QJsonObject& domainSettings) { qCDebug(avatars) << "Avatar mixer will automatically determine number of threads to use. Using:" << _slavePool.numThreads() << "threads."; } + { + const QString CONNECTION_RATE = "connection_rate"; + auto nodeList = DependencyManager::get(); + auto defaultConnectionRate = nodeList->getMaxConnectionRate(); + int connectionRate = avatarMixerGroupObject[CONNECTION_RATE].toInt(defaultConnectionRate); + nodeList->setMaxConnectionRate(connectionRate); + } + const QString AVATARS_SETTINGS_KEY = "avatars"; static const QString MIN_HEIGHT_OPTION = "min_avatar_height"; diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 49023c9af8..140c7d6c17 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -1302,6 +1302,14 @@ "placeholder": "1", "default": "1", "advanced": true + }, + { + "name": "connection_rate", + "label": "Connection Rate", + "help": "Number of new agents that can connect to the mixer every second", + "placeholder": "50", + "default": "50", + "advanced": true } ] }, diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 258038b8f1..8ba0cbc115 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1243,12 +1243,11 @@ void DomainServer::broadcastNewNode(const SharedNodePointer& addedNode) { limitedNodeList->eachMatchingNode( [this, addedNode](const SharedNodePointer& node)->bool { - if (node->getLinkedData() && node->getActiveSocket() && node != addedNode) { - // is the added Node in this node's interest list? - return isInInterestSet(node, addedNode); - } else { - return false; - } + // is the added Node in this node's interest list? + return node->getLinkedData() + && node->getActiveSocket() + && node != addedNode + && isInInterestSet(node, addedNode); }, [this, &addNodePacket, connectionSecretIndex, addedNode, limitedNodeListWeak](const SharedNodePointer& node) { // send off this packet to the node diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 5e8909db2b..1de710e8ca 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -37,7 +37,9 @@ #include "SharedUtil.h" #include -const int KEEPALIVE_PING_INTERVAL_MS = 1000; +using namespace std::chrono_literals; +static const std::chrono::milliseconds CONNECTION_RATE_INTERVAL = 1s; +static const std::chrono::milliseconds KEEPALIVE_PING_INTERVAL = 1s; NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) : LimitedNodeList(socketListenPort, dtlsListenPort), @@ -104,7 +106,7 @@ NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) connect(this, &LimitedNodeList::nodeActivated, this, &NodeList::maybeSendIgnoreSetToNode); // setup our timer to send keepalive pings (it's started and stopped on domain connect/disconnect) - _keepAlivePingTimer.setInterval(KEEPALIVE_PING_INTERVAL_MS); // 1s, Qt::CoarseTimer acceptable + _keepAlivePingTimer.setInterval(KEEPALIVE_PING_INTERVAL); // 1s, Qt::CoarseTimer acceptable connect(&_keepAlivePingTimer, &QTimer::timeout, this, &NodeList::sendKeepAlivePings); connect(&_domainHandler, SIGNAL(connectedToDomain(QUrl)), &_keepAlivePingTimer, SLOT(start())); connect(&_domainHandler, &DomainHandler::disconnectedFromDomain, &_keepAlivePingTimer, &QTimer::stop); @@ -116,6 +118,11 @@ NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) // we definitely want STUN to update our public socket, so call the LNL to kick that off startSTUNPublicSocketUpdate(); + // check for local socket updates every so often + QTimer* delayedAddsFlushTimer = new QTimer(this); + connect(delayedAddsFlushTimer, &QTimer::timeout, this, &NodeList::processDelayedAdds); + delayedAddsFlushTimer->start(CONNECTION_RATE_INTERVAL); + auto& packetReceiver = getPacketReceiver(); packetReceiver.registerListener(PacketType::DomainList, this, "processDomainServerList"); packetReceiver.registerListener(PacketType::Ping, this, "processPingPacket"); @@ -200,7 +207,6 @@ void NodeList::timePingReply(ReceivedMessage& message, const SharedNodePointer& } void NodeList::processPingPacket(QSharedPointer message, SharedNodePointer sendingNode) { - // send back a reply auto replyPacket = constructPingReplyPacket(*message); const HifiSockAddr& senderSockAddr = message->getSenderSockAddr(); @@ -711,27 +717,38 @@ void NodeList::processDomainServerRemovedNode(QSharedPointer me } void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) { - // setup variables to read into from QDataStream - qint8 nodeType; - QUuid nodeUUID, connectionSecretUUID; - HifiSockAddr nodePublicSocket, nodeLocalSocket; - NodePermissions permissions; - bool isReplicated; - Node::LocalID sessionLocalID; + NewNodeInfo info; - packetStream >> nodeType >> nodeUUID >> nodePublicSocket >> nodeLocalSocket >> permissions - >> isReplicated >> sessionLocalID; + packetStream >> info.type + >> info.uuid + >> info.publicSocket + >> info.localSocket + >> info.permissions + >> info.isReplicated + >> info.sessionLocalID + >> info.connectionSecretUUID; // if the public socket address is 0 then it's reachable at the same IP // as the domain server - if (nodePublicSocket.getAddress().isNull()) { - nodePublicSocket.setAddress(_domainHandler.getIP()); + if (info.publicSocket.getAddress().isNull()) { + info.publicSocket.setAddress(_domainHandler.getIP()); } - packetStream >> connectionSecretUUID; + // Throttle connection of new agents. + if (info.type != NodeType::Agent + || _nodesAddedInCurrentTimeSlice < _maxConnectionRate) { - SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, nodeLocalSocket, - sessionLocalID, isReplicated, false, connectionSecretUUID, permissions); + addNewNode(info); + ++_nodesAddedInCurrentTimeSlice; + } else { + delayNodeAdd(info); + } +} + +void NodeList::addNewNode(NewNodeInfo info) { + SharedNodePointer node = addOrUpdateNode(info.uuid, info.type, info.publicSocket, info.localSocket, + info.sessionLocalID, info.isReplicated, false, + info.connectionSecretUUID, info.permissions); // nodes that are downstream or upstream of our own type are kept alive when we hear about them from the domain server // and always have their public socket as their active socket @@ -739,6 +756,23 @@ void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) { node->setLastHeardMicrostamp(usecTimestampNow()); node->activatePublicSocket(); } +}; + +void NodeList::delayNodeAdd(NewNodeInfo info) { + _delayedNodeAdds.push_back(info); +}; + +void NodeList::processDelayedAdds() { + _nodesAddedInCurrentTimeSlice = 0; + + auto nodesToAdd = glm::min(_delayedNodeAdds.size(), _maxConnectionRate); + auto firstNodeToAdd = _delayedNodeAdds.begin(); + auto lastNodeToAdd = firstNodeToAdd + nodesToAdd; + + for (auto it = firstNodeToAdd; it != lastNodeToAdd; ++it) { + addNewNode(*it); + } + _delayedNodeAdds.erase(firstNodeToAdd, lastNodeToAdd); } void NodeList::sendAssignment(Assignment& assignment) { diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index e135bc937d..f913b7c3b9 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -38,6 +38,8 @@ const quint64 DOMAIN_SERVER_CHECK_IN_MSECS = 1 * 1000; +static const size_t DEFAULT_MAX_CONNECTION_RATE { 50 }; + using PacketOrPacketList = std::pair, std::unique_ptr>; using NodePacketOrPacketListPair = std::pair; @@ -93,6 +95,9 @@ public: bool getSendDomainServerCheckInEnabled() { return _sendDomainServerCheckInEnabled; } void setSendDomainServerCheckInEnabled(bool enabled) { _sendDomainServerCheckInEnabled = enabled; } + size_t getMaxConnectionRate() { return _maxConnectionRate; } + void setMaxConnectionRate(size_t rate) { _maxConnectionRate = rate; } + void removeFromIgnoreMuteSets(const QUuid& nodeID); virtual bool isDomainServer() const override { return false; } @@ -146,6 +151,17 @@ private slots: void maybeSendIgnoreSetToNode(SharedNodePointer node); private: + struct NewNodeInfo { + qint8 type; + QUuid uuid; + HifiSockAddr publicSocket; + HifiSockAddr localSocket; + NodePermissions permissions; + bool isReplicated; + Node::LocalID sessionLocalID; + QUuid connectionSecretUUID; + }; + NodeList() : LimitedNodeList(INVALID_PORT, INVALID_PORT) { assert(false); } // Not implemented, needed for DependencyManager templates compile NodeList(char ownerType, int socketListenPort = INVALID_PORT, int dtlsListenPort = INVALID_PORT); NodeList(NodeList const&) = delete; // Don't implement, needed to avoid copies of singleton @@ -164,6 +180,10 @@ private: bool sockAddrBelongsToDomainOrNode(const HifiSockAddr& sockAddr); + void addNewNode(NewNodeInfo info); + void delayNodeAdd(NewNodeInfo info); + void processDelayedAdds(); + std::atomic _ownerType; NodeSet _nodeTypesOfInterest; DomainHandler _domainHandler; @@ -181,6 +201,10 @@ private: mutable QReadWriteLock _avatarGainMapLock; tbb::concurrent_unordered_map _avatarGainMap; + size_t _maxConnectionRate { DEFAULT_MAX_CONNECTION_RATE }; + size_t _nodesAddedInCurrentTimeSlice { 0 }; + std::vector _delayedNodeAdds; + void sendIgnoreRadiusStateToNode(const SharedNodePointer& destinationNode); #if defined(Q_OS_ANDROID) Setting::Handle _ignoreRadiusEnabled { "IgnoreRadiusEnabled", false }; From 80320635125577c0370c7ebae39872f40525b518 Mon Sep 17 00:00:00 2001 From: Clement Date: Wed, 27 Feb 2019 19:14:36 -0800 Subject: [PATCH 2/5] Move to LimitedNodeList --- libraries/networking/src/LimitedNodeList.cpp | 57 +++++++++++++++++++- libraries/networking/src/LimitedNodeList.h | 27 ++++++++++ libraries/networking/src/NodeList.cpp | 56 ++++--------------- libraries/networking/src/NodeList.h | 24 --------- 4 files changed, 93 insertions(+), 71 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index eaa02f059e..f00614141c 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -40,6 +40,9 @@ static Setting::Handle LIMITED_NODELIST_LOCAL_PORT("LimitedNodeList.LocalPort", 0); +using namespace std::chrono_literals; +static const std::chrono::milliseconds CONNECTION_RATE_INTERVAL = 1s; + const std::set SOLO_NODE_TYPES = { NodeType::AvatarMixer, NodeType::AudioMixer, @@ -88,6 +91,11 @@ LimitedNodeList::LimitedNodeList(int socketListenPort, int dtlsListenPort) : connect(statsSampleTimer, &QTimer::timeout, this, &LimitedNodeList::sampleConnectionStats); statsSampleTimer->start(CONNECTION_STATS_SAMPLE_INTERVAL_MSECS); + // Flush delayed adds every second + QTimer* delayedAddsFlushTimer = new QTimer(this); + connect(delayedAddsFlushTimer, &QTimer::timeout, this, &NodeList::processDelayedAdds); + delayedAddsFlushTimer->start(CONNECTION_RATE_INTERVAL); + // check the local socket right now updateLocalSocket(); @@ -367,7 +375,7 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe return true; - } else { + } else if (!isDelayedNode(sourceID)){ HIFI_FCDEBUG(networking(), "Packet of type" << headerType << "received from unknown node with Local ID" << sourceLocalID); } @@ -736,6 +744,53 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t return newNodePointer; } +void LimitedNodeList::addNewNode(NewNodeInfo info) { + // Throttle connection of new agents. + if (info.type == NodeType::Agent && _nodesAddedInCurrentTimeSlice >= _maxConnectionRate) { + delayNodeAdd(info); + return; + } + + SharedNodePointer node = addOrUpdateNode(info.uuid, info.type, info.publicSocket, info.localSocket, + info.sessionLocalID, info.isReplicated, false, + info.connectionSecretUUID, info.permissions); + + ++_nodesAddedInCurrentTimeSlice; +} + +void LimitedNodeList::delayNodeAdd(NewNodeInfo info) { + _delayedNodeAdds.push_back(info); +} + +void LimitedNodeList::removeDelayedAdd(QUuid nodeUUID) { + auto it = std::find_if(_delayedNodeAdds.begin(), _delayedNodeAdds.end(), [&](auto info) { + return info.uuid == nodeUUID; + }); + if (it != _delayedNodeAdds.end()) { + _delayedNodeAdds.erase(it); + } +} + +bool LimitedNodeList::isDelayedNode(QUuid nodeUUID) { + auto it = std::find_if(_delayedNodeAdds.begin(), _delayedNodeAdds.end(), [&](auto info) { + return info.uuid == nodeUUID; + }); + return it != _delayedNodeAdds.end(); +} + +void LimitedNodeList::processDelayedAdds() { + _nodesAddedInCurrentTimeSlice = 0; + + auto nodesToAdd = glm::min(_delayedNodeAdds.size(), _maxConnectionRate); + auto firstNodeToAdd = _delayedNodeAdds.begin(); + auto lastNodeToAdd = firstNodeToAdd + nodesToAdd; + + for (auto it = firstNodeToAdd; it != lastNodeToAdd; ++it) { + addNewNode(*it); + } + _delayedNodeAdds.erase(firstNodeToAdd, lastNodeToAdd); +} + std::unique_ptr LimitedNodeList::constructPingPacket(const QUuid& nodeId, PingType_t pingType) { int packetSize = sizeof(PingType_t) + sizeof(quint64) + sizeof(int64_t); diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 450fad96a9..fbd37ae065 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -51,6 +51,8 @@ const int INVALID_PORT = -1; const quint64 NODE_SILENCE_THRESHOLD_MSECS = 5 * 1000; +static const size_t DEFAULT_MAX_CONNECTION_RATE { 50 }; + extern const std::set SOLO_NODE_TYPES; const char DEFAULT_ASSIGNMENT_SERVER_HOSTNAME[] = "localhost"; @@ -316,6 +318,9 @@ public: void sendFakedHandshakeRequestToNode(SharedNodePointer node); #endif + size_t getMaxConnectionRate() { return _maxConnectionRate; } + void setMaxConnectionRate(size_t rate) { _maxConnectionRate = rate; } + int getInboundPPS() const { return _inboundPPS; } int getOutboundPPS() const { return _outboundPPS; } float getInboundKbps() const { return _inboundKbps; } @@ -367,7 +372,20 @@ protected slots: void clientConnectionToSockAddrReset(const HifiSockAddr& sockAddr); + void processDelayedAdds(); + protected: + struct NewNodeInfo { + qint8 type; + QUuid uuid; + HifiSockAddr publicSocket; + HifiSockAddr localSocket; + NodePermissions permissions; + bool isReplicated; + Node::LocalID sessionLocalID; + QUuid connectionSecretUUID; + }; + LimitedNodeList(int socketListenPort = INVALID_PORT, int dtlsListenPort = INVALID_PORT); LimitedNodeList(LimitedNodeList const&) = delete; // Don't implement, needed to avoid copies of singleton void operator=(LimitedNodeList const&) = delete; // Don't implement, needed to avoid copies of singleton @@ -390,6 +408,11 @@ protected: bool sockAddrBelongsToNode(const HifiSockAddr& sockAddr); + void addNewNode(NewNodeInfo info); + void delayNodeAdd(NewNodeInfo info); + void removeDelayedAdd(QUuid nodeUUID); + bool isDelayedNode(QUuid nodeUUID); + NodeHash _nodeHash; mutable QReadWriteLock _nodeMutex { QReadWriteLock::Recursive }; udt::Socket _nodeSocket; @@ -440,6 +463,10 @@ private: Node::LocalID _sessionLocalID { 0 }; bool _flagTimeForConnectionStep { false }; // only keep track in interface + size_t _maxConnectionRate { DEFAULT_MAX_CONNECTION_RATE }; + size_t _nodesAddedInCurrentTimeSlice { 0 }; + std::vector _delayedNodeAdds; + int _inboundPPS { 0 }; int _outboundPPS { 0 }; float _inboundKbps { 0.0f }; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 1de710e8ca..4097ddf1a3 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -38,7 +38,6 @@ #include using namespace std::chrono_literals; -static const std::chrono::milliseconds CONNECTION_RATE_INTERVAL = 1s; static const std::chrono::milliseconds KEEPALIVE_PING_INTERVAL = 1s; NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) : @@ -118,11 +117,6 @@ NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) // we definitely want STUN to update our public socket, so call the LNL to kick that off startSTUNPublicSocketUpdate(); - // check for local socket updates every so often - QTimer* delayedAddsFlushTimer = new QTimer(this); - connect(delayedAddsFlushTimer, &QTimer::timeout, this, &NodeList::processDelayedAdds); - delayedAddsFlushTimer->start(CONNECTION_RATE_INTERVAL); - auto& packetReceiver = getPacketReceiver(); packetReceiver.registerListener(PacketType::DomainList, this, "processDomainServerList"); packetReceiver.registerListener(PacketType::Ping, this, "processPingPacket"); @@ -714,6 +708,7 @@ void NodeList::processDomainServerRemovedNode(QSharedPointer me QUuid nodeUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); qCDebug(networking) << "Received packet from domain-server to remove node with UUID" << uuidStringWithoutCurlyBraces(nodeUUID); killNodeWithUUID(nodeUUID); + removeDelayedAdd(nodeUUID); } void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) { @@ -734,45 +729,7 @@ void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) { info.publicSocket.setAddress(_domainHandler.getIP()); } - // Throttle connection of new agents. - if (info.type != NodeType::Agent - || _nodesAddedInCurrentTimeSlice < _maxConnectionRate) { - - addNewNode(info); - ++_nodesAddedInCurrentTimeSlice; - } else { - delayNodeAdd(info); - } -} - -void NodeList::addNewNode(NewNodeInfo info) { - SharedNodePointer node = addOrUpdateNode(info.uuid, info.type, info.publicSocket, info.localSocket, - info.sessionLocalID, info.isReplicated, false, - info.connectionSecretUUID, info.permissions); - - // nodes that are downstream or upstream of our own type are kept alive when we hear about them from the domain server - // and always have their public socket as their active socket - if (node->getType() == NodeType::downstreamType(_ownerType) || node->getType() == NodeType::upstreamType(_ownerType)) { - node->setLastHeardMicrostamp(usecTimestampNow()); - node->activatePublicSocket(); - } -}; - -void NodeList::delayNodeAdd(NewNodeInfo info) { - _delayedNodeAdds.push_back(info); -}; - -void NodeList::processDelayedAdds() { - _nodesAddedInCurrentTimeSlice = 0; - - auto nodesToAdd = glm::min(_delayedNodeAdds.size(), _maxConnectionRate); - auto firstNodeToAdd = _delayedNodeAdds.begin(); - auto lastNodeToAdd = firstNodeToAdd + nodesToAdd; - - for (auto it = firstNodeToAdd; it != lastNodeToAdd; ++it) { - addNewNode(*it); - } - _delayedNodeAdds.erase(firstNodeToAdd, lastNodeToAdd); + addNewNode(info); } void NodeList::sendAssignment(Assignment& assignment) { @@ -819,7 +776,6 @@ void NodeList::pingPunchForInactiveNode(const SharedNodePointer& node) { } void NodeList::startNodeHolePunch(const SharedNodePointer& node) { - // we don't hole punch to downstream servers, since it is assumed that we have a direct line to them // we also don't hole punch to relayed upstream nodes, since we do not communicate directly with them @@ -833,6 +789,14 @@ void NodeList::startNodeHolePunch(const SharedNodePointer& node) { // ping this node immediately pingPunchForInactiveNode(node); } + + // nodes that are downstream or upstream of our own type are kept alive when we hear about them from the domain server + // and always have their public socket as their active socket + if (node->getType() == NodeType::downstreamType(_ownerType) || node->getType() == NodeType::upstreamType(_ownerType)) { + node->setLastHeardMicrostamp(usecTimestampNow()); + node->activatePublicSocket(); + } + } void NodeList::handleNodePingTimeout() { diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index f913b7c3b9..e135bc937d 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -38,8 +38,6 @@ const quint64 DOMAIN_SERVER_CHECK_IN_MSECS = 1 * 1000; -static const size_t DEFAULT_MAX_CONNECTION_RATE { 50 }; - using PacketOrPacketList = std::pair, std::unique_ptr>; using NodePacketOrPacketListPair = std::pair; @@ -95,9 +93,6 @@ public: bool getSendDomainServerCheckInEnabled() { return _sendDomainServerCheckInEnabled; } void setSendDomainServerCheckInEnabled(bool enabled) { _sendDomainServerCheckInEnabled = enabled; } - size_t getMaxConnectionRate() { return _maxConnectionRate; } - void setMaxConnectionRate(size_t rate) { _maxConnectionRate = rate; } - void removeFromIgnoreMuteSets(const QUuid& nodeID); virtual bool isDomainServer() const override { return false; } @@ -151,17 +146,6 @@ private slots: void maybeSendIgnoreSetToNode(SharedNodePointer node); private: - struct NewNodeInfo { - qint8 type; - QUuid uuid; - HifiSockAddr publicSocket; - HifiSockAddr localSocket; - NodePermissions permissions; - bool isReplicated; - Node::LocalID sessionLocalID; - QUuid connectionSecretUUID; - }; - NodeList() : LimitedNodeList(INVALID_PORT, INVALID_PORT) { assert(false); } // Not implemented, needed for DependencyManager templates compile NodeList(char ownerType, int socketListenPort = INVALID_PORT, int dtlsListenPort = INVALID_PORT); NodeList(NodeList const&) = delete; // Don't implement, needed to avoid copies of singleton @@ -180,10 +164,6 @@ private: bool sockAddrBelongsToDomainOrNode(const HifiSockAddr& sockAddr); - void addNewNode(NewNodeInfo info); - void delayNodeAdd(NewNodeInfo info); - void processDelayedAdds(); - std::atomic _ownerType; NodeSet _nodeTypesOfInterest; DomainHandler _domainHandler; @@ -201,10 +181,6 @@ private: mutable QReadWriteLock _avatarGainMapLock; tbb::concurrent_unordered_map _avatarGainMap; - size_t _maxConnectionRate { DEFAULT_MAX_CONNECTION_RATE }; - size_t _nodesAddedInCurrentTimeSlice { 0 }; - std::vector _delayedNodeAdds; - void sendIgnoreRadiusStateToNode(const SharedNodePointer& destinationNode); #if defined(Q_OS_ANDROID) Setting::Handle _ignoreRadiusEnabled { "IgnoreRadiusEnabled", false }; From 9fe7a3350c619d14a4514b3808d41580e8f9478a Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 28 Feb 2019 13:10:10 -0800 Subject: [PATCH 3/5] Fix windows compile error --- assignment-client/src/avatars/AvatarMixer.cpp | 2 +- libraries/networking/src/LimitedNodeList.cpp | 18 +++++++++--------- libraries/networking/src/NodeList.cpp | 5 ++--- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 7c21daefc3..dc3570c7b3 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -908,7 +908,7 @@ void AvatarMixer::parseDomainServerSettings(const QJsonObject& domainSettings) { const QString CONNECTION_RATE = "connection_rate"; auto nodeList = DependencyManager::get(); auto defaultConnectionRate = nodeList->getMaxConnectionRate(); - int connectionRate = avatarMixerGroupObject[CONNECTION_RATE].toInt(defaultConnectionRate); + int connectionRate = avatarMixerGroupObject[CONNECTION_RATE].toInt((int)defaultConnectionRate); nodeList->setMaxConnectionRate(connectionRate); } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index f00614141c..01c7a16166 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -41,7 +41,7 @@ static Setting::Handle LIMITED_NODELIST_LOCAL_PORT("LimitedNodeList.LocalPort", 0); using namespace std::chrono_literals; -static const std::chrono::milliseconds CONNECTION_RATE_INTERVAL = 1s; +static const std::chrono::milliseconds CONNECTION_RATE_INTERVAL_MS = 1s; const std::set SOLO_NODE_TYPES = { NodeType::AvatarMixer, @@ -94,7 +94,7 @@ LimitedNodeList::LimitedNodeList(int socketListenPort, int dtlsListenPort) : // Flush delayed adds every second QTimer* delayedAddsFlushTimer = new QTimer(this); connect(delayedAddsFlushTimer, &QTimer::timeout, this, &NodeList::processDelayedAdds); - delayedAddsFlushTimer->start(CONNECTION_RATE_INTERVAL); + delayedAddsFlushTimer->start(CONNECTION_RATE_INTERVAL_MS.count()); // check the local socket right now updateLocalSocket(); @@ -848,13 +848,13 @@ unsigned int LimitedNodeList::broadcastToNodes(std::unique_ptr packet, eachNode([&](const SharedNodePointer& node){ if (node && destinationNodeTypes.contains(node->getType())) { - if (packet->isReliable()) { - auto packetCopy = NLPacket::createCopy(*packet); - sendPacket(std::move(packetCopy), *node); - } else { - sendUnreliablePacket(*packet, *node); - } - ++n; + if (packet->isReliable()) { + auto packetCopy = NLPacket::createCopy(*packet); + sendPacket(std::move(packetCopy), *node); + } else { + sendUnreliablePacket(*packet, *node); + } + ++n; } }); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 4097ddf1a3..d45e466291 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -37,8 +37,7 @@ #include "SharedUtil.h" #include -using namespace std::chrono_literals; -static const std::chrono::milliseconds KEEPALIVE_PING_INTERVAL = 1s; +const int KEEPALIVE_PING_INTERVAL_MS = 1000; NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) : LimitedNodeList(socketListenPort, dtlsListenPort), @@ -105,7 +104,7 @@ NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) connect(this, &LimitedNodeList::nodeActivated, this, &NodeList::maybeSendIgnoreSetToNode); // setup our timer to send keepalive pings (it's started and stopped on domain connect/disconnect) - _keepAlivePingTimer.setInterval(KEEPALIVE_PING_INTERVAL); // 1s, Qt::CoarseTimer acceptable + _keepAlivePingTimer.setInterval(KEEPALIVE_PING_INTERVAL_MS); // 1s, Qt::CoarseTimer acceptable connect(&_keepAlivePingTimer, &QTimer::timeout, this, &NodeList::sendKeepAlivePings); connect(&_domainHandler, SIGNAL(connectedToDomain(QUrl)), &_keepAlivePingTimer, SLOT(start())); connect(&_domainHandler, &DomainHandler::disconnectedFromDomain, &_keepAlivePingTimer, &QTimer::stop); From 9ea41f7122ab0aa4ddb86cc11d278195e843e36e Mon Sep 17 00:00:00 2001 From: Clement Date: Thu, 28 Feb 2019 15:22:07 -0800 Subject: [PATCH 4/5] CR --- libraries/networking/src/LimitedNodeList.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index fbd37ae065..18b9a318ef 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -318,7 +318,7 @@ public: void sendFakedHandshakeRequestToNode(SharedNodePointer node); #endif - size_t getMaxConnectionRate() { return _maxConnectionRate; } + size_t getMaxConnectionRate() const { return _maxConnectionRate; } void setMaxConnectionRate(size_t rate) { _maxConnectionRate = rate; } int getInboundPPS() const { return _inboundPPS; } From a804d3532e6b04fb86e5e520147bd34c331b3f36 Mon Sep 17 00:00:00 2001 From: Clement Date: Thu, 28 Feb 2019 15:30:57 -0800 Subject: [PATCH 5/5] Set default limit for other nodes to size_t max --- libraries/networking/src/LimitedNodeList.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 18b9a318ef..eb1a3e2dde 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -51,7 +51,7 @@ const int INVALID_PORT = -1; const quint64 NODE_SILENCE_THRESHOLD_MSECS = 5 * 1000; -static const size_t DEFAULT_MAX_CONNECTION_RATE { 50 }; +static const size_t DEFAULT_MAX_CONNECTION_RATE { std::numeric_limits::max() }; extern const std::set SOLO_NODE_TYPES;