From 89aeb034d1057d1c0b0e52622917d4bc89062b73 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 28 Mar 2014 15:22:44 -0700 Subject: [PATCH 01/86] add find module for QCA and link to interface and DS --- cmake/modules/FindQCA.cmake | 38 ++++++++++++++++++++++++++++++++++++ domain-server/CMakeLists.txt | 7 ++++++- interface/CMakeLists.txt | 4 +++- 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 cmake/modules/FindQCA.cmake diff --git a/cmake/modules/FindQCA.cmake b/cmake/modules/FindQCA.cmake new file mode 100644 index 0000000000..1e679ff96b --- /dev/null +++ b/cmake/modules/FindQCA.cmake @@ -0,0 +1,38 @@ +# Try to find the QCA library +# +# You can provide a QCA_ROOT_DIR which contains lib and include directories +# +# Once done this will define +# +# QCA_FOUND - system found qca +# QCA_INCLUDE_DIRS - the qca include directory +# QCA_LIBRARIES - Link this to use qca +# +# Created on 3/28/2014 by Stephen Birarda +# Copyright (c) 2014 High Fidelity +# + +if (QCA_LIBRARIES AND QCA_INCLUDE_DIRS) + # in cache already + set(QCA_FOUND TRUE) +else () + + set(QCA_SEARCH_DIRS "${QCA_ROOT_DIR}" "$ENV{HIFI_LIB_DIR}/qca") + + find_path(QCA_INCLUDE_DIR qca.h PATH_SUFFIXES include/QtCrypto HINTS ${QCA_SEARCH_DIRS}) + + find_library(QCA_LIBRARY NAMES qca PATH_SUFFIXES lib HINTS ${QCA_SEARCH_DIRS}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(QCA DEFAULT_MSG QCA_INCLUDE_DIR QCA_LIBRARY) + + if (QCA_FOUND) + if (NOT QCA_FIND_QUIETLY) + message(STATUS "Found qca: ${QCA_LIBRARY}") + endif () + else () + if (QCA_FIND_REQUIRED) + message(FATAL_ERROR "Could not find qca") + endif () + endif () +endif () \ No newline at end of file diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index 16bdb0df6b..57c9fa848c 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -17,6 +17,7 @@ include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") find_package(Qt5Network REQUIRED) +find_package(QCA REQUIRED) include(${MACRO_DIR}/SetupHifiProject.cmake) @@ -36,8 +37,12 @@ include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") +# include the QCA dir +include_directories(QCA_INCLUDE_DIR) + IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) -target_link_libraries(${TARGET_NAME} Qt5::Network) \ No newline at end of file +# link QtNetwork and QCA +target_link_libraries(${TARGET_NAME} Qt5::Network "${QCA_LIBRARY}") \ No newline at end of file diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index f991212a6e..b260f994a3 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -67,6 +67,7 @@ foreach(EXTERNAL_SOURCE_SUBDIR ${EXTERNAL_SOURCE_SUBDIRS}) endforeach(EXTERNAL_SOURCE_SUBDIR) find_package(Qt5 COMPONENTS Core Gui Multimedia Network OpenGL Script Svg WebKit WebKitWidgets Xml UiTools) +find_package(QCA REQUIRED) # grab the ui files in resources/ui file (GLOB_RECURSE QT_UI_FILES ui/*.ui) @@ -187,7 +188,7 @@ include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes" # include external library headers # use system flag so warnings are supressed -include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}") +include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}" "${QCA_INCLUDE_DIR}") target_link_libraries( ${TARGET_NAME} @@ -195,6 +196,7 @@ target_link_libraries( "${ZLIB_LIBRARIES}" Qt5::Core Qt5::Gui Qt5::Multimedia Qt5::Network Qt5::OpenGL Qt5::Script Qt5::Svg Qt5::WebKit Qt5::WebKitWidgets Qt5::Xml Qt5::UiTools + "${QCA_LIBRARY}" ) if (APPLE) From 9ae06913a02d443662d9a6547b9d46b8cccb88c4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 31 Mar 2014 09:45:19 -0700 Subject: [PATCH 02/86] remove QCA which only supports DTLS v1 --- cmake/modules/FindQCA.cmake | 38 ------- domain-server/src/DomainServer.cpp | 176 +++++++++++------------------ domain-server/src/DomainServer.h | 18 +-- domain-server/src/main.cpp | 2 +- 4 files changed, 73 insertions(+), 161 deletions(-) delete mode 100644 cmake/modules/FindQCA.cmake diff --git a/cmake/modules/FindQCA.cmake b/cmake/modules/FindQCA.cmake deleted file mode 100644 index 1e679ff96b..0000000000 --- a/cmake/modules/FindQCA.cmake +++ /dev/null @@ -1,38 +0,0 @@ -# Try to find the QCA library -# -# You can provide a QCA_ROOT_DIR which contains lib and include directories -# -# Once done this will define -# -# QCA_FOUND - system found qca -# QCA_INCLUDE_DIRS - the qca include directory -# QCA_LIBRARIES - Link this to use qca -# -# Created on 3/28/2014 by Stephen Birarda -# Copyright (c) 2014 High Fidelity -# - -if (QCA_LIBRARIES AND QCA_INCLUDE_DIRS) - # in cache already - set(QCA_FOUND TRUE) -else () - - set(QCA_SEARCH_DIRS "${QCA_ROOT_DIR}" "$ENV{HIFI_LIB_DIR}/qca") - - find_path(QCA_INCLUDE_DIR qca.h PATH_SUFFIXES include/QtCrypto HINTS ${QCA_SEARCH_DIRS}) - - find_library(QCA_LIBRARY NAMES qca PATH_SUFFIXES lib HINTS ${QCA_SEARCH_DIRS}) - - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(QCA DEFAULT_MSG QCA_INCLUDE_DIR QCA_LIBRARY) - - if (QCA_FOUND) - if (NOT QCA_FIND_QUIETLY) - message(STATUS "Found qca: ${QCA_LIBRARY}") - endif () - else () - if (QCA_FIND_REQUIRED) - message(FATAL_ERROR "Could not find qca") - endif () - endif () -endif () \ No newline at end of file diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 035e6c9a20..1f1e3a4207 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -32,63 +32,80 @@ DomainServer::DomainServer(int argc, char* argv[]) : QCoreApplication(argc, argv), _HTTPManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this), _staticAssignmentHash(), - _assignmentQueue(), - _nodeAuthenticationURL(), - _redeemedTokenResponses() -{ + _assignmentQueue() +{ setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); setApplicationName("domain-server"); QSettings::setDefaultFormat(QSettings::IniFormat); _argumentList = arguments(); - int argumentIndex = 0; - // check if this domain server should use no authentication or a custom hostname for authentication - const QString DEFAULT_AUTH_OPTION = "--defaultAuth"; - const QString CUSTOM_AUTH_OPTION = "--customAuth"; - if ((argumentIndex = _argumentList.indexOf(DEFAULT_AUTH_OPTION) != -1)) { - _nodeAuthenticationURL = QUrl(DEFAULT_NODE_AUTH_URL); - } else if ((argumentIndex = _argumentList.indexOf(CUSTOM_AUTH_OPTION)) != -1) { - _nodeAuthenticationURL = QUrl(_argumentList.value(argumentIndex + 1)); - } - - if (!_nodeAuthenticationURL.isEmpty()) { - const QString DATA_SERVER_USERNAME_ENV = "HIFI_DS_USERNAME"; - const QString DATA_SERVER_PASSWORD_ENV = "HIFI_DS_PASSWORD"; - - // this node will be using an authentication server, let's make sure we have a username/password - QProcessEnvironment sysEnvironment = QProcessEnvironment::systemEnvironment(); - - QString username = sysEnvironment.value(DATA_SERVER_USERNAME_ENV); - QString password = sysEnvironment.value(DATA_SERVER_PASSWORD_ENV); - - AccountManager& accountManager = AccountManager::getInstance(); - accountManager.setAuthURL(_nodeAuthenticationURL); - - if (!username.isEmpty() && !password.isEmpty()) { - - connect(&accountManager, &AccountManager::loginComplete, this, &DomainServer::requestCreationFromDataServer); - - // ask the account manager to log us in from the env variables - accountManager.requestAccessToken(username, password); - } else { - qDebug() << "Authentication was requested against" << qPrintable(_nodeAuthenticationURL.toString()) - << "but both or one of" << qPrintable(DATA_SERVER_USERNAME_ENV) - << "/" << qPrintable(DATA_SERVER_PASSWORD_ENV) << "are not set. Qutting!"; - - // bail out - QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); - - return; - } - - } else { - // auth is not requested for domain-server, setup NodeList and assignments now + if (readCertificateAndPrivateKey()) { + // we either read a certificate and private key or were not passed one, good to load assignments + // and set up the node list setupNodeListAndAssignments(); } } +bool DomainServer::readCertificateAndPrivateKey() { + const QString X509_CERTIFICATE_PATH_OPTION = "--cert"; + const QString PRIVATE_KEY_OPTION = "--key"; + const QString PRIVATE_KEY_PASSPHRASE_ENV = "DOMAIN_SERVER_KEY_PASSPHRASE"; + + int certificateIndex = _argumentList.indexOf(X509_CERTIFICATE_PATH_OPTION); + int keyIndex = _argumentList.indexOf(PRIVATE_KEY_OPTION); + + if (certificateIndex != -1 && keyIndex != -1) { + // the user wants to use DTLS to encrypt communication with nodes + // let's make sure we can load the certificate and private key + +// QCA::ConvertResult conversionResult = QCA::ErrorFile; +// +// QFile certificateFile(_argumentList.value(certificateIndex + 1)); +// qDebug() << "Attempting to read X.509 certificate from" << certificateFile.fileName(); +// +// if (certificateFile.exists()) { +// certificateFile.open(QIODevice::ReadOnly); +// QByteArray filearray = certificateFile.readAll(); +// qDebug() << filearray; +// _certificate = QCA::Certificate::fromPEM(filearray, &conversionResult); +// certificateFile.close(); +// } +// +// if (conversionResult != QCA::ConvertGood) { +// // couldn't read the certificate from file, bail +// qCritical() << "Error" << conversionResult << "reading certificate from file. domain-server will now quit." ; +// QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); +// return false; +// } +// +// QByteArray keyPassphrase = QProcessEnvironment::systemEnvironment().value(PRIVATE_KEY_PASSPHRASE_ENV).toLocal8Bit(); +// QCA::SecureArray keySecureArray = QCA::SecureArray(keyPassphrase); +// +// QString keyFileString(_argumentList.value(keyIndex + 1)); +// qDebug() << "Attempting to read private key from" << keyFileString; +// _privateKey = QCA::PrivateKey::fromPEMFile(keyFileString, keySecureArray, &conversionResult); +// +// if (conversionResult != QCA::ConvertGood) { +// // couldn't read the private key from file, bail +// qCritical() << "Error" << conversionResult << "reading private key from file. domain-server will now quit."; +// QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); +// return false; +// } + + qDebug() << "Successfully read certificate and private key. Using DTLS for node communication."; + } else if (certificateIndex != -1 || keyIndex != -1) { + // one of the certificate or private key was missing, can't use one without the other + // bail + qCritical("Missing certificate or private key. domain-server will now quit."); + QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); + return false; + } + + return true; +} + void DomainServer::requestCreationFromDataServer() { // this slot is fired when we get a valid access token from the data-server // now let's ask it to set us up with a UUID @@ -109,17 +126,6 @@ void DomainServer::processCreateResponseFromDataServer(const QJsonObject& jsonOb } } -void DomainServer::processTokenRedeemResponse(const QJsonObject& jsonObject) { - // pull out the registration token this is associated with - QString registrationToken = jsonObject["data"].toObject()["registration_token"].toString(); - - // if we have a registration token add it to our hash of redeemed token responses - if (!registrationToken.isEmpty()) { - qDebug() << "Redeemed registration token" << registrationToken; - _redeemedTokenResponses.insert(registrationToken, jsonObject); - } -} - void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { int argumentIndex = 0; @@ -299,21 +305,6 @@ void DomainServer::populateDefaultStaticAssignmentsExcludingTypes(const QSetgetNodeSocket().writeDatagram(authenticationRequestPacket, - senderSockAddr.getAddress(), senderSockAddr.getPort()); -} - const NodeSet STATICALLY_ASSIGNED_NODES = NodeSet() << NodeType::AudioMixer << NodeType::AvatarMixer << NodeType::VoxelServer << NodeType::ParticleServer << NodeType::MetavoxelServer; @@ -483,7 +474,6 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif void DomainServer::readAvailableDatagrams() { NodeList* nodeList = NodeList::getInstance(); - AccountManager& accountManager = AccountManager::getInstance(); HifiSockAddr senderSockAddr; @@ -507,43 +497,9 @@ void DomainServer::readAvailableDatagrams() { quint8 hasRegistrationToken; packetStream >> hasRegistrationToken; - if (requiresAuthentication() && !hasRegistrationToken) { - // we need authentication and this node did not give us a registration token - tell it to auth - requestAuthenticationFromPotentialNode(senderSockAddr); - } else if (requiresAuthentication()) { - QByteArray registrationToken; - packetStream >> registrationToken; - - QString registrationTokenString(registrationToken.toHex()); - QJsonObject jsonForRedeemedToken = _redeemedTokenResponses.value(registrationTokenString); - - // check if we have redeemed this token and are ready to check the node in - if (jsonForRedeemedToken.isEmpty()) { - // make a request against the data-server to get information required to connect to this node - JSONCallbackParameters tokenCallbackParams; - tokenCallbackParams.jsonCallbackReceiver = this; - tokenCallbackParams.jsonCallbackMethod = "processTokenRedeemResponse"; - - QString redeemURLString = QString("/api/v1/nodes/redeem/%1.json").arg(registrationTokenString); - accountManager.authenticatedRequest(redeemURLString, QNetworkAccessManager::GetOperation, - tokenCallbackParams); - } else if (jsonForRedeemedToken["status"].toString() != "success") { - // we redeemed the token, but it was invalid - get the node to get another - requestAuthenticationFromPotentialNode(senderSockAddr); - } else { - // we've redeemed the token for this node and are ready to start communicating with it - // add the node to our NodeList - addNodeToNodeListAndConfirmConnection(receivedPacket, senderSockAddr, jsonForRedeemedToken); - } - - // if it exists, remove this response from the in-memory hash - _redeemedTokenResponses.remove(registrationTokenString); - - } else { - // we don't require authentication - add this node to our NodeList - // and send back session UUID right away - addNodeToNodeListAndConfirmConnection(receivedPacket, senderSockAddr); - } + // we don't require authentication - add this node to our NodeList + // and send back session UUID right away + addNodeToNodeListAndConfirmConnection(receivedPacket, senderSockAddr); } else if (requestType == PacketTypeDomainListRequest) { QUuid nodeUUID = uuidFromPacketHeader(receivedPacket); diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 597be7f50d..c6a9879555 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -28,8 +28,6 @@ class DomainServer : public QCoreApplication, public HTTPRequestHandler { public: DomainServer(int argc, char* argv[]); - bool requiresAuthentication() const { return !_nodeAuthenticationURL.isEmpty(); } - bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url); void exit(int retCode = 0); @@ -40,8 +38,14 @@ public slots: /// Called by NodeList to inform us a node has been killed void nodeKilled(SharedNodePointer node); +private slots: + void requestCreationFromDataServer(); + void processCreateResponseFromDataServer(const QJsonObject& jsonObject); + + void readAvailableDatagrams(); private: void setupNodeListAndAssignments(const QUuid& sessionUUID = QUuid::createUuid()); + bool readCertificateAndPrivateKey(); void requestAuthenticationFromPotentialNode(const HifiSockAddr& senderSockAddr); void addNodeToNodeListAndConfirmConnection(const QByteArray& packet, const HifiSockAddr& senderSockAddr, @@ -73,17 +77,7 @@ private: QHash _staticAssignmentHash; QQueue _assignmentQueue; - QUrl _nodeAuthenticationURL; - QStringList _argumentList; - - QHash _redeemedTokenResponses; -private slots: - void requestCreationFromDataServer(); - void processCreateResponseFromDataServer(const QJsonObject& jsonObject); - void processTokenRedeemResponse(const QJsonObject& jsonObject); - - void readAvailableDatagrams(); }; #endif /* defined(__hifi__DomainServer__) */ diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 970d1dad70..096431e0a4 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -23,7 +23,7 @@ int main(int argc, char* argv[]) { #ifndef WIN32 setvbuf(stdout, NULL, _IOLBF, 0); #endif - + qInstallMessageHandler(Logging::verboseMessageHandler); DomainServer domainServer(argc, argv); From dc38b27485d00fb1483a657ce0010c69673db264 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 31 Mar 2014 12:31:34 -0700 Subject: [PATCH 03/86] using GnuTLS read self-signed key and cert on DS load --- cmake/modules/FindGnuTLS.cmake | 28 +++++++++++ cmake/modules/FindQxmpp.cmake | 12 +---- domain-server/CMakeLists.txt | 6 +-- domain-server/src/DomainServer.cpp | 77 ++++++++++++------------------ domain-server/src/DomainServer.h | 4 ++ domain-server/src/main.cpp | 2 + interface/CMakeLists.txt | 4 +- 7 files changed, 69 insertions(+), 64 deletions(-) create mode 100644 cmake/modules/FindGnuTLS.cmake diff --git a/cmake/modules/FindGnuTLS.cmake b/cmake/modules/FindGnuTLS.cmake new file mode 100644 index 0000000000..d09ba38fb7 --- /dev/null +++ b/cmake/modules/FindGnuTLS.cmake @@ -0,0 +1,28 @@ +# Try to find the GnuTLS library +# +# You can provide a GNUTLS_ROOT_DIR which contains lib and include directories +# +# Once done this will define +# +# GNUTLS_FOUND - system found GnuTLS +# GNUTLS_INCLUDE_DIRS - the GnuTLS include directory +# GNUTLS_LIBRARY - Link this to use GnuTLS +# +# Created on 3/31/2014 by Stephen Birarda +# Copyright (c) 2014 High Fidelity +# + +if (GNUTLS_LIBRARY AND GNUTLS_INCLUDE_DIRS) + # in cache already + set(GNUTLS_FOUND TRUE) +else () + + set(GNUTLS_SEARCH_DIRS "${GNUTLS_ROOT_DIR}" "$ENV{HIFI_LIB_DIR}/gnutls") + + find_path(GNUTLS_INCLUDE_DIR gnutls.h PATH_SUFFIXES include gnutls HINTS ${GNUTLS_SEARCH_DIRS}) + + find_library(GNUTLS_LIBRARY NAMES gnutls PATH_SUFFIXES lib HINTS ${GNUTLS_SEARCH_DIRS}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(GNUTLS DEFAULT_MSG GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY) +endif () \ No newline at end of file diff --git a/cmake/modules/FindQxmpp.cmake b/cmake/modules/FindQxmpp.cmake index 415b184a65..2e883e02f2 100644 --- a/cmake/modules/FindQxmpp.cmake +++ b/cmake/modules/FindQxmpp.cmake @@ -6,7 +6,7 @@ # # QXMPP_FOUND - system found qxmpp # QXMPP_INCLUDE_DIRS - the qxmpp include directory -# QXMPP_LIBRARIES - Link this to use qxmpp +# QXMPP_LIBRARY - Link this to use qxmpp # # Created on 3/10/2014 by Stephen Birarda # Copyright (c) 2014 High Fidelity @@ -25,14 +25,4 @@ else () include(FindPackageHandleStandardArgs) find_package_handle_standard_args(QXMPP DEFAULT_MSG QXMPP_INCLUDE_DIR QXMPP_LIBRARY) - - if (QXMPP_FOUND) - if (NOT QXMPP_FIND_QUIETLY) - message(STATUS "Found qxmpp: ${QXMPP_LIBRARY}") - endif () - else () - if (QXMPP_FIND_REQUIRED) - message(FATAL_ERROR "Could not find qxmpp") - endif () - endif () endif () \ No newline at end of file diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index 57c9fa848c..4cbc29c62d 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -17,7 +17,7 @@ include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") find_package(Qt5Network REQUIRED) -find_package(QCA REQUIRED) +find_package(GnuTLS REQUIRED) include(${MACRO_DIR}/SetupHifiProject.cmake) @@ -38,11 +38,11 @@ link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") # include the QCA dir -include_directories(QCA_INCLUDE_DIR) +include_directories(GNUTLS_INCLUDE_DIR) IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) # link QtNetwork and QCA -target_link_libraries(${TARGET_NAME} Qt5::Network "${QCA_LIBRARY}") \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Network "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 1f1e3a4207..80a86da8a0 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -16,6 +16,8 @@ #include #include +#include + #include #include #include @@ -32,7 +34,8 @@ DomainServer::DomainServer(int argc, char* argv[]) : QCoreApplication(argc, argv), _HTTPManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this), _staticAssignmentHash(), - _assignmentQueue() + _assignmentQueue(), + _x509Credentials() { setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); @@ -49,56 +52,36 @@ DomainServer::DomainServer(int argc, char* argv[]) : } bool DomainServer::readCertificateAndPrivateKey() { - const QString X509_CERTIFICATE_PATH_OPTION = "--cert"; - const QString PRIVATE_KEY_OPTION = "--key"; - const QString PRIVATE_KEY_PASSPHRASE_ENV = "DOMAIN_SERVER_KEY_PASSPHRASE"; + const QString X509_CERTIFICATE_OPTION = "--cert"; + const QString X509_PRIVATE_KEY_OPTION = "--key"; + const QString X509_KEY_PASSPHRASE_ENV = "DOMAIN_SERVER_KEY_PASSPHRASE"; + + int certIndex = _argumentList.indexOf(X509_CERTIFICATE_OPTION); + int keyIndex = _argumentList.indexOf(X509_PRIVATE_KEY_OPTION); - int certificateIndex = _argumentList.indexOf(X509_CERTIFICATE_PATH_OPTION); - int keyIndex = _argumentList.indexOf(PRIVATE_KEY_OPTION); - - if (certificateIndex != -1 && keyIndex != -1) { + if (certIndex != -1 && keyIndex != -1) { // the user wants to use DTLS to encrypt communication with nodes - // let's make sure we can load the certificate and private key - -// QCA::ConvertResult conversionResult = QCA::ErrorFile; -// -// QFile certificateFile(_argumentList.value(certificateIndex + 1)); -// qDebug() << "Attempting to read X.509 certificate from" << certificateFile.fileName(); -// -// if (certificateFile.exists()) { -// certificateFile.open(QIODevice::ReadOnly); -// QByteArray filearray = certificateFile.readAll(); -// qDebug() << filearray; -// _certificate = QCA::Certificate::fromPEM(filearray, &conversionResult); -// certificateFile.close(); -// } -// -// if (conversionResult != QCA::ConvertGood) { -// // couldn't read the certificate from file, bail -// qCritical() << "Error" << conversionResult << "reading certificate from file. domain-server will now quit." ; -// QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); -// return false; -// } -// -// QByteArray keyPassphrase = QProcessEnvironment::systemEnvironment().value(PRIVATE_KEY_PASSPHRASE_ENV).toLocal8Bit(); -// QCA::SecureArray keySecureArray = QCA::SecureArray(keyPassphrase); -// -// QString keyFileString(_argumentList.value(keyIndex + 1)); -// qDebug() << "Attempting to read private key from" << keyFileString; -// _privateKey = QCA::PrivateKey::fromPEMFile(keyFileString, keySecureArray, &conversionResult); -// -// if (conversionResult != QCA::ConvertGood) { -// // couldn't read the private key from file, bail -// qCritical() << "Error" << conversionResult << "reading private key from file. domain-server will now quit."; -// QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); -// return false; -// } + // let's make sure we can load the ey + gnutls_certificate_allocate_credentials(&_x509Credentials); + + QString keyPassphraseString = QProcessEnvironment::systemEnvironment().value(X509_KEY_PASSPHRASE_ENV); + + int gnutlsReturn = gnutls_certificate_set_x509_key_file2(_x509Credentials, + _argumentList[certIndex + 1].toLocal8Bit().constData(), + _argumentList[keyIndex + 1].toLocal8Bit().constData(), + GNUTLS_X509_FMT_PEM, + keyPassphraseString.toLocal8Bit().constData(), + 0); + + if (gnutlsReturn < 0) { + qDebug() << "Unable to load certificate or key file." << "Error" << gnutlsReturn << "- domain-server will now quit."; + QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); + return false; + } qDebug() << "Successfully read certificate and private key. Using DTLS for node communication."; - } else if (certificateIndex != -1 || keyIndex != -1) { - // one of the certificate or private key was missing, can't use one without the other - // bail - qCritical("Missing certificate or private key. domain-server will now quit."); + } else if (certIndex != -1 || keyIndex != -1) { + qDebug() << "Missing certificate or private key. domain-server will now quit."; QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); return false; } diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index c6a9879555..244621c7b1 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -17,6 +17,8 @@ #include #include +#include + #include #include #include @@ -78,6 +80,8 @@ private: QQueue _assignmentQueue; QStringList _argumentList; + + gnutls_certificate_credentials_t _x509Credentials; }; #endif /* defined(__hifi__DomainServer__) */ diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 096431e0a4..4bfa35fac5 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -24,6 +24,8 @@ int main(int argc, char* argv[]) { setvbuf(stdout, NULL, _IOLBF, 0); #endif + gnutls_global_init(); + qInstallMessageHandler(Logging::verboseMessageHandler); DomainServer domainServer(argc, argv); diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index b260f994a3..f991212a6e 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -67,7 +67,6 @@ foreach(EXTERNAL_SOURCE_SUBDIR ${EXTERNAL_SOURCE_SUBDIRS}) endforeach(EXTERNAL_SOURCE_SUBDIR) find_package(Qt5 COMPONENTS Core Gui Multimedia Network OpenGL Script Svg WebKit WebKitWidgets Xml UiTools) -find_package(QCA REQUIRED) # grab the ui files in resources/ui file (GLOB_RECURSE QT_UI_FILES ui/*.ui) @@ -188,7 +187,7 @@ include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes" # include external library headers # use system flag so warnings are supressed -include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}" "${QCA_INCLUDE_DIR}") +include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}") target_link_libraries( ${TARGET_NAME} @@ -196,7 +195,6 @@ target_link_libraries( "${ZLIB_LIBRARIES}" Qt5::Core Qt5::Gui Qt5::Multimedia Qt5::Network Qt5::OpenGL Qt5::Script Qt5::Svg Qt5::WebKit Qt5::WebKitWidgets Qt5::Xml Qt5::UiTools - "${QCA_LIBRARY}" ) if (APPLE) From da30d21f6efeff8626aaafb2324435e8e66a2222 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 31 Mar 2014 14:02:11 -0700 Subject: [PATCH 04/86] complete inital DTLS setup in domain-server --- domain-server/src/DomainServer.cpp | 80 +++++++++++++++++++++++++++--- domain-server/src/DomainServer.h | 9 +++- libraries/shared/src/NodeList.cpp | 9 ++++ libraries/shared/src/NodeList.h | 2 + 4 files changed, 90 insertions(+), 10 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 80a86da8a0..df0935ba54 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -35,7 +35,10 @@ DomainServer::DomainServer(int argc, char* argv[]) : _HTTPManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this), _staticAssignmentHash(), _assignmentQueue(), - _x509Credentials() + _isUsingDTLS(false), + _x509Credentials(NULL), + _dhParams(NULL), + _priorityCache(NULL) { setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); @@ -44,29 +47,85 @@ DomainServer::DomainServer(int argc, char* argv[]) : _argumentList = arguments(); - if (readCertificateAndPrivateKey()) { + if (optionallySetupDTLS()) { // we either read a certificate and private key or were not passed one, good to load assignments // and set up the node list + qDebug() << "Setting up NodeList and assignments."; setupNodeListAndAssignments(); + + if (_isUsingDTLS) { + // we're using DTLS and our NodeList socket is good to go, so make the required DTLS changes + // DTLS requires that IP_DONTFRAG be set + // This is not accessible on some platforms (OS X) so we need to make sure DTLS still works without it + + NodeList* nodeList = NodeList::getInstance(); + +#if defined(IP_DONTFRAG) || defined(IP_MTU_DISCOVER) + qDebug() << "Making required DTLS changes to NodeList DTLS socket."; + + int socketHandle = NodeList::getInstance()->getDTLSSocket().socketDescriptor(); +#if defined(IP_DONTFRAG) + int optValue = 1;yea + setsockopt(socketHandle, IPPROTO_IP, IP_DONTFRAG, (const void*) optValue, sizeof(optValue)); +#elif defined(IP_MTU_DISCOVER) + int optValue = 1; + setsockopt(socketHandle, IPPROTO_IP, IP_MTU_DISCOVER, (const void*) optValue, sizeof(optValue)); +#endif +#endif + // connect our socket to read datagrams received on the DTLS socket + connect(&nodeList->getDTLSSocket(), &QUdpSocket::readyRead, this, &DomainServer::readAvailableDTLSDatagrams); + } } } -bool DomainServer::readCertificateAndPrivateKey() { +bool DomainServer::optionallySetupDTLS() { + if (readX509KeyAndCertificate()) { + qDebug() << "Generating Diffie-Hellman parameters."; + + // generate Diffie-Hellman parameters + // When short bit length is used, it might be wise to regenerate parameters often. + int dhBits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); + + _dhParams = new gnutls_dh_params_t; + gnutls_dh_params_init(_dhParams); + gnutls_dh_params_generate2(*_dhParams, dhBits); + + qDebug() << "Successfully generated Diffie-Hellman parameters."; + + // set the D-H paramters on the X509 credentials + gnutls_certificate_set_dh_params(*_x509Credentials, *_dhParams); + + _priorityCache = new gnutls_priority_t; + const char DTLS_PRIORITY_STRING[] = "PERFORMANCE:-VERS-TLS-ALL:+VERS-DTLS1.2:%SERVER_PRECEDENCE"; + gnutls_priority_init(_priorityCache, DTLS_PRIORITY_STRING, NULL); + + _isUsingDTLS = true; + + qDebug() << "Initial DTLS setup complete."; + + return true; + } else { + return false; + } +} + +bool DomainServer::readX509KeyAndCertificate() { const QString X509_CERTIFICATE_OPTION = "--cert"; const QString X509_PRIVATE_KEY_OPTION = "--key"; const QString X509_KEY_PASSPHRASE_ENV = "DOMAIN_SERVER_KEY_PASSPHRASE"; - + int certIndex = _argumentList.indexOf(X509_CERTIFICATE_OPTION); int keyIndex = _argumentList.indexOf(X509_PRIVATE_KEY_OPTION); if (certIndex != -1 && keyIndex != -1) { // the user wants to use DTLS to encrypt communication with nodes - // let's make sure we can load the ey - gnutls_certificate_allocate_credentials(&_x509Credentials); + // let's make sure we can load the key and certificate + _x509Credentials = new gnutls_certificate_credentials_t; + gnutls_certificate_allocate_credentials(_x509Credentials); QString keyPassphraseString = QProcessEnvironment::systemEnvironment().value(X509_KEY_PASSPHRASE_ENV); - int gnutlsReturn = gnutls_certificate_set_x509_key_file2(_x509Credentials, + int gnutlsReturn = gnutls_certificate_set_x509_key_file2(*_x509Credentials, _argumentList[certIndex + 1].toLocal8Bit().constData(), _argumentList[keyIndex + 1].toLocal8Bit().constData(), GNUTLS_X509_FMT_PEM, @@ -79,7 +138,8 @@ bool DomainServer::readCertificateAndPrivateKey() { return false; } - qDebug() << "Successfully read certificate and private key. Using DTLS for node communication."; + qDebug() << "Successfully read certificate and private key."; + } else if (certIndex != -1 || keyIndex != -1) { qDebug() << "Missing certificate or private key. domain-server will now quit."; QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); @@ -552,6 +612,10 @@ void DomainServer::readAvailableDatagrams() { } } +void DomainServer::readAvailableDTLSDatagrams() { + +} + QJsonObject DomainServer::jsonForSocket(const HifiSockAddr& socket) { QJsonObject socketJSON; diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 244621c7b1..ba2b47a2e7 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -45,9 +45,11 @@ private slots: void processCreateResponseFromDataServer(const QJsonObject& jsonObject); void readAvailableDatagrams(); + void readAvailableDTLSDatagrams(); private: void setupNodeListAndAssignments(const QUuid& sessionUUID = QUuid::createUuid()); - bool readCertificateAndPrivateKey(); + bool optionallySetupDTLS(); + bool readX509KeyAndCertificate(); void requestAuthenticationFromPotentialNode(const HifiSockAddr& senderSockAddr); void addNodeToNodeListAndConfirmConnection(const QByteArray& packet, const HifiSockAddr& senderSockAddr, @@ -81,7 +83,10 @@ private: QStringList _argumentList; - gnutls_certificate_credentials_t _x509Credentials; + bool _isUsingDTLS; + gnutls_certificate_credentials_t* _x509Credentials; + gnutls_dh_params_t* _dhParams; + gnutls_priority_t* _priorityCache; }; #endif /* defined(__hifi__DomainServer__) */ diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 761ea40d55..b053db356e 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -89,6 +89,15 @@ NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) : _packetStatTimer.start(); } +QUdpSocket& NodeList::getDTLSSocket() { + if (_dtlsSocket.state() == QAbstractSocket::UnconnectedState) { + _dtlsSocket.bind(QHostAddress::AnyIPv4); + qDebug() << "NodeList DTLS socket is listening on" << _dtlsSocket.localPort(); + } + + return _dtlsSocket; +} + void NodeList::changeSendSocketBufferSize(int numSendBytes) { // change the socket send buffer size to be 1MB int oldBufferSize = 0; diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index d05d6a2fbc..24281e3aa3 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -72,6 +72,7 @@ public: void setSessionUUID(const QUuid& sessionUUID); QUdpSocket& getNodeSocket() { return _nodeSocket; } + QUdpSocket& getDTLSSocket(); bool packetVersionAndHashMatch(const QByteArray& packet); @@ -165,6 +166,7 @@ private: NodeHash _nodeHash; QMutex _nodeHashMutex; QUdpSocket _nodeSocket; + QUdpSocket _dtlsSocket; NodeType_t _ownerType; NodeSet _nodeTypesOfInterest; DomainInfo _domainInfo; From 6c08e2a4075082fb5aa3683a000a8da8d615eed6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 31 Mar 2014 15:06:58 -0700 Subject: [PATCH 05/86] add option for domain-server to enforce DTLS --- cmake/modules/FindGnuTLS.cmake | 2 +- domain-server/src/DomainServer.cpp | 161 +++++++++++++---------- domain-server/src/DomainServer.h | 3 +- interface/CMakeLists.txt | 4 +- libraries/shared/CMakeLists.txt | 4 +- libraries/shared/src/DomainInfo.cpp | 44 +++---- libraries/shared/src/DomainInfo.h | 20 +-- libraries/shared/src/NodeList.cpp | 175 +++++++------------------ libraries/shared/src/NodeList.h | 6 +- libraries/shared/src/PacketHeaders.cpp | 2 +- libraries/shared/src/PacketHeaders.h | 6 +- 11 files changed, 180 insertions(+), 247 deletions(-) diff --git a/cmake/modules/FindGnuTLS.cmake b/cmake/modules/FindGnuTLS.cmake index d09ba38fb7..f56a0db7d2 100644 --- a/cmake/modules/FindGnuTLS.cmake +++ b/cmake/modules/FindGnuTLS.cmake @@ -5,7 +5,7 @@ # Once done this will define # # GNUTLS_FOUND - system found GnuTLS -# GNUTLS_INCLUDE_DIRS - the GnuTLS include directory +# GNUTLS_INCLUDE_DIR - the GnuTLS include directory # GNUTLS_LIBRARY - Link this to use GnuTLS # # Created on 3/31/2014 by Stephen Birarda diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index df0935ba54..7584b00c8d 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -180,6 +180,18 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { domainServerPort = _argumentList.value(argumentIndex + 1).toUShort(); } + unsigned short domainServerDTLSPort = -1; + + if (_isUsingDTLS) { + domainServerDTLSPort = DEFAULT_DOMAIN_SERVER_DTLS_PORT; + + const QString CUSTOM_DTLS_PORT_OPTION = "--dtlsPort"; + + if ((argumentIndex = _argumentList.indexOf(CUSTOM_DTLS_PORT_OPTION)) != -1) { + domainServerDTLSPort = _argumentList.value(argumentIndex + 1).toUShort(); + } + } + QSet parsedTypes(QSet() << Assignment::AgentType); parseCommandLineTypeConfigs(_argumentList, parsedTypes); @@ -191,7 +203,7 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { populateDefaultStaticAssignmentsExcludingTypes(parsedTypes); - NodeList* nodeList = NodeList::createInstance(NodeType::DomainServer, domainServerPort); + NodeList* nodeList = NodeList::createInstance(NodeType::DomainServer, domainServerPort, domainServerDTLSPort); // create a random UUID for this session for the domain-server nodeList->setSessionUUID(sessionUUID); @@ -519,10 +531,6 @@ void DomainServer::readAvailableDatagrams() { NodeList* nodeList = NodeList::getInstance(); HifiSockAddr senderSockAddr; - - static QByteArray assignmentPacket = byteArrayWithPopulatedHeader(PacketTypeCreateAssignment); - static int numAssignmentPacketHeaderBytes = assignmentPacket.size(); - QByteArray receivedPacket; while (nodeList->getNodeSocket().hasPendingDatagrams()) { @@ -530,22 +538,42 @@ void DomainServer::readAvailableDatagrams() { nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(), senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); - if (nodeList->packetVersionAndHashMatch(receivedPacket)) { - PacketType requestType = packetTypeForPacket(receivedPacket); + if (!_isUsingDTLS) { + // not using DTLS, process datagram normally + processDatagram(receivedPacket, senderSockAddr); + } else { + // we're using DTLS, so tell the sender to get back to us using DTLS + static QByteArray dtlsRequiredPacket = byteArrayWithPopulatedHeader(PacketTypeDomainServerRequireDTLS); + static int numBytesDTLSHeader = numBytesForPacketHeaderGivenPacketType(PacketTypeDomainServerRequireDTLS); - if (requestType == PacketTypeDomainConnectRequest) { - QDataStream packetStream(receivedPacket); - packetStream.skipRawData(numBytesForPacketHeader(receivedPacket)); - - quint8 hasRegistrationToken; - packetStream >> hasRegistrationToken; - - // we don't require authentication - add this node to our NodeList - // and send back session UUID right away - addNodeToNodeListAndConfirmConnection(receivedPacket, senderSockAddr); - - } else if (requestType == PacketTypeDomainListRequest) { - QUuid nodeUUID = uuidFromPacketHeader(receivedPacket); + if (dtlsRequiredPacket.size() == numBytesDTLSHeader) { + // pack the port that we accept DTLS traffic on + unsigned short dtlsPort = nodeList->getDTLSSocket().localPort(); + dtlsRequiredPacket.replace(numBytesDTLSHeader, sizeof(dtlsPort), reinterpret_cast(&dtlsPort)); + } + + nodeList->getNodeSocket().writeDatagram(dtlsRequiredPacket, senderSockAddr.getAddress(), senderSockAddr.getPort()); + } + } +} + +void DomainServer::readAvailableDTLSDatagrams() { + +} + +void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) { + NodeList* nodeList = NodeList::getInstance(); + + static QByteArray assignmentPacket = byteArrayWithPopulatedHeader(PacketTypeCreateAssignment); + static int numAssignmentPacketHeaderBytes = assignmentPacket.size(); + + if (nodeList->packetVersionAndHashMatch(receivedPacket)) { + PacketType requestType = packetTypeForPacket(receivedPacket); + + if (requestType == PacketTypeDomainListRequest) { + QUuid nodeUUID = uuidFromPacketHeader(receivedPacket); + + if (!nodeUUID.isNull() && nodeList->nodeWithUUID(nodeUUID)) { NodeType_t throwawayNodeType; HifiSockAddr nodePublicAddress, nodeLocalAddress; @@ -553,69 +581,68 @@ void DomainServer::readAvailableDatagrams() { receivedPacket, senderSockAddr); SharedNodePointer checkInNode = nodeList->updateSocketsForNode(nodeUUID, nodePublicAddress, nodeLocalAddress); - + // update last receive to now quint64 timeNow = usecTimestampNow(); checkInNode->setLastHeardMicrostamp(timeNow); - - + sendDomainListToNode(checkInNode, senderSockAddr, nodeInterestListFromPacket(receivedPacket, numNodeInfoBytes)); + } else { + // new node - add this node to our NodeList + // and send back session UUID right away + addNodeToNodeListAndConfirmConnection(receivedPacket, senderSockAddr); + } + + } else if (requestType == PacketTypeRequestAssignment) { + + // construct the requested assignment from the packet data + Assignment requestAssignment(receivedPacket); + + // Suppress these for Assignment::AgentType to once per 5 seconds + static quint64 lastNoisyMessage = usecTimestampNow(); + quint64 timeNow = usecTimestampNow(); + const quint64 NOISY_TIME_ELAPSED = 5 * USECS_PER_SECOND; + bool noisyMessage = false; + if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastNoisyMessage) > NOISY_TIME_ELAPSED) { + qDebug() << "Received a request for assignment type" << requestAssignment.getType() + << "from" << senderSockAddr; + noisyMessage = true; + } + + SharedAssignmentPointer assignmentToDeploy = deployableAssignmentForRequest(requestAssignment); + + if (assignmentToDeploy) { + qDebug() << "Deploying assignment -" << *assignmentToDeploy.data() << "- to" << senderSockAddr; - } else if (requestType == PacketTypeRequestAssignment) { + // give this assignment out, either the type matches or the requestor said they will take any + assignmentPacket.resize(numAssignmentPacketHeaderBytes); - // construct the requested assignment from the packet data - Assignment requestAssignment(receivedPacket); + QDataStream assignmentStream(&assignmentPacket, QIODevice::Append); - // Suppress these for Assignment::AgentType to once per 5 seconds - static quint64 lastNoisyMessage = usecTimestampNow(); - quint64 timeNow = usecTimestampNow(); - const quint64 NOISY_TIME_ELAPSED = 5 * USECS_PER_SECOND; - bool noisyMessage = false; + assignmentStream << *assignmentToDeploy.data(); + + nodeList->getNodeSocket().writeDatagram(assignmentPacket, + senderSockAddr.getAddress(), senderSockAddr.getPort()); + } else { if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastNoisyMessage) > NOISY_TIME_ELAPSED) { - qDebug() << "Received a request for assignment type" << requestAssignment.getType() + qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType() << "from" << senderSockAddr; noisyMessage = true; } - - SharedAssignmentPointer assignmentToDeploy = deployableAssignmentForRequest(requestAssignment); - - if (assignmentToDeploy) { - qDebug() << "Deploying assignment -" << *assignmentToDeploy.data() << "- to" << senderSockAddr; - - // give this assignment out, either the type matches or the requestor said they will take any - assignmentPacket.resize(numAssignmentPacketHeaderBytes); - - QDataStream assignmentStream(&assignmentPacket, QIODevice::Append); - - assignmentStream << *assignmentToDeploy.data(); - - nodeList->getNodeSocket().writeDatagram(assignmentPacket, - senderSockAddr.getAddress(), senderSockAddr.getPort()); - } else { - if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastNoisyMessage) > NOISY_TIME_ELAPSED) { - qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType() - << "from" << senderSockAddr; - noisyMessage = true; - } - } - - if (noisyMessage) { - lastNoisyMessage = timeNow; - } - } else if (requestType == PacketTypeNodeJsonStats) { - SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket); - if (matchingNode) { - reinterpret_cast(matchingNode->getLinkedData())->parseJSONStatsPacket(receivedPacket); - } + } + + if (noisyMessage) { + lastNoisyMessage = timeNow; + } + } else if (requestType == PacketTypeNodeJsonStats) { + SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket); + if (matchingNode) { + reinterpret_cast(matchingNode->getLinkedData())->parseJSONStatsPacket(receivedPacket); } } } } -void DomainServer::readAvailableDTLSDatagrams() { - -} - QJsonObject DomainServer::jsonForSocket(const HifiSockAddr& socket) { QJsonObject socketJSON; diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index ba2b47a2e7..7ee6d7374e 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -51,7 +51,8 @@ private: bool optionallySetupDTLS(); bool readX509KeyAndCertificate(); - void requestAuthenticationFromPotentialNode(const HifiSockAddr& senderSockAddr); + void processDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr); + void addNodeToNodeListAndConfirmConnection(const QByteArray& packet, const HifiSockAddr& senderSockAddr, const QJsonObject& authJsonObject = QJsonObject()); int parseNodeDataFromByteArray(NodeType_t& nodeType, HifiSockAddr& publicSockAddr, diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index f991212a6e..18210668f6 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -67,6 +67,7 @@ foreach(EXTERNAL_SOURCE_SUBDIR ${EXTERNAL_SOURCE_SUBDIRS}) endforeach(EXTERNAL_SOURCE_SUBDIR) find_package(Qt5 COMPONENTS Core Gui Multimedia Network OpenGL Script Svg WebKit WebKitWidgets Xml UiTools) +find_package(GnuTLS REQUIRED) # grab the ui files in resources/ui file (GLOB_RECURSE QT_UI_FILES ui/*.ui) @@ -187,7 +188,7 @@ include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes" # include external library headers # use system flag so warnings are supressed -include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}") +include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") target_link_libraries( ${TARGET_NAME} @@ -195,6 +196,7 @@ target_link_libraries( "${ZLIB_LIBRARIES}" Qt5::Core Qt5::Gui Qt5::Multimedia Qt5::Network Qt5::OpenGL Qt5::Script Qt5::Svg Qt5::WebKit Qt5::WebKitWidgets Qt5::Xml Qt5::UiTools + "${GNUTLS_LIBRARY}" ) if (APPLE) diff --git a/libraries/shared/CMakeLists.txt b/libraries/shared/CMakeLists.txt index 3af7272cc1..6b4dafd8d4 100644 --- a/libraries/shared/CMakeLists.txt +++ b/libraries/shared/CMakeLists.txt @@ -11,6 +11,7 @@ set(TARGET_NAME shared) project(${TARGET_NAME}) find_package(Qt5 COMPONENTS Network Widgets Xml) +find_package(GnuTLS REQUIRED) include(${MACRO_DIR}/SetupHifiLibrary.cmake) setup_hifi_library(${TARGET_NAME}) @@ -32,4 +33,5 @@ if (UNIX AND NOT APPLE) target_link_libraries(${TARGET_NAME} "${CMAKE_THREAD_LIBS_INIT}") endif (UNIX AND NOT APPLE) -target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets) +include_directories("${GNUTLS_INCLUDE_DIR}") +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/shared/src/DomainInfo.cpp b/libraries/shared/src/DomainInfo.cpp index bed638bf59..648f658619 100644 --- a/libraries/shared/src/DomainInfo.cpp +++ b/libraries/shared/src/DomainInfo.cpp @@ -8,7 +8,7 @@ #include -#include "AccountManager.h" +#include "PacketHeaders.h" #include "DomainInfo.h" @@ -16,22 +16,14 @@ DomainInfo::DomainInfo() : _uuid(), _sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)), _assignmentUUID(), - _connectionSecret(), - _registrationToken(), - _rootAuthenticationURL(), - _publicKey(), + _requiresDTLS(false), _isConnected(false) { - // clear appropriate variables after a domain-server logout - connect(&AccountManager::getInstance(), &AccountManager::logoutComplete, this, &DomainInfo::logout); + } void DomainInfo::clearConnectionInfo() { _uuid = QUuid(); - _connectionSecret = QUuid(); - _registrationToken = QByteArray(); - _rootAuthenticationURL = QUrl(); - _publicKey = QString(); _isConnected = false; } @@ -39,13 +31,7 @@ void DomainInfo::reset() { clearConnectionInfo(); _hostname = QString(); _sockAddr.setAddress(QHostAddress::Null); -} - -void DomainInfo::parseAuthInformationFromJsonObject(const QJsonObject& jsonObject) { - QJsonObject dataObject = jsonObject["data"].toObject(); - _connectionSecret = QUuid(dataObject["connection_secret"].toString()); - _registrationToken = QByteArray::fromHex(dataObject["registration_token"].toString().toUtf8()); - _publicKey = dataObject["public_key"].toString(); + _requiresDTLS = false; } void DomainInfo::setSockAddr(const HifiSockAddr& sockAddr) { @@ -114,13 +100,15 @@ void DomainInfo::setIsConnected(bool isConnected) { } } -void DomainInfo::logout() { - // clear any information related to auth for this domain, assuming it had requested auth - if (!_rootAuthenticationURL.isEmpty()) { - _rootAuthenticationURL = QUrl(); - _connectionSecret = QUuid(); - _registrationToken = QByteArray(); - _publicKey = QString(); - _isConnected = false; - } -} +void DomainInfo::parseDTLSRequirementPacket(const QByteArray& dtlsRequirementPacket) { + // figure out the port that the DS wants us to use for us to talk to them with DTLS + int numBytesPacketHeader = numBytesForPacketHeader(dtlsRequirementPacket); + + unsigned short dtlsPort = 0; + memcpy(&dtlsPort, dtlsRequirementPacket.data() + numBytesPacketHeader, sizeof(dtlsPort)); + + _sockAddr.setPort(dtlsPort); + _requiresDTLS = true; + + qDebug() << "domain-server DTLS port changed to" << dtlsPort << "- DTLS enabled."; +} \ No newline at end of file diff --git a/libraries/shared/src/DomainInfo.h b/libraries/shared/src/DomainInfo.h index da65525f9d..63c7dcbf6d 100644 --- a/libraries/shared/src/DomainInfo.h +++ b/libraries/shared/src/DomainInfo.h @@ -18,6 +18,7 @@ const QString DEFAULT_DOMAIN_HOSTNAME = "alpha.highfidelity.io"; const unsigned short DEFAULT_DOMAIN_SERVER_PORT = 40102; +const unsigned short DEFAULT_DOMAIN_SERVER_DTLS_PORT = 40103; class DomainInfo : public QObject { Q_OBJECT @@ -26,8 +27,6 @@ public: void clearConnectionInfo(); - void parseAuthInformationFromJsonObject(const QJsonObject& jsonObject); - const QUuid& getUUID() const { return _uuid; } void setUUID(const QUuid& uuid) { _uuid = uuid; } @@ -45,21 +44,13 @@ public: const QUuid& getAssignmentUUID() const { return _assignmentUUID; } void setAssignmentUUID(const QUuid& assignmentUUID) { _assignmentUUID = assignmentUUID; } - const QUuid& getConnectionSecret() const { return _connectionSecret; } - void setConnectionSecret(const QUuid& connectionSecret) { _connectionSecret = connectionSecret; } - - const QByteArray& getRegistrationToken() const { return _registrationToken; } - - const QUrl& getRootAuthenticationURL() const { return _rootAuthenticationURL; } - void setRootAuthenticationURL(const QUrl& rootAuthenticationURL) { _rootAuthenticationURL = rootAuthenticationURL; } - bool isConnected() const { return _isConnected; } void setIsConnected(bool isConnected); + void parseDTLSRequirementPacket(const QByteArray& dtlsRequirementPacket); + private slots: void completedHostnameLookup(const QHostInfo& hostInfo); - - void logout(); signals: void hostnameChanged(const QString& hostname); void connectedToDomain(const QString& hostname); @@ -70,10 +61,7 @@ private: QString _hostname; HifiSockAddr _sockAddr; QUuid _assignmentUUID; - QUuid _connectionSecret; - QByteArray _registrationToken; - QUrl _rootAuthenticationURL; - QString _publicKey; + bool _requiresDTLS; bool _isConnected; }; diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index b053db356e..bb4ff84865 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -34,11 +34,11 @@ const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://data-web.highfidelity.io"); NodeList* NodeList::_sharedInstance = NULL; -NodeList* NodeList::createInstance(char ownerType, unsigned short int socketListenPort) { +NodeList* NodeList::createInstance(char ownerType, unsigned short socketListenPort, unsigned short dtlsPort) { if (!_sharedInstance) { NodeType::init(); - _sharedInstance = new NodeList(ownerType, socketListenPort); + _sharedInstance = new NodeList(ownerType, socketListenPort, dtlsPort); // register the SharedNodePointer meta-type for signals/slots qRegisterMetaType(); @@ -58,7 +58,7 @@ NodeList* NodeList::getInstance() { } -NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) : +NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned short dtlsListenPort) : _nodeHash(), _nodeHashMutex(QMutex::Recursive), _nodeSocket(this), @@ -74,9 +74,15 @@ NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) : _numCollectedBytes(0), _packetStatTimer() { - _nodeSocket.bind(QHostAddress::AnyIPv4, newSocketListenPort); + _nodeSocket.bind(QHostAddress::AnyIPv4, socketListenPort); qDebug() << "NodeList socket is listening on" << _nodeSocket.localPort(); + if (dtlsListenPort > 0) { + // we have a specfic DTLS port, bind that socket now + _dtlsSocket.bind(QHostAddress::AnyIPv4, dtlsListenPort); + qDebug() << "NodeList DTLS socket is listening on" << _dtlsSocket.localPort(); + } + // clear our NodeList when the domain changes connect(&_domainInfo, &DomainInfo::hostnameChanged, this, &NodeList::reset); @@ -141,7 +147,7 @@ bool NodeList::packetVersionAndHashMatch(const QByteArray& packet) { } const QSet NON_VERIFIED_PACKETS = QSet() - << PacketTypeDomainServerAuthRequest << PacketTypeDomainConnectRequest + << PacketTypeDomainServerRequireDTLS << PacketTypeDomainList << PacketTypeDomainListRequest << PacketTypeStunResponse << PacketTypeDataServerConfirm << PacketTypeDataServerGet << PacketTypeDataServerPut << PacketTypeDataServerSend << PacketTypeCreateAssignment << PacketTypeRequestAssignment; @@ -158,31 +164,6 @@ bool NodeList::packetVersionAndHashMatch(const QByteArray& packet) { << uuidFromPacketHeader(packet); } } else { - if (checkType == PacketTypeDomainList) { - - if (_domainInfo.getRootAuthenticationURL().isEmpty() && _domainInfo.getUUID().isNull()) { - // if this is a domain-server that doesn't require auth, - // pull the UUID from this packet and set it as our domain-server UUID - _domainInfo.setUUID(uuidFromPacketHeader(packet)); - - // we also know this domain-server requires no authentication - // so set the account manager root URL to the default one - AccountManager::getInstance().setAuthURL(DEFAULT_NODE_AUTH_URL); - } - - if (_domainInfo.getUUID() == uuidFromPacketHeader(packet)) { - if (hashForPacketAndConnectionUUID(packet, _domainInfo.getConnectionSecret()) == hashFromPacketHeader(packet)) { - // this is a packet from the domain-server (PacketTypeDomainServerListRequest) - // and the sender UUID matches the UUID we expect for the domain - return true; - } else { - // this is a packet from the domain-server but there is a hash mismatch - qDebug() << "Packet hash mismatch on" << checkType << "from domain-server at" << _domainInfo.getHostname(); - return false; - } - } - } - qDebug() << "Packet of type" << checkType << "received from unknown node with UUID" << uuidFromPacketHeader(packet); } @@ -246,7 +227,7 @@ qint64 NodeList::sendStatsToDomainServer(const QJsonObject& statsObject) { statsPacketStream << statsObject.toVariantMap(); - return writeDatagram(statsPacket, _domainInfo.getSockAddr(), _domainInfo.getConnectionSecret()); + return writeDatagram(statsPacket, _domainInfo.getSockAddr(), QUuid()); } void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer& sendingNode) { @@ -290,10 +271,8 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteAr processDomainServerList(packet); break; } - case PacketTypeDomainServerAuthRequest: { - // the domain-server has asked us to auth via a data-server - processDomainServerAuthRequest(packet); - + case PacketTypeDomainServerRequireDTLS: { + _domainInfo.parseDTLSRequirementPacket(packet); break; } case PacketTypePing: { @@ -590,61 +569,44 @@ void NodeList::sendDomainServerCheckIn() { // send a STUN request to figure it out sendSTUNRequest(); } else if (!_domainInfo.getIP().isNull()) { - if (_domainInfo.getRootAuthenticationURL().isEmpty() - || !_sessionUUID.isNull() - || !_domainInfo.getRegistrationToken().isEmpty() ) { - // construct the DS check in packet - - PacketType domainPacketType = _sessionUUID.isNull() ? PacketTypeDomainConnectRequest : PacketTypeDomainListRequest; - - QUuid packetUUID = (domainPacketType == PacketTypeDomainListRequest) - ? _sessionUUID : _domainInfo.getAssignmentUUID(); - - QByteArray domainServerPacket = byteArrayWithPopulatedHeader(domainPacketType, packetUUID); - QDataStream packetStream(&domainServerPacket, QIODevice::Append); - - if (domainPacketType == PacketTypeDomainConnectRequest) { - // we may need a registration token to present to the domain-server - packetStream << (quint8) !_domainInfo.getRegistrationToken().isEmpty(); - - if (!_domainInfo.getRegistrationToken().isEmpty()) { - // if we have a registration token send that along in the request - packetStream << _domainInfo.getRegistrationToken(); - } - } - - // pack our data to send to the domain-server - packetStream << _ownerType << _publicSockAddr - << HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort()) - << (quint8) _nodeTypesOfInterest.size(); - - // copy over the bytes for node types of interest, if required - foreach (NodeType_t nodeTypeOfInterest, _nodeTypesOfInterest) { - packetStream << nodeTypeOfInterest; - } - - writeDatagram(domainServerPacket, _domainInfo.getSockAddr(), _domainInfo.getConnectionSecret()); - const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5; - static unsigned int numDomainCheckins = 0; - - // send a STUN request every Nth domain server check in so we update our public socket, if required - if (numDomainCheckins++ % NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST == 0) { - sendSTUNRequest(); - } - - if (_numNoReplyDomainCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { - // we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS - // so emit our signal that indicates that - emit limitOfSilentDomainCheckInsReached(); - } - - // increment the count of un-replied check-ins - _numNoReplyDomainCheckIns++; - } else if (AccountManager::getInstance().hasValidAccessToken()) { - // we have an access token we can use for the authentication server the domain-server requested - // so ask that server to provide us with information to connect to the domain-server - requestAuthForDomainServer(); + // construct the DS check in packet + + PacketType domainPacketType = _sessionUUID.isNull() ? PacketTypeDomainConnectRequest : PacketTypeDomainListRequest; + + QUuid packetUUID = (domainPacketType == PacketTypeDomainListRequest) + ? _sessionUUID : _domainInfo.getAssignmentUUID(); + + QByteArray domainServerPacket = byteArrayWithPopulatedHeader(domainPacketType, packetUUID); + QDataStream packetStream(&domainServerPacket, QIODevice::Append); + + + // pack our data to send to the domain-server + packetStream << _ownerType << _publicSockAddr + << HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort()) + << (quint8) _nodeTypesOfInterest.size(); + + // copy over the bytes for node types of interest, if required + foreach (NodeType_t nodeTypeOfInterest, _nodeTypesOfInterest) { + packetStream << nodeTypeOfInterest; } + + writeDatagram(domainServerPacket, _domainInfo.getSockAddr(), QUuid()); + const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5; + static unsigned int numDomainCheckins = 0; + + // send a STUN request every Nth domain server check in so we update our public socket, if required + if (numDomainCheckins++ % NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST == 0) { + sendSTUNRequest(); + } + + if (_numNoReplyDomainCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { + // we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS + // so emit our signal that indicates that + emit limitOfSilentDomainCheckInsReached(); + } + + // increment the count of un-replied check-ins + _numNoReplyDomainCheckIns++; } } @@ -707,41 +669,6 @@ int NodeList::processDomainServerList(const QByteArray& packet) { return readNodes; } -void NodeList::domainServerAuthReply(const QJsonObject& jsonObject) { - _domainInfo.parseAuthInformationFromJsonObject(jsonObject); -} - -void NodeList::requestAuthForDomainServer() { - JSONCallbackParameters callbackParams; - callbackParams.jsonCallbackReceiver = this; - callbackParams.jsonCallbackMethod = "domainServerAuthReply"; - - AccountManager::getInstance().authenticatedRequest("/api/v1/domains/" - + uuidStringWithoutCurlyBraces(_domainInfo.getUUID()) + "/auth.json", - QNetworkAccessManager::GetOperation, - callbackParams); -} - -void NodeList::processDomainServerAuthRequest(const QByteArray& packet) { - QDataStream authPacketStream(packet); - authPacketStream.skipRawData(numBytesForPacketHeader(packet)); - - _domainInfo.setUUID(uuidFromPacketHeader(packet)); - AccountManager& accountManager = AccountManager::getInstance(); - - // grab the hostname this domain-server wants us to authenticate with - QUrl authenticationRootURL; - authPacketStream >> authenticationRootURL; - - accountManager.setAuthURL(authenticationRootURL); - _domainInfo.setRootAuthenticationURL(authenticationRootURL); - - if (AccountManager::getInstance().checkAndSignalForAccessToken()) { - // request a domain-server auth - requestAuthForDomainServer(); - } -} - void NodeList::sendAssignment(Assignment& assignment) { PacketType assignmentPacketType = assignment.getCommand() == Assignment::CreateCommand diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 24281e3aa3..4f9b839779 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -63,7 +63,7 @@ namespace PingType { class NodeList : public QObject { Q_OBJECT public: - static NodeList* createInstance(char ownerType, unsigned short int socketListenPort = 0); + static NodeList* createInstance(char ownerType, unsigned short socketListenPort = 0, unsigned short dtlsPort = 0); static NodeList* getInstance(); NodeType_t getOwnerType() const { return _ownerType; } void setOwnerType(NodeType_t ownerType) { _ownerType = ownerType; } @@ -140,12 +140,10 @@ signals: void nodeAdded(SharedNodePointer); void nodeKilled(SharedNodePointer); void limitOfSilentDomainCheckInsReached(); -private slots: - void domainServerAuthReply(const QJsonObject& jsonObject); private: static NodeList* _sharedInstance; - NodeList(char ownerType, unsigned short int socketListenPort); + NodeList(char ownerType, unsigned short socketListenPort, unsigned short dtlsListenPort); NodeList(NodeList const&); // Don't implement, needed to avoid copies of singleton void operator=(NodeList const&); // Don't implement, needed to avoid copies of singleton void sendSTUNRequest(); diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index c7518708ce..0035f053fb 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -52,7 +52,7 @@ PacketVersion versionForPacketType(PacketType type) { return 1; case PacketTypeDomainList: case PacketTypeDomainListRequest: - return 1; + return 2; case PacketTypeCreateAssignment: case PacketTypeRequestAssignment: return 1; diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index a9bc5d3763..483fdb8a4d 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -57,9 +57,9 @@ enum PacketType { PacketTypeMetavoxelData, PacketTypeAvatarIdentity, PacketTypeAvatarBillboard, - PacketTypeDomainConnectRequest, - PacketTypeDomainServerAuthRequest, - PacketTypeNodeJsonStats + PacketTypeDomainConnectRequest, // RE-USABLE + PacketTypeDomainServerRequireDTLS, + PacketTypeNodeJsonStats, }; typedef char PacketVersion; From 62da4d622df716806d7a950676b05bfe12dc6448 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 31 Mar 2014 15:36:32 -0700 Subject: [PATCH 06/86] don't require an MD5 hash in non-verified packets --- domain-server/src/DomainServer.cpp | 4 ++-- libraries/shared/src/NodeList.cpp | 19 +++++++++-------- libraries/shared/src/NodeList.h | 1 + libraries/shared/src/PacketHeaders.cpp | 29 ++++++++++++++++---------- libraries/shared/src/PacketHeaders.h | 19 +++++++++++------ 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 7584b00c8d..a9bb6c4cfc 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -551,8 +551,8 @@ void DomainServer::readAvailableDatagrams() { unsigned short dtlsPort = nodeList->getDTLSSocket().localPort(); dtlsRequiredPacket.replace(numBytesDTLSHeader, sizeof(dtlsPort), reinterpret_cast(&dtlsPort)); } - - nodeList->getNodeSocket().writeDatagram(dtlsRequiredPacket, senderSockAddr.getAddress(), senderSockAddr.getPort()); + + nodeList->writeUnverifiedDatagram(dtlsRequiredPacket, senderSockAddr); } } } diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index bb4ff84865..167354542c 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -146,12 +146,6 @@ bool NodeList::packetVersionAndHashMatch(const QByteArray& packet) { return false; } - const QSet NON_VERIFIED_PACKETS = QSet() - << PacketTypeDomainServerRequireDTLS << PacketTypeDomainList << PacketTypeDomainListRequest - << PacketTypeStunResponse << PacketTypeDataServerConfirm - << PacketTypeDataServerGet << PacketTypeDataServerPut << PacketTypeDataServerSend - << PacketTypeCreateAssignment << PacketTypeRequestAssignment; - if (!NON_VERIFIED_PACKETS.contains(checkType)) { // figure out which node this is from SharedNodePointer sendingNode = sendingNodeForPacket(packet); @@ -178,14 +172,17 @@ qint64 NodeList::writeDatagram(const QByteArray& datagram, const HifiSockAddr& d const QUuid& connectionSecret) { QByteArray datagramCopy = datagram; - // setup the MD5 hash for source verification in the header - replaceHashInPacketGivenConnectionUUID(datagramCopy, connectionSecret); + if (!connectionSecret.isNull()) { + // setup the MD5 hash for source verification in the header + replaceHashInPacketGivenConnectionUUID(datagramCopy, connectionSecret); + } // stat collection for packets ++_numCollectedPackets; _numCollectedBytes += datagram.size(); - qint64 bytesWritten = _nodeSocket.writeDatagram(datagramCopy, destinationSockAddr.getAddress(), destinationSockAddr.getPort()); + qint64 bytesWritten = _nodeSocket.writeDatagram(datagramCopy, + destinationSockAddr.getAddress(), destinationSockAddr.getPort()); if (bytesWritten < 0) { qDebug() << "ERROR in writeDatagram:" << _nodeSocket.error() << "-" << _nodeSocket.errorString(); @@ -216,6 +213,10 @@ qint64 NodeList::writeDatagram(const QByteArray& datagram, const SharedNodePoint return 0; } +qint64 NodeList::writeUnverifiedDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr) { + return writeDatagram(datagram, destinationSockAddr, QUuid()); +} + qint64 NodeList::writeDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode, const HifiSockAddr& overridenSockAddr) { return writeDatagram(QByteArray(data, size), destinationNode, overridenSockAddr); diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 4f9b839779..613b431929 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -78,6 +78,7 @@ public: qint64 writeDatagram(const QByteArray& datagram, const SharedNodePointer& destinationNode, const HifiSockAddr& overridenSockAddr = HifiSockAddr()); + qint64 writeUnverifiedDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr); qint64 writeDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode, const HifiSockAddr& overridenSockAddr = HifiSockAddr()); qint64 sendStatsToDomainServer(const QJsonObject& statsObject); diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index 0035f053fb..da8de0ddb0 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -56,11 +56,6 @@ PacketVersion versionForPacketType(PacketType type) { case PacketTypeCreateAssignment: case PacketTypeRequestAssignment: return 1; - case PacketTypeDataServerGet: - case PacketTypeDataServerPut: - case PacketTypeDataServerConfirm: - case PacketTypeDataServerSend: - return 1; case PacketTypeVoxelSet: case PacketTypeVoxelSetDestructive: return 1; @@ -95,9 +90,11 @@ int populatePacketHeader(char* packet, PacketType type, const QUuid& connectionU memcpy(position, rfcUUID.constData(), NUM_BYTES_RFC4122_UUID); position += NUM_BYTES_RFC4122_UUID; - // pack 16 bytes of zeros where the md5 hash will be placed one data is packed - memset(position, 0, NUM_BYTES_MD5_HASH); - position += NUM_BYTES_MD5_HASH; + if (!NON_VERIFIED_PACKETS.contains(type)) { + // pack 16 bytes of zeros where the md5 hash will be placed one data is packed + memset(position, 0, NUM_BYTES_MD5_HASH); + position += NUM_BYTES_MD5_HASH; + } // return the number of bytes written for pointer pushing return position - packet; @@ -105,16 +102,26 @@ int populatePacketHeader(char* packet, PacketType type, const QUuid& connectionU int numBytesForPacketHeader(const QByteArray& packet) { // returns the number of bytes used for the type, version, and UUID - return numBytesArithmeticCodingFromBuffer(packet.data()) + NUM_STATIC_HEADER_BYTES; + return numBytesArithmeticCodingFromBuffer(packet.data()) + + numHashBytesInPacketHeaderGivenPacketType(packetTypeForPacket(packet)) + + NUM_STATIC_HEADER_BYTES; } int numBytesForPacketHeader(const char* packet) { // returns the number of bytes used for the type, version, and UUID - return numBytesArithmeticCodingFromBuffer(packet) + NUM_STATIC_HEADER_BYTES; + return numBytesArithmeticCodingFromBuffer(packet) + + numHashBytesInPacketHeaderGivenPacketType(packetTypeForPacket(packet)) + + NUM_STATIC_HEADER_BYTES; } int numBytesForPacketHeaderGivenPacketType(PacketType type) { - return (int) ceilf((float)type / 255) + NUM_STATIC_HEADER_BYTES; + return (int) ceilf((float)type / 255) + + numHashBytesInPacketHeaderGivenPacketType(type) + + NUM_STATIC_HEADER_BYTES; +} + +int numHashBytesInPacketHeaderGivenPacketType(PacketType type) { + return (NON_VERIFIED_PACKETS.contains(type) ? 0 : NUM_BYTES_MD5_HASH); } QUuid uuidFromPacketHeader(const QByteArray& packet) { diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index 483fdb8a4d..0250fb038a 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -13,6 +13,7 @@ #define hifi_PacketHeaders_h #include +#include #include #include "UUID.h" @@ -37,9 +38,9 @@ enum PacketType { PacketTypeDomainListRequest, PacketTypeRequestAssignment, PacketTypeCreateAssignment, - PacketTypeDataServerPut, - PacketTypeDataServerGet, - PacketTypeDataServerSend, + PacketTypeDataServerPut, // reusable + PacketTypeDataServerGet, // reusable + PacketTypeDataServerSend, // reusable PacketTypeDataServerConfirm, PacketTypeVoxelQuery, PacketTypeVoxelData, @@ -57,16 +58,20 @@ enum PacketType { PacketTypeMetavoxelData, PacketTypeAvatarIdentity, PacketTypeAvatarBillboard, - PacketTypeDomainConnectRequest, // RE-USABLE + PacketTypeDomainConnectRequest, // reusable PacketTypeDomainServerRequireDTLS, PacketTypeNodeJsonStats, }; typedef char PacketVersion; +const QSet NON_VERIFIED_PACKETS = QSet() + << PacketTypeDomainServerRequireDTLS << PacketTypeDomainList << PacketTypeDomainListRequest + << PacketTypeCreateAssignment << PacketTypeRequestAssignment << PacketTypeStunResponse; + const int NUM_BYTES_MD5_HASH = 16; -const int NUM_STATIC_HEADER_BYTES = sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH; -const int MAX_PACKET_HEADER_BYTES = sizeof(PacketType) + NUM_STATIC_HEADER_BYTES; +const int NUM_STATIC_HEADER_BYTES = sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID; +const int MAX_PACKET_HEADER_BYTES = sizeof(PacketType) + NUM_BYTES_MD5_HASH + NUM_STATIC_HEADER_BYTES; PacketVersion versionForPacketType(PacketType type); @@ -76,6 +81,8 @@ QByteArray byteArrayWithPopulatedHeader(PacketType type, const QUuid& connection int populatePacketHeader(QByteArray& packet, PacketType type, const QUuid& connectionUUID = nullUUID); int populatePacketHeader(char* packet, PacketType type, const QUuid& connectionUUID = nullUUID); +int numHashBytesInPacketHeaderGivenPacketType(PacketType type); + int numBytesForPacketHeader(const QByteArray& packet); int numBytesForPacketHeader(const char* packet); int numBytesForPacketHeaderGivenPacketType(PacketType type); From caf2473df82741db635097b8f03a2ec1e4f44976 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 1 Apr 2014 13:08:00 -0700 Subject: [PATCH 07/86] add a DTLSSession object to handle GnuTLS DTLS sessions --- assignment-client/src/AssignmentClient.cpp | 4 + domain-server/src/DomainServer.cpp | 168 +++++++++++---------- domain-server/src/main.cpp | 2 - libraries/shared/src/DTLSSession.cpp | 43 ++++++ libraries/shared/src/DTLSSession.h | 32 ++++ libraries/shared/src/DomainInfo.cpp | 21 ++- libraries/shared/src/DomainInfo.h | 7 +- libraries/shared/src/NodeList.cpp | 23 +-- libraries/shared/src/NodeList.h | 4 +- 9 files changed, 206 insertions(+), 98 deletions(-) create mode 100644 libraries/shared/src/DTLSSession.cpp create mode 100644 libraries/shared/src/DTLSSession.h diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index aa20f2ff29..7da87e4e5d 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -10,6 +10,8 @@ #include #include +#include + #include #include #include @@ -31,6 +33,8 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : QCoreApplication(argc, argv), _currentAssignment() { + gnutls_global_init(); + setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); setApplicationName("assignment-client"); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index a9bb6c4cfc..d6fc91c8e7 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -39,7 +39,9 @@ DomainServer::DomainServer(int argc, char* argv[]) : _x509Credentials(NULL), _dhParams(NULL), _priorityCache(NULL) -{ +{ + gnutls_global_init(); + setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); setApplicationName("domain-server"); @@ -80,28 +82,30 @@ DomainServer::DomainServer(int argc, char* argv[]) : bool DomainServer::optionallySetupDTLS() { if (readX509KeyAndCertificate()) { - qDebug() << "Generating Diffie-Hellman parameters."; - - // generate Diffie-Hellman parameters - // When short bit length is used, it might be wise to regenerate parameters often. - int dhBits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); - - _dhParams = new gnutls_dh_params_t; - gnutls_dh_params_init(_dhParams); - gnutls_dh_params_generate2(*_dhParams, dhBits); - - qDebug() << "Successfully generated Diffie-Hellman parameters."; - - // set the D-H paramters on the X509 credentials - gnutls_certificate_set_dh_params(*_x509Credentials, *_dhParams); - - _priorityCache = new gnutls_priority_t; - const char DTLS_PRIORITY_STRING[] = "PERFORMANCE:-VERS-TLS-ALL:+VERS-DTLS1.2:%SERVER_PRECEDENCE"; - gnutls_priority_init(_priorityCache, DTLS_PRIORITY_STRING, NULL); - - _isUsingDTLS = true; - - qDebug() << "Initial DTLS setup complete."; + if (_x509Credentials) { + qDebug() << "Generating Diffie-Hellman parameters."; + + // generate Diffie-Hellman parameters + // When short bit length is used, it might be wise to regenerate parameters often. + int dhBits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); + + _dhParams = new gnutls_dh_params_t; + gnutls_dh_params_init(_dhParams); + gnutls_dh_params_generate2(*_dhParams, dhBits); + + qDebug() << "Successfully generated Diffie-Hellman parameters."; + + // set the D-H paramters on the X509 credentials + gnutls_certificate_set_dh_params(*_x509Credentials, *_dhParams); + + _priorityCache = new gnutls_priority_t; + const char DTLS_PRIORITY_STRING[] = "PERFORMANCE:-VERS-TLS-ALL:+VERS-DTLS1.2:%SERVER_PRECEDENCE"; + gnutls_priority_init(_priorityCache, DTLS_PRIORITY_STRING, NULL); + + _isUsingDTLS = true; + + qDebug() << "Initial DTLS setup complete."; + } return true; } else { @@ -180,7 +184,7 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { domainServerPort = _argumentList.value(argumentIndex + 1).toUShort(); } - unsigned short domainServerDTLSPort = -1; + unsigned short domainServerDTLSPort = 0; if (_isUsingDTLS) { domainServerDTLSPort = DEFAULT_DOMAIN_SERVER_DTLS_PORT; @@ -532,69 +536,17 @@ void DomainServer::readAvailableDatagrams() { HifiSockAddr senderSockAddr; QByteArray receivedPacket; + + + static QByteArray assignmentPacket = byteArrayWithPopulatedHeader(PacketTypeCreateAssignment); + static int numAssignmentPacketHeaderBytes = assignmentPacket.size(); while (nodeList->getNodeSocket().hasPendingDatagrams()) { receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize()); nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(), senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); - - if (!_isUsingDTLS) { - // not using DTLS, process datagram normally - processDatagram(receivedPacket, senderSockAddr); - } else { - // we're using DTLS, so tell the sender to get back to us using DTLS - static QByteArray dtlsRequiredPacket = byteArrayWithPopulatedHeader(PacketTypeDomainServerRequireDTLS); - static int numBytesDTLSHeader = numBytesForPacketHeaderGivenPacketType(PacketTypeDomainServerRequireDTLS); - - if (dtlsRequiredPacket.size() == numBytesDTLSHeader) { - // pack the port that we accept DTLS traffic on - unsigned short dtlsPort = nodeList->getDTLSSocket().localPort(); - dtlsRequiredPacket.replace(numBytesDTLSHeader, sizeof(dtlsPort), reinterpret_cast(&dtlsPort)); - } + if (packetTypeForPacket(receivedPacket) && nodeList->packetVersionAndHashMatch(receivedPacket)) { - nodeList->writeUnverifiedDatagram(dtlsRequiredPacket, senderSockAddr); - } - } -} - -void DomainServer::readAvailableDTLSDatagrams() { - -} - -void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) { - NodeList* nodeList = NodeList::getInstance(); - - static QByteArray assignmentPacket = byteArrayWithPopulatedHeader(PacketTypeCreateAssignment); - static int numAssignmentPacketHeaderBytes = assignmentPacket.size(); - - if (nodeList->packetVersionAndHashMatch(receivedPacket)) { - PacketType requestType = packetTypeForPacket(receivedPacket); - - if (requestType == PacketTypeDomainListRequest) { - QUuid nodeUUID = uuidFromPacketHeader(receivedPacket); - - if (!nodeUUID.isNull() && nodeList->nodeWithUUID(nodeUUID)) { - NodeType_t throwawayNodeType; - HifiSockAddr nodePublicAddress, nodeLocalAddress; - - int numNodeInfoBytes = parseNodeDataFromByteArray(throwawayNodeType, nodePublicAddress, nodeLocalAddress, - receivedPacket, senderSockAddr); - - SharedNodePointer checkInNode = nodeList->updateSocketsForNode(nodeUUID, nodePublicAddress, nodeLocalAddress); - - // update last receive to now - quint64 timeNow = usecTimestampNow(); - checkInNode->setLastHeardMicrostamp(timeNow); - - sendDomainListToNode(checkInNode, senderSockAddr, nodeInterestListFromPacket(receivedPacket, numNodeInfoBytes)); - } else { - // new node - add this node to our NodeList - // and send back session UUID right away - addNodeToNodeListAndConfirmConnection(receivedPacket, senderSockAddr); - } - - } else if (requestType == PacketTypeRequestAssignment) { - // construct the requested assignment from the packet data Assignment requestAssignment(receivedPacket); @@ -626,7 +578,7 @@ void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiS } else { if (requestAssignment.getType() != Assignment::AgentType || (timeNow - lastNoisyMessage) > NOISY_TIME_ELAPSED) { qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType() - << "from" << senderSockAddr; + << "from" << senderSockAddr; noisyMessage = true; } } @@ -634,6 +586,58 @@ void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiS if (noisyMessage) { lastNoisyMessage = timeNow; } + } else if (!_isUsingDTLS) { + // not using DTLS, process datagram normally + processDatagram(receivedPacket, senderSockAddr); + } else { + // we're using DTLS, so tell the sender to get back to us using DTLS + static QByteArray dtlsRequiredPacket = byteArrayWithPopulatedHeader(PacketTypeDomainServerRequireDTLS); + static int numBytesDTLSHeader = numBytesForPacketHeaderGivenPacketType(PacketTypeDomainServerRequireDTLS); + + if (dtlsRequiredPacket.size() == numBytesDTLSHeader) { + // pack the port that we accept DTLS traffic on + unsigned short dtlsPort = nodeList->getDTLSSocket().localPort(); + dtlsRequiredPacket.replace(numBytesDTLSHeader, sizeof(dtlsPort), reinterpret_cast(&dtlsPort)); + } + + nodeList->writeUnverifiedDatagram(dtlsRequiredPacket, senderSockAddr); + } + } +} + +void DomainServer::readAvailableDTLSDatagrams() { + +} + +void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) { + NodeList* nodeList = NodeList::getInstance(); + + if (nodeList->packetVersionAndHashMatch(receivedPacket)) { + PacketType requestType = packetTypeForPacket(receivedPacket); + + if (requestType == PacketTypeDomainListRequest) { + QUuid nodeUUID = uuidFromPacketHeader(receivedPacket); + + if (!nodeUUID.isNull() && nodeList->nodeWithUUID(nodeUUID)) { + NodeType_t throwawayNodeType; + HifiSockAddr nodePublicAddress, nodeLocalAddress; + + int numNodeInfoBytes = parseNodeDataFromByteArray(throwawayNodeType, nodePublicAddress, nodeLocalAddress, + receivedPacket, senderSockAddr); + + SharedNodePointer checkInNode = nodeList->updateSocketsForNode(nodeUUID, nodePublicAddress, nodeLocalAddress); + + // update last receive to now + quint64 timeNow = usecTimestampNow(); + checkInNode->setLastHeardMicrostamp(timeNow); + + sendDomainListToNode(checkInNode, senderSockAddr, nodeInterestListFromPacket(receivedPacket, numNodeInfoBytes)); + } else { + // new node - add this node to our NodeList + // and send back session UUID right away + addNodeToNodeListAndConfirmConnection(receivedPacket, senderSockAddr); + } + } else if (requestType == PacketTypeNodeJsonStats) { SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket); if (matchingNode) { diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 4bfa35fac5..096431e0a4 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -24,8 +24,6 @@ int main(int argc, char* argv[]) { setvbuf(stdout, NULL, _IOLBF, 0); #endif - gnutls_global_init(); - qInstallMessageHandler(Logging::verboseMessageHandler); DomainServer domainServer(argc, argv); diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp new file mode 100644 index 0000000000..ce14d91f27 --- /dev/null +++ b/libraries/shared/src/DTLSSession.cpp @@ -0,0 +1,43 @@ +// +// DTLSSession.cpp +// hifi +// +// Created by Stephen Birarda on 2014-04-01. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// + +#include "DTLSSession.h" + +static int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms) { + return 1; +} + +static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size) { + DTLSSession* session = static_cast(ptr); + QUdpSocket& dtlsSocket = session->_dtlsSocket; + + if (dtlsSocket.hasPendingDatagrams()) { + return dtlsSocket.read(reinterpret_cast(buffer), size); + } else { + gnutls_transport_set_errno(session->_gnutlsSession, GNUTLS_E_AGAIN); + return 0; + } +} + +static ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size) { + DTLSSession* session = static_cast(ptr); + QUdpSocket& dtlsSocket = session->_dtlsSocket; + + if (dtlsSocket.state() != QAbstractSocket::ConnectedState) { + gnutls_transport_set_errno(session->_gnutlsSession, GNUTLS_E_AGAIN); + return -1; + } + + return dtlsSocket.write(reinterpret_cast(buffer), size); +} + +DTLSSession::DTLSSession(QUdpSocket& dtlsSocket) : + _dtlsSocket(dtlsSocket) +{ + +} \ No newline at end of file diff --git a/libraries/shared/src/DTLSSession.h b/libraries/shared/src/DTLSSession.h new file mode 100644 index 0000000000..190373c155 --- /dev/null +++ b/libraries/shared/src/DTLSSession.h @@ -0,0 +1,32 @@ +// +// DTLSSession.h +// hifi +// +// Created by Stephen Birarda on 2014-04-01. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__DTLSSession__ +#define __hifi__DTLSSession__ + +#include + +#include + +static int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms); +static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size); +static ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size); + +class DTLSSession { +public: + DTLSSession(QUdpSocket& dtlsSocket); + + friend int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms); + friend ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size); + friend ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size); +private: + QUdpSocket& _dtlsSocket; + gnutls_session_t _gnutlsSession; +}; + +#endif /* defined(__hifi__DTLSSession__) */ diff --git a/libraries/shared/src/DomainInfo.cpp b/libraries/shared/src/DomainInfo.cpp index 648f658619..1a360d1150 100644 --- a/libraries/shared/src/DomainInfo.cpp +++ b/libraries/shared/src/DomainInfo.cpp @@ -6,8 +6,9 @@ // Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // -#include +#include +#include "NodeList.h" #include "PacketHeaders.h" #include "DomainInfo.h" @@ -16,12 +17,17 @@ DomainInfo::DomainInfo() : _uuid(), _sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)), _assignmentUUID(), + _isConnected(false), _requiresDTLS(false), - _isConnected(false) + _dtlsSession(NULL) { } +DomainInfo::~DomainInfo() { + delete _dtlsSession; +} + void DomainInfo::clearConnectionInfo() { _uuid = QUuid(); _isConnected = false; @@ -34,6 +40,12 @@ void DomainInfo::reset() { _requiresDTLS = false; } +void DomainInfo::initializeDTLSSession() { + if (!_dtlsSession) { + _dtlsSession = new DTLSSession(NodeList::getInstance()->getDTLSSocket()); + } +} + void DomainInfo::setSockAddr(const HifiSockAddr& sockAddr) { if (_sockAddr != sockAddr) { // we should reset on a sockAddr change @@ -107,8 +119,11 @@ void DomainInfo::parseDTLSRequirementPacket(const QByteArray& dtlsRequirementPac unsigned short dtlsPort = 0; memcpy(&dtlsPort, dtlsRequirementPacket.data() + numBytesPacketHeader, sizeof(dtlsPort)); + + qDebug() << "domain-server DTLS port changed to" << dtlsPort << "- Enabling DTLS."; + _sockAddr.setPort(dtlsPort); _requiresDTLS = true; - qDebug() << "domain-server DTLS port changed to" << dtlsPort << "- DTLS enabled."; + initializeDTLSSession(); } \ No newline at end of file diff --git a/libraries/shared/src/DomainInfo.h b/libraries/shared/src/DomainInfo.h index 63c7dcbf6d..71a0caabe0 100644 --- a/libraries/shared/src/DomainInfo.h +++ b/libraries/shared/src/DomainInfo.h @@ -14,6 +14,7 @@ #include #include +#include "DTLSSession.h" #include "HifiSockAddr.h" const QString DEFAULT_DOMAIN_HOSTNAME = "alpha.highfidelity.io"; @@ -24,6 +25,7 @@ class DomainInfo : public QObject { Q_OBJECT public: DomainInfo(); + ~DomainInfo(); void clearConnectionInfo(); @@ -54,15 +56,18 @@ private slots: signals: void hostnameChanged(const QString& hostname); void connectedToDomain(const QString& hostname); + void initializedDTLSSession(); private: void reset(); + void initializeDTLSSession(); QUuid _uuid; QString _hostname; HifiSockAddr _sockAddr; QUuid _assignmentUUID; - bool _requiresDTLS; bool _isConnected; + bool _requiresDTLS; + DTLSSession* _dtlsSession; }; #endif /* defined(__hifi__DomainInfo__) */ diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 167354542c..56986b4cc8 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -62,6 +62,7 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned _nodeHash(), _nodeHashMutex(QMutex::Recursive), _nodeSocket(this), + _dtlsSocket(NULL), _ownerType(newOwnerType), _nodeTypesOfInterest(), _sessionUUID(), @@ -78,9 +79,11 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned qDebug() << "NodeList socket is listening on" << _nodeSocket.localPort(); if (dtlsListenPort > 0) { - // we have a specfic DTLS port, bind that socket now - _dtlsSocket.bind(QHostAddress::AnyIPv4, dtlsListenPort); - qDebug() << "NodeList DTLS socket is listening on" << _dtlsSocket.localPort(); + // only create the DTLS socket during constructor if a custom port is passed + _dtlsSocket = new QUdpSocket(this); + + _dtlsSocket->bind(QHostAddress::AnyIPv4, dtlsListenPort); + qDebug() << "NodeList DTLS socket is listening on" << _dtlsSocket->localPort(); } // clear our NodeList when the domain changes @@ -96,12 +99,15 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned } QUdpSocket& NodeList::getDTLSSocket() { - if (_dtlsSocket.state() == QAbstractSocket::UnconnectedState) { - _dtlsSocket.bind(QHostAddress::AnyIPv4); - qDebug() << "NodeList DTLS socket is listening on" << _dtlsSocket.localPort(); + if (!_dtlsSocket) { + // DTLS socket getter called but no DTLS socket exists, create it now + _dtlsSocket = new QUdpSocket(this); + + _dtlsSocket->bind(QHostAddress::AnyIPv4, 0, QAbstractSocket::DontShareAddress); + qDebug() << "NodeList DTLS socket is listening on" << _dtlsSocket->localPort(); } - return _dtlsSocket; + return *_dtlsSocket; } void NodeList::changeSendSocketBufferSize(int numSendBytes) { @@ -569,7 +575,7 @@ void NodeList::sendDomainServerCheckIn() { // 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 (!_domainInfo.getIP().isNull()) { + } else if (!_domainInfo.getIP().isNull()) { // construct the DS check in packet PacketType domainPacketType = _sessionUUID.isNull() ? PacketTypeDomainConnectRequest : PacketTypeDomainListRequest; @@ -580,7 +586,6 @@ void NodeList::sendDomainServerCheckIn() { QByteArray domainServerPacket = byteArrayWithPopulatedHeader(domainPacketType, packetUUID); QDataStream packetStream(&domainServerPacket, QIODevice::Append); - // pack our data to send to the domain-server packetStream << _ownerType << _publicSockAddr << HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort()) diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 613b431929..b12174296b 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -29,6 +29,8 @@ #include #include +#include + #include "DomainInfo.h" #include "Node.h" @@ -165,7 +167,7 @@ private: NodeHash _nodeHash; QMutex _nodeHashMutex; QUdpSocket _nodeSocket; - QUdpSocket _dtlsSocket; + QUdpSocket* _dtlsSocket; NodeType_t _ownerType; NodeSet _nodeTypesOfInterest; DomainInfo _domainInfo; From 62041d91a8682fd25dd14710b0b593f0b97177fe Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 1 Apr 2014 13:09:35 -0700 Subject: [PATCH 08/86] rename NodeList DomainInfo to DomainHandler --- animation-server/src/AnimationServer.cpp | 4 +-- assignment-client/src/Agent.cpp | 2 +- assignment-client/src/AssignmentClient.cpp | 6 ++--- interface/src/Application.cpp | 6 ++--- interface/src/Menu.cpp | 12 ++++----- interface/src/avatar/MyAvatar.cpp | 2 +- interface/src/ui/Snapshot.cpp | 2 +- .../src/{DomainInfo.cpp => DomainHandler.cpp} | 24 ++++++++--------- .../src/{DomainInfo.h => DomainHandler.h} | 14 +++++----- libraries/shared/src/NodeList.cpp | 26 +++++++++---------- libraries/shared/src/NodeList.h | 6 ++--- 11 files changed, 52 insertions(+), 52 deletions(-) rename libraries/shared/src/{DomainInfo.cpp => DomainHandler.cpp} (85%) rename libraries/shared/src/{DomainInfo.h => DomainHandler.h} (90%) diff --git a/animation-server/src/AnimationServer.cpp b/animation-server/src/AnimationServer.cpp index 1f0828ec17..e66ca35501 100644 --- a/animation-server/src/AnimationServer.cpp +++ b/animation-server/src/AnimationServer.cpp @@ -723,12 +723,12 @@ AnimationServer::AnimationServer(int &argc, char **argv) : ::wantLocalDomain = cmdOptionExists(argc, (const char**) argv,local); if (::wantLocalDomain) { printf("Local Domain MODE!\n"); - nodeList->getDomainInfo().setIPToLocalhost(); + nodeList->getDomainHandler().setIPToLocalhost(); } const char* domainHostname = getCmdOption(argc, (const char**) argv, "--domain"); if (domainHostname) { - NodeList::getInstance()->getDomainInfo().setHostname(domainHostname); + NodeList::getInstance()->getDomainHandler().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 b5199e87e8..4203ec02dc 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -146,7 +146,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()->getDomainInfo().getIP().toString(), + scriptURLString = scriptURLString.arg(NodeList::getInstance()->getDomainHandler().getIP().toString(), uuidStringWithoutCurlyBraces(_uuid)); QNetworkAccessManager *networkManager = new QNetworkAccessManager(this); diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 7da87e4e5d..046f362e1e 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -136,10 +136,10 @@ void AssignmentClient::readPendingDatagrams() { // switch our nodelist domain IP and port to whoever sent us the assignment - nodeList->getDomainInfo().setSockAddr(senderSockAddr); - nodeList->getDomainInfo().setAssignmentUUID(_currentAssignment->getUUID()); + nodeList->getDomainHandler().setSockAddr(senderSockAddr); + nodeList->getDomainHandler().setAssignmentUUID(_currentAssignment->getUUID()); - qDebug() << "Destination IP for assignment is" << nodeList->getDomainInfo().getIP().toString(); + qDebug() << "Destination IP for assignment is" << nodeList->getDomainHandler().getIP().toString(); // start the deployed assignment AssignmentThread* workerThread = new AssignmentThread(_currentAssignment, this); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c6fc522fca..4ffdf5b2b7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -228,8 +228,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : audioThread->start(); - connect(&nodeList->getDomainInfo(), SIGNAL(hostnameChanged(const QString&)), SLOT(domainChanged(const QString&))); - connect(&nodeList->getDomainInfo(), SIGNAL(connectedToDomain(const QString&)), SLOT(connectedToDomain(const QString&))); + connect(&nodeList->getDomainHandler(), SIGNAL(hostnameChanged(const QString&)), SLOT(domainChanged(const QString&))); + connect(&nodeList->getDomainHandler(), SIGNAL(connectedToDomain(const QString&)), SLOT(connectedToDomain(const QString&))); connect(nodeList, &NodeList::nodeAdded, this, &Application::nodeAdded); connect(nodeList, &NodeList::nodeKilled, this, &Application::nodeKilled); @@ -3279,7 +3279,7 @@ void Application::updateWindowTitle(){ QString username = AccountManager::getInstance().getUsername(); QString title = QString() + (!username.isEmpty() ? username + " " : QString()) + nodeList->getSessionUUID().toString() - + " @ " + nodeList->getDomainInfo().getHostname() + buildVersion; + + " @ " + nodeList->getDomainHandler().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 7748c466c7..ebb817deb3 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -863,23 +863,23 @@ void Menu::editPreferences() { } void Menu::goToDomain(const QString newDomain) { - if (NodeList::getInstance()->getDomainInfo().getHostname() != newDomain) { + if (NodeList::getInstance()->getDomainHandler().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()->getDomainInfo().setHostname(newDomain); + NodeList::getInstance()->getDomainHandler().setHostname(newDomain); } } void Menu::goToDomainDialog() { - QString currentDomainHostname = NodeList::getInstance()->getDomainInfo().getHostname(); + QString currentDomainHostname = NodeList::getInstance()->getDomainHandler().getHostname(); - if (NodeList::getInstance()->getDomainInfo().getPort() != DEFAULT_DOMAIN_SERVER_PORT) { + if (NodeList::getInstance()->getDomainHandler().getPort() != DEFAULT_DOMAIN_SERVER_PORT) { // add the port to the currentDomainHostname string if it is custom - currentDomainHostname.append(QString(":%1").arg(NodeList::getInstance()->getDomainInfo().getPort())); + currentDomainHostname.append(QString(":%1").arg(NodeList::getInstance()->getDomainHandler().getPort())); } QInputDialog domainDialog(Application::getInstance()->getWindow()); @@ -1034,7 +1034,7 @@ void Menu::nameLocation() { connect(manager, &LocationManager::creationCompleted, this, &Menu::namedLocationCreated); NamedLocation* location = new NamedLocation(locationName, myAvatar->getPosition(), myAvatar->getOrientation(), - NodeList::getInstance()->getDomainInfo().getHostname()); + NodeList::getInstance()->getDomainHandler().getHostname()); manager->createNamedLocation(location); } } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 62ba24a384..4fadd98cdd 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1129,7 +1129,7 @@ void MyAvatar::goToLocationFromResponse(const QJsonObject& jsonObject) { QStringList coordinateItems = positionString.split(','); QStringList orientationItems = orientationString.split(','); - NodeList::getInstance()->getDomainInfo().setHostname(domainHostnameString); + NodeList::getInstance()->getDomainHandler().setHostname(domainHostnameString); // orient the user to face the target glm::quat newOrientation = glm::quat(glm::radians(glm::vec3(orientationItems[0].toFloat(), diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index a29a96f009..dec69498ed 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -76,7 +76,7 @@ void Snapshot::saveSnapshot(QGLWidget* widget, Avatar* avatar) { shot.setText(ORIENTATION_Z, QString::number(orientation.z)); shot.setText(ORIENTATION_W, QString::number(orientation.w)); - shot.setText(DOMAIN_KEY, NodeList::getInstance()->getDomainInfo().getHostname()); + shot.setText(DOMAIN_KEY, NodeList::getInstance()->getDomainHandler().getHostname()); QString formattedLocation = QString("%1_%2_%3").arg(location.x).arg(location.y).arg(location.z); // replace decimal . with '-' diff --git a/libraries/shared/src/DomainInfo.cpp b/libraries/shared/src/DomainHandler.cpp similarity index 85% rename from libraries/shared/src/DomainInfo.cpp rename to libraries/shared/src/DomainHandler.cpp index 1a360d1150..52bfa04414 100644 --- a/libraries/shared/src/DomainInfo.cpp +++ b/libraries/shared/src/DomainHandler.cpp @@ -1,5 +1,5 @@ // -// DomainInfo.cpp +// DomainHandler.cpp // hifi // // Created by Stephen Birarda on 2/18/2014. @@ -11,9 +11,9 @@ #include "NodeList.h" #include "PacketHeaders.h" -#include "DomainInfo.h" +#include "DomainHandler.h" -DomainInfo::DomainInfo() : +DomainHandler::DomainHandler() : _uuid(), _sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)), _assignmentUUID(), @@ -24,29 +24,29 @@ DomainInfo::DomainInfo() : } -DomainInfo::~DomainInfo() { +DomainHandler::~DomainHandler() { delete _dtlsSession; } -void DomainInfo::clearConnectionInfo() { +void DomainHandler::clearConnectionInfo() { _uuid = QUuid(); _isConnected = false; } -void DomainInfo::reset() { +void DomainHandler::reset() { clearConnectionInfo(); _hostname = QString(); _sockAddr.setAddress(QHostAddress::Null); _requiresDTLS = false; } -void DomainInfo::initializeDTLSSession() { +void DomainHandler::initializeDTLSSession() { if (!_dtlsSession) { _dtlsSession = new DTLSSession(NodeList::getInstance()->getDTLSSocket()); } } -void DomainInfo::setSockAddr(const HifiSockAddr& sockAddr) { +void DomainHandler::setSockAddr(const HifiSockAddr& sockAddr) { if (_sockAddr != sockAddr) { // we should reset on a sockAddr change reset(); @@ -55,7 +55,7 @@ void DomainInfo::setSockAddr(const HifiSockAddr& sockAddr) { } } -void DomainInfo::setHostname(const QString& hostname) { +void DomainHandler::setHostname(const QString& hostname) { if (hostname != _hostname) { // re-set the domain info so that auth information is reloaded @@ -88,7 +88,7 @@ void DomainInfo::setHostname(const QString& hostname) { } } -void DomainInfo::completedHostnameLookup(const QHostInfo& hostInfo) { +void DomainHandler::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]); @@ -102,7 +102,7 @@ void DomainInfo::completedHostnameLookup(const QHostInfo& hostInfo) { qDebug("Failed domain server lookup"); } -void DomainInfo::setIsConnected(bool isConnected) { +void DomainHandler::setIsConnected(bool isConnected) { if (_isConnected != isConnected) { _isConnected = isConnected; @@ -112,7 +112,7 @@ void DomainInfo::setIsConnected(bool isConnected) { } } -void DomainInfo::parseDTLSRequirementPacket(const QByteArray& dtlsRequirementPacket) { +void DomainHandler::parseDTLSRequirementPacket(const QByteArray& dtlsRequirementPacket) { // figure out the port that the DS wants us to use for us to talk to them with DTLS int numBytesPacketHeader = numBytesForPacketHeader(dtlsRequirementPacket); diff --git a/libraries/shared/src/DomainInfo.h b/libraries/shared/src/DomainHandler.h similarity index 90% rename from libraries/shared/src/DomainInfo.h rename to libraries/shared/src/DomainHandler.h index 71a0caabe0..4a9f166963 100644 --- a/libraries/shared/src/DomainInfo.h +++ b/libraries/shared/src/DomainHandler.h @@ -1,13 +1,13 @@ // -// DomainInfo.h +// DomainHandler.h // hifi // // Created by Stephen Birarda on 2/18/2014. // Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // -#ifndef __hifi__DomainInfo__ -#define __hifi__DomainInfo__ +#ifndef __hifi__DomainHandler__ +#define __hifi__DomainHandler__ #include #include @@ -21,11 +21,11 @@ const QString DEFAULT_DOMAIN_HOSTNAME = "alpha.highfidelity.io"; const unsigned short DEFAULT_DOMAIN_SERVER_PORT = 40102; const unsigned short DEFAULT_DOMAIN_SERVER_DTLS_PORT = 40103; -class DomainInfo : public QObject { +class DomainHandler : public QObject { Q_OBJECT public: - DomainInfo(); - ~DomainInfo(); + DomainHandler(); + ~DomainHandler(); void clearConnectionInfo(); @@ -70,4 +70,4 @@ private: DTLSSession* _dtlsSession; }; -#endif /* defined(__hifi__DomainInfo__) */ +#endif /* defined(__hifi__DomainHandler__) */ diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 56986b4cc8..7cf58385fe 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -87,7 +87,7 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned } // clear our NodeList when the domain changes - connect(&_domainInfo, &DomainInfo::hostnameChanged, this, &NodeList::reset); + connect(&_DomainHandler, &DomainHandler::hostnameChanged, this, &NodeList::reset); // clear our NodeList when logout is requested connect(&AccountManager::getInstance(), &AccountManager::logoutComplete , this, &NodeList::reset); @@ -234,7 +234,7 @@ qint64 NodeList::sendStatsToDomainServer(const QJsonObject& statsObject) { statsPacketStream << statsObject.toVariantMap(); - return writeDatagram(statsPacket, _domainInfo.getSockAddr(), QUuid()); + return writeDatagram(statsPacket, _DomainHandler.getSockAddr(), QUuid()); } void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer& sendingNode) { @@ -279,7 +279,7 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteAr break; } case PacketTypeDomainServerRequireDTLS: { - _domainInfo.parseDTLSRequirementPacket(packet); + _DomainHandler.parseDTLSRequirementPacket(packet); break; } case PacketTypePing: { @@ -400,7 +400,7 @@ void NodeList::reset() { setSessionUUID(QUuid()); // clear the domain connection information - _domainInfo.clearConnectionInfo(); + _DomainHandler.clearConnectionInfo(); } void NodeList::addNodeTypeToInterestSet(NodeType_t nodeTypeToAdd) { @@ -575,13 +575,13 @@ void NodeList::sendDomainServerCheckIn() { // 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 (!_domainInfo.getIP().isNull()) { + } else if (!_DomainHandler.getIP().isNull()) { // construct the DS check in packet PacketType domainPacketType = _sessionUUID.isNull() ? PacketTypeDomainConnectRequest : PacketTypeDomainListRequest; QUuid packetUUID = (domainPacketType == PacketTypeDomainListRequest) - ? _sessionUUID : _domainInfo.getAssignmentUUID(); + ? _sessionUUID : _DomainHandler.getAssignmentUUID(); QByteArray domainServerPacket = byteArrayWithPopulatedHeader(domainPacketType, packetUUID); QDataStream packetStream(&domainServerPacket, QIODevice::Append); @@ -596,7 +596,7 @@ void NodeList::sendDomainServerCheckIn() { packetStream << nodeTypeOfInterest; } - writeDatagram(domainServerPacket, _domainInfo.getSockAddr(), QUuid()); + writeDatagram(domainServerPacket, _DomainHandler.getSockAddr(), QUuid()); const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5; static unsigned int numDomainCheckins = 0; @@ -632,7 +632,7 @@ int NodeList::processDomainServerList(const QByteArray& packet) { _numNoReplyDomainCheckIns = 0; // if this was the first domain-server list from this domain, we've now connected - _domainInfo.setIsConnected(true); + _DomainHandler.setIsConnected(true); int readNodes = 0; @@ -659,7 +659,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(_domainInfo.getIP()); + nodePublicSocket.setAddress(_DomainHandler.getIP()); } SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, nodeLocalSocket); @@ -881,9 +881,9 @@ void NodeList::loadData(QSettings *settings) { QString domainServerHostname = settings->value(DOMAIN_SERVER_SETTING_KEY).toString(); if (domainServerHostname.size() > 0) { - _domainInfo.setHostname(domainServerHostname); + _DomainHandler.setHostname(domainServerHostname); } else { - _domainInfo.setHostname(DEFAULT_DOMAIN_HOSTNAME); + _DomainHandler.setHostname(DEFAULT_DOMAIN_HOSTNAME); } settings->endGroup(); @@ -892,9 +892,9 @@ void NodeList::loadData(QSettings *settings) { void NodeList::saveData(QSettings* settings) { settings->beginGroup(DOMAIN_SERVER_SETTING_KEY); - if (_domainInfo.getHostname() != DEFAULT_DOMAIN_HOSTNAME) { + if (_DomainHandler.getHostname() != DEFAULT_DOMAIN_HOSTNAME) { // the user is using a different hostname, store it - settings->setValue(DOMAIN_SERVER_SETTING_KEY, QVariant(_domainInfo.getHostname())); + settings->setValue(DOMAIN_SERVER_SETTING_KEY, QVariant(_DomainHandler.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 b12174296b..9c19e33ed9 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -31,7 +31,7 @@ #include -#include "DomainInfo.h" +#include "DomainHandler.h" #include "Node.h" const quint64 NODE_SILENCE_THRESHOLD_USECS = 2 * 1000 * 1000; @@ -91,7 +91,7 @@ public: int size() const { return _nodeHash.size(); } int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; } - DomainInfo& getDomainInfo() { return _domainInfo; } + DomainHandler& getDomainHandler() { return _DomainHandler; } const NodeSet& getNodeInterestSet() const { return _nodeTypesOfInterest; } void addNodeTypeToInterestSet(NodeType_t nodeTypeToAdd); @@ -170,7 +170,7 @@ private: QUdpSocket* _dtlsSocket; NodeType_t _ownerType; NodeSet _nodeTypesOfInterest; - DomainInfo _domainInfo; + DomainHandler _DomainHandler; QUuid _sessionUUID; int _numNoReplyDomainCheckIns; HifiSockAddr _assignmentServerSocket; From 45c6ae44a665dfb2851de1add545b8045dbcbf22 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 1 Apr 2014 13:33:30 -0700 Subject: [PATCH 09/86] use a LimitedNodeList in domain-server --- domain-server/src/DomainServer.cpp | 37 +- libraries/shared/src/LimitedNodeList.cpp | 429 +++++++++++++++++++++++ libraries/shared/src/LimitedNodeList.h | 128 +++++++ libraries/shared/src/NodeList.cpp | 380 +------------------- libraries/shared/src/NodeList.h | 75 +--- 5 files changed, 582 insertions(+), 467 deletions(-) create mode 100644 libraries/shared/src/LimitedNodeList.cpp create mode 100644 libraries/shared/src/LimitedNodeList.h diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index d6fc91c8e7..a32ae76e79 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -60,12 +60,12 @@ DomainServer::DomainServer(int argc, char* argv[]) : // DTLS requires that IP_DONTFRAG be set // This is not accessible on some platforms (OS X) so we need to make sure DTLS still works without it - NodeList* nodeList = NodeList::getInstance(); + LimitedNodeList* nodeList = LimitedNodeList::getInstance(); #if defined(IP_DONTFRAG) || defined(IP_MTU_DISCOVER) qDebug() << "Making required DTLS changes to NodeList DTLS socket."; - int socketHandle = NodeList::getInstance()->getDTLSSocket().socketDescriptor(); + int socketHandle = LimitedNodeList::getInstance()->getDTLSSocket().socketDescriptor(); #if defined(IP_DONTFRAG) int optValue = 1;yea setsockopt(socketHandle, IPPROTO_IP, IP_DONTFRAG, (const void*) optValue, sizeof(optValue)); @@ -207,13 +207,10 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { populateDefaultStaticAssignmentsExcludingTypes(parsedTypes); - NodeList* nodeList = NodeList::createInstance(NodeType::DomainServer, domainServerPort, domainServerDTLSPort); + LimitedNodeList* nodeList = LimitedNodeList::createInstance(domainServerPort, domainServerDTLSPort); - // create a random UUID for this session for the domain-server - nodeList->setSessionUUID(sessionUUID); - - connect(nodeList, &NodeList::nodeAdded, this, &DomainServer::nodeAdded); - connect(nodeList, &NodeList::nodeKilled, this, &DomainServer::nodeKilled); + connect(nodeList, &LimitedNodeList::nodeAdded, this, &DomainServer::nodeAdded); + connect(nodeList, &LimitedNodeList::nodeKilled, this, &DomainServer::nodeKilled); QTimer* silentNodeTimer = new QTimer(this); connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); @@ -394,7 +391,7 @@ void DomainServer::addNodeToNodeListAndConfirmConnection(const QByteArray& packe // create a new session UUID for this node QUuid nodeUUID = QUuid::createUuid(); - SharedNodePointer newNode = NodeList::getInstance()->addOrUpdateNode(nodeUUID, nodeType, publicSockAddr, localSockAddr); + SharedNodePointer newNode = LimitedNodeList::getInstance()->addOrUpdateNode(nodeUUID, nodeType, publicSockAddr, localSockAddr); // when the newNode is created the linked data is also created, if this was a static assignment set the UUID reinterpret_cast(newNode->getLinkedData())->setStaticAssignmentUUID(assignmentUUID); @@ -477,7 +474,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif DomainServerNodeData* nodeData = reinterpret_cast(node->getLinkedData()); - NodeList* nodeList = NodeList::getInstance(); + LimitedNodeList* nodeList = LimitedNodeList::getInstance(); if (nodeInterestList.size() > 0) { @@ -532,7 +529,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif } void DomainServer::readAvailableDatagrams() { - NodeList* nodeList = NodeList::getInstance(); + LimitedNodeList* nodeList = LimitedNodeList::getInstance(); HifiSockAddr senderSockAddr; QByteArray receivedPacket; @@ -610,7 +607,7 @@ void DomainServer::readAvailableDTLSDatagrams() { } void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) { - NodeList* nodeList = NodeList::getInstance(); + LimitedNodeList* nodeList = LimitedNodeList::getInstance(); if (nodeList->packetVersionAndHashMatch(receivedPacket)) { PacketType requestType = packetTypeForPacket(receivedPacket); @@ -702,7 +699,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url QJsonObject assignedNodesJSON; // enumerate the NodeList to find the assigned nodes - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) { if (_staticAssignmentHash.value(node->getUUID())) { // add the node using the UUID as the key QString uuidString = uuidStringWithoutCurlyBraces(node->getUUID()); @@ -744,7 +741,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url QJsonObject nodesJSON; // enumerate the NodeList to find the assigned nodes - NodeList* nodeList = NodeList::getInstance(); + LimitedNodeList* nodeList = LimitedNodeList::getInstance(); foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { // add the node using the UUID as the key @@ -769,7 +766,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url QUuid matchingUUID = QUuid(nodeShowRegex.cap(1)); // see if we have a node that matches this ID - SharedNodePointer matchingNode = NodeList::getInstance()->nodeWithUUID(matchingUUID); + SharedNodePointer matchingNode = LimitedNodeList::getInstance()->nodeWithUUID(matchingUUID); if (matchingNode) { // create a QJsonDocument with the stats QJsonObject QJsonObject statsObject = @@ -848,14 +845,14 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url // pull the captured string, if it exists QUuid deleteUUID = QUuid(nodeDeleteRegex.cap(1)); - SharedNodePointer nodeToKill = NodeList::getInstance()->nodeWithUUID(deleteUUID); + SharedNodePointer nodeToKill = LimitedNodeList::getInstance()->nodeWithUUID(deleteUUID); if (nodeToKill) { // start with a 200 response connection->respond(HTTPConnection::StatusCode200); // we have a valid UUID and node - kill the node that has this assignment - QMetaObject::invokeMethod(NodeList::getInstance(), "killNodeWithUUID", Q_ARG(const QUuid&, deleteUUID)); + QMetaObject::invokeMethod(LimitedNodeList::getInstance(), "killNodeWithUUID", Q_ARG(const QUuid&, deleteUUID)); // successfully processed request return true; @@ -864,7 +861,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url return true; } else if (allNodesDeleteRegex.indexIn(url.path()) != -1) { qDebug() << "Received request to kill all nodes."; - NodeList::getInstance()->eraseAllNodes(); + LimitedNodeList::getInstance()->eraseAllNodes(); return true; } @@ -911,7 +908,7 @@ void DomainServer::nodeKilled(SharedNodePointer node) { // cleanup the connection secrets that we set up for this node (on the other nodes) foreach (const QUuid& otherNodeSessionUUID, nodeData->getSessionSecretHash().keys()) { - SharedNodePointer otherNode = NodeList::getInstance()->nodeWithUUID(otherNodeSessionUUID); + SharedNodePointer otherNode = LimitedNodeList::getInstance()->nodeWithUUID(otherNodeSessionUUID); if (otherNode) { reinterpret_cast(otherNode->getLinkedData())->getSessionSecretHash().remove(node->getUUID()); } @@ -996,7 +993,7 @@ void DomainServer::addStaticAssignmentsToQueue() { bool foundMatchingAssignment = false; // enumerate the nodes and check if there is one with an attached assignment with matching UUID - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) { if (node->getUUID() == staticAssignment->data()->getUUID()) { foundMatchingAssignment = true; } diff --git a/libraries/shared/src/LimitedNodeList.cpp b/libraries/shared/src/LimitedNodeList.cpp new file mode 100644 index 0000000000..88fdf18574 --- /dev/null +++ b/libraries/shared/src/LimitedNodeList.cpp @@ -0,0 +1,429 @@ +// +// LimitedNodeList.cpp +// hifi +// +// Created by Stephen Birarda on 2/15/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "AccountManager.h" +#include "Assignment.h" +#include "HifiSockAddr.h" +#include "Logging.h" +#include "LimitedNodeList.h" +#include "PacketHeaders.h" +#include "SharedUtil.h" +#include "UUID.h" + +const char SOLO_NODE_TYPES[2] = { + NodeType::AvatarMixer, + NodeType::AudioMixer +}; + +const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://data-web.highfidelity.io"); + +LimitedNodeList* LimitedNodeList::_sharedInstance = NULL; + +LimitedNodeList* LimitedNodeList::createInstance(unsigned short socketListenPort, unsigned short dtlsPort) { + if (!_sharedInstance) { + NodeType::init(); + + _sharedInstance = new LimitedNodeList(socketListenPort, dtlsPort); + + // register the SharedNodePointer meta-type for signals/slots + qRegisterMetaType(); + } else { + qDebug("NodeList createInstance called with existing instance."); + } + + return _sharedInstance; +} + +LimitedNodeList* LimitedNodeList::getInstance() { + if (!_sharedInstance) { + qDebug("NodeList getInstance called before call to createInstance. Returning NULL pointer."); + } + + return _sharedInstance; +} + + +LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort) : + _nodeHash(), + _nodeHashMutex(QMutex::Recursive), + _nodeSocket(this), + _dtlsSocket(NULL), + _numCollectedPackets(0), + _numCollectedBytes(0), + _packetStatTimer() +{ + _nodeSocket.bind(QHostAddress::AnyIPv4, socketListenPort); + qDebug() << "NodeList socket is listening on" << _nodeSocket.localPort(); + + if (dtlsListenPort > 0) { + // only create the DTLS socket during constructor if a custom port is passed + _dtlsSocket = new QUdpSocket(this); + + _dtlsSocket->bind(QHostAddress::AnyIPv4, dtlsListenPort); + qDebug() << "NodeList DTLS socket is listening on" << _dtlsSocket->localPort(); + } + + const int LARGER_SNDBUF_SIZE = 1048576; + changeSendSocketBufferSize(LARGER_SNDBUF_SIZE); + + _packetStatTimer.start(); +} + +QUdpSocket& LimitedNodeList::getDTLSSocket() { + if (!_dtlsSocket) { + // DTLS socket getter called but no DTLS socket exists, create it now + _dtlsSocket = new QUdpSocket(this); + + _dtlsSocket->bind(QHostAddress::AnyIPv4, 0, QAbstractSocket::DontShareAddress); + qDebug() << "NodeList DTLS socket is listening on" << _dtlsSocket->localPort(); + } + + return *_dtlsSocket; +} + +void LimitedNodeList::changeSendSocketBufferSize(int numSendBytes) { + // change the socket send buffer size to be 1MB + int oldBufferSize = 0; + +#ifdef Q_OS_WIN + int sizeOfInt = sizeof(oldBufferSize); +#else + unsigned int sizeOfInt = sizeof(oldBufferSize); +#endif + + getsockopt(_nodeSocket.socketDescriptor(), SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&oldBufferSize), &sizeOfInt); + + setsockopt(_nodeSocket.socketDescriptor(), SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&numSendBytes), + sizeof(numSendBytes)); + + int newBufferSize = 0; + getsockopt(_nodeSocket.socketDescriptor(), SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&newBufferSize), &sizeOfInt); + + qDebug() << "Changed socket send buffer size from" << oldBufferSize << "to" << newBufferSize << "bytes"; +} + +bool LimitedNodeList::packetVersionAndHashMatch(const QByteArray& packet) { + PacketType checkType = packetTypeForPacket(packet); + if (packet[1] != versionForPacketType(checkType) + && checkType != PacketTypeStunResponse) { + PacketType mismatchType = packetTypeForPacket(packet); + int numPacketTypeBytes = numBytesArithmeticCodingFromBuffer(packet.data()); + + static QMultiMap versionDebugSuppressMap; + + QUuid senderUUID = uuidFromPacketHeader(packet); + if (!versionDebugSuppressMap.contains(senderUUID, checkType)) { + qDebug() << "Packet version mismatch on" << packetTypeForPacket(packet) << "- Sender" + << uuidFromPacketHeader(packet) << "sent" << qPrintable(QString::number(packet[numPacketTypeBytes])) << "but" + << qPrintable(QString::number(versionForPacketType(mismatchType))) << "expected."; + + versionDebugSuppressMap.insert(senderUUID, checkType); + } + + return false; + } + + if (!NON_VERIFIED_PACKETS.contains(checkType)) { + // figure out which node this is from + SharedNodePointer sendingNode = sendingNodeForPacket(packet); + if (sendingNode) { + // check if the md5 hash in the header matches the hash we would expect + if (hashFromPacketHeader(packet) == hashForPacketAndConnectionUUID(packet, sendingNode->getConnectionSecret())) { + return true; + } else { + qDebug() << "Packet hash mismatch on" << checkType << "- Sender" + << uuidFromPacketHeader(packet); + } + } else { + qDebug() << "Packet of type" << checkType << "received from unknown node with UUID" + << uuidFromPacketHeader(packet); + } + } else { + return true; + } + + return false; +} + +qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr, + const QUuid& connectionSecret) { + QByteArray datagramCopy = datagram; + + if (!connectionSecret.isNull()) { + // setup the MD5 hash for source verification in the header + replaceHashInPacketGivenConnectionUUID(datagramCopy, connectionSecret); + } + + // stat collection for packets + ++_numCollectedPackets; + _numCollectedBytes += datagram.size(); + + qint64 bytesWritten = _nodeSocket.writeDatagram(datagramCopy, + destinationSockAddr.getAddress(), destinationSockAddr.getPort()); + + if (bytesWritten < 0) { + qDebug() << "ERROR in writeDatagram:" << _nodeSocket.error() << "-" << _nodeSocket.errorString(); + } + + return bytesWritten; +} + +qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram, const SharedNodePointer& destinationNode, + const HifiSockAddr& overridenSockAddr) { + if (destinationNode) { + // if we don't have an ovveriden address, assume they want to send to the node's active socket + const HifiSockAddr* destinationSockAddr = &overridenSockAddr; + if (overridenSockAddr.isNull()) { + if (destinationNode->getActiveSocket()) { + // use the node's active socket as the destination socket + destinationSockAddr = destinationNode->getActiveSocket(); + } else { + // we don't have a socket to send to, return 0 + return 0; + } + } + + writeDatagram(datagram, *destinationSockAddr, destinationNode->getConnectionSecret()); + } + + // didn't have a destinationNode to send to, return 0 + return 0; +} + +qint64 LimitedNodeList::writeUnverifiedDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr) { + return writeDatagram(datagram, destinationSockAddr, QUuid()); +} + +qint64 LimitedNodeList::writeDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode, + const HifiSockAddr& overridenSockAddr) { + return writeDatagram(QByteArray(data, size), destinationNode, overridenSockAddr); +} + +void LimitedNodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet) { + // the node decided not to do anything with this packet + // if it comes from a known source we should keep that node alive + SharedNodePointer matchingNode = sendingNodeForPacket(packet); + if (matchingNode) { + matchingNode->setLastHeardMicrostamp(usecTimestampNow()); + } +} + +int LimitedNodeList::updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, const QByteArray &packet) { + QMutexLocker locker(&matchingNode->getMutex()); + + matchingNode->setLastHeardMicrostamp(usecTimestampNow()); + matchingNode->recordBytesReceived(packet.size()); + + if (!matchingNode->getLinkedData() && linkedDataCreateCallback) { + linkedDataCreateCallback(matchingNode.data()); + } + + QMutexLocker linkedDataLocker(&matchingNode->getLinkedData()->getMutex()); + + return matchingNode->getLinkedData()->parseData(packet); +} + +int LimitedNodeList::findNodeAndUpdateWithDataFromPacket(const QByteArray& packet) { + SharedNodePointer matchingNode = sendingNodeForPacket(packet); + + if (matchingNode) { + updateNodeWithDataFromPacket(matchingNode, packet); + } + + // we weren't able to match the sender address to the address we have for this node, unlock and don't parse + return 0; +} + +SharedNodePointer LimitedNodeList::nodeWithUUID(const QUuid& nodeUUID, bool blockingLock) { + const int WAIT_TIME = 10; // wait up to 10ms in the try lock case + SharedNodePointer node; + // if caller wants us to block and guarantee the correct answer, then honor that request + if (blockingLock) { + // this will block till we can get access + QMutexLocker locker(&_nodeHashMutex); + node = _nodeHash.value(nodeUUID); + } else if (_nodeHashMutex.tryLock(WAIT_TIME)) { // some callers are willing to get wrong answers but not block + node = _nodeHash.value(nodeUUID); + _nodeHashMutex.unlock(); + } + return node; + } + +SharedNodePointer LimitedNodeList::sendingNodeForPacket(const QByteArray& packet) { + QUuid nodeUUID = uuidFromPacketHeader(packet); + + // return the matching node, or NULL if there is no match + return nodeWithUUID(nodeUUID); +} + +NodeHash LimitedNodeList::getNodeHash() { + QMutexLocker locker(&_nodeHashMutex); + return NodeHash(_nodeHash); +} + +void LimitedNodeList::eraseAllNodes() { + qDebug() << "Clearing the NodeList. Deleting all nodes in list."; + + QMutexLocker locker(&_nodeHashMutex); + + NodeHash::iterator nodeItem = _nodeHash.begin(); + + // iterate the nodes in the list + while (nodeItem != _nodeHash.end()) { + nodeItem = killNodeAtHashIterator(nodeItem); + } +} + +void LimitedNodeList::reset() { + eraseAllNodes(); +} + +void LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) { + QMutexLocker locker(&_nodeHashMutex); + + NodeHash::iterator nodeItemToKill = _nodeHash.find(nodeUUID); + if (nodeItemToKill != _nodeHash.end()) { + killNodeAtHashIterator(nodeItemToKill); + } +} + +NodeHash::iterator LimitedNodeList::killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill) { + qDebug() << "Killed" << *nodeItemToKill.value(); + emit nodeKilled(nodeItemToKill.value()); + return _nodeHash.erase(nodeItemToKill); +} + +void LimitedNodeList::processKillNode(const QByteArray& dataByteArray) { + // read the node id + QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader(dataByteArray), NUM_BYTES_RFC4122_UUID)); + + // kill the node with this UUID, if it exists + killNodeWithUUID(nodeUUID); +} + +SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, char nodeType, + const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) { + _nodeHashMutex.lock(); + + if (!_nodeHash.contains(uuid)) { + + // we didn't have this node, so add them + Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket); + SharedNodePointer newNodeSharedPointer(newNode, &QObject::deleteLater); + + _nodeHash.insert(newNode->getUUID(), newNodeSharedPointer); + + _nodeHashMutex.unlock(); + + qDebug() << "Added" << *newNode; + + emit nodeAdded(newNodeSharedPointer); + + return newNodeSharedPointer; + } else { + _nodeHashMutex.unlock(); + + return updateSocketsForNode(uuid, publicSocket, localSocket); + } +} + +SharedNodePointer LimitedNodeList::updateSocketsForNode(const QUuid& uuid, + const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) { + + SharedNodePointer matchingNode = nodeWithUUID(uuid); + + if (matchingNode) { + // perform appropriate updates to this node + QMutexLocker locker(&matchingNode->getMutex()); + + // check if we need to change this node's public or local sockets + if (publicSocket != matchingNode->getPublicSocket()) { + matchingNode->setPublicSocket(publicSocket); + qDebug() << "Public socket change for node" << *matchingNode; + } + + if (localSocket != matchingNode->getLocalSocket()) { + matchingNode->setLocalSocket(localSocket); + qDebug() << "Local socket change for node" << *matchingNode; + } + } + + return matchingNode; +} + +unsigned LimitedNodeList::broadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) { + unsigned n = 0; + + foreach (const SharedNodePointer& node, getNodeHash()) { + // only send to the NodeTypes we are asked to send to. + if (destinationNodeTypes.contains(node->getType())) { + writeDatagram(packet, node); + ++n; + } + } + + return n; +} + +SharedNodePointer LimitedNodeList::soloNodeOfType(char nodeType) { + + if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES))) { + foreach (const SharedNodePointer& node, getNodeHash()) { + if (node->getType() == nodeType) { + return node; + } + } + } + return SharedNodePointer(); +} + +void LimitedNodeList::getPacketStats(float& packetsPerSecond, float& bytesPerSecond) { + packetsPerSecond = (float) _numCollectedPackets / ((float) _packetStatTimer.elapsed() / 1000.0f); + bytesPerSecond = (float) _numCollectedBytes / ((float) _packetStatTimer.elapsed() / 1000.0f); +} + +void LimitedNodeList::resetPacketStats() { + _numCollectedPackets = 0; + _numCollectedBytes = 0; + _packetStatTimer.restart(); +} + +void LimitedNodeList::removeSilentNodes() { + + _nodeHashMutex.lock(); + + NodeHash::iterator nodeItem = _nodeHash.begin(); + + while (nodeItem != _nodeHash.end()) { + SharedNodePointer node = nodeItem.value(); + + node->getMutex().lock(); + + if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > NODE_SILENCE_THRESHOLD_USECS) { + // call our private method to kill this node (removes it and emits the right signal) + nodeItem = killNodeAtHashIterator(nodeItem); + } else { + // we didn't kill this node, push the iterator forwards + ++nodeItem; + } + + node->getMutex().unlock(); + } + + _nodeHashMutex.unlock(); +} diff --git a/libraries/shared/src/LimitedNodeList.h b/libraries/shared/src/LimitedNodeList.h new file mode 100644 index 0000000000..1c4035be47 --- /dev/null +++ b/libraries/shared/src/LimitedNodeList.h @@ -0,0 +1,128 @@ +// +// LimitedNodeList.h +// hifi +// +// Created by Stephen Birarda on 2/15/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__LimitedNodeList__ +#define __hifi__LimitedNodeList__ + +#ifdef _WIN32 +#include "Syssocket.h" +#else +#include +#endif +#include +#include + +#ifndef _WIN32 +#include // not on windows, not needed for mac or windows +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "DomainHandler.h" +#include "Node.h" + +const quint64 NODE_SILENCE_THRESHOLD_USECS = 2 * 1000 * 1000; + +extern const char SOLO_NODE_TYPES[2]; + +extern const QUrl DEFAULT_NODE_AUTH_URL; + +const char DEFAULT_ASSIGNMENT_SERVER_HOSTNAME[] = "localhost"; + +class HifiSockAddr; + +typedef QSet NodeSet; + +typedef QSharedPointer SharedNodePointer; +typedef QHash NodeHash; +Q_DECLARE_METATYPE(SharedNodePointer) + +class LimitedNodeList : public QObject { + Q_OBJECT +public: + static LimitedNodeList* createInstance(unsigned short socketListenPort = 0, unsigned short dtlsPort = 0); + static LimitedNodeList* getInstance(); + + QUdpSocket& getNodeSocket() { return _nodeSocket; } + QUdpSocket& getDTLSSocket(); + + bool packetVersionAndHashMatch(const QByteArray& packet); + + qint64 writeDatagram(const QByteArray& datagram, const SharedNodePointer& destinationNode, + const HifiSockAddr& overridenSockAddr = HifiSockAddr()); + qint64 writeUnverifiedDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr); + qint64 writeDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode, + const HifiSockAddr& overridenSockAddr = HifiSockAddr()); + + void(*linkedDataCreateCallback)(Node *); + + NodeHash getNodeHash(); + int size() const { return _nodeHash.size(); } + + SharedNodePointer nodeWithUUID(const QUuid& nodeUUID, bool blockingLock = true); + SharedNodePointer sendingNodeForPacket(const QByteArray& packet); + + SharedNodePointer addOrUpdateNode(const QUuid& uuid, char nodeType, + const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); + SharedNodePointer updateSocketsForNode(const QUuid& uuid, + const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); + + void processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet); + void processKillNode(const QByteArray& datagram); + + int updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, const QByteArray& packet); + int findNodeAndUpdateWithDataFromPacket(const QByteArray& packet); + + unsigned broadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes); + SharedNodePointer soloNodeOfType(char nodeType); + + void getPacketStats(float &packetsPerSecond, float &bytesPerSecond); + void resetPacketStats(); +public slots: + void reset(); + void eraseAllNodes(); + + void removeSilentNodes(); + + void killNodeWithUUID(const QUuid& nodeUUID); +signals: + void nodeAdded(SharedNodePointer); + void nodeKilled(SharedNodePointer); +protected: + static LimitedNodeList* _sharedInstance; + + LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort); + LimitedNodeList(LimitedNodeList const&); // Don't implement, needed to avoid copies of singleton + void operator=(LimitedNodeList const&); // Don't implement, needed to avoid copies of singleton + + qint64 writeDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr, + const QUuid& connectionSecret); + + NodeHash::iterator killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill); + + + void changeSendSocketBufferSize(int numSendBytes); + + NodeHash _nodeHash; + QMutex _nodeHashMutex; + QUdpSocket _nodeSocket; + QUdpSocket* _dtlsSocket; + int _numCollectedPackets; + int _numCollectedBytes; + QElapsedTimer _packetStatTimer; +}; + +#endif /* defined(__hifi__LimitedNodeList__) */ diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 7cf58385fe..0b94e1b774 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -6,10 +6,6 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // -#include -#include -#include - #include #include #include @@ -25,13 +21,6 @@ #include "SharedUtil.h" #include "UUID.h" -const char SOLO_NODE_TYPES[2] = { - NodeType::AvatarMixer, - NodeType::AudioMixer -}; - -const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://data-web.highfidelity.io"); - NodeList* NodeList::_sharedInstance = NULL; NodeList* NodeList::createInstance(char ownerType, unsigned short socketListenPort, unsigned short dtlsPort) { @@ -57,12 +46,8 @@ NodeList* NodeList::getInstance() { return _sharedInstance; } - NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned short dtlsListenPort) : - _nodeHash(), - _nodeHashMutex(QMutex::Recursive), - _nodeSocket(this), - _dtlsSocket(NULL), + LimitedNodeList(socketListenPort, dtlsListenPort), _ownerType(newOwnerType), _nodeTypesOfInterest(), _sessionUUID(), @@ -70,162 +55,13 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned _assignmentServerSocket(), _publicSockAddr(), _hasCompletedInitialSTUNFailure(false), - _stunRequestsSinceSuccess(0), - _numCollectedPackets(0), - _numCollectedBytes(0), - _packetStatTimer() + _stunRequestsSinceSuccess(0) { - _nodeSocket.bind(QHostAddress::AnyIPv4, socketListenPort); - qDebug() << "NodeList socket is listening on" << _nodeSocket.localPort(); - - if (dtlsListenPort > 0) { - // only create the DTLS socket during constructor if a custom port is passed - _dtlsSocket = new QUdpSocket(this); - - _dtlsSocket->bind(QHostAddress::AnyIPv4, dtlsListenPort); - qDebug() << "NodeList DTLS socket is listening on" << _dtlsSocket->localPort(); - } - // clear our NodeList when the domain changes connect(&_DomainHandler, &DomainHandler::hostnameChanged, this, &NodeList::reset); // clear our NodeList when logout is requested connect(&AccountManager::getInstance(), &AccountManager::logoutComplete , this, &NodeList::reset); - - const int LARGER_SNDBUF_SIZE = 1048576; - changeSendSocketBufferSize(LARGER_SNDBUF_SIZE); - - _packetStatTimer.start(); -} - -QUdpSocket& NodeList::getDTLSSocket() { - if (!_dtlsSocket) { - // DTLS socket getter called but no DTLS socket exists, create it now - _dtlsSocket = new QUdpSocket(this); - - _dtlsSocket->bind(QHostAddress::AnyIPv4, 0, QAbstractSocket::DontShareAddress); - qDebug() << "NodeList DTLS socket is listening on" << _dtlsSocket->localPort(); - } - - return *_dtlsSocket; -} - -void NodeList::changeSendSocketBufferSize(int numSendBytes) { - // change the socket send buffer size to be 1MB - int oldBufferSize = 0; - -#ifdef Q_OS_WIN - int sizeOfInt = sizeof(oldBufferSize); -#else - unsigned int sizeOfInt = sizeof(oldBufferSize); -#endif - - getsockopt(_nodeSocket.socketDescriptor(), SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&oldBufferSize), &sizeOfInt); - - setsockopt(_nodeSocket.socketDescriptor(), SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&numSendBytes), - sizeof(numSendBytes)); - - int newBufferSize = 0; - getsockopt(_nodeSocket.socketDescriptor(), SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&newBufferSize), &sizeOfInt); - - qDebug() << "Changed socket send buffer size from" << oldBufferSize << "to" << newBufferSize << "bytes"; -} - -bool NodeList::packetVersionAndHashMatch(const QByteArray& packet) { - PacketType checkType = packetTypeForPacket(packet); - if (packet[1] != versionForPacketType(checkType) - && checkType != PacketTypeStunResponse) { - PacketType mismatchType = packetTypeForPacket(packet); - int numPacketTypeBytes = numBytesArithmeticCodingFromBuffer(packet.data()); - - static QMultiMap versionDebugSuppressMap; - - QUuid senderUUID = uuidFromPacketHeader(packet); - if (!versionDebugSuppressMap.contains(senderUUID, checkType)) { - qDebug() << "Packet version mismatch on" << packetTypeForPacket(packet) << "- Sender" - << uuidFromPacketHeader(packet) << "sent" << qPrintable(QString::number(packet[numPacketTypeBytes])) << "but" - << qPrintable(QString::number(versionForPacketType(mismatchType))) << "expected."; - - versionDebugSuppressMap.insert(senderUUID, checkType); - } - - return false; - } - - if (!NON_VERIFIED_PACKETS.contains(checkType)) { - // figure out which node this is from - SharedNodePointer sendingNode = sendingNodeForPacket(packet); - if (sendingNode) { - // check if the md5 hash in the header matches the hash we would expect - if (hashFromPacketHeader(packet) == hashForPacketAndConnectionUUID(packet, sendingNode->getConnectionSecret())) { - return true; - } else { - qDebug() << "Packet hash mismatch on" << checkType << "- Sender" - << uuidFromPacketHeader(packet); - } - } else { - qDebug() << "Packet of type" << checkType << "received from unknown node with UUID" - << uuidFromPacketHeader(packet); - } - } else { - return true; - } - - return false; -} - -qint64 NodeList::writeDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr, - const QUuid& connectionSecret) { - QByteArray datagramCopy = datagram; - - if (!connectionSecret.isNull()) { - // setup the MD5 hash for source verification in the header - replaceHashInPacketGivenConnectionUUID(datagramCopy, connectionSecret); - } - - // stat collection for packets - ++_numCollectedPackets; - _numCollectedBytes += datagram.size(); - - qint64 bytesWritten = _nodeSocket.writeDatagram(datagramCopy, - destinationSockAddr.getAddress(), destinationSockAddr.getPort()); - - if (bytesWritten < 0) { - qDebug() << "ERROR in writeDatagram:" << _nodeSocket.error() << "-" << _nodeSocket.errorString(); - } - - return bytesWritten; -} - -qint64 NodeList::writeDatagram(const QByteArray& datagram, const SharedNodePointer& destinationNode, - const HifiSockAddr& overridenSockAddr) { - if (destinationNode) { - // if we don't have an ovveriden address, assume they want to send to the node's active socket - const HifiSockAddr* destinationSockAddr = &overridenSockAddr; - if (overridenSockAddr.isNull()) { - if (destinationNode->getActiveSocket()) { - // use the node's active socket as the destination socket - destinationSockAddr = destinationNode->getActiveSocket(); - } else { - // we don't have a socket to send to, return 0 - return 0; - } - } - - writeDatagram(datagram, *destinationSockAddr, destinationNode->getConnectionSecret()); - } - - // didn't have a destinationNode to send to, return 0 - return 0; -} - -qint64 NodeList::writeUnverifiedDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr) { - return writeDatagram(datagram, destinationSockAddr, QUuid()); -} - -qint64 NodeList::writeDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode, - const HifiSockAddr& overridenSockAddr) { - return writeDatagram(QByteArray(data, size), destinationNode, overridenSockAddr); } qint64 NodeList::sendStatsToDomainServer(const QJsonObject& statsObject) { @@ -315,85 +151,14 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteAr break; } default: - // the node decided not to do anything with this packet - // if it comes from a known source we should keep that node alive - SharedNodePointer matchingNode = sendingNodeForPacket(packet); - if (matchingNode) { - matchingNode->setLastHeardMicrostamp(usecTimestampNow()); - } - + LimitedNodeList::processNodeData(senderSockAddr, packet); break; } } -int NodeList::updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, const QByteArray &packet) { - QMutexLocker locker(&matchingNode->getMutex()); - - matchingNode->setLastHeardMicrostamp(usecTimestampNow()); - matchingNode->recordBytesReceived(packet.size()); - - if (!matchingNode->getLinkedData() && linkedDataCreateCallback) { - linkedDataCreateCallback(matchingNode.data()); - } - - QMutexLocker linkedDataLocker(&matchingNode->getLinkedData()->getMutex()); - - return matchingNode->getLinkedData()->parseData(packet); -} - -int NodeList::findNodeAndUpdateWithDataFromPacket(const QByteArray& packet) { - SharedNodePointer matchingNode = sendingNodeForPacket(packet); - - if (matchingNode) { - updateNodeWithDataFromPacket(matchingNode, packet); - } - - // we weren't able to match the sender address to the address we have for this node, unlock and don't parse - return 0; -} - -SharedNodePointer NodeList::nodeWithUUID(const QUuid& nodeUUID, bool blockingLock) { - const int WAIT_TIME = 10; // wait up to 10ms in the try lock case - SharedNodePointer node; - // if caller wants us to block and guarantee the correct answer, then honor that request - if (blockingLock) { - // this will block till we can get access - QMutexLocker locker(&_nodeHashMutex); - node = _nodeHash.value(nodeUUID); - } else if (_nodeHashMutex.tryLock(WAIT_TIME)) { // some callers are willing to get wrong answers but not block - node = _nodeHash.value(nodeUUID); - _nodeHashMutex.unlock(); - } - return node; - } - -SharedNodePointer NodeList::sendingNodeForPacket(const QByteArray& packet) { - QUuid nodeUUID = uuidFromPacketHeader(packet); - - // return the matching node, or NULL if there is no match - return nodeWithUUID(nodeUUID); -} - -NodeHash NodeList::getNodeHash() { - QMutexLocker locker(&_nodeHashMutex); - return NodeHash(_nodeHash); -} - -void NodeList::eraseAllNodes() { - qDebug() << "Clearing the NodeList. Deleting all nodes in list."; - - QMutexLocker locker(&_nodeHashMutex); - - NodeHash::iterator nodeItem = _nodeHash.begin(); - - // iterate the nodes in the list - while (nodeItem != _nodeHash.end()) { - nodeItem = killNodeAtHashIterator(nodeItem); - } -} - void NodeList::reset() { - eraseAllNodes(); + LimitedNodeList::reset(); + _numNoReplyDomainCheckIns = 0; // refresh the owner UUID to the NULL UUID @@ -547,29 +312,6 @@ void NodeList::processSTUNResponse(const QByteArray& packet) { } } -void NodeList::killNodeWithUUID(const QUuid& nodeUUID) { - QMutexLocker locker(&_nodeHashMutex); - - NodeHash::iterator nodeItemToKill = _nodeHash.find(nodeUUID); - if (nodeItemToKill != _nodeHash.end()) { - killNodeAtHashIterator(nodeItemToKill); - } -} - -NodeHash::iterator NodeList::killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill) { - qDebug() << "Killed" << *nodeItemToKill.value(); - emit nodeKilled(nodeItemToKill.value()); - return _nodeHash.erase(nodeItemToKill); -} - -void NodeList::processKillNode(const QByteArray& dataByteArray) { - // read the node id - QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader(dataByteArray), NUM_BYTES_RFC4122_UUID)); - - // kill the node with this UUID, if it exists - killNodeWithUUID(nodeUUID); -} - void NodeList::sendDomainServerCheckIn() { if (_publicSockAddr.isNull() && !_hasCompletedInitialSTUNFailure) { // we don't know our public socket and we need to send it to the domain server @@ -734,70 +476,6 @@ void NodeList::pingPublicAndLocalSocketsForInactiveNode(const SharedNodePointer& writeDatagram(publicPingPacket, node, node->getPublicSocket()); } -SharedNodePointer NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType, - const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) { - _nodeHashMutex.lock(); - - if (!_nodeHash.contains(uuid)) { - - // we didn't have this node, so add them - Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket); - SharedNodePointer newNodeSharedPointer(newNode, &QObject::deleteLater); - - _nodeHash.insert(newNode->getUUID(), newNodeSharedPointer); - - _nodeHashMutex.unlock(); - - qDebug() << "Added" << *newNode; - - emit nodeAdded(newNodeSharedPointer); - - return newNodeSharedPointer; - } else { - _nodeHashMutex.unlock(); - - return updateSocketsForNode(uuid, publicSocket, localSocket); - } -} - -SharedNodePointer NodeList::updateSocketsForNode(const QUuid& uuid, - const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) { - - SharedNodePointer matchingNode = nodeWithUUID(uuid); - - if (matchingNode) { - // perform appropriate updates to this node - QMutexLocker locker(&matchingNode->getMutex()); - - // check if we need to change this node's public or local sockets - if (publicSocket != matchingNode->getPublicSocket()) { - matchingNode->setPublicSocket(publicSocket); - qDebug() << "Public socket change for node" << *matchingNode; - } - - if (localSocket != matchingNode->getLocalSocket()) { - matchingNode->setLocalSocket(localSocket); - qDebug() << "Local socket change for node" << *matchingNode; - } - } - - return matchingNode; -} - -unsigned NodeList::broadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) { - unsigned n = 0; - - foreach (const SharedNodePointer& node, getNodeHash()) { - // only send to the NodeTypes we are asked to send to. - if (destinationNodeTypes.contains(node->getType())) { - writeDatagram(packet, node); - ++n; - } - } - - return n; -} - void NodeList::pingInactiveNodes() { foreach (const SharedNodePointer& node, getNodeHash()) { if (!node->getActiveSocket()) { @@ -824,54 +502,6 @@ void NodeList::activateSocketFromNodeCommunication(const QByteArray& packet, con } } -SharedNodePointer NodeList::soloNodeOfType(char nodeType) { - - if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES))) { - foreach (const SharedNodePointer& node, getNodeHash()) { - if (node->getType() == nodeType) { - return node; - } - } - } - return SharedNodePointer(); -} - -void NodeList::getPacketStats(float& packetsPerSecond, float& bytesPerSecond) { - packetsPerSecond = (float) _numCollectedPackets / ((float) _packetStatTimer.elapsed() / 1000.0f); - bytesPerSecond = (float) _numCollectedBytes / ((float) _packetStatTimer.elapsed() / 1000.0f); -} - -void NodeList::resetPacketStats() { - _numCollectedPackets = 0; - _numCollectedBytes = 0; - _packetStatTimer.restart(); -} - -void NodeList::removeSilentNodes() { - - _nodeHashMutex.lock(); - - NodeHash::iterator nodeItem = _nodeHash.begin(); - - while (nodeItem != _nodeHash.end()) { - SharedNodePointer node = nodeItem.value(); - - node->getMutex().lock(); - - if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > NODE_SILENCE_THRESHOLD_USECS) { - // call our private method to kill this node (removes it and emits the right signal) - nodeItem = killNodeAtHashIterator(nodeItem); - } else { - // we didn't kill this node, push the iterator forwards - ++nodeItem; - } - - node->getMutex().unlock(); - } - - _nodeHashMutex.unlock(); -} - const QString QSETTINGS_GROUP_NAME = "NodeList"; const QString DOMAIN_SERVER_SETTING_KEY = "domainServerHostname"; diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 9c19e33ed9..bc22c97904 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -32,28 +32,14 @@ #include #include "DomainHandler.h" +#include "LimitedNodeList.h" #include "Node.h" -const quint64 NODE_SILENCE_THRESHOLD_USECS = 2 * 1000 * 1000; const quint64 DOMAIN_SERVER_CHECK_IN_USECS = 1 * 1000000; -const quint64 PING_INACTIVE_NODE_INTERVAL_USECS = 1 * 1000 * 1000; - -extern const char SOLO_NODE_TYPES[2]; - -extern const QUrl DEFAULT_NODE_AUTH_URL; - -const char DEFAULT_ASSIGNMENT_SERVER_HOSTNAME[] = "localhost"; const int MAX_SILENT_DOMAIN_SERVER_CHECK_INS = 5; class Assignment; -class HifiSockAddr; - -typedef QSet NodeSet; - -typedef QSharedPointer SharedNodePointer; -typedef QHash NodeHash; -Q_DECLARE_METATYPE(SharedNodePointer) typedef quint8 PingType_t; namespace PingType { @@ -62,7 +48,7 @@ namespace PingType { const PingType_t Public = 2; } -class NodeList : public QObject { +class NodeList : public LimitedNodeList { Q_OBJECT public: static NodeList* createInstance(char ownerType, unsigned short socketListenPort = 0, unsigned short dtlsPort = 0); @@ -73,23 +59,8 @@ public: const QUuid& getSessionUUID() const { return _sessionUUID; } void setSessionUUID(const QUuid& sessionUUID); - QUdpSocket& getNodeSocket() { return _nodeSocket; } - QUdpSocket& getDTLSSocket(); - - bool packetVersionAndHashMatch(const QByteArray& packet); - - qint64 writeDatagram(const QByteArray& datagram, const SharedNodePointer& destinationNode, - const HifiSockAddr& overridenSockAddr = HifiSockAddr()); - qint64 writeUnverifiedDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr); - qint64 writeDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode, - const HifiSockAddr& overridenSockAddr = HifiSockAddr()); qint64 sendStatsToDomainServer(const QJsonObject& statsObject); - void(*linkedDataCreateCallback)(Node *); - - NodeHash getNodeHash(); - int size() const { return _nodeHash.size(); } - int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; } DomainHandler& getDomainHandler() { return _DomainHandler; } @@ -98,6 +69,7 @@ public: void addSetOfNodeTypesToNodeInterestSet(const NodeSet& setOfNodeTypes); void resetNodeInterestSet() { _nodeTypesOfInterest.clear(); } + void processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet); int processDomainServerList(const QByteArray& packet); void setAssignmentServerSocket(const HifiSockAddr& serverSocket) { _assignmentServerSocket = serverSocket; } @@ -106,42 +78,15 @@ public: QByteArray constructPingPacket(PingType_t pingType = PingType::Agnostic); QByteArray constructPingReplyPacket(const QByteArray& pingPacket); void pingPublicAndLocalSocketsForInactiveNode(const SharedNodePointer& node); - - SharedNodePointer nodeWithUUID(const QUuid& nodeUUID, bool blockingLock = true); - SharedNodePointer sendingNodeForPacket(const QByteArray& packet); - - SharedNodePointer addOrUpdateNode(const QUuid& uuid, char nodeType, - const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); - SharedNodePointer updateSocketsForNode(const QUuid& uuid, - const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); - - void processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet); - void processKillNode(const QByteArray& datagram); - - int updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, const QByteArray& packet); - int findNodeAndUpdateWithDataFromPacket(const QByteArray& packet); - - unsigned broadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes); - SharedNodePointer soloNodeOfType(char nodeType); - - void getPacketStats(float &packetsPerSecond, float &bytesPerSecond); - void resetPacketStats(); void loadData(QSettings* settings); void saveData(QSettings* settings); public slots: void reset(); - void eraseAllNodes(); - void sendDomainServerCheckIn(); void pingInactiveNodes(); - void removeSilentNodes(); - - void killNodeWithUUID(const QUuid& nodeUUID); signals: void uuidChanged(const QUuid& ownerUUID); - void nodeAdded(SharedNodePointer); - void nodeKilled(SharedNodePointer); void limitOfSilentDomainCheckInsReached(); private: static NodeList* _sharedInstance; @@ -152,22 +97,11 @@ private: void sendSTUNRequest(); void processSTUNResponse(const QByteArray& packet); - qint64 writeDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr, - const QUuid& connectionSecret); - - NodeHash::iterator killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill); - void processDomainServerAuthRequest(const QByteArray& packet); void requestAuthForDomainServer(); void activateSocketFromNodeCommunication(const QByteArray& packet, const SharedNodePointer& sendingNode); void timePingReply(const QByteArray& packet, const SharedNodePointer& sendingNode); - void changeSendSocketBufferSize(int numSendBytes); - - NodeHash _nodeHash; - QMutex _nodeHashMutex; - QUdpSocket _nodeSocket; - QUdpSocket* _dtlsSocket; NodeType_t _ownerType; NodeSet _nodeTypesOfInterest; DomainHandler _DomainHandler; @@ -177,9 +111,6 @@ private: HifiSockAddr _publicSockAddr; bool _hasCompletedInitialSTUNFailure; unsigned int _stunRequestsSinceSuccess; - int _numCollectedPackets; - int _numCollectedBytes; - QElapsedTimer _packetStatTimer; }; #endif /* defined(__hifi__NodeList__) */ From 0be2eb57bfef11b35ddaebf0cea577ea038d8465 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 1 Apr 2014 13:56:33 -0700 Subject: [PATCH 10/86] repairs to NodeList and LimitedNodeList --- domain-server/src/DomainServer.cpp | 5 +-- libraries/shared/src/LimitedNodeList.cpp | 16 +++++++-- libraries/shared/src/LimitedNodeList.h | 5 +++ libraries/shared/src/NodeList.cpp | 45 ++++++++---------------- libraries/shared/src/NodeList.h | 9 ++--- libraries/shared/src/PacketHeaders.cpp | 2 +- libraries/shared/src/PacketHeaders.h | 3 +- 7 files changed, 42 insertions(+), 43 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index a32ae76e79..f83b6da97f 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -52,7 +52,7 @@ DomainServer::DomainServer(int argc, char* argv[]) : if (optionallySetupDTLS()) { // we either read a certificate and private key or were not passed one, good to load assignments // and set up the node list - qDebug() << "Setting up NodeList and assignments."; + qDebug() << "Setting up LimitedNodeList and assignments."; setupNodeListAndAssignments(); if (_isUsingDTLS) { @@ -542,7 +542,8 @@ void DomainServer::readAvailableDatagrams() { receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize()); nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(), senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); - if (packetTypeForPacket(receivedPacket) && nodeList->packetVersionAndHashMatch(receivedPacket)) { + if (packetTypeForPacket(receivedPacket) == PacketTypeRequestAssignment + && nodeList->packetVersionAndHashMatch(receivedPacket)) { // construct the requested assignment from the packet data Assignment requestAssignment(receivedPacket); diff --git a/libraries/shared/src/LimitedNodeList.cpp b/libraries/shared/src/LimitedNodeList.cpp index 88fdf18574..c71f3c13c9 100644 --- a/libraries/shared/src/LimitedNodeList.cpp +++ b/libraries/shared/src/LimitedNodeList.cpp @@ -43,7 +43,7 @@ LimitedNodeList* LimitedNodeList::createInstance(unsigned short socketListenPort // register the SharedNodePointer meta-type for signals/slots qRegisterMetaType(); } else { - qDebug("NodeList createInstance called with existing instance."); + qDebug("LimitedNodeList createInstance called with existing instance."); } return _sharedInstance; @@ -51,7 +51,7 @@ LimitedNodeList* LimitedNodeList::createInstance(unsigned short socketListenPort LimitedNodeList* LimitedNodeList::getInstance() { if (!_sharedInstance) { - qDebug("NodeList getInstance called before call to createInstance. Returning NULL pointer."); + qDebug("LimitedNodeList getInstance called before call to createInstance. Returning NULL pointer."); } return _sharedInstance; @@ -59,6 +59,7 @@ LimitedNodeList* LimitedNodeList::getInstance() { LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort) : + _sessionUUID(), _nodeHash(), _nodeHashMutex(QMutex::Recursive), _nodeSocket(this), @@ -84,6 +85,17 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short _packetStatTimer.start(); } +void LimitedNodeList::setSessionUUID(const QUuid& sessionUUID) { + QUuid oldUUID = _sessionUUID; + _sessionUUID = sessionUUID; + + if (sessionUUID != oldUUID) { + qDebug() << "NodeList UUID changed from" << uuidStringWithoutCurlyBraces(oldUUID) + << "to" << uuidStringWithoutCurlyBraces(_sessionUUID); + emit uuidChanged(sessionUUID); + } +} + QUdpSocket& LimitedNodeList::getDTLSSocket() { if (!_dtlsSocket) { // DTLS socket getter called but no DTLS socket exists, create it now diff --git a/libraries/shared/src/LimitedNodeList.h b/libraries/shared/src/LimitedNodeList.h index 1c4035be47..544207d1b5 100644 --- a/libraries/shared/src/LimitedNodeList.h +++ b/libraries/shared/src/LimitedNodeList.h @@ -56,6 +56,9 @@ public: static LimitedNodeList* createInstance(unsigned short socketListenPort = 0, unsigned short dtlsPort = 0); static LimitedNodeList* getInstance(); + const QUuid& getSessionUUID() const { return _sessionUUID; } + void setSessionUUID(const QUuid& sessionUUID); + QUdpSocket& getNodeSocket() { return _nodeSocket; } QUdpSocket& getDTLSSocket(); @@ -99,6 +102,7 @@ public slots: void killNodeWithUUID(const QUuid& nodeUUID); signals: + void uuidChanged(const QUuid& ownerUUID); void nodeAdded(SharedNodePointer); void nodeKilled(SharedNodePointer); protected: @@ -116,6 +120,7 @@ protected: void changeSendSocketBufferSize(int numSendBytes); + QUuid _sessionUUID; NodeHash _nodeHash; QMutex _nodeHashMutex; QUdpSocket _nodeSocket; diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 0b94e1b774..3202909447 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -28,6 +28,7 @@ NodeList* NodeList::createInstance(char ownerType, unsigned short socketListenPo NodeType::init(); _sharedInstance = new NodeList(ownerType, socketListenPort, dtlsPort); + LimitedNodeList::_sharedInstance = _sharedInstance; // register the SharedNodePointer meta-type for signals/slots qRegisterMetaType(); @@ -50,7 +51,6 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned LimitedNodeList(socketListenPort, dtlsListenPort), _ownerType(newOwnerType), _nodeTypesOfInterest(), - _sessionUUID(), _numNoReplyDomainCheckIns(0), _assignmentServerSocket(), _publicSockAddr(), @@ -58,7 +58,7 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned _stunRequestsSinceSuccess(0) { // clear our NodeList when the domain changes - connect(&_DomainHandler, &DomainHandler::hostnameChanged, this, &NodeList::reset); + connect(&_domainHandler, &DomainHandler::hostnameChanged, this, &NodeList::reset); // clear our NodeList when logout is requested connect(&AccountManager::getInstance(), &AccountManager::logoutComplete , this, &NodeList::reset); @@ -70,7 +70,7 @@ qint64 NodeList::sendStatsToDomainServer(const QJsonObject& statsObject) { statsPacketStream << statsObject.toVariantMap(); - return writeDatagram(statsPacket, _DomainHandler.getSockAddr(), QUuid()); + return writeDatagram(statsPacket, _domainHandler.getSockAddr(), QUuid()); } void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer& sendingNode) { @@ -115,7 +115,7 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteAr break; } case PacketTypeDomainServerRequireDTLS: { - _DomainHandler.parseDTLSRequirementPacket(packet); + _domainHandler.parseDTLSRequirementPacket(packet); break; } case PacketTypePing: { @@ -165,7 +165,7 @@ void NodeList::reset() { setSessionUUID(QUuid()); // clear the domain connection information - _DomainHandler.clearConnectionInfo(); + _domainHandler.clearConnectionInfo(); } void NodeList::addNodeTypeToInterestSet(NodeType_t nodeTypeToAdd) { @@ -317,15 +317,11 @@ void NodeList::sendDomainServerCheckIn() { // 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 (!_DomainHandler.getIP().isNull()) { + } else if (!_domainHandler.getIP().isNull()) { // construct the DS check in packet + QUuid packetUUID = (!_sessionUUID.isNull() ? _sessionUUID : _domainHandler.getAssignmentUUID()); - PacketType domainPacketType = _sessionUUID.isNull() ? PacketTypeDomainConnectRequest : PacketTypeDomainListRequest; - - QUuid packetUUID = (domainPacketType == PacketTypeDomainListRequest) - ? _sessionUUID : _DomainHandler.getAssignmentUUID(); - - QByteArray domainServerPacket = byteArrayWithPopulatedHeader(domainPacketType, packetUUID); + QByteArray domainServerPacket = byteArrayWithPopulatedHeader(PacketTypeDomainListRequest, packetUUID); QDataStream packetStream(&domainServerPacket, QIODevice::Append); // pack our data to send to the domain-server @@ -338,7 +334,7 @@ void NodeList::sendDomainServerCheckIn() { packetStream << nodeTypeOfInterest; } - writeDatagram(domainServerPacket, _DomainHandler.getSockAddr(), QUuid()); + writeDatagram(domainServerPacket, _domainHandler.getSockAddr(), QUuid()); const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5; static unsigned int numDomainCheckins = 0; @@ -358,23 +354,12 @@ void NodeList::sendDomainServerCheckIn() { } } -void NodeList::setSessionUUID(const QUuid& sessionUUID) { - QUuid oldUUID = _sessionUUID; - _sessionUUID = sessionUUID; - - if (sessionUUID != oldUUID) { - qDebug() << "NodeList UUID changed from" << uuidStringWithoutCurlyBraces(oldUUID) - << "to" << uuidStringWithoutCurlyBraces(_sessionUUID); - emit uuidChanged(sessionUUID); - } -} - int NodeList::processDomainServerList(const QByteArray& packet) { // this is a packet from the domain server, reset the count of un-replied check-ins _numNoReplyDomainCheckIns = 0; // if this was the first domain-server list from this domain, we've now connected - _DomainHandler.setIsConnected(true); + _domainHandler.setIsConnected(true); int readNodes = 0; @@ -401,7 +386,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(_DomainHandler.getIP()); + nodePublicSocket.setAddress(_domainHandler.getIP()); } SharedNodePointer node = addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, nodeLocalSocket); @@ -511,9 +496,9 @@ void NodeList::loadData(QSettings *settings) { QString domainServerHostname = settings->value(DOMAIN_SERVER_SETTING_KEY).toString(); if (domainServerHostname.size() > 0) { - _DomainHandler.setHostname(domainServerHostname); + _domainHandler.setHostname(domainServerHostname); } else { - _DomainHandler.setHostname(DEFAULT_DOMAIN_HOSTNAME); + _domainHandler.setHostname(DEFAULT_DOMAIN_HOSTNAME); } settings->endGroup(); @@ -522,9 +507,9 @@ void NodeList::loadData(QSettings *settings) { void NodeList::saveData(QSettings* settings) { settings->beginGroup(DOMAIN_SERVER_SETTING_KEY); - if (_DomainHandler.getHostname() != DEFAULT_DOMAIN_HOSTNAME) { + if (_domainHandler.getHostname() != DEFAULT_DOMAIN_HOSTNAME) { // the user is using a different hostname, store it - settings->setValue(DOMAIN_SERVER_SETTING_KEY, QVariant(_DomainHandler.getHostname())); + settings->setValue(DOMAIN_SERVER_SETTING_KEY, QVariant(_domainHandler.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 bc22c97904..5ccfc80e35 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -56,13 +56,10 @@ public: NodeType_t getOwnerType() const { return _ownerType; } void setOwnerType(NodeType_t ownerType) { _ownerType = ownerType; } - const QUuid& getSessionUUID() const { return _sessionUUID; } - void setSessionUUID(const QUuid& sessionUUID); - qint64 sendStatsToDomainServer(const QJsonObject& statsObject); int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; } - DomainHandler& getDomainHandler() { return _DomainHandler; } + DomainHandler& getDomainHandler() { return _domainHandler; } const NodeSet& getNodeInterestSet() const { return _nodeTypesOfInterest; } void addNodeTypeToInterestSet(NodeType_t nodeTypeToAdd); @@ -86,7 +83,6 @@ public slots: void sendDomainServerCheckIn(); void pingInactiveNodes(); signals: - void uuidChanged(const QUuid& ownerUUID); void limitOfSilentDomainCheckInsReached(); private: static NodeList* _sharedInstance; @@ -104,8 +100,7 @@ private: NodeType_t _ownerType; NodeSet _nodeTypesOfInterest; - DomainHandler _DomainHandler; - QUuid _sessionUUID; + DomainHandler _domainHandler; int _numNoReplyDomainCheckIns; HifiSockAddr _assignmentServerSocket; HifiSockAddr _publicSockAddr; diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index da8de0ddb0..1c7439861c 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -84,7 +84,7 @@ int populatePacketHeader(char* packet, PacketType type, const QUuid& connectionU char* position = packet + numTypeBytes + sizeof(PacketVersion); - QUuid packUUID = connectionUUID.isNull() ? NodeList::getInstance()->getSessionUUID() : connectionUUID; + QUuid packUUID = connectionUUID.isNull() ? LimitedNodeList::getInstance()->getSessionUUID() : connectionUUID; QByteArray rfcUUID = packUUID.toRfc4122(); memcpy(position, rfcUUID.constData(), NUM_BYTES_RFC4122_UUID); diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index 0250fb038a..61176051bb 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -67,7 +67,8 @@ typedef char PacketVersion; const QSet NON_VERIFIED_PACKETS = QSet() << PacketTypeDomainServerRequireDTLS << PacketTypeDomainList << PacketTypeDomainListRequest - << PacketTypeCreateAssignment << PacketTypeRequestAssignment << PacketTypeStunResponse; + << PacketTypeCreateAssignment << PacketTypeRequestAssignment << PacketTypeStunResponse + << PacketTypeNodeJsonStats; const int NUM_BYTES_MD5_HASH = 16; const int NUM_STATIC_HEADER_BYTES = sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID; From 94b29782eb84ed6471f41399756b5f7a1aebfded Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 1 Apr 2014 14:19:07 -0700 Subject: [PATCH 11/86] re-scaffold some client side DTLS in DTLSSession --- libraries/shared/src/DTLSSession.cpp | 50 +++++++++++++++++++------- libraries/shared/src/DTLSSession.h | 15 ++++---- libraries/shared/src/DomainHandler.cpp | 3 +- 3 files changed, 46 insertions(+), 22 deletions(-) diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index ce14d91f27..9c86f8d7a2 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -6,13 +6,15 @@ // Copyright (c) 2014 High Fidelity, Inc. All rights reserved. // +#include + #include "DTLSSession.h" -static int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms) { +int DTLSSession::socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms) { return 1; } -static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size) { +ssize_t DTLSSession::socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size) { DTLSSession* session = static_cast(ptr); QUdpSocket& dtlsSocket = session->_dtlsSocket; @@ -24,20 +26,44 @@ static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size) } } -static ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size) { +ssize_t DTLSSession::socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size) { DTLSSession* session = static_cast(ptr); QUdpSocket& dtlsSocket = session->_dtlsSocket; - if (dtlsSocket.state() != QAbstractSocket::ConnectedState) { - gnutls_transport_set_errno(session->_gnutlsSession, GNUTLS_E_AGAIN); - return -1; - } - - return dtlsSocket.write(reinterpret_cast(buffer), size); + return dtlsSocket.writeDatagram(reinterpret_cast(buffer), size, + session->_destinationSocket.getAddress(), session->_destinationSocket.getPort()); } -DTLSSession::DTLSSession(QUdpSocket& dtlsSocket) : - _dtlsSocket(dtlsSocket) -{ +static gnutls_certificate_credentials_t* x509ClientCredentials() { + static gnutls_certificate_credentials_t x509Credentials; + static bool credentialsInitialized = false; + if (!credentialsInitialized) { + gnutls_certificate_allocate_credentials(&x509Credentials); + } + + return &x509Credentials; +} + +DTLSSession::DTLSSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : + _dtlsSocket(dtlsSocket), + _destinationSocket(destinationSocket) +{ + qDebug() << "Initializing DTLS Session."; + + gnutls_init(&_gnutlsSession, GNUTLS_CLIENT | GNUTLS_DATAGRAM); + gnutls_priority_set_direct(_gnutlsSession, "NORMAL", NULL); + + gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, x509ClientCredentials()); + + // tell GnuTLS to call us for push or pull + gnutls_transport_set_ptr(_gnutlsSession, this); + gnutls_transport_set_push_function(_gnutlsSession, socketPush); + gnutls_transport_set_pull_function(_gnutlsSession, socketPull); + gnutls_transport_set_pull_timeout_function(_gnutlsSession, socketPullTimeout); + + // start the handshake process with domain-server now + int handshakeReturn = gnutls_handshake(_gnutlsSession); + gnutls_perror(handshakeReturn); + qDebug() << "HR" << handshakeReturn; } \ No newline at end of file diff --git a/libraries/shared/src/DTLSSession.h b/libraries/shared/src/DTLSSession.h index 190373c155..c0077a38b4 100644 --- a/libraries/shared/src/DTLSSession.h +++ b/libraries/shared/src/DTLSSession.h @@ -13,20 +13,19 @@ #include -static int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms); -static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size); -static ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size); +#include "HifiSockAddr.h" class DTLSSession { public: - DTLSSession(QUdpSocket& dtlsSocket); - - friend int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms); - friend ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size); - friend ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size); + DTLSSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); private: + static int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms); + static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size); + static ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size); + QUdpSocket& _dtlsSocket; gnutls_session_t _gnutlsSession; + HifiSockAddr _destinationSocket; }; #endif /* defined(__hifi__DTLSSession__) */ diff --git a/libraries/shared/src/DomainHandler.cpp b/libraries/shared/src/DomainHandler.cpp index 52bfa04414..2881da64c5 100644 --- a/libraries/shared/src/DomainHandler.cpp +++ b/libraries/shared/src/DomainHandler.cpp @@ -42,7 +42,7 @@ void DomainHandler::reset() { void DomainHandler::initializeDTLSSession() { if (!_dtlsSession) { - _dtlsSession = new DTLSSession(NodeList::getInstance()->getDTLSSocket()); + _dtlsSession = new DTLSSession(NodeList::getInstance()->getDTLSSocket(), _sockAddr); } } @@ -119,7 +119,6 @@ void DomainHandler::parseDTLSRequirementPacket(const QByteArray& dtlsRequirement unsigned short dtlsPort = 0; memcpy(&dtlsPort, dtlsRequirementPacket.data() + numBytesPacketHeader, sizeof(dtlsPort)); - qDebug() << "domain-server DTLS port changed to" << dtlsPort << "- Enabling DTLS."; _sockAddr.setPort(dtlsPort); From ce6f84568187652e1f15ce832ec455dc38b06887 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 1 Apr 2014 14:47:30 -0700 Subject: [PATCH 12/86] remove some gnutls handshake debugging --- domain-server/src/DomainServer.cpp | 1 - libraries/shared/src/DTLSSession.cpp | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index f83b6da97f..60df41007d 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -476,7 +476,6 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif LimitedNodeList* nodeList = LimitedNodeList::getInstance(); - if (nodeInterestList.size() > 0) { // if the node has any interest types, send back those nodes as well foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) { diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index 9c86f8d7a2..90558034a7 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -63,7 +63,5 @@ DTLSSession::DTLSSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket gnutls_transport_set_pull_timeout_function(_gnutlsSession, socketPullTimeout); // start the handshake process with domain-server now - int handshakeReturn = gnutls_handshake(_gnutlsSession); - gnutls_perror(handshakeReturn); - qDebug() << "HR" << handshakeReturn; + gnutls_handshake(_gnutlsSession); } \ No newline at end of file From b5b4edc999639c60bd3ca97cfc0d7f3354466c19 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 1 Apr 2014 16:47:45 -0700 Subject: [PATCH 13/86] add notion of server and client DTLSSessions --- domain-server/src/DTLSServerSession.cpp | 15 ++++++++++ domain-server/src/DTLSServerSession.h | 19 ++++++++++++ domain-server/src/DomainServer.cpp | 34 ++++++++++++++++++---- domain-server/src/DomainServer.h | 4 +++ domain-server/src/DomainServerNodeData.cpp | 3 +- domain-server/src/DomainServerNodeData.h | 5 ++++ libraries/shared/src/DTLSClientSession.cpp | 15 ++++++++++ libraries/shared/src/DTLSClientSession.h | 19 ++++++++++++ libraries/shared/src/DTLSSession.cpp | 20 ++----------- libraries/shared/src/DTLSSession.h | 9 ++++-- libraries/shared/src/DomainHandler.cpp | 2 +- libraries/shared/src/DomainHandler.h | 4 +-- libraries/shared/src/HifiSockAddr.cpp | 19 +++++++++++- libraries/shared/src/HifiSockAddr.h | 3 ++ 14 files changed, 141 insertions(+), 30 deletions(-) create mode 100644 domain-server/src/DTLSServerSession.cpp create mode 100644 domain-server/src/DTLSServerSession.h create mode 100644 libraries/shared/src/DTLSClientSession.cpp create mode 100644 libraries/shared/src/DTLSClientSession.h diff --git a/domain-server/src/DTLSServerSession.cpp b/domain-server/src/DTLSServerSession.cpp new file mode 100644 index 0000000000..994b196357 --- /dev/null +++ b/domain-server/src/DTLSServerSession.cpp @@ -0,0 +1,15 @@ +// +// DTLSServerSession.cpp +// hifi +// +// Created by Stephen Birarda on 2014-04-01. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#include "DTLSServerSession.h" + +DTLSServerSession::DTLSServerSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : + DTLSSession(GNUTLS_SERVER, dtlsSocket, destinationSocket) +{ + +} \ No newline at end of file diff --git a/domain-server/src/DTLSServerSession.h b/domain-server/src/DTLSServerSession.h new file mode 100644 index 0000000000..5bdb0f9e91 --- /dev/null +++ b/domain-server/src/DTLSServerSession.h @@ -0,0 +1,19 @@ +// +// DTLSServerSession.h +// hifi +// +// Created by Stephen Birarda on 2014-04-01. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__DTLSServerSession__ +#define __hifi__DTLSServerSession__ + +#include + +class DTLSServerSession : public DTLSSession { +public: + DTLSServerSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); +}; + +#endif /* defined(__hifi__DTLSServerSession__) */ diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 60df41007d..ba2f2791bd 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -6,8 +6,6 @@ // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // -#include - #include #include #include @@ -393,8 +391,12 @@ void DomainServer::addNodeToNodeListAndConfirmConnection(const QByteArray& packe SharedNodePointer newNode = LimitedNodeList::getInstance()->addOrUpdateNode(nodeUUID, nodeType, publicSockAddr, localSockAddr); - // when the newNode is created the linked data is also created, if this was a static assignment set the UUID - reinterpret_cast(newNode->getLinkedData())->setStaticAssignmentUUID(assignmentUUID); + // when the newNode is created the linked data is also created + // if this was a static assignment set the UUID, set the sendingSockAddr + DomainServerNodeData* nodeData = reinterpret_cast(newNode->getLinkedData()); + + nodeData->setStaticAssignmentUUID(assignmentUUID); + nodeData->setSendingSockAddr(senderSockAddr); if (!authJsonObject.isEmpty()) { // pull the connection secret from the authJsonObject and set it as the connection secret for this node @@ -533,7 +535,6 @@ void DomainServer::readAvailableDatagrams() { HifiSockAddr senderSockAddr; QByteArray receivedPacket; - static QByteArray assignmentPacket = byteArrayWithPopulatedHeader(PacketTypeCreateAssignment); static int numAssignmentPacketHeaderBytes = assignmentPacket.size(); @@ -603,7 +604,30 @@ void DomainServer::readAvailableDatagrams() { } void DomainServer::readAvailableDTLSDatagrams() { + LimitedNodeList* nodeList = LimitedNodeList::getInstance(); + QUdpSocket& dtlsSocket = nodeList->getDTLSSocket(); + + static sockaddr senderSockAddr; + static socklen_t sockAddrSize = sizeof(senderSockAddr); + + while (dtlsSocket.hasPendingDatagrams()) { + // check if we have an active DTLS session for this sender + QByteArray peekDatagram(dtlsSocket.pendingDatagramSize(), 0); + + recvfrom(dtlsSocket.socketDescriptor(), peekDatagram.data(), dtlsSocket.pendingDatagramSize(), + MSG_PEEK, &senderSockAddr, &sockAddrSize); + + DTLSSession* existingSession = _dtlsSessions.value(HifiSockAddr(&senderSockAddr)); + + qDebug() << "Checking for a session with" << HifiSockAddr(&senderSockAddr); + + if (existingSession) { + // use GnuTLS to receive the encrypted data + } else { + // no existing session - set up a new session now + } + } } void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr) { diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 7ee6d7374e..a69df5dec0 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -23,6 +23,8 @@ #include #include +#include "DTLSServerSession.h" + typedef QSharedPointer SharedAssignmentPointer; class DomainServer : public QCoreApplication, public HTTPRequestHandler { @@ -88,6 +90,8 @@ private: gnutls_certificate_credentials_t* _x509Credentials; gnutls_dh_params_t* _dhParams; gnutls_priority_t* _priorityCache; + + QHash _dtlsSessions; }; #endif /* defined(__hifi__DomainServer__) */ diff --git a/domain-server/src/DomainServerNodeData.cpp b/domain-server/src/DomainServerNodeData.cpp index f1e08e3bc4..6e94a8a330 100644 --- a/domain-server/src/DomainServerNodeData.cpp +++ b/domain-server/src/DomainServerNodeData.cpp @@ -17,7 +17,8 @@ DomainServerNodeData::DomainServerNodeData() : _sessionSecretHash(), _staticAssignmentUUID(), - _statsJSONObject() + _statsJSONObject(), + _sendingSockAddr() { } diff --git a/domain-server/src/DomainServerNodeData.h b/domain-server/src/DomainServerNodeData.h index 20531839f4..40516a70aa 100644 --- a/domain-server/src/DomainServerNodeData.h +++ b/domain-server/src/DomainServerNodeData.h @@ -12,6 +12,7 @@ #include #include +#include #include class DomainServerNodeData : public NodeData { @@ -26,6 +27,9 @@ public: void setStaticAssignmentUUID(const QUuid& staticAssignmentUUID) { _staticAssignmentUUID = staticAssignmentUUID; } const QUuid& getStaticAssignmentUUID() const { return _staticAssignmentUUID; } + void setSendingSockAddr(const HifiSockAddr& sendingSockAddr) { _sendingSockAddr = sendingSockAddr; } + const HifiSockAddr& getSendingSockAddr() { return _sendingSockAddr; } + QHash& getSessionSecretHash() { return _sessionSecretHash; } private: QJsonObject mergeJSONStatsFromNewObject(const QJsonObject& newObject, QJsonObject destinationObject); @@ -33,6 +37,7 @@ private: QHash _sessionSecretHash; QUuid _staticAssignmentUUID; QJsonObject _statsJSONObject; + HifiSockAddr _sendingSockAddr; }; #endif /* defined(__hifi__DomainServerNodeData__) */ diff --git a/libraries/shared/src/DTLSClientSession.cpp b/libraries/shared/src/DTLSClientSession.cpp new file mode 100644 index 0000000000..30ca536c9e --- /dev/null +++ b/libraries/shared/src/DTLSClientSession.cpp @@ -0,0 +1,15 @@ +// +// DTLSClientSession.cpp +// hifi +// +// Created by Stephen Birarda on 2014-04-01. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// + +#include "DTLSClientSession.h" + +DTLSClientSession::DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : + DTLSSession(GNUTLS_CLIENT, dtlsSocket, destinationSocket) +{ + +} \ No newline at end of file diff --git a/libraries/shared/src/DTLSClientSession.h b/libraries/shared/src/DTLSClientSession.h new file mode 100644 index 0000000000..93cd51cb9a --- /dev/null +++ b/libraries/shared/src/DTLSClientSession.h @@ -0,0 +1,19 @@ +// +// DTLSClientSession.h +// hifi +// +// Created by Stephen Birarda on 2014-04-01. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__DTLSClientSession__ +#define __hifi__DTLSClientSession__ + +#include "DTLSSession.h" + +class DTLSClientSession : public DTLSSession { +public: + DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); +}; + +#endif /* defined(__hifi__DTLSClientSession__) */ diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index 90558034a7..6113019cf9 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -34,7 +34,7 @@ ssize_t DTLSSession::socketPush(gnutls_transport_ptr_t ptr, const void* buffer, session->_destinationSocket.getAddress(), session->_destinationSocket.getPort()); } -static gnutls_certificate_credentials_t* x509ClientCredentials() { +gnutls_certificate_credentials_t* x509CACredentials() { static gnutls_certificate_credentials_t x509Credentials; static bool credentialsInitialized = false; @@ -45,23 +45,9 @@ static gnutls_certificate_credentials_t* x509ClientCredentials() { return &x509Credentials; } -DTLSSession::DTLSSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : +DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : _dtlsSocket(dtlsSocket), _destinationSocket(destinationSocket) { - qDebug() << "Initializing DTLS Session."; - - gnutls_init(&_gnutlsSession, GNUTLS_CLIENT | GNUTLS_DATAGRAM); - gnutls_priority_set_direct(_gnutlsSession, "NORMAL", NULL); - - gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, x509ClientCredentials()); - - // tell GnuTLS to call us for push or pull - gnutls_transport_set_ptr(_gnutlsSession, this); - gnutls_transport_set_push_function(_gnutlsSession, socketPush); - gnutls_transport_set_pull_function(_gnutlsSession, socketPull); - gnutls_transport_set_pull_timeout_function(_gnutlsSession, socketPullTimeout); - - // start the handshake process with domain-server now - gnutls_handshake(_gnutlsSession); + gnutls_init(&_gnutlsSession, end | GNUTLS_DATAGRAM); } \ No newline at end of file diff --git a/libraries/shared/src/DTLSSession.h b/libraries/shared/src/DTLSSession.h index c0077a38b4..ce453c6d22 100644 --- a/libraries/shared/src/DTLSSession.h +++ b/libraries/shared/src/DTLSSession.h @@ -15,13 +15,16 @@ #include "HifiSockAddr.h" -class DTLSSession { +class DTLSSession : public QObject { + Q_OBJECT public: - DTLSSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); -private: + DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); + +protected: static int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms); static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size); static ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size); + static gnutls_certificate_credentials_t* x509CACredentials(); QUdpSocket& _dtlsSocket; gnutls_session_t _gnutlsSession; diff --git a/libraries/shared/src/DomainHandler.cpp b/libraries/shared/src/DomainHandler.cpp index 2881da64c5..e6403dcbc1 100644 --- a/libraries/shared/src/DomainHandler.cpp +++ b/libraries/shared/src/DomainHandler.cpp @@ -42,7 +42,7 @@ void DomainHandler::reset() { void DomainHandler::initializeDTLSSession() { if (!_dtlsSession) { - _dtlsSession = new DTLSSession(NodeList::getInstance()->getDTLSSocket(), _sockAddr); + _dtlsSession = new DTLSClientSession(NodeList::getInstance()->getDTLSSocket(), _sockAddr); } } diff --git a/libraries/shared/src/DomainHandler.h b/libraries/shared/src/DomainHandler.h index 4a9f166963..5032138858 100644 --- a/libraries/shared/src/DomainHandler.h +++ b/libraries/shared/src/DomainHandler.h @@ -14,7 +14,7 @@ #include #include -#include "DTLSSession.h" +#include "DTLSClientSession.h" #include "HifiSockAddr.h" const QString DEFAULT_DOMAIN_HOSTNAME = "alpha.highfidelity.io"; @@ -67,7 +67,7 @@ private: QUuid _assignmentUUID; bool _isConnected; bool _requiresDTLS; - DTLSSession* _dtlsSession; + DTLSClientSession* _dtlsSession; }; #endif /* defined(__hifi__DomainHandler__) */ diff --git a/libraries/shared/src/HifiSockAddr.cpp b/libraries/shared/src/HifiSockAddr.cpp index cc031525d8..8010202424 100644 --- a/libraries/shared/src/HifiSockAddr.cpp +++ b/libraries/shared/src/HifiSockAddr.cpp @@ -6,12 +6,14 @@ // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // -#include "HifiSockAddr.h" +#include #include #include #include +#include "HifiSockAddr.h" + static int hifiSockAddrMetaTypeId = qMetaTypeId(); HifiSockAddr::HifiSockAddr() : @@ -44,6 +46,16 @@ HifiSockAddr::HifiSockAddr(const QString& hostname, quint16 hostOrderPort) { } } +HifiSockAddr::HifiSockAddr(const sockaddr* sockaddr) { + _address = QHostAddress(sockaddr); + + if (sockaddr->sa_family == AF_INET) { + _port = reinterpret_cast(sockaddr)->sin_port; + } else { + _port = reinterpret_cast(sockaddr)->sin6_port; + } +} + HifiSockAddr& HifiSockAddr::operator=(const HifiSockAddr& rhsSockAddr) { _address = rhsSockAddr._address; _port = rhsSockAddr._port; @@ -109,3 +121,8 @@ quint32 getHostOrderLocalAddress() { // return the looked up local address return localAddress; } + +uint qHash(const HifiSockAddr& key, uint seed) { + // use the existing QHostAddress and quint16 hash functions to get our hash + return qHash(key.getAddress(), seed) + qHash(key.getPort(), seed); +} diff --git a/libraries/shared/src/HifiSockAddr.h b/libraries/shared/src/HifiSockAddr.h index e8f928c36d..365067080b 100644 --- a/libraries/shared/src/HifiSockAddr.h +++ b/libraries/shared/src/HifiSockAddr.h @@ -17,6 +17,7 @@ public: HifiSockAddr(const QHostAddress& address, quint16 port); HifiSockAddr(const HifiSockAddr& otherSockAddr); HifiSockAddr(const QString& hostname, quint16 hostOrderPort); + HifiSockAddr(const sockaddr* sockaddr); bool isNull() const { return _address.isNull() && _port == 0; } @@ -45,6 +46,8 @@ private: quint16 _port; }; +uint qHash(const HifiSockAddr& key, uint seed); + quint32 getHostOrderLocalAddress(); Q_DECLARE_METATYPE(HifiSockAddr) From 632dc6b8e4f6811ac8427eeca4d15ae832d3e55d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 1 Apr 2014 16:51:05 -0700 Subject: [PATCH 14/86] set GnuTLS credentials for DTLSClientSession --- libraries/shared/src/DTLSClientSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/DTLSClientSession.cpp b/libraries/shared/src/DTLSClientSession.cpp index 30ca536c9e..7649b7f352 100644 --- a/libraries/shared/src/DTLSClientSession.cpp +++ b/libraries/shared/src/DTLSClientSession.cpp @@ -11,5 +11,5 @@ DTLSClientSession::DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : DTLSSession(GNUTLS_CLIENT, dtlsSocket, destinationSocket) { - + gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, DTLSSession::x509CACredentials()); } \ No newline at end of file From fd1ed13de028ab692eed2f228600e2d3ef3231f7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 1 Apr 2014 16:53:17 -0700 Subject: [PATCH 15/86] fix static x509CACredentials method --- libraries/shared/src/DTLSSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index 6113019cf9..0ab5bdb2bc 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -34,7 +34,7 @@ ssize_t DTLSSession::socketPush(gnutls_transport_ptr_t ptr, const void* buffer, session->_destinationSocket.getAddress(), session->_destinationSocket.getPort()); } -gnutls_certificate_credentials_t* x509CACredentials() { +gnutls_certificate_credentials_t* DTLSSession::x509CACredentials() { static gnutls_certificate_credentials_t x509Credentials; static bool credentialsInitialized = false; From dc3a4d49574b2766101eacd847c3e53488da72cf Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 2 Apr 2014 09:07:34 -0700 Subject: [PATCH 16/86] remove some unneeded parenthesis --- libraries/shared/src/DTLSSession.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/DTLSSession.h b/libraries/shared/src/DTLSSession.h index ce453c6d22..81c1a50916 100644 --- a/libraries/shared/src/DTLSSession.h +++ b/libraries/shared/src/DTLSSession.h @@ -20,11 +20,11 @@ class DTLSSession : public QObject { public: DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); + static gnutls_certificate_credentials_t* x509CACredentials(); protected: static int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms); static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size); static ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size); - static gnutls_certificate_credentials_t* x509CACredentials(); QUdpSocket& _dtlsSocket; gnutls_session_t _gnutlsSession; From e1cae6d295ba2c7384546b35eb552edfb814fafb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 2 Apr 2014 17:29:14 -0700 Subject: [PATCH 17/86] initial handshaking for DTLS sessions between DS and clients --- animation-server/src/AnimationServer.cpp | 2 +- assignment-client/src/audio/AudioMixer.cpp | 2 +- domain-server/src/DTLSServerSession.h | 2 + domain-server/src/DomainServer.cpp | 51 ++++++++++-- domain-server/src/DomainServer.h | 1 + libraries/audio/src/Sound.cpp | 1 + .../metavoxels/src/DatagramSequencer.cpp | 2 +- libraries/shared/src/DTLSClientSession.cpp | 22 +++++- libraries/shared/src/DTLSClientSession.h | 2 + libraries/shared/src/DTLSSession.cpp | 78 +++++++++++++----- libraries/shared/src/DTLSSession.h | 5 +- libraries/shared/src/DomainHandler.cpp | 9 ++- libraries/shared/src/DomainHandler.h | 3 +- libraries/shared/src/HifiSockAddr.cpp | 4 +- libraries/shared/src/LimitedNodeList.h | 2 + libraries/shared/src/NodeList.cpp | 79 +++++++++++-------- libraries/shared/src/NodeList.h | 2 +- libraries/shared/src/SharedUtil.h | 3 - libraries/shared/src/ThreadedAssignment.cpp | 2 +- 19 files changed, 200 insertions(+), 72 deletions(-) diff --git a/animation-server/src/AnimationServer.cpp b/animation-server/src/AnimationServer.cpp index e66ca35501..e92169bcfa 100644 --- a/animation-server/src/AnimationServer.cpp +++ b/animation-server/src/AnimationServer.cpp @@ -797,7 +797,7 @@ AnimationServer::AnimationServer(int &argc, char **argv) : QTimer* domainServerTimer = new QTimer(this); connect(domainServerTimer, SIGNAL(timeout()), nodeList, SLOT(sendDomainServerCheckIn())); - domainServerTimer->start(DOMAIN_SERVER_CHECK_IN_USECS / 1000); + domainServerTimer->start(DOMAIN_SERVER_CHECK_IN_MSECS); QTimer* silentNodeTimer = new QTimer(this); connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index f183abade9..b8cee17df5 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -369,7 +369,7 @@ void AudioMixer::sendStatsPacket() { statsObject["average_mixes_per_listener"] = 0.0; } - ThreadedAssignment::addPacketStatsAndSendStatsPacket(statsObject); +// ThreadedAssignment::addPacketStatsAndSendStatsPacket(statsObject); _sumListeners = 0; _sumMixes = 0; diff --git a/domain-server/src/DTLSServerSession.h b/domain-server/src/DTLSServerSession.h index 5bdb0f9e91..86f642b104 100644 --- a/domain-server/src/DTLSServerSession.h +++ b/domain-server/src/DTLSServerSession.h @@ -9,6 +9,8 @@ #ifndef __hifi__DTLSServerSession__ #define __hifi__DTLSServerSession__ +#include + #include class DTLSServerSession : public DTLSSession { diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index ba2f2791bd..5550c2741d 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -96,8 +96,12 @@ bool DomainServer::optionallySetupDTLS() { // set the D-H paramters on the X509 credentials gnutls_certificate_set_dh_params(*_x509Credentials, *_dhParams); + // setup the key used for cookie verification + _cookieKey = new gnutls_datum_t; + gnutls_key_generate(_cookieKey, GNUTLS_COOKIE_KEY_SIZE); + _priorityCache = new gnutls_priority_t; - const char DTLS_PRIORITY_STRING[] = "PERFORMANCE:-VERS-TLS-ALL:+VERS-DTLS1.2:%SERVER_PRECEDENCE"; + const char DTLS_PRIORITY_STRING[] = "PERFORMANCE:-VERS-TLS-ALL:+VERS-DTLS1.0:%SERVER_PRECEDENCE"; gnutls_priority_init(_priorityCache, DTLS_PRIORITY_STRING, NULL); _isUsingDTLS = true; @@ -612,20 +616,55 @@ void DomainServer::readAvailableDTLSDatagrams() { static socklen_t sockAddrSize = sizeof(senderSockAddr); while (dtlsSocket.hasPendingDatagrams()) { + qDebug() << "Looking at a datagram"; + // check if we have an active DTLS session for this sender QByteArray peekDatagram(dtlsSocket.pendingDatagramSize(), 0); recvfrom(dtlsSocket.socketDescriptor(), peekDatagram.data(), dtlsSocket.pendingDatagramSize(), MSG_PEEK, &senderSockAddr, &sockAddrSize); - DTLSSession* existingSession = _dtlsSessions.value(HifiSockAddr(&senderSockAddr)); - - qDebug() << "Checking for a session with" << HifiSockAddr(&senderSockAddr); + HifiSockAddr senderHifiSockAddr(&senderSockAddr); + DTLSServerSession* existingSession = _dtlsSessions.value(senderHifiSockAddr); if (existingSession) { - // use GnuTLS to receive the encrypted data + // check if we have completed handshake with this user + int handshakeReturn = gnutls_handshake(*existingSession->getGnuTLSSession()); + qDebug() << "Handshake return for user is" << handshakeReturn; } else { - // no existing session - set up a new session now + // first we verify the cookie + // see http://gnutls.org/manual/html_node/DTLS-sessions.html for why this is required + gnutls_dtls_prestate_st prestate; + memset(&prestate, 0, sizeof(prestate)); + int cookieValid = gnutls_dtls_cookie_verify(_cookieKey, &senderSockAddr, sizeof(senderSockAddr), + peekDatagram.data(), peekDatagram.size(), &prestate); + + if (cookieValid < 0) { + // the cookie sent by the client was not valid + // send a valid one + DTLSServerSession tempServerSession(LimitedNodeList::getInstance()->getDTLSSocket(), senderHifiSockAddr); + gnutls_dtls_cookie_send(_cookieKey, &senderSockAddr, sizeof(senderSockAddr), &prestate, + &tempServerSession, DTLSSession::socketPush); + + // acutally pull the peeked data off the network stack so that it gets discarded + dtlsSocket.readDatagram(peekDatagram.data(), peekDatagram.size()); + } else { + // cookie valid but no existing session - set up a new session now + DTLSServerSession* newServerSession = new DTLSServerSession(LimitedNodeList::getInstance()->getDTLSSocket(), + senderHifiSockAddr); + gnutls_session_t* gnutlsSession = newServerSession->getGnuTLSSession(); + + gnutls_priority_set(*gnutlsSession, *_priorityCache); + gnutls_credentials_set(*gnutlsSession, GNUTLS_CRD_CERTIFICATE, *_x509Credentials); + gnutls_dtls_prestate_set(*gnutlsSession, &prestate); + + // handshake to begin the session + int handshakeReturn = gnutls_handshake(*gnutlsSession); + qDebug() << "initial handshake return" << handshakeReturn; + + qDebug() << "Beginning DTLS session with node at" << senderHifiSockAddr; + _dtlsSessions[senderHifiSockAddr] = newServerSession; + } } } } diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index a69df5dec0..6bca67df0d 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -89,6 +89,7 @@ private: bool _isUsingDTLS; gnutls_certificate_credentials_t* _x509Credentials; gnutls_dh_params_t* _dhParams; + gnutls_datum_t* _cookieKey; gnutls_priority_t* _priorityCache; QHash _dtlsSessions; diff --git a/libraries/audio/src/Sound.cpp b/libraries/audio/src/Sound.cpp index 91a47b7d2c..17babcdae3 100644 --- a/libraries/audio/src/Sound.cpp +++ b/libraries/audio/src/Sound.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include "AudioRingBuffer.h" diff --git a/libraries/metavoxels/src/DatagramSequencer.cpp b/libraries/metavoxels/src/DatagramSequencer.cpp index 052f480fcf..be39fb78b1 100644 --- a/libraries/metavoxels/src/DatagramSequencer.cpp +++ b/libraries/metavoxels/src/DatagramSequencer.cpp @@ -10,7 +10,7 @@ #include -#include +#include #include "DatagramSequencer.h" #include "MetavoxelMessages.h" diff --git a/libraries/shared/src/DTLSClientSession.cpp b/libraries/shared/src/DTLSClientSession.cpp index 7649b7f352..109172487f 100644 --- a/libraries/shared/src/DTLSClientSession.cpp +++ b/libraries/shared/src/DTLSClientSession.cpp @@ -8,8 +8,28 @@ #include "DTLSClientSession.h" +gnutls_certificate_credentials_t* DTLSClientSession::x509CACredentials() { + static gnutls_certificate_credentials_t x509Credentials; + static bool credentialsInitialized = false; + + if (!credentialsInitialized) { + gnutls_certificate_allocate_credentials(&x509Credentials); + qDebug() << "processed" << gnutls_certificate_set_x509_trust_file(x509Credentials, "/Users/birarda/code/hifi/certs/root-ca.crt", GNUTLS_X509_FMT_PEM); + } + + return &x509Credentials; +} + +int verifyX509Certificate(gnutls_session_t session) { + int certificateType = gnutls_certificate_type_get(session); + qDebug() << "Verifying a certificate of type" << certificateType; + + return 0; +} + DTLSClientSession::DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : DTLSSession(GNUTLS_CLIENT, dtlsSocket, destinationSocket) { - gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, DTLSSession::x509CACredentials()); + gnutls_priority_set_direct(_gnutlsSession, "PERFORMANCE", NULL); + gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, x509CACredentials()); } \ No newline at end of file diff --git a/libraries/shared/src/DTLSClientSession.h b/libraries/shared/src/DTLSClientSession.h index 93cd51cb9a..a81daf6d74 100644 --- a/libraries/shared/src/DTLSClientSession.h +++ b/libraries/shared/src/DTLSClientSession.h @@ -14,6 +14,8 @@ class DTLSClientSession : public DTLSSession { public: DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); + + static gnutls_certificate_credentials_t* x509CACredentials(); }; #endif /* defined(__hifi__DTLSClientSession__) */ diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index 0ab5bdb2bc..52c55bec23 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -8,46 +8,88 @@ #include +#include "NodeList.h" #include "DTLSSession.h" int DTLSSession::socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms) { - return 1; + DTLSSession* session = static_cast(ptr); + QUdpSocket& dtlsSocket = session->_dtlsSocket; + + if (dtlsSocket.hasPendingDatagrams()) { + // peek the data on stack to see if it belongs to this session + static sockaddr senderSockAddr; + static socklen_t sockAddrSize = sizeof(senderSockAddr); + + QByteArray peekDatagram(dtlsSocket.pendingDatagramSize(), 0); + + recvfrom(dtlsSocket.socketDescriptor(), peekDatagram.data(), dtlsSocket.pendingDatagramSize(), + MSG_PEEK, &senderSockAddr, &sockAddrSize); + + if (HifiSockAddr(&senderSockAddr) == session->_destinationSocket) { + // there is data for this session ready to be read + return 1; + } else { + // the next data from the dtlsSocket is not for this session + return 0; + } + } else { + // no data available on the dtlsSocket + return 0; + } } ssize_t DTLSSession::socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size) { DTLSSession* session = static_cast(ptr); QUdpSocket& dtlsSocket = session->_dtlsSocket; - if (dtlsSocket.hasPendingDatagrams()) { - return dtlsSocket.read(reinterpret_cast(buffer), size); - } else { - gnutls_transport_set_errno(session->_gnutlsSession, GNUTLS_E_AGAIN); - return 0; + HifiSockAddr pulledSockAddr; + qint64 bytesReceived = dtlsSocket.readDatagram(reinterpret_cast(buffer), size, + pulledSockAddr.getAddressPointer(), pulledSockAddr.getPortPointer()); + if (bytesReceived == -1) { + // no data to pull, return -1 + qDebug() << "Received no data on call to readDatagram"; + return bytesReceived; } + + if (pulledSockAddr == session->_destinationSocket) { + // bytes received from the correct sender, return number of bytes received + qDebug() << "Received" << bytesReceived << "on DTLS socket from" << pulledSockAddr; + return bytesReceived; + } else { + qDebug() << pulledSockAddr << "is not" << session->_destinationSocket; + } + + // we pulled a packet not matching this session, so output that + qDebug() << "Denied connection from" << pulledSockAddr; + + gnutls_transport_set_errno(session->_gnutlsSession, GNUTLS_E_AGAIN); + return -1; } ssize_t DTLSSession::socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size) { DTLSSession* session = static_cast(ptr); QUdpSocket& dtlsSocket = session->_dtlsSocket; + qDebug() << "Pushing a message of size" << size << "to" << session->_destinationSocket; return dtlsSocket.writeDatagram(reinterpret_cast(buffer), size, session->_destinationSocket.getAddress(), session->_destinationSocket.getPort()); } -gnutls_certificate_credentials_t* DTLSSession::x509CACredentials() { - static gnutls_certificate_credentials_t x509Credentials; - static bool credentialsInitialized = false; - - if (!credentialsInitialized) { - gnutls_certificate_allocate_credentials(&x509Credentials); - } - - return &x509Credentials; -} - DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : _dtlsSocket(dtlsSocket), _destinationSocket(destinationSocket) { - gnutls_init(&_gnutlsSession, end | GNUTLS_DATAGRAM); + gnutls_init(&_gnutlsSession, end | GNUTLS_DATAGRAM | GNUTLS_NONBLOCK); + + // see http://gnutls.org/manual/html_node/Datagram-TLS-API.html#gnutls_005fdtls_005fset_005fmtu + const unsigned int DTLS_MAX_MTU = 1452; + gnutls_dtls_set_mtu(_gnutlsSession, DTLS_MAX_MTU); + + const unsigned int DTLS_TOTAL_CONNECTION_TIMEOUT = 10 * DOMAIN_SERVER_CHECK_IN_MSECS; + gnutls_dtls_set_timeouts(_gnutlsSession, 0, DTLS_TOTAL_CONNECTION_TIMEOUT); + + gnutls_transport_set_ptr(_gnutlsSession, this); + gnutls_transport_set_push_function(_gnutlsSession, socketPush); + gnutls_transport_set_pull_function(_gnutlsSession, socketPull); + gnutls_transport_set_pull_timeout_function(_gnutlsSession, socketPullTimeout); } \ No newline at end of file diff --git a/libraries/shared/src/DTLSSession.h b/libraries/shared/src/DTLSSession.h index 81c1a50916..ce190e11c0 100644 --- a/libraries/shared/src/DTLSSession.h +++ b/libraries/shared/src/DTLSSession.h @@ -20,12 +20,13 @@ class DTLSSession : public QObject { public: DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); - static gnutls_certificate_credentials_t* x509CACredentials(); -protected: static int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms); static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size); static ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size); + gnutls_session_t* getGnuTLSSession() { return &_gnutlsSession; } + +protected: QUdpSocket& _dtlsSocket; gnutls_session_t _gnutlsSession; HifiSockAddr _destinationSocket; diff --git a/libraries/shared/src/DomainHandler.cpp b/libraries/shared/src/DomainHandler.cpp index e6403dcbc1..6bc959be47 100644 --- a/libraries/shared/src/DomainHandler.cpp +++ b/libraries/shared/src/DomainHandler.cpp @@ -18,7 +18,6 @@ DomainHandler::DomainHandler() : _sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)), _assignmentUUID(), _isConnected(false), - _requiresDTLS(false), _dtlsSession(NULL) { @@ -31,13 +30,18 @@ DomainHandler::~DomainHandler() { void DomainHandler::clearConnectionInfo() { _uuid = QUuid(); _isConnected = false; + + delete _dtlsSession; + _dtlsSession = NULL; } void DomainHandler::reset() { clearConnectionInfo(); _hostname = QString(); _sockAddr.setAddress(QHostAddress::Null); - _requiresDTLS = false; + + delete _dtlsSession; + _dtlsSession = NULL; } void DomainHandler::initializeDTLSSession() { @@ -122,7 +126,6 @@ void DomainHandler::parseDTLSRequirementPacket(const QByteArray& dtlsRequirement qDebug() << "domain-server DTLS port changed to" << dtlsPort << "- Enabling DTLS."; _sockAddr.setPort(dtlsPort); - _requiresDTLS = true; initializeDTLSSession(); } \ No newline at end of file diff --git a/libraries/shared/src/DomainHandler.h b/libraries/shared/src/DomainHandler.h index 5032138858..a867207190 100644 --- a/libraries/shared/src/DomainHandler.h +++ b/libraries/shared/src/DomainHandler.h @@ -49,6 +49,8 @@ public: bool isConnected() const { return _isConnected; } void setIsConnected(bool isConnected); + DTLSClientSession* getDTLSSession() { return _dtlsSession; } + void parseDTLSRequirementPacket(const QByteArray& dtlsRequirementPacket); private slots: @@ -66,7 +68,6 @@ private: HifiSockAddr _sockAddr; QUuid _assignmentUUID; bool _isConnected; - bool _requiresDTLS; DTLSClientSession* _dtlsSession; }; diff --git a/libraries/shared/src/HifiSockAddr.cpp b/libraries/shared/src/HifiSockAddr.cpp index 8010202424..07a7d25680 100644 --- a/libraries/shared/src/HifiSockAddr.cpp +++ b/libraries/shared/src/HifiSockAddr.cpp @@ -50,9 +50,9 @@ HifiSockAddr::HifiSockAddr(const sockaddr* sockaddr) { _address = QHostAddress(sockaddr); if (sockaddr->sa_family == AF_INET) { - _port = reinterpret_cast(sockaddr)->sin_port; + _port = ntohs(reinterpret_cast(sockaddr)->sin_port); } else { - _port = reinterpret_cast(sockaddr)->sin6_port; + _port = ntohs(reinterpret_cast(sockaddr)->sin6_port); } } diff --git a/libraries/shared/src/LimitedNodeList.h b/libraries/shared/src/LimitedNodeList.h index 544207d1b5..3688ddfdb4 100644 --- a/libraries/shared/src/LimitedNodeList.h +++ b/libraries/shared/src/LimitedNodeList.h @@ -34,6 +34,8 @@ #include "DomainHandler.h" #include "Node.h" +const int MAX_PACKET_SIZE = 1500; + const quint64 NODE_SILENCE_THRESHOLD_USECS = 2 * 1000 * 1000; extern const char SOLO_NODE_TYPES[2]; diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 3202909447..1740525ef1 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -12,6 +12,8 @@ #include #include +#include + #include "AccountManager.h" #include "Assignment.h" #include "HifiSockAddr.h" @@ -318,39 +320,54 @@ void NodeList::sendDomainServerCheckIn() { // send a STUN request to figure it out sendSTUNRequest(); } else if (!_domainHandler.getIP().isNull()) { - // construct the DS check in packet - QUuid packetUUID = (!_sessionUUID.isNull() ? _sessionUUID : _domainHandler.getAssignmentUUID()); - QByteArray domainServerPacket = byteArrayWithPopulatedHeader(PacketTypeDomainListRequest, packetUUID); - QDataStream packetStream(&domainServerPacket, QIODevice::Append); + DTLSClientSession* dtlsSession = _domainHandler.getDTLSSession(); - // pack our data to send to the domain-server - packetStream << _ownerType << _publicSockAddr - << HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort()) - << (quint8) _nodeTypesOfInterest.size(); - - // copy over the bytes for node types of interest, if required - foreach (NodeType_t nodeTypeOfInterest, _nodeTypesOfInterest) { - packetStream << nodeTypeOfInterest; - } - - writeDatagram(domainServerPacket, _domainHandler.getSockAddr(), QUuid()); - const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5; - static unsigned int numDomainCheckins = 0; - - // send a STUN request every Nth domain server check in so we update our public socket, if required - if (numDomainCheckins++ % NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST == 0) { - sendSTUNRequest(); - } - - if (_numNoReplyDomainCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { - // we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS - // so emit our signal that indicates that - emit limitOfSilentDomainCheckInsReached(); - } - - // increment the count of un-replied check-ins - _numNoReplyDomainCheckIns++; + if (dtlsSession) { + int handshakeReturn = gnutls_handshake(*dtlsSession->getGnuTLSSession()); + + gnutls_handshake_description_t inType = gnutls_handshake_get_last_in(*dtlsSession->getGnuTLSSession()); + gnutls_handshake_description_t outType = gnutls_handshake_get_last_out(*dtlsSession->getGnuTLSSession()); + qDebug() << "in" << gnutls_handshake_description_get_name(inType); + qDebug() << "out" << gnutls_handshake_description_get_name(outType); + + // make sure DTLS handshake with the domain-server is complete + qDebug() << "GnuTLS handshake return is" << handshakeReturn; + } else { + // construct the DS check in packet + QUuid packetUUID = (!_sessionUUID.isNull() ? _sessionUUID : _domainHandler.getAssignmentUUID()); + + QByteArray domainServerPacket = byteArrayWithPopulatedHeader(PacketTypeDomainListRequest, packetUUID); + QDataStream packetStream(&domainServerPacket, QIODevice::Append); + + // pack our data to send to the domain-server + packetStream << _ownerType << _publicSockAddr + << HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort()) + << (quint8) _nodeTypesOfInterest.size(); + + // copy over the bytes for node types of interest, if required + foreach (NodeType_t nodeTypeOfInterest, _nodeTypesOfInterest) { + packetStream << nodeTypeOfInterest; + } + + writeDatagram(domainServerPacket, _domainHandler.getSockAddr(), QUuid()); + const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5; + static unsigned int numDomainCheckins = 0; + + // send a STUN request every Nth domain server check in so we update our public socket, if required + if (numDomainCheckins++ % NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST == 0) { + sendSTUNRequest(); + } + + if (_numNoReplyDomainCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { + // we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS + // so emit our signal that indicates that + emit limitOfSilentDomainCheckInsReached(); + } + + // increment the count of un-replied check-ins + _numNoReplyDomainCheckIns++; + } } } diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 5ccfc80e35..625d7098ce 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -35,7 +35,7 @@ #include "LimitedNodeList.h" #include "Node.h" -const quint64 DOMAIN_SERVER_CHECK_IN_USECS = 1 * 1000000; +const quint64 DOMAIN_SERVER_CHECK_IN_MSECS = 1 * 1000; const int MAX_SILENT_DOMAIN_SERVER_CHECK_INS = 5; diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index d8d686c63b..e7898f3e2b 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -42,7 +42,6 @@ struct xColor { unsigned char blue; }; - static const float ZERO = 0.0f; static const float ONE = 1.0f; static const float ONE_HALF = 0.5f; @@ -66,8 +65,6 @@ static const quint64 USECS_PER_SECOND = USECS_PER_MSEC * MSECS_PER_SECOND; const int BITS_IN_BYTE = 8; -const int MAX_PACKET_SIZE = 1500; - quint64 usecTimestamp(const timeval *time); quint64 usecTimestampNow(); void usecTimestampNowForceClockSkew(int clockSkew); diff --git a/libraries/shared/src/ThreadedAssignment.cpp b/libraries/shared/src/ThreadedAssignment.cpp index fdf2d91c36..b31d282f64 100644 --- a/libraries/shared/src/ThreadedAssignment.cpp +++ b/libraries/shared/src/ThreadedAssignment.cpp @@ -41,7 +41,7 @@ void ThreadedAssignment::commonInit(const QString& targetName, NodeType_t nodeTy QTimer* domainServerTimer = new QTimer(this); connect(domainServerTimer, SIGNAL(timeout()), this, SLOT(checkInWithDomainServerOrExit())); - domainServerTimer->start(DOMAIN_SERVER_CHECK_IN_USECS / 1000); + domainServerTimer->start(DOMAIN_SERVER_CHECK_IN_MSECS); QTimer* silentNodeRemovalTimer = new QTimer(this); connect(silentNodeRemovalTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); From 62de84315e5226b805d6ae238a15c6e1aeb55fe2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 2 Apr 2014 17:56:04 -0700 Subject: [PATCH 18/86] detect handshake completion in DS and client --- domain-server/src/DomainServer.cpp | 22 +++++++++++++++++----- libraries/shared/src/DTLSClientSession.cpp | 10 +--------- libraries/shared/src/DTLSSession.cpp | 3 ++- libraries/shared/src/DTLSSession.h | 4 ++++ libraries/shared/src/NodeList.cpp | 22 ++++++++++++++-------- 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 5550c2741d..efecd5d322 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -628,9 +628,22 @@ void DomainServer::readAvailableDTLSDatagrams() { DTLSServerSession* existingSession = _dtlsSessions.value(senderHifiSockAddr); if (existingSession) { - // check if we have completed handshake with this user - int handshakeReturn = gnutls_handshake(*existingSession->getGnuTLSSession()); - qDebug() << "Handshake return for user is" << handshakeReturn; + if (!existingSession->completedHandshake()) { + // check if we have completed handshake with this user + int handshakeReturn = gnutls_handshake(*existingSession->getGnuTLSSession()); + + if (handshakeReturn == 0) { + existingSession->setCompletedHandshake(true); + } else if (gnutls_error_is_fatal(handshakeReturn)) { + // this was a fatal error handshaking, so remove this session + qDebug() << "Fatal error -" << gnutls_strerror(handshakeReturn) << "- during DTLS handshake with" + << senderHifiSockAddr; + _dtlsSessions.remove(senderHifiSockAddr); + } + } else { + // pull the data from this user off the stack and process it + dtlsSocket.readDatagram(peekDatagram.data(), peekDatagram.size()); + } } else { // first we verify the cookie // see http://gnutls.org/manual/html_node/DTLS-sessions.html for why this is required @@ -659,8 +672,7 @@ void DomainServer::readAvailableDTLSDatagrams() { gnutls_dtls_prestate_set(*gnutlsSession, &prestate); // handshake to begin the session - int handshakeReturn = gnutls_handshake(*gnutlsSession); - qDebug() << "initial handshake return" << handshakeReturn; + gnutls_handshake(*gnutlsSession); qDebug() << "Beginning DTLS session with node at" << senderHifiSockAddr; _dtlsSessions[senderHifiSockAddr] = newServerSession; diff --git a/libraries/shared/src/DTLSClientSession.cpp b/libraries/shared/src/DTLSClientSession.cpp index 109172487f..73daa4e03a 100644 --- a/libraries/shared/src/DTLSClientSession.cpp +++ b/libraries/shared/src/DTLSClientSession.cpp @@ -14,22 +14,14 @@ gnutls_certificate_credentials_t* DTLSClientSession::x509CACredentials() { if (!credentialsInitialized) { gnutls_certificate_allocate_credentials(&x509Credentials); - qDebug() << "processed" << gnutls_certificate_set_x509_trust_file(x509Credentials, "/Users/birarda/code/hifi/certs/root-ca.crt", GNUTLS_X509_FMT_PEM); } return &x509Credentials; } -int verifyX509Certificate(gnutls_session_t session) { - int certificateType = gnutls_certificate_type_get(session); - qDebug() << "Verifying a certificate of type" << certificateType; - - return 0; -} - DTLSClientSession::DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : DTLSSession(GNUTLS_CLIENT, dtlsSocket, destinationSocket) { gnutls_priority_set_direct(_gnutlsSession, "PERFORMANCE", NULL); - gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, x509CACredentials()); + gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, *x509CACredentials()); } \ No newline at end of file diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index 52c55bec23..9d30ab8148 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -77,7 +77,8 @@ ssize_t DTLSSession::socketPush(gnutls_transport_ptr_t ptr, const void* buffer, DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : _dtlsSocket(dtlsSocket), - _destinationSocket(destinationSocket) + _destinationSocket(destinationSocket), + _completedHandshake(false) { gnutls_init(&_gnutlsSession, end | GNUTLS_DATAGRAM | GNUTLS_NONBLOCK); diff --git a/libraries/shared/src/DTLSSession.h b/libraries/shared/src/DTLSSession.h index ce190e11c0..01e0e187e8 100644 --- a/libraries/shared/src/DTLSSession.h +++ b/libraries/shared/src/DTLSSession.h @@ -26,10 +26,14 @@ public: gnutls_session_t* getGnuTLSSession() { return &_gnutlsSession; } + bool completedHandshake() const { return _completedHandshake; } + void setCompletedHandshake(bool completedHandshake) { _completedHandshake = completedHandshake; } + protected: QUdpSocket& _dtlsSocket; gnutls_session_t _gnutlsSession; HifiSockAddr _destinationSocket; + bool _completedHandshake; }; #endif /* defined(__hifi__DTLSSession__) */ diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 1740525ef1..792215ea68 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -324,15 +324,21 @@ void NodeList::sendDomainServerCheckIn() { DTLSClientSession* dtlsSession = _domainHandler.getDTLSSession(); if (dtlsSession) { - int handshakeReturn = gnutls_handshake(*dtlsSession->getGnuTLSSession()); + if (dtlsSession->completedHandshake()) { + qDebug() << "we can send a DTLS check in!"; + } else { + int handshakeReturn = gnutls_handshake(*dtlsSession->getGnuTLSSession()); + if (handshakeReturn == 0) { + dtlsSession->setCompletedHandshake(true); + } else if (gnutls_error_is_fatal(handshakeReturn)) { + // this was a fatal error handshaking, so remove this session + qDebug() << "Fatal error -" << gnutls_strerror(handshakeReturn) + << "- during DTLS handshake with DS at" << _domainHandler.getHostname(); + + _domainHandler.clearConnectionInfo(); + } + } - gnutls_handshake_description_t inType = gnutls_handshake_get_last_in(*dtlsSession->getGnuTLSSession()); - gnutls_handshake_description_t outType = gnutls_handshake_get_last_out(*dtlsSession->getGnuTLSSession()); - qDebug() << "in" << gnutls_handshake_description_get_name(inType); - qDebug() << "out" << gnutls_handshake_description_get_name(outType); - - // make sure DTLS handshake with the domain-server is complete - qDebug() << "GnuTLS handshake return is" << handshakeReturn; } else { // construct the DS check in packet QUuid packetUUID = (!_sessionUUID.isNull() ? _sessionUUID : _domainHandler.getAssignmentUUID()); From 1c4d44ba4af3d3cf0fee3c4b8b71aa3dd67c1611 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 2 Apr 2014 18:08:44 -0700 Subject: [PATCH 19/86] attempt to complete handshake every 100ms instead of every 1s --- libraries/shared/src/DomainHandler.cpp | 46 ++++++++++++++++++++++++-- libraries/shared/src/DomainHandler.h | 5 ++- libraries/shared/src/NodeList.cpp | 19 ++--------- 3 files changed, 51 insertions(+), 19 deletions(-) diff --git a/libraries/shared/src/DomainHandler.cpp b/libraries/shared/src/DomainHandler.cpp index 6bc959be47..00278689a2 100644 --- a/libraries/shared/src/DomainHandler.cpp +++ b/libraries/shared/src/DomainHandler.cpp @@ -13,12 +13,14 @@ #include "DomainHandler.h" -DomainHandler::DomainHandler() : +DomainHandler::DomainHandler(QObject* parent) : + QObject(parent), _uuid(), _sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)), _assignmentUUID(), _isConnected(false), - _dtlsSession(NULL) + _dtlsSession(NULL), + _handshakeTimer(NULL) { } @@ -33,6 +35,12 @@ void DomainHandler::clearConnectionInfo() { delete _dtlsSession; _dtlsSession = NULL; + + if (_handshakeTimer) { + _handshakeTimer->stop(); + delete _handshakeTimer; + _handshakeTimer = NULL; + } } void DomainHandler::reset() { @@ -44,9 +52,21 @@ void DomainHandler::reset() { _dtlsSession = NULL; } +const unsigned int DTLS_HANDSHAKE_INTERVAL_MSECS = 100; + void DomainHandler::initializeDTLSSession() { if (!_dtlsSession) { _dtlsSession = new DTLSClientSession(NodeList::getInstance()->getDTLSSocket(), _sockAddr); + + // start a timer to complete the handshake process + _handshakeTimer = new QTimer(this); + connect(_handshakeTimer, &QTimer::timeout, this, &DomainHandler::completeDTLSHandshake); + + // start the handshake right now + completeDTLSHandshake(); + + // start the timer to finish off the handshake + _handshakeTimer->start(DTLS_HANDSHAKE_INTERVAL_MSECS); } } @@ -92,6 +112,28 @@ void DomainHandler::setHostname(const QString& hostname) { } } +void DomainHandler::completeDTLSHandshake() { + int handshakeReturn = gnutls_handshake(*_dtlsSession->getGnuTLSSession()); + + qDebug() << "handshake return is" << handshakeReturn; + + if (handshakeReturn == 0) { + // we've shaken hands, so we're good to go now + _dtlsSession->setCompletedHandshake(true); + + _handshakeTimer->stop(); + delete _handshakeTimer; + _handshakeTimer = NULL; + + } else if (gnutls_error_is_fatal(handshakeReturn)) { + // this was a fatal error handshaking, so remove this session + qDebug() << "Fatal error -" << gnutls_strerror(handshakeReturn) + << "- during DTLS handshake with DS at" << getHostname(); + + clearConnectionInfo(); + } +} + void DomainHandler::completedHostnameLookup(const QHostInfo& hostInfo) { for (int i = 0; i < hostInfo.addresses().size(); i++) { if (hostInfo.addresses()[i].protocol() == QAbstractSocket::IPv4Protocol) { diff --git a/libraries/shared/src/DomainHandler.h b/libraries/shared/src/DomainHandler.h index a867207190..f53cbd5689 100644 --- a/libraries/shared/src/DomainHandler.h +++ b/libraries/shared/src/DomainHandler.h @@ -10,6 +10,7 @@ #define __hifi__DomainHandler__ #include +#include #include #include #include @@ -24,7 +25,7 @@ const unsigned short DEFAULT_DOMAIN_SERVER_DTLS_PORT = 40103; class DomainHandler : public QObject { Q_OBJECT public: - DomainHandler(); + DomainHandler(QObject* parent = 0); ~DomainHandler(); void clearConnectionInfo(); @@ -54,6 +55,7 @@ public: void parseDTLSRequirementPacket(const QByteArray& dtlsRequirementPacket); private slots: + void completeDTLSHandshake(); void completedHostnameLookup(const QHostInfo& hostInfo); signals: void hostnameChanged(const QString& hostname); @@ -69,6 +71,7 @@ private: QUuid _assignmentUUID; bool _isConnected; DTLSClientSession* _dtlsSession; + QTimer* _handshakeTimer; }; #endif /* defined(__hifi__DomainHandler__) */ diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 792215ea68..50339947ef 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -53,6 +53,7 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned LimitedNodeList(socketListenPort, dtlsListenPort), _ownerType(newOwnerType), _nodeTypesOfInterest(), + _domainHandler(this), _numNoReplyDomainCheckIns(0), _assignmentServerSocket(), _publicSockAddr(), @@ -323,22 +324,8 @@ void NodeList::sendDomainServerCheckIn() { DTLSClientSession* dtlsSession = _domainHandler.getDTLSSession(); - if (dtlsSession) { - if (dtlsSession->completedHandshake()) { - qDebug() << "we can send a DTLS check in!"; - } else { - int handshakeReturn = gnutls_handshake(*dtlsSession->getGnuTLSSession()); - if (handshakeReturn == 0) { - dtlsSession->setCompletedHandshake(true); - } else if (gnutls_error_is_fatal(handshakeReturn)) { - // this was a fatal error handshaking, so remove this session - qDebug() << "Fatal error -" << gnutls_strerror(handshakeReturn) - << "- during DTLS handshake with DS at" << _domainHandler.getHostname(); - - _domainHandler.clearConnectionInfo(); - } - } - + if (dtlsSession && dtlsSession->completedHandshake()) { + qDebug() << "we can send a DTLS check in!"; } else { // construct the DS check in packet QUuid packetUUID = (!_sessionUUID.isNull() ? _sessionUUID : _domainHandler.getAssignmentUUID()); From 7b6ce7769055f22c38407ed7c4d95f480b861337 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 4 Apr 2014 09:20:40 -0700 Subject: [PATCH 20/86] add processing of DTLS datagrams to domain-server --- domain-server/src/DomainServer.cpp | 13 +++-- libraries/shared/src/DTLSSession.cpp | 6 +- libraries/shared/src/NodeList.cpp | 82 ++++++++++++++++------------ 3 files changed, 59 insertions(+), 42 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index efecd5d322..82f908fcf9 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -101,7 +101,7 @@ bool DomainServer::optionallySetupDTLS() { gnutls_key_generate(_cookieKey, GNUTLS_COOKIE_KEY_SIZE); _priorityCache = new gnutls_priority_t; - const char DTLS_PRIORITY_STRING[] = "PERFORMANCE:-VERS-TLS-ALL:+VERS-DTLS1.0:%SERVER_PRECEDENCE"; + const char DTLS_PRIORITY_STRING[] = "PERFORMANCE:-VERS-TLS-ALL:+VERS-DTLS1.2:%SERVER_PRECEDENCE"; gnutls_priority_init(_priorityCache, DTLS_PRIORITY_STRING, NULL); _isUsingDTLS = true; @@ -616,8 +616,6 @@ void DomainServer::readAvailableDTLSDatagrams() { static socklen_t sockAddrSize = sizeof(senderSockAddr); while (dtlsSocket.hasPendingDatagrams()) { - qDebug() << "Looking at a datagram"; - // check if we have an active DTLS session for this sender QByteArray peekDatagram(dtlsSocket.pendingDatagramSize(), 0); @@ -642,7 +640,14 @@ void DomainServer::readAvailableDTLSDatagrams() { } } else { // pull the data from this user off the stack and process it - dtlsSocket.readDatagram(peekDatagram.data(), peekDatagram.size()); + int receiveCode = gnutls_record_recv(*existingSession->getGnuTLSSession(), + peekDatagram.data(), peekDatagram.size()); + if (receiveCode > 0) { + processDatagram(peekDatagram, senderHifiSockAddr); + } else if (gnutls_error_is_fatal(receiveCode)) { + qDebug() << "Fatal error -" << gnutls_strerror(receiveCode) << "- during DTLS handshake with" + << senderHifiSockAddr; + } } } else { // first we verify the cookie diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index 9d30ab8148..07dadef54c 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -54,9 +54,8 @@ ssize_t DTLSSession::socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t if (pulledSockAddr == session->_destinationSocket) { // bytes received from the correct sender, return number of bytes received qDebug() << "Received" << bytesReceived << "on DTLS socket from" << pulledSockAddr; + qDebug() << QByteArray(reinterpret_cast(buffer), bytesReceived).toHex(); return bytesReceived; - } else { - qDebug() << pulledSockAddr << "is not" << session->_destinationSocket; } // we pulled a packet not matching this session, so output that @@ -71,6 +70,7 @@ ssize_t DTLSSession::socketPush(gnutls_transport_ptr_t ptr, const void* buffer, QUdpSocket& dtlsSocket = session->_dtlsSocket; qDebug() << "Pushing a message of size" << size << "to" << session->_destinationSocket; + qDebug() << QByteArray(reinterpret_cast(buffer), size).toHex(); return dtlsSocket.writeDatagram(reinterpret_cast(buffer), size, session->_destinationSocket.getAddress(), session->_destinationSocket.getPort()); } @@ -87,7 +87,7 @@ DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinat gnutls_dtls_set_mtu(_gnutlsSession, DTLS_MAX_MTU); const unsigned int DTLS_TOTAL_CONNECTION_TIMEOUT = 10 * DOMAIN_SERVER_CHECK_IN_MSECS; - gnutls_dtls_set_timeouts(_gnutlsSession, 0, DTLS_TOTAL_CONNECTION_TIMEOUT); + gnutls_dtls_set_timeouts(_gnutlsSession, 1, DTLS_TOTAL_CONNECTION_TIMEOUT); gnutls_transport_set_ptr(_gnutlsSession, this); gnutls_transport_set_push_function(_gnutlsSession, socketPush); diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 50339947ef..705de5afec 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -323,44 +323,56 @@ void NodeList::sendDomainServerCheckIn() { } else if (!_domainHandler.getIP().isNull()) { DTLSClientSession* dtlsSession = _domainHandler.getDTLSSession(); + bool isUsingDTLS = false; - if (dtlsSession && dtlsSession->completedHandshake()) { - qDebug() << "we can send a DTLS check in!"; - } else { - // construct the DS check in packet - QUuid packetUUID = (!_sessionUUID.isNull() ? _sessionUUID : _domainHandler.getAssignmentUUID()); - - QByteArray domainServerPacket = byteArrayWithPopulatedHeader(PacketTypeDomainListRequest, packetUUID); - QDataStream packetStream(&domainServerPacket, QIODevice::Append); - - // pack our data to send to the domain-server - packetStream << _ownerType << _publicSockAddr - << HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort()) - << (quint8) _nodeTypesOfInterest.size(); - - // copy over the bytes for node types of interest, if required - foreach (NodeType_t nodeTypeOfInterest, _nodeTypesOfInterest) { - packetStream << nodeTypeOfInterest; + if (dtlsSession) { + if (!dtlsSession->completedHandshake()) { + // if the handshake process is not complete then we can't check in, so return + return; + } else { + isUsingDTLS = true; } - + } + + // construct the DS check in packet + QUuid packetUUID = (!_sessionUUID.isNull() ? _sessionUUID : _domainHandler.getAssignmentUUID()); + + QByteArray domainServerPacket = byteArrayWithPopulatedHeader(PacketTypeDomainListRequest, packetUUID); + QDataStream packetStream(&domainServerPacket, QIODevice::Append); + + // pack our data to send to the domain-server + packetStream << _ownerType << _publicSockAddr + << HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort()) + << (quint8) _nodeTypesOfInterest.size(); + + // copy over the bytes for node types of interest, if required + foreach (NodeType_t nodeTypeOfInterest, _nodeTypesOfInterest) { + packetStream << nodeTypeOfInterest; + } + + if (!isUsingDTLS) { writeDatagram(domainServerPacket, _domainHandler.getSockAddr(), QUuid()); - const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5; - static unsigned int numDomainCheckins = 0; - - // send a STUN request every Nth domain server check in so we update our public socket, if required - if (numDomainCheckins++ % NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST == 0) { - sendSTUNRequest(); - } - - if (_numNoReplyDomainCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { - // we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS - // so emit our signal that indicates that - emit limitOfSilentDomainCheckInsReached(); - } - - // increment the count of un-replied check-ins - _numNoReplyDomainCheckIns++; - } + } else { + gnutls_record_send(*dtlsSession->getGnuTLSSession(), domainServerPacket.data(), domainServerPacket.size()); + } + + + const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5; + static unsigned int numDomainCheckins = 0; + + // send a STUN request every Nth domain server check in so we update our public socket, if required + if (numDomainCheckins++ % NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST == 0) { + sendSTUNRequest(); + } + + if (_numNoReplyDomainCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { + // we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS + // so emit our signal that indicates that + emit limitOfSilentDomainCheckInsReached(); + } + + // increment the count of un-replied check-ins + _numNoReplyDomainCheckIns++; } } From efd176f93ceaee2cda497253f6273c49f0d56592 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 4 Apr 2014 09:56:57 -0700 Subject: [PATCH 21/86] complete check in and heartbeat via DTLS --- domain-server/src/DomainServer.cpp | 31 ++++++++++++++++-------- libraries/shared/src/DTLSSession.cpp | 18 ++++++++++++-- libraries/shared/src/DTLSSession.h | 2 ++ libraries/shared/src/DomainHandler.cpp | 5 ++-- libraries/shared/src/DomainHandler.h | 3 ++- libraries/shared/src/LimitedNodeList.cpp | 2 +- libraries/shared/src/NodeList.cpp | 31 +++++++++++++++++++++--- libraries/shared/src/NodeList.h | 3 +++ 8 files changed, 76 insertions(+), 19 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 82f908fcf9..205661aae2 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -483,6 +483,9 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif LimitedNodeList* nodeList = LimitedNodeList::getInstance(); if (nodeInterestList.size() > 0) { + + DTLSServerSession* dtlsSession = _isUsingDTLS ? _dtlsSessions[senderSockAddr] : NULL; + // if the node has any interest types, send back those nodes as well foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) { @@ -516,7 +519,11 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif // we need to break here and start a new packet // so send the current one - nodeList->writeDatagram(broadcastPacket, node, senderSockAddr); + if (!dtlsSession) { + nodeList->writeDatagram(broadcastPacket, node, senderSockAddr); + } else { + dtlsSession->writeDatagram(broadcastPacket); + } // reset the broadcastPacket structure broadcastPacket.resize(numBroadcastPacketLeadBytes); @@ -527,10 +534,14 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif broadcastPacket.append(nodeByteArray); } } + + // always write the last broadcastPacket + if (!dtlsSession) { + nodeList->writeDatagram(broadcastPacket, node, senderSockAddr); + } else { + dtlsSession->writeDatagram(broadcastPacket); + } } - - // always write the last broadcastPacket - nodeList->writeDatagram(broadcastPacket, node, senderSockAddr); } void DomainServer::readAvailableDatagrams() { @@ -640,12 +651,12 @@ void DomainServer::readAvailableDTLSDatagrams() { } } else { // pull the data from this user off the stack and process it - int receiveCode = gnutls_record_recv(*existingSession->getGnuTLSSession(), - peekDatagram.data(), peekDatagram.size()); - if (receiveCode > 0) { - processDatagram(peekDatagram, senderHifiSockAddr); - } else if (gnutls_error_is_fatal(receiveCode)) { - qDebug() << "Fatal error -" << gnutls_strerror(receiveCode) << "- during DTLS handshake with" + int receivedBytes = gnutls_record_recv(*existingSession->getGnuTLSSession(), + peekDatagram.data(), peekDatagram.size()); + if (receivedBytes > 0) { + processDatagram(peekDatagram.left(receivedBytes), senderHifiSockAddr); + } else if (gnutls_error_is_fatal(receivedBytes)) { + qDebug() << "Fatal error -" << gnutls_strerror(receivedBytes) << "- during DTLS handshake with" << senderHifiSockAddr; } } diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index 07dadef54c..b8b3efddae 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -11,6 +11,8 @@ #include "NodeList.h" #include "DTLSSession.h" +#define DTLS_VERBOSE_DEBUG 0 + int DTLSSession::socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms) { DTLSSession* session = static_cast(ptr); QUdpSocket& dtlsSocket = session->_dtlsSocket; @@ -47,14 +49,19 @@ ssize_t DTLSSession::socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t pulledSockAddr.getAddressPointer(), pulledSockAddr.getPortPointer()); if (bytesReceived == -1) { // no data to pull, return -1 +#if DTLS_VERBOSE_DEBUG qDebug() << "Received no data on call to readDatagram"; +#endif return bytesReceived; } if (pulledSockAddr == session->_destinationSocket) { // bytes received from the correct sender, return number of bytes received + +#if DTLS_VERBOSE_DEBUG qDebug() << "Received" << bytesReceived << "on DTLS socket from" << pulledSockAddr; - qDebug() << QByteArray(reinterpret_cast(buffer), bytesReceived).toHex(); +#endif + return bytesReceived; } @@ -69,8 +76,10 @@ ssize_t DTLSSession::socketPush(gnutls_transport_ptr_t ptr, const void* buffer, DTLSSession* session = static_cast(ptr); QUdpSocket& dtlsSocket = session->_dtlsSocket; +#if DTLS_VERBOSE_DEBUG qDebug() << "Pushing a message of size" << size << "to" << session->_destinationSocket; - qDebug() << QByteArray(reinterpret_cast(buffer), size).toHex(); +#endif + return dtlsSocket.writeDatagram(reinterpret_cast(buffer), size, session->_destinationSocket.getAddress(), session->_destinationSocket.getPort()); } @@ -93,4 +102,9 @@ DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinat gnutls_transport_set_push_function(_gnutlsSession, socketPush); gnutls_transport_set_pull_function(_gnutlsSession, socketPull); gnutls_transport_set_pull_timeout_function(_gnutlsSession, socketPullTimeout); +} + +qint64 DTLSSession::writeDatagram(const QByteArray& datagram) { + // we don't need to put a hash in this packet, so just send it off + return gnutls_record_send(_gnutlsSession, datagram.data(), datagram.size()); } \ No newline at end of file diff --git a/libraries/shared/src/DTLSSession.h b/libraries/shared/src/DTLSSession.h index 01e0e187e8..a06ddc00ad 100644 --- a/libraries/shared/src/DTLSSession.h +++ b/libraries/shared/src/DTLSSession.h @@ -24,6 +24,8 @@ public: static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size); static ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size); + qint64 writeDatagram(const QByteArray& datagram); + gnutls_session_t* getGnuTLSSession() { return &_gnutlsSession; } bool completedHandshake() const { return _completedHandshake; } diff --git a/libraries/shared/src/DomainHandler.cpp b/libraries/shared/src/DomainHandler.cpp index 00278689a2..59b7f73e0d 100644 --- a/libraries/shared/src/DomainHandler.cpp +++ b/libraries/shared/src/DomainHandler.cpp @@ -115,8 +115,6 @@ void DomainHandler::setHostname(const QString& hostname) { void DomainHandler::completeDTLSHandshake() { int handshakeReturn = gnutls_handshake(*_dtlsSession->getGnuTLSSession()); - qDebug() << "handshake return is" << handshakeReturn; - if (handshakeReturn == 0) { // we've shaken hands, so we're good to go now _dtlsSession->setCompletedHandshake(true); @@ -125,6 +123,9 @@ void DomainHandler::completeDTLSHandshake() { delete _handshakeTimer; _handshakeTimer = NULL; + // emit a signal so NodeList can handle incoming DTLS packets + emit completedDTLSHandshake(); + } else if (gnutls_error_is_fatal(handshakeReturn)) { // this was a fatal error handshaking, so remove this session qDebug() << "Fatal error -" << gnutls_strerror(handshakeReturn) diff --git a/libraries/shared/src/DomainHandler.h b/libraries/shared/src/DomainHandler.h index f53cbd5689..b8351653f6 100644 --- a/libraries/shared/src/DomainHandler.h +++ b/libraries/shared/src/DomainHandler.h @@ -60,7 +60,8 @@ private slots: signals: void hostnameChanged(const QString& hostname); void connectedToDomain(const QString& hostname); - void initializedDTLSSession(); + void completedDTLSHandshake(); + private: void reset(); void initializeDTLSSession(); diff --git a/libraries/shared/src/LimitedNodeList.cpp b/libraries/shared/src/LimitedNodeList.cpp index c71f3c13c9..ca377e553c 100644 --- a/libraries/shared/src/LimitedNodeList.cpp +++ b/libraries/shared/src/LimitedNodeList.cpp @@ -173,7 +173,7 @@ bool LimitedNodeList::packetVersionAndHashMatch(const QByteArray& packet) { } qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr, - const QUuid& connectionSecret) { + const QUuid& connectionSecret) { QByteArray datagramCopy = datagram; if (!connectionSecret.isNull()) { diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 705de5afec..50fa0269ef 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -65,6 +65,9 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned // clear our NodeList when logout is requested connect(&AccountManager::getInstance(), &AccountManager::logoutComplete , this, &NodeList::reset); + + // perform a function when DTLS handshake is completed + connect(&_domainHandler, &DomainHandler::completedDTLSHandshake, this, &NodeList::completedDTLSHandshake); } qint64 NodeList::sendStatsToDomainServer(const QJsonObject& statsObject) { @@ -111,6 +114,28 @@ void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer& } } +void NodeList::completedDTLSHandshake() { + // at this point, we've got a DTLS socket + // make this NodeList the handler of DTLS packets + connect(_dtlsSocket, &QUdpSocket::readyRead, this, &NodeList::processAvailableDTLSDatagrams); +} + +void NodeList::processAvailableDTLSDatagrams() { + while (_dtlsSocket->hasPendingDatagrams()) { + QByteArray dtlsPacket(_dtlsSocket->pendingDatagramSize(), 0); + + // pull the data from this user off the stack and process it + int receivedBytes = gnutls_record_recv(*_domainHandler.getDTLSSession()->getGnuTLSSession(), + dtlsPacket.data(), dtlsPacket.size()); + if (receivedBytes > 0) { + // successful data receive, hand this off to processNodeData + processNodeData(_domainHandler.getSockAddr(), dtlsPacket.left(receivedBytes)); + } else if (gnutls_error_is_fatal(receivedBytes)) { + qDebug() << "Fatal error -" << gnutls_strerror(receivedBytes) << "- receiving DTLS packet from domain-server."; + } + } +} + void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet) { switch (packetTypeForPacket(packet)) { case PacketTypeDomainList: { @@ -342,8 +367,8 @@ void NodeList::sendDomainServerCheckIn() { // pack our data to send to the domain-server packetStream << _ownerType << _publicSockAddr - << HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort()) - << (quint8) _nodeTypesOfInterest.size(); + << HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort()) + << (quint8) _nodeTypesOfInterest.size(); // copy over the bytes for node types of interest, if required foreach (NodeType_t nodeTypeOfInterest, _nodeTypesOfInterest) { @@ -353,7 +378,7 @@ void NodeList::sendDomainServerCheckIn() { if (!isUsingDTLS) { writeDatagram(domainServerPacket, _domainHandler.getSockAddr(), QUuid()); } else { - gnutls_record_send(*dtlsSession->getGnuTLSSession(), domainServerPacket.data(), domainServerPacket.size()); + dtlsSession->writeDatagram(domainServerPacket); } diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 625d7098ce..c7598eb7d0 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -67,6 +67,7 @@ public: void resetNodeInterestSet() { _nodeTypesOfInterest.clear(); } void processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet); + int processDomainServerList(const QByteArray& packet); void setAssignmentServerSocket(const HifiSockAddr& serverSocket) { _assignmentServerSocket = serverSocket; } @@ -82,6 +83,8 @@ public slots: void reset(); void sendDomainServerCheckIn(); void pingInactiveNodes(); + void completedDTLSHandshake(); + void processAvailableDTLSDatagrams(); signals: void limitOfSilentDomainCheckInsReached(); private: From c8409046429d3cd65dc347f064344fcfcfac7c5d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 4 Apr 2014 10:44:15 -0700 Subject: [PATCH 22/86] output a message when handshake has completed with a client --- libraries/shared/src/DTLSSession.cpp | 5 +++++ libraries/shared/src/DTLSSession.h | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index b8b3efddae..8278ad93ed 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -104,6 +104,11 @@ DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinat gnutls_transport_set_pull_timeout_function(_gnutlsSession, socketPullTimeout); } +void DTLSSession::setCompletedHandshake(bool completedHandshake) { + _completedHandshake = completedHandshake; + qDebug() << "Completed DTLS handshake with" << _destinationSocket; +} + qint64 DTLSSession::writeDatagram(const QByteArray& datagram) { // we don't need to put a hash in this packet, so just send it off return gnutls_record_send(_gnutlsSession, datagram.data(), datagram.size()); diff --git a/libraries/shared/src/DTLSSession.h b/libraries/shared/src/DTLSSession.h index a06ddc00ad..e9b5267592 100644 --- a/libraries/shared/src/DTLSSession.h +++ b/libraries/shared/src/DTLSSession.h @@ -29,12 +29,11 @@ public: gnutls_session_t* getGnuTLSSession() { return &_gnutlsSession; } bool completedHandshake() const { return _completedHandshake; } - void setCompletedHandshake(bool completedHandshake) { _completedHandshake = completedHandshake; } - + void setCompletedHandshake(bool completedHandshake); protected: QUdpSocket& _dtlsSocket; - gnutls_session_t _gnutlsSession; HifiSockAddr _destinationSocket; + gnutls_session_t _gnutlsSession; bool _completedHandshake; }; From e2224e0f0c8e715b0b49168712f8f2a8bfe1c9f9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 4 Apr 2014 10:56:04 -0700 Subject: [PATCH 23/86] cleanup node silence timing and use for DTLS timeouts --- animation-server/src/AnimationServer.cpp | 2 +- domain-server/src/DomainServer.cpp | 2 +- interface/src/Application.cpp | 2 +- libraries/shared/src/DTLSSession.cpp | 5 +++-- libraries/shared/src/LimitedNodeList.cpp | 2 +- libraries/shared/src/LimitedNodeList.h | 2 +- libraries/shared/src/ThreadedAssignment.cpp | 2 +- 7 files changed, 9 insertions(+), 8 deletions(-) diff --git a/animation-server/src/AnimationServer.cpp b/animation-server/src/AnimationServer.cpp index e92169bcfa..61a3dc4aa9 100644 --- a/animation-server/src/AnimationServer.cpp +++ b/animation-server/src/AnimationServer.cpp @@ -801,7 +801,7 @@ AnimationServer::AnimationServer(int &argc, char **argv) : QTimer* silentNodeTimer = new QTimer(this); connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); - silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000); + silentNodeTimer->start(NODE_SILENCE_THRESHOLD_MSECS); connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), SLOT(readPendingDatagrams())); } diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 205661aae2..12df8a4ada 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -216,7 +216,7 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { QTimer* silentNodeTimer = new QTimer(this); connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); - silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000); + silentNodeTimer->start(NODE_SILENCE_THRESHOLD_MSECS); connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), SLOT(readAvailableDatagrams())); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4ffdf5b2b7..548b5ac702 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -274,7 +274,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : QTimer* silentNodeTimer = new QTimer(); connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); silentNodeTimer->moveToThread(_nodeThread); - silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000); + silentNodeTimer->start(NODE_SILENCE_THRESHOLD_MSECS); // send the identity packet for our avatar each second to our avatar mixer QTimer* identityPacketTimer = new QTimer(); diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index 8278ad93ed..9b009730b4 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -95,8 +95,9 @@ DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinat const unsigned int DTLS_MAX_MTU = 1452; gnutls_dtls_set_mtu(_gnutlsSession, DTLS_MAX_MTU); - const unsigned int DTLS_TOTAL_CONNECTION_TIMEOUT = 10 * DOMAIN_SERVER_CHECK_IN_MSECS; - gnutls_dtls_set_timeouts(_gnutlsSession, 1, DTLS_TOTAL_CONNECTION_TIMEOUT); + const unsigned int DTLS_HANDSHAKE_RETRANSMISSION_TIMEOUT = DOMAIN_SERVER_CHECK_IN_MSECS; + const unsigned int DTLS_TOTAL_CONNECTION_TIMEOUT = 2 * NODE_SILENCE_THRESHOLD_MSECS; + gnutls_dtls_set_timeouts(_gnutlsSession, DTLS_HANDSHAKE_RETRANSMISSION_TIMEOUT, DTLS_TOTAL_CONNECTION_TIMEOUT); gnutls_transport_set_ptr(_gnutlsSession, this); gnutls_transport_set_push_function(_gnutlsSession, socketPush); diff --git a/libraries/shared/src/LimitedNodeList.cpp b/libraries/shared/src/LimitedNodeList.cpp index ca377e553c..e9fdaa493c 100644 --- a/libraries/shared/src/LimitedNodeList.cpp +++ b/libraries/shared/src/LimitedNodeList.cpp @@ -426,7 +426,7 @@ void LimitedNodeList::removeSilentNodes() { node->getMutex().lock(); - if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > NODE_SILENCE_THRESHOLD_USECS) { + if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * 1000)) { // call our private method to kill this node (removes it and emits the right signal) nodeItem = killNodeAtHashIterator(nodeItem); } else { diff --git a/libraries/shared/src/LimitedNodeList.h b/libraries/shared/src/LimitedNodeList.h index 3688ddfdb4..adbc94e8d2 100644 --- a/libraries/shared/src/LimitedNodeList.h +++ b/libraries/shared/src/LimitedNodeList.h @@ -36,7 +36,7 @@ const int MAX_PACKET_SIZE = 1500; -const quint64 NODE_SILENCE_THRESHOLD_USECS = 2 * 1000 * 1000; +const quint64 NODE_SILENCE_THRESHOLD_MSECS = 2 * 1000; extern const char SOLO_NODE_TYPES[2]; diff --git a/libraries/shared/src/ThreadedAssignment.cpp b/libraries/shared/src/ThreadedAssignment.cpp index b31d282f64..82bea4e279 100644 --- a/libraries/shared/src/ThreadedAssignment.cpp +++ b/libraries/shared/src/ThreadedAssignment.cpp @@ -45,7 +45,7 @@ void ThreadedAssignment::commonInit(const QString& targetName, NodeType_t nodeTy QTimer* silentNodeRemovalTimer = new QTimer(this); connect(silentNodeRemovalTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); - silentNodeRemovalTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000); + silentNodeRemovalTimer->start(NODE_SILENCE_THRESHOLD_MSECS); if (shouldSendStats) { // send a stats packet every 1 second From 85933545cd44fe6119dacd9d9b06702e8e90d404 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 4 Apr 2014 10:59:58 -0700 Subject: [PATCH 24/86] add GnuTLS init to Application --- interface/src/Application.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 548b5ac702..4c2d28376f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -171,6 +171,9 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _resetRecentMaxPacketsSoon(true), _logger(new FileLogger(this)) { + // init GnuTLS for DTLS with domain-servers + gnutls_global_init(); + // read the ApplicationInfo.ini file for Name/Version/Domain information QSettings applicationInfo(Application::resourcesPath() + "info/ApplicationInfo.ini", QSettings::IniFormat); From fd8e32190e772341c85a756b4b157bb14ea24c4e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 4 Apr 2014 11:08:50 -0700 Subject: [PATCH 25/86] perform cleanup of GnuTLS structures across targets --- assignment-client/src/AssignmentClient.cpp | 4 ++++ assignment-client/src/AssignmentClient.h | 1 + domain-server/src/DomainServer.cpp | 14 +++++++++++++ domain-server/src/DomainServer.h | 1 + interface/src/Application.cpp | 2 ++ libraries/shared/src/DTLSClientSession.cpp | 23 ++++++++++------------ libraries/shared/src/DTLSClientSession.h | 5 +++-- 7 files changed, 35 insertions(+), 15 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 046f362e1e..c370c78132 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -109,6 +109,10 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : this, &AssignmentClient::handleAuthenticationRequest); } +AssignmentClient::~AssignmentClient() { + gnutls_global_deinit(); +} + void AssignmentClient::sendAssignmentRequest() { if (!_currentAssignment) { NodeList::getInstance()->sendAssignment(_requestAssignment); diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index c267c6238b..939d06b14f 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -17,6 +17,7 @@ class AssignmentClient : public QCoreApplication { Q_OBJECT public: AssignmentClient(int &argc, char **argv); + ~AssignmentClient(); private slots: void sendAssignmentRequest(); void readPendingDatagrams(); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 12df8a4ada..a40bb2fa37 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -78,6 +78,20 @@ DomainServer::DomainServer(int argc, char* argv[]) : } } +DomainServer::~DomainServer() { + if (_x509Credentials) { + gnutls_certificate_free_credentials(*_x509Credentials); + gnutls_priority_deinit(*_priorityCache); + gnutls_dh_params_deinit(*_dhParams); + + delete _x509Credentials; + delete _priorityCache; + delete _dhParams; + delete _cookieKey; + } + gnutls_global_deinit(); +} + bool DomainServer::optionallySetupDTLS() { if (readX509KeyAndCertificate()) { if (_x509Credentials) { diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 6bca67df0d..78e48f1468 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -31,6 +31,7 @@ class DomainServer : public QCoreApplication, public HTTPRequestHandler { Q_OBJECT public: DomainServer(int argc, char* argv[]); + ~DomainServer(); bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4c2d28376f..255712b5b6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -393,6 +393,8 @@ Application::~Application() { delete _glWidget; AccountManager::getInstance().destroy(); + + gnutls_global_deinit(); } void Application::restoreSizeAndPosition() { diff --git a/libraries/shared/src/DTLSClientSession.cpp b/libraries/shared/src/DTLSClientSession.cpp index 73daa4e03a..58ca99f1a8 100644 --- a/libraries/shared/src/DTLSClientSession.cpp +++ b/libraries/shared/src/DTLSClientSession.cpp @@ -8,20 +8,17 @@ #include "DTLSClientSession.h" -gnutls_certificate_credentials_t* DTLSClientSession::x509CACredentials() { - static gnutls_certificate_credentials_t x509Credentials; - static bool credentialsInitialized = false; - - if (!credentialsInitialized) { - gnutls_certificate_allocate_credentials(&x509Credentials); - } - - return &x509Credentials; -} - DTLSClientSession::DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : DTLSSession(GNUTLS_CLIENT, dtlsSocket, destinationSocket) { + // _x509 as a member variable and not global/static assumes a single DTLSClientSession per client + gnutls_certificate_allocate_credentials(&_x509Credentials); + gnutls_priority_set_direct(_gnutlsSession, "PERFORMANCE", NULL); - gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, *x509CACredentials()); -} \ No newline at end of file + gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, _x509Credentials); +} + +DTLSClientSession::~DTLSClientSession() { + gnutls_certificate_free_credentials(_x509Credentials); +} + diff --git a/libraries/shared/src/DTLSClientSession.h b/libraries/shared/src/DTLSClientSession.h index a81daf6d74..325a162f61 100644 --- a/libraries/shared/src/DTLSClientSession.h +++ b/libraries/shared/src/DTLSClientSession.h @@ -14,8 +14,9 @@ class DTLSClientSession : public DTLSSession { public: DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); - - static gnutls_certificate_credentials_t* x509CACredentials(); + ~DTLSClientSession(); +private: + gnutls_certificate_credentials_t _x509Credentials; }; #endif /* defined(__hifi__DTLSClientSession__) */ From b40dd6a31a49a53e6065f161aa61189a8b206206 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 4 Apr 2014 11:17:50 -0700 Subject: [PATCH 26/86] say bye and de-init DTLS session from DomainServer --- domain-server/src/DomainServer.cpp | 9 +++++++++ libraries/shared/src/DTLSSession.cpp | 5 +++++ libraries/shared/src/DTLSSession.h | 1 + 3 files changed, 15 insertions(+) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index a40bb2fa37..a66c46fc09 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1001,6 +1001,7 @@ void DomainServer::nodeAdded(SharedNodePointer node) { void DomainServer::nodeKilled(SharedNodePointer node) { DomainServerNodeData* nodeData = reinterpret_cast(node->getLinkedData()); + if (nodeData) { // if this node's UUID matches a static assignment we need to throw it back in the assignment queue if (!nodeData->getStaticAssignmentUUID().isNull()) { @@ -1018,6 +1019,14 @@ void DomainServer::nodeKilled(SharedNodePointer node) { reinterpret_cast(otherNode->getLinkedData())->getSessionSecretHash().remove(node->getUUID()); } } + + if (_isUsingDTLS) { + // check if we need to remove a DTLS session from our in-memory hash + DTLSServerSession* existingSession = _dtlsSessions.take(nodeData->getSendingSockAddr()); + if (existingSession) { + delete existingSession; + } + } } } diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index 9b009730b4..44829c424e 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -105,6 +105,11 @@ DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinat gnutls_transport_set_pull_timeout_function(_gnutlsSession, socketPullTimeout); } +DTLSSession::~DTLSSession() { + gnutls_bye(_gnutlsSession, GNUTLS_SHUT_WR); + gnutls_deinit(_gnutlsSession); +} + void DTLSSession::setCompletedHandshake(bool completedHandshake) { _completedHandshake = completedHandshake; qDebug() << "Completed DTLS handshake with" << _destinationSocket; diff --git a/libraries/shared/src/DTLSSession.h b/libraries/shared/src/DTLSSession.h index e9b5267592..395809c6c6 100644 --- a/libraries/shared/src/DTLSSession.h +++ b/libraries/shared/src/DTLSSession.h @@ -19,6 +19,7 @@ class DTLSSession : public QObject { Q_OBJECT public: DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); + ~DTLSSession(); static int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms); static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size); From c015fdd212eb49a3a9508450708694de155de388 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 4 Apr 2014 11:42:14 -0700 Subject: [PATCH 27/86] leverage a DummyDTLSSession to not require cleanup of DTLSSession for cookies --- domain-server/src/DomainServer.cpp | 5 +++- libraries/shared/src/DTLSClientSession.cpp | 23 +++++++++------- libraries/shared/src/DTLSClientSession.h | 5 ++-- libraries/shared/src/DTLSSession.cpp | 21 +++------------ libraries/shared/src/DTLSSession.h | 6 ++--- libraries/shared/src/DomainHandler.cpp | 6 ++--- libraries/shared/src/DummyDTLSSession.cpp | 28 +++++++++++++++++++ libraries/shared/src/DummyDTLSSession.h | 31 ++++++++++++++++++++++ libraries/shared/src/LimitedNodeList.cpp | 2 +- libraries/shared/src/NodeList.cpp | 2 ++ 10 files changed, 89 insertions(+), 40 deletions(-) create mode 100644 libraries/shared/src/DummyDTLSSession.cpp create mode 100644 libraries/shared/src/DummyDTLSSession.h diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index a66c46fc09..5d99a755c1 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -23,6 +23,7 @@ #include #include "DomainServerNodeData.h" +#include "DummyDTLSSession.h" #include "DomainServer.h" @@ -651,6 +652,7 @@ void DomainServer::readAvailableDTLSDatagrams() { DTLSServerSession* existingSession = _dtlsSessions.value(senderHifiSockAddr); if (existingSession) { + qDebug() << "There is an existing session for" << senderHifiSockAddr; if (!existingSession->completedHandshake()) { // check if we have completed handshake with this user int handshakeReturn = gnutls_handshake(*existingSession->getGnuTLSSession()); @@ -685,7 +687,8 @@ void DomainServer::readAvailableDTLSDatagrams() { if (cookieValid < 0) { // the cookie sent by the client was not valid // send a valid one - DTLSServerSession tempServerSession(LimitedNodeList::getInstance()->getDTLSSocket(), senderHifiSockAddr); + DummyDTLSSession tempServerSession(LimitedNodeList::getInstance()->getDTLSSocket(), senderHifiSockAddr); + qDebug() << "sending back a fresh cookie!"; gnutls_dtls_cookie_send(_cookieKey, &senderSockAddr, sizeof(senderSockAddr), &prestate, &tempServerSession, DTLSSession::socketPush); diff --git a/libraries/shared/src/DTLSClientSession.cpp b/libraries/shared/src/DTLSClientSession.cpp index 58ca99f1a8..73daa4e03a 100644 --- a/libraries/shared/src/DTLSClientSession.cpp +++ b/libraries/shared/src/DTLSClientSession.cpp @@ -8,17 +8,20 @@ #include "DTLSClientSession.h" +gnutls_certificate_credentials_t* DTLSClientSession::x509CACredentials() { + static gnutls_certificate_credentials_t x509Credentials; + static bool credentialsInitialized = false; + + if (!credentialsInitialized) { + gnutls_certificate_allocate_credentials(&x509Credentials); + } + + return &x509Credentials; +} + DTLSClientSession::DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : DTLSSession(GNUTLS_CLIENT, dtlsSocket, destinationSocket) { - // _x509 as a member variable and not global/static assumes a single DTLSClientSession per client - gnutls_certificate_allocate_credentials(&_x509Credentials); - gnutls_priority_set_direct(_gnutlsSession, "PERFORMANCE", NULL); - gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, _x509Credentials); -} - -DTLSClientSession::~DTLSClientSession() { - gnutls_certificate_free_credentials(_x509Credentials); -} - + gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, *x509CACredentials()); +} \ No newline at end of file diff --git a/libraries/shared/src/DTLSClientSession.h b/libraries/shared/src/DTLSClientSession.h index 325a162f61..a81daf6d74 100644 --- a/libraries/shared/src/DTLSClientSession.h +++ b/libraries/shared/src/DTLSClientSession.h @@ -14,9 +14,8 @@ class DTLSClientSession : public DTLSSession { public: DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); - ~DTLSClientSession(); -private: - gnutls_certificate_credentials_t _x509Credentials; + + static gnutls_certificate_credentials_t* x509CACredentials(); }; #endif /* defined(__hifi__DTLSClientSession__) */ diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index 44829c424e..c5f4ade182 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -11,8 +11,6 @@ #include "NodeList.h" #include "DTLSSession.h" -#define DTLS_VERBOSE_DEBUG 0 - int DTLSSession::socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms) { DTLSSession* session = static_cast(ptr); QUdpSocket& dtlsSocket = session->_dtlsSocket; @@ -72,21 +70,8 @@ ssize_t DTLSSession::socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t return -1; } -ssize_t DTLSSession::socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size) { - DTLSSession* session = static_cast(ptr); - QUdpSocket& dtlsSocket = session->_dtlsSocket; - -#if DTLS_VERBOSE_DEBUG - qDebug() << "Pushing a message of size" << size << "to" << session->_destinationSocket; -#endif - - return dtlsSocket.writeDatagram(reinterpret_cast(buffer), size, - session->_destinationSocket.getAddress(), session->_destinationSocket.getPort()); -} - DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : - _dtlsSocket(dtlsSocket), - _destinationSocket(destinationSocket), + DummyDTLSSession(dtlsSocket, destinationSocket), _completedHandshake(false) { gnutls_init(&_gnutlsSession, end | GNUTLS_DATAGRAM | GNUTLS_NONBLOCK); @@ -100,13 +85,13 @@ DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinat gnutls_dtls_set_timeouts(_gnutlsSession, DTLS_HANDSHAKE_RETRANSMISSION_TIMEOUT, DTLS_TOTAL_CONNECTION_TIMEOUT); gnutls_transport_set_ptr(_gnutlsSession, this); - gnutls_transport_set_push_function(_gnutlsSession, socketPush); + gnutls_transport_set_push_function(_gnutlsSession, DummyDTLSSession::socketPush); gnutls_transport_set_pull_function(_gnutlsSession, socketPull); gnutls_transport_set_pull_timeout_function(_gnutlsSession, socketPullTimeout); } DTLSSession::~DTLSSession() { - gnutls_bye(_gnutlsSession, GNUTLS_SHUT_WR); + qDebug() << "cleaning up current session"; gnutls_deinit(_gnutlsSession); } diff --git a/libraries/shared/src/DTLSSession.h b/libraries/shared/src/DTLSSession.h index 395809c6c6..6b5f5df5e3 100644 --- a/libraries/shared/src/DTLSSession.h +++ b/libraries/shared/src/DTLSSession.h @@ -13,9 +13,10 @@ #include +#include "DummyDTLSSession.h" #include "HifiSockAddr.h" -class DTLSSession : public QObject { +class DTLSSession : public DummyDTLSSession { Q_OBJECT public: DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); @@ -23,7 +24,6 @@ public: static int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms); static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size); - static ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size); qint64 writeDatagram(const QByteArray& datagram); @@ -32,8 +32,6 @@ public: bool completedHandshake() const { return _completedHandshake; } void setCompletedHandshake(bool completedHandshake); protected: - QUdpSocket& _dtlsSocket; - HifiSockAddr _destinationSocket; gnutls_session_t _gnutlsSession; bool _completedHandshake; }; diff --git a/libraries/shared/src/DomainHandler.cpp b/libraries/shared/src/DomainHandler.cpp index 59b7f73e0d..e1aedc4d11 100644 --- a/libraries/shared/src/DomainHandler.cpp +++ b/libraries/shared/src/DomainHandler.cpp @@ -33,14 +33,14 @@ void DomainHandler::clearConnectionInfo() { _uuid = QUuid(); _isConnected = false; - delete _dtlsSession; - _dtlsSession = NULL; - if (_handshakeTimer) { _handshakeTimer->stop(); delete _handshakeTimer; _handshakeTimer = NULL; } + + delete _dtlsSession; + _dtlsSession = NULL; } void DomainHandler::reset() { diff --git a/libraries/shared/src/DummyDTLSSession.cpp b/libraries/shared/src/DummyDTLSSession.cpp new file mode 100644 index 0000000000..df7e82274c --- /dev/null +++ b/libraries/shared/src/DummyDTLSSession.cpp @@ -0,0 +1,28 @@ +// +// DummyDTLSSession.cpp +// hifi +// +// Created by Stephen Birarda on 2014-04-04. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// + +#include "DummyDTLSSession.h" + +ssize_t DummyDTLSSession::socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size) { + DummyDTLSSession* session = static_cast(ptr); + QUdpSocket& dtlsSocket = session->_dtlsSocket; + +#if DTLS_VERBOSE_DEBUG + qDebug() << "Pushing a message of size" << size << "to" << session->_destinationSocket; +#endif + + return dtlsSocket.writeDatagram(reinterpret_cast(buffer), size, + session->_destinationSocket.getAddress(), session->_destinationSocket.getPort()); +} + +DummyDTLSSession::DummyDTLSSession(QUdpSocket& dtlsSocket, const HifiSockAddr& destinationSocket) : + _dtlsSocket(dtlsSocket), + _destinationSocket(destinationSocket) +{ + +} \ No newline at end of file diff --git a/libraries/shared/src/DummyDTLSSession.h b/libraries/shared/src/DummyDTLSSession.h new file mode 100644 index 0000000000..6d4a54b4ca --- /dev/null +++ b/libraries/shared/src/DummyDTLSSession.h @@ -0,0 +1,31 @@ +// +// DummyDTLSSession.h +// hifi +// +// Created by Stephen Birarda on 2014-04-04. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__DummyDTLSSession__ +#define __hifi__DummyDTLSSession__ + +#include + +#include + +#include "HifiSockAddr.h" + +#define DTLS_VERBOSE_DEBUG 1 + +class DummyDTLSSession : public QObject { + Q_OBJECT +public: + DummyDTLSSession(QUdpSocket& dtlsSocket, const HifiSockAddr& destinationSocket); + + static ssize_t socketPush(gnutls_transport_ptr_t ptr, const void* buffer, size_t size); +protected: + QUdpSocket& _dtlsSocket; + HifiSockAddr _destinationSocket; +}; + +#endif /* defined(__hifi__DummyDTLSSession__) */ diff --git a/libraries/shared/src/LimitedNodeList.cpp b/libraries/shared/src/LimitedNodeList.cpp index e9fdaa493c..f6e6d282d9 100644 --- a/libraries/shared/src/LimitedNodeList.cpp +++ b/libraries/shared/src/LimitedNodeList.cpp @@ -426,7 +426,7 @@ void LimitedNodeList::removeSilentNodes() { node->getMutex().lock(); - if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * 1000)) { + if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * 1)) { // call our private method to kill this node (removes it and emits the right signal) nodeItem = killNodeAtHashIterator(nodeItem); } else { diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 50fa0269ef..92eb186c96 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -132,6 +132,8 @@ void NodeList::processAvailableDTLSDatagrams() { processNodeData(_domainHandler.getSockAddr(), dtlsPacket.left(receivedBytes)); } else if (gnutls_error_is_fatal(receivedBytes)) { qDebug() << "Fatal error -" << gnutls_strerror(receivedBytes) << "- receiving DTLS packet from domain-server."; + } else { + qDebug() << "non fatal receive" << receivedBytes; } } } From 45d796e8f3dbf91dc94c6abc82a577038b62b950 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 4 Apr 2014 15:56:02 -0700 Subject: [PATCH 28/86] allow re-handshake in NodeList after domain refresh --- domain-server/src/DomainServer.cpp | 1 - libraries/shared/src/DomainHandler.h | 1 + libraries/shared/src/DummyDTLSSession.h | 2 +- libraries/shared/src/LimitedNodeList.cpp | 2 +- libraries/shared/src/NodeList.cpp | 3 +++ 5 files changed, 6 insertions(+), 3 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 5d99a755c1..60c5cf1d0e 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -652,7 +652,6 @@ void DomainServer::readAvailableDTLSDatagrams() { DTLSServerSession* existingSession = _dtlsSessions.value(senderHifiSockAddr); if (existingSession) { - qDebug() << "There is an existing session for" << senderHifiSockAddr; if (!existingSession->completedHandshake()) { // check if we have completed handshake with this user int handshakeReturn = gnutls_handshake(*existingSession->getGnuTLSSession()); diff --git a/libraries/shared/src/DomainHandler.h b/libraries/shared/src/DomainHandler.h index b8351653f6..c34321cf87 100644 --- a/libraries/shared/src/DomainHandler.h +++ b/libraries/shared/src/DomainHandler.h @@ -61,6 +61,7 @@ signals: void hostnameChanged(const QString& hostname); void connectedToDomain(const QString& hostname); void completedDTLSHandshake(); + void DTLSConnectionLost(); private: void reset(); diff --git a/libraries/shared/src/DummyDTLSSession.h b/libraries/shared/src/DummyDTLSSession.h index 6d4a54b4ca..394bb82ae5 100644 --- a/libraries/shared/src/DummyDTLSSession.h +++ b/libraries/shared/src/DummyDTLSSession.h @@ -15,7 +15,7 @@ #include "HifiSockAddr.h" -#define DTLS_VERBOSE_DEBUG 1 +#define DTLS_VERBOSE_DEBUG 0 class DummyDTLSSession : public QObject { Q_OBJECT diff --git a/libraries/shared/src/LimitedNodeList.cpp b/libraries/shared/src/LimitedNodeList.cpp index f6e6d282d9..e9fdaa493c 100644 --- a/libraries/shared/src/LimitedNodeList.cpp +++ b/libraries/shared/src/LimitedNodeList.cpp @@ -426,7 +426,7 @@ void LimitedNodeList::removeSilentNodes() { node->getMutex().lock(); - if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * 1)) { + if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * 1000)) { // call our private method to kill this node (removes it and emits the right signal) nodeItem = killNodeAtHashIterator(nodeItem); } else { diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 92eb186c96..50fd3d1cbc 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -196,6 +196,9 @@ void NodeList::reset() { // clear the domain connection information _domainHandler.clearConnectionInfo(); + + // also disconnect from the DTLS socket readyRead() so it can handle handshaking + disconnect(_dtlsSocket, 0, this, 0); } void NodeList::addNodeTypeToInterestSet(NodeType_t nodeTypeToAdd) { From 69504b0a9df5ecef878db505ec84d25863cda46d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 7 Apr 2014 09:47:51 -0700 Subject: [PATCH 29/86] proper cleanup of CA credentials on DTLSClientSession side --- assignment-client/src/AssignmentClient.cpp | 4 ++-- interface/src/Application.cpp | 4 ++-- libraries/shared/src/DTLSClientSession.cpp | 20 +++++++++++++------- libraries/shared/src/DTLSClientSession.h | 6 +++++- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index c370c78132..222cb0ce9a 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -33,7 +33,7 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : QCoreApplication(argc, argv), _currentAssignment() { - gnutls_global_init(); + DTLSClientSession::globalInit(); setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); @@ -110,7 +110,7 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : } AssignmentClient::~AssignmentClient() { - gnutls_global_deinit(); + DTLSClientSession::globalDeinit(); } void AssignmentClient::sendAssignmentRequest() { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b3bb085cdc..cfe920bf40 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -167,7 +167,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _logger(new FileLogger(this)) { // init GnuTLS for DTLS with domain-servers - gnutls_global_init(); + DTLSClientSession::globalInit(); // read the ApplicationInfo.ini file for Name/Version/Domain information QSettings applicationInfo(Application::resourcesPath() + "info/ApplicationInfo.ini", QSettings::IniFormat); @@ -396,7 +396,7 @@ Application::~Application() { AccountManager::getInstance().destroy(); - gnutls_global_deinit(); + DTLSClientSession::globalDeinit(); } void Application::restoreSizeAndPosition() { diff --git a/libraries/shared/src/DTLSClientSession.cpp b/libraries/shared/src/DTLSClientSession.cpp index 73daa4e03a..5762038a20 100644 --- a/libraries/shared/src/DTLSClientSession.cpp +++ b/libraries/shared/src/DTLSClientSession.cpp @@ -8,20 +8,26 @@ #include "DTLSClientSession.h" -gnutls_certificate_credentials_t* DTLSClientSession::x509CACredentials() { - static gnutls_certificate_credentials_t x509Credentials; - static bool credentialsInitialized = false; +gnutls_certificate_credentials_t DTLSClientSession::_x509CACredentials; + +void DTLSClientSession::globalInit() { + static bool initialized = false; - if (!credentialsInitialized) { - gnutls_certificate_allocate_credentials(&x509Credentials); + if (!initialized) { + gnutls_global_init(); + gnutls_certificate_allocate_credentials(&_x509CACredentials); } +} + +void DTLSClientSession::globalDeinit() { + gnutls_certificate_free_credentials(_x509CACredentials); - return &x509Credentials; + gnutls_global_deinit(); } DTLSClientSession::DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : DTLSSession(GNUTLS_CLIENT, dtlsSocket, destinationSocket) { gnutls_priority_set_direct(_gnutlsSession, "PERFORMANCE", NULL); - gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, *x509CACredentials()); + gnutls_credentials_set(_gnutlsSession, GNUTLS_CRD_CERTIFICATE, _x509CACredentials); } \ No newline at end of file diff --git a/libraries/shared/src/DTLSClientSession.h b/libraries/shared/src/DTLSClientSession.h index a81daf6d74..ad5b0cd55b 100644 --- a/libraries/shared/src/DTLSClientSession.h +++ b/libraries/shared/src/DTLSClientSession.h @@ -15,7 +15,11 @@ class DTLSClientSession : public DTLSSession { public: DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); - static gnutls_certificate_credentials_t* x509CACredentials(); + static void globalInit(); + static void globalDeinit(); + + static gnutls_certificate_credentials_t _x509CACredentials; + static bool _wasGloballyInitialized; }; #endif /* defined(__hifi__DTLSClientSession__) */ From a6641aa95b5d1edfc2b5c862730e8d6cb347fb37 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 7 Apr 2014 10:48:58 -0700 Subject: [PATCH 30/86] respect the DTLS MTU for domain server list sending --- domain-server/src/DomainServer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 60c5cf1d0e..2f4179e56b 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -37,7 +37,8 @@ DomainServer::DomainServer(int argc, char* argv[]) : _isUsingDTLS(false), _x509Credentials(NULL), _dhParams(NULL), - _priorityCache(NULL) + _priorityCache(NULL), + _dtlsSessions() { gnutls_global_init(); @@ -500,6 +501,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif if (nodeInterestList.size() > 0) { DTLSServerSession* dtlsSession = _isUsingDTLS ? _dtlsSessions[senderSockAddr] : NULL; + unsigned int dataMTU = dtlsSession ? gnutls_dtls_get_data_mtu(*dtlsSession->getGnuTLSSession()) : MAX_PACKET_SIZE; // if the node has any interest types, send back those nodes as well foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) { @@ -530,7 +532,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif nodeDataStream << secretUUID; - if (broadcastPacket.size() + nodeByteArray.size() > MAX_PACKET_SIZE) { + if (broadcastPacket.size() + nodeByteArray.size() > dataMTU) { // we need to break here and start a new packet // so send the current one From 0f92e02da798f0ba482b6ebee839d4c73f7c3143 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 7 Apr 2014 11:19:06 -0700 Subject: [PATCH 31/86] add the hifi root CA trusted cert to source --- libraries/shared/src/DTLSClientSession.cpp | 2 ++ libraries/shared/src/DTLSSession.cpp | 37 ++++++++++++++++++++++ libraries/shared/src/DTLSSession.h | 2 ++ 3 files changed, 41 insertions(+) diff --git a/libraries/shared/src/DTLSClientSession.cpp b/libraries/shared/src/DTLSClientSession.cpp index 5762038a20..40b2b87b66 100644 --- a/libraries/shared/src/DTLSClientSession.cpp +++ b/libraries/shared/src/DTLSClientSession.cpp @@ -16,6 +16,8 @@ void DTLSClientSession::globalInit() { if (!initialized) { gnutls_global_init(); gnutls_certificate_allocate_credentials(&_x509CACredentials); + int certsProcessed = gnutls_certificate_set_x509_trust_mem(_x509CACredentials, DTLSSession::highFidelityCADatum(), GNUTLS_X509_FMT_PEM); + qDebug() << "There were" << certsProcessed; } } diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index c5f4ade182..f76119fd1f 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -70,6 +70,43 @@ ssize_t DTLSSession::socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t return -1; } +gnutls_datum_t* DTLSSession::highFidelityCADatum() { + static gnutls_datum_t hifiCADatum; + static bool datumInitialized = false; + + static unsigned char HIGHFIDELITY_ROOT_CA_CERT[] = + "-----BEGIN CERTIFICATE-----" + "MIID6TCCA1KgAwIBAgIJANlfRkRD9A8bMA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD\n" + "VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5j\n" + "aXNjbzEbMBkGA1UEChMSSGlnaCBGaWRlbGl0eSwgSW5jMRMwEQYDVQQLEwpPcGVy\n" + "YXRpb25zMRgwFgYDVQQDEw9oaWdoZmlkZWxpdHkuaW8xIjAgBgkqhkiG9w0BCQEW\n" + "E29wc0BoaWdoZmlkZWxpdHkuaW8wHhcNMTQwMzI4MjIzMzM1WhcNMjQwMzI1MjIz\n" + "MzM1WjCBqjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNV\n" + "BAcTDVNhbiBGcmFuY2lzY28xGzAZBgNVBAoTEkhpZ2ggRmlkZWxpdHksIEluYzET\n" + "MBEGA1UECxMKT3BlcmF0aW9uczEYMBYGA1UEAxMPaGlnaGZpZGVsaXR5LmlvMSIw\n" + "IAYJKoZIhvcNAQkBFhNvcHNAaGlnaGZpZGVsaXR5LmlvMIGfMA0GCSqGSIb3DQEB\n" + "AQUAA4GNADCBiQKBgQDyo1euYiPPEdnvDZnIjWrrP230qUKMSj8SWoIkbTJF2hE8\n" + "2eP3YOgbgSGBzZ8EJBxIOuNmj9g9Eg6691hIKFqy5W0BXO38P04Gg+pVBvpHFGBi\n" + "wpqGbfsjaUDuYmBeJRcMO0XYkLCRQG+lAQNHoFDdItWAJfC3FwtP3OCDnz8cNwID\n" + "AQABo4IBEzCCAQ8wHQYDVR0OBBYEFCSv2kmiGg6VFMnxXzLDNP304cPAMIHfBgNV\n" + "HSMEgdcwgdSAFCSv2kmiGg6VFMnxXzLDNP304cPAoYGwpIGtMIGqMQswCQYDVQQG\n" + "EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNj\n" + "bzEbMBkGA1UEChMSSGlnaCBGaWRlbGl0eSwgSW5jMRMwEQYDVQQLEwpPcGVyYXRp\n" + "b25zMRgwFgYDVQQDEw9oaWdoZmlkZWxpdHkuaW8xIjAgBgkqhkiG9w0BCQEWE29w\n" + "c0BoaWdoZmlkZWxpdHkuaW+CCQDZX0ZEQ/QPGzAMBgNVHRMEBTADAQH/MA0GCSqG\n" + "SIb3DQEBBQUAA4GBAEkQl3p+lH5vuoCNgyfa67nL0MsBEt+5RSBOgjwCjjASjzou\n" + "FTv5w0he2OypgMQb8i/BYtS1lJSFqjPJcSM1Salzrm3xDOK5pOXJ7h6SQLPDVEyf\n" + "Hy2/9d/to+99+SOUlvfzfgycgjOc+s/AV7Y+GBd7uzGxUdrN4egCZW1F6/mH\n" + "-----END CERTIFICATE-----"; + + if (!datumInitialized) { + hifiCADatum.data = HIGHFIDELITY_ROOT_CA_CERT; + hifiCADatum.size = sizeof(HIGHFIDELITY_ROOT_CA_CERT); + } + + return &hifiCADatum; +} + DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : DummyDTLSSession(dtlsSocket, destinationSocket), _completedHandshake(false) diff --git a/libraries/shared/src/DTLSSession.h b/libraries/shared/src/DTLSSession.h index 6b5f5df5e3..2d5a7098f1 100644 --- a/libraries/shared/src/DTLSSession.h +++ b/libraries/shared/src/DTLSSession.h @@ -25,6 +25,8 @@ public: static int socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms); static ssize_t socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t size); + static gnutls_datum_t* highFidelityCADatum(); + qint64 writeDatagram(const QByteArray& datagram); gnutls_session_t* getGnuTLSSession() { return &_gnutlsSession; } From 86a0b715f3185eefba0163190037af041256b0ce Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 7 Apr 2014 11:36:32 -0700 Subject: [PATCH 32/86] verify DTLS certificate to ensure trust before handshaking --- domain-server/src/DomainServer.cpp | 2 +- libraries/shared/src/DTLSClientSession.cpp | 36 ++++++++++++++++++++-- libraries/shared/src/DTLSClientSession.h | 2 ++ libraries/shared/src/DTLSSession.cpp | 1 - libraries/shared/src/DomainHandler.cpp | 3 +- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 2f4179e56b..d0ac369700 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -689,7 +689,7 @@ void DomainServer::readAvailableDTLSDatagrams() { // the cookie sent by the client was not valid // send a valid one DummyDTLSSession tempServerSession(LimitedNodeList::getInstance()->getDTLSSocket(), senderHifiSockAddr); - qDebug() << "sending back a fresh cookie!"; + gnutls_dtls_cookie_send(_cookieKey, &senderSockAddr, sizeof(senderSockAddr), &prestate, &tempServerSession, DTLSSession::socketPush); diff --git a/libraries/shared/src/DTLSClientSession.cpp b/libraries/shared/src/DTLSClientSession.cpp index 40b2b87b66..0ebb282f29 100644 --- a/libraries/shared/src/DTLSClientSession.cpp +++ b/libraries/shared/src/DTLSClientSession.cpp @@ -16,8 +16,9 @@ void DTLSClientSession::globalInit() { if (!initialized) { gnutls_global_init(); gnutls_certificate_allocate_credentials(&_x509CACredentials); - int certsProcessed = gnutls_certificate_set_x509_trust_mem(_x509CACredentials, DTLSSession::highFidelityCADatum(), GNUTLS_X509_FMT_PEM); - qDebug() << "There were" << certsProcessed; + + gnutls_certificate_set_x509_trust_mem(_x509CACredentials, DTLSSession::highFidelityCADatum(), GNUTLS_X509_FMT_PEM); + gnutls_certificate_set_verify_function(_x509CACredentials, DTLSClientSession::verifyServerCertificate); } } @@ -27,6 +28,37 @@ void DTLSClientSession::globalDeinit() { gnutls_global_deinit(); } +int DTLSClientSession::verifyServerCertificate(gnutls_session_t session) { + unsigned int verifyStatus = 0; + int certReturn = gnutls_certificate_verify_peers3(session, NULL, &verifyStatus); + + if (certReturn < 0) { + return GNUTLS_E_CERTIFICATE_ERROR; + } + + gnutls_certificate_type_t typeReturn = gnutls_certificate_type_get(session); + + gnutls_datum_t printOut; + + + certReturn = gnutls_certificate_verification_status_print(verifyStatus, typeReturn, &printOut, 0); + + if (certReturn < 0) { + return GNUTLS_E_CERTIFICATE_ERROR; + } + + qDebug() << "Gnutls certificate verification status:" << reinterpret_cast(printOut.data); + gnutls_free(printOut.data); + + if (verifyStatus != 0) { + qDebug() << "Server provided certificate for DTLS is not trusted. Can not complete handshake."; + return GNUTLS_E_CERTIFICATE_ERROR; + } else { + // certificate is valid, continue handshaking as normal + return 0; + } +} + DTLSClientSession::DTLSClientSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket) : DTLSSession(GNUTLS_CLIENT, dtlsSocket, destinationSocket) { diff --git a/libraries/shared/src/DTLSClientSession.h b/libraries/shared/src/DTLSClientSession.h index ad5b0cd55b..fe8dec49b9 100644 --- a/libraries/shared/src/DTLSClientSession.h +++ b/libraries/shared/src/DTLSClientSession.h @@ -18,6 +18,8 @@ public: static void globalInit(); static void globalDeinit(); + static int verifyServerCertificate(gnutls_session_t session); + static gnutls_certificate_credentials_t _x509CACredentials; static bool _wasGloballyInitialized; }; diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index f76119fd1f..4685a05970 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -128,7 +128,6 @@ DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinat } DTLSSession::~DTLSSession() { - qDebug() << "cleaning up current session"; gnutls_deinit(_gnutlsSession); } diff --git a/libraries/shared/src/DomainHandler.cpp b/libraries/shared/src/DomainHandler.cpp index e1aedc4d11..380a9a4b7b 100644 --- a/libraries/shared/src/DomainHandler.cpp +++ b/libraries/shared/src/DomainHandler.cpp @@ -129,7 +129,8 @@ void DomainHandler::completeDTLSHandshake() { } else if (gnutls_error_is_fatal(handshakeReturn)) { // this was a fatal error handshaking, so remove this session qDebug() << "Fatal error -" << gnutls_strerror(handshakeReturn) - << "- during DTLS handshake with DS at" << getHostname(); + << "- during DTLS handshake with DS at" + << qPrintable((_hostname.isEmpty() ? _sockAddr.getAddress().toString() : _hostname)); clearConnectionInfo(); } From 02e2135a2ecda70ee2855c4210fc4405634de177 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 7 Apr 2014 12:52:26 -0700 Subject: [PATCH 33/86] allow setting of expected DTLS cert hostname from AC --- assignment-client/src/AssignmentClient.cpp | 58 ++++++++++------------ assignment-client/src/AssignmentClient.h | 1 + libraries/shared/src/DTLSClientSession.cpp | 11 +++- libraries/shared/src/DomainHandler.cpp | 7 ++- libraries/shared/src/DomainHandler.h | 2 +- 5 files changed, 43 insertions(+), 36 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 222cb0ce9a..d5d6beaead 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -31,7 +31,8 @@ int hifiSockAddrMeta = qRegisterMetaType("HifiSockAddr"); AssignmentClient::AssignmentClient(int &argc, char **argv) : QCoreApplication(argc, argv), - _currentAssignment() + _currentAssignment(), + _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME) { DTLSClientSession::globalInit(); @@ -40,57 +41,48 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : setApplicationName("assignment-client"); QSettings::setDefaultFormat(QSettings::IniFormat); + QStringList argumentList = arguments(); + // register meta type is required for queued invoke method on Assignment subclasses // set the logging target to the the CHILD_TARGET_NAME Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); - const char ASSIGNMENT_TYPE_OVVERIDE_OPTION[] = "-t"; - const char* assignmentTypeString = getCmdOption(argc, (const char**)argv, ASSIGNMENT_TYPE_OVVERIDE_OPTION); + const QString ASSIGNMENT_TYPE_OVVERIDE_OPTION = "-t"; + int argumentIndex = argumentList.indexOf(ASSIGNMENT_TYPE_OVVERIDE_OPTION); Assignment::Type requestAssignmentType = Assignment::AllTypes; - if (assignmentTypeString) { - // the user is asking to only be assigned to a particular type of assignment - // so set that as the ::overridenAssignmentType to be used in requests - requestAssignmentType = (Assignment::Type) atoi(assignmentTypeString); + if (argumentIndex != -1) { + requestAssignmentType = (Assignment::Type) argumentList[argumentIndex + 1].toInt(); } - const char ASSIGNMENT_POOL_OPTION[] = "--pool"; - const char* requestAssignmentPool = getCmdOption(argc, (const char**) argv, ASSIGNMENT_POOL_OPTION); + const QString ASSIGNMENT_POOL_OPTION = "--pool"; + argumentIndex = argumentList.indexOf(ASSIGNMENT_POOL_OPTION); + QString assignmentPool; + + if (argumentIndex != -1) { + assignmentPool = argumentList[argumentIndex + 1]; + } // setup our _requestAssignment member variable from the passed arguments - _requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, requestAssignmentPool); + _requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, assignmentPool); // create a NodeList as an unassigned client NodeList* nodeList = NodeList::createInstance(NodeType::Unassigned); - const char CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION[] = "-a"; - const char CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION[] = "-p"; + // check for an overriden assignment server hostname + const QString CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION = "-a"; - // grab the overriden assignment-server hostname from argv, if it exists - const char* customAssignmentServerHostname = getCmdOption(argc, (const char**)argv, CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION); - const char* customAssignmentServerPortString = getCmdOption(argc,(const char**)argv, CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION); + argumentIndex = argumentList.indexOf(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION); - HifiSockAddr customAssignmentSocket; - - if (customAssignmentServerHostname || customAssignmentServerPortString) { + if (argumentIndex != -1) { + _assignmentServerHostname = argumentList[argumentIndex + 1]; - // set the custom port or default if it wasn't passed - unsigned short assignmentServerPort = customAssignmentServerPortString - ? atoi(customAssignmentServerPortString) : DEFAULT_DOMAIN_SERVER_PORT; + // set the custom assignment socket on our NodeList + HifiSockAddr customAssignmentSocket = HifiSockAddr(_assignmentServerHostname, DEFAULT_DOMAIN_SERVER_PORT); - // set the custom hostname or default if it wasn't passed - if (!customAssignmentServerHostname) { - customAssignmentServerHostname = DEFAULT_ASSIGNMENT_SERVER_HOSTNAME; - } - - customAssignmentSocket = HifiSockAddr(customAssignmentServerHostname, assignmentServerPort); - } - - // set the custom assignment socket if we have it - if (!customAssignmentSocket.isNull()) { nodeList->setAssignmentServerSocket(customAssignmentSocket); } @@ -138,9 +130,9 @@ void AssignmentClient::readPendingDatagrams() { if (_currentAssignment) { qDebug() << "Received an assignment -" << *_currentAssignment; - // switch our nodelist domain IP and port to whoever sent us the assignment + // switch our DomainHandler hostname and port to whoever sent us the assignment - nodeList->getDomainHandler().setSockAddr(senderSockAddr); + nodeList->getDomainHandler().setSockAddr(senderSockAddr, _assignmentServerHostname); nodeList->getDomainHandler().setAssignmentUUID(_currentAssignment->getUUID()); qDebug() << "Destination IP for assignment is" << nodeList->getDomainHandler().getIP().toString(); diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 939d06b14f..33b1dd70e9 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -26,6 +26,7 @@ private slots: private: Assignment _requestAssignment; SharedAssignmentPointer _currentAssignment; + QString _assignmentServerHostname; }; #endif /* defined(__hifi__AssignmentClient__) */ diff --git a/libraries/shared/src/DTLSClientSession.cpp b/libraries/shared/src/DTLSClientSession.cpp index 0ebb282f29..ec8e121013 100644 --- a/libraries/shared/src/DTLSClientSession.cpp +++ b/libraries/shared/src/DTLSClientSession.cpp @@ -6,6 +6,8 @@ // Copyright (c) 2014 High Fidelity, Inc. All rights reserved. // +#include "DomainHandler.h" + #include "DTLSClientSession.h" gnutls_certificate_credentials_t DTLSClientSession::_x509CACredentials; @@ -30,7 +32,14 @@ void DTLSClientSession::globalDeinit() { int DTLSClientSession::verifyServerCertificate(gnutls_session_t session) { unsigned int verifyStatus = 0; - int certReturn = gnutls_certificate_verify_peers3(session, NULL, &verifyStatus); + + // grab the hostname from the domain handler that this session is associated with + DomainHandler* domainHandler = reinterpret_cast(gnutls_session_get_ptr(session)); + qDebug() << "Checking for" << domainHandler->getHostname() << "from cert."; + + int certReturn = gnutls_certificate_verify_peers3(session, + domainHandler->getHostname().toLocal8Bit().constData(), + &verifyStatus); if (certReturn < 0) { return GNUTLS_E_CERTIFICATE_ERROR; diff --git a/libraries/shared/src/DomainHandler.cpp b/libraries/shared/src/DomainHandler.cpp index 380a9a4b7b..4773a368a4 100644 --- a/libraries/shared/src/DomainHandler.cpp +++ b/libraries/shared/src/DomainHandler.cpp @@ -58,6 +58,8 @@ void DomainHandler::initializeDTLSSession() { if (!_dtlsSession) { _dtlsSession = new DTLSClientSession(NodeList::getInstance()->getDTLSSocket(), _sockAddr); + gnutls_session_set_ptr(*_dtlsSession->getGnuTLSSession(), this); + // start a timer to complete the handshake process _handshakeTimer = new QTimer(this); connect(_handshakeTimer, &QTimer::timeout, this, &DomainHandler::completeDTLSHandshake); @@ -70,13 +72,16 @@ void DomainHandler::initializeDTLSSession() { } } -void DomainHandler::setSockAddr(const HifiSockAddr& sockAddr) { +void DomainHandler::setSockAddr(const HifiSockAddr& sockAddr, const QString& hostname) { if (_sockAddr != sockAddr) { // we should reset on a sockAddr change reset(); // change the sockAddr _sockAddr = sockAddr; } + + // some callers may pass a hostname, this is not to be used for lookup but for DTLS certificate verification + _hostname = hostname; } void DomainHandler::setHostname(const QString& hostname) { diff --git a/libraries/shared/src/DomainHandler.h b/libraries/shared/src/DomainHandler.h index c34321cf87..106eff67f1 100644 --- a/libraries/shared/src/DomainHandler.h +++ b/libraries/shared/src/DomainHandler.h @@ -40,7 +40,7 @@ public: void setIPToLocalhost() { _sockAddr.setAddress(QHostAddress(QHostAddress::LocalHost)); } const HifiSockAddr& getSockAddr() { return _sockAddr; } - void setSockAddr(const HifiSockAddr& sockAddr); + void setSockAddr(const HifiSockAddr& sockAddr, const QString& hostname); unsigned short getPort() const { return _sockAddr.getPort(); } From c2ff43818236d44801a6fed6490f0edc3903955a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 8 Apr 2014 13:37:07 -0700 Subject: [PATCH 34/86] add a CL + JSON settings reader --- domain-server/src/DomainServer.cpp | 196 ++++++------------ domain-server/src/DomainServer.h | 8 +- libraries/shared/src/HifiConfigVariantMap.cpp | 92 ++++++++ libraries/shared/src/HifiConfigVariantMap.h | 19 ++ 4 files changed, 181 insertions(+), 134 deletions(-) create mode 100644 libraries/shared/src/HifiConfigVariantMap.cpp create mode 100644 libraries/shared/src/HifiConfigVariantMap.h diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index af3e9a643f..ad531998c3 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -47,7 +48,7 @@ DomainServer::DomainServer(int argc, char* argv[]) : setApplicationName("domain-server"); QSettings::setDefaultFormat(QSettings::IniFormat); - _argumentList = arguments(); + _argumentVariantMap = HifiConfigVariantMap::mergeCLParametersWithJSONConfig(arguments()); if (optionallySetupDTLS()) { // we either read a certificate and private key or were not passed one, good to load assignments @@ -132,14 +133,14 @@ bool DomainServer::optionallySetupDTLS() { } bool DomainServer::readX509KeyAndCertificate() { - const QString X509_CERTIFICATE_OPTION = "--cert"; - const QString X509_PRIVATE_KEY_OPTION = "--key"; + const QString X509_CERTIFICATE_OPTION = "cert"; + const QString X509_PRIVATE_KEY_OPTION = "key"; const QString X509_KEY_PASSPHRASE_ENV = "DOMAIN_SERVER_KEY_PASSPHRASE"; - int certIndex = _argumentList.indexOf(X509_CERTIFICATE_OPTION); - int keyIndex = _argumentList.indexOf(X509_PRIVATE_KEY_OPTION); + QString certPath = _argumentVariantMap.value(X509_CERTIFICATE_OPTION).toString(); + QString keyPath = _argumentVariantMap.value(X509_PRIVATE_KEY_OPTION).toString(); - if (certIndex != -1 && keyIndex != -1) { + if (!certPath.isEmpty() && !keyPath.isEmpty()) { // the user wants to use DTLS to encrypt communication with nodes // let's make sure we can load the key and certificate _x509Credentials = new gnutls_certificate_credentials_t; @@ -148,8 +149,8 @@ bool DomainServer::readX509KeyAndCertificate() { QString keyPassphraseString = QProcessEnvironment::systemEnvironment().value(X509_KEY_PASSPHRASE_ENV); int gnutlsReturn = gnutls_certificate_set_x509_key_file2(*_x509Credentials, - _argumentList[certIndex + 1].toLocal8Bit().constData(), - _argumentList[keyIndex + 1].toLocal8Bit().constData(), + certPath.toLocal8Bit().constData(), + keyPath.toLocal8Bit().constData(), GNUTLS_X509_FMT_PEM, keyPassphraseString.toLocal8Bit().constData(), 0); @@ -162,7 +163,7 @@ bool DomainServer::readX509KeyAndCertificate() { qDebug() << "Successfully read certificate and private key."; - } else if (certIndex != -1 || keyIndex != -1) { + } else if (!certPath.isEmpty() || !keyPath.isEmpty()) { qDebug() << "Missing certificate or private key. domain-server will now quit."; QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); return false; @@ -193,13 +194,11 @@ void DomainServer::processCreateResponseFromDataServer(const QJsonObject& jsonOb void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { - int argumentIndex = 0; - - const QString CUSTOM_PORT_OPTION = "-p"; + const QString CUSTOM_PORT_OPTION = "port"; unsigned short domainServerPort = DEFAULT_DOMAIN_SERVER_PORT; - if ((argumentIndex = _argumentList.indexOf(CUSTOM_PORT_OPTION)) != -1) { - domainServerPort = _argumentList.value(argumentIndex + 1).toUShort(); + if (_argumentVariantMap.contains(CUSTOM_PORT_OPTION)) { + domainServerPort = (unsigned short) _argumentVariantMap.value(CUSTOM_PORT_OPTION).toUInt(); } unsigned short domainServerDTLSPort = 0; @@ -207,21 +206,15 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { if (_isUsingDTLS) { domainServerDTLSPort = DEFAULT_DOMAIN_SERVER_DTLS_PORT; - const QString CUSTOM_DTLS_PORT_OPTION = "--dtlsPort"; + const QString CUSTOM_DTLS_PORT_OPTION = "dtls-port"; - if ((argumentIndex = _argumentList.indexOf(CUSTOM_DTLS_PORT_OPTION)) != -1) { - domainServerDTLSPort = _argumentList.value(argumentIndex + 1).toUShort(); + if (_argumentVariantMap.contains(CUSTOM_DTLS_PORT_OPTION)) { + domainServerDTLSPort = (unsigned short) _argumentVariantMap.value(CUSTOM_DTLS_PORT_OPTION).toUInt(); } } QSet parsedTypes(QSet() << Assignment::AgentType); - parseCommandLineTypeConfigs(_argumentList, parsedTypes); - - const QString CONFIG_FILE_OPTION = "--configFile"; - if ((argumentIndex = _argumentList.indexOf(CONFIG_FILE_OPTION)) != -1) { - QString configFilePath = _argumentList.value(argumentIndex + 1); - readConfigFile(configFilePath, parsedTypes); - } + parseAssignmentConfigs(parsedTypes); populateDefaultStaticAssignmentsExcludingTypes(parsedTypes); @@ -240,130 +233,75 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { addStaticAssignmentsToQueue(); } -void DomainServer::parseCommandLineTypeConfigs(const QStringList& argumentList, QSet& excludedTypes) { +void DomainServer::parseAssignmentConfigs(QSet& excludedTypes) { // check for configs from the command line, these take precedence - const QString CONFIG_TYPE_OPTION = "--configType"; - int clConfigIndex = argumentList.indexOf(CONFIG_TYPE_OPTION); + const QString ASSIGNMENT_CONFIG_REGEX_STRING = "config-([\\d]+)"; + QRegExp assignmentConfigRegex(ASSIGNMENT_CONFIG_REGEX_STRING); - // enumerate all CL config overrides and parse them to files - while (clConfigIndex != -1) { - int clConfigType = argumentList.value(clConfigIndex + 1).toInt(); - if (clConfigType < Assignment::AllTypes && !excludedTypes.contains((Assignment::Type) clConfigIndex)) { - Assignment::Type assignmentType = (Assignment::Type) clConfigType; - createStaticAssignmentsForTypeGivenConfigString((Assignment::Type) assignmentType, - argumentList.value(clConfigIndex + 2)); - excludedTypes.insert(assignmentType); + // scan for assignment config keys + QStringList variantMapKeys = _argumentVariantMap.keys(); + int configIndex = variantMapKeys.indexOf(assignmentConfigRegex); + + while (configIndex != -1) { + // figure out which assignment type this matches + Assignment::Type assignmentType = (Assignment::Type) assignmentConfigRegex.cap().toInt(); + + QVariant mapValue = _argumentVariantMap[variantMapKeys[configIndex]]; + + if (mapValue.type() == QVariant::String) { + QJsonDocument deserializedDocument = QJsonDocument::fromJson(mapValue.toString().toUtf8()); + createStaticAssignmentsForType(assignmentType, deserializedDocument.array()); + } else { + createStaticAssignmentsForType(assignmentType, mapValue.toJsonArray()); } - clConfigIndex = argumentList.indexOf(CONFIG_TYPE_OPTION, clConfigIndex + 1); - } -} - -// Attempts to read configuration from specified path -// returns true on success, false otherwise -void DomainServer::readConfigFile(const QString& path, QSet& excludedTypes) { - if (path.isEmpty()) { - // config file not specified - return; - } - - if (!QFile::exists(path)) { - qWarning("Specified configuration file does not exist!"); - return; - } - - QFile configFile(path); - if (!configFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - qWarning("Can't open specified configuration file!"); - return; - } else { - qDebug() << "Reading configuration from" << path; - } - - QTextStream configStream(&configFile); - QByteArray configStringByteArray = configStream.readAll().toUtf8(); - QJsonObject configDocObject = QJsonDocument::fromJson(configStringByteArray).object(); - configFile.close(); - - QSet appendedExcludedTypes = excludedTypes; - - foreach (const QString& rootStringValue, configDocObject.keys()) { - int possibleConfigType = rootStringValue.toInt(); + excludedTypes.insert(assignmentType); - if (possibleConfigType < Assignment::AllTypes - && !excludedTypes.contains((Assignment::Type) possibleConfigType)) { - // this is an appropriate config type and isn't already in our excluded types - // we are good to parse it - Assignment::Type assignmentType = (Assignment::Type) possibleConfigType; - QString configString = readServerAssignmentConfig(configDocObject, rootStringValue); - createStaticAssignmentsForTypeGivenConfigString(assignmentType, configString); - - excludedTypes.insert(assignmentType); - } + configIndex = variantMapKeys.indexOf(assignmentConfigRegex); } } -// find assignment configurations on the specified node name and json object -// returns a string in the form of its equivalent cmd line params -QString DomainServer::readServerAssignmentConfig(const QJsonObject& jsonObject, const QString& nodeName) { - QJsonArray nodeArray = jsonObject[nodeName].toArray(); - - QStringList serverConfig; - foreach (const QJsonValue& childValue, nodeArray) { - QString cmdParams; - QJsonObject childObject = childValue.toObject(); - QStringList keys = childObject.keys(); - for (int i = 0; i < keys.size(); i++) { - QString key = keys[i]; - QString value = childObject[key].toString(); - // both cmd line params and json keys are the same - cmdParams += QString("--%1 %2 ").arg(key, value); - } - serverConfig << cmdParams; - } - - // according to split() calls from DomainServer::prepopulateStaticAssignmentFile - // we shold simply join them with semicolons - return serverConfig.join(';'); -} - void DomainServer::addStaticAssignmentToAssignmentHash(Assignment* newAssignment) { qDebug() << "Inserting assignment" << *newAssignment << "to static assignment hash."; _staticAssignmentHash.insert(newAssignment->getUUID(), SharedAssignmentPointer(newAssignment)); } -void DomainServer::createStaticAssignmentsForTypeGivenConfigString(Assignment::Type type, const QString& configString) { +void DomainServer::createStaticAssignmentsForType(Assignment::Type type, const QJsonArray& configArray) { // we have a string for config for this type qDebug() << "Parsing command line config for assignment type" << type; - QStringList multiConfigList = configString.split(";", QString::SkipEmptyParts); + int configCounter = 0; - const QString ASSIGNMENT_CONFIG_POOL_REGEX = "--pool\\s*([\\w-]+)"; - QRegExp poolRegex(ASSIGNMENT_CONFIG_POOL_REGEX); - - // read each config to a payload for this type of assignment - for (int i = 0; i < multiConfigList.size(); i++) { - QString config = multiConfigList.at(i); - - // check the config string for a pool - QString assignmentPool; - - int poolIndex = poolRegex.indexIn(config); - - if (poolIndex != -1) { - assignmentPool = poolRegex.cap(1); + foreach(const QJsonValue& jsonValue, configArray) { + if (jsonValue.isObject()) { + QJsonObject jsonObject = jsonValue.toObject(); - // remove the pool from the config string, the assigned node doesn't need it - config.remove(poolIndex, poolRegex.matchedLength()); + // check the config string for a pool + const QString ASSIGNMENT_POOL_KEY = "pool"; + QString assignmentPool; + + QJsonValue poolValue = jsonObject[ASSIGNMENT_POOL_KEY]; + if (!poolValue.isUndefined()) { + assignmentPool = poolValue.toString(); + + jsonObject.remove(ASSIGNMENT_POOL_KEY); + } + + ++configCounter; + qDebug() << "Type" << type << "config" << configCounter << "=" << jsonObject; + + Assignment* configAssignment = new Assignment(Assignment::CreateCommand, type, assignmentPool); + + // setup the payload as a semi-colon separated list of key = value + QStringList payloadStringList; + foreach(const QString& payloadKey, jsonObject.keys()) { + payloadStringList << QString("%1=%2").arg(payloadKey).arg(jsonObject[payloadKey].toString()); + } + + configAssignment->setPayload(payloadStringList.join(';').toUtf8()); + + addStaticAssignmentToAssignmentHash(configAssignment); } - - qDebug("Type %d config[%d] = %s", type, i, config.toLocal8Bit().constData()); - - Assignment* configAssignment = new Assignment(Assignment::CreateCommand, type, assignmentPool); - - configAssignment->setPayload(config.toUtf8()); - - addStaticAssignmentToAssignmentHash(configAssignment); } } diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 78e48f1468..2f570fe5ad 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -64,11 +64,9 @@ private: void sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr& senderSockAddr, const NodeSet& nodeInterestList); - void parseCommandLineTypeConfigs(const QStringList& argumentList, QSet& excludedTypes); - void readConfigFile(const QString& path, QSet& excludedTypes); - QString readServerAssignmentConfig(const QJsonObject& jsonObject, const QString& nodeName); + void parseAssignmentConfigs(QSet& excludedTypes); void addStaticAssignmentToAssignmentHash(Assignment* newAssignment); - void createStaticAssignmentsForTypeGivenConfigString(Assignment::Type type, const QString& configString); + void createStaticAssignmentsForType(Assignment::Type type, const QJsonArray& configArray); void populateDefaultStaticAssignmentsExcludingTypes(const QSet& excludedTypes); SharedAssignmentPointer matchingStaticAssignmentForCheckIn(const QUuid& checkInUUID, NodeType_t nodeType); @@ -85,7 +83,7 @@ private: QHash _staticAssignmentHash; QQueue _assignmentQueue; - QStringList _argumentList; + QVariantMap _argumentVariantMap; bool _isUsingDTLS; gnutls_certificate_credentials_t* _x509Credentials; diff --git a/libraries/shared/src/HifiConfigVariantMap.cpp b/libraries/shared/src/HifiConfigVariantMap.cpp new file mode 100644 index 0000000000..f0dc012ffa --- /dev/null +++ b/libraries/shared/src/HifiConfigVariantMap.cpp @@ -0,0 +1,92 @@ +// +// HifiConfigVariantMap.cpp +// hifi +// +// Created by Stephen Birarda on 2014-04-08. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include + +#include "HifiConfigVariantMap.h" + +QVariantMap HifiConfigVariantMap::mergeCLParametersWithJSONConfig(const QStringList& argumentList) { + + QVariantMap mergedMap; + + // Add anything in the CL parameter list to the variant map. + // Take anything with a dash in it as a key, and the values after it as the value. + + const QString DASHED_KEY_REGEX_STRING = "(^-{1,2})([\\w-]+)"; + QRegExp dashedKeyRegex(DASHED_KEY_REGEX_STRING); + + int keyIndex = argumentList.indexOf(dashedKeyRegex); + int nextKeyIndex = 0; + + // check if there is a config file to read where we can pull config info not passed on command line + const QString CONFIG_FILE_OPTION = "--config"; + + while (keyIndex != -1) { + if (argumentList[keyIndex] != CONFIG_FILE_OPTION) { + // we have a key - look forward to see how many values associate to it + QString key = dashedKeyRegex.cap(2); + + nextKeyIndex = argumentList.indexOf(dashedKeyRegex, keyIndex + 1); + + if (nextKeyIndex == keyIndex + 1) { + // there's no value associated with this option, it's a boolean + // so add it to the variant map with NULL as value + mergedMap.insertMulti(key, QVariant()); + } else { + int maxIndex = (nextKeyIndex == -1) ? argumentList.size() : nextKeyIndex; + + // there's at least one value associated with the option + // pull the first value to start + QString value = argumentList[keyIndex + 1]; + + // for any extra values, append them, with a space, to the value string + for (int i = keyIndex + 2; i < maxIndex; i++) { + value += " " + argumentList[i]; + } + + // add the finalized value to the merged map + mergedMap.insert(key, value); + } + + keyIndex = nextKeyIndex; + } else { + keyIndex = argumentList.indexOf(dashedKeyRegex, keyIndex + 1); + } + } + + int configIndex = argumentList.indexOf(CONFIG_FILE_OPTION); + + if (configIndex != -1) { + // we have a config file - try and read it + QString configFilePath = argumentList[configIndex + 1]; + QFile configFile(configFilePath); + + if (configFile.exists()) { + configFile.open(QIODevice::ReadOnly); + + QJsonDocument configDocument = QJsonDocument::fromJson(configFile.readAll()); + QJsonObject rootObject = configDocument.object(); + + // enumerate the keys of the configDocument object + foreach(const QString& key, rootObject.keys()) { + + if (!mergedMap.contains(key)) { + // no match in existing list, add it + mergedMap.insert(key, QVariant(rootObject[key])); + } + } + } + } + + return mergedMap; +} diff --git a/libraries/shared/src/HifiConfigVariantMap.h b/libraries/shared/src/HifiConfigVariantMap.h new file mode 100644 index 0000000000..c652278b0d --- /dev/null +++ b/libraries/shared/src/HifiConfigVariantMap.h @@ -0,0 +1,19 @@ +// +// HifiConfigVariantMap.h +// hifi +// +// Created by Stephen Birarda on 2014-04-08. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__HifiConfigVariantMap__ +#define __hifi__HifiConfigVariantMap__ + +#include + +class HifiConfigVariantMap { +public: + static QVariantMap mergeCLParametersWithJSONConfig(const QStringList& argumentList); +}; + +#endif /* defined(__hifi__HifiConfigVariantMap__) */ From 9a9939c11a6778a739de24fa6b70c5f227fb29ad Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 8 Apr 2014 14:03:42 -0700 Subject: [PATCH 35/86] repairs for assignment parsing from command line and JSON --- domain-server/src/DomainServer.cpp | 34 ++++++++---------------------- domain-server/src/DomainServer.h | 2 -- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index ad531998c3..2f4f4666cc 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -172,26 +172,6 @@ bool DomainServer::readX509KeyAndCertificate() { return true; } -void DomainServer::requestCreationFromDataServer() { - // this slot is fired when we get a valid access token from the data-server - // now let's ask it to set us up with a UUID - JSONCallbackParameters callbackParams; - callbackParams.jsonCallbackReceiver = this; - callbackParams.jsonCallbackMethod = "processCreateResponseFromDataServer"; - - AccountManager::getInstance().authenticatedRequest("/api/v1/domains/create", - QNetworkAccessManager::PostOperation, - callbackParams); -} - -void DomainServer::processCreateResponseFromDataServer(const QJsonObject& jsonObject) { - if (jsonObject["status"].toString() == "success") { - // pull out the UUID the data-server is telling us to use, and complete our setup with it - QUuid newSessionUUID = QUuid(jsonObject["data"].toObject()["uuid"].toString()); - setupNodeListAndAssignments(newSessionUUID); - } -} - void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { const QString CUSTOM_PORT_OPTION = "port"; @@ -244,20 +224,21 @@ void DomainServer::parseAssignmentConfigs(QSet& excludedTypes) while (configIndex != -1) { // figure out which assignment type this matches - Assignment::Type assignmentType = (Assignment::Type) assignmentConfigRegex.cap().toInt(); + Assignment::Type assignmentType = (Assignment::Type) assignmentConfigRegex.cap(1).toInt(); QVariant mapValue = _argumentVariantMap[variantMapKeys[configIndex]]; if (mapValue.type() == QVariant::String) { + qDebug() << mapValue.toString(); QJsonDocument deserializedDocument = QJsonDocument::fromJson(mapValue.toString().toUtf8()); createStaticAssignmentsForType(assignmentType, deserializedDocument.array()); } else { - createStaticAssignmentsForType(assignmentType, mapValue.toJsonArray()); + createStaticAssignmentsForType(assignmentType, mapValue.toJsonValue().toArray()); } excludedTypes.insert(assignmentType); - configIndex = variantMapKeys.indexOf(assignmentConfigRegex); + configIndex = variantMapKeys.indexOf(assignmentConfigRegex, configIndex + 1); } } @@ -272,6 +253,8 @@ void DomainServer::createStaticAssignmentsForType(Assignment::Type type, const Q int configCounter = 0; + qDebug() << configArray; + foreach(const QJsonValue& jsonValue, configArray) { if (jsonValue.isObject()) { QJsonObject jsonObject = jsonValue.toObject(); @@ -295,10 +278,11 @@ void DomainServer::createStaticAssignmentsForType(Assignment::Type type, const Q // setup the payload as a semi-colon separated list of key = value QStringList payloadStringList; foreach(const QString& payloadKey, jsonObject.keys()) { - payloadStringList << QString("%1=%2").arg(payloadKey).arg(jsonObject[payloadKey].toString()); + QString dashes = payloadKey.size() == 1 ? "-" : "--"; + payloadStringList << QString("%1%2 %3").arg(dashes).arg(payloadKey).arg(jsonObject[payloadKey].toString()); } - configAssignment->setPayload(payloadStringList.join(';').toUtf8()); + configAssignment->setPayload(payloadStringList.join(' ').toUtf8()); addStaticAssignmentToAssignmentHash(configAssignment); } diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 2f570fe5ad..48c77625bb 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -44,8 +44,6 @@ public slots: void nodeKilled(SharedNodePointer node); private slots: - void requestCreationFromDataServer(); - void processCreateResponseFromDataServer(const QJsonObject& jsonObject); void readAvailableDatagrams(); void readAvailableDTLSDatagrams(); From 9ca864bb501cca4d2bb856dff599e4fb4183a269 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 8 Apr 2014 14:05:26 -0700 Subject: [PATCH 36/86] don't parse excluded types from config variant map --- domain-server/src/DomainServer.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 2f4f4666cc..322f88188b 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -226,17 +226,18 @@ void DomainServer::parseAssignmentConfigs(QSet& excludedTypes) // figure out which assignment type this matches Assignment::Type assignmentType = (Assignment::Type) assignmentConfigRegex.cap(1).toInt(); - QVariant mapValue = _argumentVariantMap[variantMapKeys[configIndex]]; - - if (mapValue.type() == QVariant::String) { - qDebug() << mapValue.toString(); - QJsonDocument deserializedDocument = QJsonDocument::fromJson(mapValue.toString().toUtf8()); - createStaticAssignmentsForType(assignmentType, deserializedDocument.array()); - } else { - createStaticAssignmentsForType(assignmentType, mapValue.toJsonValue().toArray()); - } - - excludedTypes.insert(assignmentType); + if (assignmentType < Assignment::AllTypes && !excludedTypes.contains(assignmentType)) { + QVariant mapValue = _argumentVariantMap[variantMapKeys[configIndex]]; + + if (mapValue.type() == QVariant::String) { + QJsonDocument deserializedDocument = QJsonDocument::fromJson(mapValue.toString().toUtf8()); + createStaticAssignmentsForType(assignmentType, deserializedDocument.array()); + } else { + createStaticAssignmentsForType(assignmentType, mapValue.toJsonValue().toArray()); + } + + excludedTypes.insert(assignmentType); + } configIndex = variantMapKeys.indexOf(assignmentConfigRegex, configIndex + 1); } From e417e7670b0bef8816f136adac0f3f02d394e1d1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 8 Apr 2014 14:07:31 -0700 Subject: [PATCH 37/86] cleanup DomainServer debug during config parsing --- domain-server/src/DomainServer.cpp | 6 ++---- libraries/shared/src/HifiConfigVariantMap.cpp | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 322f88188b..090e781be0 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -237,7 +237,7 @@ void DomainServer::parseAssignmentConfigs(QSet& excludedTypes) } excludedTypes.insert(assignmentType); - } + } configIndex = variantMapKeys.indexOf(assignmentConfigRegex, configIndex + 1); } @@ -250,12 +250,10 @@ void DomainServer::addStaticAssignmentToAssignmentHash(Assignment* newAssignment void DomainServer::createStaticAssignmentsForType(Assignment::Type type, const QJsonArray& configArray) { // we have a string for config for this type - qDebug() << "Parsing command line config for assignment type" << type; + qDebug() << "Parsing config for assignment type" << type; int configCounter = 0; - qDebug() << configArray; - foreach(const QJsonValue& jsonValue, configArray) { if (jsonValue.isObject()) { QJsonObject jsonObject = jsonValue.toObject(); diff --git a/libraries/shared/src/HifiConfigVariantMap.cpp b/libraries/shared/src/HifiConfigVariantMap.cpp index f0dc012ffa..f68c64581b 100644 --- a/libraries/shared/src/HifiConfigVariantMap.cpp +++ b/libraries/shared/src/HifiConfigVariantMap.cpp @@ -72,6 +72,7 @@ QVariantMap HifiConfigVariantMap::mergeCLParametersWithJSONConfig(const QStringL QFile configFile(configFilePath); if (configFile.exists()) { + qDebug() << "Reading JSON config file at" << configFilePath; configFile.open(QIODevice::ReadOnly); QJsonDocument configDocument = QJsonDocument::fromJson(configFile.readAll()); @@ -85,6 +86,8 @@ QVariantMap HifiConfigVariantMap::mergeCLParametersWithJSONConfig(const QStringL mergedMap.insert(key, QVariant(rootObject[key])); } } + } else { + qDebug() << "Could not find JSON config file at" << configFilePath; } } From ea61ccff7f474bfe4305af0e70b442e527e37e6e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 8 Apr 2014 14:10:04 -0700 Subject: [PATCH 38/86] add some more debugging when reading X509 cert files for DTLS --- domain-server/src/DomainServer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 090e781be0..1f7b73cda2 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -148,6 +148,9 @@ bool DomainServer::readX509KeyAndCertificate() { QString keyPassphraseString = QProcessEnvironment::systemEnvironment().value(X509_KEY_PASSPHRASE_ENV); + qDebug() << "Reading certificate file at" << certPath << "for DTLS."; + qDebug() << "Reading key file at" << keyPath << "for DTLS."; + int gnutlsReturn = gnutls_certificate_set_x509_key_file2(*_x509Credentials, certPath.toLocal8Bit().constData(), keyPath.toLocal8Bit().constData(), From 3f84f36d600b63588c9f1624a69a3f7be89eb246 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Apr 2014 15:00:57 -0700 Subject: [PATCH 39/86] add proper boilerplate to GnuTLS find module --- cmake/modules/FindGnuTLS.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmake/modules/FindGnuTLS.cmake b/cmake/modules/FindGnuTLS.cmake index f56a0db7d2..fcfd1909f8 100644 --- a/cmake/modules/FindGnuTLS.cmake +++ b/cmake/modules/FindGnuTLS.cmake @@ -1,3 +1,6 @@ +# +# FindFaceshift.cmake +# # Try to find the GnuTLS library # # You can provide a GNUTLS_ROOT_DIR which contains lib and include directories @@ -11,6 +14,9 @@ # Created on 3/31/2014 by Stephen Birarda # Copyright (c) 2014 High Fidelity # +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# if (GNUTLS_LIBRARY AND GNUTLS_INCLUDE_DIRS) # in cache already From 5a79079c090d7a004126e4ee5fc8beddff3c2dc6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Apr 2014 15:03:56 -0700 Subject: [PATCH 40/86] fix boilerplates in new DTLS files --- domain-server/src/DTLSServerSession.cpp | 7 +++++-- domain-server/src/DTLSServerSession.h | 7 +++++-- libraries/shared/src/DTLSClientSession.cpp | 7 +++++-- libraries/shared/src/DTLSClientSession.h | 7 +++++-- libraries/shared/src/DTLSSession.cpp | 7 +++++-- libraries/shared/src/DTLSSession.h | 7 +++++-- libraries/shared/src/DummyDTLSSession.cpp | 7 +++++-- libraries/shared/src/DummyDTLSSession.h | 7 +++++-- 8 files changed, 40 insertions(+), 16 deletions(-) diff --git a/domain-server/src/DTLSServerSession.cpp b/domain-server/src/DTLSServerSession.cpp index 994b196357..a80c54ee02 100644 --- a/domain-server/src/DTLSServerSession.cpp +++ b/domain-server/src/DTLSServerSession.cpp @@ -1,9 +1,12 @@ // // DTLSServerSession.cpp -// hifi +// domain-server/src // // Created by Stephen Birarda on 2014-04-01. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "DTLSServerSession.h" diff --git a/domain-server/src/DTLSServerSession.h b/domain-server/src/DTLSServerSession.h index 86f642b104..cc94c9dc2e 100644 --- a/domain-server/src/DTLSServerSession.h +++ b/domain-server/src/DTLSServerSession.h @@ -1,9 +1,12 @@ // // DTLSServerSession.h -// hifi +// domain-server/src // // Created by Stephen Birarda on 2014-04-01. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #ifndef __hifi__DTLSServerSession__ diff --git a/libraries/shared/src/DTLSClientSession.cpp b/libraries/shared/src/DTLSClientSession.cpp index ec8e121013..bd626dfcd8 100644 --- a/libraries/shared/src/DTLSClientSession.cpp +++ b/libraries/shared/src/DTLSClientSession.cpp @@ -1,9 +1,12 @@ // // DTLSClientSession.cpp -// hifi +// libraries/shared/src // // Created by Stephen Birarda on 2014-04-01. -// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "DomainHandler.h" diff --git a/libraries/shared/src/DTLSClientSession.h b/libraries/shared/src/DTLSClientSession.h index fe8dec49b9..8dece76a5c 100644 --- a/libraries/shared/src/DTLSClientSession.h +++ b/libraries/shared/src/DTLSClientSession.h @@ -1,9 +1,12 @@ // // DTLSClientSession.h -// hifi +// libraries/shared/src // // Created by Stephen Birarda on 2014-04-01. -// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #ifndef __hifi__DTLSClientSession__ diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/shared/src/DTLSSession.cpp index 4685a05970..8e84c38edc 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/shared/src/DTLSSession.cpp @@ -1,9 +1,12 @@ // // DTLSSession.cpp -// hifi +// libraries/shared/src // // Created by Stephen Birarda on 2014-04-01. -// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include diff --git a/libraries/shared/src/DTLSSession.h b/libraries/shared/src/DTLSSession.h index 2d5a7098f1..f7849999ae 100644 --- a/libraries/shared/src/DTLSSession.h +++ b/libraries/shared/src/DTLSSession.h @@ -1,9 +1,12 @@ // // DTLSSession.h -// hifi +// libraries/shared/src // // Created by Stephen Birarda on 2014-04-01. -// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #ifndef __hifi__DTLSSession__ diff --git a/libraries/shared/src/DummyDTLSSession.cpp b/libraries/shared/src/DummyDTLSSession.cpp index df7e82274c..96207477cf 100644 --- a/libraries/shared/src/DummyDTLSSession.cpp +++ b/libraries/shared/src/DummyDTLSSession.cpp @@ -1,9 +1,12 @@ // // DummyDTLSSession.cpp -// hifi +// libraries/shared/src // // Created by Stephen Birarda on 2014-04-04. -// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "DummyDTLSSession.h" diff --git a/libraries/shared/src/DummyDTLSSession.h b/libraries/shared/src/DummyDTLSSession.h index 394bb82ae5..336d473c63 100644 --- a/libraries/shared/src/DummyDTLSSession.h +++ b/libraries/shared/src/DummyDTLSSession.h @@ -1,9 +1,12 @@ // // DummyDTLSSession.h -// hifi +// libraries/shared/src // // Created by Stephen Birarda on 2014-04-04. -// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #ifndef __hifi__DummyDTLSSession__ From 3fe5af1505bde2c9ca8eff6d57b6854250b97af8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Apr 2014 15:08:56 -0700 Subject: [PATCH 41/86] update boilerplate and include guards for other new files --- domain-server/src/DTLSServerSession.h | 6 +++--- libraries/shared/src/DTLSClientSession.h | 6 +++--- libraries/shared/src/DTLSSession.h | 6 +++--- libraries/shared/src/DomainHandler.cpp | 7 +++++-- libraries/shared/src/DomainHandler.h | 13 ++++++++----- libraries/shared/src/DummyDTLSSession.h | 6 +++--- libraries/shared/src/HifiConfigVariantMap.cpp | 7 +++++-- libraries/shared/src/HifiConfigVariantMap.h | 13 ++++++++----- libraries/shared/src/LimitedNodeList.cpp | 7 +++++-- libraries/shared/src/LimitedNodeList.h | 13 ++++++++----- 10 files changed, 51 insertions(+), 33 deletions(-) diff --git a/domain-server/src/DTLSServerSession.h b/domain-server/src/DTLSServerSession.h index cc94c9dc2e..5fdc602df7 100644 --- a/domain-server/src/DTLSServerSession.h +++ b/domain-server/src/DTLSServerSession.h @@ -9,8 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef __hifi__DTLSServerSession__ -#define __hifi__DTLSServerSession__ +#ifndef hifi_DTLSServerSession_h +#define hifi_DTLSServerSession_h #include @@ -21,4 +21,4 @@ public: DTLSServerSession(QUdpSocket& dtlsSocket, HifiSockAddr& destinationSocket); }; -#endif /* defined(__hifi__DTLSServerSession__) */ +#endif // hifi_DTLSServerSession_h diff --git a/libraries/shared/src/DTLSClientSession.h b/libraries/shared/src/DTLSClientSession.h index 8dece76a5c..fcd5a3b5e9 100644 --- a/libraries/shared/src/DTLSClientSession.h +++ b/libraries/shared/src/DTLSClientSession.h @@ -9,8 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef __hifi__DTLSClientSession__ -#define __hifi__DTLSClientSession__ +#ifndef hifi_DTLSClientSession_h +#define hifi_DTLSClientSession_h #include "DTLSSession.h" @@ -27,4 +27,4 @@ public: static bool _wasGloballyInitialized; }; -#endif /* defined(__hifi__DTLSClientSession__) */ +#endif // hifi_DTLSClientSession_h diff --git a/libraries/shared/src/DTLSSession.h b/libraries/shared/src/DTLSSession.h index f7849999ae..4b69f13c78 100644 --- a/libraries/shared/src/DTLSSession.h +++ b/libraries/shared/src/DTLSSession.h @@ -9,8 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef __hifi__DTLSSession__ -#define __hifi__DTLSSession__ +#ifndef hifi_DTLSSession_h +#define hifi_DTLSSession_h #include @@ -41,4 +41,4 @@ protected: bool _completedHandshake; }; -#endif /* defined(__hifi__DTLSSession__) */ +#endif // hifi_DTLSSession_h diff --git a/libraries/shared/src/DomainHandler.cpp b/libraries/shared/src/DomainHandler.cpp index 4773a368a4..85c452f01c 100644 --- a/libraries/shared/src/DomainHandler.cpp +++ b/libraries/shared/src/DomainHandler.cpp @@ -1,9 +1,12 @@ // // DomainHandler.cpp -// hifi +// libraries/shared/src // // Created by Stephen Birarda on 2/18/2014. -// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include diff --git a/libraries/shared/src/DomainHandler.h b/libraries/shared/src/DomainHandler.h index 106eff67f1..f31e2a6817 100644 --- a/libraries/shared/src/DomainHandler.h +++ b/libraries/shared/src/DomainHandler.h @@ -1,13 +1,16 @@ // // DomainHandler.h -// hifi +// libraries/shared/src // // Created by Stephen Birarda on 2/18/2014. -// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef __hifi__DomainHandler__ -#define __hifi__DomainHandler__ +#ifndef hifi_DomainHandler_h +#define hifi_DomainHandler_h #include #include @@ -76,4 +79,4 @@ private: QTimer* _handshakeTimer; }; -#endif /* defined(__hifi__DomainHandler__) */ +#endif // hifi_DomainHandler_h diff --git a/libraries/shared/src/DummyDTLSSession.h b/libraries/shared/src/DummyDTLSSession.h index 336d473c63..e13686ac51 100644 --- a/libraries/shared/src/DummyDTLSSession.h +++ b/libraries/shared/src/DummyDTLSSession.h @@ -9,8 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef __hifi__DummyDTLSSession__ -#define __hifi__DummyDTLSSession__ +#ifndef hifi_DummyDTLSSession_h +#define hifi_DummyDTLSSession_h #include @@ -31,4 +31,4 @@ protected: HifiSockAddr _destinationSocket; }; -#endif /* defined(__hifi__DummyDTLSSession__) */ +#endif // hifi_DummyDTLSSession_h diff --git a/libraries/shared/src/HifiConfigVariantMap.cpp b/libraries/shared/src/HifiConfigVariantMap.cpp index f68c64581b..d20f4276f1 100644 --- a/libraries/shared/src/HifiConfigVariantMap.cpp +++ b/libraries/shared/src/HifiConfigVariantMap.cpp @@ -1,9 +1,12 @@ // // HifiConfigVariantMap.cpp -// hifi +// libraries/shared/src // // Created by Stephen Birarda on 2014-04-08. -// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include diff --git a/libraries/shared/src/HifiConfigVariantMap.h b/libraries/shared/src/HifiConfigVariantMap.h index c652278b0d..378aa749c5 100644 --- a/libraries/shared/src/HifiConfigVariantMap.h +++ b/libraries/shared/src/HifiConfigVariantMap.h @@ -1,13 +1,16 @@ // // HifiConfigVariantMap.h -// hifi +// libraries/shared/src // // Created by Stephen Birarda on 2014-04-08. -// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef __hifi__HifiConfigVariantMap__ -#define __hifi__HifiConfigVariantMap__ +#ifndef hifi_HifiConfigVariantMap_h +#define hifi_HifiConfigVariantMap_h #include @@ -16,4 +19,4 @@ public: static QVariantMap mergeCLParametersWithJSONConfig(const QStringList& argumentList); }; -#endif /* defined(__hifi__HifiConfigVariantMap__) */ +#endif // hifi_HifiConfigVariantMap_h diff --git a/libraries/shared/src/LimitedNodeList.cpp b/libraries/shared/src/LimitedNodeList.cpp index e9fdaa493c..b4a65475d6 100644 --- a/libraries/shared/src/LimitedNodeList.cpp +++ b/libraries/shared/src/LimitedNodeList.cpp @@ -1,9 +1,12 @@ // // LimitedNodeList.cpp -// hifi +// libraries/shared/src // // Created by Stephen Birarda on 2/15/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include diff --git a/libraries/shared/src/LimitedNodeList.h b/libraries/shared/src/LimitedNodeList.h index adbc94e8d2..d428805511 100644 --- a/libraries/shared/src/LimitedNodeList.h +++ b/libraries/shared/src/LimitedNodeList.h @@ -1,13 +1,16 @@ // // LimitedNodeList.h -// hifi +// libraries/shared/src // // Created by Stephen Birarda on 2/15/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef __hifi__LimitedNodeList__ -#define __hifi__LimitedNodeList__ +#ifndef hifi_LimitedNodeList_h +#define hifi_LimitedNodeList_h #ifdef _WIN32 #include "Syssocket.h" @@ -132,4 +135,4 @@ protected: QElapsedTimer _packetStatTimer; }; -#endif /* defined(__hifi__LimitedNodeList__) */ +#endif // hifi_LimitedNodeList_h From 03bb2573d19934f531e36bec088ee36e9d9b7057 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Apr 2014 17:18:34 -0700 Subject: [PATCH 42/86] look in bin folder to find GnuTLS on windows --- cmake/modules/FindGnuTLS.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/FindGnuTLS.cmake b/cmake/modules/FindGnuTLS.cmake index fcfd1909f8..8d9823962f 100644 --- a/cmake/modules/FindGnuTLS.cmake +++ b/cmake/modules/FindGnuTLS.cmake @@ -27,7 +27,7 @@ else () find_path(GNUTLS_INCLUDE_DIR gnutls.h PATH_SUFFIXES include gnutls HINTS ${GNUTLS_SEARCH_DIRS}) - find_library(GNUTLS_LIBRARY NAMES gnutls PATH_SUFFIXES lib HINTS ${GNUTLS_SEARCH_DIRS}) + find_library(GNUTLS_LIBRARY NAMES gnutls gnutls-28 PATH_SUFFIXES lib bin HINTS ${GNUTLS_SEARCH_DIRS}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(GNUTLS DEFAULT_MSG GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY) From d54c21cdf13c839e5695e725b3bc0e0a4ee9921d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Apr 2014 17:23:13 -0700 Subject: [PATCH 43/86] fix path suffixes for gnutls headers --- cmake/modules/FindGnuTLS.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/FindGnuTLS.cmake b/cmake/modules/FindGnuTLS.cmake index 8d9823962f..58b10a9ed3 100644 --- a/cmake/modules/FindGnuTLS.cmake +++ b/cmake/modules/FindGnuTLS.cmake @@ -25,7 +25,7 @@ else () set(GNUTLS_SEARCH_DIRS "${GNUTLS_ROOT_DIR}" "$ENV{HIFI_LIB_DIR}/gnutls") - find_path(GNUTLS_INCLUDE_DIR gnutls.h PATH_SUFFIXES include gnutls HINTS ${GNUTLS_SEARCH_DIRS}) + find_path(GNUTLS_INCLUDE_DIR gnutls.h PATH_SUFFIXES include/gnutls gnutls HINTS ${GNUTLS_SEARCH_DIRS}) find_library(GNUTLS_LIBRARY NAMES gnutls gnutls-28 PATH_SUFFIXES lib bin HINTS ${GNUTLS_SEARCH_DIRS}) From 35519e07dc6efbd472de9d7d8e06886ce1292079 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Apr 2014 17:27:37 -0700 Subject: [PATCH 44/86] quote dashed library name to potentially fix find on windows --- cmake/modules/FindGnuTLS.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/FindGnuTLS.cmake b/cmake/modules/FindGnuTLS.cmake index 58b10a9ed3..24b414bcc0 100644 --- a/cmake/modules/FindGnuTLS.cmake +++ b/cmake/modules/FindGnuTLS.cmake @@ -27,7 +27,7 @@ else () find_path(GNUTLS_INCLUDE_DIR gnutls.h PATH_SUFFIXES include/gnutls gnutls HINTS ${GNUTLS_SEARCH_DIRS}) - find_library(GNUTLS_LIBRARY NAMES gnutls gnutls-28 PATH_SUFFIXES lib bin HINTS ${GNUTLS_SEARCH_DIRS}) + find_library(GNUTLS_LIBRARY NAMES gnutls "gnutls-28" PATH_SUFFIXES lib bin HINTS ${GNUTLS_SEARCH_DIRS}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(GNUTLS DEFAULT_MSG GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY) From 8b23addc470b818df0948cbf0449139377074942 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Apr 2014 17:31:11 -0700 Subject: [PATCH 45/86] prepend the gnutls library with lib for windows find --- cmake/modules/FindGnuTLS.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/FindGnuTLS.cmake b/cmake/modules/FindGnuTLS.cmake index 24b414bcc0..24baaff358 100644 --- a/cmake/modules/FindGnuTLS.cmake +++ b/cmake/modules/FindGnuTLS.cmake @@ -27,7 +27,7 @@ else () find_path(GNUTLS_INCLUDE_DIR gnutls.h PATH_SUFFIXES include/gnutls gnutls HINTS ${GNUTLS_SEARCH_DIRS}) - find_library(GNUTLS_LIBRARY NAMES gnutls "gnutls-28" PATH_SUFFIXES lib bin HINTS ${GNUTLS_SEARCH_DIRS}) + find_library(GNUTLS_LIBRARY NAMES gnutls libgnutls libgnutls-28 PATH_SUFFIXES lib bin HINTS ${GNUTLS_SEARCH_DIRS}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(GNUTLS DEFAULT_MSG GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY) From 17d2e14f0fc5c4c6681f66cb9fc3c16b49c1b416 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Apr 2014 17:33:41 -0700 Subject: [PATCH 46/86] find correct parent include folder for gnutls --- cmake/modules/FindGnuTLS.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/FindGnuTLS.cmake b/cmake/modules/FindGnuTLS.cmake index 24baaff358..f718bea68b 100644 --- a/cmake/modules/FindGnuTLS.cmake +++ b/cmake/modules/FindGnuTLS.cmake @@ -25,7 +25,7 @@ else () set(GNUTLS_SEARCH_DIRS "${GNUTLS_ROOT_DIR}" "$ENV{HIFI_LIB_DIR}/gnutls") - find_path(GNUTLS_INCLUDE_DIR gnutls.h PATH_SUFFIXES include/gnutls gnutls HINTS ${GNUTLS_SEARCH_DIRS}) + find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h PATH_SUFFIXES include HINTS ${GNUTLS_SEARCH_DIRS}) find_library(GNUTLS_LIBRARY NAMES gnutls libgnutls libgnutls-28 PATH_SUFFIXES lib bin HINTS ${GNUTLS_SEARCH_DIRS}) From 3d071e85d5684fef60a8f59fefe78f8273c028e4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Apr 2014 17:37:23 -0700 Subject: [PATCH 47/86] link GnuTLS to the assignment-client --- assignment-client/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index 505708a899..1611b1e2b4 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -13,6 +13,7 @@ set(MACRO_DIR "${ROOT_DIR}/cmake/macros") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") find_package(Qt5 COMPONENTS Network Script Widgets) +find_package(GnuTLS REQUIRED) include("${MACRO_DIR}/SetupHifiProject.cmake") setup_hifi_project(${TARGET_NAME} TRUE) @@ -41,4 +42,5 @@ IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) -target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) +include_directories("${GNUTLS_INCLUDE_DIR}") +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file From 31382b7e121a167d401f7d8a9034e14ab5f7346f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Apr 2014 17:41:18 -0700 Subject: [PATCH 48/86] add a message for Win32 users to generate the MSVC GnuTLS import library --- cmake/modules/FindGnuTLS.cmake | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindGnuTLS.cmake b/cmake/modules/FindGnuTLS.cmake index f718bea68b..ac0f30877f 100644 --- a/cmake/modules/FindGnuTLS.cmake +++ b/cmake/modules/FindGnuTLS.cmake @@ -21,8 +21,7 @@ if (GNUTLS_LIBRARY AND GNUTLS_INCLUDE_DIRS) # in cache already set(GNUTLS_FOUND TRUE) -else () - +else () set(GNUTLS_SEARCH_DIRS "${GNUTLS_ROOT_DIR}" "$ENV{HIFI_LIB_DIR}/gnutls") find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h PATH_SUFFIXES include HINTS ${GNUTLS_SEARCH_DIRS}) @@ -31,4 +30,12 @@ else () include(FindPackageHandleStandardArgs) find_package_handle_standard_args(GNUTLS DEFAULT_MSG GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY) + + if (WIN32 AND NOT GNUTLS_FOUND) + message(STATUS "If you're generating a MSVC environment, you'll need to run the command") + message(STATUS "$GnuTLS-DIR\\bin>lib /def:libgnutls-28.def") + message(STATUS "From the MSVC command prompt to generate the .lib file and copy it into") + message(STATUS "your lib folder. Replace $GnuTLS-DIR in the command with the directory") + message(STATUS "containing GnuTLS.") + endif () endif () \ No newline at end of file From d5d52f804f5d5b3223fb65c4ae7d08b9e19abff1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 09:32:17 -0700 Subject: [PATCH 49/86] add a networking library and link from appropriate targets --- animation-server/CMakeLists.txt | 3 ++- assignment-client/CMakeLists.txt | 5 ++-- .../src/avatars/AvatarMixerClientData.cpp | 2 ++ domain-server/CMakeLists.txt | 1 + interface/CMakeLists.txt | 9 ++++--- libraries/audio/CMakeLists.txt | 3 ++- libraries/avatars/CMakeLists.txt | 1 + libraries/metavoxels/CMakeLists.txt | 7 ++++-- libraries/networking/CMakeLists.txt | 24 +++++++++++++++++++ .../src/AccountManager.cpp | 2 +- .../src/AccountManager.h | 2 +- .../{shared => networking}/src/Assignment.cpp | 2 +- .../{shared => networking}/src/Assignment.h | 2 +- .../src/DTLSClientSession.cpp | 2 +- .../src/DTLSClientSession.h | 2 +- .../src/DTLSSession.cpp | 2 +- .../{shared => networking}/src/DTLSSession.h | 2 +- .../src/DataServerAccountInfo.cpp | 2 +- .../src/DataServerAccountInfo.h | 2 +- .../src/DomainHandler.cpp | 2 +- .../src/DomainHandler.h | 2 +- .../src/DummyDTLSSession.cpp | 2 +- .../src/DummyDTLSSession.h | 2 +- .../src/HifiSockAddr.cpp | 2 +- .../{shared => networking}/src/HifiSockAddr.h | 2 +- .../src/LimitedNodeList.cpp | 2 +- .../src/LimitedNodeList.h | 2 +- .../{shared => networking}/src/Logging.cpp | 2 +- .../{shared => networking}/src/Logging.h | 2 +- .../src/NetworkPacket.cpp | 2 +- .../src/NetworkPacket.h | 2 +- libraries/{shared => networking}/src/Node.cpp | 2 +- libraries/{shared => networking}/src/Node.h | 2 +- .../{shared => networking}/src/NodeData.cpp | 2 +- .../{shared => networking}/src/NodeData.h | 2 +- .../{shared => networking}/src/NodeList.cpp | 2 +- .../{shared => networking}/src/NodeList.h | 2 +- .../src/OAuthAccessToken.cpp | 2 +- .../src/OAuthAccessToken.h | 2 +- .../src/PacketHeaders.cpp | 2 +- .../src/PacketHeaders.h | 2 +- .../src/PacketSender.cpp | 2 +- .../{shared => networking}/src/PacketSender.h | 2 +- .../src/ReceivedPacketProcessor.cpp | 2 +- .../src/ReceivedPacketProcessor.h | 2 +- .../{shared => networking}/src/Syssocket.h | 0 .../src/ThreadedAssignment.cpp | 0 .../src/ThreadedAssignment.h | 0 libraries/octree/CMakeLists.txt | 1 + libraries/particles/CMakeLists.txt | 1 + libraries/shared/CMakeLists.txt | 4 +--- libraries/shared/src/SharedUtil.cpp | 1 - libraries/shared/src/SharedUtil.h | 2 -- libraries/voxels/CMakeLists.txt | 1 + voxel-edit/CMakeLists.txt | 3 +++ 55 files changed, 86 insertions(+), 54 deletions(-) create mode 100644 libraries/networking/CMakeLists.txt rename libraries/{shared => networking}/src/AccountManager.cpp (99%) rename libraries/{shared => networking}/src/AccountManager.h (99%) rename libraries/{shared => networking}/src/Assignment.cpp (99%) rename libraries/{shared => networking}/src/Assignment.h (99%) rename libraries/{shared => networking}/src/DTLSClientSession.cpp (98%) rename libraries/{shared => networking}/src/DTLSClientSession.h (96%) rename libraries/{shared => networking}/src/DTLSSession.cpp (99%) rename libraries/{shared => networking}/src/DTLSSession.h (97%) rename libraries/{shared => networking}/src/DataServerAccountInfo.cpp (98%) rename libraries/{shared => networking}/src/DataServerAccountInfo.h (97%) rename libraries/{shared => networking}/src/DomainHandler.cpp (99%) rename libraries/{shared => networking}/src/DomainHandler.h (98%) rename libraries/{shared => networking}/src/DummyDTLSSession.cpp (97%) rename libraries/{shared => networking}/src/DummyDTLSSession.h (96%) rename libraries/{shared => networking}/src/HifiSockAddr.cpp (99%) rename libraries/{shared => networking}/src/HifiSockAddr.h (98%) rename libraries/{shared => networking}/src/LimitedNodeList.cpp (99%) rename libraries/{shared => networking}/src/LimitedNodeList.h (99%) rename libraries/{shared => networking}/src/Logging.cpp (99%) rename libraries/{shared => networking}/src/Logging.h (98%) rename libraries/{shared => networking}/src/NetworkPacket.cpp (98%) rename libraries/{shared => networking}/src/NetworkPacket.h (98%) rename libraries/{shared => networking}/src/Node.cpp (99%) rename libraries/{shared => networking}/src/Node.h (99%) rename libraries/{shared => networking}/src/NodeData.cpp (92%) rename libraries/{shared => networking}/src/NodeData.h (95%) rename libraries/{shared => networking}/src/NodeList.cpp (99%) rename libraries/{shared => networking}/src/NodeList.h (99%) rename libraries/{shared => networking}/src/OAuthAccessToken.cpp (98%) rename libraries/{shared => networking}/src/OAuthAccessToken.h (97%) rename libraries/{shared => networking}/src/PacketHeaders.cpp (99%) rename libraries/{shared => networking}/src/PacketHeaders.h (99%) rename libraries/{shared => networking}/src/PacketSender.cpp (99%) rename libraries/{shared => networking}/src/PacketSender.h (99%) rename libraries/{shared => networking}/src/ReceivedPacketProcessor.cpp (98%) rename libraries/{shared => networking}/src/ReceivedPacketProcessor.h (98%) rename libraries/{shared => networking}/src/Syssocket.h (100%) rename libraries/{shared => networking}/src/ThreadedAssignment.cpp (100%) rename libraries/{shared => networking}/src/ThreadedAssignment.h (100%) diff --git a/animation-server/CMakeLists.txt b/animation-server/CMakeLists.txt index 7d3222327a..d8fa8d97b2 100644 --- a/animation-server/CMakeLists.txt +++ b/animation-server/CMakeLists.txt @@ -29,4 +29,5 @@ link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") # link in the hifi voxels library link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") - +# link the hifi networking library +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") \ No newline at end of file diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index 1611b1e2b4..fa8d23051a 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -13,7 +13,6 @@ set(MACRO_DIR "${ROOT_DIR}/cmake/macros") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") find_package(Qt5 COMPONENTS Network Script Widgets) -find_package(GnuTLS REQUIRED) include("${MACRO_DIR}/SetupHifiProject.cmake") setup_hifi_project(${TARGET_NAME} TRUE) @@ -31,6 +30,7 @@ link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(particles ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(metavoxels ${TARGET_NAME} "${ROOT_DIR}") +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(script-engine ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") @@ -42,5 +42,4 @@ IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) -include_directories("${GNUTLS_INCLUDE_DIR}") -target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) \ No newline at end of file diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index 9289d640f5..f35285124f 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include "AvatarMixerClientData.h" AvatarMixerClientData::AvatarMixerClientData() : diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index 4cbc29c62d..0db22542b0 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -34,6 +34,7 @@ add_custom_command(TARGET ${TARGET_NAME} POST_BUILD # link the shared hifi library include(${MACRO_DIR}/LinkHifiLibrary.cmake) +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 251553f3c3..6a3186bb70 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -32,8 +32,8 @@ elseif (UNIX) # include the right GL headers for UNIX set(GL_HEADERS "#include \n#include \n#include ") elseif (WIN32) - add_definitions( -D_USE_MATH_DEFINES ) # apparently needed to get M_PI and other defines from cmath/math.h - add_definitions( -DWINDOWS_LEAN_AND_MEAN ) # needed to make sure windows doesn't go to crazy with its defines + add_definitions(-D_USE_MATH_DEFINES) # apparently needed to get M_PI and other defines from cmath/math.h + add_definitions(-DWINDOWS_LEAN_AND_MEAN) # needed to make sure windows doesn't go to crazy with its defines set(GL_HEADERS "#include \n#include \n#include ") endif () @@ -67,7 +67,6 @@ foreach(EXTERNAL_SOURCE_SUBDIR ${EXTERNAL_SOURCE_SUBDIRS}) endforeach(EXTERNAL_SOURCE_SUBDIR) find_package(Qt5 COMPONENTS Core Gui Multimedia Network OpenGL Script Svg WebKit WebKitWidgets Xml UiTools) -find_package(GnuTLS REQUIRED) # grab the ui files in resources/ui file (GLOB_RECURSE QT_UI_FILES ui/*.ui) @@ -125,6 +124,7 @@ link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(metavoxels ${TARGET_NAME} "${ROOT_DIR}") +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(particles ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(avatars ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(audio ${TARGET_NAME} "${ROOT_DIR}") @@ -189,7 +189,7 @@ include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes" # include external library headers # use system flag so warnings are supressed -include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") +include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}") target_link_libraries( ${TARGET_NAME} @@ -197,7 +197,6 @@ target_link_libraries( "${ZLIB_LIBRARIES}" Qt5::Core Qt5::Gui Qt5::Multimedia Qt5::Network Qt5::OpenGL Qt5::Script Qt5::Svg Qt5::WebKit Qt5::WebKitWidgets Qt5::Xml Qt5::UiTools - "${GNUTLS_LIBRARY}" ) if (APPLE) diff --git a/libraries/audio/CMakeLists.txt b/libraries/audio/CMakeLists.txt index 8d2feb22a2..0bf0ba9904 100644 --- a/libraries/audio/CMakeLists.txt +++ b/libraries/audio/CMakeLists.txt @@ -20,4 +20,5 @@ include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") include(${MACRO_DIR}/LinkHifiLibrary.cmake) -link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") \ No newline at end of file +link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") \ No newline at end of file diff --git a/libraries/avatars/CMakeLists.txt b/libraries/avatars/CMakeLists.txt index 4cc97e56a5..9816282dda 100644 --- a/libraries/avatars/CMakeLists.txt +++ b/libraries/avatars/CMakeLists.txt @@ -26,5 +26,6 @@ link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") # link in the hifi voxels library link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") target_link_libraries(${TARGET_NAME} Qt5::Script) \ No newline at end of file diff --git a/libraries/metavoxels/CMakeLists.txt b/libraries/metavoxels/CMakeLists.txt index acc060b270..7a8319815a 100644 --- a/libraries/metavoxels/CMakeLists.txt +++ b/libraries/metavoxels/CMakeLists.txt @@ -20,8 +20,11 @@ auto_mtc(${TARGET_NAME} "${ROOT_DIR}") include(${MACRO_DIR}/SetupHifiLibrary.cmake) setup_hifi_library(${TARGET_NAME} "${AUTOMTC_SRC}") +# link in the networking library +include(${MACRO_DIR}/LinkHifiLibrary.cmake) +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") + include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") -target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) - +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) \ No newline at end of file diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt new file mode 100644 index 0000000000..101e739fea --- /dev/null +++ b/libraries/networking/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 2.8) + +if (WIN32) + cmake_policy (SET CMP0020 NEW) +endif (WIN32) + +set(ROOT_DIR ../..) +set(MACRO_DIR "${ROOT_DIR}/cmake/macros") + +set(TARGET_NAME networking) +project(${TARGET_NAME}) + +find_package(Qt5 COMPONENTS Network) +find_package(GnuTLS REQUIRED) + +include(${MACRO_DIR}/SetupHifiLibrary.cmake) +setup_hifi_library(${TARGET_NAME}) + +# include GLM +include(${MACRO_DIR}/IncludeGLM.cmake) +include_glm(${TARGET_NAME} "${ROOT_DIR}") + +include_directories("${GNUTLS_INCLUDE_DIR}") +target_link_libraries(${TARGET_NAME} Qt5::Network "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/shared/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp similarity index 99% rename from libraries/shared/src/AccountManager.cpp rename to libraries/networking/src/AccountManager.cpp index 6c0bcb33cb..d1e4edf2ea 100644 --- a/libraries/shared/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -1,6 +1,6 @@ // // AccountManager.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/18/2014. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/shared/src/AccountManager.h b/libraries/networking/src/AccountManager.h similarity index 99% rename from libraries/shared/src/AccountManager.h rename to libraries/networking/src/AccountManager.h index fed6a61772..cb76786f4e 100644 --- a/libraries/shared/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -1,6 +1,6 @@ // // AccountManager.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/18/2014. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/shared/src/Assignment.cpp b/libraries/networking/src/Assignment.cpp similarity index 99% rename from libraries/shared/src/Assignment.cpp rename to libraries/networking/src/Assignment.cpp index 4d6740b400..dd318aad8e 100644 --- a/libraries/shared/src/Assignment.cpp +++ b/libraries/networking/src/Assignment.cpp @@ -1,6 +1,6 @@ // // Assignment.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 8/22/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/Assignment.h b/libraries/networking/src/Assignment.h similarity index 99% rename from libraries/shared/src/Assignment.h rename to libraries/networking/src/Assignment.h index c5a83cf417..041121f760 100644 --- a/libraries/shared/src/Assignment.h +++ b/libraries/networking/src/Assignment.h @@ -1,6 +1,6 @@ // // Assignment.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 8/22/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/DTLSClientSession.cpp b/libraries/networking/src/DTLSClientSession.cpp similarity index 98% rename from libraries/shared/src/DTLSClientSession.cpp rename to libraries/networking/src/DTLSClientSession.cpp index bd626dfcd8..b17de8e168 100644 --- a/libraries/shared/src/DTLSClientSession.cpp +++ b/libraries/networking/src/DTLSClientSession.cpp @@ -1,6 +1,6 @@ // // DTLSClientSession.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2014-04-01. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/shared/src/DTLSClientSession.h b/libraries/networking/src/DTLSClientSession.h similarity index 96% rename from libraries/shared/src/DTLSClientSession.h rename to libraries/networking/src/DTLSClientSession.h index fcd5a3b5e9..eeca1aaa68 100644 --- a/libraries/shared/src/DTLSClientSession.h +++ b/libraries/networking/src/DTLSClientSession.h @@ -1,6 +1,6 @@ // // DTLSClientSession.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2014-04-01. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/shared/src/DTLSSession.cpp b/libraries/networking/src/DTLSSession.cpp similarity index 99% rename from libraries/shared/src/DTLSSession.cpp rename to libraries/networking/src/DTLSSession.cpp index 8e84c38edc..7d375ec327 100644 --- a/libraries/shared/src/DTLSSession.cpp +++ b/libraries/networking/src/DTLSSession.cpp @@ -1,6 +1,6 @@ // // DTLSSession.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2014-04-01. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/shared/src/DTLSSession.h b/libraries/networking/src/DTLSSession.h similarity index 97% rename from libraries/shared/src/DTLSSession.h rename to libraries/networking/src/DTLSSession.h index 4b69f13c78..9e9542e147 100644 --- a/libraries/shared/src/DTLSSession.h +++ b/libraries/networking/src/DTLSSession.h @@ -1,6 +1,6 @@ // // DTLSSession.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2014-04-01. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/shared/src/DataServerAccountInfo.cpp b/libraries/networking/src/DataServerAccountInfo.cpp similarity index 98% rename from libraries/shared/src/DataServerAccountInfo.cpp rename to libraries/networking/src/DataServerAccountInfo.cpp index 1c53bca30f..87d3b694a7 100644 --- a/libraries/shared/src/DataServerAccountInfo.cpp +++ b/libraries/networking/src/DataServerAccountInfo.cpp @@ -1,6 +1,6 @@ // // DataServerAccountInfo.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/18/2014. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/shared/src/DataServerAccountInfo.h b/libraries/networking/src/DataServerAccountInfo.h similarity index 97% rename from libraries/shared/src/DataServerAccountInfo.h rename to libraries/networking/src/DataServerAccountInfo.h index ae5de6de64..21380c0855 100644 --- a/libraries/shared/src/DataServerAccountInfo.h +++ b/libraries/networking/src/DataServerAccountInfo.h @@ -1,6 +1,6 @@ // // DataServerAccountInfo.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/21/2014. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/shared/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp similarity index 99% rename from libraries/shared/src/DomainHandler.cpp rename to libraries/networking/src/DomainHandler.cpp index 85c452f01c..6c2fb0274a 100644 --- a/libraries/shared/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -1,6 +1,6 @@ // // DomainHandler.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/18/2014. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/shared/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h similarity index 98% rename from libraries/shared/src/DomainHandler.h rename to libraries/networking/src/DomainHandler.h index ef698fd826..9a18feb1ed 100644 --- a/libraries/shared/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -1,6 +1,6 @@ // // DomainHandler.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/18/2014. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/shared/src/DummyDTLSSession.cpp b/libraries/networking/src/DummyDTLSSession.cpp similarity index 97% rename from libraries/shared/src/DummyDTLSSession.cpp rename to libraries/networking/src/DummyDTLSSession.cpp index 96207477cf..a42e3f1599 100644 --- a/libraries/shared/src/DummyDTLSSession.cpp +++ b/libraries/networking/src/DummyDTLSSession.cpp @@ -1,6 +1,6 @@ // // DummyDTLSSession.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2014-04-04. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/shared/src/DummyDTLSSession.h b/libraries/networking/src/DummyDTLSSession.h similarity index 96% rename from libraries/shared/src/DummyDTLSSession.h rename to libraries/networking/src/DummyDTLSSession.h index e13686ac51..352b2c23e2 100644 --- a/libraries/shared/src/DummyDTLSSession.h +++ b/libraries/networking/src/DummyDTLSSession.h @@ -1,6 +1,6 @@ // // DummyDTLSSession.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2014-04-04. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/shared/src/HifiSockAddr.cpp b/libraries/networking/src/HifiSockAddr.cpp similarity index 99% rename from libraries/shared/src/HifiSockAddr.cpp rename to libraries/networking/src/HifiSockAddr.cpp index fd79341850..be482cfe02 100644 --- a/libraries/shared/src/HifiSockAddr.cpp +++ b/libraries/networking/src/HifiSockAddr.cpp @@ -1,6 +1,6 @@ // // HifiSockAddr.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 11/26/2013. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/HifiSockAddr.h b/libraries/networking/src/HifiSockAddr.h similarity index 98% rename from libraries/shared/src/HifiSockAddr.h rename to libraries/networking/src/HifiSockAddr.h index 229587e523..49db336d19 100644 --- a/libraries/shared/src/HifiSockAddr.h +++ b/libraries/networking/src/HifiSockAddr.h @@ -1,6 +1,6 @@ // // HifiSockAddr.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 11/26/2013. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp similarity index 99% rename from libraries/shared/src/LimitedNodeList.cpp rename to libraries/networking/src/LimitedNodeList.cpp index b4a65475d6..b0b048dde4 100644 --- a/libraries/shared/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -1,6 +1,6 @@ // // LimitedNodeList.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/15/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h similarity index 99% rename from libraries/shared/src/LimitedNodeList.h rename to libraries/networking/src/LimitedNodeList.h index d428805511..7fc0346a74 100644 --- a/libraries/shared/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -1,6 +1,6 @@ // // LimitedNodeList.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/15/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/Logging.cpp b/libraries/networking/src/Logging.cpp similarity index 99% rename from libraries/shared/src/Logging.cpp rename to libraries/networking/src/Logging.cpp index 2625cc744a..17a4706de0 100644 --- a/libraries/shared/src/Logging.cpp +++ b/libraries/networking/src/Logging.cpp @@ -1,6 +1,6 @@ // // Logging.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 6/11/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/Logging.h b/libraries/networking/src/Logging.h similarity index 98% rename from libraries/shared/src/Logging.h rename to libraries/networking/src/Logging.h index edbe8f62ee..b37962e931 100644 --- a/libraries/shared/src/Logging.h +++ b/libraries/networking/src/Logging.h @@ -1,6 +1,6 @@ // // Logging.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 6/11/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/NetworkPacket.cpp b/libraries/networking/src/NetworkPacket.cpp similarity index 98% rename from libraries/shared/src/NetworkPacket.cpp rename to libraries/networking/src/NetworkPacket.cpp index b948b10c96..bf18aa9b37 100644 --- a/libraries/shared/src/NetworkPacket.cpp +++ b/libraries/networking/src/NetworkPacket.cpp @@ -1,6 +1,6 @@ // // NetworkPacket.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Brad Hefta-Gaub on 8/9/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/NetworkPacket.h b/libraries/networking/src/NetworkPacket.h similarity index 98% rename from libraries/shared/src/NetworkPacket.h rename to libraries/networking/src/NetworkPacket.h index 6c086e2f5a..94ddf8d56e 100644 --- a/libraries/shared/src/NetworkPacket.h +++ b/libraries/networking/src/NetworkPacket.h @@ -1,6 +1,6 @@ // // NetworkPacket.h -// libraries/shared/src +// libraries/networking/src // // Created by Brad Hefta-Gaub on 8/9/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/Node.cpp b/libraries/networking/src/Node.cpp similarity index 99% rename from libraries/shared/src/Node.cpp rename to libraries/networking/src/Node.cpp index 13f700ad5a..f6445de58d 100644 --- a/libraries/shared/src/Node.cpp +++ b/libraries/networking/src/Node.cpp @@ -1,6 +1,6 @@ // // Node.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/15/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/Node.h b/libraries/networking/src/Node.h similarity index 99% rename from libraries/shared/src/Node.h rename to libraries/networking/src/Node.h index e7ebbcfb13..6cc8d5bfaf 100644 --- a/libraries/shared/src/Node.h +++ b/libraries/networking/src/Node.h @@ -1,6 +1,6 @@ // // Node.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/15/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/NodeData.cpp b/libraries/networking/src/NodeData.cpp similarity index 92% rename from libraries/shared/src/NodeData.cpp rename to libraries/networking/src/NodeData.cpp index 6b71ef8f37..2e6fa9e8e1 100644 --- a/libraries/shared/src/NodeData.cpp +++ b/libraries/networking/src/NodeData.cpp @@ -1,6 +1,6 @@ // // NodeData.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/19/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/NodeData.h b/libraries/networking/src/NodeData.h similarity index 95% rename from libraries/shared/src/NodeData.h rename to libraries/networking/src/NodeData.h index 3b26d5b6d5..b865e444a9 100644 --- a/libraries/shared/src/NodeData.h +++ b/libraries/networking/src/NodeData.h @@ -1,6 +1,6 @@ // // NodeData.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/19/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp similarity index 99% rename from libraries/shared/src/NodeList.cpp rename to libraries/networking/src/NodeList.cpp index cb4bacc5f9..93377c7763 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -1,6 +1,6 @@ // // NodeList.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/15/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/NodeList.h b/libraries/networking/src/NodeList.h similarity index 99% rename from libraries/shared/src/NodeList.h rename to libraries/networking/src/NodeList.h index 06505cc36c..1cc824c294 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -1,6 +1,6 @@ // // NodeList.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/15/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/OAuthAccessToken.cpp b/libraries/networking/src/OAuthAccessToken.cpp similarity index 98% rename from libraries/shared/src/OAuthAccessToken.cpp rename to libraries/networking/src/OAuthAccessToken.cpp index ab5ec6462a..365b07a935 100644 --- a/libraries/shared/src/OAuthAccessToken.cpp +++ b/libraries/networking/src/OAuthAccessToken.cpp @@ -1,6 +1,6 @@ // // OAuthAccessToken.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/18/2014. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/shared/src/OAuthAccessToken.h b/libraries/networking/src/OAuthAccessToken.h similarity index 97% rename from libraries/shared/src/OAuthAccessToken.h rename to libraries/networking/src/OAuthAccessToken.h index 7f7c621231..36859b79f8 100644 --- a/libraries/shared/src/OAuthAccessToken.h +++ b/libraries/networking/src/OAuthAccessToken.h @@ -1,6 +1,6 @@ // // OAuthAccessToken.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 2/18/2014. // Copyright 2014 High Fidelity, Inc. diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp similarity index 99% rename from libraries/shared/src/PacketHeaders.cpp rename to libraries/networking/src/PacketHeaders.cpp index 5916c542dd..fe999fed96 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/networking/src/PacketHeaders.cpp @@ -1,6 +1,6 @@ // // PacketHeaders.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 6/28/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h similarity index 99% rename from libraries/shared/src/PacketHeaders.h rename to libraries/networking/src/PacketHeaders.h index 924445e276..3e2ff3d8b0 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/networking/src/PacketHeaders.h @@ -1,6 +1,6 @@ // // PacketHeaders.h -// libraries/shared/src +// libraries/networking/src // // Created by Stephen Birarda on 4/8/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/PacketSender.cpp b/libraries/networking/src/PacketSender.cpp similarity index 99% rename from libraries/shared/src/PacketSender.cpp rename to libraries/networking/src/PacketSender.cpp index 489b083d92..5f7502a738 100644 --- a/libraries/shared/src/PacketSender.cpp +++ b/libraries/networking/src/PacketSender.cpp @@ -1,6 +1,6 @@ // // PacketSender.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Brad Hefta-Gaub on 8/12/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/PacketSender.h b/libraries/networking/src/PacketSender.h similarity index 99% rename from libraries/shared/src/PacketSender.h rename to libraries/networking/src/PacketSender.h index cc65564461..7d2c0dc8aa 100644 --- a/libraries/shared/src/PacketSender.h +++ b/libraries/networking/src/PacketSender.h @@ -1,6 +1,6 @@ // // PacketSender.h -// libraries/shared/src +// libraries/networking/src // // Created by Brad Hefta-Gaub on 8/12/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/ReceivedPacketProcessor.cpp b/libraries/networking/src/ReceivedPacketProcessor.cpp similarity index 98% rename from libraries/shared/src/ReceivedPacketProcessor.cpp rename to libraries/networking/src/ReceivedPacketProcessor.cpp index 8394559524..d54e165285 100644 --- a/libraries/shared/src/ReceivedPacketProcessor.cpp +++ b/libraries/networking/src/ReceivedPacketProcessor.cpp @@ -1,6 +1,6 @@ // // ReceivedPacketProcessor.cpp -// libraries/shared/src +// libraries/networking/src // // Created by Brad Hefta-Gaub on 8/12/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/ReceivedPacketProcessor.h b/libraries/networking/src/ReceivedPacketProcessor.h similarity index 98% rename from libraries/shared/src/ReceivedPacketProcessor.h rename to libraries/networking/src/ReceivedPacketProcessor.h index a34b43626c..f8306b4896 100644 --- a/libraries/shared/src/ReceivedPacketProcessor.h +++ b/libraries/networking/src/ReceivedPacketProcessor.h @@ -1,6 +1,6 @@ // // ReceivedPacketProcessor.h -// libraries/shared/src +// libraries/networking/src // // Created by Brad Hefta-Gaub on 8/12/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/shared/src/Syssocket.h b/libraries/networking/src/Syssocket.h similarity index 100% rename from libraries/shared/src/Syssocket.h rename to libraries/networking/src/Syssocket.h diff --git a/libraries/shared/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp similarity index 100% rename from libraries/shared/src/ThreadedAssignment.cpp rename to libraries/networking/src/ThreadedAssignment.cpp diff --git a/libraries/shared/src/ThreadedAssignment.h b/libraries/networking/src/ThreadedAssignment.h similarity index 100% rename from libraries/shared/src/ThreadedAssignment.h rename to libraries/networking/src/ThreadedAssignment.h diff --git a/libraries/octree/CMakeLists.txt b/libraries/octree/CMakeLists.txt index 422089a57d..5f4e66ea11 100644 --- a/libraries/octree/CMakeLists.txt +++ b/libraries/octree/CMakeLists.txt @@ -22,6 +22,7 @@ include_glm(${TARGET_NAME} "${ROOT_DIR}") include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") # link ZLIB find_package(ZLIB) diff --git a/libraries/particles/CMakeLists.txt b/libraries/particles/CMakeLists.txt index b483e3e479..e6c554dbdf 100644 --- a/libraries/particles/CMakeLists.txt +++ b/libraries/particles/CMakeLists.txt @@ -23,6 +23,7 @@ include_glm(${TARGET_NAME} "${ROOT_DIR}") include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") # link ZLIB find_package(ZLIB) diff --git a/libraries/shared/CMakeLists.txt b/libraries/shared/CMakeLists.txt index 6b4dafd8d4..7f9a34492d 100644 --- a/libraries/shared/CMakeLists.txt +++ b/libraries/shared/CMakeLists.txt @@ -11,7 +11,6 @@ set(TARGET_NAME shared) project(${TARGET_NAME}) find_package(Qt5 COMPONENTS Network Widgets Xml) -find_package(GnuTLS REQUIRED) include(${MACRO_DIR}/SetupHifiLibrary.cmake) setup_hifi_library(${TARGET_NAME}) @@ -33,5 +32,4 @@ if (UNIX AND NOT APPLE) target_link_libraries(${TARGET_NAME} "${CMAKE_THREAD_LIBS_INIT}") endif (UNIX AND NOT APPLE) -include_directories("${GNUTLS_INCLUDE_DIR}") -target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets "${GNUTLS_LIBRARY}") \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets) \ No newline at end of file diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index fc54c62d51..42aed77fcb 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -26,7 +26,6 @@ #include #include "OctalCode.h" -#include "PacketHeaders.h" #include "SharedUtil.h" quint64 usecTimestamp(const timeval *time) { diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index c4abd4965f..f41c5b8aa2 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -30,8 +30,6 @@ #include #endif -#include "PacketHeaders.h" - const int BYTES_PER_COLOR = 3; const int BYTES_PER_FLAGS = 1; typedef unsigned char rgbColor[BYTES_PER_COLOR]; diff --git a/libraries/voxels/CMakeLists.txt b/libraries/voxels/CMakeLists.txt index afc0b34b64..1cb838a6f0 100644 --- a/libraries/voxels/CMakeLists.txt +++ b/libraries/voxels/CMakeLists.txt @@ -24,6 +24,7 @@ include_glm(${TARGET_NAME} "${ROOT_DIR}") include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") # link ZLIB find_package(ZLIB) diff --git a/voxel-edit/CMakeLists.txt b/voxel-edit/CMakeLists.txt index 0de8fd059e..ce3c542691 100644 --- a/voxel-edit/CMakeLists.txt +++ b/voxel-edit/CMakeLists.txt @@ -31,6 +31,9 @@ link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") # link in the hifi voxels library link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") +# link in the hifi networking library +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") + IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) From f51b7a78c62ea84bfce04d526ff419b0c79587c4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 09:32:44 -0700 Subject: [PATCH 50/86] look only in lib for GnuTLS library --- cmake/modules/FindGnuTLS.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindGnuTLS.cmake b/cmake/modules/FindGnuTLS.cmake index ac0f30877f..724dcbe171 100644 --- a/cmake/modules/FindGnuTLS.cmake +++ b/cmake/modules/FindGnuTLS.cmake @@ -26,7 +26,7 @@ else () find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h PATH_SUFFIXES include HINTS ${GNUTLS_SEARCH_DIRS}) - find_library(GNUTLS_LIBRARY NAMES gnutls libgnutls libgnutls-28 PATH_SUFFIXES lib bin HINTS ${GNUTLS_SEARCH_DIRS}) + find_library(GNUTLS_LIBRARY NAMES gnutls libgnutls libgnutls-28 PATH_SUFFIXES lib HINTS ${GNUTLS_SEARCH_DIRS}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(GNUTLS DEFAULT_MSG GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY) @@ -35,7 +35,7 @@ else () message(STATUS "If you're generating a MSVC environment, you'll need to run the command") message(STATUS "$GnuTLS-DIR\\bin>lib /def:libgnutls-28.def") message(STATUS "From the MSVC command prompt to generate the .lib file and copy it into") - message(STATUS "your lib folder. Replace $GnuTLS-DIR in the command with the directory") + message(STATUS "the GnuTLS lib folder. Replace $GnuTLS-DIR in the command with the directory") message(STATUS "containing GnuTLS.") endif () endif () \ No newline at end of file From 7e2b73906c5ae6f14434821b825285744a9b0bb3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 09:35:25 -0700 Subject: [PATCH 51/86] remove Syssocket include from SharedUtil --- libraries/shared/src/SharedUtil.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 42aed77fcb..9a59bb5493 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -15,10 +15,6 @@ #include #include -#ifdef _WIN32 -#include "Syssocket.h" -#endif - #ifdef __APPLE__ #include #endif From 1d5644a85fb4bbed1e4d213d7690d80618d32a09 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 09:45:57 -0700 Subject: [PATCH 52/86] link GnuTLS to octree library --- animation-server/CMakeLists.txt | 10 +++++++++- domain-server/CMakeLists.txt | 6 +++--- libraries/octree/CMakeLists.txt | 8 +++++--- libraries/shared/src/SharedUtil.cpp | 5 +++++ 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/animation-server/CMakeLists.txt b/animation-server/CMakeLists.txt index d8fa8d97b2..490e01ffec 100644 --- a/animation-server/CMakeLists.txt +++ b/animation-server/CMakeLists.txt @@ -30,4 +30,12 @@ link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") # link the hifi networking library -link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") \ No newline at end of file +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") + +find_package(GnuTLS REQUIRED) + +# include the GnuTLS dir +include_directories("${GNUTLS_INCLUDE_DIR}") + +# link GnuTLS +target_link_libraries(${TARGET_NAME} "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index 0db22542b0..c960005995 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -38,12 +38,12 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") -# include the QCA dir -include_directories(GNUTLS_INCLUDE_DIR) +# include the GnuTLS dir +include_directories("${GNUTLS_INCLUDE_DIR}") IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) -# link QtNetwork and QCA +# link QtNetwork and GnuTLS target_link_libraries(${TARGET_NAME} Qt5::Network "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/octree/CMakeLists.txt b/libraries/octree/CMakeLists.txt index 5f4e66ea11..a4758e52f3 100644 --- a/libraries/octree/CMakeLists.txt +++ b/libraries/octree/CMakeLists.txt @@ -24,8 +24,10 @@ include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") -# link ZLIB +# link ZLIB and GnuTLS find_package(ZLIB) -include_directories("${ZLIB_INCLUDE_DIRS}") +find_package(GnuTLS REQUIRED) -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) +include_directories("${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") + +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 9a59bb5493..0eecd00333 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -15,6 +15,11 @@ #include #include +#ifdef _WIN32 +#ifndef _timeval_ +#define _timeval_ +#endif + #ifdef __APPLE__ #include #endif From 58298984d35520bfe38697b2395158711b4e8124 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 09:48:47 -0700 Subject: [PATCH 53/86] link GnuTLS to the assignment-client, fix timeval in SharedUtil --- assignment-client/CMakeLists.txt | 5 ++++- libraries/shared/src/SharedUtil.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index fa8d23051a..4930c2ace1 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -34,6 +34,9 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(script-engine ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") +find_package(GnuTLS REQUIRED) +include_directories("${GNUTLS_INCLUDE_DIR}") + if (UNIX) target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS}) endif (UNIX) @@ -42,4 +45,4 @@ IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) -target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 0eecd00333..7be21dfb52 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -15,7 +15,7 @@ #include #include -#ifdef _WIN32 +#ifdef WIN32 #ifndef _timeval_ #define _timeval_ #endif From ba6f861ad8b4cadcfc9ff54f61b4cdfa16032f0b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 09:54:37 -0700 Subject: [PATCH 54/86] fix unmatched #ifdef in Syssocket --- libraries/networking/src/Syssocket.h | 3 --- libraries/shared/src/SharedUtil.cpp | 5 +++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/libraries/networking/src/Syssocket.h b/libraries/networking/src/Syssocket.h index 36713a2b7b..7d7955426f 100644 --- a/libraries/networking/src/Syssocket.h +++ b/libraries/networking/src/Syssocket.h @@ -4,9 +4,6 @@ #ifdef _WIN32 #define WINSOCK_API_LINKAGE #include -#ifndef _timeval_ -#define _timeval_ -#endif typedef SSIZE_T ssize_t; typedef ULONG32 in_addr_t; typedef USHORT in_port_t; diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 7be21dfb52..3569c700ed 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -15,10 +15,11 @@ #include #include -#ifdef WIN32 +#ifdef _WIN32 #ifndef _timeval_ #define _timeval_ #endif +#endif #ifdef __APPLE__ #include @@ -44,7 +45,7 @@ quint64 usecTimestampNow() { return (now.tv_sec * 1000000 + now.tv_usec) + ::usecTimestampNowAdjust; } -float randFloat () { +float randFloat() { return (rand() % 10000)/10000.f; } From 68c445e7183a74930fc1534fb8cb8f06bc57d732 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 10:00:10 -0700 Subject: [PATCH 55/86] link GnuTLS to targets linking the networking library --- interface/CMakeLists.txt | 4 +++- libraries/audio/CMakeLists.txt | 7 ++++++- libraries/avatars/CMakeLists.txt | 4 +++- libraries/metavoxels/CMakeLists.txt | 4 +++- libraries/particles/CMakeLists.txt | 7 ++++--- libraries/voxels/CMakeLists.txt | 8 +++++--- voxel-edit/CMakeLists.txt | 6 +++++- 7 files changed, 29 insertions(+), 11 deletions(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 6a3186bb70..d435f048ab 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -67,6 +67,7 @@ foreach(EXTERNAL_SOURCE_SUBDIR ${EXTERNAL_SOURCE_SUBDIRS}) endforeach(EXTERNAL_SOURCE_SUBDIR) find_package(Qt5 COMPONENTS Core Gui Multimedia Network OpenGL Script Svg WebKit WebKitWidgets Xml UiTools) +find_package(GnuTLS REQUIRED) # grab the ui files in resources/ui file (GLOB_RECURSE QT_UI_FILES ui/*.ui) @@ -189,7 +190,7 @@ include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes" # include external library headers # use system flag so warnings are supressed -include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}") +include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") target_link_libraries( ${TARGET_NAME} @@ -197,6 +198,7 @@ target_link_libraries( "${ZLIB_LIBRARIES}" Qt5::Core Qt5::Gui Qt5::Multimedia Qt5::Network Qt5::OpenGL Qt5::Script Qt5::Svg Qt5::WebKit Qt5::WebKitWidgets Qt5::Xml Qt5::UiTools + "${GNUTLS_LIBRARY}" ) if (APPLE) diff --git a/libraries/audio/CMakeLists.txt b/libraries/audio/CMakeLists.txt index 0bf0ba9904..213e04c43a 100644 --- a/libraries/audio/CMakeLists.txt +++ b/libraries/audio/CMakeLists.txt @@ -21,4 +21,9 @@ include_glm(${TARGET_NAME} "${ROOT_DIR}") include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") -link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") \ No newline at end of file +link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") + +# link GnuTLS +find_package(GnuTLS REQUIRED) +include_directories("${GNUTLS_INCLUDE_DIR}") +target_link_libraries(${TARGET_NAME} "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/avatars/CMakeLists.txt b/libraries/avatars/CMakeLists.txt index 9816282dda..fe31eb6a06 100644 --- a/libraries/avatars/CMakeLists.txt +++ b/libraries/avatars/CMakeLists.txt @@ -28,4 +28,6 @@ link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") -target_link_libraries(${TARGET_NAME} Qt5::Script) \ No newline at end of file +find_package(GnuTLS REQUIRED) +include_directories("${GNUTLS_INCLUDE_DIR}") +target_link_libraries(${TARGET_NAME} Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/metavoxels/CMakeLists.txt b/libraries/metavoxels/CMakeLists.txt index 7a8319815a..4ef9fcc9cb 100644 --- a/libraries/metavoxels/CMakeLists.txt +++ b/libraries/metavoxels/CMakeLists.txt @@ -27,4 +27,6 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") -target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) \ No newline at end of file +find_package(GnuTLS REQUIRED) +include_directories("${GNUTLS_INCLUDE_DIR}") +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/particles/CMakeLists.txt b/libraries/particles/CMakeLists.txt index e6c554dbdf..4df0859195 100644 --- a/libraries/particles/CMakeLists.txt +++ b/libraries/particles/CMakeLists.txt @@ -25,8 +25,9 @@ link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") -# link ZLIB +# link ZLIB and GnuTLS find_package(ZLIB) -include_directories("${ZLIB_INCLUDE_DIRS}") +find_package(GnuTLS REQUIRED) -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) +include_directories("${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/voxels/CMakeLists.txt b/libraries/voxels/CMakeLists.txt index 1cb838a6f0..68ce7c13aa 100644 --- a/libraries/voxels/CMakeLists.txt +++ b/libraries/voxels/CMakeLists.txt @@ -26,8 +26,10 @@ link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") -# link ZLIB +# link ZLIB and GnuTLS find_package(ZLIB) -include_directories("${ZLIB_INCLUDE_DIRS}") +find_package(GnuTLS REQUIRED) -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets Qt5::Script) +include_directories("${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") + +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" "${GNUTLS_LIBRARY}" Qt5::Widgets Qt5::Script) \ No newline at end of file diff --git a/voxel-edit/CMakeLists.txt b/voxel-edit/CMakeLists.txt index ce3c542691..883b1debe4 100644 --- a/voxel-edit/CMakeLists.txt +++ b/voxel-edit/CMakeLists.txt @@ -34,8 +34,12 @@ link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") # link in the hifi networking library link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") +# link GnuTLS +find_package(GnuTLS REQUIRED) +include_directories("${GNUTLS_INCLUDE_DIR}") + IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) -target_link_libraries(${TARGET_NAME} Qt5::Script) \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file From 16bb28a4fa53bde55af503f4c615bf5c032e4a81 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 10:04:02 -0700 Subject: [PATCH 56/86] make GnuTLS a system include to suppress warnings --- animation-server/CMakeLists.txt | 2 +- assignment-client/CMakeLists.txt | 2 +- domain-server/CMakeLists.txt | 2 +- libraries/audio/CMakeLists.txt | 2 +- libraries/avatars/CMakeLists.txt | 2 +- libraries/metavoxels/CMakeLists.txt | 2 +- libraries/networking/CMakeLists.txt | 2 +- libraries/octree/CMakeLists.txt | 2 +- libraries/particles/CMakeLists.txt | 2 +- libraries/voxels/CMakeLists.txt | 2 +- voxel-edit/CMakeLists.txt | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/animation-server/CMakeLists.txt b/animation-server/CMakeLists.txt index 490e01ffec..80544c103a 100644 --- a/animation-server/CMakeLists.txt +++ b/animation-server/CMakeLists.txt @@ -35,7 +35,7 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") find_package(GnuTLS REQUIRED) # include the GnuTLS dir -include_directories("${GNUTLS_INCLUDE_DIR}") +include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") # link GnuTLS target_link_libraries(${TARGET_NAME} "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index 4930c2ace1..ce2c6b6d4e 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -35,7 +35,7 @@ link_hifi_library(script-engine ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") find_package(GnuTLS REQUIRED) -include_directories("${GNUTLS_INCLUDE_DIR}") +include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") if (UNIX) target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS}) diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index c960005995..5388d5d8e0 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -39,7 +39,7 @@ link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") # include the GnuTLS dir -include_directories("${GNUTLS_INCLUDE_DIR}") +include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) diff --git a/libraries/audio/CMakeLists.txt b/libraries/audio/CMakeLists.txt index 213e04c43a..e34dfa65f5 100644 --- a/libraries/audio/CMakeLists.txt +++ b/libraries/audio/CMakeLists.txt @@ -25,5 +25,5 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") # link GnuTLS find_package(GnuTLS REQUIRED) -include_directories("${GNUTLS_INCLUDE_DIR}") +include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/avatars/CMakeLists.txt b/libraries/avatars/CMakeLists.txt index fe31eb6a06..c4eff1c45b 100644 --- a/libraries/avatars/CMakeLists.txt +++ b/libraries/avatars/CMakeLists.txt @@ -29,5 +29,5 @@ link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") find_package(GnuTLS REQUIRED) -include_directories("${GNUTLS_INCLUDE_DIR}") +include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/metavoxels/CMakeLists.txt b/libraries/metavoxels/CMakeLists.txt index 4ef9fcc9cb..220cca1f11 100644 --- a/libraries/metavoxels/CMakeLists.txt +++ b/libraries/metavoxels/CMakeLists.txt @@ -28,5 +28,5 @@ include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") find_package(GnuTLS REQUIRED) -include_directories("${GNUTLS_INCLUDE_DIR}") +include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index 101e739fea..56e937e0d7 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -20,5 +20,5 @@ setup_hifi_library(${TARGET_NAME}) include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") -include_directories("${GNUTLS_INCLUDE_DIR}") +include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} Qt5::Network "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/octree/CMakeLists.txt b/libraries/octree/CMakeLists.txt index a4758e52f3..9118ee6215 100644 --- a/libraries/octree/CMakeLists.txt +++ b/libraries/octree/CMakeLists.txt @@ -28,6 +28,6 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") find_package(ZLIB) find_package(GnuTLS REQUIRED) -include_directories("${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/particles/CMakeLists.txt b/libraries/particles/CMakeLists.txt index 4df0859195..2cd5a1644b 100644 --- a/libraries/particles/CMakeLists.txt +++ b/libraries/particles/CMakeLists.txt @@ -29,5 +29,5 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") find_package(ZLIB) find_package(GnuTLS REQUIRED) -include_directories("${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/voxels/CMakeLists.txt b/libraries/voxels/CMakeLists.txt index 68ce7c13aa..c39525e279 100644 --- a/libraries/voxels/CMakeLists.txt +++ b/libraries/voxels/CMakeLists.txt @@ -30,6 +30,6 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") find_package(ZLIB) find_package(GnuTLS REQUIRED) -include_directories("${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" "${GNUTLS_LIBRARY}" Qt5::Widgets Qt5::Script) \ No newline at end of file diff --git a/voxel-edit/CMakeLists.txt b/voxel-edit/CMakeLists.txt index 883b1debe4..0717aea479 100644 --- a/voxel-edit/CMakeLists.txt +++ b/voxel-edit/CMakeLists.txt @@ -36,7 +36,7 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") # link GnuTLS find_package(GnuTLS REQUIRED) -include_directories("${GNUTLS_INCLUDE_DIR}") +include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) From 11cce7640e4d339cf2e7f7b43bd90b20f8b53056 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 10:12:09 -0700 Subject: [PATCH 57/86] link to GnuTLS library from script-engine --- libraries/script-engine/CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/script-engine/CMakeLists.txt b/libraries/script-engine/CMakeLists.txt index 615000e260..f1bdde1b93 100644 --- a/libraries/script-engine/CMakeLists.txt +++ b/libraries/script-engine/CMakeLists.txt @@ -28,6 +28,7 @@ link_hifi_library(particles ${TARGET_NAME} "${ROOT_DIR}") # link ZLIB find_package(ZLIB) -include_directories("${ZLIB_INCLUDE_DIRS}") +find_package(GnuTLS REQUIRED) +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIRS}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" "${GNUTLS_LIBRARY}" Qt5::Widgets) From 4e2e3b7b6d4ab6bafe1f11af73e86dee45e69614 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 10:15:18 -0700 Subject: [PATCH 58/86] fix GnuTLS include dir variable name --- libraries/script-engine/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/script-engine/CMakeLists.txt b/libraries/script-engine/CMakeLists.txt index f1bdde1b93..78f698a7d1 100644 --- a/libraries/script-engine/CMakeLists.txt +++ b/libraries/script-engine/CMakeLists.txt @@ -29,6 +29,6 @@ link_hifi_library(particles ${TARGET_NAME} "${ROOT_DIR}") # link ZLIB find_package(ZLIB) find_package(GnuTLS REQUIRED) -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIRS}") +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" "${GNUTLS_LIBRARY}" Qt5::Widgets) From 2518d314ac8f329b36ce120fb92cd515c1bd948a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 10:19:45 -0700 Subject: [PATCH 59/86] add ssize_t definition for gnutls.h include on Windows --- animation-server/CMakeLists.txt | 5 +++++ assignment-client/CMakeLists.txt | 5 +++++ domain-server/CMakeLists.txt | 5 +++++ interface/CMakeLists.txt | 5 +++++ libraries/audio/CMakeLists.txt | 6 ++++++ libraries/avatars/CMakeLists.txt | 6 ++++++ libraries/metavoxels/CMakeLists.txt | 6 ++++++ libraries/octree/CMakeLists.txt | 5 +++++ libraries/particles/CMakeLists.txt | 6 ++++++ libraries/script-engine/CMakeLists.txt | 5 +++++ libraries/voxels/CMakeLists.txt | 5 +++++ voxel-edit/CMakeLists.txt | 3 +++ 12 files changed, 62 insertions(+) diff --git a/animation-server/CMakeLists.txt b/animation-server/CMakeLists.txt index 80544c103a..5d9f3604bc 100644 --- a/animation-server/CMakeLists.txt +++ b/animation-server/CMakeLists.txt @@ -37,5 +37,10 @@ find_package(GnuTLS REQUIRED) # include the GnuTLS dir include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") +# add a definition for ssize_t so that windows doesn't bail on gnutls.h +if (WIN32) + add_definitions(-Dssize_t=long) +endif () + # link GnuTLS target_link_libraries(${TARGET_NAME} "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index ce2c6b6d4e..d63d09520a 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -37,6 +37,11 @@ link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") find_package(GnuTLS REQUIRED) include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") +# add a definition for ssize_t so that windows doesn't bail on gnutls.h +if (WIN32) + add_definitions(-Dssize_t=long) +endif () + if (UNIX) target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS}) endif (UNIX) diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index 5388d5d8e0..4736c2438b 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -41,6 +41,11 @@ link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") # include the GnuTLS dir include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") +# add a definition for ssize_t so that windows doesn't bail on gnutls.h +if (WIN32) + add_definitions(-Dssize_t=long) +endif () + IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index d435f048ab..d205719c21 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -192,6 +192,11 @@ include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes" # use system flag so warnings are supressed include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") +# add a definition for ssize_t so that windows doesn't bail on gnutls.h +if (WIN32) + add_definitions(-Dssize_t=long) +endif () + target_link_libraries( ${TARGET_NAME} "${FACESHIFT_LIBRARIES}" diff --git a/libraries/audio/CMakeLists.txt b/libraries/audio/CMakeLists.txt index e34dfa65f5..d5cd02f083 100644 --- a/libraries/audio/CMakeLists.txt +++ b/libraries/audio/CMakeLists.txt @@ -26,4 +26,10 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") # link GnuTLS find_package(GnuTLS REQUIRED) include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") + +# add a definition for ssize_t so that windows doesn't bail on gnutls.h +if (WIN32) + add_definitions(-Dssize_t=long) +endif () + target_link_libraries(${TARGET_NAME} "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/avatars/CMakeLists.txt b/libraries/avatars/CMakeLists.txt index c4eff1c45b..8c6b6417a1 100644 --- a/libraries/avatars/CMakeLists.txt +++ b/libraries/avatars/CMakeLists.txt @@ -30,4 +30,10 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") find_package(GnuTLS REQUIRED) include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") + +# add a definition for ssize_t so that windows doesn't bail on gnutls.h +if (WIN32) + add_definitions(-Dssize_t=long) +endif () + target_link_libraries(${TARGET_NAME} Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/metavoxels/CMakeLists.txt b/libraries/metavoxels/CMakeLists.txt index 220cca1f11..6d88006d84 100644 --- a/libraries/metavoxels/CMakeLists.txt +++ b/libraries/metavoxels/CMakeLists.txt @@ -29,4 +29,10 @@ include_glm(${TARGET_NAME} "${ROOT_DIR}") find_package(GnuTLS REQUIRED) include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") + +# add a definition for ssize_t so that windows doesn't bail on gnutls.h +if (WIN32) + add_definitions(-Dssize_t=long) +endif () + target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/octree/CMakeLists.txt b/libraries/octree/CMakeLists.txt index 9118ee6215..0d2cb330b6 100644 --- a/libraries/octree/CMakeLists.txt +++ b/libraries/octree/CMakeLists.txt @@ -30,4 +30,9 @@ find_package(GnuTLS REQUIRED) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") +# add a definition for ssize_t so that windows doesn't bail on gnutls.h +if (WIN32) + add_definitions(-Dssize_t=long) +endif () + target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/particles/CMakeLists.txt b/libraries/particles/CMakeLists.txt index 2cd5a1644b..fa97f87854 100644 --- a/libraries/particles/CMakeLists.txt +++ b/libraries/particles/CMakeLists.txt @@ -30,4 +30,10 @@ find_package(ZLIB) find_package(GnuTLS REQUIRED) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") + +# add a definition for ssize_t so that windows doesn't bail on gnutls.h +if (WIN32) + add_definitions(-Dssize_t=long) +endif () + target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/script-engine/CMakeLists.txt b/libraries/script-engine/CMakeLists.txt index 78f698a7d1..414ac1e9eb 100644 --- a/libraries/script-engine/CMakeLists.txt +++ b/libraries/script-engine/CMakeLists.txt @@ -31,4 +31,9 @@ find_package(ZLIB) find_package(GnuTLS REQUIRED) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") +# add a definition for ssize_t so that windows doesn't bail on gnutls.h +if (WIN32) + add_definitions(-Dssize_t=long) +endif () + target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" "${GNUTLS_LIBRARY}" Qt5::Widgets) diff --git a/libraries/voxels/CMakeLists.txt b/libraries/voxels/CMakeLists.txt index c39525e279..dc13603450 100644 --- a/libraries/voxels/CMakeLists.txt +++ b/libraries/voxels/CMakeLists.txt @@ -32,4 +32,9 @@ find_package(GnuTLS REQUIRED) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") +# add a definition for ssize_t so that windows doesn't bail on gnutls.h +if (WIN32) + add_definitions(-Dssize_t=long) +endif () + target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" "${GNUTLS_LIBRARY}" Qt5::Widgets Qt5::Script) \ No newline at end of file diff --git a/voxel-edit/CMakeLists.txt b/voxel-edit/CMakeLists.txt index 0717aea479..65e82932b2 100644 --- a/voxel-edit/CMakeLists.txt +++ b/voxel-edit/CMakeLists.txt @@ -40,6 +40,9 @@ include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) + + # add a definition for ssize_t so that windows doesn't bail on gnutls.h + add_definitions(-Dssize_t=long) ENDIF(WIN32) target_link_libraries(${TARGET_NAME} Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file From 54647f0f085f34e964ceb485bf959165713e0097 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 10:27:08 -0700 Subject: [PATCH 60/86] make sure gnutls define for ssize_t comes before gnutls include --- assignment-client/CMakeLists.txt | 3 ++- interface/CMakeLists.txt | 8 ++++---- libraries/audio/CMakeLists.txt | 2 +- libraries/avatars/CMakeLists.txt | 3 ++- libraries/metavoxels/CMakeLists.txt | 2 +- libraries/networking/CMakeLists.txt | 5 +++++ libraries/octree/CMakeLists.txt | 4 ++-- libraries/particles/CMakeLists.txt | 3 +-- libraries/script-engine/CMakeLists.txt | 4 ++-- libraries/voxels/CMakeLists.txt | 4 ++-- voxel-edit/CMakeLists.txt | 3 ++- 11 files changed, 24 insertions(+), 17 deletions(-) diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index d63d09520a..a8343e94ad 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -35,13 +35,14 @@ link_hifi_library(script-engine ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") find_package(GnuTLS REQUIRED) -include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") # add a definition for ssize_t so that windows doesn't bail on gnutls.h if (WIN32) add_definitions(-Dssize_t=long) endif () +include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") + if (UNIX) target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS}) endif (UNIX) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index d205719c21..6b1a0e81f9 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -188,15 +188,15 @@ endif (QXMPP_FOUND AND NOT DISABLE_QXMPP) # include headers for interface and InterfaceConfig. include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes") -# include external library headers -# use system flag so warnings are supressed -include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") - # add a definition for ssize_t so that windows doesn't bail on gnutls.h if (WIN32) add_definitions(-Dssize_t=long) endif () +# include external library headers +# use system flag so warnings are supressed +include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") + target_link_libraries( ${TARGET_NAME} "${FACESHIFT_LIBRARIES}" diff --git a/libraries/audio/CMakeLists.txt b/libraries/audio/CMakeLists.txt index d5cd02f083..d946ae5b34 100644 --- a/libraries/audio/CMakeLists.txt +++ b/libraries/audio/CMakeLists.txt @@ -25,11 +25,11 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") # link GnuTLS find_package(GnuTLS REQUIRED) -include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") # add a definition for ssize_t so that windows doesn't bail on gnutls.h if (WIN32) add_definitions(-Dssize_t=long) endif () +include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/avatars/CMakeLists.txt b/libraries/avatars/CMakeLists.txt index 8c6b6417a1..3fa1ebcfe2 100644 --- a/libraries/avatars/CMakeLists.txt +++ b/libraries/avatars/CMakeLists.txt @@ -29,11 +29,12 @@ link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") find_package(GnuTLS REQUIRED) -include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") # add a definition for ssize_t so that windows doesn't bail on gnutls.h if (WIN32) add_definitions(-Dssize_t=long) endif () + +include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/metavoxels/CMakeLists.txt b/libraries/metavoxels/CMakeLists.txt index 6d88006d84..e2a90cb085 100644 --- a/libraries/metavoxels/CMakeLists.txt +++ b/libraries/metavoxels/CMakeLists.txt @@ -28,11 +28,11 @@ include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") find_package(GnuTLS REQUIRED) -include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") # add a definition for ssize_t so that windows doesn't bail on gnutls.h if (WIN32) add_definitions(-Dssize_t=long) endif () +include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index 56e937e0d7..6d805cae6c 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -20,5 +20,10 @@ setup_hifi_library(${TARGET_NAME}) include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") +# add a definition for ssize_t so that windows doesn't bail on gnutls.h +if (WIN32) + add_definitions(-Dssize_t=long) +endif () + include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} Qt5::Network "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/octree/CMakeLists.txt b/libraries/octree/CMakeLists.txt index 0d2cb330b6..88554ed5f8 100644 --- a/libraries/octree/CMakeLists.txt +++ b/libraries/octree/CMakeLists.txt @@ -28,11 +28,11 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") find_package(ZLIB) find_package(GnuTLS REQUIRED) -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") - # add a definition for ssize_t so that windows doesn't bail on gnutls.h if (WIN32) add_definitions(-Dssize_t=long) endif () + +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/particles/CMakeLists.txt b/libraries/particles/CMakeLists.txt index fa97f87854..26d2b7fc26 100644 --- a/libraries/particles/CMakeLists.txt +++ b/libraries/particles/CMakeLists.txt @@ -29,11 +29,10 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") find_package(ZLIB) find_package(GnuTLS REQUIRED) -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") - # add a definition for ssize_t so that windows doesn't bail on gnutls.h if (WIN32) add_definitions(-Dssize_t=long) endif () +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/libraries/script-engine/CMakeLists.txt b/libraries/script-engine/CMakeLists.txt index 414ac1e9eb..20569e2fe0 100644 --- a/libraries/script-engine/CMakeLists.txt +++ b/libraries/script-engine/CMakeLists.txt @@ -29,11 +29,11 @@ link_hifi_library(particles ${TARGET_NAME} "${ROOT_DIR}") # link ZLIB find_package(ZLIB) find_package(GnuTLS REQUIRED) -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") # add a definition for ssize_t so that windows doesn't bail on gnutls.h if (WIN32) add_definitions(-Dssize_t=long) endif () -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" "${GNUTLS_LIBRARY}" Qt5::Widgets) +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" "${GNUTLS_LIBRARY}" Qt5::Widgets) \ No newline at end of file diff --git a/libraries/voxels/CMakeLists.txt b/libraries/voxels/CMakeLists.txt index dc13603450..bdba388594 100644 --- a/libraries/voxels/CMakeLists.txt +++ b/libraries/voxels/CMakeLists.txt @@ -30,11 +30,11 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") find_package(ZLIB) find_package(GnuTLS REQUIRED) -include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") - # add a definition for ssize_t so that windows doesn't bail on gnutls.h if (WIN32) add_definitions(-Dssize_t=long) endif () + +include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${GNUTLS_INCLUDE_DIR}") target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" "${GNUTLS_LIBRARY}" Qt5::Widgets Qt5::Script) \ No newline at end of file diff --git a/voxel-edit/CMakeLists.txt b/voxel-edit/CMakeLists.txt index 65e82932b2..cc0a122bf0 100644 --- a/voxel-edit/CMakeLists.txt +++ b/voxel-edit/CMakeLists.txt @@ -36,7 +36,6 @@ link_hifi_library(networking ${TARGET_NAME} "${ROOT_DIR}") # link GnuTLS find_package(GnuTLS REQUIRED) -include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) @@ -45,4 +44,6 @@ IF (WIN32) add_definitions(-Dssize_t=long) ENDIF(WIN32) +include_directories(SYSTEM "${GNUTLS_INCLUDE_DIR}") + target_link_libraries(${TARGET_NAME} Qt5::Script "${GNUTLS_LIBRARY}") \ No newline at end of file From 7cef2def66e70d68bc30f994e62b52bd03190371 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 10:34:31 -0700 Subject: [PATCH 61/86] remove Syssocket which is from our pre-Qt days --- assignment-client/src/audio/AudioMixer.cpp | 1 - libraries/networking/src/LimitedNodeList.h | 5 ----- libraries/networking/src/Node.cpp | 6 ------ libraries/networking/src/NodeList.h | 5 ----- libraries/networking/src/Syssocket.h | 15 --------------- 5 files changed, 32 deletions(-) delete mode 100644 libraries/networking/src/Syssocket.h diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 779e56af9e..407a64d7a8 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -21,7 +21,6 @@ #include #ifdef _WIN32 -#include "Syssocket.h" #include "Systime.h" #include #else diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 7fc0346a74..f941a8aa5d 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -12,11 +12,6 @@ #ifndef hifi_LimitedNodeList_h #define hifi_LimitedNodeList_h -#ifdef _WIN32 -#include "Syssocket.h" -#else -#include -#endif #include #include diff --git a/libraries/networking/src/Node.cpp b/libraries/networking/src/Node.cpp index f6445de58d..9e6ea0dfec 100644 --- a/libraries/networking/src/Node.cpp +++ b/libraries/networking/src/Node.cpp @@ -12,12 +12,6 @@ #include #include -#ifdef _WIN32 -#include "Syssocket.h" -#else -#include // not available on windows, apparently not needed on mac -#endif - #include "Node.h" #include "SharedUtil.h" diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index 1cc824c294..c55f08e7f0 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -12,11 +12,6 @@ #ifndef hifi_NodeList_h #define hifi_NodeList_h -#ifdef _WIN32 -#include "Syssocket.h" -#else -#include -#endif #include #include diff --git a/libraries/networking/src/Syssocket.h b/libraries/networking/src/Syssocket.h deleted file mode 100644 index 7d7955426f..0000000000 --- a/libraries/networking/src/Syssocket.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __Syssocket__ -#define __Syssocket__ - -#ifdef _WIN32 -#define WINSOCK_API_LINKAGE -#include -typedef SSIZE_T ssize_t; -typedef ULONG32 in_addr_t; -typedef USHORT in_port_t; -typedef USHORT uint16_t; -typedef ULONG32 socklen_t; - -#endif _Win32 - -#endif __Syssocket__ \ No newline at end of file From 8b19982e61754bf72c4b324151794416d754f4e7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 10:36:30 -0700 Subject: [PATCH 62/86] commit missing Syssocket removals to Node and Logging --- libraries/networking/src/Logging.h | 6 ------ libraries/networking/src/Node.h | 6 ------ 2 files changed, 12 deletions(-) diff --git a/libraries/networking/src/Logging.h b/libraries/networking/src/Logging.h index b37962e931..c52812bd33 100644 --- a/libraries/networking/src/Logging.h +++ b/libraries/networking/src/Logging.h @@ -12,12 +12,6 @@ #ifndef hifi_Logging_h #define hifi_Logging_h -#ifdef _WIN32 -#include "Syssocket.h" -#else -#include -#endif - #include const int LOGSTASH_UDP_PORT = 9500; diff --git a/libraries/networking/src/Node.h b/libraries/networking/src/Node.h index 6cc8d5bfaf..3b3237cf6e 100644 --- a/libraries/networking/src/Node.h +++ b/libraries/networking/src/Node.h @@ -15,12 +15,6 @@ #include #include -#ifdef _WIN32 -#include "Syssocket.h" -#else -#include -#endif - #include #include #include From b87c04444ed36fd95bfc4736908ff0477b07480e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 10:41:01 -0700 Subject: [PATCH 63/86] include winsock2 from HifiSockAddr --- libraries/networking/src/HifiSockAddr.cpp | 2 -- libraries/networking/src/HifiSockAddr.h | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/HifiSockAddr.cpp b/libraries/networking/src/HifiSockAddr.cpp index be482cfe02..33f5c0bb70 100644 --- a/libraries/networking/src/HifiSockAddr.cpp +++ b/libraries/networking/src/HifiSockAddr.cpp @@ -9,8 +9,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include - #include #include #include diff --git a/libraries/networking/src/HifiSockAddr.h b/libraries/networking/src/HifiSockAddr.h index 49db336d19..5ecf944aef 100644 --- a/libraries/networking/src/HifiSockAddr.h +++ b/libraries/networking/src/HifiSockAddr.h @@ -12,6 +12,12 @@ #ifndef hifi_HifiSockAddr_h #define hifi_HifiSockAddr_h +#ifdef WIN32 +#include +#else +#include +#endif + #include class HifiSockAddr { From da24483d7c72ea6e32bd3cfd7772198a051e7153 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 10:45:43 -0700 Subject: [PATCH 64/86] include WS2tcpip for socklen_t on windows --- libraries/networking/src/HifiSockAddr.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/networking/src/HifiSockAddr.h b/libraries/networking/src/HifiSockAddr.h index 5ecf944aef..8a591a60b8 100644 --- a/libraries/networking/src/HifiSockAddr.h +++ b/libraries/networking/src/HifiSockAddr.h @@ -14,6 +14,7 @@ #ifdef WIN32 #include +#include #else #include #endif From 186c588d5ae4f11403caf378e09517e39ff3fc01 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 10:48:50 -0700 Subject: [PATCH 65/86] remove doubled timeval definition from SharedUtil --- libraries/shared/src/SharedUtil.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 3569c700ed..cd98fbdbd2 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -15,12 +15,6 @@ #include #include -#ifdef _WIN32 -#ifndef _timeval_ -#define _timeval_ -#endif -#endif - #ifdef __APPLE__ #include #endif From 714db42f873f527525d8049af58168139fbf6935 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 10:51:20 -0700 Subject: [PATCH 66/86] include QNetworkConfigManager to fix HifiSockAddr error on windows --- libraries/networking/src/HifiSockAddr.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/networking/src/HifiSockAddr.cpp b/libraries/networking/src/HifiSockAddr.cpp index 33f5c0bb70..240d02631e 100644 --- a/libraries/networking/src/HifiSockAddr.cpp +++ b/libraries/networking/src/HifiSockAddr.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include "HifiSockAddr.h" From ad0776be4e2d7b833a70d7a1d70a403367dde80b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 10:55:02 -0700 Subject: [PATCH 67/86] repair QNetworkConfigurationManager include --- libraries/networking/src/HifiSockAddr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/HifiSockAddr.cpp b/libraries/networking/src/HifiSockAddr.cpp index 240d02631e..1e1b13ff9a 100644 --- a/libraries/networking/src/HifiSockAddr.cpp +++ b/libraries/networking/src/HifiSockAddr.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include "HifiSockAddr.h" From 52203bd36e879181480ab5792fbbdcb2ae54912c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 10:58:20 -0700 Subject: [PATCH 68/86] another attempt to repair QNetworkInterface call on windows --- libraries/networking/src/HifiSockAddr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/HifiSockAddr.cpp b/libraries/networking/src/HifiSockAddr.cpp index 1e1b13ff9a..5e8293e629 100644 --- a/libraries/networking/src/HifiSockAddr.cpp +++ b/libraries/networking/src/HifiSockAddr.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include "HifiSockAddr.h" From 7d4399da3507fb6bd59c13dec7c7dbbfe436e000 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 11:01:17 -0700 Subject: [PATCH 69/86] don't use reserved word causing issues on windows --- libraries/networking/src/HifiSockAddr.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libraries/networking/src/HifiSockAddr.cpp b/libraries/networking/src/HifiSockAddr.cpp index 5e8293e629..d30f7944d7 100644 --- a/libraries/networking/src/HifiSockAddr.cpp +++ b/libraries/networking/src/HifiSockAddr.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include "HifiSockAddr.h" @@ -96,13 +95,13 @@ quint32 getHostOrderLocalAddress() { static int localAddress = 0; if (localAddress == 0) { - foreach(const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) { - if (interface.flags() & QNetworkInterface::IsUp - && interface.flags() & QNetworkInterface::IsRunning - && interface.flags() & ~QNetworkInterface::IsLoopBack) { + foreach(const QNetworkInterface &networkInterface, QNetworkInterface::allInterfaces()) { + if (networkInterface.flags() & QNetworkInterface::IsUp + && networkInterface.flags() & QNetworkInterface::IsRunning + && networkInterface.flags() & ~QNetworkInterface::IsLoopBack) { // we've decided that this is the active NIC // enumerate it's addresses to grab the IPv4 address - foreach(const QNetworkAddressEntry &entry, interface.addressEntries()) { + foreach(const QNetworkAddressEntry &entry, networkInterface.addressEntries()) { // make sure it's an IPv4 address that isn't the loopback if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol && !entry.ip().isLoopback()) { qDebug("Node's local address is %s", entry.ip().toString().toLocal8Bit().constData()); From 53aafd689707299f18f51e7f4c8c7c3102ffefa0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 11:06:22 -0700 Subject: [PATCH 70/86] rely on winsock2 for timeval declaration --- libraries/shared/src/Systime.cpp | 5 ++--- libraries/shared/src/Systime.h | 26 ++------------------------ 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/libraries/shared/src/Systime.cpp b/libraries/shared/src/Systime.cpp index 7d8764e3f9..505703a7ee 100644 --- a/libraries/shared/src/Systime.cpp +++ b/libraries/shared/src/Systime.cpp @@ -1,14 +1,13 @@ #ifdef _WIN32 #include -#define _timeval_ #include "Systime.h" - int gettimeofday( timeval* p_tv, timezone* p_tz ) - { + int gettimeofday(timeval* p_tv, timezone* p_tz) { int tt = timeGetTime(); p_tv->tv_sec = tt / 1000; p_tv->tv_usec = tt % 1000 * 1000; return 0; } + #endif diff --git a/libraries/shared/src/Systime.h b/libraries/shared/src/Systime.h index 1d25de0b80..5d96b53e7a 100644 --- a/libraries/shared/src/Systime.h +++ b/libraries/shared/src/Systime.h @@ -1,38 +1,16 @@ #ifndef __Systime__ #define __Systime__ - #ifdef _WIN32 -#ifdef _WINSOCK2API_ -#define _timeval_ -#endif - -#ifndef _timeval_ -#define _timeval_ -/* - * Structure returned by gettimeofday(2) system call, - * and used in other calls. - */ - -// this is a bit of a hack for now, but sometimes on windows -// we need timeval defined here, sometimes we get it -// from winsock.h -#ifdef WANT_TIMEVAL -struct timeval { - long tv_sec; /* seconds */ - long tv_usec; /* and microseconds */ -}; -#endif - -#endif _timeval_ +#include struct timezone { int tz_minuteswest; /* minutes west of Greenwich */ int tz_dsttime; /* type of dst correction */ }; -int gettimeofday( struct timeval* p_tv, struct timezone* p_tz ); +int gettimeofday(struct timeval* p_tv, struct timezone* p_tz); #endif _Win32 From ef418f09b3648afeb10c55b183ead157b0befdfd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 11:15:33 -0700 Subject: [PATCH 71/86] don't let windows.h include winsock --- interface/src/Audio.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index a98d276acc..a29f5aaa6e 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -20,6 +20,7 @@ #ifdef WIN32 #define WIN32_LEAN_AND_MEAN +#define _WINSOCKAPI_ #include #include #include From 7c9e0927abda212a21f6003f1fc4d400b086314c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 11:17:03 -0700 Subject: [PATCH 72/86] define WIN32_LEAN_AND_MEAN before include windows.h in Systime --- interface/src/Audio.cpp | 1 - libraries/shared/src/Systime.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index a29f5aaa6e..a98d276acc 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -20,7 +20,6 @@ #ifdef WIN32 #define WIN32_LEAN_AND_MEAN -#define _WINSOCKAPI_ #include #include #include diff --git a/libraries/shared/src/Systime.cpp b/libraries/shared/src/Systime.cpp index 505703a7ee..1fc6778dad 100644 --- a/libraries/shared/src/Systime.cpp +++ b/libraries/shared/src/Systime.cpp @@ -1,4 +1,5 @@ #ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN #include #include "Systime.h" From 3651eff3d631658b8fcdb30b9d63e0acb66a1204 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 11:24:54 -0700 Subject: [PATCH 73/86] cleanup Systime to gettimeofday without lean and mean windows --- interface/src/Audio.h | 1 - interface/src/starfield/Controller.cpp | 1 - interface/src/starfield/Generator.cpp | 1 - interface/src/ui/BandwidthMeter.h | 1 - libraries/shared/src/Systime.cpp | 62 +++++++++++++++++++++----- libraries/shared/src/Systime.h | 23 +++++----- 6 files changed, 63 insertions(+), 26 deletions(-) diff --git a/interface/src/Audio.h b/interface/src/Audio.h index c529fc2651..a0c7398328 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -13,7 +13,6 @@ #define hifi_Audio_h #ifdef _WIN32 -#define WANT_TIMEVAL #include #endif diff --git a/interface/src/starfield/Controller.cpp b/interface/src/starfield/Controller.cpp index b50c393f00..771029c689 100755 --- a/interface/src/starfield/Controller.cpp +++ b/interface/src/starfield/Controller.cpp @@ -10,7 +10,6 @@ // #ifdef _WIN32 -#define WANT_TIMEVAL #include #endif diff --git a/interface/src/starfield/Generator.cpp b/interface/src/starfield/Generator.cpp index 15d1736e4e..b18e1834be 100644 --- a/interface/src/starfield/Generator.cpp +++ b/interface/src/starfield/Generator.cpp @@ -10,7 +10,6 @@ // #ifdef _WIN32 -#define WANT_TIMEVAL #include #endif diff --git a/interface/src/ui/BandwidthMeter.h b/interface/src/ui/BandwidthMeter.h index 45226c8e82..6838f28c70 100644 --- a/interface/src/ui/BandwidthMeter.h +++ b/interface/src/ui/BandwidthMeter.h @@ -13,7 +13,6 @@ #define hifi_BandwidthMeter_h #ifdef _WIN32 -#define WANT_TIMEVAL #include #endif diff --git a/libraries/shared/src/Systime.cpp b/libraries/shared/src/Systime.cpp index 1fc6778dad..a63336f777 100644 --- a/libraries/shared/src/Systime.cpp +++ b/libraries/shared/src/Systime.cpp @@ -1,14 +1,56 @@ -#ifdef _WIN32 +// +// Systime.cpp +// libraries/shared/src +// +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +/** + * gettimeofday + * Implementation according to: + * The Open Group Base Specifications Issue 6 + * IEEE Std 1003.1, 2004 Edition + */ + +/** + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Contributed by: + * Danny Smith + */ + +#include #define WIN32_LEAN_AND_MEAN #include -#include "Systime.h" - int gettimeofday(timeval* p_tv, timezone* p_tz) { - int tt = timeGetTime(); +/** Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ +#define _W32_FT_OFFSET (116444736000000000ULL) - p_tv->tv_sec = tt / 1000; - p_tv->tv_usec = tt % 1000 * 1000; - return 0; - } - -#endif +int __cdecl gettimeofday(struct timeval *__restrict__ tp, + void *__restrict__ tzp __attribute__((unused))) { + union { + unsigned long long ns100; /**time since 1 Jan 1601 in 100ns units */ + FILETIME ft; + } _now; + + if (tp) { + GetSystemTimeAsFileTime (&_now.ft); + tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL ); + tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL); + } + + /** Always return 0 as per Open Group Base Specifications Issue 6. + Do not set errno on error. */ + return 0; +} \ No newline at end of file diff --git a/libraries/shared/src/Systime.h b/libraries/shared/src/Systime.h index 5d96b53e7a..07d467e63d 100644 --- a/libraries/shared/src/Systime.h +++ b/libraries/shared/src/Systime.h @@ -1,17 +1,16 @@ +// +// Systime.h +// libraries/shared/src +// +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + #ifndef __Systime__ #define __Systime__ -#ifdef _WIN32 - #include -struct timezone { - int tz_minuteswest; /* minutes west of Greenwich */ - int tz_dsttime; /* type of dst correction */ -}; - -int gettimeofday(struct timeval* p_tv, struct timezone* p_tz); - -#endif _Win32 - -#endif __Systime__ +#endif __Systime__ \ No newline at end of file From 1daaf561de524f06d3aecb2af1fd171f364c5686 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 11:26:47 -0700 Subject: [PATCH 74/86] don't include missing sys/time, declare gettimeofday in Systime header --- libraries/shared/src/Systime.cpp | 1 - libraries/shared/src/Systime.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/Systime.cpp b/libraries/shared/src/Systime.cpp index a63336f777..157dc99990 100644 --- a/libraries/shared/src/Systime.cpp +++ b/libraries/shared/src/Systime.cpp @@ -30,7 +30,6 @@ * Danny Smith */ -#include #define WIN32_LEAN_AND_MEAN #include diff --git a/libraries/shared/src/Systime.h b/libraries/shared/src/Systime.h index 07d467e63d..6197c46c02 100644 --- a/libraries/shared/src/Systime.h +++ b/libraries/shared/src/Systime.h @@ -13,4 +13,6 @@ #include +int __cdecl gettimeofday(struct timeval *__restrict__, void *__restrict__); + #endif __Systime__ \ No newline at end of file From 885cee28c5007b9c5adddeb42f5dd02daec553b7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 11:28:22 -0700 Subject: [PATCH 75/86] guard Systime against being included on UNIX/OS X --- libraries/shared/src/Systime.cpp | 6 +++++- libraries/shared/src/Systime.h | 10 +++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/libraries/shared/src/Systime.cpp b/libraries/shared/src/Systime.cpp index 157dc99990..eab02ce2ab 100644 --- a/libraries/shared/src/Systime.cpp +++ b/libraries/shared/src/Systime.cpp @@ -8,6 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#ifdef WIN32 + /** * gettimeofday * Implementation according to: @@ -52,4 +54,6 @@ int __cdecl gettimeofday(struct timeval *__restrict__ tp, /** Always return 0 as per Open Group Base Specifications Issue 6. Do not set errno on error. */ return 0; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/libraries/shared/src/Systime.h b/libraries/shared/src/Systime.h index 6197c46c02..d8b1dc9f77 100644 --- a/libraries/shared/src/Systime.h +++ b/libraries/shared/src/Systime.h @@ -8,11 +8,15 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef __Systime__ -#define __Systime__ +#ifndef hifi_Systime_h +#define hifi_Systime_h + +#ifdef WIN32 #include int __cdecl gettimeofday(struct timeval *__restrict__, void *__restrict__); -#endif __Systime__ \ No newline at end of file +#endif + +#endif // hifi_Systime_h \ No newline at end of file From ea8f0df17d4f3820193c0b1d9b32c4da8b47d6af Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 11:30:20 -0700 Subject: [PATCH 76/86] use extern C in Systime header --- libraries/shared/src/Systime.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/shared/src/Systime.h b/libraries/shared/src/Systime.h index d8b1dc9f77..b6eaa70cab 100644 --- a/libraries/shared/src/Systime.h +++ b/libraries/shared/src/Systime.h @@ -15,8 +15,12 @@ #include +extern "C" { + int __cdecl gettimeofday(struct timeval *__restrict__, void *__restrict__); +} + #endif #endif // hifi_Systime_h \ No newline at end of file From 00a826330e9988afeab2c602a95973832f9f9c57 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 11:34:43 -0700 Subject: [PATCH 77/86] use GetSystemTimeAsFileTime with previous gettimeofday setup --- libraries/shared/src/Systime.cpp | 12 ++++++------ libraries/shared/src/Systime.h | 9 +++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/libraries/shared/src/Systime.cpp b/libraries/shared/src/Systime.cpp index eab02ce2ab..0b2d782bbf 100644 --- a/libraries/shared/src/Systime.cpp +++ b/libraries/shared/src/Systime.cpp @@ -38,21 +38,21 @@ /** Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ #define _W32_FT_OFFSET (116444736000000000ULL) -int __cdecl gettimeofday(struct timeval *__restrict__ tp, - void *__restrict__ tzp __attribute__((unused))) { +int gettimeofday(timeval* p_tv, timezone* p_tz) { + union { unsigned long long ns100; /**time since 1 Jan 1601 in 100ns units */ FILETIME ft; } _now; - if (tp) { + if (p_tv) { GetSystemTimeAsFileTime (&_now.ft); - tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL ); - tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL); + p_tv->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL ); + p_tv->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL); } /** Always return 0 as per Open Group Base Specifications Issue 6. - Do not set errno on error. */ + Do not set errno on error. */ return 0; } diff --git a/libraries/shared/src/Systime.h b/libraries/shared/src/Systime.h index b6eaa70cab..3098f09ecd 100644 --- a/libraries/shared/src/Systime.h +++ b/libraries/shared/src/Systime.h @@ -15,11 +15,12 @@ #include -extern "C" { +struct timezone { + int tz_minuteswest; /* minutes west of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; -int __cdecl gettimeofday(struct timeval *__restrict__, void *__restrict__); - -} +int gettimeofday(struct timeval* p_tv, struct timezone* p_tz); #endif From cfc2431a59638ee1cda339c2e79c7ab5977be21c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 11:37:09 -0700 Subject: [PATCH 78/86] don't be a dummy and include Systime header from implementation --- libraries/shared/src/Systime.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/shared/src/Systime.cpp b/libraries/shared/src/Systime.cpp index 0b2d782bbf..ab32821a0f 100644 --- a/libraries/shared/src/Systime.cpp +++ b/libraries/shared/src/Systime.cpp @@ -10,6 +10,8 @@ #ifdef WIN32 +#include "Systime.h" + /** * gettimeofday * Implementation according to: From 2c96ce08aebcb24a213d35164808d46d01e30aa1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 11:50:26 -0700 Subject: [PATCH 79/86] add stackoverflow fix for lnk2001 error in gnutls_free --- libraries/networking/src/DTLSClientSession.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/DTLSClientSession.cpp b/libraries/networking/src/DTLSClientSession.cpp index b17de8e168..51151a7d36 100644 --- a/libraries/networking/src/DTLSClientSession.cpp +++ b/libraries/networking/src/DTLSClientSession.cpp @@ -33,6 +33,17 @@ void DTLSClientSession::globalDeinit() { gnutls_global_deinit(); } +// fix for lnk2001 link error on windows +// call xgnutls_free instead of gnutls_free +// http://stackoverflow.com/questions/14593949/getting-error-lnk2001-unresolved-external-symbol-gnutls-free-when-using-gnut + +typedef void (*gnutls_free_function) (void *); +__declspec(dllimport) extern gnutls_free_function gnutls_free; + +void xgnutls_free(void* p){ + gnutls_free(p); +} + int DTLSClientSession::verifyServerCertificate(gnutls_session_t session) { unsigned int verifyStatus = 0; @@ -60,7 +71,7 @@ int DTLSClientSession::verifyServerCertificate(gnutls_session_t session) { } qDebug() << "Gnutls certificate verification status:" << reinterpret_cast(printOut.data); - gnutls_free(printOut.data); + xgnutls_free(printOut.data); if (verifyStatus != 0) { qDebug() << "Server provided certificate for DTLS is not trusted. Can not complete handshake."; From 97444eac1c5457e9fbe7190c5d89f8e68f1f1310 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 12:11:37 -0700 Subject: [PATCH 80/86] put gnutls_free fix in DTLSSession header --- libraries/networking/src/DTLSClientSession.cpp | 12 ------------ libraries/networking/src/DTLSSession.h | 13 +++++++++++++ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/libraries/networking/src/DTLSClientSession.cpp b/libraries/networking/src/DTLSClientSession.cpp index 51151a7d36..14de3dfb0c 100644 --- a/libraries/networking/src/DTLSClientSession.cpp +++ b/libraries/networking/src/DTLSClientSession.cpp @@ -33,17 +33,6 @@ void DTLSClientSession::globalDeinit() { gnutls_global_deinit(); } -// fix for lnk2001 link error on windows -// call xgnutls_free instead of gnutls_free -// http://stackoverflow.com/questions/14593949/getting-error-lnk2001-unresolved-external-symbol-gnutls-free-when-using-gnut - -typedef void (*gnutls_free_function) (void *); -__declspec(dllimport) extern gnutls_free_function gnutls_free; - -void xgnutls_free(void* p){ - gnutls_free(p); -} - int DTLSClientSession::verifyServerCertificate(gnutls_session_t session) { unsigned int verifyStatus = 0; @@ -63,7 +52,6 @@ int DTLSClientSession::verifyServerCertificate(gnutls_session_t session) { gnutls_datum_t printOut; - certReturn = gnutls_certificate_verification_status_print(verifyStatus, typeReturn, &printOut, 0); if (certReturn < 0) { diff --git a/libraries/networking/src/DTLSSession.h b/libraries/networking/src/DTLSSession.h index 9e9542e147..e379e20a2d 100644 --- a/libraries/networking/src/DTLSSession.h +++ b/libraries/networking/src/DTLSSession.h @@ -19,6 +19,19 @@ #include "DummyDTLSSession.h" #include "HifiSockAddr.h" +// fix for lnk2001 link error on windows +// call xgnutls_free instead of gnutls_free +// http://stackoverflow.com/questions/14593949/getting-error-lnk2001-unresolved-external-symbol-gnutls-free-when-using-gnut + +#ifdef WIN32 +typedef void (*gnutls_free_function) (void *); +__declspec(dllimport) extern gnutls_free_function gnutls_free; +#endif + +void xgnutls_free(void* gnutlsPtr){ + gnutls_free(gnutlsPtr); +} + class DTLSSession : public DummyDTLSSession { Q_OBJECT public: From 38867a2f099b8cf35bfdf8de7507524d8ec1222c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 12:14:37 -0700 Subject: [PATCH 81/86] fix for re-declarations of xgnutls_free --- libraries/networking/src/DTLSSession.cpp | 4 ++++ libraries/networking/src/DTLSSession.h | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/DTLSSession.cpp b/libraries/networking/src/DTLSSession.cpp index 7d375ec327..addfd7b09a 100644 --- a/libraries/networking/src/DTLSSession.cpp +++ b/libraries/networking/src/DTLSSession.cpp @@ -14,6 +14,10 @@ #include "NodeList.h" #include "DTLSSession.h" +void xgnutls_free(void* gnutlsPtr){ + gnutls_free(gnutlsPtr); +} + int DTLSSession::socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms) { DTLSSession* session = static_cast(ptr); QUdpSocket& dtlsSocket = session->_dtlsSocket; diff --git a/libraries/networking/src/DTLSSession.h b/libraries/networking/src/DTLSSession.h index e379e20a2d..0db791c8f8 100644 --- a/libraries/networking/src/DTLSSession.h +++ b/libraries/networking/src/DTLSSession.h @@ -28,9 +28,7 @@ typedef void (*gnutls_free_function) (void *); __declspec(dllimport) extern gnutls_free_function gnutls_free; #endif -void xgnutls_free(void* gnutlsPtr){ - gnutls_free(gnutlsPtr); -} +void xgnutls_free(void* gnutlsPtr); class DTLSSession : public DummyDTLSSession { Q_OBJECT From 9912c4c9a7af818bc5df08245dd74357b399af97 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 12:24:41 -0700 Subject: [PATCH 82/86] just call free instead of gnutls_free on windows --- libraries/networking/src/DTLSClientSession.cpp | 7 ++++++- libraries/networking/src/DTLSSession.cpp | 4 ---- libraries/networking/src/DTLSSession.h | 11 ----------- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/libraries/networking/src/DTLSClientSession.cpp b/libraries/networking/src/DTLSClientSession.cpp index 14de3dfb0c..367f162cbe 100644 --- a/libraries/networking/src/DTLSClientSession.cpp +++ b/libraries/networking/src/DTLSClientSession.cpp @@ -59,7 +59,12 @@ int DTLSClientSession::verifyServerCertificate(gnutls_session_t session) { } qDebug() << "Gnutls certificate verification status:" << reinterpret_cast(printOut.data); - xgnutls_free(printOut.data); + +#ifdef WIN32 + free(printOut.data) +#else + gnutls_free(printOut.data); +#endif if (verifyStatus != 0) { qDebug() << "Server provided certificate for DTLS is not trusted. Can not complete handshake."; diff --git a/libraries/networking/src/DTLSSession.cpp b/libraries/networking/src/DTLSSession.cpp index addfd7b09a..7d375ec327 100644 --- a/libraries/networking/src/DTLSSession.cpp +++ b/libraries/networking/src/DTLSSession.cpp @@ -14,10 +14,6 @@ #include "NodeList.h" #include "DTLSSession.h" -void xgnutls_free(void* gnutlsPtr){ - gnutls_free(gnutlsPtr); -} - int DTLSSession::socketPullTimeout(gnutls_transport_ptr_t ptr, unsigned int ms) { DTLSSession* session = static_cast(ptr); QUdpSocket& dtlsSocket = session->_dtlsSocket; diff --git a/libraries/networking/src/DTLSSession.h b/libraries/networking/src/DTLSSession.h index 0db791c8f8..9e9542e147 100644 --- a/libraries/networking/src/DTLSSession.h +++ b/libraries/networking/src/DTLSSession.h @@ -19,17 +19,6 @@ #include "DummyDTLSSession.h" #include "HifiSockAddr.h" -// fix for lnk2001 link error on windows -// call xgnutls_free instead of gnutls_free -// http://stackoverflow.com/questions/14593949/getting-error-lnk2001-unresolved-external-symbol-gnutls-free-when-using-gnut - -#ifdef WIN32 -typedef void (*gnutls_free_function) (void *); -__declspec(dllimport) extern gnutls_free_function gnutls_free; -#endif - -void xgnutls_free(void* gnutlsPtr); - class DTLSSession : public DummyDTLSSession { Q_OBJECT public: From 86b0b786925235f03d3149d70f788d297bd97a28 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 12:27:52 -0700 Subject: [PATCH 83/86] add a missing semi-colon for windows build --- libraries/networking/src/DTLSClientSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/DTLSClientSession.cpp b/libraries/networking/src/DTLSClientSession.cpp index 367f162cbe..72384fbd10 100644 --- a/libraries/networking/src/DTLSClientSession.cpp +++ b/libraries/networking/src/DTLSClientSession.cpp @@ -61,7 +61,7 @@ int DTLSClientSession::verifyServerCertificate(gnutls_session_t session) { qDebug() << "Gnutls certificate verification status:" << reinterpret_cast(printOut.data); #ifdef WIN32 - free(printOut.data) + free(printOut.data); #else gnutls_free(printOut.data); #endif From 9fcb656027458de398910f281a0a3dcafc76bec8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 11 Apr 2014 09:26:45 -0700 Subject: [PATCH 84/86] add a newline to FindGnuTLS and fix filename in header --- cmake/modules/FindGnuTLS.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindGnuTLS.cmake b/cmake/modules/FindGnuTLS.cmake index 724dcbe171..0e1899864b 100644 --- a/cmake/modules/FindGnuTLS.cmake +++ b/cmake/modules/FindGnuTLS.cmake @@ -1,5 +1,5 @@ # -# FindFaceshift.cmake +# FindGnuTLS.cmake # # Try to find the GnuTLS library # @@ -38,4 +38,4 @@ else () message(STATUS "the GnuTLS lib folder. Replace $GnuTLS-DIR in the command with the directory") message(STATUS "containing GnuTLS.") endif () -endif () \ No newline at end of file +endif () From 6431d35f86778ea23bfd7fe6ff11cf0bc187ccf5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 11 Apr 2014 10:19:31 -0700 Subject: [PATCH 85/86] add a missing newline to DomainHandler --- libraries/networking/src/DomainHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 9a18feb1ed..2cc520991c 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -79,4 +79,4 @@ private: QTimer* _handshakeTimer; }; -#endif // hifi_DomainHandler_h \ No newline at end of file +#endif // hifi_DomainHandler_h From 1cd5fec71cc628ec6ea90007204bbed61239d4d5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 11 Apr 2014 11:42:33 -0700 Subject: [PATCH 86/86] push packet version for assignments --- libraries/networking/src/PacketHeaders.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp index fe999fed96..fdbdca3db7 100644 --- a/libraries/networking/src/PacketHeaders.cpp +++ b/libraries/networking/src/PacketHeaders.cpp @@ -58,7 +58,7 @@ PacketVersion versionForPacketType(PacketType type) { return 2; case PacketTypeCreateAssignment: case PacketTypeRequestAssignment: - return 1; + return 2; case PacketTypeVoxelSet: case PacketTypeVoxelSetDestructive: return 1;