From 7b6ce7769055f22c38407ed7c4d95f480b861337 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 4 Apr 2014 09:20:40 -0700 Subject: [PATCH] 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++; } }