Overte C++ Documentation
NodeList.h
1 //
2 // NodeList.h
3 // libraries/networking/src
4 //
5 // Created by Stephen Birarda on 2/15/13.
6 // Copyright 2013 High Fidelity, Inc.
7 // Copyright 2021 Vircadia contributors.
8 //
9 // Distributed under the Apache License, Version 2.0.
10 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
11 //
12 
13 #ifndef hifi_NodeList_h
14 #define hifi_NodeList_h
15 
16 #include <stdint.h>
17 #include <iterator>
18 #include <assert.h>
19 
20 #ifndef _WIN32
21 #include <unistd.h> // not on windows, not needed for mac or windows
22 #endif
23 
24 #include <TBBHelpers.h>
25 
26 #include <QtCore/QElapsedTimer>
27 #include <QtCore/QMutex>
28 #include <QtCore/QSet>
29 #include <QtCore/QSharedPointer>
30 #include <QtNetwork/QHostAddress>
31 #include <QtNetwork/QUdpSocket>
32 
33 #include <DependencyManager.h>
34 #include <SettingHandle.h>
35 
36 #include "DomainHandler.h"
37 #include "LimitedNodeList.h"
38 #include "Node.h"
39 
40 const quint64 DOMAIN_SERVER_CHECK_IN_MSECS = 1 * 1000;
41 
42 using PacketOrPacketList = std::pair<std::unique_ptr<NLPacket>, std::unique_ptr<NLPacketList>>;
43 using NodePacketOrPacketListPair = std::pair<SharedNodePointer, PacketOrPacketList>;
44 
45 using NodePacketPair = std::pair<SharedNodePointer, std::unique_ptr<NLPacket>>;
46 using NodeSharedPacketPair = std::pair<SharedNodePointer, QSharedPointer<NLPacket>>;
47 using NodeSharedReceivedMessagePair = std::pair<SharedNodePointer, QSharedPointer<ReceivedMessage>>;
48 
49 class Application;
50 class Assignment;
51 
52 class NodeList : public LimitedNodeList {
53  Q_OBJECT
54  SINGLETON_DEPENDENCY
55 
56 public:
57  void startThread();
58  NodeType_t getOwnerType() const { return _ownerType.load(); }
59  void setOwnerType(NodeType_t ownerType) { _ownerType.store(ownerType); }
60 
61  Q_INVOKABLE qint64 sendStats(QJsonObject statsObject, SockAddr destination);
62  Q_INVOKABLE qint64 sendStatsToDomainServer(QJsonObject statsObject);
63 
64  DomainHandler& getDomainHandler() { return _domainHandler; }
65 
66  const NodeSet& getNodeInterestSet() const { return _nodeTypesOfInterest; }
67  void addNodeTypeToInterestSet(NodeType_t nodeTypeToAdd);
68  void addSetOfNodeTypesToNodeInterestSet(const NodeSet& setOfNodeTypes);
69  void resetNodeInterestSet() { _nodeTypesOfInterest.clear(); }
70 
71  void setAssignmentServerSocket(const SockAddr& serverSocket) { _assignmentServerSocket = serverSocket; }
72  void sendAssignment(Assignment& assignment);
73 
74  void disableDomainPortAutoDiscovery(bool disabled = false) { _domainPortAutoDiscovery = !disabled; };
75 
76  void setIsShuttingDown(bool isShuttingDown) { _isShuttingDown = isShuttingDown; }
77 
78  void ignoreNodesInRadius(bool enabled = true);
79  bool getIgnoreRadiusEnabled() const { return _ignoreRadiusEnabled.get(); }
80  void toggleIgnoreRadius() { ignoreNodesInRadius(!getIgnoreRadiusEnabled()); }
81  void enableIgnoreRadius() { ignoreNodesInRadius(true); }
82  void disableIgnoreRadius() { ignoreNodesInRadius(false); }
83  void ignoreNodeBySessionID(const QUuid& nodeID, bool ignoreEnabled);
84  bool isIgnoringNode(const QUuid& nodeID) const;
85  void personalMuteNodeBySessionID(const QUuid& nodeID, bool muteEnabled);
86  bool isPersonalMutingNode(const QUuid& nodeID) const;
87  void setAvatarGain(const QUuid& nodeID, float gain);
88  float getAvatarGain(const QUuid& nodeID);
89  void setInjectorGain(float gain);
90  float getInjectorGain();
91 
92  void kickNodeBySessionID(const QUuid& nodeID, unsigned int banFlags);
93  void muteNodeBySessionID(const QUuid& nodeID);
94  void requestUsernameFromSessionID(const QUuid& nodeID);
95  bool getRequestsDomainListData() { return _requestsDomainListData; }
96  void setRequestsDomainListData(bool isRequesting);
97 
98  bool getSendDomainServerCheckInEnabled() { return _sendDomainServerCheckInEnabled; }
99  void setSendDomainServerCheckInEnabled(bool enabled) { _sendDomainServerCheckInEnabled = enabled; }
100 
101  void removeFromIgnoreMuteSets(const QUuid& nodeID);
102 
103  virtual bool isDomainServer() const override { return false; }
104  virtual QUuid getDomainUUID() const override { return _domainHandler.getUUID(); }
105  virtual Node::LocalID getDomainLocalID() const override { return _domainHandler.getLocalID(); }
106  virtual SockAddr getDomainSockAddr() const override { return _domainHandler.getSockAddr(); }
107 
108 public slots:
109  void reset(QString reason, bool skipDomainHandlerReset = false);
110  void resetFromDomainHandler() { reset("Reset from Domain Handler", true); }
111 
112  void sendDomainServerCheckIn();
113  void handleDSPathQuery(const QString& newPath);
114 
115  void processDomainList(QSharedPointer<ReceivedMessage> message);
116  void processDomainServerAddedNode(QSharedPointer<ReceivedMessage> message);
117  void processDomainServerRemovedNode(QSharedPointer<ReceivedMessage> message);
118  void processDomainServerPathResponse(QSharedPointer<ReceivedMessage> message);
119 
120  void processDomainServerConnectionTokenPacket(QSharedPointer<ReceivedMessage> message);
121 
122  void processPingPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
123  void processPingReplyPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
124 
125  void processICEPingPacket(QSharedPointer<ReceivedMessage> message);
126 
127  void processUsernameFromIDReply(QSharedPointer<ReceivedMessage> message);
128 
129  // FIXME: Can remove these work-arounds in version 2021.2.0. (New protocol version implies a domain server upgrade.)
130  bool adjustCanRezAvatarEntitiesPermissions(const QJsonObject& domainSettingsObject, NodePermissions& permissions,
131  bool notify);
132  void adjustCanRezAvatarEntitiesPerSettings(const QJsonObject& domainSettingsObject);
133 
134 #if (PR_BUILD || DEV_BUILD)
135  void toggleSendNewerDSConnectVersion(bool shouldSendNewerVersion) { _shouldSendNewerVersion = shouldSendNewerVersion; }
136 #endif
137 
138 signals:
139  void receivedDomainServerList();
140  void ignoredNode(const QUuid& nodeID, bool enabled);
141  void ignoreRadiusEnabledChanged(bool isIgnored);
142  void usernameFromIDReply(const QString& nodeID, const QString& username, const QString& machineFingerprint, bool isAdmin);
143 
144 private slots:
145  void stopKeepalivePingTimer();
146  void sendPendingDSPathQuery();
147  void handleICEConnectionToDomainServer();
148 
149  void startNodeHolePunch(const SharedNodePointer& node);
150  void handleNodePingTimeout();
151 
152  void pingPunchForDomainServer();
153 
154  void sendKeepAlivePings();
155 
156  void maybeSendIgnoreSetToNode(SharedNodePointer node);
157 
158 private:
159  Q_DISABLE_COPY(NodeList)
160  NodeList() : LimitedNodeList(INVALID_PORT, INVALID_PORT) {
161  assert(false); // Not implemented, needed for DependencyManager templates compile
162  }
163  NodeList(char ownerType, int socketListenPort = INVALID_PORT, int dtlsListenPort = INVALID_PORT);
164 
165  void processDomainServerAuthRequest(const QByteArray& packet);
166  void requestAuthForDomainServer();
167  void activateSocketFromNodeCommunication(ReceivedMessage& message, const SharedNodePointer& sendingNode);
168  void timePingReply(ReceivedMessage& message, const SharedNodePointer& sendingNode);
169 
170  void sendDSPathQuery(const QString& newPath);
171 
172  void parseNodeFromPacketStream(QDataStream& packetStream);
173 
174  void pingPunchForInactiveNode(const SharedNodePointer& node);
175 
176  bool sockAddrBelongsToDomainOrNode(const SockAddr& sockAddr);
177 
178  std::atomic<NodeType_t> _ownerType;
179  NodeSet _nodeTypesOfInterest;
180  DomainHandler _domainHandler;
181  SockAddr _assignmentServerSocket;
182  bool _isShuttingDown { false };
183  QTimer _keepAlivePingTimer;
184  bool _requestsDomainListData { false };
185 
186  bool _sendDomainServerCheckInEnabled { true };
187  bool _domainPortAutoDiscovery { true };
188 
189  mutable QReadWriteLock _ignoredSetLock;
190  tbb::concurrent_unordered_set<QUuid, UUIDHasher> _ignoredNodeIDs;
191  mutable QReadWriteLock _personalMutedSetLock;
192  tbb::concurrent_unordered_set<QUuid, UUIDHasher> _personalMutedNodeIDs;
193  mutable QReadWriteLock _avatarGainMapLock;
194  tbb::concurrent_unordered_map<QUuid, float, UUIDHasher> _avatarGainMap;
195 
196  std::atomic<float> _avatarGain { 0.0f }; // in dB
197  std::atomic<float> _injectorGain { 0.0f }; // in dB
198 
199  void sendIgnoreRadiusStateToNode(const SharedNodePointer& destinationNode);
200 #if defined(Q_OS_ANDROID)
201  Setting::Handle<bool> _ignoreRadiusEnabled { "IgnoreRadiusEnabled", false };
202 #else
203  Setting::Handle<bool> _ignoreRadiusEnabled { "IgnoreRadiusEnabled", false }; // False, until such time as it is made to work better.
204 #endif
205 
206 #if (PR_BUILD || DEV_BUILD)
207  bool _shouldSendNewerVersion { false };
208 #endif
209 
210  bool _hasDomainAccountManager { false };
211 };
212 
213 #endif // hifi_NodeList_h
quint8 NodeType_t
An 8-bit value identifying the type of a node - domain server, audio mixer, etc.
Definition: NodeType.h:22
Holds information used for request, creation, and deployment of assignments.
Definition: Assignment.h:28