diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index adc7f5e3c5..8e44cdd157 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -44,7 +44,8 @@ const long long ASSIGNMENT_REQUEST_INTERVAL_MSECS = 1 * 1000; AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool, quint16 listenPort, QUuid walletUUID, QString assignmentServerHostname, - quint16 assignmentServerPort, quint16 assignmentMonitorPort) : + quint16 assignmentServerPort, quint16 assignmentMonitorPort, + bool disableDomainPortAutoDiscovery) : _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME) { LogUtils::init(); @@ -89,6 +90,13 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri _assignmentServerSocket.setObjectName("AssignmentServer"); nodeList->setAssignmentServerSocket(_assignmentServerSocket); + if (disableDomainPortAutoDiscovery == true) { + _disableDomainPortAutoDiscovery = disableDomainPortAutoDiscovery; + qCDebug(assignment_client) << "Disabling domain port auto discovery by the assignment client due to parsed command line parameter."; + } + + nodeList->setDomainPortAutoDiscovery(_disableDomainPortAutoDiscovery); + qCDebug(assignment_client) << "Assignment server socket is" << _assignmentServerSocket; // call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required @@ -164,7 +172,7 @@ void AssignmentClient::setUpStatusToMonitor() { void AssignmentClient::sendStatusPacketToACM() { // tell the assignment client monitor what this assignment client is doing (if anything) auto nodeList = DependencyManager::get(); - + quint8 assignmentType = Assignment::Type::AllTypes; if (_currentAssignment) { @@ -175,7 +183,7 @@ void AssignmentClient::sendStatusPacketToACM() { statusPacket->write(_childAssignmentUUID.toRfc4122()); statusPacket->writePrimitive(assignmentType); - + nodeList->sendPacket(std::move(statusPacket), _assignmentClientMonitorSocket); } @@ -185,7 +193,7 @@ void AssignmentClient::sendAssignmentRequest() { auto nodeList = DependencyManager::get(); - if (_assignmentServerHostname == "localhost") { + if (_assignmentServerHostname == "localhost" && _disableDomainPortAutoDiscovery == false) { // we want to check again for the local domain-server port in case the DS has restarted quint16 localAssignmentServerPort; if (nodeList->getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, localAssignmentServerPort)) { @@ -270,10 +278,10 @@ void AssignmentClient::handleCreateAssignmentPacket(QSharedPointer message) { const HifiSockAddr& senderSockAddr = message->getSenderSockAddr(); - + if (senderSockAddr.getAddress() == QHostAddress::LocalHost || senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) { - + qCDebug(assignment_client) << "AssignmentClientMonitor at" << senderSockAddr << "requested stop via PacketType::StopNode."; QCoreApplication::quit(); } else { @@ -307,7 +315,7 @@ void AssignmentClient::handleAuthenticationRequest() { void AssignmentClient::assignmentCompleted() { crash::annotations::setShutdownState(true); - + // we expect that to be here the previous assignment has completely cleaned up assert(_currentAssignment.isNull()); @@ -328,6 +336,6 @@ void AssignmentClient::assignmentCompleted() { nodeList->setOwnerType(NodeType::Unassigned); nodeList->reset("Assignment completed"); nodeList->resetNodeInterestSet(); - + _isAssigned = false; } diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 28464bc222..d40f0964d1 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -23,9 +23,9 @@ class AssignmentClient : public QObject { Q_OBJECT public: AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool, - quint16 listenPort, - QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort, - quint16 assignmentMonitorPort); + quint16 listenPort, QUuid walletUUID, QString assignmentServerHostname, + quint16 assignmentServerPort, quint16 assignmentMonitorPort, + bool disableDomainPortAutoDiscovery); ~AssignmentClient(); private slots: @@ -53,6 +53,7 @@ private: QTimer _requestTimer; // timer for requesting and assignment QTimer _statsTimerACM; // timer for sending stats to assignment client monitor QUuid _childAssignmentUUID = QUuid::createUuid(); + bool _disableDomainPortAutoDiscovery { false }; protected: HifiSockAddr _assignmentClientMonitorSocket; diff --git a/assignment-client/src/AssignmentClientApp.cpp b/assignment-client/src/AssignmentClientApp.cpp index 1dd050fcb9..49674f5728 100644 --- a/assignment-client/src/AssignmentClientApp.cpp +++ b/assignment-client/src/AssignmentClientApp.cpp @@ -4,6 +4,7 @@ // // Created by Seth Alves on 2/19/15. // Copyright 2015 High Fidelity, Inc. +// Copyright 2021 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -44,7 +45,7 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : // parse command-line QCommandLineParser parser; - parser.setApplicationDescription("High Fidelity Assignment Client"); + parser.setApplicationDescription("Vircadia Assignment Client"); const QCommandLineOption helpOption = parser.addHelpOption(); const QCommandLineOption versionOption = parser.addVersionOption(); @@ -54,8 +55,8 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : type = static_cast(static_cast(type) + 1)) { typeDescription.append(QStringLiteral("\n%1 | %2").arg(QString::number(type), Assignment::typeToString(type))); } - const QCommandLineOption clientTypeOption(ASSIGNMENT_TYPE_OVERRIDE_OPTION, typeDescription, "type"); + const QCommandLineOption clientTypeOption(ASSIGNMENT_TYPE_OVERRIDE_OPTION, typeDescription, "type"); parser.addOption(clientTypeOption); const QCommandLineOption poolOption(ASSIGNMENT_POOL_OPTION, "set assignment pool", "pool-name"); @@ -99,6 +100,9 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : const QCommandLineOption logDirectoryOption(ASSIGNMENT_LOG_DIRECTORY, "directory to store logs", "log-directory"); parser.addOption(logDirectoryOption); + const QCommandLineOption disableDomainPortAutoDiscoveryOption(ASSIGNMENT_DISABLE_DOMAIN_AUTO_PORT_DISCOVERY, "disable automatic discovery of the domain server port"); + parser.addOption(disableDomainPortAutoDiscoveryOption); + const QCommandLineOption parentPIDOption(PARENT_PID_OPTION, "PID of the parent process", "parent-pid"); parser.addOption(parentPIDOption); @@ -151,11 +155,14 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : } QString logDirectory; - if (parser.isSet(logDirectoryOption)) { logDirectory = parser.value(logDirectoryOption); } + bool disableDomainPortAutoDiscovery = false; + if (parser.isSet(disableDomainPortAutoDiscoveryOption)) { + disableDomainPortAutoDiscovery = true; + } Assignment::Type requestAssignmentType = Assignment::AllTypes; if (argumentVariantMap.contains(ASSIGNMENT_TYPE_OVERRIDE_OPTION)) { @@ -250,13 +257,15 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : AssignmentClientMonitor* monitor = new AssignmentClientMonitor(numForks, minForks, maxForks, requestAssignmentType, assignmentPool, listenPort, childMinListenPort, walletUUID, assignmentServerHostname, - assignmentServerPort, httpStatusPort, logDirectory); + assignmentServerPort, httpStatusPort, logDirectory, + disableDomainPortAutoDiscovery); monitor->setParent(this); connect(this, &QCoreApplication::aboutToQuit, monitor, &AssignmentClientMonitor::aboutToQuit); } else { AssignmentClient* client = new AssignmentClient(requestAssignmentType, assignmentPool, listenPort, walletUUID, assignmentServerHostname, - assignmentServerPort, monitorPort); + assignmentServerPort, monitorPort, + disableDomainPortAutoDiscovery); client->setParent(this); connect(this, &QCoreApplication::aboutToQuit, client, &AssignmentClient::aboutToQuit); } diff --git a/assignment-client/src/AssignmentClientApp.h b/assignment-client/src/AssignmentClientApp.h index 1b50922980..e48e05f4f0 100644 --- a/assignment-client/src/AssignmentClientApp.h +++ b/assignment-client/src/AssignmentClientApp.h @@ -4,6 +4,7 @@ // // Created by Seth Alves on 2/19/15. // Copyright 2015 High Fidelity, Inc. +// Copyright 2021 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -28,6 +29,7 @@ const QString ASSIGNMENT_MAX_FORKS_OPTION = "max"; const QString ASSIGNMENT_CLIENT_MONITOR_PORT_OPTION = "monitor-port"; const QString ASSIGNMENT_HTTP_STATUS_PORT = "http-status-port"; const QString ASSIGNMENT_LOG_DIRECTORY = "log-directory"; +const QString ASSIGNMENT_DISABLE_DOMAIN_AUTO_PORT_DISCOVERY = "disable-domain-port-auto-discovery"; class AssignmentClientApp : public QCoreApplication { Q_OBJECT diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 68c0dfc9fd..811a731707 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -4,6 +4,7 @@ // // Created by Stephen Birarda on 1/10/2014. // Copyright 2014 High Fidelity, Inc. +// Copyright 2021 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -41,7 +42,8 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen const unsigned int maxAssignmentClientForks, Assignment::Type requestAssignmentType, QString assignmentPool, quint16 listenPort, quint16 childMinListenPort, QUuid walletUUID, QString assignmentServerHostname, - quint16 assignmentServerPort, quint16 httpStatusServerPort, QString logDirectory) : + quint16 assignmentServerPort, quint16 httpStatusServerPort, QString logDirectory, + bool disableDomainPortAutoDiscovery) : _httpManager(QHostAddress::LocalHost, httpStatusServerPort, "", this), _numAssignmentClientForks(numAssignmentClientForks), _minAssignmentClientForks(minAssignmentClientForks), @@ -51,7 +53,8 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen _walletUUID(walletUUID), _assignmentServerHostname(assignmentServerHostname), _assignmentServerPort(assignmentServerPort), - _childMinListenPort(childMinListenPort) + _childMinListenPort(childMinListenPort), + _disableDomainPortAutoDiscovery(disableDomainPortAutoDiscovery) { qDebug() << "_requestAssignmentType =" << _requestAssignmentType; @@ -198,6 +201,9 @@ void AssignmentClientMonitor::spawnChildClient() { _childArguments.append("--" + ASSIGNMENT_TYPE_OVERRIDE_OPTION); _childArguments.append(QString::number(_requestAssignmentType)); } + if (_disableDomainPortAutoDiscovery != false) { + _childArguments.append("--" + ASSIGNMENT_DISABLE_DOMAIN_AUTO_PORT_DISCOVERY); + } if (listenPort) { _childArguments.append("-" + ASSIGNMENT_CLIENT_LISTEN_PORT_OPTION); @@ -266,7 +272,7 @@ void AssignmentClientMonitor::spawnChildClient() { stderrPath = stderrPathTemp; stderrFilename = stderrFilenameTemp; } - + qDebug() << "Child stdout being written to: " << stdoutFilename; qDebug() << "Child stderr being written to: " << stderrFilename; } diff --git a/assignment-client/src/AssignmentClientMonitor.h b/assignment-client/src/AssignmentClientMonitor.h index f5355476b7..20d4a6767b 100644 --- a/assignment-client/src/AssignmentClientMonitor.h +++ b/assignment-client/src/AssignmentClientMonitor.h @@ -4,6 +4,7 @@ // // Created by Stephen Birarda on 1/10/2014. // Copyright 2014 High Fidelity, Inc. +// Copyright 2021 Vircadia contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -27,7 +28,7 @@ extern const char* NUM_FORKS_PARAMETER; struct ACProcess { - QProcess* process; // looks like a dangling pointer, but is parented by the AssignmentClientMonitor + QProcess* process; // looks like a dangling pointer, but is parented by the AssignmentClientMonitor QString logStdoutPath; QString logStderrPath; }; @@ -39,7 +40,7 @@ public: const unsigned int maxAssignmentClientForks, Assignment::Type requestAssignmentType, QString assignmentPool, quint16 listenPort, quint16 childMinListenPort, QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort, quint16 httpStatusServerPort, - QString logDirectory); + QString logDirectory, bool disableDomainPortAutoDiscovery); ~AssignmentClientMonitor(); void stopChildProcesses(); @@ -80,6 +81,7 @@ private: QSet _childListenPorts; bool _wantsChildFileLogging { false }; + bool _disableDomainPortAutoDiscovery { false }; }; #endif // hifi_AssignmentClientMonitor_h diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index a975302699..cf443367a4 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -377,7 +377,7 @@ void NodeList::sendDomainServerCheckIn() { // if so we need to make sure we have an up-to-date local port in case it restarted if (domainSockAddr.getAddress() == QHostAddress::LocalHost - || hostname == "localhost") { + || hostname == "localhost" && _domainPortAutoDiscovery == true) { quint16 domainPort = DEFAULT_DOMAIN_SERVER_PORT; getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, domainPort); @@ -534,7 +534,7 @@ void NodeList::sendDomainServerCheckIn() { sendPacket(std::move(packetCopy), domainSockAddr); } sendPacket(std::move(domainPacket), domainSockAddr); - + } } @@ -661,7 +661,7 @@ void NodeList::handleICEConnectionToDomainServer() { _domainHandler.getICEClientID(), _domainHandler.getPendingDomainID()); } -} +} void NodeList::pingPunchForDomainServer() { // make sure if we're here that we actually still need to ping the domain-server @@ -713,7 +713,7 @@ void NodeList::processDomainServerConnectionTokenPacket(QSharedPointer message) { - // parse header information + // parse header information QDataStream packetStream(message->getMessage()); // grab the domain's ID from the beginning of the packet @@ -794,7 +794,7 @@ void NodeList::processDomainServerList(QSharedPointer message) if (_domainHandler.isConnected() && _domainHandler.getUUID() != domainUUID) { // Received packet from different domain. - qWarning() << "IGNORING DomainList packet from" << domainUUID << "while connected to" + qWarning() << "IGNORING DomainList packet from" << domainUUID << "while connected to" << _domainHandler.getUUID() << ": sent " << pingLagTime << " msec ago."; qWarning(networking) << "DomainList request lag (interface->ds): " << domainServerRequestLag << "msec"; qWarning(networking) << "DomainList server processing time: " << domainServerCheckinProcessingTime << "usec"; @@ -821,9 +821,9 @@ void NodeList::processDomainServerList(QSharedPointer message) setSessionLocalID(newLocalID); setSessionUUID(newUUID); - // FIXME: Remove this call to requestDomainSettings() and reinstate the one in DomainHandler::setIsConnected(), in version + // FIXME: Remove this call to requestDomainSettings() and reinstate the one in DomainHandler::setIsConnected(), in version // 2021.2.0. (New protocol version implies a domain server upgrade.) - if (!_domainHandler.isConnected() + if (!_domainHandler.isConnected() && _domainHandler.getScheme() == URL_SCHEME_HIFI && !_domainHandler.getHostname().isEmpty()) { // We're about to connect but we need the domain settings (in particular, the node permissions) in order to adjust the // canRezAvatarEntities permission above before using the permissions in determining whether or not to connect without @@ -831,7 +831,7 @@ void NodeList::processDomainServerList(QSharedPointer message) _domainHandler.requestDomainSettings(); } - // Don't continue login to the domain if have avatar entities and don't have permissions to rez them, unless user has OKed + // Don't continue login to the domain if have avatar entities and don't have permissions to rez them, unless user has OKed // continuing login. if (!newPermissions.can(NodePermissions::Permission::canRezAvatarEntities) && (!adjustedPermissions || !_domainHandler.canConnectWithoutAvatarEntities())) { @@ -920,7 +920,7 @@ void NodeList::pingPunchForInactiveNode(const SharedNodePointer& node) { if (node->getConnectionAttempts() > 0 && node->getConnectionAttempts() % NUM_DEBUG_CONNECTION_ATTEMPTS == 0) { qCDebug(networking) << "No response to UDP hole punch pings for node" << node->getUUID() << "in last 2 s."; } - + auto nodeID = node->getUUID(); // send the ping packet to the local and public sockets for this node diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index 59b3815fba..685b998269 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -70,6 +70,8 @@ public: void setAssignmentServerSocket(const HifiSockAddr& serverSocket) { _assignmentServerSocket = serverSocket; } void sendAssignment(Assignment& assignment); + void setDomainPortAutoDiscovery(bool enabled = true) { _domainPortAutoDiscovery = enabled; }; + void setIsShuttingDown(bool isShuttingDown) { _isShuttingDown = isShuttingDown; } void ignoreNodesInRadius(bool enabled = true); @@ -105,7 +107,7 @@ public: public slots: void reset(QString reason, bool skipDomainHandlerReset = false); void resetFromDomainHandler() { reset("Reset from Domain Handler", true); } - + void sendDomainServerCheckIn(); void handleDSPathQuery(const QString& newPath); @@ -180,6 +182,7 @@ private: bool _requestsDomainListData { false }; bool _sendDomainServerCheckInEnabled { true }; + bool _domainPortAutoDiscovery { true }; mutable QReadWriteLock _ignoredSetLock; tbb::concurrent_unordered_set _ignoredNodeIDs;