13 #ifndef hifi_DomainHandler_h
14 #define hifi_DomainHandler_h
16 #include <QProcessEnvironment>
18 #include <QtCore/QJsonObject>
19 #include <QtCore/QObject>
20 #include <QtCore/QSharedPointer>
21 #include <QtCore/QTimer>
22 #include <QtCore/QUuid>
23 #include <QtCore/QUrl>
24 #include <QtNetwork/QHostInfo>
26 #include <shared/ReadWriteLockable.h>
27 #include <SettingHandle.h>
30 #include "NetworkPeer.h"
32 #include "NLPacketList.h"
34 #include "ReceivedMessage.h"
35 #include "NetworkingConstants.h"
36 #include "MetaverseAPI.h"
38 const unsigned short DEFAULT_DOMAIN_SERVER_PORT =
39 QProcessEnvironment::systemEnvironment()
40 .contains(
"HIFI_DOMAIN_SERVER_PORT")
41 ? QProcessEnvironment::systemEnvironment()
42 .value(
"HIFI_DOMAIN_SERVER_PORT")
46 const unsigned short DEFAULT_DOMAIN_SERVER_WS_PORT =
47 QProcessEnvironment::systemEnvironment()
48 .contains(
"OVERTE_DOMAIN_SERVER_WS_PORT")
49 ? QProcessEnvironment::systemEnvironment()
50 .value(
"OVERTE_DOMAIN_SERVER_WS_PORT")
54 const unsigned short DEFAULT_DOMAIN_SERVER_DTLS_PORT =
55 QProcessEnvironment::systemEnvironment()
56 .contains(
"HIFI_DOMAIN_SERVER_DTLS_PORT")
57 ? QProcessEnvironment::systemEnvironment()
58 .value(
"HIFI_DOMAIN_SERVER_DTLS_PORT")
62 const quint16 DOMAIN_SERVER_HTTP_PORT =
63 QProcessEnvironment::systemEnvironment()
64 .contains(
"HIFI_DOMAIN_SERVER_HTTP_PORT")
65 ? QProcessEnvironment::systemEnvironment()
66 .value(
"HIFI_DOMAIN_SERVER_HTTP_PORT")
70 const quint16 DOMAIN_SERVER_HTTPS_PORT =
71 QProcessEnvironment::systemEnvironment()
72 .contains(
"HIFI_DOMAIN_SERVER_HTTPS_PORT")
73 ? QProcessEnvironment::systemEnvironment()
74 .value(
"HIFI_DOMAIN_SERVER_HTTPS_PORT")
78 const quint16 DOMAIN_SERVER_EXPORTER_PORT =
79 QProcessEnvironment::systemEnvironment()
80 .contains(
"OVERTE_DOMAIN_SERVER_EXPORTER_PORT")
81 ? QProcessEnvironment::systemEnvironment()
82 .value(
"OVERTE_DOMAIN_SERVER_EXPORTER_PORT")
86 const quint16 DOMAIN_SERVER_METADATA_EXPORTER_PORT =
87 QProcessEnvironment::systemEnvironment()
88 .contains(
"OVERTE_DOMAIN_SERVER_METADATA_EXPORTER_PORT")
89 ? QProcessEnvironment::systemEnvironment()
90 .value(
"OVERTE_DOMAIN_SERVER_METADATA_EXPORTER_PORT")
94 const int MAX_SILENT_DOMAIN_SERVER_CHECK_INS = 5;
96 class DomainHandler :
public QObject {
99 DomainHandler(QObject* parent = 0);
101 void disconnect(QString reason);
102 void clearSettings();
104 const QUuid& getUUID()
const {
return _uuid; }
105 void setUUID(
const QUuid& uuid);
107 Node::LocalID getLocalID()
const {
return _localID; }
108 void setLocalID(Node::LocalID localID) { _localID = localID; }
110 QString getScheme()
const {
return _domainURL.scheme(); }
111 QString getHostname()
const {
return _domainURL.host(); }
113 QUrl getErrorDomainURL(){
return _errorDomainURL; }
114 void setErrorDomainURL(
const QUrl& url);
116 int getLastDomainConnectionError() {
return _lastDomainConnectionError; }
118 const QHostAddress& getIP()
const {
return _sockAddr.getAddress(); }
119 void setIPToLocalhost() { _sockAddr.setAddress(QHostAddress(QHostAddress::LocalHost)); }
121 const SockAddr& getSockAddr()
const {
return _sockAddr; }
122 void setSockAddr(
const SockAddr& sockAddr,
const QString& hostname);
124 unsigned short getPort()
const {
return _sockAddr.getPort(); }
125 void setPort(quint16 port) { _sockAddr.setPort(port); }
127 const QUuid& getConnectionToken()
const {
return _connectionToken; }
128 void setConnectionToken(
const QUuid& connectionToken) { _connectionToken = connectionToken; }
130 const QUuid& getAssignmentUUID()
const {
return _assignmentUUID; }
131 void setAssignmentUUID(
const QUuid& assignmentUUID) { _assignmentUUID = assignmentUUID; }
133 const QUuid& getPendingDomainID()
const {
return _pendingDomainID; }
135 const QUuid& getICEClientID()
const {
return _iceClientID; }
137 bool requiresICE()
const {
return !_iceServerSockAddr.isNull(); }
138 const SockAddr& getICEServerSockAddr()
const {
return _iceServerSockAddr; }
139 NetworkPeer& getICEPeer() {
return _icePeer; }
140 void activateICELocalSocket();
141 void activateICEPublicSocket();
143 bool isConnected()
const {
return _isConnected; }
144 void setIsConnected(
bool isConnected);
146 void setCanConnectWithoutAvatarEntities(
bool canConnect);
147 bool canConnectWithoutAvatarEntities();
149 bool isServerless()
const {
return _domainURL.scheme() != URL_SCHEME_OVERTE; }
150 bool getInterstitialModeEnabled()
const;
151 void setInterstitialModeEnabled(
bool enableInterstitialMode);
153 void connectedToServerless(std::map<QString, QString> namedPaths);
155 void loadedErrorDomain(std::map<QString, QString> namedPaths);
157 QString getViewPointFromNamedPath(QString namedPath);
159 bool hasSettings()
const {
return !_settingsObject.isEmpty(); }
160 void requestDomainSettings();
161 const QJsonObject& getSettingsObject()
const {
return _settingsObject; }
163 void setPendingPath(
const QString& pendingPath) { _pendingPath = pendingPath; }
164 const QString& getPendingPath() {
return _pendingPath; }
165 void clearPendingPath() { _pendingPath.clear(); }
167 bool isSocketKnown()
const {
return !_sockAddr.getAddress().isNull(); }
169 void softReset(QString reason);
171 int getCheckInPacketsSinceLastReply()
const {
return _checkInPacketsSinceLastReply; }
172 bool checkInPacketTimeout();
173 void clearPendingCheckins() { _checkInPacketsSinceLastReply = 0; }
175 void resetConfirmConnectWithoutAvatarEntities() {
176 _haveAskedConnectWithoutAvatarEntities =
false;
234 enum class ConnectionRefusedReason : uint8_t {
238 NotAuthorizedMetaverse,
246 void setURLAndID(QUrl domainURL, QUuid domainID);
247 void setIceServerHostnameAndID(
const QString& iceServerHostname,
const QUuid&
id);
249 void processSettingsPacketList(QSharedPointer<ReceivedMessage> packetList);
250 void processICEPingReplyPacket(QSharedPointer<ReceivedMessage> message);
251 void processDTLSRequirementPacket(QSharedPointer<ReceivedMessage> dtlsRequirementPacket);
252 void processICEResponsePacket(QSharedPointer<ReceivedMessage> icePacket);
253 void processDomainServerConnectionDeniedPacket(QSharedPointer<ReceivedMessage> message);
256 void setRedirectErrorState(QUrl errorUrl, QString reasonMessage =
"",
int reasonCode = -1,
const QString& extraInfo =
"");
258 bool isInErrorState() {
return _isInErrorState; }
261 void completedHostnameLookup(
const QHostInfo& hostInfo);
262 void completedIceServerHostnameLookup();
265 void domainURLChanged(QUrl domainURL);
269 void completedSocketDiscovery();
272 void confirmConnectWithoutAvatarEntities();
273 void connectedToDomain(QUrl domainURL);
274 void disconnectedFromDomain();
276 void iceSocketAndIDReceived();
277 void icePeerSocketsReceived();
279 void settingsReceived(
const QJsonObject& domainSettingsObject);
280 void settingsReceiveFail();
282 void domainConnectionRefused(QString reasonMessage,
int reasonCode,
const QString& extraInfo);
283 void redirectToErrorDomainURL(QUrl errorDomainURL);
284 void redirectErrorStateChanged(
bool isInErrorState);
286 void limitOfSilentDomainCheckInsReached();
289 bool reasonSuggestsMetaverseLogin(ConnectionRefusedReason reasonCode);
290 bool reasonSuggestsDomainLogin(ConnectionRefusedReason reasonCode);
291 void sendDisconnectPacket();
292 void hardReset(QString reason);
294 bool isHardRefusal(
int reasonCode);
297 Node::LocalID _localID;
299 QUrl _errorDomainURL;
301 QUuid _assignmentUUID;
302 QUuid _connectionToken;
303 QUuid _pendingDomainID;
305 SockAddr _iceServerSockAddr;
306 NetworkPeer _icePeer;
307 bool _isConnected {
false };
308 bool _haveAskedConnectWithoutAvatarEntities {
false };
309 bool _canConnectWithoutAvatarEntities {
false };
310 bool _isInErrorState {
false };
311 QJsonObject _settingsObject;
312 QString _pendingPath;
313 QTimer _settingsTimer;
314 mutable ReadWriteLockable _interstitialModeSettingLock;
321 QSet<QString> _domainConnectionRefusals;
322 bool _hasCheckedForAccessToken {
false };
323 bool _hasCheckedForDomainAccessToken {
false };
324 int _connectionDenialsSinceKeypairRegen { 0 };
325 int _checkInPacketsSinceLastReply { 0 };
327 QTimer _apiRefreshTimer;
329 std::map<QString, QString> _namedPaths;
332 int _lastDomainConnectionError{ -1 };
335 const QString DOMAIN_SPAWNING_POINT {
"/0, -10, 0" };
336 const QString DEFAULT_NAMED_PATH {
"/" };
@ Unknown
Socket type unknown or not set.