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:
Chris Collins 2016-06-10 15:26:42 -07:00 committed by GitHub
commit 006eb8fe64
15 changed files with 145 additions and 89 deletions

View file

@ -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) {

View file

@ -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);

View file

@ -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.

View file

@ -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()) {

View file

@ -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;

View file

@ -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

View file

@ -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";

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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);
}

View file

@ -65,6 +65,7 @@ public:
void setType(PacketType type);
PacketVersion getVersion() const { return _version; }
void setVersion(PacketVersion version);
const QUuid& getSourceID() const { return _sourceID; }

View file

@ -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

View file

@ -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