leverage a DummyDTLSSession to not require cleanup of DTLSSession for cookies

This commit is contained in:
Stephen Birarda 2014-04-04 11:42:14 -07:00
parent b40dd6a31a
commit c015fdd212
10 changed files with 89 additions and 40 deletions

View file

@ -23,6 +23,7 @@
#include <UUID.h>
#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);

View file

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

View file

@ -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__) */

View file

@ -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<DTLSSession*>(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<DTLSSession*>(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<const char*>(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);
}

View file

@ -13,9 +13,10 @@
#include <gnutls/gnutls.h>
#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;
};

View file

@ -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() {

View file

@ -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<DummyDTLSSession*>(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<const char*>(buffer), size,
session->_destinationSocket.getAddress(), session->_destinationSocket.getPort());
}
DummyDTLSSession::DummyDTLSSession(QUdpSocket& dtlsSocket, const HifiSockAddr& destinationSocket) :
_dtlsSocket(dtlsSocket),
_destinationSocket(destinationSocket)
{
}

View file

@ -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 <QtNetwork/QUdpSocket>
#include <gnutls/gnutls.h>
#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__) */

View file

@ -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 {

View file

@ -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;
}
}
}