From ab85c4109dfb2103fbd991893a762771eaabf5b2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 18 Sep 2013 13:29:53 -0700 Subject: [PATCH] use QHostInfo and QHostAddress for DS changes in NodeList --- animation-server/src/main.cpp | 6 +-- assignment-client/src/Agent.cpp | 2 +- assignment-client/src/main.cpp | 13 +++--- interface/src/Application.cpp | 6 +-- interface/src/Menu.cpp | 74 +++++++++++------------------- libraries/shared/CMakeLists.txt | 4 ++ libraries/shared/src/NodeList.cpp | 69 ++++++++++++---------------- libraries/shared/src/NodeList.h | 22 ++++----- libraries/shared/src/UDPSocket.cpp | 2 +- libraries/shared/src/UDPSocket.h | 2 +- 10 files changed, 87 insertions(+), 113 deletions(-) diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index eb1e3546dd..50e1da707c 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -685,9 +685,9 @@ int main(int argc, const char * argv[]) nodeList->setDomainIPToLocalhost(); } - const char* domainIP = getCmdOption(argc, argv, "--domain"); - if (domainIP) { - NodeList::getInstance()->setDomainIP(domainIP); + const char* domainHostname = getCmdOption(argc, argv, "--domain"); + if (domainHostname) { + NodeList::getInstance()->setDomainHostname(domainHostname); } nodeList->linkedDataCreateCallback = NULL; // do we need a callback? diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index a2d96c6a1c..5ba022d3a6 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -27,7 +27,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(), + scriptURLString = scriptURLString.arg(NodeList::getInstance()->getDomainIP().toString(), this->getUUIDStringWithoutCurlyBraces()); QUrl scriptURL(scriptURLString); diff --git a/assignment-client/src/main.cpp b/assignment-client/src/main.cpp index 479e12eec7..83c793736f 100644 --- a/assignment-client/src/main.cpp +++ b/assignment-client/src/main.cpp @@ -84,19 +84,20 @@ void childClient() { if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT || deployedAssignment->getAttachedPublicSocket()->sa_family == AF_INET) { - in_addr domainSocketAddr = {}; + + sockaddr* domainSocket = NULL; if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT) { // the domain server IP address is the address we got this packet from - domainSocketAddr = senderSocket.sin_addr; + domainSocket = (sockaddr*) &senderSocket; } else { // grab the domain server IP address from the packet from the AS - domainSocketAddr = ((sockaddr_in*) deployedAssignment->getAttachedPublicSocket())->sin_addr; + domainSocket = (sockaddr*) deployedAssignment->getAttachedPublicSocket(); } - nodeList->setDomainIP(inet_ntoa(domainSocketAddr)); + nodeList->setDomainIP(QHostAddress(domainSocket)); - qDebug("Destination IP for assignment is %s\n", inet_ntoa(domainSocketAddr)); + qDebug("Destination IP for assignment is %s\n", nodeList->getDomainIP().toString().toStdString().c_str()); // run the deployed assignment deployedAssignment->run(); @@ -199,7 +200,7 @@ int main(int argc, const char* argv[]) { if (customAssignmentServerHostname) { const char* customAssignmentServerPortString = getCmdOption(argc, argv, CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION); unsigned short assignmentServerPort = customAssignmentServerPortString - ? atoi(customAssignmentServerPortString) : DEFAULT_DOMAINSERVER_PORT; + ? atoi(customAssignmentServerPortString) : DEFAULT_DOMAIN_SERVER_PORT; ::customAssignmentSocket = socketForHostnameAndHostOrderPort(customAssignmentServerHostname, assignmentServerPort); } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c0484bf7fa..06ea59d30a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -183,9 +183,9 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : // --domain or --local options NodeList::getInstance()->loadData(_settings); - const char* domainIP = getCmdOption(argc, constArgv, "--domain"); - if (domainIP) { - NodeList::getInstance()->setDomainIP(domainIP); + const char* domainHostname = getCmdOption(argc, constArgv, "--domain"); + if (domainHostname) { + NodeList::getInstance()->setDomainHostname(domainHostname); } // Handle Local Domain testing with the --local command line diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 8a693582c1..b2e94f993c 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -687,6 +687,30 @@ void Menu::aboutApp() { InfoView::forcedShow(); } +void updateDSHostname(const QString& domainServerHostname) { + QString newHostname(DEFAULT_DOMAIN_HOSTNAME); + + if (domainServerHostname.size() > 0) { + // the user input a new hostname, use that + newHostname = domainServerHostname; + } + + // check if the domain server hostname is new + if (NodeList::getInstance()->getDomainHostname() != newHostname) { + + NodeList::getInstance()->clear(); + + // kill the local voxels + Application::getInstance()->getVoxels()->killLocalVoxels(); + + // reset the environment to default + Application::getInstance()->getEnvironment()->resetToDefault(); + + // set the new hostname + NodeList::getInstance()->setDomainHostname(newHostname); + } +} + void Menu::editPreferences() { Application* applicationInstance = Application::getInstance(); QDialog dialog(applicationInstance->getGLWidget()); @@ -738,30 +762,7 @@ void Menu::editPreferences() { return; } - QByteArray newHostname; - - if (domainServerHostname->text().size() > 0) { - // the user input a new hostname, use that - newHostname = domainServerHostname->text().toLocal8Bit(); - } else { - // the user left the field blank, use the default hostname - newHostname = QByteArray(DEFAULT_DOMAIN_HOSTNAME); - } - - // check if the domain server hostname is new - if (memcmp(NodeList::getInstance()->getDomainHostname(), newHostname.constData(), newHostname.size()) != 0) { - - NodeList::getInstance()->clear(); - - // kill the local voxels - applicationInstance->getVoxels()->killLocalVoxels(); - - // reset the environment to default - applicationInstance->getEnvironment()->resetToDefault(); - - // set the new hostname - NodeList::getInstance()->setDomainHostname(newHostname.constData()); - } + updateDSHostname(domainServerHostname->text()); QUrl url(avatarURL->text()); applicationInstance->getAvatar()->getVoxels()->setVoxelURL(url); @@ -808,30 +809,7 @@ void Menu::goToDomain() { return; } - QByteArray newHostname; - - if (domainServerHostname->text().size() > 0) { - // the user input a new hostname, use that - newHostname = domainServerHostname->text().toLocal8Bit(); - } else { - // the user left the field blank, use the default hostname - newHostname = QByteArray(DEFAULT_DOMAIN_HOSTNAME); - } - - // check if the domain server hostname is new - if (memcmp(NodeList::getInstance()->getDomainHostname(), newHostname.constData(), newHostname.size()) != 0) { - - NodeList::getInstance()->clear(); - - // kill the local voxels - applicationInstance->getVoxels()->killLocalVoxels(); - - // reset the environment to default - applicationInstance->getEnvironment()->resetToDefault(); - - // set the new hostname - NodeList::getInstance()->setDomainHostname(newHostname.constData()); - } + updateDSHostname(domainServerHostname->text()); } void Menu::goToLocation() { diff --git a/libraries/shared/CMakeLists.txt b/libraries/shared/CMakeLists.txt index 218adb4d5f..d9bfc769d1 100644 --- a/libraries/shared/CMakeLists.txt +++ b/libraries/shared/CMakeLists.txt @@ -6,9 +6,13 @@ set(MACRO_DIR ${ROOT_DIR}/cmake/macros) set(TARGET_NAME shared) project(${TARGET_NAME}) +find_package(Qt5Network REQUIRED) + include(${MACRO_DIR}/SetupHifiLibrary.cmake) setup_hifi_library(${TARGET_NAME}) +qt5_use_modules(${TARGET_NAME} Network) + set(EXTERNAL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external) if (WIN32) diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 6af17c2dcf..76820d9a40 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -12,6 +12,7 @@ #include #include +#include #include "Assignment.h" #include "Logging.h" @@ -31,9 +32,8 @@ const char SOLO_NODE_TYPES[2] = { NODE_TYPE_AUDIO_MIXER }; -const char DEFAULT_DOMAIN_HOSTNAME[MAX_HOSTNAME_BYTES] = "root.highfidelity.io"; -const char DEFAULT_DOMAIN_IP[INET_ADDRSTRLEN] = ""; // IP Address will be re-set by lookup on startup -const unsigned short DEFAULT_DOMAINSERVER_PORT = 40102; +const QString DEFAULT_DOMAIN_HOSTNAME = "root.highfidelity.io"; +const unsigned short DEFAULT_DOMAIN_SERVER_PORT = 40102; bool silentNodeThreadStopFlag = false; bool pingUnknownNodeThreadStopFlag = false; @@ -59,6 +59,9 @@ NodeList* NodeList::getInstance() { } NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) : + _domainHostname(DEFAULT_DOMAIN_HOSTNAME), + _domainIP(), + _domainPort(DEFAULT_DOMAIN_SERVER_PORT), _nodeBuckets(), _numNodes(0), _nodeSocket(newSocketListenPort), @@ -69,8 +72,7 @@ NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) : _numNoReplyDomainCheckIns(0), _assignmentServerSocket(NULL) { - memcpy(_domainHostname, DEFAULT_DOMAIN_HOSTNAME, sizeof(DEFAULT_DOMAIN_HOSTNAME)); - memcpy(_domainIP, DEFAULT_DOMAIN_IP, sizeof(DEFAULT_DOMAIN_IP)); + } NodeList::~NodeList() { @@ -82,22 +84,11 @@ NodeList::~NodeList() { stopSilentNodeRemovalThread(); } -void NodeList::setDomainHostname(const char* domainHostname) { - memset(_domainHostname, 0, sizeof(_domainHostname)); - memcpy(_domainHostname, domainHostname, strlen(domainHostname)); +void NodeList::setDomainHostname(const QString& domainHostname) { + _domainHostname = domainHostname; - // reset the domain IP so the hostname is checked again - setDomainIP(""); -} - -void NodeList::setDomainIP(const char* domainIP) { - memset(_domainIP, 0, sizeof(_domainIP)); - memcpy(_domainIP, domainIP, strlen(domainIP)); -} - -void NodeList::setDomainIPToLocalhost() { - int ip = getLocalAddress(); - sprintf(_domainIP, "%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); + // reset our _domainIP to the null address so that a lookup happens on next check in + _domainIP = QHostAddress(); } void NodeList::timePingReply(sockaddr *nodeAddress, unsigned char *packetData) { @@ -117,10 +108,7 @@ void NodeList::processNodeData(sockaddr* senderAddress, unsigned char* packetDat switch (packetData[0]) { case PACKET_TYPE_DOMAIN: { // only process the DS if this is our current domain server - sockaddr_in domainServerSocket = *(sockaddr_in*) senderAddress; - const char* domainSenderIP = inet_ntoa(domainServerSocket.sin_addr); - - if (memcmp(domainSenderIP, _domainIP, strlen(domainSenderIP)) == 0) { + if (_domainIP == QHostAddress(senderAddress)) { processDomainServerList(packetData, dataBytes); } @@ -272,19 +260,23 @@ void NodeList::sendDomainServerCheckIn(const char* assignmentUUID) { static bool printedDomainServerIP = false; // Lookup the IP address of the domain server if we need to - if (atoi(_domainIP) == 0) { - printf("Looking up %s\n", _domainHostname); - struct hostent* pHostInfo; - if ((pHostInfo = gethostbyname(_domainHostname)) != NULL) { - sockaddr_in tempAddress; - memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length); - strcpy(_domainIP, inet_ntoa(tempAddress.sin_addr)); - qDebug("Domain Server: %s\n", _domainHostname); + if (_domainIP.isNull()) { + qDebug("Looking up DS hostname %s.\n", _domainHostname.toStdString().c_str()); + + QHostInfo domainServerHostInfo = QHostInfo::fromName(_domainHostname); + + if (!domainServerHostInfo.addresses().isEmpty()) { + // set our domainIP to the first IP address + _domainIP = domainServerHostInfo.addresses().first(); + + qDebug("DS at %s is at %s\n", _domainHostname.toStdString().c_str(), _domainIP.toString().toStdString().c_str()); + + printedDomainServerIP = true; } else { qDebug("Failed domain server lookup\n"); } } else if (!printedDomainServerIP) { - qDebug("Domain Server IP: %s\n", _domainIP); + qDebug("Domain Server IP: %s\n", _domainIP.toString().toStdString().c_str()); printedDomainServerIP = true; } @@ -337,7 +329,7 @@ void NodeList::sendDomainServerCheckIn(const char* assignmentUUID) { checkInPacketSize = packetPosition - checkInPacket; } - _nodeSocket.send(_domainIP, DEFAULT_DOMAINSERVER_PORT, checkInPacket, checkInPacketSize); + _nodeSocket.send(_domainIP.toString().toStdString().c_str(), _domainPort, checkInPacket, checkInPacketSize); // increment the count of un-replied check-ins _numNoReplyDomainCheckIns++; @@ -370,7 +362,7 @@ int NodeList::processDomainServerList(unsigned char* packetData, size_t dataByte // if the public socket address is 0 then it's reachable at the same IP // as the domain server if (nodePublicSocket.sin_addr.s_addr == 0) { - inet_aton(_domainIP, &nodePublicSocket.sin_addr); + nodePublicSocket.sin_addr.s_addr = _domainIP.toIPv4Address(); } addOrUpdateNode((sockaddr*) &nodePublicSocket, (sockaddr*) &nodeLocalSocket, nodeType, nodeId); @@ -384,7 +376,7 @@ int NodeList::processDomainServerList(unsigned char* packetData, size_t dataByte const char LOCAL_ASSIGNMENT_SERVER_HOSTNAME[] = "localhost"; const sockaddr_in DEFAULT_LOCAL_ASSIGNMENT_SOCKET = socketForHostnameAndHostOrderPort(LOCAL_ASSIGNMENT_SERVER_HOSTNAME, - DEFAULT_DOMAINSERVER_PORT); + DEFAULT_DOMAIN_SERVER_PORT); void NodeList::sendAssignment(Assignment& assignment) { unsigned char assignmentPacket[MAX_PACKET_SIZE]; @@ -561,8 +553,7 @@ void NodeList::loadData(QSettings *settings) { QString domainServerHostname = settings->value(DOMAIN_SERVER_SETTING_KEY).toString(); if (domainServerHostname.size() > 0) { - memset(_domainHostname, 0, MAX_HOSTNAME_BYTES); - memcpy(_domainHostname, domainServerHostname.toLocal8Bit().constData(), domainServerHostname.size()); + _domainHostname = domainServerHostname; } settings->endGroup(); @@ -571,7 +562,7 @@ void NodeList::loadData(QSettings *settings) { void NodeList::saveData(QSettings* settings) { settings->beginGroup(DOMAIN_SERVER_SETTING_KEY); - if (memcmp(_domainHostname, DEFAULT_DOMAIN_HOSTNAME, strlen(DEFAULT_DOMAIN_HOSTNAME)) != 0) { + if (_domainHostname != DEFAULT_DOMAIN_HOSTNAME) { // the user is using a different hostname, store it settings->setValue(DOMAIN_SERVER_SETTING_KEY, QVariant(_domainHostname)); } else { diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 0834a278dc..32a6d33e1e 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -14,6 +14,7 @@ #include #include +#include #include #include "Node.h" @@ -36,9 +37,8 @@ extern const char SOLO_NODE_TYPES[2]; const int MAX_HOSTNAME_BYTES = 256; -extern const char DEFAULT_DOMAIN_HOSTNAME[MAX_HOSTNAME_BYTES]; -extern const char DEFAULT_DOMAIN_IP[INET_ADDRSTRLEN]; // IP Address will be re-set by lookup on startup -extern const unsigned short DEFAULT_DOMAINSERVER_PORT; +extern const QString DEFAULT_DOMAIN_HOSTNAME; +extern const unsigned short DEFAULT_DOMAIN_SERVER_PORT; const int UNKNOWN_NODE_ID = 0; @@ -65,16 +65,15 @@ public: NodeListIterator begin() const; NodeListIterator end() const; - NODE_TYPE getOwnerType() const { return _ownerType; } void setOwnerType(NODE_TYPE ownerType) { _ownerType = ownerType; } - const char* getDomainHostname() const { return _domainHostname; } - void setDomainHostname(const char* domainHostname); + const QString& getDomainHostname() const { return _domainHostname; } + void setDomainHostname(const QString& domainHostname); - const char* getDomainIP() const { return _domainIP; } - void setDomainIP(const char* domainIP); - void setDomainIPToLocalhost(); + const QHostAddress& getDomainIP() const { return _domainIP; } + void setDomainIP(const QHostAddress& domainIP) { _domainIP = domainIP; } + void setDomainIPToLocalhost() { _domainIP = QHostAddress(INADDR_LOOPBACK); } uint16_t getLastNodeID() const { return _lastNodeID; } void increaseNodeID() { (++_lastNodeID == UNKNOWN_NODE_ID) ? ++_lastNodeID : _lastNodeID; } @@ -141,8 +140,9 @@ private: void addNodeToList(Node* newNode); - char _domainHostname[MAX_HOSTNAME_BYTES]; - char _domainIP[INET_ADDRSTRLEN]; + QString _domainHostname; + QHostAddress _domainIP; + unsigned short _domainPort; Node** _nodeBuckets[MAX_NUM_NODES / NODES_PER_BUCKET]; int _numNodes; UDPSocket _nodeSocket; diff --git a/libraries/shared/src/UDPSocket.cpp b/libraries/shared/src/UDPSocket.cpp index 11fd218a56..beee5c6879 100644 --- a/libraries/shared/src/UDPSocket.cpp +++ b/libraries/shared/src/UDPSocket.cpp @@ -275,7 +275,7 @@ int UDPSocket::send(sockaddr* destAddress, const void* data, size_t byteLength) return sent_bytes; } -int UDPSocket::send(char* destAddress, int destPort, const void* data, size_t byteLength) const { +int UDPSocket::send(const char* destAddress, int destPort, const void* data, size_t byteLength) const { // change address and port on reusable global to passed variables destSockaddr.sin_addr.s_addr = inet_addr(destAddress); diff --git a/libraries/shared/src/UDPSocket.h b/libraries/shared/src/UDPSocket.h index d3f7cfac58..b177fd4e30 100644 --- a/libraries/shared/src/UDPSocket.h +++ b/libraries/shared/src/UDPSocket.h @@ -31,7 +31,7 @@ public: void setBlockingReceiveTimeoutInUsecs(int timeoutUsecs); int send(sockaddr* destAddress, const void* data, size_t byteLength) const; - int send(char* destAddress, int destPort, const void* data, size_t byteLength) const; + int send(const char* destAddress, int destPort, const void* data, size_t byteLength) const; bool receive(void* receivedData, ssize_t* receivedBytes) const; bool receive(sockaddr* recvAddress, void* receivedData, ssize_t* receivedBytes) const;