From 89aeb034d1057d1c0b0e52622917d4bc89062b73 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 28 Mar 2014 15:22:44 -0700 Subject: [PATCH 001/110] 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 002/110] 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 003/110] 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 004/110] 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 005/110] 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 006/110] 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 007/110] 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 008/110] 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 009/110] 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 010/110] 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 011/110] 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 012/110] 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 013/110] 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 014/110] 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 015/110] 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 016/110] 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 017/110] 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 018/110] 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 019/110] 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 020/110] 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 021/110] 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 022/110] 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 023/110] 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 024/110] 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 025/110] 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 026/110] 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 027/110] 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 028/110] 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 029/110] 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 030/110] 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 031/110] 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 032/110] 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 033/110] 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 034/110] 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 035/110] 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 036/110] 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 037/110] 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 038/110] 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 039/110] 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 040/110] 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 041/110] 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 042/110] 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 043/110] 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 044/110] 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 045/110] 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 046/110] 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 047/110] 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 048/110] 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 049/110] 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 050/110] 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 051/110] 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 052/110] 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 053/110] 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 054/110] 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 055/110] 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 056/110] 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 057/110] 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 058/110] 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 059/110] 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 060/110] 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 061/110] 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 062/110] 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 063/110] 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 064/110] 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 065/110] 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 066/110] 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 067/110] 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 068/110] 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 069/110] 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 070/110] 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 071/110] 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 072/110] 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 073/110] 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 074/110] 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 075/110] 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 076/110] 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 077/110] 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 078/110] 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 5099a0e06126edce98b7df50cd8b2fdcee2af76a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 10 Apr 2014 11:41:10 -0700 Subject: [PATCH 079/110] Remove chat window opening animation --- interface/src/Menu.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 70e69597f6..ba3ea45229 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1212,12 +1212,6 @@ void Menu::showChat() { _chatWindow->resize(0, _chatWindow->height()); _chatWindow->toggleViewAction()->trigger(); - QPropertyAnimation* slideAnimation = new QPropertyAnimation(_chatWindow, "geometry", _chatWindow); - slideAnimation->setStartValue(_chatWindow->geometry()); - slideAnimation->setEndValue(QRect(mainWindow->width() - width, _chatWindow->y(), - width, _chatWindow->height())); - slideAnimation->setDuration(250); - slideAnimation->start(QAbstractAnimation::DeleteWhenStopped); } } From 2d481dda4e4d5ff345dcec0cda9cbc56515ce342 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 10 Apr 2014 11:46:28 -0700 Subject: [PATCH 080/110] Update chat menu to properly position itself when opening The previous implementation seemed to assume a full-screen main window - it will now open on the right side of the window, vertically centered, regardless of where the main window is. --- interface/src/Menu.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index ba3ea45229..7b67aadfba 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1206,12 +1206,12 @@ void Menu::showChat() { mainWindow->addDockWidget(Qt::NoDockWidgetArea, _chatWindow = new ChatWindow()); } if (!_chatWindow->toggleViewAction()->isChecked()) { - int width = _chatWindow->width(); - int y = qMax((mainWindow->height() - _chatWindow->height()) / 2, 0); - _chatWindow->move(mainWindow->width(), y); + const QRect& windowGeometry = mainWindow->geometry(); + _chatWindow->move(windowGeometry.topRight().x() - _chatWindow->width(), + windowGeometry.topRight().y() + (windowGeometry.height() / 2) - (_chatWindow->height() / 2)); + _chatWindow->resize(0, _chatWindow->height()); _chatWindow->toggleViewAction()->trigger(); - } } From 2c96ce08aebcb24a213d35164808d46d01e30aa1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 11:50:26 -0700 Subject: [PATCH 081/110] 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 ff3ebd1eda1e8a69210be650df3c87b35c83a7e6 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 10 Apr 2014 12:04:30 -0700 Subject: [PATCH 082/110] Fix centering of timestamp in chat window --- interface/src/ui/ChatWindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index 0060cb839c..63f76295bd 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -155,6 +155,8 @@ void ChatWindow::addTimeStamp() { timeLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); timeLabel->setAlignment(Qt::AlignHCenter); ui->messagesGridLayout->addWidget(timeLabel, ui->messagesGridLayout->rowCount(), 0, 1, 2); + ui->messagesGridLayout->parentWidget()->updateGeometry(); + numMessagesAfterLastTimeStamp = 0; } } From 37f9f47488a4ef48c27c930cc43354c5b659fdba Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 10 Apr 2014 12:09:06 -0700 Subject: [PATCH 083/110] Fix odd resizing of chat messages When calling updateGeometry on the message labels the layout system seems to resize the widgets in weird ways. There may be a different way to keep it from doing this. --- interface/src/ui/ChatWindow.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index 63f76295bd..1230140fc8 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -251,7 +251,6 @@ void ChatWindow::messageReceived(const QXmppMessage& message) { Application::processEvents(); QScrollBar* verticalScrollBar = ui->messagesScrollArea->verticalScrollBar(); verticalScrollBar->setSliderPosition(verticalScrollBar->maximum()); - messageLabel->updateGeometry(); ++numMessagesAfterLastTimeStamp; if (message.stamp().isValid()) { From 97444eac1c5457e9fbe7190c5d89f8e68f1f1310 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 12:11:37 -0700 Subject: [PATCH 084/110] 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 085/110] 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 de475ee46cafd67d4ffea57e680d81309445b020 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 10 Apr 2014 12:19:27 -0700 Subject: [PATCH 086/110] Update behavior of chat window close button Use a stylesheet to suppress highlighting of the background when pressing the button down. Instead, it will change the image. Unfortunately I wasn't able to find a way to do this without requiring an extra image, or by doing it through the icon system. The different icon states didn't seem to take effect for button presses, and using opacity in the stylesheet doesn't work yet for `QPushButton`s. --- interface/resources/images/close_down.svg | 79 +++++++++++++++++++++++ interface/resources/resources.qrc | 13 ++-- interface/ui/chatWindow.ui | 18 ++++-- 3 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 interface/resources/images/close_down.svg diff --git a/interface/resources/images/close_down.svg b/interface/resources/images/close_down.svg new file mode 100644 index 0000000000..f36865fff1 --- /dev/null +++ b/interface/resources/images/close_down.svg @@ -0,0 +1,79 @@ + + + + + + image/svg+xml + + Slice 1 + + + + + Slice 1 + Created with Sketch (http://www.bohemiancoding.com/sketch) + + + + + + + + diff --git a/interface/resources/resources.qrc b/interface/resources/resources.qrc index 35c0e40270..bc41f41784 100644 --- a/interface/resources/resources.qrc +++ b/interface/resources/resources.qrc @@ -1,8 +1,9 @@ - - images/close.svg - images/kill-script.svg - images/reload.svg - images/stop.svg - + + images/close_down.svg + images/close.svg + images/kill-script.svg + images/reload.svg + images/stop.svg + diff --git a/interface/ui/chatWindow.ui b/interface/ui/chatWindow.ui index 60a0c6badd..095a2ba8f9 100644 --- a/interface/ui/chatWindow.ui +++ b/interface/ui/chatWindow.ui @@ -96,13 +96,23 @@ Qt::NoFocus + + QPushButton { + background-color: rgba( 0, 0, 0, 0% ); + border: none; + image: url(:images/close.svg) +} + + +QPushButton:pressed { + background-color: rgba( 0, 0, 0, 0% ); + border: none; + image: url(:images/close_down.svg) +} + - - - :/images/close.svg:/images/close.svg - true From 9912c4c9a7af818bc5df08245dd74357b399af97 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Apr 2014 12:24:41 -0700 Subject: [PATCH 087/110] 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 088/110] 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 16a2367b294b28284db382a60671a63df1af1b6f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 10 Apr 2014 12:34:45 -0700 Subject: [PATCH 089/110] Update chat window to only scroll when at the bottom It can be frustrating when scrolling up to read a message to have the window forcibly scrolled to the bottom when a new message appears. --- interface/src/ui/ChatWindow.cpp | 28 ++++++++++++++++++++++++++-- interface/src/ui/ChatWindow.h | 2 ++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index 1230140fc8..c164ea3fb3 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -154,10 +154,18 @@ void ChatWindow::addTimeStamp() { "padding: 4px;"); timeLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); timeLabel->setAlignment(Qt::AlignHCenter); + + bool atBottom = isAtBottom(); + ui->messagesGridLayout->addWidget(timeLabel, ui->messagesGridLayout->rowCount(), 0, 1, 2); ui->messagesGridLayout->parentWidget()->updateGeometry(); + Application::processEvents(); numMessagesAfterLastTimeStamp = 0; + + if (atBottom) { + scrollToBottom(); + } } } @@ -245,12 +253,15 @@ void ChatWindow::messageReceived(const QXmppMessage& message) { messageLabel->setStyleSheet(messageLabel->styleSheet() + "; background-color: #e1e8ea"); } + bool atBottom = isAtBottom(); ui->messagesGridLayout->addWidget(userLabel, ui->messagesGridLayout->rowCount(), 0); ui->messagesGridLayout->addWidget(messageLabel, ui->messagesGridLayout->rowCount() - 1, 1); ui->messagesGridLayout->parentWidget()->updateGeometry(); Application::processEvents(); - QScrollBar* verticalScrollBar = ui->messagesScrollArea->verticalScrollBar(); - verticalScrollBar->setSliderPosition(verticalScrollBar->maximum()); + + if (atBottom) { + scrollToBottom(); + } ++numMessagesAfterLastTimeStamp; if (message.stamp().isValid()) { @@ -260,4 +271,17 @@ void ChatWindow::messageReceived(const QXmppMessage& message) { } } +bool ChatWindow::isAtBottom() { + QScrollBar* verticalScrollBar = ui->messagesScrollArea->verticalScrollBar(); + qDebug() << "Checking for bottom " << verticalScrollBar->sliderPosition() << " " << verticalScrollBar->maximum(); + return verticalScrollBar->sliderPosition() == verticalScrollBar->maximum(); +} + +// Scroll chat message area to bottom. +void ChatWindow::scrollToBottom() { + QScrollBar* verticalScrollBar = ui->messagesScrollArea->verticalScrollBar(); + qDebug() << "Scrolling to " << verticalScrollBar->maximum(); + verticalScrollBar->setSliderPosition(verticalScrollBar->maximum()); +} + #endif diff --git a/interface/src/ui/ChatWindow.h b/interface/src/ui/ChatWindow.h index cb9619cc42..46e7de1c39 100644 --- a/interface/src/ui/ChatWindow.h +++ b/interface/src/ui/ChatWindow.h @@ -48,6 +48,8 @@ private: #endif void startTimerForTimeStamps(); void addTimeStamp(); + bool isAtBottom(); + void scrollToBottom(); Ui::ChatWindow* ui; int numMessagesAfterLastTimeStamp; From 9fcb656027458de398910f281a0a3dcafc76bec8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 11 Apr 2014 09:26:45 -0700 Subject: [PATCH 090/110] 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 091/110] 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 092/110] 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; From 0ad841edfb44466cf5248e0263d9c2f0dc4d6912 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 11 Apr 2014 17:44:51 -0700 Subject: [PATCH 093/110] don't render avatar boundary shapes in first person --- interface/src/avatar/Avatar.cpp | 20 ++++++++++++++------ interface/src/avatar/Avatar.h | 1 + interface/src/avatar/Head.h | 2 +- interface/src/avatar/MyAvatar.cpp | 13 +++++++++---- interface/src/avatar/MyAvatar.h | 1 + 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 475e7a1abc..e9d804d227 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -228,14 +228,18 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { _skeletonModel.renderJointCollisionShapes(0.7f); } if (Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionShapes)) { - getHead()->getFaceModel().updateShapePositions(); - getHead()->getFaceModel().renderJointCollisionShapes(0.7f); + if (shouldRenderHead(cameraPosition, renderMode)) { + getHead()->getFaceModel().updateShapePositions(); + getHead()->getFaceModel().renderJointCollisionShapes(0.7f); + } } if (Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes)) { - getHead()->getFaceModel().updateShapePositions(); - getHead()->getFaceModel().renderBoundingCollisionShapes(0.7f); - _skeletonModel.updateShapePositions(); - _skeletonModel.renderBoundingCollisionShapes(0.7f); + if (shouldRenderHead(cameraPosition, renderMode)) { + getHead()->getFaceModel().updateShapePositions(); + getHead()->getFaceModel().renderBoundingCollisionShapes(0.7f); + _skeletonModel.updateShapePositions(); + _skeletonModel.renderBoundingCollisionShapes(0.7f); + } } // quick check before falling into the code below: @@ -344,6 +348,10 @@ void Avatar::renderBody(RenderMode renderMode) { getHand()->render(false); } +bool Avatar::shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const { + return true; +} + void Avatar::updateJointMappings() { // no-op; joint mappings come from skeleton model } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index ca05e5dbbf..4d68f2168b 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -195,6 +195,7 @@ protected: void renderDisplayName(); virtual void renderBody(RenderMode renderMode); + virtual bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const; virtual void updateJointMappings(); diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index a6cda5622c..5f0c6519ef 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -78,7 +78,7 @@ public: const bool getReturnToCenter() const { return _returnHeadToCenter; } // Do you want head to try to return to center (depends on interface detected) float getAverageLoudness() const { return _averageLoudness; } - glm::vec3 calculateAverageEyePosition() { return _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF; } + glm::vec3 calculateAverageEyePosition() const { return _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF; } /// \return the point about which scaling occurs. glm::vec3 getScalePivot() const; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index a258cd341b..fa15117cb2 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -647,15 +647,20 @@ void MyAvatar::renderBody(RenderMode renderMode) { _skeletonModel.render(1.0f, modelRenderMode); // Render head so long as the camera isn't inside it - const float RENDER_HEAD_CUTOFF_DISTANCE = 0.50f; - Camera* myCamera = Application::getInstance()->getCamera(); - if (renderMode != NORMAL_RENDER_MODE || (glm::length(myCamera->getPosition() - getHead()->calculateAverageEyePosition()) > - RENDER_HEAD_CUTOFF_DISTANCE * _scale)) { + if (shouldRenderHead(Application::getInstance()->getCamera()->getPosition(), renderMode)) { getHead()->render(1.0f, modelRenderMode); } getHand()->render(true); } +const float RENDER_HEAD_CUTOFF_DISTANCE = 0.50f; + +bool MyAvatar::shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const { + const Head* head = getHead(); + return (renderMode != NORMAL_RENDER_MODE) || + (glm::length(cameraPosition - head->calculateAverageEyePosition()) > RENDER_HEAD_CUTOFF_DISTANCE * _scale); +} + void MyAvatar::updateThrust(float deltaTime) { // // Gather thrust information from keyboard and sensors to apply to avatar motion diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 66ab322444..71c74f7c91 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -41,6 +41,7 @@ public: void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE); void renderBody(RenderMode renderMode); + bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const; void renderDebugBodyPoints(); void renderHeadMouse() const; From 13cf0c80e687f4bf34d5d5532af01d84f29b25eb Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Sat, 12 Apr 2014 00:20:43 -0700 Subject: [PATCH 094/110] Fix chat message formatting and word wrapping By switching from a QLabel to a QTextBrowser widget more formatting options and word wrapping that breaks words is possible. It comes with an issue I have been unable to resolve * Selecting text and going down with the cursor will cause it to scroll. It's possible to increase padding to remove this behavior, but it doesn't look great. --- interface/src/ui/ChatMessageArea.cpp | 44 ++++++++++++++++++++++++++++ interface/src/ui/ChatMessageArea.h | 33 +++++++++++++++++++++ interface/src/ui/ChatWindow.cpp | 35 +++++++++++++++------- 3 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 interface/src/ui/ChatMessageArea.cpp create mode 100644 interface/src/ui/ChatMessageArea.h diff --git a/interface/src/ui/ChatMessageArea.cpp b/interface/src/ui/ChatMessageArea.cpp new file mode 100644 index 0000000000..936f2dba18 --- /dev/null +++ b/interface/src/ui/ChatMessageArea.cpp @@ -0,0 +1,44 @@ +// +// ChatMessageArea.cpp +// interface/src/ui +// +// Created by Ryan Huffman on 4/11/14. +// 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 "ChatMessageArea.h" +#include +#include + +ChatMessageArea::ChatMessageArea() : QTextBrowser() { + connect(document()->documentLayout(), &QAbstractTextDocumentLayout::documentSizeChanged, + this, &ChatMessageArea::updateLayout); +}; + +void ChatMessageArea::setHtml(const QString& html) { + // Create format with updated line height + QTextBlockFormat format; + format.setLineHeight(CHAT_MESSAGE_LINE_HEIGHT, QTextBlockFormat::ProportionalHeight); + + // Possibly a bug in QT, the format won't take effect if `insertHtml` is used first. Inserting a space and deleting + // it after ensures the format is applied. + QTextCursor cursor = textCursor(); + cursor.setBlockFormat(format); + cursor.insertText(" "); + cursor.insertHtml(html); + cursor.setPosition(0); + cursor.deleteChar(); +}; + +void ChatMessageArea::updateLayout() { + setFixedHeight(document()->size().height()); + updateGeometry(); +} + +void ChatMessageArea::wheelEvent(QWheelEvent* event) { + // Capture wheel events to stop Ctrl-WheelUp/Down zooming + event->ignore(); +}; diff --git a/interface/src/ui/ChatMessageArea.h b/interface/src/ui/ChatMessageArea.h new file mode 100644 index 0000000000..1c49c60b08 --- /dev/null +++ b/interface/src/ui/ChatMessageArea.h @@ -0,0 +1,33 @@ +// +// ChatMessageArea.h +// interface/src/ui +// +// Created by Ryan Huffman on 4/11/14. +// 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_ChatMessageArea_h +#define hifi_ChatMessageArea_h + +#include + +const int CHAT_MESSAGE_LINE_HEIGHT = 130; + +class ChatMessageArea : public QTextBrowser { + Q_OBJECT +public: + ChatMessageArea(); + virtual void setHtml(const QString& html); + +public slots: + void updateLayout(); + +protected: + virtual void wheelEvent(QWheelEvent* event); + +}; + +#endif // hifi_ChatMessageArea_h diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index c164ea3fb3..9cd0690536 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -22,6 +22,7 @@ #include "qtimespan.h" #include "ui_chatWindow.h" #include "XmppClient.h" +#include "ChatMessageArea.h" #include "ChatWindow.h" @@ -241,25 +242,39 @@ void ChatWindow::messageReceived(const QXmppMessage& message) { userLabel->setStyleSheet("padding: 2px; font-weight: bold"); userLabel->setAlignment(Qt::AlignTop | Qt::AlignRight); - QLabel* messageLabel = new QLabel(message.body().replace(regexLinks, "\\1")); - messageLabel->setWordWrap(true); - messageLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); - messageLabel->setOpenExternalLinks(true); - messageLabel->setStyleSheet("padding-bottom: 2px; padding-left: 2px; padding-top: 2px; padding-right: 20px"); - messageLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft); + ChatMessageArea* messageArea = new ChatMessageArea(); - if (getParticipantName(message.from()) == AccountManager::getInstance().getUsername()) { + messageArea->setOpenLinks(true); + messageArea->setOpenExternalLinks(true); + messageArea->setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + messageArea->setTextInteractionFlags(Qt::TextBrowserInteraction); + messageArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + messageArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + messageArea->setReadOnly(true); + + messageArea->setStyleSheet("padding-bottom: 2px;" + "padding-left: 2px;" + "padding-top: 2px;" + "padding-right: 20px;" + "background-color: rgba(0, 0, 0, 0%);" + "border: 0;"); + + bool fromSelf = getParticipantName(message.from()) == AccountManager::getInstance().getUsername(); + if (fromSelf) { userLabel->setStyleSheet(userLabel->styleSheet() + "; background-color: #e1e8ea"); - messageLabel->setStyleSheet(messageLabel->styleSheet() + "; background-color: #e1e8ea"); + messageArea->setStyleSheet(messageArea->styleSheet() + "; background-color: #e1e8ea"); } + messageArea->setHtml(message.body().replace(regexLinks, "\\1")); + bool atBottom = isAtBottom(); ui->messagesGridLayout->addWidget(userLabel, ui->messagesGridLayout->rowCount(), 0); - ui->messagesGridLayout->addWidget(messageLabel, ui->messagesGridLayout->rowCount() - 1, 1); + ui->messagesGridLayout->addWidget(messageArea, ui->messagesGridLayout->rowCount() - 1, 1); + ui->messagesGridLayout->parentWidget()->updateGeometry(); Application::processEvents(); - if (atBottom) { + if (atBottom || fromSelf) { scrollToBottom(); } From 45402336ac9ff702c9440f0a6118b069e23b9f02 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Sat, 12 Apr 2014 00:25:53 -0700 Subject: [PATCH 095/110] Add chat window dragging This was originally implemented by Mohammed Nafees, shared on Basecamp. I've noticed an issue with dragging across screens (monitors) where the chat window will jump vertically. I've tried debugging it, and ultimately it looks like an issue with the `move` method. The coordinates are valid (I tried using global coordinates as well), and the amount to move is correct, but when moving to coordinates on a different screen it doesn't do the right thing. --- interface/src/ui/ChatWindow.cpp | 23 ++++++++++++++++++++++- interface/src/ui/ChatWindow.h | 6 ++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index 9cd0690536..de1362273b 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -32,7 +32,9 @@ const QRegularExpression regexLinks("((?:(?:ftp)|(?:https?))://\\S+)"); ChatWindow::ChatWindow() : ui(new Ui::ChatWindow), - numMessagesAfterLastTimeStamp(0) + numMessagesAfterLastTimeStamp(0), + _mousePressed(false), + _mouseStartPosition() { ui->setupUi(this); @@ -83,6 +85,25 @@ ChatWindow::~ChatWindow() { delete ui; } +void ChatWindow::mousePressEvent(QMouseEvent *e) { + if (e->button() == Qt::LeftButton) { + _mousePressed = true; + _mouseStartPosition = e->pos(); + } +} + +void ChatWindow::mouseMoveEvent(QMouseEvent *e) { + if (_mousePressed) { + move(mapToParent(e->pos() - _mouseStartPosition)); + } +} + +void ChatWindow::mouseReleaseEvent( QMouseEvent *e ) { + if ( e->button() == Qt::LeftButton ) { + _mousePressed = false; + } +} + void ChatWindow::keyPressEvent(QKeyEvent* event) { QDockWidget::keyPressEvent(event); if (event->key() == Qt::Key_Escape) { diff --git a/interface/src/ui/ChatWindow.h b/interface/src/ui/ChatWindow.h index 46e7de1c39..4a339ad278 100644 --- a/interface/src/ui/ChatWindow.h +++ b/interface/src/ui/ChatWindow.h @@ -39,6 +39,10 @@ public: virtual void keyPressEvent(QKeyEvent *event); virtual void showEvent(QShowEvent* event); + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseMoveEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *e); + protected: bool eventFilter(QObject* sender, QEvent* event); @@ -54,6 +58,8 @@ private: Ui::ChatWindow* ui; int numMessagesAfterLastTimeStamp; QDateTime lastMessageStamp; + bool _mousePressed; + QPoint _mouseStartPosition; private slots: void connected(); From 8b904b91eaf812537525431af5a1b162a9696332 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Sat, 12 Apr 2014 00:53:43 -0700 Subject: [PATCH 096/110] Cleanup ChatMessageArea.cpp --- interface/src/ui/ChatMessageArea.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/ChatMessageArea.cpp b/interface/src/ui/ChatMessageArea.cpp index 936f2dba18..f15b788990 100644 --- a/interface/src/ui/ChatMessageArea.cpp +++ b/interface/src/ui/ChatMessageArea.cpp @@ -16,7 +16,7 @@ ChatMessageArea::ChatMessageArea() : QTextBrowser() { connect(document()->documentLayout(), &QAbstractTextDocumentLayout::documentSizeChanged, this, &ChatMessageArea::updateLayout); -}; +} void ChatMessageArea::setHtml(const QString& html) { // Create format with updated line height @@ -31,7 +31,7 @@ void ChatMessageArea::setHtml(const QString& html) { cursor.insertHtml(html); cursor.setPosition(0); cursor.deleteChar(); -}; +} void ChatMessageArea::updateLayout() { setFixedHeight(document()->size().height()); @@ -41,4 +41,4 @@ void ChatMessageArea::updateLayout() { void ChatMessageArea::wheelEvent(QWheelEvent* event) { // Capture wheel events to stop Ctrl-WheelUp/Down zooming event->ignore(); -}; +} From 2c10b558589d913ecd181c0b7f92f4a5ee5b1406 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Sat, 12 Apr 2014 01:09:29 -0700 Subject: [PATCH 097/110] Remove extraneous debug messages --- interface/src/ui/ChatWindow.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index de1362273b..78d5adf394 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -309,14 +309,12 @@ void ChatWindow::messageReceived(const QXmppMessage& message) { bool ChatWindow::isAtBottom() { QScrollBar* verticalScrollBar = ui->messagesScrollArea->verticalScrollBar(); - qDebug() << "Checking for bottom " << verticalScrollBar->sliderPosition() << " " << verticalScrollBar->maximum(); return verticalScrollBar->sliderPosition() == verticalScrollBar->maximum(); } // Scroll chat message area to bottom. void ChatWindow::scrollToBottom() { QScrollBar* verticalScrollBar = ui->messagesScrollArea->verticalScrollBar(); - qDebug() << "Scrolling to " << verticalScrollBar->maximum(); verticalScrollBar->setSliderPosition(verticalScrollBar->maximum()); } From 6b4a7d365f69cb23b39ed87d88d36d1b7107d8fd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 14 Apr 2014 10:43:42 -0700 Subject: [PATCH 098/110] update build guide with extra info for GnuTLS --- BUILD.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/BUILD.md b/BUILD.md index 6464f14d08..7e35c9569b 100644 --- a/BUILD.md +++ b/BUILD.md @@ -5,6 +5,8 @@ Dependencies * [zLib](http://www.zlib.net/) ~> 1.2.8 * [glm](http://glm.g-truc.net/0.9.5/index.html) ~> 0.9.5.2 * [qxmpp](https://code.google.com/p/qxmpp/) ~> 0.7.6 +* [GnuTLS](http://gnutls.org/download.html) ~> 3.2.12 + * IMPORTANT: GnuTLS 3.2.12 is crtiical to avoid a security vulnerability. #####Linux only * [freeglut](http://freeglut.sourceforge.net/) ~> 2.8.0 @@ -50,12 +52,18 @@ Should you choose not to install Qt5 via a package manager that handles dependen libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack-dev +#####GnuTLS + +If `libgnutls28-dev` 3.2.12 or higher is available via your package manager, it would be easiest to grab it from there. At the time of this writing that is not the case for any version of Ubuntu, so it will need to be built from source. + +gmplib is a dependency for GnuTLS. On Ubuntu, we were unable to build hogweed (part of libnettle) with gmp 6.x.x. If nettle is not built with hogweed, GnuTLS will fail to build. If you run into this problem, try version 4.2.1 of gmplib. + ####OS X #####Package Managers [Homebrew](http://brew.sh/) is an excellent package manager for OS X. It makes install of all hifi dependencies very simple. brew tap highfidelity/homebrew-formulas - brew install cmake glm zlib + brew install cmake glm zlib gnutls brew install highfidelity/formulas/qt5 brew link qt5 --force brew install highfidelity/formulas/qxmpp @@ -128,6 +136,15 @@ For many of the external libraries where precompiled binaries are readily availa *NOTE: Qt does not support 64-bit builds on Windows 7, so you must use the 32-bit version of libraries for interface.exe to run. The 32-bit version of the static library is the one linked by our CMake find modules* +#####GnuTLS +You can get a precompiled version of GnuTLS for Windows [here](ftp://ftp.gnutls.org/gcrypt/gnutls/w32/). + +To use GnuTLS with Visual Studio, you will need to create `libgnutls-28.lib`, the import library for Visual Studio projects. this is done using the `lib` command in the `bin` folder of your GnuTLS download. + + $GNUTLS_DIR\bin> lib /def:libgnutls-28.def + +This will create `libgnutls-28.lib`. Copy that file to the `lib` folder of you GnuTLS folder, and the Cmake FindGnuTLS module in this repo will find it during the Cmake run. As will other external dependencies for this project, the associated GnuTLS DLL will need to be in your path. + #### DLLs As with the Qt libraries, you will need to make sure the directory containing dynamically-linked libraries is in your path. For example, for a dynamically linked build of freeglut, the directory to add to your path in which the DLL is found is `FREEGLUT_DIR/bin`. Where possible, you can use static builds of the external dependencies to avoid this requirement. From 007a477400705af7a0ad71ec09a1b203c31c5ba0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 14 Apr 2014 10:46:42 -0700 Subject: [PATCH 099/110] fix a typo in build guide --- BUILD.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD.md b/BUILD.md index 7e35c9569b..e29c20b6d2 100644 --- a/BUILD.md +++ b/BUILD.md @@ -6,7 +6,7 @@ Dependencies * [glm](http://glm.g-truc.net/0.9.5/index.html) ~> 0.9.5.2 * [qxmpp](https://code.google.com/p/qxmpp/) ~> 0.7.6 * [GnuTLS](http://gnutls.org/download.html) ~> 3.2.12 - * IMPORTANT: GnuTLS 3.2.12 is crtiical to avoid a security vulnerability. + * IMPORTANT: GnuTLS 3.2.12 is critical to avoid a security vulnerability. #####Linux only * [freeglut](http://freeglut.sourceforge.net/) ~> 2.8.0 From 6cb5497242e3714fdbf271713be752693d87260e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 14 Apr 2014 10:49:11 -0700 Subject: [PATCH 100/110] codify some library names and fix some other spelling --- BUILD.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD.md b/BUILD.md index e29c20b6d2..265e21e031 100644 --- a/BUILD.md +++ b/BUILD.md @@ -56,7 +56,7 @@ Should you choose not to install Qt5 via a package manager that handles dependen If `libgnutls28-dev` 3.2.12 or higher is available via your package manager, it would be easiest to grab it from there. At the time of this writing that is not the case for any version of Ubuntu, so it will need to be built from source. -gmplib is a dependency for GnuTLS. On Ubuntu, we were unable to build hogweed (part of libnettle) with gmp 6.x.x. If nettle is not built with hogweed, GnuTLS will fail to build. If you run into this problem, try version 4.2.1 of gmplib. +`gmplib` is a dependency for GnuTLS. On Ubuntu, we were unable to build `hogweed` (part of `libnettle`) with `gmpib` 6.x.x. If nettle is not built with `hogweed`, GnuTLS will fail to build. If you run into this problem, try version 4.2.1 of `gmplib`. ####OS X #####Package Managers @@ -143,7 +143,7 @@ To use GnuTLS with Visual Studio, you will need to create `libgnutls-28.lib`, th $GNUTLS_DIR\bin> lib /def:libgnutls-28.def -This will create `libgnutls-28.lib`. Copy that file to the `lib` folder of you GnuTLS folder, and the Cmake FindGnuTLS module in this repo will find it during the Cmake run. As will other external dependencies for this project, the associated GnuTLS DLL will need to be in your path. +This will create `libgnutls-28.lib` in the `bin` folder. Copy that file to the `lib` sub-folder of your GnuTLS folder, and the Cmake FindGnuTLS module in this repo will find it during the Cmake run. As with other external dependencies for this project, the associated GnuTLS DLL will need to be in your path. #### DLLs As with the Qt libraries, you will need to make sure the directory containing dynamically-linked libraries is in your path. For example, for a dynamically linked build of freeglut, the directory to add to your path in which the DLL is found is `FREEGLUT_DIR/bin`. Where possible, you can use static builds of the external dependencies to avoid this requirement. From 1c7f8c87bcf9e9b1bb625025046489bc713cf384 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 14 Apr 2014 10:50:03 -0700 Subject: [PATCH 101/110] don't codify directories in OS X section --- BUILD.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD.md b/BUILD.md index 265e21e031..d6ec7c82b1 100644 --- a/BUILD.md +++ b/BUILD.md @@ -79,7 +79,7 @@ If Xcode is your editor of choice, you can ask CMake to generate Xcode project f After running cmake, you will have the make files or Xcode project file necessary to build all of the components. Open the hifi.xcodeproj file, choose ALL_BUILD from the Product > Scheme menu (or target drop down), and click Run. -If the build completes successfully, you will have built targets for all components located in the `build/${target_name}/Debug directories`. +If the build completes successfully, you will have built targets for all components located in the `build/${target_name}/Debug` directories. Windows === From 95abc74d83294039f9b3c3c4d6a3ea52fe8eb095 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 14 Apr 2014 10:50:57 -0700 Subject: [PATCH 102/110] add GnuTLS to example windows folder structure --- BUILD.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/BUILD.md b/BUILD.md index d6ec7c82b1..24618ff7ac 100644 --- a/BUILD.md +++ b/BUILD.md @@ -129,6 +129,10 @@ The recommended route for CMake to find external dependencies is to place all of -> qxmpp -> include -> lib + -> gnutls + -> bin + -> include + -> lib *NOTE: Be careful with glm. For the folder other libraries would normally call 'include', the folder containing the headers, glm opts to use 'glm'. You will have a glm folder nested inside the top-level glm folder.* From 70191111c737cca0adecbab9682e61b577b5d99b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 14 Apr 2014 10:51:36 -0700 Subject: [PATCH 103/110] remove GnuTLS DLL tip since DLL section is right below --- BUILD.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD.md b/BUILD.md index 24618ff7ac..f789437d60 100644 --- a/BUILD.md +++ b/BUILD.md @@ -147,7 +147,7 @@ To use GnuTLS with Visual Studio, you will need to create `libgnutls-28.lib`, th $GNUTLS_DIR\bin> lib /def:libgnutls-28.def -This will create `libgnutls-28.lib` in the `bin` folder. Copy that file to the `lib` sub-folder of your GnuTLS folder, and the Cmake FindGnuTLS module in this repo will find it during the Cmake run. As with other external dependencies for this project, the associated GnuTLS DLL will need to be in your path. +This will create `libgnutls-28.lib` in the `bin` folder. Copy that file to the `lib` sub-folder of your GnuTLS folder, and the Cmake FindGnuTLS module in this repo will find it during the Cmake run. #### DLLs As with the Qt libraries, you will need to make sure the directory containing dynamically-linked libraries is in your path. For example, for a dynamically linked build of freeglut, the directory to add to your path in which the DLL is found is `FREEGLUT_DIR/bin`. Where possible, you can use static builds of the external dependencies to avoid this requirement. From c5c8327359eabbd583336d0fd476bfe783ce59c0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 14 Apr 2014 10:57:34 -0700 Subject: [PATCH 104/110] update required version of cmake to 2.8.12.2 --- BUILD.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD.md b/BUILD.md index f789437d60..c5a7a604b4 100644 --- a/BUILD.md +++ b/BUILD.md @@ -1,6 +1,6 @@ Dependencies === -* [cmake](http://www.cmake.org/cmake/resources/software.html) ~> 2.8.11 +* [cmake](http://www.cmake.org/cmake/resources/software.html) ~> 2.8.12.2 * [Qt](http://qt-project.org/downloads) ~> 5.2.0 * [zLib](http://www.zlib.net/) ~> 1.2.8 * [glm](http://glm.g-truc.net/0.9.5/index.html) ~> 0.9.5.2 From f698f3375aae2da4ed3fc86e8e2f874d27509bc5 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 14 Apr 2014 11:34:27 -0700 Subject: [PATCH 105/110] Update resource urls for chat window close button --- interface/ui/chatWindow.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/ui/chatWindow.ui b/interface/ui/chatWindow.ui index 9321e1e8ea..0372e00c09 100644 --- a/interface/ui/chatWindow.ui +++ b/interface/ui/chatWindow.ui @@ -139,14 +139,14 @@ QPushButton { background-color: rgba( 0, 0, 0, 0% ); border: none; - image: url(:images/close.svg) + image: url(../resources/images/close.svg) } QPushButton:pressed { background-color: rgba( 0, 0, 0, 0% ); border: none; - image: url(:images/close_down.svg) + image: url(../resources/images/close_down.svg) } From 4ae148ff19d141199648595685593897d67f3f71 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 14 Apr 2014 11:34:35 -0700 Subject: [PATCH 106/110] Update chat window to not allow movement while docked --- interface/src/ui/ChatWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index 38e9553723..97fa81afc5 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -90,7 +90,7 @@ ChatWindow::~ChatWindow() { } void ChatWindow::mousePressEvent(QMouseEvent *e) { - if (e->button() == Qt::LeftButton) { + if (e->button() == Qt::LeftButton && isFloating()) { _mousePressed = true; _mouseStartPosition = e->pos(); } From 1aacba3b4600c3ea48ede248ba78d3f81d74dac2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 14 Apr 2014 12:31:41 -0700 Subject: [PATCH 107/110] changes to Windows instructions for GnuTLS --- BUILD.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD.md b/BUILD.md index c5a7a604b4..33e18545e0 100644 --- a/BUILD.md +++ b/BUILD.md @@ -141,9 +141,9 @@ For many of the external libraries where precompiled binaries are readily availa *NOTE: Qt does not support 64-bit builds on Windows 7, so you must use the 32-bit version of libraries for interface.exe to run. The 32-bit version of the static library is the one linked by our CMake find modules* #####GnuTLS -You can get a precompiled version of GnuTLS for Windows [here](ftp://ftp.gnutls.org/gcrypt/gnutls/w32/). +You can get a precompiled version of GnuTLS for Windows [here](http://gnutls.org/download.html). -To use GnuTLS with Visual Studio, you will need to create `libgnutls-28.lib`, the import library for Visual Studio projects. this is done using the `lib` command in the `bin` folder of your GnuTLS download. +To use GnuTLS with Visual Studio, you will need to create `libgnutls-28.lib`, the import library for Visual Studio projects. this is done using the `lib` command in the `bin` folder of your GnuTLS download. Run the following in a Visual Studio Command Prompt (found in the tools menu of Visual Studio). $GNUTLS_DIR\bin> lib /def:libgnutls-28.def From d3776afc93b7eed1d9b61ffd1859f2de3482ab07 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 14 Apr 2014 12:36:13 -0700 Subject: [PATCH 108/110] fix for DLL section in BUILD guide --- BUILD.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/BUILD.md b/BUILD.md index 33e18545e0..b855ed1450 100644 --- a/BUILD.md +++ b/BUILD.md @@ -140,6 +140,11 @@ For many of the external libraries where precompiled binaries are readily availa *NOTE: Qt does not support 64-bit builds on Windows 7, so you must use the 32-bit version of libraries for interface.exe to run. The 32-bit version of the static library is the one linked by our CMake find modules* +##### DLLs +As with the Qt libraries, you will need to make sure the directories containing dynamically-linked libraries is in your path. + +For example, for a dynamically linked build of freeglut, the directory to add to your path in which the DLL is found is `FREEGLUT_DIR/bin`. Where possible, you can use static builds of the external dependencies to avoid this requirement. + #####GnuTLS You can get a precompiled version of GnuTLS for Windows [here](http://gnutls.org/download.html). @@ -149,9 +154,6 @@ To use GnuTLS with Visual Studio, you will need to create `libgnutls-28.lib`, th This will create `libgnutls-28.lib` in the `bin` folder. Copy that file to the `lib` sub-folder of your GnuTLS folder, and the Cmake FindGnuTLS module in this repo will find it during the Cmake run. -#### DLLs -As with the Qt libraries, you will need to make sure the directory containing dynamically-linked libraries is in your path. For example, for a dynamically linked build of freeglut, the directory to add to your path in which the DLL is found is `FREEGLUT_DIR/bin`. Where possible, you can use static builds of the external dependencies to avoid this requirement. - ####Building in Visual Studio Follow the same build steps from the CMake section, but pass a different generator to CMake. From 55172c6f437a23506004d802cf4cd9184a8a1a15 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 14 Apr 2014 12:39:43 -0700 Subject: [PATCH 109/110] more cleanup to BUILD guide for windows --- BUILD.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/BUILD.md b/BUILD.md index b855ed1450..487bcb0eb1 100644 --- a/BUILD.md +++ b/BUILD.md @@ -108,11 +108,12 @@ Once Qt is installed, you need to manually configure the following: NOTE: zLib should configure itself correctly on install. However, sometimes zLib doesn't properly detect system components and fails to configure itself correctly. When it fails, it will not correctly set the #if HAVE_UNISTD_H at line 287 of zconf.h to #if 0... if it fails, you're build will have errors in the voxels target. You can correct this by setting the #if to 0 instead of 1, since Windows does not have unistd.h. ####External Libraries -We don't currently have a Windows installer, so before running Interface, you will need to ensure that all required resources are loadable. -CMake will need to know where the headers and libraries for required external dependencies are. If you installed ZLIB using the installer, the FindZLIB cmake module will be able to find it. This isn't the case for the others. +CMake will need to know where the headers and libraries for required external dependencies are. -The recommended route for CMake to find external dependencies is to place all of the dependencies in one folder and set one ENV variable - HIFI_LIB_DIR. That ENV variable should point to a directory with the following structure: +If you installed zLib using the installer, the Cmake find module for zLib should locate it on your system. + +The recommended route for CMake to find the other external dependencies is to place all of the dependencies in one folder and set one ENV variable - HIFI_LIB_DIR. That ENV variable should point to a directory with the following structure: root_lib_dir -> glm @@ -134,10 +135,10 @@ The recommended route for CMake to find external dependencies is to place all of -> include -> lib -*NOTE: Be careful with glm. For the folder other libraries would normally call 'include', the folder containing the headers, glm opts to use 'glm'. You will have a glm folder nested inside the top-level glm folder.* - For many of the external libraries where precompiled binaries are readily available you should be able to simply copy the extracted folder that you get from the download links provided at the top of the guide. Otherwise you may need to build from source and install the built product to this directory. The `root_lib_dir` in the above example can be wherever you choose on your system - as long as the environment variable HIFI_LIB_DIR is set to it. +*NOTE: Be careful with glm. For the folder other libraries would normally call 'include', the folder containing the headers, glm opts to use 'glm'. You will have a glm folder nested inside the top-level glm folder.* + *NOTE: Qt does not support 64-bit builds on Windows 7, so you must use the 32-bit version of libraries for interface.exe to run. The 32-bit version of the static library is the one linked by our CMake find modules* ##### DLLs From 06235decae206efa7caffa868b8ee18babc9c454 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 14 Apr 2014 14:10:12 -0700 Subject: [PATCH 110/110] Move ChatWindow isAtBottom and moveToBottom outside of HAVE_QXMPP --- interface/src/ui/ChatWindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index 97fa81afc5..635f1f3d10 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -311,6 +311,8 @@ void ChatWindow::messageReceived(const QXmppMessage& message) { } } +#endif + bool ChatWindow::isAtBottom() { QScrollBar* verticalScrollBar = ui->messagesScrollArea->verticalScrollBar(); return verticalScrollBar->sliderPosition() == verticalScrollBar->maximum(); @@ -322,8 +324,6 @@ void ChatWindow::scrollToBottom() { verticalScrollBar->setSliderPosition(verticalScrollBar->maximum()); } -#endif - void ChatWindow::togglePinned() { QMainWindow* mainWindow = Application::getInstance()->getWindow(); mainWindow->removeDockWidget(this);