// // DomainServer.h // domain-server/src // // Created by Stephen Birarda on 9/26/13. // Copyright 2013 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #ifndef hifi_DomainServer_h #define hifi_DomainServer_h #include #include #include #include #include #include #include #include #include #include #include #include "DomainGatekeeper.h" #include "DomainServerSettingsManager.h" #include "DomainServerWebSessionData.h" #include "WalletTransaction.h" #include "PendingAssignedNodeData.h" typedef QSharedPointer SharedAssignmentPointer; typedef QMultiHash TransactionHash; class DomainServer : public QCoreApplication, public HTTPSRequestHandler { Q_OBJECT public: DomainServer(int argc, char* argv[]); ~DomainServer(); static int const EXIT_CODE_REBOOT; bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url, bool skipSubHandler = false); bool handleHTTPSRequest(HTTPSConnection* connection, const QUrl& url, bool skipSubHandler = false); public slots: /// Called by NodeList to inform us a node has been added void nodeAdded(SharedNodePointer node); /// Called by NodeList to inform us a node has been killed void nodeKilled(SharedNodePointer node); void transactionJSONCallback(const QJsonObject& data); void restart(); void processRequestAssignmentPacket(QSharedPointer packet); void processListRequestPacket(QSharedPointer packet, SharedNodePointer sendingNode); void processNodeJSONStatsPacket(QSharedPointer packetList, SharedNodePointer sendingNode); void processPathQueryPacket(QSharedPointer packet); void processNodeDisconnectRequestPacket(QSharedPointer message); void processICEServerHeartbeatDenialPacket(QSharedPointer message); void processICEServerHeartbeatACK(QSharedPointer message); private slots: void aboutToQuit(); void setupPendingAssignmentCredits(); void sendPendingTransactionsToServer(); void performIPAddressUpdate(const HifiSockAddr& newPublicSockAddr); void sendHeartbeatToDataServer() { sendHeartbeatToDataServer(QString()); } void sendHeartbeatToIceServer(); void handleConnectedNode(SharedNodePointer newNode); void handleTempDomainSuccess(QNetworkReply& requestReply); void handleTempDomainError(QNetworkReply& requestReply); void queuedQuit(QString quitMessage, int exitCode); void handleKeypairChange(); void updateICEServerAddresses(); void handleICEHostInfo(const QHostInfo& hostInfo); signals: void iceServerChanged(); private: void setupNodeListAndAssignments(const QUuid& sessionUUID = QUuid::createUuid()); bool optionallySetupOAuth(); bool optionallyReadX509KeyAndCertificate(); void optionallyGetTemporaryName(const QStringList& arguments); bool resetAccountManagerAccessToken(); void setupAutomaticNetworking(); void setupICEHeartbeatForFullNetworking(); void sendHeartbeatToDataServer(const QString& networkAddress); void randomizeICEServerAddress(); unsigned int countConnectedUsers(); void sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr& senderSockAddr); QUuid connectionSecretForNodes(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB); void broadcastNewNode(const SharedNodePointer& node); void parseAssignmentConfigs(QSet& excludedTypes); void addStaticAssignmentToAssignmentHash(Assignment* newAssignment); void createStaticAssignmentsForType(Assignment::Type type, const QVariantList& configList); void populateDefaultStaticAssignmentsExcludingTypes(const QSet& excludedTypes); void populateStaticScriptedAssignmentsFromSettings(); SharedAssignmentPointer dequeueMatchingAssignment(const QUuid& checkInUUID, NodeType_t nodeType); SharedAssignmentPointer deployableAssignmentForRequest(const Assignment& requestAssignment); void refreshStaticAssignmentAndAddToQueue(SharedAssignmentPointer& assignment); void addStaticAssignmentsToQueue(); QUrl oauthRedirectURL(); QUrl oauthAuthorizationURL(const QUuid& stateUUID = QUuid::createUuid()); bool isAuthenticatedRequest(HTTPConnection* connection, const QUrl& url); void handleTokenRequestFinished(); QNetworkReply* profileRequestGivenTokenReply(QNetworkReply* tokenReply); void handleProfileRequestFinished(); Headers setupCookieHeadersFromProfileReply(QNetworkReply* profileReply); void loadExistingSessionsFromSettings(); QJsonObject jsonForSocket(const HifiSockAddr& socket); QJsonObject jsonObjectForNode(const SharedNodePointer& node); DomainGatekeeper _gatekeeper; HTTPManager _httpManager; HTTPSManager* _httpsManager; QHash _allAssignments; QQueue _unfulfilledAssignments; TransactionHash _pendingAssignmentCredits; bool _isUsingDTLS; QUrl _oauthProviderURL; QString _oauthClientID; QString _oauthClientSecret; QString _hostname; std::unordered_map _ephemeralACScripts; QSet _webAuthenticationStateSet; QHash _cookieSessionHash; QString _automaticNetworkingSetting; DomainServerSettingsManager _settingsManager; HifiSockAddr _iceServerSocket; std::unique_ptr _iceServerHeartbeatPacket; QTimer* _iceHeartbeatTimer { nullptr }; // this looks like it dangles when created but it's parented to the DomainServer QList _iceServerAddresses; QSet _failedIceServerAddresses; QTimer* _iceAddressLookupTimer { nullptr }; // this looks like a dangling pointer but is parented to the DomainServer int _iceAddressLookupID { -1 }; int _noReplyICEHeartbeats { 0 }; friend class DomainGatekeeper; }; #endif // hifi_DomainServer_h