From 94b29782eb84ed6471f41399756b5f7a1aebfded Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 1 Apr 2014 14:19:07 -0700 Subject: [PATCH] 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);