summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp28
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h4
-rw-r--r--src/network/bearer/qbearerengine_p.h4
-rw-r--r--src/network/bearer/qnetworkconfigmanager.cpp169
-rw-r--r--src/network/bearer/qnetworkconfigmanager_p.cpp218
-rw-r--r--src/network/bearer/qnetworkconfigmanager_p.h7
-rw-r--r--src/network/bearer/qnetworkconfiguration.cpp60
-rw-r--r--src/network/bearer/qnetworkconfiguration_p.h22
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp15
-rw-r--r--src/network/ssl/qsslsocket_openssl_p.h1
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp6
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h2
12 files changed, 329 insertions, 207 deletions
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 7bb1399..1940dd1 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -880,17 +880,18 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
return new QDisabledNetworkReply(this, req, op);
}
+#ifdef QT_QNAM_DEFAULT_NETWORK_SESSION
if (!d->networkSession && (d->initializeSession || !d->networkConfiguration.isEmpty())) {
QNetworkConfigurationManager manager;
if (d->networkConfiguration.isEmpty())
d->createSession(manager.defaultConfiguration());
else
d->createSession(manager.configurationFromIdentifier(d->networkConfiguration));
+ }
+#endif
- d->initializeSession = false;
- } else if (d->networkSession) {
+ if (d->networkSession)
d->networkSession->setSessionProperty(QLatin1String("AutoCloseSessionTimeout"), -1);
- }
QNetworkRequest request = req;
if (!request.header(QNetworkRequest::ContentLengthHeader).isValid() &&
@@ -1207,6 +1208,10 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
{
Q_Q(QNetworkAccessManager);
+#ifdef QT_QNAM_DEFAULT_NETWORK_SESSION
+ initializeSession = false;
+#endif
+
if (networkSession)
delete networkSession;
@@ -1229,24 +1234,29 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
void QNetworkAccessManagerPrivate::_q_networkSessionClosed()
{
- networkConfiguration = networkSession->configuration().identifier();
+ if (networkSession) {
+ networkConfiguration = networkSession->configuration().identifier();
- delete networkSession;
- networkSession = 0;
+ networkSession->deleteLater();
+ networkSession = 0;
+ }
}
void QNetworkAccessManagerPrivate::_q_networkSessionNewConfigurationActivated()
{
Q_Q(QNetworkAccessManager);
- networkSession->accept();
+ if (networkSession) {
+ networkSession->accept();
- emit q->networkSessionOnline();
+ emit q->networkSessionOnline();
+ }
}
void QNetworkAccessManagerPrivate::_q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &, bool)
{
- networkSession->migrate();
+ if (networkSession)
+ networkSession->migrate();
}
QT_END_NAMESPACE
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index 0140268..4a2a840 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -77,7 +77,9 @@ public:
#endif
networkSession(0),
networkAccessEnabled(true),
+#ifdef QT_QNAM_DEFAULT_NETWORK_SESSION
initializeSession(true),
+#endif
cookieJarCreated(false)
{ }
~QNetworkAccessManagerPrivate();
@@ -124,7 +126,9 @@ public:
QNetworkSession *networkSession;
QString networkConfiguration;
bool networkAccessEnabled;
+#ifdef QT_QNAM_DEFAULT_NETWORK_SESSION
bool initializeSession;
+#endif
bool cookieJarCreated;
diff --git a/src/network/bearer/qbearerengine_p.h b/src/network/bearer/qbearerengine_p.h
index 028c174..fd4bf87 100644
--- a/src/network/bearer/qbearerengine_p.h
+++ b/src/network/bearer/qbearerengine_p.h
@@ -73,7 +73,7 @@ class Q_NETWORK_EXPORT QBearerEngine : public QObject
{
Q_OBJECT
- friend class QNetworkConfigurationManager;
+ friend class QNetworkConfigurationManagerPrivate;
public:
QBearerEngine(QObject *parent = 0);
@@ -81,8 +81,6 @@ public:
virtual bool hasIdentifier(const QString &id) = 0;
- virtual void requestUpdate() = 0;
-
virtual QNetworkConfigurationManager::Capabilities capabilities() const = 0;
virtual QNetworkSessionPrivate *createSessionBackend() = 0;
diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp
index b631cf1..e7595a4 100644
--- a/src/network/bearer/qnetworkconfigmanager.cpp
+++ b/src/network/bearer/qnetworkconfigmanager.cpp
@@ -212,114 +212,7 @@ QNetworkConfigurationManager::~QNetworkConfigurationManager()
*/
QNetworkConfiguration QNetworkConfigurationManager::defaultConfiguration() const
{
- QNetworkConfigurationManagerPrivate *conPriv = connManager();
-
- foreach (QBearerEngine *engine, conPriv->engines()) {
- QNetworkConfigurationPrivatePointer ptr = engine->defaultConfiguration();
-
- if (ptr) {
- QNetworkConfiguration config;
- config.d = ptr;
- return config;
- }
- }
-
- // Engines don't have a default configuration.
-
- // Return first active snap
- QNetworkConfigurationPrivatePointer defaultConfiguration;
-
- foreach (QBearerEngine *engine, conPriv->engines()) {
- QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
- QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
-
- QMutexLocker locker(&engine->mutex);
-
- for (it = engine->snapConfigurations.begin(), end = engine->snapConfigurations.end();
- it != end; ++it) {
- if ((it.value()->state & QNetworkConfiguration::Active) ==
- QNetworkConfiguration::Active) {
- QNetworkConfiguration config;
- config.d = it.value();
- return config;
- } else if (!defaultConfiguration) {
- if ((it.value()->state & QNetworkConfiguration::Discovered) ==
- QNetworkConfiguration::Discovered) {
- defaultConfiguration = it.value();
- }
- }
- }
- }
-
- // No Active SNAPs return first Discovered SNAP.
- if (defaultConfiguration) {
- QNetworkConfiguration config;
- config.d = defaultConfiguration;
- return config;
- }
-
- /*
- No Active or Discovered SNAPs, find the perferred access point.
- The following priority order is used:
-
- 1. Active Ethernet
- 2. Active WLAN
- 3. Active Other
- 4. Discovered Ethernet
- 5. Discovered WLAN
- 6. Discovered Other
- */
-
- defaultConfiguration.reset();
-
- foreach (QBearerEngine *engine, conPriv->engines()) {
- QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
- QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
-
- QMutexLocker locker(&engine->mutex);
-
- for (it = engine->accessPointConfigurations.begin(),
- end = engine->accessPointConfigurations.end(); it != end; ++it) {
-
- if ((it.value()->state & QNetworkConfiguration::Discovered) ==
- QNetworkConfiguration::Discovered) {
- if (!defaultConfiguration) {
- defaultConfiguration = it.value();
- } else {
- if (defaultConfiguration->state == it.value()->state) {
- if (defaultConfiguration->bearerName() == QLatin1String("Ethernet")) {
- // do nothing
- } else if (defaultConfiguration->bearerName() == QLatin1String("WLAN")) {
- // ethernet beats wlan
- if (it.value()->bearerName() == QLatin1String("Ethernet"))
- defaultConfiguration = it.value();
- } else {
- // ethernet and wlan beats other
- if (it.value()->bearerName() == QLatin1String("Ethernet") ||
- it.value()->bearerName() == QLatin1String("WLAN")) {
- defaultConfiguration = it.value();
- }
- }
- } else {
- // active beats discovered
- if ((defaultConfiguration->state & QNetworkConfiguration::Active) !=
- QNetworkConfiguration::Active) {
- defaultConfiguration = it.value();
- }
- }
- }
- }
- }
- }
-
- // No Active InternetAccessPoint return first Discovered InternetAccessPoint.
- if (defaultConfiguration) {
- QNetworkConfiguration config;
- config.d = defaultConfiguration;
- return config;
- }
-
- return QNetworkConfiguration();
+ return connManager()->defaultConfiguration();
}
/*!
@@ -349,37 +242,7 @@ QNetworkConfiguration QNetworkConfigurationManager::defaultConfiguration() const
*/
QList<QNetworkConfiguration> QNetworkConfigurationManager::allConfigurations(QNetworkConfiguration::StateFlags filter) const
{
- QList<QNetworkConfiguration> result;
- QNetworkConfigurationManagerPrivate* conPriv = connManager();
-
- foreach (QBearerEngine *engine, conPriv->engines()) {
- QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
- QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
-
- QMutexLocker locker(&engine->mutex);
-
- //find all InternetAccessPoints
- for (it = engine->accessPointConfigurations.begin(),
- end = engine->accessPointConfigurations.end(); it != end; ++it) {
- if ((it.value()->state & filter) == filter) {
- QNetworkConfiguration pt;
- pt.d = it.value();
- result << pt;
- }
- }
-
- //find all service networks
- for (it = engine->snapConfigurations.begin(),
- end = engine->snapConfigurations.end(); it != end; ++it) {
- if ((it.value()->state & filter) == filter) {
- QNetworkConfiguration pt;
- pt.d = it.value();
- result << pt;
- }
- }
- }
-
- return result;
+ return connManager()->allConfigurations(filter);
}
/*!
@@ -388,28 +251,9 @@ QList<QNetworkConfiguration> QNetworkConfigurationManager::allConfigurations(QNe
\sa QNetworkConfiguration::identifier()
*/
-QNetworkConfiguration QNetworkConfigurationManager::configurationFromIdentifier(const QString& identifier) const
+QNetworkConfiguration QNetworkConfigurationManager::configurationFromIdentifier(const QString &identifier) const
{
- QNetworkConfigurationManagerPrivate* conPriv = connManager();
-
- QNetworkConfiguration item;
-
- foreach (QBearerEngine *engine, conPriv->engines()) {
- QMutexLocker locker(&engine->mutex);
-
- if (engine->accessPointConfigurations.contains(identifier))
- item.d = engine->accessPointConfigurations.value(identifier);
- else if (engine->snapConfigurations.contains(identifier))
- item.d = engine->snapConfigurations.value(identifier);
- else if (engine->userChoiceConfigurations.contains(identifier))
- item.d = engine->userChoiceConfigurations.value(identifier);
- else
- continue;
-
- return item;
- }
-
- return item;
+ return connManager()->configurationFromIdentifier(identifier);
}
/*!
@@ -424,10 +268,7 @@ QNetworkConfiguration QNetworkConfigurationManager::configurationFromIdentifier(
*/
bool QNetworkConfigurationManager::isOnline() const
{
- QNetworkConfigurationManagerPrivate* conPriv = connManager();
- Q_UNUSED(conPriv);
- QList<QNetworkConfiguration> activeConfigs = allConfigurations(QNetworkConfiguration::Active);
- return activeConfigs.count() > 0;
+ return connManager()->isOnline();
}
/*!
diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp
index 9740424..c665fa2 100644
--- a/src/network/bearer/qnetworkconfigmanager_p.cpp
+++ b/src/network/bearer/qnetworkconfigmanager_p.cpp
@@ -47,6 +47,7 @@
#include <QtCore/qdebug.h>
#include <QtCore/qtimer.h>
#include <QtCore/qstringlist.h>
+#include <QtCore/qthread.h>
#include <QtCore/private/qcoreapplication_p.h>
QT_BEGIN_NAMESPACE
@@ -57,11 +58,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate()
: capFlags(0), mutex(QMutex::Recursive), pollTimer(0), forcedPolling(0), firstUpdate(true)
{
- updateConfigurations();
+ qRegisterMetaType<QNetworkConfiguration>("QNetworkConfiguration");
moveToThread(QCoreApplicationPrivate::mainThread());
- foreach (QBearerEngine *engine, sessionEngines)
- engine->moveToThread(QCoreApplicationPrivate::mainThread());
+ updateConfigurations();
}
QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate()
@@ -71,6 +71,200 @@ QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate()
qDeleteAll(sessionEngines);
}
+QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration()
+{
+ QMutexLocker locker(&mutex);
+
+ foreach (QBearerEngine *engine, sessionEngines) {
+ QNetworkConfigurationPrivatePointer ptr = engine->defaultConfiguration();
+
+ if (ptr) {
+ QNetworkConfiguration config;
+ config.d = ptr;
+ return config;
+ }
+ }
+
+ // Engines don't have a default configuration.
+
+ // Return first active snap
+ QNetworkConfigurationPrivatePointer defaultConfiguration;
+
+ foreach (QBearerEngine *engine, sessionEngines) {
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
+
+ QMutexLocker locker(&engine->mutex);
+
+ for (it = engine->snapConfigurations.begin(), end = engine->snapConfigurations.end();
+ it != end; ++it) {
+ QNetworkConfigurationPrivatePointer ptr = it.value();
+
+ QMutexLocker configLocker(&ptr->mutex);
+
+ if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ QNetworkConfiguration config;
+ config.d = ptr;
+ return config;
+ } else if (!defaultConfiguration) {
+ if ((ptr->state & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ defaultConfiguration = ptr;
+ }
+ }
+ }
+ }
+
+ // No Active SNAPs return first Discovered SNAP.
+ if (defaultConfiguration) {
+ QNetworkConfiguration config;
+ config.d = defaultConfiguration;
+ return config;
+ }
+
+ /*
+ No Active or Discovered SNAPs, find the perferred access point.
+ The following priority order is used:
+
+ 1. Active Ethernet
+ 2. Active WLAN
+ 3. Active Other
+ 4. Discovered Ethernet
+ 5. Discovered WLAN
+ 6. Discovered Other
+ */
+
+ defaultConfiguration.reset();
+
+ foreach (QBearerEngine *engine, sessionEngines) {
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
+
+ QMutexLocker locker(&engine->mutex);
+
+ for (it = engine->accessPointConfigurations.begin(),
+ end = engine->accessPointConfigurations.end(); it != end; ++it) {
+ QNetworkConfigurationPrivatePointer ptr = it.value();
+
+ const QString bearerName = ptr->bearerName();
+ QMutexLocker configLocker(&ptr->mutex);
+
+ if ((ptr->state & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ if (!defaultConfiguration) {
+ defaultConfiguration = ptr;
+ } else {
+ if (defaultConfiguration->state == ptr->state) {
+ if (defaultConfiguration->bearerName() == QLatin1String("Ethernet")) {
+ // do nothing
+ } else if (defaultConfiguration->bearerName() == QLatin1String("WLAN")) {
+ // ethernet beats wlan
+ if (bearerName == QLatin1String("Ethernet"))
+ defaultConfiguration = ptr;
+ } else {
+ // ethernet and wlan beats other
+ if (bearerName == QLatin1String("Ethernet") ||
+ bearerName == QLatin1String("WLAN")) {
+ defaultConfiguration = ptr;
+ }
+ }
+ } else {
+ // active beats discovered
+ if ((defaultConfiguration->state & QNetworkConfiguration::Active) !=
+ QNetworkConfiguration::Active) {
+ defaultConfiguration = ptr;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // No Active InternetAccessPoint return first Discovered InternetAccessPoint.
+ if (defaultConfiguration) {
+ QNetworkConfiguration config;
+ config.d = defaultConfiguration;
+ return config;
+ }
+
+ return QNetworkConfiguration();
+}
+
+QList<QNetworkConfiguration> QNetworkConfigurationManagerPrivate::allConfigurations(QNetworkConfiguration::StateFlags filter)
+{
+ QList<QNetworkConfiguration> result;
+
+ QMutexLocker locker(&mutex);
+
+ foreach (QBearerEngine *engine, sessionEngines) {
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
+
+ QMutexLocker locker(&engine->mutex);
+
+ //find all InternetAccessPoints
+ for (it = engine->accessPointConfigurations.begin(),
+ end = engine->accessPointConfigurations.end(); it != end; ++it) {
+ QNetworkConfigurationPrivatePointer ptr = it.value();
+
+ QMutexLocker configLocker(&ptr->mutex);
+
+ if ((ptr->state & filter) == filter) {
+ QNetworkConfiguration pt;
+ pt.d = ptr;
+ result << pt;
+ }
+ }
+
+ //find all service networks
+ for (it = engine->snapConfigurations.begin(),
+ end = engine->snapConfigurations.end(); it != end; ++it) {
+ QNetworkConfigurationPrivatePointer ptr = it.value();
+
+ QMutexLocker configLocker(&ptr->mutex);
+
+ if ((ptr->state & filter) == filter) {
+ QNetworkConfiguration pt;
+ pt.d = ptr;
+ result << pt;
+ }
+ }
+ }
+
+ return result;
+}
+
+QNetworkConfiguration QNetworkConfigurationManagerPrivate::configurationFromIdentifier(const QString &identifier)
+{
+ QNetworkConfiguration item;
+
+ QMutexLocker locker(&mutex);
+
+ foreach (QBearerEngine *engine, sessionEngines) {
+ QMutexLocker locker(&engine->mutex);
+
+ if (engine->accessPointConfigurations.contains(identifier))
+ item.d = engine->accessPointConfigurations.value(identifier);
+ else if (engine->snapConfigurations.contains(identifier))
+ item.d = engine->snapConfigurations.value(identifier);
+ else if (engine->userChoiceConfigurations.contains(identifier))
+ item.d = engine->userChoiceConfigurations.value(identifier);
+ else
+ continue;
+
+ return item;
+ }
+
+ return item;
+}
+
+bool QNetworkConfigurationManagerPrivate::isOnline()
+{
+ QMutexLocker locker(&mutex);
+
+ return !onlineConfigurations.isEmpty();
+}
+
void QNetworkConfigurationManagerPrivate::configurationAdded(QNetworkConfigurationPrivatePointer ptr)
{
QMutexLocker locker(&mutex);
@@ -81,10 +275,14 @@ void QNetworkConfigurationManagerPrivate::configurationAdded(QNetworkConfigurati
emit configurationAdded(item);
}
+ ptr->mutex.lock();
if (ptr->state == QNetworkConfiguration::Active) {
+ ptr->mutex.unlock();
onlineConfigurations.insert(ptr->id);
if (!firstUpdate && onlineConfigurations.count() == 1)
emit onlineStateChanged(true);
+ } else {
+ ptr->mutex.unlock();
}
}
@@ -92,7 +290,9 @@ void QNetworkConfigurationManagerPrivate::configurationRemoved(QNetworkConfigura
{
QMutexLocker locker(&mutex);
+ ptr->mutex.lock();
ptr->isValid = false;
+ ptr->mutex.unlock();
if (!firstUpdate) {
QNetworkConfiguration item;
@@ -117,10 +317,12 @@ void QNetworkConfigurationManagerPrivate::configurationChanged(QNetworkConfigura
bool previous = !onlineConfigurations.isEmpty();
+ ptr->mutex.lock();
if (ptr->state == QNetworkConfiguration::Active)
onlineConfigurations.insert(ptr->id);
else
onlineConfigurations.remove(ptr->id);
+ ptr->mutex.unlock();
bool online = !onlineConfigurations.isEmpty();
@@ -154,6 +356,8 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations()
else
sessionEngines.append(engine);
+ engine->moveToThread(QCoreApplicationPrivate::mainThread());
+
connect(engine, SIGNAL(updateCompleted()),
this, SLOT(updateConfigurations()));
connect(engine, SIGNAL(configurationAdded(QNetworkConfigurationPrivatePointer)),
@@ -165,7 +369,7 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations()
capFlags |= engine->capabilities();
- engine->requestUpdate();
+ QMetaObject::invokeMethod(engine, "requestUpdate");
}
}
@@ -211,7 +415,7 @@ void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate()
for (int i = 0; i < sessionEngines.count(); ++i) {
updatingEngines.insert(i);
- sessionEngines.at(i)->requestUpdate();
+ QMetaObject::invokeMethod(sessionEngines.at(i), "requestUpdate");
}
}
@@ -266,7 +470,7 @@ void QNetworkConfigurationManagerPrivate::pollEngines()
if ((forcedPolling && sessionEngines.at(i)->requiresPolling()) ||
sessionEngines.at(i)->configurationsInUse()) {
pollingEngines.insert(i);
- sessionEngines.at(i)->requestUpdate();
+ QMetaObject::invokeMethod(sessionEngines.at(i), "requestUpdate");
}
}
}
@@ -278,7 +482,7 @@ void QNetworkConfigurationManagerPrivate::enablePolling()
++forcedPolling;
if (forcedPolling == 1)
- startPolling();
+ QMetaObject::invokeMethod(this, "startPolling");
}
void QNetworkConfigurationManagerPrivate::disablePolling()
diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h
index ac8518c..8ec8152 100644
--- a/src/network/bearer/qnetworkconfigmanager_p.h
+++ b/src/network/bearer/qnetworkconfigmanager_p.h
@@ -66,11 +66,16 @@ class QTimer;
class Q_NETWORK_EXPORT QNetworkConfigurationManagerPrivate : public QObject
{
Q_OBJECT
+
public:
QNetworkConfigurationManagerPrivate();
virtual ~QNetworkConfigurationManagerPrivate();
QNetworkConfiguration defaultConfiguration();
+ QList<QNetworkConfiguration> allConfigurations(QNetworkConfiguration::StateFlags filter);
+ QNetworkConfiguration configurationFromIdentifier(const QString &identifier);
+
+ bool isOnline();
QNetworkConfigurationManager::Capabilities capFlags;
@@ -78,7 +83,7 @@ public:
QList<QBearerEngine *> engines();
- void startPolling();
+ Q_INVOKABLE void startPolling();
void enablePolling();
void disablePolling();
diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp
index c4ba406..82669e0 100644
--- a/src/network/bearer/qnetworkconfiguration.cpp
+++ b/src/network/bearer/qnetworkconfiguration.cpp
@@ -246,7 +246,11 @@ bool QNetworkConfiguration::operator==(const QNetworkConfiguration& other) const
*/
QString QNetworkConfiguration::name() const
{
- return d ? d->name : QString();
+ if (!d)
+ return QString();
+
+ QMutexLocker locker(&d->mutex);
+ return d->name;
}
/*!
@@ -255,7 +259,11 @@ QString QNetworkConfiguration::name() const
*/
QString QNetworkConfiguration::identifier() const
{
- return d ? d->id : QString();
+ if (!d)
+ return QString();
+
+ QMutexLocker locker(&d->mutex);
+ return d->id;
}
/*!
@@ -268,7 +276,11 @@ QString QNetworkConfiguration::identifier() const
*/
QNetworkConfiguration::Type QNetworkConfiguration::type() const
{
- return d ? d->type : QNetworkConfiguration::Invalid;
+ if (!d)
+ return QNetworkConfiguration::Invalid;
+
+ QMutexLocker locker(&d->mutex);
+ return d->type;
}
/*!
@@ -283,7 +295,11 @@ QNetworkConfiguration::Type QNetworkConfiguration::type() const
*/
bool QNetworkConfiguration::isValid() const
{
- return d ? d->isValid : false;
+ if (!d)
+ return false;
+
+ QMutexLocker locker(&d->mutex);
+ return d->isValid;
}
/*!
@@ -291,7 +307,11 @@ bool QNetworkConfiguration::isValid() const
*/
QNetworkConfiguration::StateFlags QNetworkConfiguration::state() const
{
- return d ? d->state : QNetworkConfiguration::Undefined;
+ if (!d)
+ return QNetworkConfiguration::Undefined;
+
+ QMutexLocker locker(&d->mutex);
+ return d->state;
}
/*!
@@ -303,7 +323,11 @@ QNetworkConfiguration::StateFlags QNetworkConfiguration::state() const
*/
QNetworkConfiguration::Purpose QNetworkConfiguration::purpose() const
{
- return d ? d->purpose : QNetworkConfiguration::UnknownPurpose;
+ if (!d)
+ return QNetworkConfiguration::UnknownPurpose;
+
+ QMutexLocker locker(&d->mutex);
+ return d->purpose;
}
/*!
@@ -311,7 +335,11 @@ QNetworkConfiguration::Purpose QNetworkConfiguration::purpose() const
*/
bool QNetworkConfiguration::isRoamingAvailable() const
{
- return d ? d->roamingSupported : false;
+ if (!d)
+ return false;
+
+ QMutexLocker locker(&d->mutex);
+ return d->roamingSupported;
}
/*!
@@ -322,15 +350,25 @@ bool QNetworkConfiguration::isRoamingAvailable() const
QList<QNetworkConfiguration> QNetworkConfiguration::children() const
{
QList<QNetworkConfiguration> results;
- if (type() != QNetworkConfiguration::ServiceNetwork || !isValid() )
+
+ if (type() != QNetworkConfiguration::ServiceNetwork || !isValid())
return results;
+ QMutexLocker locker(&d->mutex);
+
QMutableListIterator<QNetworkConfigurationPrivatePointer> iter(d->serviceNetworkMembers);
- while(iter.hasNext()) {
+ while (iter.hasNext()) {
QNetworkConfigurationPrivatePointer p = iter.next();
+
//if we have an invalid member get rid of it -> was deleted earlier on
- if (!p->isValid)
- iter.remove();
+ {
+ QMutexLocker childLocker(&p->mutex);
+
+ if (!p->isValid) {
+ iter.remove();
+ continue;
+ }
+ }
QNetworkConfiguration item;
item.d = p;
diff --git a/src/network/bearer/qnetworkconfiguration_p.h b/src/network/bearer/qnetworkconfiguration_p.h
index 6b40946..6908277 100644
--- a/src/network/bearer/qnetworkconfiguration_p.h
+++ b/src/network/bearer/qnetworkconfiguration_p.h
@@ -54,7 +54,9 @@
//
#include "qnetworkconfiguration.h"
+
#include <QtCore/qshareddata.h>
+#include <QtCore/qmutex.h>
#include <QtNetwork/QNetworkInterface>
QT_BEGIN_NAMESPACE
@@ -64,8 +66,9 @@ class QNetworkConfigurationPrivate : public QSharedData
{
public:
QNetworkConfigurationPrivate ()
- : isValid(false), type(QNetworkConfiguration::Invalid),
- roamingSupported(false), purpose(QNetworkConfiguration::UnknownPurpose), internet(false)
+ : mutex(QMutex::Recursive), type(QNetworkConfiguration::Invalid),
+ purpose(QNetworkConfiguration::UnknownPurpose),
+ isValid(false), roamingSupported(false)
{
}
@@ -77,26 +80,27 @@ public:
virtual QString bearerName() const
{
+ QMutexLocker locker(&mutex);
+
return bearer;
}
- QString bearer;
+ mutable QMutex mutex;
+ QString bearer;
QString name;
-
- bool isValid;
QString id;
+
QNetworkConfiguration::StateFlags state;
QNetworkConfiguration::Type type;
- bool roamingSupported;
QNetworkConfiguration::Purpose purpose;
- bool internet;
-
QList<QNetworkConfigurationPrivatePointer> serviceNetworkMembers;
-private:
+ bool isValid;
+ bool roamingSupported;
+private:
// disallow detaching
QNetworkConfigurationPrivate &operator=(const QNetworkConfigurationPrivate &other);
QNetworkConfigurationPrivate(const QNetworkConfigurationPrivate &other);
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index ce2aee1..4010710 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -153,6 +153,7 @@ static unsigned long id_function()
QSslSocketBackendPrivate::QSslSocketBackendPrivate()
: ssl(0),
ctx(0),
+ pkey(0),
readBio(0),
writeBio(0),
session(0)
@@ -311,11 +312,14 @@ init_context:
}
// Load private key
- EVP_PKEY *pkey = q_EVP_PKEY_new();
+ pkey = q_EVP_PKEY_new();
+ // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free.
+ // this lead to a memory leak. Now we use the *_set1_* functions which do not
+ // take ownership of the RSA/DSA key instance because the QSslKey already has ownership.
if (configuration.privateKey.algorithm() == QSsl::Rsa)
- q_EVP_PKEY_assign_RSA(pkey, (RSA *)configuration.privateKey.handle());
+ q_EVP_PKEY_set1_RSA(pkey, (RSA *)configuration.privateKey.handle());
else
- q_EVP_PKEY_assign_DSA(pkey, (DSA *)configuration.privateKey.handle());
+ q_EVP_PKEY_set1_DSA(pkey, (DSA *)configuration.privateKey.handle());
if (!q_SSL_CTX_use_PrivateKey(ctx, pkey)) {
q->setErrorString(QSslSocket::tr("Error loading private key, %1").arg(SSL_ERRORSTR()));
emit q->error(QAbstractSocket::UnknownSocketError);
@@ -922,6 +926,11 @@ void QSslSocketBackendPrivate::disconnected()
q_SSL_CTX_free(ctx);
ctx = 0;
}
+ if (pkey) {
+ q_EVP_PKEY_free(pkey);
+ pkey = 0;
+ }
+
}
QSslCipher QSslSocketBackendPrivate::sessionCipher() const
diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h
index 836f064..3c08757 100644
--- a/src/network/ssl/qsslsocket_openssl_p.h
+++ b/src/network/ssl/qsslsocket_openssl_p.h
@@ -97,6 +97,7 @@ public:
bool initSslContext();
SSL *ssl;
SSL_CTX *ctx;
+ EVP_PKEY *pkey;
BIO *readBio;
BIO *writeBio;
SSL_SESSION *session;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 94cc9d2..d2eb6f1 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -119,6 +119,8 @@ DEFINEFUNC2(char *, ERR_error_string, unsigned long a, a, char *b, b, return 0,
DEFINEFUNC(unsigned long, ERR_get_error, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return)
+DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return)
+DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return)
DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG)
DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return 0, return)
DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return 0, return)
@@ -510,6 +512,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(ERR_get_error, 749, libs.second )
RESOLVEFUNC(EVP_des_ede3_cbc, 919, libs.second )
RESOLVEFUNC(EVP_PKEY_assign, 859, libs.second )
+ RESOLVEFUNC(EVP_PKEY_set1_RSA, 880, libs.second )
+ RESOLVEFUNC(EVP_PKEY_set1_DSA, 879, libs.second )
RESOLVEFUNC(EVP_PKEY_free, 867, libs.second )
RESOLVEFUNC(EVP_PKEY_get1_DSA, 869, libs.second )
RESOLVEFUNC(EVP_PKEY_get1_RSA, 870, libs.second )
@@ -632,6 +636,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(ERR_get_error)
RESOLVEFUNC(EVP_des_ede3_cbc)
RESOLVEFUNC(EVP_PKEY_assign)
+ RESOLVEFUNC(EVP_PKEY_set1_RSA)
+ RESOLVEFUNC(EVP_PKEY_set1_DSA)
RESOLVEFUNC(EVP_PKEY_free)
RESOLVEFUNC(EVP_PKEY_get1_DSA)
RESOLVEFUNC(EVP_PKEY_get1_RSA)
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index c93d547..ef61dbf 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -227,6 +227,8 @@ char *q_ERR_error_string(unsigned long a, char *b);
unsigned long q_ERR_get_error();
const EVP_CIPHER *q_EVP_des_ede3_cbc();
int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c);
+int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b);
+int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b);
void q_EVP_PKEY_free(EVP_PKEY *a);
RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a);
DSA *q_EVP_PKEY_get1_DSA(EVP_PKEY *a);