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());