QDtls - handle server-side timeouts

According to RFC 6347 a DTLS server also must retransmit buffered message(s)
if timeouts happen during the handshake phase (so it's not a client only as
I initially understood it).

Conveniently so an auto-test is already in place and needs just a tiny
adjustment - handshakeWithRetransmission covers both sides.

Change-Id: If914ec3052e28ef5bf12a40e5eede45bbc53e8e0
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Timur Pocheptsov 2018-06-22 11:49:27 +02:00 committed by Edward Welbourne
parent 2afa6e5f94
commit 5bd9f98342
3 changed files with 15 additions and 17 deletions

View File

@ -398,12 +398,6 @@ bool QDtls::handleTimeout(QUdpSocket *socket)
return false;
}
if (sslMode() == QSslSocket::SslServerMode) {
d->setDtlsError(QDtlsError::InvalidOperation,
tr("DTLS server connection does not have/handle timeouts"));
return false;
}
return d->handleTimeout(socket);
}

View File

@ -1020,17 +1020,16 @@ bool QDtlsPrivateOpenSSL::continueHandshake(QUdpSocket *socket, const QByteArray
// SSL_get_state can provide more information about state
// machine and we can switch to NotStarted (since we have not
// replied with our hello ...)
if (mode == QSslSocket::SslClientMode) {
if (!timeoutHandler.data()) {
timeoutHandler.reset(new TimeoutHandler);
timeoutHandler->dtlsConnection = this;
} else {
// Back to 1s.
timeoutHandler->resetTimeout();
}
timeoutHandler->start();
if (!timeoutHandler.data()) {
timeoutHandler.reset(new TimeoutHandler);
timeoutHandler->dtlsConnection = this;
} else {
// Back to 1s.
timeoutHandler->resetTimeout();
}
timeoutHandler->start();
return true; // The handshake is not yet complete.
default:
storePeerCertificates();

View File

@ -217,6 +217,8 @@ void tst_QDtls::init()
connect(clientCrypto.data(), &QDtls::handshakeTimeout,
this, &tst_QDtls::handleHandshakeTimeout);
connect(serverCrypto.data(), &QDtls::handshakeTimeout,
this, &tst_QDtls::handleHandshakeTimeout);
}
void tst_QDtls::construction_data()
@ -1209,7 +1211,10 @@ void tst_QDtls::pskRequested(QSslPreSharedKeyAuthenticator *auth)
void tst_QDtls::handleHandshakeTimeout()
{
if (!clientCrypto->handleTimeout(&clientSocket))
auto crypto = qobject_cast<QDtls *>(sender());
Q_ASSERT(crypto);
if (!crypto->handleTimeout(&clientSocket))
testLoop.exitLoop();
}