Delay when using SSL on Windows
-
wrote on 6 Aug 2014, 16:50 last edited by
We were experiencing a very long delay (4 seconds) on the first access to the SSL libraries. The problem only occurs on Windows, where we are using ssleay32.dll and libeay32.dll which come from OpenSSL (version openssl-1.0.1g-bin-mingw48). We have a work around for the issue, but the work around is not obvious unless you know the root cause of the delay.
This is not an issue for Qt to fix, but it does effect Qt developers.
We found these two links to discussions that talk about the issue. These discussions mention that the open SSL libraries are traversing the heap to compute an entropy value.
http://rt.openssl.org/Ticket/Display.html?id=2100&user=guest&pass=guest
https://groups.google.com/forum/#!topic/mailing.openssl.users/s41yE12pOVEThe work around we found that fixes the 4 second delay was to access the SSL library very early in the application startup. By accessing the SSL library early, the size of the heap is small and the library spends less time traversing the heap to compute the entropy value.
Attached is a small program that demonstrates the issue. A compile switch is used to measure the time to access SSL on a very small heap, and on a heap that has 500,000 objects on it. When there are 500,000 objects on the heap, the first call to the SSL library takes about 4500 msec. When the heap is minimal, the first call to the SSL library takes about 100 msec. This is on Windows 7 X64 Core i5-3437 1.9Ghz. The app is compiled in 32 bit.
To see the effect of the SSL delay, build the program in release mode and run it from the command line. The delay does not materialize when running in the QtCreator debugger.
@
#include <QCoreApplication>
#include <QSslSocket>
#include <QElapsedTimer>
#include <QDebug>#define fillHeap
int main(int argc, char *argv[])
{
qDebug() << "ShowSSLDelay";QCoreApplication a(argc, argv); QElapsedTimer myTimer; qint64 elapsed;
#ifdef fillHeap
myTimer.start();
// Fill up the heap with objects.
QList<QString> heapUser;
int numToMake = 500 * 1000;
for( int i=0; i<numToMake; i++ )
{
QString s = QString::number(i);
heapUser.append(s);
}
elapsed = myTimer.elapsed();
qDebug() << "elapsed time to make " << numToMake << " objects = " << elapsed << " msec.";
#endifmyTimer.start(); bool supports = QSslSocket::supportsSsl(); elapsed = myTimer.elapsed(); qDebug() << "elapsed time to call supportsSSL = " << elapsed << " msec."; qDebug() << "Supports SSL = " << supports; myTimer.start(); supports = QSslSocket::supportsSsl(); elapsed = myTimer.elapsed(); qDebug() << "elapsed time to call supportsSSL second time = " << elapsed << " msec."; return 0;
}
@
Output:
ShowSSLDelay
elapsed time to make 500000 objects = 210 msec.
elapsed time to call supportsSSL = 4491 msec.
Supports SSL = true
elapsed time to call supportsSSL second time = 0 msec.
1/1