summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Petersson <martin.petersson@nokia.com>2011-12-19 11:02:46 +0100
committerQt by Nokia <qt-info@nokia.com>2011-12-22 00:47:03 +0100
commit54c487cdd2950ac447f9164a9fea2d0468d87433 (patch)
treed3797a2a8495a9d0e4a3119b72949830e7761604
parentbc8f25c7e6ab73441c46ea41362a054843b42ec3 (diff)
QNetworkAccessManager: delay IPv4 or IPv6 based on getaddrinfo order
Instead of always delaying IPv4 when we have both Ipv4 and IPv6 we should use the order we get from getaddrinfo to descide which one that should be delayed. Task-number: QTBUG-23066 Change-Id: Ibe8c4d7000abd6e57fe8c6afac8a4a843e17ff27 Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp42
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h7
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp4
3 files changed, 35 insertions, 18 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index b43f2b9bcd..b4004eae14 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -81,7 +81,7 @@ const int QHttpNetworkConnectionPrivate::defaultRePipelineLength = 2;
QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt)
: state(RunningState),
networkLayerState(Unknown),
- hostName(hostName), port(port), encrypt(encrypt),
+ hostName(hostName), port(port), encrypt(encrypt), delayIpv4(true),
channelCount(defaultChannelCount)
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
@@ -92,7 +92,7 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host
QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt)
: state(RunningState), networkLayerState(Unknown),
- hostName(hostName), port(port), encrypt(encrypt),
+ hostName(hostName), port(port), encrypt(encrypt), delayIpv4(true),
channelCount(channelCount)
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
@@ -126,8 +126,8 @@ void QHttpNetworkConnectionPrivate::init()
#endif
channels[i].init();
}
- ipv4ConnectTimer.setSingleShot(true);
- QObject::connect(&ipv4ConnectTimer, SIGNAL(timeout()), q, SLOT(_q_connectIPv4Channel()));
+ delayedConnectionTimer.setSingleShot(true);
+ QObject::connect(&delayedConnectionTimer, SIGNAL(timeout()), q, SLOT(_q_connectDelayedChannel()));
}
void QHttpNetworkConnectionPrivate::pauseConnection()
@@ -189,9 +189,9 @@ bool QHttpNetworkConnectionPrivate::shouldEmitChannelError(QAbstractSocket *sock
int otherSocket = (i == 0 ? 1 : 0);
// If the IPv4 connection still isn't started we need to start it now.
- if (ipv4ConnectTimer.isActive()) {
- ipv4ConnectTimer.stop();
- channels[0].ensureConnection();
+ if (delayedConnectionTimer.isActive()) {
+ delayedConnectionTimer.stop();
+ channels[otherSocket].ensureConnection();
}
if (channelCount == 1) {
@@ -974,12 +974,22 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(QHostInfo info)
{
bool bIpv4 = false;
bool bIpv6 = false;
+ bool foundAddress = false;
foreach (QHostAddress address, info.addresses()) {
- if (address.protocol() == QAbstractSocket::IPv4Protocol)
+ if (address.protocol() == QAbstractSocket::IPv4Protocol) {
+ if (!foundAddress) {
+ foundAddress = true;
+ delayIpv4 = false;
+ }
bIpv4 = true;
- else if (address.protocol() == QAbstractSocket::IPv6Protocol)
+ } else if (address.protocol() == QAbstractSocket::IPv6Protocol) {
+ if (!foundAddress) {
+ foundAddress = true;
+ delayIpv4 = true;
+ }
bIpv6 = true;
+ }
}
if (bIpv4 && bIpv6)
@@ -1030,8 +1040,11 @@ void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup()
else if (networkSession->configuration().bearerType() == QNetworkConfiguration::BearerHSPA)
timeout = 400;
#endif
- ipv4ConnectTimer.start(timeout);
- channels[1].ensureConnection();
+ delayedConnectionTimer.start(timeout);
+ if (delayIpv4)
+ channels[1].ensureConnection();
+ else
+ channels[0].ensureConnection();
} else {
networkLayerState = InProgress;
channels[0].networkLayerPreference = QAbstractSocket::AnyIPProtocol;
@@ -1039,9 +1052,12 @@ void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup()
}
}
-void QHttpNetworkConnectionPrivate::_q_connectIPv4Channel()
+void QHttpNetworkConnectionPrivate::_q_connectDelayedChannel()
{
- channels[0].ensureConnection();
+ if (delayIpv4)
+ channels[0].ensureConnection();
+ else
+ channels[1].ensureConnection();
}
#ifndef QT_NO_BEARERMANAGEMENT
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 18ec92a07a..75da382145 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -135,7 +135,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest())
Q_PRIVATE_SLOT(d_func(), void _q_hostLookupFinished(QHostInfo))
- Q_PRIVATE_SLOT(d_func(), void _q_connectIPv4Channel())
+ Q_PRIVATE_SLOT(d_func(), void _q_connectDelayedChannel())
};
@@ -198,7 +198,7 @@ public:
void _q_startNextRequest(); // send the next request from the queue
void _q_hostLookupFinished(QHostInfo info);
- void _q_connectIPv4Channel();
+ void _q_connectDelayedChannel();
void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request);
@@ -210,9 +210,10 @@ public:
QString hostName;
quint16 port;
bool encrypt;
+ bool delayIpv4;
const int channelCount;
- QTimer ipv4ConnectTimer;
+ QTimer delayedConnectionTimer;
QHttpNetworkConnectionChannel *channels; // parallel connections to the server
bool shouldEmitChannelError(QAbstractSocket *socket);
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index edf66ff1aa..ab178be582 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -954,8 +954,8 @@ void QHttpNetworkConnectionChannel::_q_connected()
// For the Happy Eyeballs we need to check if this is the first channel to connect.
if (!pendingEncrypt) {
if (connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::InProgress) {
- if (connection->d_func()->ipv4ConnectTimer.isActive())
- connection->d_func()->ipv4ConnectTimer.stop();
+ if (connection->d_func()->delayedConnectionTimer.isActive())
+ connection->d_func()->delayedConnectionTimer.stop();
if (networkLayerPreference == QAbstractSocket::IPv4Protocol)
connection->d_func()->networkLayerState = QHttpNetworkConnectionPrivate::IPv4;
else if (networkLayerPreference == QAbstractSocket::IPv6Protocol)