Overte C++ Documentation
DomainServer.h
1 //
2 // DomainServer.h
3 // domain-server/src
4 //
5 // Created by Stephen Birarda on 9/26/13.
6 // Copyright 2013 High Fidelity, Inc.
7 // Copyright 2020 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_DomainServer_h
14 #define hifi_DomainServer_h
15 
16 #include <QtCore/QCoreApplication>
17 #include <QtCore/QHash>
18 #include <QtCore/QJsonObject>
19 #include <QtCore/QQueue>
20 #include <QtCore/QSharedPointer>
21 #include <QtCore/QStringList>
22 #include <QtCore/QThread>
23 #include <QtCore/QUrl>
24 #include <QHostAddress>
25 #include <QAbstractNativeEventFilter>
26 
27 #include <Assignment.h>
28 #include <HTTPSConnection.h>
29 #include <LimitedNodeList.h>
30 #include <shared/WebRTC.h>
31 #include <webrtc/WebRTCSignalingServer.h>
32 
33 #include "AssetsBackupHandler.h"
34 #include "DomainGatekeeper.h"
35 #include "DomainMetadata.h"
36 #include "DomainServerSettingsManager.h"
37 #include "DomainServerWebSessionData.h"
38 #include "DomainContentBackupManager.h"
39 
40 #include "PendingAssignedNodeData.h"
41 #include "DomainServerExporter.h"
42 
43 #include <QLoggingCategory>
44 
45 Q_DECLARE_LOGGING_CATEGORY(domain_server)
46 Q_DECLARE_LOGGING_CATEGORY(domain_server_ice)
47 Q_DECLARE_LOGGING_CATEGORY(domain_server_auth)
48 
49 typedef QSharedPointer<Assignment> SharedAssignmentPointer;
50 
51 using Subnet = QPair<QHostAddress, int>;
52 using SubnetList = std::vector<Subnet>;
53 
54 const int INVALID_ICE_LOOKUP_ID = -1;
55 
56 enum ReplicationServerDirection {
57  Upstream,
58  Downstream
59 };
60 
61 class DomainServer : public QCoreApplication, public HTTPSRequestHandler {
62  Q_OBJECT
63 public:
64  DomainServer(int argc, char* argv[]);
65  ~DomainServer();
66 
67  static void parseCommandLine(int argc, char* argv[]);
68 
69  enum DomainType {
70  NonMetaverse,
71  MetaverseDomain,
72  MetaverseTemporaryDomain
73  };
74 
75  static int const EXIT_CODE_REBOOT;
76 
77  bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url, bool skipSubHandler = false) override;
78  bool handleHTTPSRequest(HTTPSConnection* connection, const QUrl& url, bool skipSubHandler = false) override;
79 
80  static const QString REPLACEMENT_FILE_EXTENSION;
81 
82  bool isAssetServerEnabled();
83 
84  static bool forceCrashReporting() { return _forceCrashReporting; }
85 
86 public slots:
88  void nodeAdded(SharedNodePointer node);
90  void nodeKilled(SharedNodePointer node);
91 
92  void restart();
93 
94 private slots:
95  void processRequestAssignmentPacket(QSharedPointer<ReceivedMessage> packet);
96  void processListRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode);
97  void processNodeJSONStatsPacket(QSharedPointer<ReceivedMessage> packetList, SharedNodePointer sendingNode);
98  void processPathQueryPacket(QSharedPointer<ReceivedMessage> packet);
99  void processNodeDisconnectRequestPacket(QSharedPointer<ReceivedMessage> message);
100  void processICEServerHeartbeatDenialPacket(QSharedPointer<ReceivedMessage> message);
101  void processICEServerHeartbeatACK(QSharedPointer<ReceivedMessage> message);
102  void processAvatarZonePresencePacket(QSharedPointer<ReceivedMessage> packet);
103 
104  void handleDomainContentReplacementFromURLRequest(QSharedPointer<ReceivedMessage> message);
105  void handleOctreeFileReplacementRequest(QSharedPointer<ReceivedMessage> message);
106  bool handleOctreeFileReplacement(QByteArray octreeFile, QString sourceFilename, QString name, QString username);
107 
108  void processOctreeDataRequestMessage(QSharedPointer<ReceivedMessage> message);
109  void processOctreeDataPersistMessage(QSharedPointer<ReceivedMessage> message);
110 
111  void performIPAddressPortUpdate(const SockAddr& newPublicSockAddr);
112  void sendHeartbeatToMetaverse() { sendHeartbeatToMetaverse(QString(), int()); }
113  void sendHeartbeatToIceServer();
114  void nodePingMonitor();
115 
116  void handleConnectedNode(SharedNodePointer newNode, quint64 requestReceiveTime);
117  void handleTempDomainSuccess(QNetworkReply* requestReply);
118  void handleTempDomainError(QNetworkReply* requestReply);
119 
120  void handleMetaverseHeartbeatError(QNetworkReply* requestReply);
121 
122  void queuedQuit(QString quitMessage, int exitCode);
123 
124  void handleKeypairChange();
125 
126  void updateICEServerAddresses();
127  void handleICEHostInfo(const QHostInfo& hostInfo);
128 
129  void sendICEServerAddressToMetaverseAPI();
130  void handleSuccessfulICEServerAddressUpdate(QNetworkReply* requestReply);
131  void handleFailedICEServerAddressUpdate(QNetworkReply* requestReply);
132 
133  void updateReplicatedNodes();
134  void updateDownstreamNodes();
135  void updateUpstreamNodes();
136 
137  void initializeExporter();
138  void initializeMetadataExporter();
139 
140  void tokenGrantFinished();
141  void profileRequestFinished();
142 
143 #if defined(WEBRTC_DATA_CHANNELS)
144  void forwardAssignmentClientSignalingMessageToUserClient(QSharedPointer<ReceivedMessage> message);
145 #endif
146 
147  void aboutToQuit();
148 
149 signals:
150  void iceServerChanged();
151  void userConnected();
152  void userDisconnected();
153 
154 #if defined(WEBRTC_DATA_CHANNELS)
155  void webrtcSignalingMessageForDomainServer(const QJsonObject& json);
156  void webrtcSignalingMessageForUserClient(const QJsonObject& json);
157 #endif
158 
159 
160 private:
161  QUuid getID();
162 
163  QString getContentBackupDir();
164  QString getEntitiesDirPath();
165  QString getEntitiesFilePath();
166  QString getEntitiesReplacementFilePath();
167 
168  void maybeHandleReplacementEntityFile();
169 
170  void setupNodeListAndAssignments();
171  bool optionallySetupOAuth();
172  bool optionallyReadX509KeyAndCertificate();
173 
174  void getTemporaryName(bool force = false);
175 
176  static bool isPacketVerified(const udt::Packet& packet);
177 
178  bool resetAccountManagerAccessToken();
179 
180  void setupAutomaticNetworking();
181  void setupICEHeartbeatForFullNetworking();
182  void setupHeartbeatToMetaverse();
183  void sendHeartbeatToMetaverse(const QString& networkAddress, const int port);
184 
185  void randomizeICEServerAddress(bool shouldTriggerHostLookup);
186 
187  unsigned int countConnectedUsers();
188 
189  void handleKillNode(SharedNodePointer nodeToKill);
190  void broadcastNodeDisconnect(const SharedNodePointer& disconnnectedNode);
191 
192  void sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const SockAddr& senderSockAddr, bool newConnection);
193 
194  bool isInInterestSet(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB);
195 
196  QUuid connectionSecretForNodes(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB);
197  void broadcastNewNode(const SharedNodePointer& node);
198 
199  void parseAssignmentConfigs(QSet<Assignment::Type>& excludedTypes);
200  void addStaticAssignmentToAssignmentHash(Assignment* newAssignment);
201  void createStaticAssignmentsForType(Assignment::Type type, const QVariantList& configList);
202  void populateDefaultStaticAssignmentsExcludingTypes(const QSet<Assignment::Type>& excludedTypes);
203  void populateStaticScriptedAssignmentsFromSettings();
204 
205  SharedAssignmentPointer dequeueMatchingAssignment(const QUuid& checkInUUID, NodeType_t nodeType);
206  SharedAssignmentPointer deployableAssignmentForRequest(const Assignment& requestAssignment);
207  void refreshStaticAssignmentAndAddToQueue(SharedAssignmentPointer& assignment);
208  void addStaticAssignmentsToQueue();
209 
210  QUrl oauthRedirectURL();
211  QUrl oauthAuthorizationURL(const QUuid& stateUUID = QUuid::createUuid());
212 
213  std::pair<bool, QString> isAuthenticatedRequest(HTTPConnection* connection);
214 
215  QNetworkReply* profileRequestGivenTokenReply(QNetworkReply* tokenReply);
216  Headers setupCookieHeadersFromProfileReply(QNetworkReply* profileReply);
217 
218  QJsonObject jsonForSocket(const SockAddr& socket);
219  QJsonObject jsonObjectForNode(const SharedNodePointer& node);
220 
221  bool shouldReplicateNode(const Node& node);
222 
223  void setupGroupCacheRefresh();
224 
225  QString pathForRedirect(QString path = QString()) const;
226 
227  void updateReplicationNodes(ReplicationServerDirection direction);
228 
229  HTTPSConnection* connectionFromReplyWithState(QNetworkReply* reply);
230 
231  bool processPendingContent(HTTPConnection* connection, QString itemName, QString filename, QByteArray dataChunk);
232 
233  bool forwardMetaverseAPIRequest(HTTPConnection* connection,
234  const QUrl& requestUrl,
235  const QString& metaversePath,
236  const QString& requestSubobjectKey = "",
237  std::initializer_list<QString> requiredData = { },
238  std::initializer_list<QString> optionalData = { },
239  bool requireAccessToken = true);
240 
241 #if defined(WEBRTC_DATA_CHANNELS)
242  void setUpWebRTCSignalingServer();
243  void routeWebRTCSignalingMessage(const QJsonObject& json);
244  void sendWebRTCSignalingMessageToAssignmentClient(const QJsonObject& json);
245 #endif
246 
247  QString operationToString(const QNetworkAccessManager::Operation &op);
248 
249  SubnetList _acSubnetAllowlist;
250 
251  std::vector<QString> _replicatedUsernames;
252 
253  DomainGatekeeper _gatekeeper;
254  DomainServerExporter _exporter;
255 
256  HTTPManager _httpManager;
257  HTTPManager* _httpExporterManager { nullptr };
258  HTTPManager* _httpMetadataExporterManager { nullptr };
259 
260  std::unique_ptr<HTTPSManager> _httpsManager;
261 
262  QHash<QUuid, SharedAssignmentPointer> _allAssignments;
263  QQueue<SharedAssignmentPointer> _unfulfilledAssignments;
264 
265  bool _isUsingDTLS { false };
266 
267  bool _oauthEnable { false };
268  QUrl _oauthProviderURL;
269  QString _oauthClientID;
270  QString _oauthClientSecret;
271  QString _hostname;
272 
273  std::unordered_map<QUuid, QByteArray> _ephemeralACScripts;
274 
275  QSet<QUuid> _webAuthenticationStateSet;
276  QHash<QUuid, DomainServerWebSessionData> _cookieSessionHash;
277 
278  QString _automaticNetworkingSetting;
279 
280  DomainServerSettingsManager _settingsManager;
281 
282  SockAddr _iceServerSocket;
283  std::unique_ptr<NLPacket> _iceServerHeartbeatPacket;
284 
285  // These will be parented to this, they are not dangling
286  DomainMetadata* _metadata { nullptr };
287  QTimer* _iceHeartbeatTimer { nullptr };
288  QTimer* _metaverseHeartbeatTimer { nullptr };
289  QTimer* _metaverseGroupCacheTimer { nullptr };
290  QTimer* _nodePingMonitorTimer { nullptr };
291 
292  QList<QHostAddress> _iceServerAddresses;
293  QSet<QHostAddress> _failedIceServerAddresses;
294  int _iceAddressLookupID { INVALID_ICE_LOOKUP_ID };
295  int _noReplyICEHeartbeats { 0 };
296  int _numHeartbeatDenials { 0 };
297  bool _connectedToICEServer { false };
298 
299  DomainType _type { DomainType::NonMetaverse };
300 
301  friend class DomainGatekeeper;
302  friend class DomainMetadata;
303 
304  static QString _iceServerAddr;
305  static int _iceServerPort;
306  static bool _overrideDomainID; // should we override the domain-id from settings?
307  static QUuid _overridingDomainID; // what should we override it with?
308  static bool _getTempName;
309  static QString _userConfigFilename;
310  static int _parentPID;
311  static bool _forceCrashReporting;
312 
313 
314  bool _sendICEServerAddressToMetaverseAPIInProgress { false };
315  bool _sendICEServerAddressToMetaverseAPIRedo { false };
316 
317  std::unique_ptr<DomainContentBackupManager> _contentManager { nullptr };
318 
319  QHash<QUuid, QPointer<HTTPSConnection>> _pendingOAuthConnections;
320 
321  std::unordered_map<int, QByteArray> _pendingUploadedContents;
322  std::unordered_map<int, std::unique_ptr<QTemporaryFile>> _pendingContentFiles;
323 
324  QThread _assetClientThread;
325 
326 #if defined(WEBRTC_DATA_CHANNELS)
327  std::unique_ptr<WebRTCSignalingServer> _webrtcSignalingServer { nullptr };
328 #endif
329 };
330 
331 
332 #endif // hifi_DomainServer_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
Prometheus exporter for domain stats.
Definition: DomainServerExporter.h:35
Manages the domain-wide settings.
Definition: DomainServerSettingsManager.h:75
Handles a single HTTP connection.
Definition: HTTPConnection.h:43
Handles HTTP connections.
Definition: HTTPManager.h:32