diff --git a/animation-server/src/AnimationServer.cpp b/animation-server/src/AnimationServer.cpp index 3151445794..a2ca454741 100644 --- a/animation-server/src/AnimationServer.cpp +++ b/animation-server/src/AnimationServer.cpp @@ -736,12 +736,12 @@ AnimationServer::AnimationServer(int &argc, char **argv) : ::wantLocalDomain = cmdOptionExists(argc, (const char**) argv,local); if (::wantLocalDomain) { printf("Local Domain MODE!\n"); - nodeList->setDomainIPToLocalhost(); + nodeList->getDomainInfo().setIPToLocalhost(); } const char* domainHostname = getCmdOption(argc, (const char**) argv, "--domain"); if (domainHostname) { - NodeList::getInstance()->setDomainHostname(domainHostname); + NodeList::getInstance()->getDomainInfo().setHostname(domainHostname); } const char* packetsPerSecondCommand = getCmdOption(argc, (const char**) argv, "--pps"); diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index cc0ddd59f2..f9c3a2c8f3 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -79,7 +79,7 @@ void Agent::run() { // figure out the URL for the script for this agent assignment QString scriptURLString("http://%1:8080/assignment/%2"); - scriptURLString = scriptURLString.arg(NodeList::getInstance()->getDomainIP().toString(), + scriptURLString = scriptURLString.arg(NodeList::getInstance()->getDomainInfo().getIP().toString(), uuidStringWithoutCurlyBraces(_uuid)); QNetworkAccessManager *networkManager = new QNetworkAccessManager(this); diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 978882f358..0ae67574ed 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -120,10 +120,10 @@ void AssignmentClient::readPendingDatagrams() { // switch our nodelist domain IP and port to whoever sent us the assignment - nodeList->setDomainSockAddr(senderSockAddr); + nodeList->getDomainInfo().setSockAddr(senderSockAddr); nodeList->setSessionUUID(_currentAssignment->getUUID()); - qDebug() << "Destination IP for assignment is" << nodeList->getDomainIP().toString(); + qDebug() << "Destination IP for assignment is" << nodeList->getDomainInfo().getIP().toString(); // start the deployed assignment QThread* workerThread = new QThread(this); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 36fd8f9635..9a1380e183 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -200,7 +200,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : audioThread->start(); - connect(nodeList, SIGNAL(domainChanged(const QString&)), SLOT(domainChanged(const QString&))); + connect(&nodeList->getDomainInfo(), SIGNAL(hostnameChanged(const QString&)), SLOT(domainChanged(const QString&))); connect(nodeList, &NodeList::nodeAdded, this, &Application::nodeAdded); connect(nodeList, &NodeList::nodeKilled, this, &Application::nodeKilled); connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer))); @@ -3829,7 +3829,7 @@ void Application::updateWindowTitle(){ NodeList* nodeList = NodeList::getInstance(); QString title = QString() + _profile.getUsername() + " " + nodeList->getSessionUUID().toString() - + " @ " + nodeList->getDomainHostname() + buildVersion; + + " @ " + nodeList->getDomainInfo().getHostname() + buildVersion; qDebug("Application title set to: %s", title.toStdString().c_str()); _window->setWindowTitle(title); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index c61b4cbdaf..d74784adc4 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -887,23 +887,23 @@ void Menu::editPreferences() { } void Menu::goToDomain(const QString newDomain) { - if (NodeList::getInstance()->getDomainHostname() != newDomain) { + if (NodeList::getInstance()->getDomainInfo().getHostname() != newDomain) { // send a node kill request, indicating to other clients that they should play the "disappeared" effect Application::getInstance()->getAvatar()->sendKillAvatar(); // give our nodeList the new domain-server hostname - NodeList::getInstance()->setDomainHostname(newDomain); + NodeList::getInstance()->getDomainInfo().setHostname(newDomain); } } void Menu::goToDomain() { - QString currentDomainHostname = NodeList::getInstance()->getDomainHostname(); + QString currentDomainHostname = NodeList::getInstance()->getDomainInfo().getHostname(); - if (NodeList::getInstance()->getDomainPort() != DEFAULT_DOMAIN_SERVER_PORT) { + if (NodeList::getInstance()->getDomainInfo().getPort() != DEFAULT_DOMAIN_SERVER_PORT) { // add the port to the currentDomainHostname string if it is custom - currentDomainHostname.append(QString(":%1").arg(NodeList::getInstance()->getDomainPort())); + currentDomainHostname.append(QString(":%1").arg(NodeList::getInstance()->getDomainInfo().getPort())); } QInputDialog domainDialog(Application::getInstance()->getWindow()); diff --git a/interface/src/avatar/Profile.cpp b/interface/src/avatar/Profile.cpp index a2a412199e..c3aef6b9ef 100644 --- a/interface/src/avatar/Profile.cpp +++ b/interface/src/avatar/Profile.cpp @@ -29,7 +29,7 @@ Profile::Profile(const QString &username) : DataServerClient::getValueForKeyAndUserString(DataServerKey::UUID, getUserString(), this); // send our current domain server to the data-server - updateDomain(NodeList::getInstance()->getDomainHostname()); + updateDomain(NodeList::getInstance()->getDomainInfo().getHostname()); } } @@ -138,7 +138,7 @@ void Profile::processDataServerResponse(const QString& userString, const QString ", and orientation to" << valueList[i + 2].toLocal8Bit().constData() << "to go to" << userString; - NodeList::getInstance()->setDomainHostname(valueList[i]); + NodeList::getInstance()->getDomainInfo().setHostname(valueList[i]); // orient the user to face the target glm::quat newOrientation = glm::quat(glm::radians(glm::vec3(orientationItems[0].toFloat(), orientationItems[1].toFloat(), diff --git a/libraries/shared/src/DomainInfo.cpp b/libraries/shared/src/DomainInfo.cpp new file mode 100644 index 0000000000..42337fae0d --- /dev/null +++ b/libraries/shared/src/DomainInfo.cpp @@ -0,0 +1,62 @@ +// +// DomainInfo.cpp +// hifi +// +// Created by Stephen Birarda on 2/18/2014. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// + +#include "DomainInfo.h" + +DomainInfo::DomainInfo() : + _sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)) +{ + +} + +void DomainInfo::setHostname(const QString& hostname) { + + if (hostname != _hostname) { + int colonIndex = hostname.indexOf(':'); + + if (colonIndex > 0) { + // the user has included a custom DS port with the hostname + + // the new hostname is everything up to the colon + _hostname = hostname.left(colonIndex); + + // grab the port by reading the string after the colon + _sockAddr.setPort(atoi(hostname.mid(colonIndex + 1, hostname.size()).toLocal8Bit().constData())); + + qDebug() << "Updated hostname to" << _hostname << "and port to" << _sockAddr.getPort(); + + } else { + // no port included with the hostname, simply set the member variable and reset the domain server port to default + _hostname = hostname; + _sockAddr.setPort(DEFAULT_DOMAIN_SERVER_PORT); + } + + // re-set the sock addr to null and fire off a lookup of the IP address for this domain-server's hostname + _sockAddr.setAddress(QHostAddress::Null); + qDebug("Looking up DS hostname %s.", _hostname.toLocal8Bit().constData()); + QHostInfo::lookupHost(_hostname, this, SLOT(completedHostnameLookup(const QHostInfo&))); + + emit hostnameChanged(_hostname); + } +} + +void DomainInfo::completedHostnameLookup(const QHostInfo& hostInfo) { + for (int i = 0; i < hostInfo.addresses().size(); i++) { + if (hostInfo.addresses()[i].protocol() == QAbstractSocket::IPv4Protocol) { + _sockAddr.setAddress(hostInfo.addresses()[i]); + qDebug("DS at %s is at %s", _hostname.toLocal8Bit().constData(), + _sockAddr.getAddress().toString().toLocal8Bit().constData()); + return; + } + + + } + + // if we got here then we failed to lookup the address + qDebug("Failed domain server lookup"); +} diff --git a/libraries/shared/src/DomainInfo.h b/libraries/shared/src/DomainInfo.h new file mode 100644 index 0000000000..5d55f2333a --- /dev/null +++ b/libraries/shared/src/DomainInfo.h @@ -0,0 +1,44 @@ +// +// DomainInfo.h +// hifi +// +// Created by Stephen Birarda on 2/18/2014. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// + +#ifndef __hifi__DomainInfo__ +#define __hifi__DomainInfo__ + +#include +#include + +#include "HifiSockAddr.h" + +const QString DEFAULT_DOMAIN_HOSTNAME = "root.highfidelity.io"; +const unsigned short DEFAULT_DOMAIN_SERVER_PORT = 40102; + +class DomainInfo : public QObject { + Q_OBJECT +public: + DomainInfo(); + + const QString& getHostname() const { return _hostname; } + void setHostname(const QString& hostname); + + const QHostAddress& getIP() const { return _sockAddr.getAddress(); } + void setIPToLocalhost() { _sockAddr.setAddress(QHostAddress(QHostAddress::LocalHost)); } + + const HifiSockAddr& getSockAddr() { return _sockAddr; } + void setSockAddr(const HifiSockAddr& sockAddr) { _sockAddr = sockAddr; } + + unsigned short getPort() const { return _sockAddr.getPort(); } +private slots: + void completedHostnameLookup(const QHostInfo& hostInfo); +signals: + void hostnameChanged(const QString& hostname); +private: + QString _hostname; + HifiSockAddr _sockAddr; +}; + +#endif /* defined(__hifi__DomainInfo__) */ diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index c0bc7f0010..f68ffadc97 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -27,9 +27,6 @@ const char SOLO_NODE_TYPES[2] = { NodeType::AudioMixer }; -const QString DEFAULT_DOMAIN_HOSTNAME = "root.highfidelity.io"; -const unsigned short DEFAULT_DOMAIN_SERVER_PORT = 40102; - NodeList* NodeList::_sharedInstance = NULL; NodeList* NodeList::createInstance(char ownerType, unsigned short int socketListenPort) { @@ -59,8 +56,6 @@ NodeList* NodeList::getInstance() { NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) : _nodeHash(), _nodeHashMutex(QMutex::Recursive), - _domainHostname(), - _domainSockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)), _nodeSocket(this), _ownerType(newOwnerType), _nodeTypesOfInterest(), @@ -149,37 +144,6 @@ qint64 NodeList::writeDatagram(const char* data, qint64 size, const SharedNodePo return writeDatagram(QByteArray(data, size), destinationNode, overridenSockAddr); } -void NodeList::setDomainHostname(const QString& domainHostname) { - - if (domainHostname != _domainHostname) { - int colonIndex = domainHostname.indexOf(':'); - - if (colonIndex > 0) { - // the user has included a custom DS port with the hostname - - // the new hostname is everything up to the colon - _domainHostname = domainHostname.left(colonIndex); - - // grab the port by reading the string after the colon - _domainSockAddr.setPort(atoi(domainHostname.mid(colonIndex + 1, domainHostname.size()).toLocal8Bit().constData())); - - qDebug() << "Updated hostname to" << _domainHostname << "and port to" << _domainSockAddr.getPort(); - - } else { - // no port included with the hostname, simply set the member variable and reset the domain server port to default - _domainHostname = domainHostname; - _domainSockAddr.setPort(DEFAULT_DOMAIN_SERVER_PORT); - } - - // clear the NodeList so nodes from this domain are killed - clear(); - - // reset our _domainIP to the null address so that a lookup happens on next check in - _domainSockAddr.setAddress(QHostAddress::Null); - emit domainChanged(_domainHostname); - } -} - void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer& sendingNode) { QDataStream packetStream(packet); packetStream.skipRawData(numBytesForPacketHeader(packet)); @@ -219,7 +183,7 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteAr switch (packetTypeForPacket(packet)) { case PacketTypeDomainList: { // only process the DS if this is our current domain server - if (_domainSockAddr == senderSockAddr) { + if (_domainInfo.getSockAddr() == senderSockAddr) { processDomainServerList(packet); } @@ -492,39 +456,11 @@ void NodeList::processKillNode(const QByteArray& dataByteArray) { } void NodeList::sendDomainServerCheckIn() { - static bool printedDomainServerIP = false; - - // Lookup the IP address of the domain server if we need to - if (_domainSockAddr.getAddress().isNull() && !_domainHostname.isEmpty()) { - qDebug("Looking up DS hostname %s.", _domainHostname.toLocal8Bit().constData()); - QHostInfo domainServerHostInfo = QHostInfo::fromName(_domainHostname); - - for (int i = 0; i < domainServerHostInfo.addresses().size(); i++) { - if (domainServerHostInfo.addresses()[i].protocol() == QAbstractSocket::IPv4Protocol) { - _domainSockAddr.setAddress(domainServerHostInfo.addresses()[i]); - qDebug("DS at %s is at %s", _domainHostname.toLocal8Bit().constData(), - _domainSockAddr.getAddress().toString().toLocal8Bit().constData()); - - printedDomainServerIP = true; - - break; - } - - // if we got here without a break out of the for loop then we failed to lookup the address - if (i == domainServerHostInfo.addresses().size() - 1) { - qDebug("Failed domain server lookup"); - } - } - } else if (!printedDomainServerIP) { - qDebug("Domain Server IP: %s", _domainSockAddr.getAddress().toString().toLocal8Bit().constData()); - printedDomainServerIP = true; - } - if (_publicSockAddr.isNull() && !_hasCompletedInitialSTUNFailure) { // we don't know our public socket and we need to send it to the domain server // send a STUN request to figure it out sendSTUNRequest(); - } else if (!_domainSockAddr.getAddress().isNull()) { + } else if (!_domainInfo.getIP().isNull()) { // construct the DS check in packet if we can // check in packet has header, optional UUID, node type, port, IP, node types of interest, null termination @@ -541,7 +477,7 @@ void NodeList::sendDomainServerCheckIn() { packetStream << nodeTypeOfInterest; } - _nodeSocket.writeDatagram(domainServerPacket, _domainSockAddr.getAddress(), _domainSockAddr.getPort()); + _nodeSocket.writeDatagram(domainServerPacket, _domainInfo.getIP(), _domainInfo.getPort()); const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5; static unsigned int numDomainCheckins = 0; @@ -594,7 +530,7 @@ int NodeList::processDomainServerList(const QByteArray& packet) { // if the public socket address is 0 then it's reachable at the same IP // as the domain server if (nodePublicSocket.getAddress().isNull()) { - nodePublicSocket.setAddress(_domainSockAddr.getAddress()); + nodePublicSocket.setAddress(_domainInfo.getIP()); } SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, nodeLocalSocket); @@ -803,9 +739,9 @@ void NodeList::loadData(QSettings *settings) { QString domainServerHostname = settings->value(DOMAIN_SERVER_SETTING_KEY).toString(); if (domainServerHostname.size() > 0) { - _domainHostname = domainServerHostname; + _domainInfo.setHostname(domainServerHostname); } else { - _domainHostname = DEFAULT_DOMAIN_HOSTNAME; + _domainInfo.setHostname(DEFAULT_DOMAIN_HOSTNAME); } settings->endGroup(); @@ -814,9 +750,9 @@ void NodeList::loadData(QSettings *settings) { void NodeList::saveData(QSettings* settings) { settings->beginGroup(DOMAIN_SERVER_SETTING_KEY); - if (_domainHostname != DEFAULT_DOMAIN_HOSTNAME) { + if (_domainInfo.getHostname() != DEFAULT_DOMAIN_HOSTNAME) { // the user is using a different hostname, store it - settings->setValue(DOMAIN_SERVER_SETTING_KEY, QVariant(_domainHostname)); + settings->setValue(DOMAIN_SERVER_SETTING_KEY, QVariant(_domainInfo.getHostname())); } else { // the user has switched back to default, remove the current setting settings->remove(DOMAIN_SERVER_SETTING_KEY); diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index ca4e8ab7b4..2629bd351a 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -28,6 +28,7 @@ #include #include +#include "DomainInfo.h" #include "Node.h" const quint64 NODE_SILENCE_THRESHOLD_USECS = 2 * 1000 * 1000; @@ -67,16 +68,6 @@ public: NodeType_t getOwnerType() const { return _ownerType; } void setOwnerType(NodeType_t ownerType) { _ownerType = ownerType; } - const QString& getDomainHostname() const { return _domainHostname; } - void setDomainHostname(const QString& domainHostname); - - const QHostAddress& getDomainIP() const { return _domainSockAddr.getAddress(); } - void setDomainIPToLocalhost() { _domainSockAddr.setAddress(QHostAddress(INADDR_LOOPBACK)); } - - void setDomainSockAddr(const HifiSockAddr& domainSockAddr) { _domainSockAddr = domainSockAddr; } - - unsigned short getDomainPort() const { return _domainSockAddr.getPort(); } - const QUuid& getSessionUUID() const { return _sessionUUID; } void setSessionUUID(const QUuid& sessionUUID); @@ -95,7 +86,8 @@ public: int size() const { return _nodeHash.size(); } int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; } - + DomainInfo& getDomainInfo() { return _domainInfo; } + void reset(); const NodeSet& getNodeInterestSet() const { return _nodeTypesOfInterest; } @@ -135,7 +127,6 @@ public slots: void killNodeWithUUID(const QUuid& nodeUUID); signals: - void domainChanged(const QString& domainHostname); void uuidChanged(const QUuid& ownerUUID); void nodeAdded(SharedNodePointer); void nodeKilled(SharedNodePointer); @@ -153,11 +144,10 @@ private: NodeHash _nodeHash; QMutex _nodeHashMutex; - QString _domainHostname; - HifiSockAddr _domainSockAddr; QUdpSocket _nodeSocket; NodeType_t _ownerType; NodeSet _nodeTypesOfInterest; + DomainInfo _domainInfo; QUuid _sessionUUID; int _numNoReplyDomainCheckIns; HifiSockAddr _assignmentServerSocket; diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index f0ba78c144..708616e006 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -54,6 +54,7 @@ enum PacketType { PacketTypeParticleAddResponse, PacketTypeMetavoxelData, PacketTypeAvatarIdentity, + PacketTypeDomainConnectRequest, PacketTypeDomainServerAuthRequest };