summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMårten Nordheim <marten.nordheim@qt.io>2019-09-07 02:22:21 +0200
committerMårten Nordheim <marten.nordheim@qt.io>2019-10-21 13:48:07 +0200
commit559b563d711db0760a51b0dce26536dbc8766a9d (patch)
tree8c1e66c226a3fd651b1a838c7d3458851d3a0c16 /src
parent69a43c6c3e3fcaf10480544c1638f6446ed25d00 (diff)
Use Schannel's incomplete data guesstimation feature
It tells us how many bytes we will need before the call succeeds. It's not accurate but will reduce the amount of calls to their slow functions Change-Id: I82393d5acd68b84c6e6f3377ba40bb1d5c51ca8a Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/network/ssl/qsslsocket_schannel.cpp32
-rw-r--r--src/network/ssl/qsslsocket_schannel_p.h1
2 files changed, 33 insertions, 0 deletions
diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp
index 3166cda4c9..78d807106b 100644
--- a/src/network/ssl/qsslsocket_schannel.cpp
+++ b/src/network/ssl/qsslsocket_schannel.cpp
@@ -467,6 +467,17 @@ void retainExtraData(QByteArray &buffer, const SecBuffer &secBuffer)
buffer.resize(secBuffer.cbBuffer);
}
+qint64 checkIncompleteData(const SecBuffer &secBuffer)
+{
+ if (secBuffer.BufferType == SECBUFFER_MISSING) {
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl, "Need %lu more bytes.", secBuffer.cbBuffer);
+#endif
+ return secBuffer.cbBuffer;
+}
+ return 0;
+}
+
} // anonymous namespace
bool QSslSocketPrivate::s_loadRootCertsOnDemand = true;
@@ -810,6 +821,10 @@ bool QSslSocketBackendPrivate::acceptContext()
Q_ASSERT(mode == QSslSocket::SslServerMode);
ULONG contextReq = getContextRequirements();
+ if (missingData > plainSocket->bytesAvailable())
+ return true;
+
+ missingData = 0;
readToBuffer(intermediateBuffer, plainSocket);
if (intermediateBuffer.isEmpty())
return true; // definitely need more data..
@@ -866,6 +881,7 @@ bool QSslSocketBackendPrivate::acceptContext()
if (status == SEC_E_INCOMPLETE_MESSAGE) {
// Need more data
+ missingData = checkIncompleteData(outBuffers[0]);
return true;
}
@@ -905,6 +921,10 @@ bool QSslSocketBackendPrivate::performHandshake()
qCDebug(lcSsl, "intermediateBuffer size: %d", intermediateBuffer.size());
#endif
+ if (missingData > plainSocket->bytesAvailable())
+ return true;
+
+ missingData = 0;
readToBuffer(intermediateBuffer, plainSocket);
if (intermediateBuffer.isEmpty())
return true; // no data, will fail
@@ -990,6 +1010,7 @@ bool QSslSocketBackendPrivate::performHandshake()
return true;
case SEC_E_INCOMPLETE_MESSAGE:
// Simply incomplete, wait for more data
+ missingData = checkIncompleteData(outBuffers[0]);
return true;
case SEC_E_ALGORITHM_MISMATCH:
setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
@@ -1192,6 +1213,8 @@ void QSslSocketBackendPrivate::reset()
connectionEncrypted = false;
shutdown = false;
renegotiating = false;
+
+ missingData = 0;
}
void QSslSocketBackendPrivate::startClientEncryption()
@@ -1288,6 +1311,14 @@ void QSslSocketBackendPrivate::transmit()
int totalRead = 0;
bool hadIncompleteData = false;
while (!readBufferMaxSize || buffer.size() < readBufferMaxSize) {
+ if (missingData > plainSocket->bytesAvailable()) {
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl, "We're still missing %lld bytes, will check later.", missingData);
+#endif
+ break;
+ }
+
+ missingData = 0;
const qint64 bytesRead = readToBuffer(intermediateBuffer, plainSocket);
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl, "Read %lld encrypted bytes from the socket", bytesRead);
@@ -1341,6 +1372,7 @@ void QSslSocketBackendPrivate::transmit()
}
if (status == SEC_E_INCOMPLETE_MESSAGE) {
+ missingData = checkIncompleteData(dataBuffer[0]);
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl, "We didn't have enough data to decrypt anything, will try again!");
#endif
diff --git a/src/network/ssl/qsslsocket_schannel_p.h b/src/network/ssl/qsslsocket_schannel_p.h
index 6ab200e1f9..a184deef49 100644
--- a/src/network/ssl/qsslsocket_schannel_p.h
+++ b/src/network/ssl/qsslsocket_schannel_p.h
@@ -145,6 +145,7 @@ private:
const CERT_CONTEXT *localCertContext = nullptr;
ULONG contextAttributes = 0;
+ qint64 missingData = 0;
bool renegotiating = false;
};