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  void screensharePresence(QString roomname, QUuid avatarID, int expiration_seconds = 0);
85 
86  static bool forceCrashReporting() { return _forceCrashReporting; }
87 
88 public slots:
90  void nodeAdded(SharedNodePointer node);
92  void nodeKilled(SharedNodePointer node);
93 
94  void restart();
95 
96 private slots:
97  void processRequestAssignmentPacket(QSharedPointer<ReceivedMessage> packet);
98  void processListRequestPacket(QSharedPointer<ReceivedMessage> packet, SharedNodePointer sendingNode);
99  void processNodeJSONStatsPacket(QSharedPointer<ReceivedMessage> packetList, SharedNodePointer sendingNode);
100  void processPathQueryPacket(QSharedPointer<ReceivedMessage> packet);
101  void processNodeDisconnectRequestPacket(QSharedPointer<ReceivedMessage> message);
102  void processICEServerHeartbeatDenialPacket(QSharedPointer<ReceivedMessage> message);
103  void processICEServerHeartbeatACK(QSharedPointer<ReceivedMessage> message);
104  void processAvatarZonePresencePacket(QSharedPointer<ReceivedMessage> packet);
105 
106  void handleDomainContentReplacementFromURLRequest(QSharedPointer<ReceivedMessage> message);
107  void handleOctreeFileReplacementRequest(QSharedPointer<ReceivedMessage> message);
108  bool handleOctreeFileReplacement(QByteArray octreeFile, QString sourceFilename, QString name, QString username);
109 
110  void processOctreeDataRequestMessage(QSharedPointer<ReceivedMessage> message);
111  void processOctreeDataPersistMessage(QSharedPointer<ReceivedMessage> message);
112 
113  void performIPAddressPortUpdate(const SockAddr& newPublicSockAddr);
114  void sendHeartbeatToMetaverse() { sendHeartbeatToMetaverse(QString(), int()); }
115  void sendHeartbeatToIceServer();
116  void nodePingMonitor();
117 
118  void handleConnectedNode(SharedNodePointer newNode, quint64 requestReceiveTime);
119  void handleTempDomainSuccess(QNetworkReply* requestReply);
120  void handleTempDomainError(QNetworkReply* requestReply);
121 
122  void handleMetaverseHeartbeatError(QNetworkReply* requestReply);
123 
124  void queuedQuit(QString quitMessage, int exitCode);
125 
126  void handleKeypairChange();
127 
128  void updateICEServerAddresses();
129  void handleICEHostInfo(const QHostInfo& hostInfo);
130 
131  void sendICEServerAddressToMetaverseAPI();
132  void handleSuccessfulICEServerAddressUpdate(QNetworkReply* requestReply);
133  void handleFailedICEServerAddressUpdate(QNetworkReply* requestReply);
134 
135  void handleSuccessfulScreensharePresence(QNetworkReply* requestReply, QJsonObject callbackData);
136  void handleFailedScreensharePresence(QNetworkReply* requestReply);
137 
138  void updateReplicatedNodes();
139  void updateDownstreamNodes();
140  void updateUpstreamNodes();
141 
142  void initializeExporter();
143  void initializeMetadataExporter();
144 
145  void tokenGrantFinished();
146  void profileRequestFinished();
147 
148 #if defined(WEBRTC_DATA_CHANNELS)
149  void forwardAssignmentClientSignalingMessageToUserClient(QSharedPointer<ReceivedMessage> message);
150 #endif
151 
152  void aboutToQuit();
153 
154 signals:
155  void iceServerChanged();
156  void userConnected();
157  void userDisconnected();
158 
159 #if defined(WEBRTC_DATA_CHANNELS)
160  void webrtcSignalingMessageForDomainServer(const QJsonObject& json);
161  void webrtcSignalingMessageForUserClient(const QJsonObject& json);
162 #endif
163 
164 
165 private:
166  QUuid getID();
167 
168  QString getContentBackupDir();
169  QString getEntitiesDirPath();
170  QString getEntitiesFilePath();
171  QString getEntitiesReplacementFilePath();
172 
173  void maybeHandleReplacementEntityFile();
174 
175  void setupNodeListAndAssignments();
176  bool optionallySetupOAuth();
177  bool optionallyReadX509KeyAndCertificate();
178 
179  void getTemporaryName(bool force = false);
180 
181  static bool isPacketVerified(const udt::Packet& packet);
182 
183  bool resetAccountManagerAccessToken();
184 
185  void setupAutomaticNetworking();
186  void setupICEHeartbeatForFullNetworking();
187  void setupHeartbeatToMetaverse();
188  void sendHeartbeatToMetaverse(const QString& networkAddress, const int port);
189 
190  void randomizeICEServerAddress(bool shouldTriggerHostLookup);
191 
192  unsigned int countConnectedUsers();
193 
194  void handleKillNode(SharedNodePointer nodeToKill);
195  void broadcastNodeDisconnect(const SharedNodePointer& disconnnectedNode);
196 
197  void sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const SockAddr& senderSockAddr, bool newConnection);
198 
199  bool isInInterestSet(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB);
200 
201  QUuid connectionSecretForNodes(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB);
202  void broadcastNewNode(const SharedNodePointer& node);
203 
204  void parseAssignmentConfigs(QSet<Assignment::Type>& excludedTypes);
205  void addStaticAssignmentToAssignmentHash(Assignment* newAssignment);
206  void createStaticAssignmentsForType(Assignment::Type type, const QVariantList& configList);
207  void populateDefaultStaticAssignmentsExcludingTypes(const QSet<Assignment::Type>& excludedTypes);
208  void populateStaticScriptedAssignmentsFromSettings();
209 
210  SharedAssignmentPointer dequeueMatchingAssignment(const QUuid& checkInUUID, NodeType_t nodeType);
211  SharedAssignmentPointer deployableAssignmentForRequest(const Assignment& requestAssignment);
212  void refreshStaticAssignmentAndAddToQueue(SharedAssignmentPointer& assignment);
213  void addStaticAssignmentsToQueue();
214 
215  QUrl oauthRedirectURL();
216  QUrl oauthAuthorizationURL(const QUuid& stateUUID = QUuid::createUuid());
217 
218  std::pair<bool, QString> isAuthenticatedRequest(HTTPConnection* connection);
219 
220  QNetworkReply* profileRequestGivenTokenReply(QNetworkReply* tokenReply);
221  Headers setupCookieHeadersFromProfileReply(QNetworkReply* profileReply);
222 
223  QJsonObject jsonForSocket(const SockAddr& socket);
224  QJsonObject jsonObjectForNode(const SharedNodePointer& node);
225 
226  bool shouldReplicateNode(const Node& node);
227 
228  void setupGroupCacheRefresh();
229 
230  QString pathForRedirect(QString path = QString()) const;
231 
232  void updateReplicationNodes(ReplicationServerDirection direction);
233 
234  HTTPSConnection* connectionFromReplyWithState(QNetworkReply* reply);
235 
236  bool processPendingContent(HTTPConnection* connection, QString itemName, QString filename, QByteArray dataChunk);
237 
238  bool forwardMetaverseAPIRequest(HTTPConnection* connection,
239  const QUrl& requestUrl,
240  const QString& metaversePath,
241  const QString& requestSubobjectKey = "",
242  std::initializer_list<QString> requiredData = { },
243  std::initializer_list<QString> optionalData = { },
244  bool requireAccessToken = true);
245 
246 #if defined(WEBRTC_DATA_CHANNELS)
247  void setUpWebRTCSignalingServer();
248  void routeWebRTCSignalingMessage(const QJsonObject& json);
249  void sendWebRTCSignalingMessageToAssignmentClient(const QJsonObject& json);
250 #endif
251 
252  QString operationToString(const QNetworkAccessManager::Operation &op);
253 
254  SubnetList _acSubnetWhitelist;
255 
256  std::vector<QString> _replicatedUsernames;
257 
258  DomainGatekeeper _gatekeeper;
259  DomainServerExporter _exporter;
260 
261  HTTPManager _httpManager;
262  HTTPManager* _httpExporterManager { nullptr };
263  HTTPManager* _httpMetadataExporterManager { nullptr };
264 
265  std::unique_ptr<HTTPSManager> _httpsManager;
266 
267  QHash<QUuid, SharedAssignmentPointer> _allAssignments;
268  QQueue<SharedAssignmentPointer> _unfulfilledAssignments;
269 
270  bool _isUsingDTLS { false };
271 
272  bool _oauthEnable { false };
273  QUrl _oauthProviderURL;
274  QString _oauthClientID;
275  QString _oauthClientSecret;
276  QString _hostname;
277 
278  std::unordered_map<QUuid, QByteArray> _ephemeralACScripts;
279 
280  QSet<QUuid> _webAuthenticationStateSet;
281  QHash<QUuid, DomainServerWebSessionData> _cookieSessionHash;
282 
283  QString _automaticNetworkingSetting;
284 
285  DomainServerSettingsManager _settingsManager;
286 
287  SockAddr _iceServerSocket;
288  std::unique_ptr<NLPacket> _iceServerHeartbeatPacket;
289 
290  // These will be parented to this, they are not dangling
291  DomainMetadata* _metadata { nullptr };
292  QTimer* _iceHeartbeatTimer { nullptr };
293  QTimer* _metaverseHeartbeatTimer { nullptr };
294  QTimer* _metaverseGroupCacheTimer { nullptr };
295  QTimer* _nodePingMonitorTimer { nullptr };
296 
297  QList<QHostAddress> _iceServerAddresses;
298  QSet<QHostAddress> _failedIceServerAddresses;
299  int _iceAddressLookupID { INVALID_ICE_LOOKUP_ID };
300  int _noReplyICEHeartbeats { 0 };
301  int _numHeartbeatDenials { 0 };
302  bool _connectedToICEServer { false };
303 
304  DomainType _type { DomainType::NonMetaverse };
305 
306  friend class DomainGatekeeper;
307  friend class DomainMetadata;
308 
309  static QString _iceServerAddr;
310  static int _iceServerPort;
311  static bool _overrideDomainID; // should we override the domain-id from settings?
312  static QUuid _overridingDomainID; // what should we override it with?
313  static bool _getTempName;
314  static QString _userConfigFilename;
315  static int _parentPID;
316  static bool _forceCrashReporting;
317 
318 
319  bool _sendICEServerAddressToMetaverseAPIInProgress { false };
320  bool _sendICEServerAddressToMetaverseAPIRedo { false };
321 
322  std::unique_ptr<DomainContentBackupManager> _contentManager { nullptr };
323 
324  QHash<QUuid, QPointer<HTTPSConnection>> _pendingOAuthConnections;
325 
326  std::unordered_map<int, QByteArray> _pendingUploadedContents;
327  std::unordered_map<int, std::unique_ptr<QTemporaryFile>> _pendingContentFiles;
328 
329  QThread _assetClientThread;
330 
331 #if defined(WEBRTC_DATA_CHANNELS)
332  std::unique_ptr<WebRTCSignalingServer> _webrtcSignalingServer { nullptr };
333 #endif
334 };
335 
336 
337 #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