detect handshake completion in DS and client

This commit is contained in:
Stephen Birarda 2014-04-02 17:56:04 -07:00
parent e1cae6d295
commit 62de84315e
5 changed files with 38 additions and 23 deletions

View file

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

View file

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

View file

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

View file

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

View file

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