mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-08 15:43:17 +02:00
Merge pull request #8031 from birarda/api-recheck-on-fail
re-instate domain API connection info refresh during failure, fix localhost connection after downgrade
This commit is contained in:
commit
006eb8fe64
15 changed files with 145 additions and 89 deletions
|
@ -62,10 +62,7 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
|
|||
|
||||
QByteArray myProtocolVersion = protocolVersionsSignature();
|
||||
if (nodeConnection.protocolVersion != myProtocolVersion) {
|
||||
QString protocolVersionError = "Protocol version mismatch - Domain version:" + QCoreApplication::applicationVersion();
|
||||
qDebug() << "Protocol Version mismatch - denying connection.";
|
||||
sendConnectionDeniedPacket(protocolVersionError, message->getSenderSockAddr(),
|
||||
DomainHandler::ConnectionRefusedReason::ProtocolMismatch);
|
||||
sendProtocolMismatchConnectionDenial(message->getSenderSockAddr());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -530,15 +527,24 @@ void DomainGatekeeper::publicKeyJSONCallback(QNetworkReply& requestReply) {
|
|||
}
|
||||
}
|
||||
|
||||
void DomainGatekeeper::sendProtocolMismatchConnectionDenial(const HifiSockAddr& senderSockAddr) {
|
||||
QString protocolVersionError = "Protocol version mismatch - Domain version: " + QCoreApplication::applicationVersion();
|
||||
|
||||
qDebug() << "Protocol Version mismatch - denying connection.";
|
||||
|
||||
sendConnectionDeniedPacket(protocolVersionError, senderSockAddr,
|
||||
DomainHandler::ConnectionRefusedReason::ProtocolMismatch);
|
||||
}
|
||||
|
||||
void DomainGatekeeper::sendConnectionDeniedPacket(const QString& reason, const HifiSockAddr& senderSockAddr,
|
||||
DomainHandler::ConnectionRefusedReason reasonCode) {
|
||||
DomainHandler::ConnectionRefusedReason reasonCode) {
|
||||
// this is an agent and we've decided we won't let them connect - send them a packet to deny connection
|
||||
QByteArray utfString = reason.toUtf8();
|
||||
quint16 payloadSize = utfString.size();
|
||||
|
||||
// setup the DomainConnectionDenied packet
|
||||
auto connectionDeniedPacket = NLPacket::create(PacketType::DomainConnectionDenied,
|
||||
payloadSize + sizeof(payloadSize) + sizeof(uint8_t));
|
||||
payloadSize + sizeof(payloadSize) + sizeof(uint8_t));
|
||||
|
||||
// pack in the reason the connection was denied (the client displays this)
|
||||
if (payloadSize > 0) {
|
||||
|
|
|
@ -42,6 +42,8 @@ public:
|
|||
void preloadAllowedUserPublicKeys();
|
||||
|
||||
void removeICEPeer(const QUuid& peerUUID) { _icePeers.remove(peerUUID); }
|
||||
|
||||
static void sendProtocolMismatchConnectionDenial(const HifiSockAddr& senderSockAddr);
|
||||
public slots:
|
||||
void processConnectRequestPacket(QSharedPointer<ReceivedMessage> message);
|
||||
void processICEPingPacket(QSharedPointer<ReceivedMessage> message);
|
||||
|
@ -76,8 +78,8 @@ private:
|
|||
const HifiSockAddr& senderSockAddr);
|
||||
|
||||
void sendConnectionTokenPacket(const QString& username, const HifiSockAddr& senderSockAddr);
|
||||
void sendConnectionDeniedPacket(const QString& reason, const HifiSockAddr& senderSockAddr,
|
||||
DomainHandler::ConnectionRefusedReason reasonCode = DomainHandler::ConnectionRefusedReason::Unknown);
|
||||
static void sendConnectionDeniedPacket(const QString& reason, const HifiSockAddr& senderSockAddr,
|
||||
DomainHandler::ConnectionRefusedReason reasonCode = DomainHandler::ConnectionRefusedReason::Unknown);
|
||||
|
||||
void pingPunchForConnectingPeer(const SharedNetworkPeer& peer);
|
||||
|
||||
|
|
|
@ -318,16 +318,11 @@ bool DomainServer::packetVersionMatch(const udt::Packet& packet) {
|
|||
|
||||
auto nodeList = DependencyManager::get<LimitedNodeList>();
|
||||
|
||||
// This implements a special case that handles OLD clients which don't know how to negotiate matching
|
||||
// protocol versions. We know these clients will sent DomainConnectRequest with older versions. We also
|
||||
// know these clients will show a warning dialog if they get an EntityData with a protocol version they
|
||||
// don't understand, so we can send them an empty EntityData with our latest version and they will
|
||||
// warn the user that the protocol is not compatible
|
||||
if (headerType == PacketType::DomainConnectRequest &&
|
||||
headerVersion < static_cast<PacketVersion>(DomainConnectRequestVersion::HasProtocolVersions)) {
|
||||
auto packetWithBadVersion = NLPacket::create(PacketType::EntityData);
|
||||
nodeList->sendPacket(std::move(packetWithBadVersion), packet.getSenderSockAddr());
|
||||
return false;
|
||||
// if this is a mismatching connect packet, we can't simply drop it on the floor
|
||||
// send back a packet to the interface that tells them we refuse connection for a mismatch
|
||||
if (headerType == PacketType::DomainConnectRequest
|
||||
&& headerVersion != versionForPacketType(PacketType::DomainConnectRequest)) {
|
||||
DomainGatekeeper::sendProtocolMismatchConnectionDenial(packet.getSenderSockAddr());
|
||||
}
|
||||
|
||||
// let the normal nodeList implementation handle all other packets.
|
||||
|
|
|
@ -630,7 +630,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
connect(&domainHandler, SIGNAL(connectedToDomain(const QString&)), SLOT(updateWindowTitle()));
|
||||
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(updateWindowTitle()));
|
||||
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(clearDomainOctreeDetails()));
|
||||
connect(&domainHandler, &DomainHandler::resetting, nodeList.data(), &NodeList::resetDomainServerCheckInVersion);
|
||||
connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &Application::domainConnectionRefused);
|
||||
|
||||
// update our location every 5 seconds in the metaverse server, assuming that we are authenticated with one
|
||||
|
@ -654,9 +653,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
connect(nodeList.data(), &NodeList::nodeActivated, this, &Application::nodeActivated);
|
||||
connect(nodeList.data(), &NodeList::uuidChanged, getMyAvatar(), &MyAvatar::setSessionUUID);
|
||||
connect(nodeList.data(), &NodeList::uuidChanged, this, &Application::setSessionUUID);
|
||||
connect(nodeList.data(), &NodeList::limitOfSilentDomainCheckInsReached, this, &Application::limitOfSilentDomainCheckInsReached);
|
||||
connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch);
|
||||
|
||||
// you might think we could just do this in NodeList but we only want this connection for Interface
|
||||
connect(nodeList.data(), &NodeList::limitOfSilentDomainCheckInsReached, nodeList.data(), &NodeList::reset);
|
||||
|
||||
// connect to appropriate slots on AccountManager
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
|
||||
|
@ -1074,8 +1075,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
void Application::domainConnectionRefused(const QString& reasonMessage, int reasonCode) {
|
||||
switch (static_cast<DomainHandler::ConnectionRefusedReason>(reasonCode)) {
|
||||
case DomainHandler::ConnectionRefusedReason::ProtocolMismatch:
|
||||
notifyPacketVersionMismatch();
|
||||
break;
|
||||
case DomainHandler::ConnectionRefusedReason::TooManyUsers:
|
||||
case DomainHandler::ConnectionRefusedReason::Unknown: {
|
||||
QString message = "Unable to connect to the location you are visiting.\n";
|
||||
|
@ -4619,17 +4618,6 @@ void Application::setSessionUUID(const QUuid& sessionUUID) const {
|
|||
Physics::setSessionUUID(sessionUUID);
|
||||
}
|
||||
|
||||
|
||||
// If we're not getting anything back from the domain server checkin, it might be that the domain speaks an
|
||||
// older version of the DomainConnectRequest protocol. We will attempt to send and older version of DomainConnectRequest.
|
||||
// We won't actually complete the connection, but if the server responds, we know that it needs to be upgraded (or we
|
||||
// need to be downgraded to talk to it).
|
||||
void Application::limitOfSilentDomainCheckInsReached() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
nodeList->downgradeDomainServerCheckInVersion(); // attempt to use an older domain checkin version
|
||||
nodeList->reset();
|
||||
}
|
||||
|
||||
bool Application::askToSetAvatarUrl(const QString& url) {
|
||||
QUrl realUrl(url);
|
||||
if (realUrl.isLocalFile()) {
|
||||
|
|
|
@ -318,7 +318,6 @@ private slots:
|
|||
bool displayAvatarAttachmentConfirmationDialog(const QString& name) const;
|
||||
|
||||
void setSessionUUID(const QUuid& sessionUUID) const;
|
||||
void limitOfSilentDomainCheckInsReached();
|
||||
|
||||
void domainChanged(const QString& domainHostname);
|
||||
void updateWindowTitle() const;
|
||||
|
|
|
@ -542,6 +542,9 @@ Menu::Menu() {
|
|||
#if (PR_BUILD || DEV_BUILD)
|
||||
addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::SendWrongProtocolVersion, 0, false,
|
||||
qApp, SLOT(sendWrongProtocolVersionsSignature(bool)));
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::SendWrongDSConnectVersion, 0, false,
|
||||
nodeList.data(), SLOT(toggleSendNewerDSConnectVersion(bool)));
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -166,6 +166,7 @@ namespace MenuOption {
|
|||
const QString RunTimingTests = "Run Timing Tests";
|
||||
const QString ScriptEditor = "Script Editor...";
|
||||
const QString ScriptedMotorControl = "Enable Scripted Motor Control";
|
||||
const QString SendWrongDSConnectVersion = "Send wrong DS connect version";
|
||||
const QString SendWrongProtocolVersion = "Send wrong protocol version";
|
||||
const QString SetHomeLocation = "Set Home Location";
|
||||
const QString ShowDSConnectTable = "Show Domain Connection Timing";
|
||||
|
|
|
@ -144,12 +144,21 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) {
|
|||
// 4. domain network address (IP or dns resolvable hostname)
|
||||
|
||||
// use our regex'ed helpers to figure out what we're supposed to do with this
|
||||
if (!handleUsername(lookupUrl.authority())) {
|
||||
if (handleUsername(lookupUrl.authority())) {
|
||||
// handled a username for lookup
|
||||
|
||||
// in case we're failing to connect to where we thought this user was
|
||||
// store their username as previous lookup so we can refresh their location via API
|
||||
_previousLookup = lookupUrl;
|
||||
} else {
|
||||
// we're assuming this is either a network address or global place name
|
||||
// check if it is a network address first
|
||||
bool hostChanged;
|
||||
if (handleNetworkAddress(lookupUrl.host()
|
||||
+ (lookupUrl.port() == -1 ? "" : ":" + QString::number(lookupUrl.port())), trigger, hostChanged)) {
|
||||
+ (lookupUrl.port() == -1 ? "" : ":" + QString::number(lookupUrl.port())), trigger, hostChanged)) {
|
||||
|
||||
// a network address lookup clears the previous lookup since we don't expect to re-attempt it
|
||||
_previousLookup.clear();
|
||||
|
||||
// If the host changed then we have already saved to history
|
||||
if (hostChanged) {
|
||||
|
@ -165,10 +174,16 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) {
|
|||
// we may have a path that defines a relative viewpoint - if so we should jump to that now
|
||||
handlePath(path, trigger);
|
||||
} else if (handleDomainID(lookupUrl.host())){
|
||||
// store this domain ID as the previous lookup in case we're failing to connect and want to refresh API info
|
||||
_previousLookup = lookupUrl;
|
||||
|
||||
// no place name - this is probably a domain ID
|
||||
// try to look up the domain ID on the metaverse API
|
||||
attemptDomainIDLookup(lookupUrl.host(), lookupUrl.path(), trigger);
|
||||
} else {
|
||||
// store this place name as the previous lookup in case we fail to connect and want to refresh API info
|
||||
_previousLookup = lookupUrl;
|
||||
|
||||
// wasn't an address - lookup the place name
|
||||
// we may have a path that defines a relative viewpoint - pass that through the lookup so we can go to it after
|
||||
attemptPlaceNameLookup(lookupUrl.host(), lookupUrl.path(), trigger);
|
||||
|
@ -180,9 +195,13 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) {
|
|||
} else if (lookupUrl.toString().startsWith('/')) {
|
||||
qCDebug(networking) << "Going to relative path" << lookupUrl.path();
|
||||
|
||||
// a path lookup clears the previous lookup since we don't expect to re-attempt it
|
||||
_previousLookup.clear();
|
||||
|
||||
// if this is a relative path then handle it as a relative viewpoint
|
||||
handlePath(lookupUrl.path(), trigger, true);
|
||||
emit lookupResultsFinished();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -276,7 +295,7 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject, const
|
|||
|
||||
qCDebug(networking) << "Possible domain change required to connect to" << domainHostname
|
||||
<< "on" << domainPort;
|
||||
emit possibleDomainChangeRequired(domainHostname, domainPort);
|
||||
emit possibleDomainChangeRequired(domainHostname, domainPort, domainID);
|
||||
} else {
|
||||
QString iceServerAddress = domainObject[DOMAIN_ICE_SERVER_ADDRESS_KEY].toString();
|
||||
|
||||
|
@ -315,7 +334,10 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject, const
|
|||
QString overridePath = reply.property(OVERRIDE_PATH_KEY).toString();
|
||||
|
||||
if (!overridePath.isEmpty()) {
|
||||
handlePath(overridePath, trigger);
|
||||
// make sure we don't re-handle an overriden path if this was a refresh of info from API
|
||||
if (trigger != LookupTrigger::AttemptedRefresh) {
|
||||
handlePath(overridePath, trigger);
|
||||
}
|
||||
} else {
|
||||
// take the path that came back
|
||||
const QString PLACE_PATH_KEY = "path";
|
||||
|
@ -362,7 +384,7 @@ void AddressManager::handleAPIError(QNetworkReply& errorReply) {
|
|||
|
||||
if (errorReply.error() == QNetworkReply::ContentNotFoundError) {
|
||||
// if this is a lookup that has no result, don't keep re-trying it
|
||||
//_previousLookup.clear();
|
||||
_previousLookup.clear();
|
||||
|
||||
emit lookupResultIsNotFound();
|
||||
}
|
||||
|
@ -598,7 +620,7 @@ bool AddressManager::setDomainInfo(const QString& hostname, quint16 port, Lookup
|
|||
|
||||
DependencyManager::get<NodeList>()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::HandleAddress);
|
||||
|
||||
emit possibleDomainChangeRequired(hostname, port);
|
||||
emit possibleDomainChangeRequired(hostname, port, QUuid());
|
||||
|
||||
return hostChanged;
|
||||
}
|
||||
|
@ -618,6 +640,13 @@ void AddressManager::goToUser(const QString& username) {
|
|||
QByteArray(), nullptr, requestParams);
|
||||
}
|
||||
|
||||
void AddressManager::refreshPreviousLookup() {
|
||||
// if we have a non-empty previous lookup, fire it again now (but don't re-store it in the history)
|
||||
if (!_previousLookup.isEmpty()) {
|
||||
handleUrl(_previousLookup, LookupTrigger::AttemptedRefresh);
|
||||
}
|
||||
}
|
||||
|
||||
void AddressManager::copyAddress() {
|
||||
QApplication::clipboard()->setText(currentAddress().toString());
|
||||
}
|
||||
|
@ -629,7 +658,10 @@ void AddressManager::copyPath() {
|
|||
void AddressManager::addCurrentAddressToHistory(LookupTrigger trigger) {
|
||||
|
||||
// if we're cold starting and this is called for the first address (from settings) we don't do anything
|
||||
if (trigger != LookupTrigger::StartupFromSettings && trigger != LookupTrigger::DomainPathResponse) {
|
||||
if (trigger != LookupTrigger::StartupFromSettings
|
||||
&& trigger != LookupTrigger::DomainPathResponse
|
||||
&& trigger != LookupTrigger::AttemptedRefresh) {
|
||||
|
||||
if (trigger == LookupTrigger::Back) {
|
||||
// we're about to push to the forward stack
|
||||
// if it's currently empty emit our signal to say that going forward is now possible
|
||||
|
|
|
@ -48,7 +48,8 @@ public:
|
|||
Forward,
|
||||
StartupFromSettings,
|
||||
DomainPathResponse,
|
||||
Internal
|
||||
Internal,
|
||||
AttemptedRefresh
|
||||
};
|
||||
|
||||
bool isConnected();
|
||||
|
@ -89,6 +90,8 @@ public slots:
|
|||
|
||||
void goToUser(const QString& username);
|
||||
|
||||
void refreshPreviousLookup();
|
||||
|
||||
void storeCurrentAddress();
|
||||
|
||||
void copyAddress();
|
||||
|
@ -99,7 +102,7 @@ signals:
|
|||
void lookupResultIsOffline();
|
||||
void lookupResultIsNotFound();
|
||||
|
||||
void possibleDomainChangeRequired(const QString& newHostname, quint16 newPort);
|
||||
void possibleDomainChangeRequired(const QString& newHostname, quint16 newPort, const QUuid& domainID);
|
||||
void possibleDomainChangeRequiredViaICEForID(const QString& iceServerHostname, const QUuid& domainID);
|
||||
|
||||
void locationChangeRequired(const glm::vec3& newPosition,
|
||||
|
@ -152,6 +155,8 @@ private:
|
|||
quint64 _lastBackPush = 0;
|
||||
|
||||
QString _newHostLookupPath;
|
||||
|
||||
QUrl _previousLookup;
|
||||
};
|
||||
|
||||
#endif // hifi_AddressManager_h
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QDataStream>
|
||||
|
||||
#include "AddressManager.h"
|
||||
#include "Assignment.h"
|
||||
#include "HifiSockAddr.h"
|
||||
#include "NodeList.h"
|
||||
|
@ -28,17 +29,10 @@
|
|||
|
||||
DomainHandler::DomainHandler(QObject* parent) :
|
||||
QObject(parent),
|
||||
_uuid(),
|
||||
_sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
|
||||
_assignmentUUID(),
|
||||
_connectionToken(),
|
||||
_iceDomainID(),
|
||||
_iceClientID(),
|
||||
_iceServerSockAddr(),
|
||||
_icePeer(this),
|
||||
_isConnected(false),
|
||||
_settingsObject(),
|
||||
_settingsTimer(this)
|
||||
_settingsTimer(this),
|
||||
_apiRefreshTimer(this)
|
||||
{
|
||||
_sockAddr.setObjectName("DomainServer");
|
||||
|
||||
|
@ -49,6 +43,16 @@ DomainHandler::DomainHandler(QObject* parent) :
|
|||
static const int DOMAIN_SETTINGS_TIMEOUT_MS = 5000;
|
||||
_settingsTimer.setInterval(DOMAIN_SETTINGS_TIMEOUT_MS);
|
||||
connect(&_settingsTimer, &QTimer::timeout, this, &DomainHandler::settingsReceiveFail);
|
||||
|
||||
// setup the API refresh timer for auto connection information refresh from API when failing to connect
|
||||
const int API_REFRESH_TIMEOUT_MSEC = 2500;
|
||||
_apiRefreshTimer.setInterval(API_REFRESH_TIMEOUT_MSEC);
|
||||
|
||||
auto addressManager = DependencyManager::get<AddressManager>();
|
||||
connect(&_apiRefreshTimer, &QTimer::timeout, addressManager.data(), &AddressManager::refreshPreviousLookup);
|
||||
|
||||
// stop the refresh timer if we connect to a domain
|
||||
connect(this, &DomainHandler::connectedToDomain, &_apiRefreshTimer, &QTimer::stop);
|
||||
}
|
||||
|
||||
void DomainHandler::disconnect() {
|
||||
|
@ -93,10 +97,14 @@ void DomainHandler::softReset() {
|
|||
|
||||
clearSettings();
|
||||
|
||||
_domainConnectionRefusals.clear();
|
||||
_connectionDenialsSinceKeypairRegen = 0;
|
||||
|
||||
// cancel the failure timeout for any pending requests for settings
|
||||
QMetaObject::invokeMethod(&_settingsTimer, "stop");
|
||||
|
||||
// restart the API refresh timer in case we fail to connect and need to refresh information
|
||||
QMetaObject::invokeMethod(&_apiRefreshTimer, "start");
|
||||
}
|
||||
|
||||
void DomainHandler::hardReset() {
|
||||
|
@ -105,7 +113,7 @@ void DomainHandler::hardReset() {
|
|||
softReset();
|
||||
|
||||
qCDebug(networking) << "Hard reset in NodeList DomainHandler.";
|
||||
_iceDomainID = QUuid();
|
||||
_pendingDomainID = QUuid();
|
||||
_iceServerSockAddr = HifiSockAddr();
|
||||
_hostname = QString();
|
||||
_sockAddr.clear();
|
||||
|
@ -139,7 +147,9 @@ void DomainHandler::setUUID(const QUuid& uuid) {
|
|||
}
|
||||
}
|
||||
|
||||
void DomainHandler::setHostnameAndPort(const QString& hostname, quint16 port) {
|
||||
void DomainHandler::setSocketAndID(const QString& hostname, quint16 port, const QUuid& domainID) {
|
||||
|
||||
_pendingDomainID = domainID;
|
||||
|
||||
if (hostname != _hostname || _sockAddr.getPort() != port) {
|
||||
// re-set the domain info so that auth information is reloaded
|
||||
|
@ -149,9 +159,6 @@ void DomainHandler::setHostnameAndPort(const QString& hostname, quint16 port) {
|
|||
// set the new hostname
|
||||
_hostname = hostname;
|
||||
|
||||
// FIXME - is this the right place???
|
||||
_domainConnectionRefusals.clear();
|
||||
|
||||
qCDebug(networking) << "Updated domain hostname to" << _hostname;
|
||||
|
||||
// re-set the sock addr to null and fire off a lookup of the IP address for this domain-server's hostname
|
||||
|
@ -174,14 +181,15 @@ void DomainHandler::setHostnameAndPort(const QString& hostname, quint16 port) {
|
|||
}
|
||||
|
||||
void DomainHandler::setIceServerHostnameAndID(const QString& iceServerHostname, const QUuid& id) {
|
||||
if (id != _uuid) {
|
||||
|
||||
if (_iceServerSockAddr.getAddress().toString() != iceServerHostname || id != _pendingDomainID) {
|
||||
// re-set the domain info to connect to new domain
|
||||
hardReset();
|
||||
|
||||
// refresh our ICE client UUID to something new
|
||||
_iceClientID = QUuid::createUuid();
|
||||
|
||||
_iceDomainID = id;
|
||||
_pendingDomainID = id;
|
||||
|
||||
HifiSockAddr* replaceableSockAddr = &_iceServerSockAddr;
|
||||
replaceableSockAddr->~HifiSockAddr();
|
||||
|
@ -255,6 +263,7 @@ void DomainHandler::setIsConnected(bool isConnected) {
|
|||
|
||||
// we've connected to new domain - time to ask it for global settings
|
||||
requestDomainSettings();
|
||||
|
||||
} else {
|
||||
emit disconnectedFromDomain();
|
||||
}
|
||||
|
@ -305,6 +314,9 @@ void DomainHandler::processICEPingReplyPacket(QSharedPointer<ReceivedMessage> me
|
|||
qCDebug(networking) << "Received reply from domain-server on" << senderSockAddr;
|
||||
|
||||
if (getIP().isNull()) {
|
||||
// we're hearing back from this domain-server, no need to refresh API information
|
||||
_apiRefreshTimer.stop();
|
||||
|
||||
// for now we're unsafely assuming this came back from the domain
|
||||
if (senderSockAddr == _icePeer.getLocalSocket()) {
|
||||
qCDebug(networking) << "Connecting to domain using local socket";
|
||||
|
@ -333,17 +345,20 @@ void DomainHandler::processDTLSRequirementPacket(QSharedPointer<ReceivedMessage>
|
|||
void DomainHandler::processICEResponsePacket(QSharedPointer<ReceivedMessage> message) {
|
||||
if (_icePeer.hasSockets()) {
|
||||
qDebug() << "Received an ICE peer packet for domain-server but we already have sockets. Not processing.";
|
||||
// bail on processing this packet if our ice peer doesn't have sockets
|
||||
// bail on processing this packet if our ice peer already has sockets
|
||||
return;
|
||||
}
|
||||
|
||||
// start or restart the API refresh timer now that we have new information
|
||||
_apiRefreshTimer.start();
|
||||
|
||||
QDataStream iceResponseStream(message->getMessage());
|
||||
|
||||
iceResponseStream >> _icePeer;
|
||||
|
||||
DependencyManager::get<NodeList>()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveDSPeerInformation);
|
||||
|
||||
if (_icePeer.getUUID() != _iceDomainID) {
|
||||
if (_icePeer.getUUID() != _pendingDomainID) {
|
||||
qCDebug(networking) << "Received a network peer with ID that does not match current domain. Will not attempt connection.";
|
||||
_icePeer.reset();
|
||||
} else {
|
||||
|
@ -373,6 +388,9 @@ bool DomainHandler::reasonSuggestsLogin(ConnectionRefusedReason reasonCode) {
|
|||
}
|
||||
|
||||
void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer<ReceivedMessage> message) {
|
||||
// we're hearing from this domain-server, don't need to refresh API info
|
||||
_apiRefreshTimer.stop();
|
||||
|
||||
// Read deny reason from packet
|
||||
uint8_t reasonCodeWire;
|
||||
|
||||
|
|
|
@ -58,8 +58,8 @@ public:
|
|||
|
||||
const QUuid& getAssignmentUUID() const { return _assignmentUUID; }
|
||||
void setAssignmentUUID(const QUuid& assignmentUUID) { _assignmentUUID = assignmentUUID; }
|
||||
|
||||
const QUuid& getICEDomainID() const { return _iceDomainID; }
|
||||
|
||||
const QUuid& getPendingDomainID() const { return _pendingDomainID; }
|
||||
|
||||
const QUuid& getICEClientID() const { return _iceClientID; }
|
||||
|
||||
|
@ -75,7 +75,6 @@ public:
|
|||
bool hasSettings() const { return !_settingsObject.isEmpty(); }
|
||||
void requestDomainSettings();
|
||||
const QJsonObject& getSettingsObject() const { return _settingsObject; }
|
||||
|
||||
|
||||
void setPendingPath(const QString& pendingPath) { _pendingPath = pendingPath; }
|
||||
const QString& getPendingPath() { return _pendingPath; }
|
||||
|
@ -94,7 +93,7 @@ public:
|
|||
};
|
||||
|
||||
public slots:
|
||||
void setHostnameAndPort(const QString& hostname, quint16 port = DEFAULT_DOMAIN_SERVER_PORT);
|
||||
void setSocketAndID(const QString& hostname, quint16 port = DEFAULT_DOMAIN_SERVER_PORT, const QUuid& id = QUuid());
|
||||
void setIceServerHostnameAndID(const QString& iceServerHostname, const QUuid& id);
|
||||
|
||||
void processSettingsPacketList(QSharedPointer<ReceivedMessage> packetList);
|
||||
|
@ -136,11 +135,11 @@ private:
|
|||
HifiSockAddr _sockAddr;
|
||||
QUuid _assignmentUUID;
|
||||
QUuid _connectionToken;
|
||||
QUuid _iceDomainID;
|
||||
QUuid _pendingDomainID; // ID of domain being connected to, via ICE or direct connection
|
||||
QUuid _iceClientID;
|
||||
HifiSockAddr _iceServerSockAddr;
|
||||
NetworkPeer _icePeer;
|
||||
bool _isConnected;
|
||||
bool _isConnected { false };
|
||||
QJsonObject _settingsObject;
|
||||
QString _pendingPath;
|
||||
QTimer _settingsTimer;
|
||||
|
@ -148,6 +147,8 @@ private:
|
|||
QStringList _domainConnectionRefusals;
|
||||
bool _hasCheckedForAccessToken { false };
|
||||
int _connectionDenialsSinceKeypairRegen { 0 };
|
||||
|
||||
QTimer _apiRefreshTimer;
|
||||
};
|
||||
|
||||
#endif // hifi_DomainHandler_h
|
||||
|
|
|
@ -184,6 +184,11 @@ void NLPacket::setType(PacketType type) {
|
|||
writeTypeAndVersion();
|
||||
}
|
||||
|
||||
void NLPacket::setVersion(PacketVersion version) {
|
||||
_version = version;
|
||||
writeTypeAndVersion();
|
||||
}
|
||||
|
||||
void NLPacket::readType() {
|
||||
_type = NLPacket::typeInHeader(*this);
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ public:
|
|||
void setType(PacketType type);
|
||||
|
||||
PacketVersion getVersion() const { return _version; }
|
||||
void setVersion(PacketVersion version);
|
||||
|
||||
const QUuid& getSourceID() const { return _sourceID; }
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned
|
|||
|
||||
// handle domain change signals from AddressManager
|
||||
connect(addressManager.data(), &AddressManager::possibleDomainChangeRequired,
|
||||
&_domainHandler, &DomainHandler::setHostnameAndPort);
|
||||
&_domainHandler, &DomainHandler::setSocketAndID);
|
||||
|
||||
connect(addressManager.data(), &AddressManager::possibleDomainChangeRequiredViaICEForID,
|
||||
&_domainHandler, &DomainHandler::setIceServerHostnameAndID);
|
||||
|
@ -250,7 +250,6 @@ void NodeList::sendDomainServerCheckIn() {
|
|||
qCDebug(networking) << "Waiting for ICE discovered domain-server socket. Will not send domain-server check in.";
|
||||
handleICEConnectionToDomainServer();
|
||||
} else if (!_domainHandler.getIP().isNull()) {
|
||||
bool isUsingDTLS = false;
|
||||
|
||||
PacketType domainPacketType = !_domainHandler.isConnected()
|
||||
? PacketType::DomainConnectRequest : PacketType::DomainListRequest;
|
||||
|
@ -292,12 +291,18 @@ void NodeList::sendDomainServerCheckIn() {
|
|||
return;
|
||||
}
|
||||
|
||||
auto packetVersion = (domainPacketType == PacketType::DomainConnectRequest) ? _domainConnectRequestVersion : 0;
|
||||
auto domainPacket = NLPacket::create(domainPacketType, -1, false, false, packetVersion);
|
||||
auto domainPacket = NLPacket::create(domainPacketType);
|
||||
|
||||
QDataStream packetStream(domainPacket.get());
|
||||
|
||||
if (domainPacketType == PacketType::DomainConnectRequest) {
|
||||
|
||||
#if (PR_BUILD || DEV_BUILD)
|
||||
if (_shouldSendNewerVersion) {
|
||||
domainPacket->setVersion(versionForPacketType(domainPacketType) + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
QUuid connectUUID;
|
||||
|
||||
if (!_domainHandler.getAssignmentUUID().isNull()) {
|
||||
|
@ -315,18 +320,14 @@ void NodeList::sendDomainServerCheckIn() {
|
|||
packetStream << connectUUID;
|
||||
|
||||
// include the protocol version signature in our connect request
|
||||
if (_domainConnectRequestVersion >= static_cast<PacketVersion>(DomainConnectRequestVersion::HasProtocolVersions)) {
|
||||
QByteArray protocolVersionSig = protocolVersionsSignature();
|
||||
packetStream.writeBytes(protocolVersionSig.constData(), protocolVersionSig.size());
|
||||
}
|
||||
QByteArray protocolVersionSig = protocolVersionsSignature();
|
||||
packetStream.writeBytes(protocolVersionSig.constData(), protocolVersionSig.size());
|
||||
}
|
||||
|
||||
// pack our data to send to the domain-server including
|
||||
// the hostname information (so the domain-server can see which place name we came in on)
|
||||
packetStream << _ownerType << _publicSockAddr << _localSockAddr << _nodeTypesOfInterest.toList();
|
||||
if (_domainConnectRequestVersion >= static_cast<PacketVersion>(DomainConnectRequestVersion::HasHostname)) {
|
||||
packetStream << DependencyManager::get<AddressManager>()->getPlaceName();
|
||||
}
|
||||
packetStream << DependencyManager::get<AddressManager>()->getPlaceName();
|
||||
|
||||
if (!_domainHandler.isConnected()) {
|
||||
DataServerAccountInfo& accountInfo = accountManager->getAccountInfo();
|
||||
|
@ -341,9 +342,7 @@ void NodeList::sendDomainServerCheckIn() {
|
|||
|
||||
flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::SendDSCheckIn);
|
||||
|
||||
if (!isUsingDTLS) {
|
||||
sendPacket(std::move(domainPacket), _domainHandler.getSockAddr());
|
||||
}
|
||||
sendPacket(std::move(domainPacket), _domainHandler.getSockAddr());
|
||||
|
||||
if (_numNoReplyDomainCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
|
||||
// we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS
|
||||
|
@ -462,7 +461,7 @@ void NodeList::handleICEConnectionToDomainServer() {
|
|||
|
||||
LimitedNodeList::sendPeerQueryToIceServer(_domainHandler.getICEServerSockAddr(),
|
||||
_domainHandler.getICEClientID(),
|
||||
_domainHandler.getICEDomainID());
|
||||
_domainHandler.getPendingDomainID());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -475,7 +474,7 @@ void NodeList::pingPunchForDomainServer() {
|
|||
|
||||
if (_domainHandler.getICEPeer().getConnectionAttempts() == 0) {
|
||||
qCDebug(networking) << "Sending ping packets to establish connectivity with domain-server with ID"
|
||||
<< uuidStringWithoutCurlyBraces(_domainHandler.getICEDomainID());
|
||||
<< uuidStringWithoutCurlyBraces(_domainHandler.getPendingDomainID());
|
||||
} else {
|
||||
if (_domainHandler.getICEPeer().getConnectionAttempts() % NUM_DOMAIN_SERVER_PINGS_BEFORE_RESET == 0) {
|
||||
// if we have then nullify the domain handler's network peer and send a fresh ICE heartbeat
|
||||
|
|
|
@ -68,9 +68,6 @@ public:
|
|||
|
||||
void setIsShuttingDown(bool isShuttingDown) { _isShuttingDown = isShuttingDown; }
|
||||
|
||||
/// downgrades the DomainConnnectRequest PacketVersion to attempt to probe for older domain servers
|
||||
void downgradeDomainServerCheckInVersion() { _domainConnectRequestVersion--; }
|
||||
|
||||
public slots:
|
||||
void reset();
|
||||
void sendDomainServerCheckIn();
|
||||
|
@ -88,8 +85,9 @@ public slots:
|
|||
|
||||
void processICEPingPacket(QSharedPointer<ReceivedMessage> message);
|
||||
|
||||
void resetDomainServerCheckInVersion()
|
||||
{ _domainConnectRequestVersion = versionForPacketType(PacketType::DomainConnectRequest); }
|
||||
#if (PR_BUILD || DEV_BUILD)
|
||||
void toggleSendNewerDSConnectVersion(bool shouldSendNewerVersion) { _shouldSendNewerVersion = shouldSendNewerVersion; }
|
||||
#endif
|
||||
|
||||
signals:
|
||||
void limitOfSilentDomainCheckInsReached();
|
||||
|
@ -105,6 +103,7 @@ private slots:
|
|||
void pingPunchForDomainServer();
|
||||
|
||||
void sendKeepAlivePings();
|
||||
|
||||
private:
|
||||
NodeList() : LimitedNodeList(0, 0) { assert(false); } // Not implemented, needed for DependencyManager templates compile
|
||||
NodeList(char ownerType, unsigned short socketListenPort = 0, unsigned short dtlsListenPort = 0);
|
||||
|
@ -130,7 +129,9 @@ private:
|
|||
bool _isShuttingDown { false };
|
||||
QTimer _keepAlivePingTimer;
|
||||
|
||||
PacketVersion _domainConnectRequestVersion = versionForPacketType(PacketType::DomainConnectRequest);
|
||||
#if (PR_BUILD || DEV_BUILD)
|
||||
bool _shouldSendNewerVersion { false };
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // hifi_NodeList_h
|
||||
|
|
Loading…
Reference in a new issue