summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/access.pri59
-rw-r--r--src/network/access/http2/hpack.cpp22
-rw-r--r--src/network/access/http2/http2streams_p.h2
-rw-r--r--src/network/access/http2/huffman_p.h13
-rw-r--r--src/network/access/qabstractnetworkcache.h2
-rw-r--r--src/network/access/qabstractprotocolhandler.cpp4
-rw-r--r--src/network/access/qabstractprotocolhandler_p.h4
-rw-r--r--src/network/access/qhsts.cpp16
-rw-r--r--src/network/access/qhsts_p.h5
-rw-r--r--src/network/access/qhttp2protocolhandler.cpp7
-rw-r--r--src/network/access/qhttp2protocolhandler_p.h6
-rw-r--r--src/network/access/qhttpmultipart.h6
-rw-r--r--src/network/access/qhttpmultipart_p.h20
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp12
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h7
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp30
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel_p.h6
-rw-r--r--src/network/access/qhttpnetworkheader.cpp4
-rw-r--r--src/network/access/qhttpnetworkheader_p.h8
-rw-r--r--src/network/access/qhttpnetworkreply.cpp4
-rw-r--r--src/network/access/qhttpnetworkreply_p.h25
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp18
-rw-r--r--src/network/access/qhttpnetworkrequest_p.h29
-rw-r--r--src/network/access/qhttpprotocolhandler.cpp4
-rw-r--r--src/network/access/qhttpprotocolhandler_p.h10
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp12
-rw-r--r--src/network/access/qhttpthreaddelegate_p.h16
-rw-r--r--src/network/access/qnetworkaccessauthenticationmanager.cpp2
-rw-r--r--src/network/access/qnetworkaccesscache_p.h2
-rw-r--r--src/network/access/qnetworkaccesscachebackend_p.h6
-rw-r--r--src/network/access/qnetworkaccessdebugpipebackend_p.h10
-rw-r--r--src/network/access/qnetworkaccessfilebackend_p.h10
-rw-r--r--src/network/access/qnetworkaccessftpbackend.cpp2
-rw-r--r--src/network/access/qnetworkaccessftpbackend_p.h10
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp20
-rw-r--r--src/network/access/qnetworkaccessmanager.h13
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h2
-rw-r--r--src/network/access/qnetworkcookiejar.h2
-rw-r--r--src/network/access/qnetworkdiskcache.h18
-rw-r--r--src/network/access/qnetworkfile_p.h2
-rw-r--r--src/network/access/qnetworkreply.h8
-rw-r--r--src/network/access/qnetworkreplydataimpl_p.h12
-rw-r--r--src/network/access/qnetworkreplyfileimpl_p.h12
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp14
-rw-r--r--src/network/access/qnetworkreplyhttpimpl_p.h28
-rw-r--r--src/network/access/qnetworkreplyimpl_p.h24
-rw-r--r--src/network/access/qnetworkrequest.cpp12
-rw-r--r--src/network/access/qnetworkrequest.h1
-rw-r--r--src/network/access/qspdyprotocolhandler.cpp4
-rw-r--r--src/network/access/qspdyprotocolhandler_p.h12
-rw-r--r--src/network/bearer/qnetworkconfigmanager.h2
-rw-r--r--src/network/bearer/qnetworksession.h6
-rw-r--r--src/network/configure.json34
-rw-r--r--src/network/kernel/kernel.pri29
-rw-r--r--src/network/kernel/qdnslookup.h8
-rw-r--r--src/network/kernel/qdnslookup_p.h4
-rw-r--r--src/network/kernel/qhostaddress.cpp222
-rw-r--r--src/network/kernel/qhostaddress.h6
-rw-r--r--src/network/kernel/qhostaddress_p.h45
-rw-r--r--src/network/kernel/qhostinfo_p.h4
-rw-r--r--src/network/kernel/qhostinfo_unix.cpp74
-rw-r--r--src/network/kernel/qnetworkdatagram.h2
-rw-r--r--src/network/kernel/qnetworkinterface.cpp318
-rw-r--r--src/network/kernel/qnetworkinterface.h43
-rw-r--r--src/network/kernel/qnetworkinterface_linux.cpp443
-rw-r--r--src/network/kernel/qnetworkinterface_p.h23
-rw-r--r--src/network/kernel/qnetworkinterface_uikit_p.h241
-rw-r--r--src/network/kernel/qnetworkinterface_unix.cpp187
-rw-r--r--src/network/kernel/qnetworkinterface_unix_p.h102
-rw-r--r--src/network/kernel/qnetworkinterface_win.cpp58
-rw-r--r--src/network/kernel/qnetworkproxy.cpp12
-rw-r--r--src/network/network.pro2
-rw-r--r--src/network/socket/qabstractsocket.cpp33
-rw-r--r--src/network/socket/qabstractsocket.h27
-rw-r--r--src/network/socket/qabstractsocket_p.h3
-rw-r--r--src/network/socket/qabstractsocketengine_p.h3
-rw-r--r--src/network/socket/qhttpsocketengine.cpp21
-rw-r--r--src/network/socket/qhttpsocketengine_p.h74
-rw-r--r--src/network/socket/qlocalserver.h4
-rw-r--r--src/network/socket/qlocalsocket.h22
-rw-r--r--src/network/socket/qlocalsocket_p.h2
-rw-r--r--src/network/socket/qlocalsocket_tcp.cpp5
-rw-r--r--src/network/socket/qlocalsocket_unix.cpp5
-rw-r--r--src/network/socket/qnativesocketengine_p.h68
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp30
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp26
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp4
-rw-r--r--src/network/socket/qnet_unix_p.h3
-rw-r--r--src/network/socket/qsctpserver.h2
-rw-r--r--src/network/socket/qsctpserver_p.h2
-rw-r--r--src/network/socket/qsctpsocket.h8
-rw-r--r--src/network/socket/qsctpsocket_p.h6
-rw-r--r--src/network/socket/qsocks5socketengine.cpp2
-rw-r--r--src/network/socket/qsocks5socketengine_p.h78
-rw-r--r--src/network/socket/qtcpserver.h6
-rw-r--r--src/network/socket/qtcpserver_p.h12
-rw-r--r--src/network/socket/qtcpsocket.h6
-rw-r--r--src/network/socket/qudpsocket.h4
-rw-r--r--src/network/socket/socket.pri9
-rw-r--r--src/network/ssl/qsslcertificate.h2
-rw-r--r--src/network/ssl/qssldiffiehellmanparameters_openssl.cpp4
-rw-r--r--src/network/ssl/qsslkey_qt.cpp7
-rw-r--r--src/network/ssl/qsslsocket.cpp14
-rw-r--r--src/network/ssl/qsslsocket.h38
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp70
-rw-r--r--src/network/ssl/qsslsocket_mac_p.h16
-rw-r--r--src/network/ssl/qsslsocket_openssl_p.h18
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h8
-rw-r--r--src/network/ssl/qsslsocket_opensslpre11.cpp3
-rw-r--r--src/network/ssl/qsslsocket_p.h9
-rw-r--r--src/network/ssl/qsslsocket_winrt.cpp2
-rw-r--r--src/network/ssl/qsslsocket_winrt_p.h16
113 files changed, 2417 insertions, 699 deletions
diff --git a/src/network/access/access.pri b/src/network/access/access.pri
index e8669dcec8..1d6a04a424 100644
--- a/src/network/access/access.pri
+++ b/src/network/access/access.pri
@@ -1,14 +1,6 @@
# Qt network access module
HEADERS += \
- access/qhttpnetworkheader_p.h \
- access/qhttpnetworkrequest_p.h \
- access/qhttpnetworkreply_p.h \
- access/qhttpnetworkconnection_p.h \
- access/qhttpnetworkconnectionchannel_p.h \
- access/qabstractprotocolhandler_p.h \
- access/qhttpprotocolhandler_p.h \
- access/qspdyprotocolhandler_p.h \
access/qnetworkaccessauthenticationmanager_p.h \
access/qnetworkaccessmanager.h \
access/qnetworkaccessmanager_p.h \
@@ -27,28 +19,15 @@ HEADERS += \
access/qnetworkreply_p.h \
access/qnetworkreplyimpl_p.h \
access/qnetworkreplydataimpl_p.h \
- access/qnetworkreplyhttpimpl_p.h \
access/qnetworkreplyfileimpl_p.h \
access/qabstractnetworkcache_p.h \
access/qabstractnetworkcache.h \
- access/qhttpthreaddelegate_p.h \
- access/qhttpmultipart.h \
- access/qhttpmultipart_p.h \
access/qnetworkfile_p.h \
- access/qhttp2protocolhandler_p.h \
access/qhsts_p.h \
access/qhstspolicy.h \
access/qhstsstore_p.h
SOURCES += \
- access/qhttpnetworkheader.cpp \
- access/qhttpnetworkrequest.cpp \
- access/qhttpnetworkreply.cpp \
- access/qhttpnetworkconnection.cpp \
- access/qhttpnetworkconnectionchannel.cpp \
- access/qabstractprotocolhandler.cpp \
- access/qhttpprotocolhandler.cpp \
- access/qspdyprotocolhandler.cpp \
access/qnetworkaccessauthenticationmanager.cpp \
access/qnetworkaccessmanager.cpp \
access/qnetworkaccesscache.cpp \
@@ -62,13 +41,9 @@ SOURCES += \
access/qnetworkreply.cpp \
access/qnetworkreplyimpl.cpp \
access/qnetworkreplydataimpl.cpp \
- access/qnetworkreplyhttpimpl.cpp \
access/qnetworkreplyfileimpl.cpp \
access/qabstractnetworkcache.cpp \
- access/qhttpthreaddelegate.cpp \
- access/qhttpmultipart.cpp \
access/qnetworkfile.cpp \
- access/qhttp2protocolhandler.cpp \
access/qhsts.cpp \
access/qhstspolicy.cpp \
access/qhstsstore.cpp
@@ -94,4 +69,36 @@ qtConfig(networkdiskcache) {
mac: LIBS_PRIVATE += -framework Security
include($$PWD/../../3rdparty/zlib_dependency.pri)
-include($$PWD/http2/http2.pri)
+
+qtConfig(http) {
+ include($$PWD/http2/http2.pri)
+
+ SOURCES += \
+ access/qabstractprotocolhandler.cpp \
+ access/qhttp2protocolhandler.cpp \
+ access/qhttpmultipart.cpp \
+ access/qhttpnetworkconnection.cpp \
+ access/qhttpnetworkconnectionchannel.cpp \
+ access/qhttpnetworkheader.cpp \
+ access/qhttpnetworkreply.cpp \
+ access/qhttpnetworkrequest.cpp \
+ access/qhttpprotocolhandler.cpp \
+ access/qhttpthreaddelegate.cpp \
+ access/qnetworkreplyhttpimpl.cpp \
+ access/qspdyprotocolhandler.cpp
+
+ HEADERS += \
+ access/qabstractprotocolhandler_p.h \
+ access/qhttp2protocolhandler_p.h \
+ access/qhttpmultipart.h \
+ access/qhttpmultipart_p.h \
+ access/qhttpnetworkconnection_p.h \
+ access/qhttpnetworkconnectionchannel_p.h \
+ access/qhttpnetworkheader_p.h \
+ access/qhttpnetworkreply_p.h \
+ access/qhttpnetworkrequest_p.h \
+ access/qhttpprotocolhandler_p.h \
+ access/qhttpthreaddelegate_p.h \
+ access/qnetworkreplyhttpimpl_p.h \
+ access/qspdyprotocolhandler_p.h
+}
diff --git a/src/network/access/http2/hpack.cpp b/src/network/access/http2/hpack.cpp
index 95e6f9051b..2d324d5092 100644
--- a/src/network/access/http2/hpack.cpp
+++ b/src/network/access/http2/hpack.cpp
@@ -67,18 +67,6 @@ HeaderSize header_size(const HttpHeader &header)
struct BitPattern
{
- BitPattern()
- : value(),
- bitLength()
- {
- }
-
- BitPattern(uchar v, uchar len)
- : value(v),
- bitLength(len)
- {
- }
-
uchar value;
uchar bitLength;
};
@@ -102,11 +90,11 @@ using StreamError = BitIStream::Error;
// It's always 1 or 0 actually, but the number of bits to extract
// from the input stream - differs.
-const BitPattern Indexed(1, 1);
-const BitPattern LiteralIncrementalIndexing(1, 2);
-const BitPattern LiteralNoIndexing(0, 4);
-const BitPattern LiteralNeverIndexing(1, 4);
-const BitPattern SizeUpdate(1, 3);
+const BitPattern Indexed = {1, 1};
+const BitPattern LiteralIncrementalIndexing = {1, 2};
+const BitPattern LiteralNoIndexing = {0, 4};
+const BitPattern LiteralNeverIndexing = {1, 4};
+const BitPattern SizeUpdate = {1, 3};
bool is_literal_field(const BitPattern &pattern)
{
diff --git a/src/network/access/http2/http2streams_p.h b/src/network/access/http2/http2streams_p.h
index 8465486ae8..0be6b3b253 100644
--- a/src/network/access/http2/http2streams_p.h
+++ b/src/network/access/http2/http2streams_p.h
@@ -62,6 +62,8 @@
#include <vector>
+QT_REQUIRE_CONFIG(http);
+
QT_BEGIN_NAMESPACE
class QNonContiguousByteDevice;
diff --git a/src/network/access/http2/huffman_p.h b/src/network/access/http2/huffman_p.h
index 7195661664..c5324d42b1 100644
--- a/src/network/access/http2/huffman_p.h
+++ b/src/network/access/http2/huffman_p.h
@@ -62,19 +62,6 @@ namespace HPack
struct CodeEntry
{
- CodeEntry() : byteValue(),
- huffmanCode(),
- bitLength()
- {
- }
-
- CodeEntry(quint32 val, quint32 code, quint32 len)
- : byteValue(val),
- huffmanCode(code),
- bitLength(len)
- {
- }
-
quint32 byteValue;
quint32 huffmanCode;
quint32 bitLength;
diff --git a/src/network/access/qabstractnetworkcache.h b/src/network/access/qabstractnetworkcache.h
index 33b0bc4ce3..678bae2d6e 100644
--- a/src/network/access/qabstractnetworkcache.h
+++ b/src/network/access/qabstractnetworkcache.h
@@ -131,7 +131,7 @@ public Q_SLOTS:
virtual void clear() = 0;
protected:
- explicit QAbstractNetworkCache(QObject *parent = Q_NULLPTR);
+ explicit QAbstractNetworkCache(QObject *parent = nullptr);
QAbstractNetworkCache(QAbstractNetworkCachePrivate &dd, QObject *parent);
private:
diff --git a/src/network/access/qabstractprotocolhandler.cpp b/src/network/access/qabstractprotocolhandler.cpp
index d408f3b37a..f15dfe6899 100644
--- a/src/network/access/qabstractprotocolhandler.cpp
+++ b/src/network/access/qabstractprotocolhandler.cpp
@@ -40,8 +40,6 @@
#include <private/qabstractprotocolhandler_p.h>
#include <private/qhttpnetworkconnectionchannel_p.h>
-#ifndef QT_NO_HTTP
-
QT_BEGIN_NAMESPACE
QAbstractProtocolHandler::QAbstractProtocolHandler(QHttpNetworkConnectionChannel *channel)
@@ -62,5 +60,3 @@ void QAbstractProtocolHandler::setReply(QHttpNetworkReply *reply)
}
QT_END_NAMESPACE
-
-#endif // QT_NO_HTTP
diff --git a/src/network/access/qabstractprotocolhandler_p.h b/src/network/access/qabstractprotocolhandler_p.h
index 30814d6737..04a07734dd 100644
--- a/src/network/access/qabstractprotocolhandler_p.h
+++ b/src/network/access/qabstractprotocolhandler_p.h
@@ -53,7 +53,7 @@
#include <QtNetwork/private/qtnetworkglobal_p.h>
-#ifndef QT_NO_HTTP
+QT_REQUIRE_CONFIG(http);
QT_BEGIN_NAMESPACE
@@ -81,6 +81,4 @@ protected:
QT_END_NAMESPACE
-#endif // QT_NO_HTTP
-
#endif // QABSTRACTPROTOCOLHANDLER_H
diff --git a/src/network/access/qhsts.cpp b/src/network/access/qhsts.cpp
index 6a731afc2f..43a8a3663e 100644
--- a/src/network/access/qhsts.cpp
+++ b/src/network/access/qhsts.cpp
@@ -136,7 +136,7 @@ void QHstsCache::updateKnownHost(const QString &host, const QDateTime &expires,
return;
}
- knownHosts.insert(pos, hostName, newPolicy);
+ knownHosts.insert(pos, {hostName, newPolicy});
if (hstsStore)
hstsStore->addToObserved(newPolicy);
return;
@@ -144,8 +144,8 @@ void QHstsCache::updateKnownHost(const QString &host, const QDateTime &expires,
if (newPolicy.isExpired())
knownHosts.erase(pos);
- else if (*pos != newPolicy)
- *pos = std::move(newPolicy);
+ else if (pos->second != newPolicy)
+ pos->second = std::move(newPolicy);
else
return;
@@ -185,13 +185,13 @@ bool QHstsCache::isKnownHost(const QUrl &url) const
while (nameToTest.fragment.size()) {
auto const pos = knownHosts.find(nameToTest);
if (pos != knownHosts.end()) {
- if (pos.value().isExpired()) {
+ if (pos->second.isExpired()) {
knownHosts.erase(pos);
if (hstsStore) {
// Inform our store that this policy has expired.
- hstsStore->addToObserved(pos.value());
+ hstsStore->addToObserved(pos->second);
}
- } else if (!superDomainMatch || pos.value().includesSubDomains()) {
+ } else if (!superDomainMatch || pos->second.includesSubDomains()) {
return true;
}
}
@@ -215,9 +215,9 @@ void QHstsCache::clear()
QVector<QHstsPolicy> QHstsCache::policies() const
{
QVector<QHstsPolicy> values;
- values.reserve(knownHosts.size());
+ values.reserve(int(knownHosts.size()));
for (const auto &host : knownHosts)
- values << host;
+ values << host.second;
return values;
}
diff --git a/src/network/access/qhsts_p.h b/src/network/access/qhsts_p.h
index 2feb73b446..bc8708341d 100644
--- a/src/network/access/qhsts_p.h
+++ b/src/network/access/qhsts_p.h
@@ -61,7 +61,8 @@
#include <QtCore/qglobal.h>
#include <QtCore/qpair.h>
#include <QtCore/qurl.h>
-#include <QtCore/qmap.h>
+
+#include <map>
QT_BEGIN_NAMESPACE
@@ -117,7 +118,7 @@ private:
QStringRef fragment;
};
- mutable QMap<HostName, QHstsPolicy> knownHosts;
+ mutable std::map<HostName, QHstsPolicy> knownHosts;
QHstsStore *hstsStore = nullptr;
};
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
index 42f1343c52..0cdcee6b59 100644
--- a/src/network/access/qhttp2protocolhandler.cpp
+++ b/src/network/access/qhttp2protocolhandler.cpp
@@ -40,8 +40,6 @@
#include "qhttpnetworkconnection_p.h"
#include "qhttp2protocolhandler_p.h"
-#if !defined(QT_NO_HTTP)
-
#include "http2/bitstreams_p.h"
#include <private/qnoncontiguousbytedevice_p.h>
@@ -88,7 +86,8 @@ HPack::HttpHeader build_headers(const QHttpNetworkRequest &request, quint32 maxH
if (size.second > maxHeaderListSize)
return HttpHeader(); // Bad, we cannot send this request ...
- for (const auto &field : request.header()) {
+ const auto requestHeader = request.header();
+ for (const auto &field : requestHeader) {
const HeaderSize delta = entry_size(field.first, field.second);
if (!delta.first) // Overflow???
break;
@@ -1511,5 +1510,3 @@ void QHttp2ProtocolHandler::closeSession()
}
QT_END_NAMESPACE
-
-#endif // !defined(QT_NO_HTTP)
diff --git a/src/network/access/qhttp2protocolhandler_p.h b/src/network/access/qhttp2protocolhandler_p.h
index dd209bd0ef..9165808302 100644
--- a/src/network/access/qhttp2protocolhandler_p.h
+++ b/src/network/access/qhttp2protocolhandler_p.h
@@ -55,8 +55,6 @@
#include <private/qabstractprotocolhandler_p.h>
#include <private/qhttpnetworkrequest_p.h>
-#if !defined(QT_NO_HTTP)
-
#include <private/http2protocol_p.h>
#include <private/http2streams_p.h>
#include <private/http2frames_p.h>
@@ -75,6 +73,8 @@
#include <deque>
#include <set>
+QT_REQUIRE_CONFIG(http);
+
QT_BEGIN_NAMESPACE
class QHttp2ProtocolHandler : public QObject, public QAbstractProtocolHandler
@@ -228,6 +228,4 @@ private:
QT_END_NAMESPACE
-#endif // !defined(QT_NO_HTTP)
-
#endif
diff --git a/src/network/access/qhttpmultipart.h b/src/network/access/qhttpmultipart.h
index 6d4531b099..78585a704d 100644
--- a/src/network/access/qhttpmultipart.h
+++ b/src/network/access/qhttpmultipart.h
@@ -46,6 +46,8 @@
#include <QtCore/QIODevice>
#include <QtNetwork/QNetworkRequest>
+QT_REQUIRE_CONFIG(http);
+
QT_BEGIN_NAMESPACE
@@ -98,8 +100,8 @@ public:
AlternativeType
};
- explicit QHttpMultiPart(QObject *parent = Q_NULLPTR);
- explicit QHttpMultiPart(ContentType contentType, QObject *parent = Q_NULLPTR);
+ explicit QHttpMultiPart(QObject *parent = nullptr);
+ explicit QHttpMultiPart(ContentType contentType, QObject *parent = nullptr);
~QHttpMultiPart();
void append(const QHttpPart &httpPart);
diff --git a/src/network/access/qhttpmultipart_p.h b/src/network/access/qhttpmultipart_p.h
index a03df9cb13..363e0b346c 100644
--- a/src/network/access/qhttpmultipart_p.h
+++ b/src/network/access/qhttpmultipart_p.h
@@ -56,6 +56,8 @@
#include "qnetworkrequest_p.h" // for deriving QHttpPartPrivate from QNetworkHeadersPrivate
#include "private/qobject_p.h"
+QT_REQUIRE_CONFIG(http);
+
QT_BEGIN_NAMESPACE
@@ -124,30 +126,30 @@ public:
~QHttpMultiPartIODevice() {
}
- virtual bool atEnd() const Q_DECL_OVERRIDE {
+ virtual bool atEnd() const override {
return readPointer == size();
}
- virtual qint64 bytesAvailable() const Q_DECL_OVERRIDE {
+ virtual qint64 bytesAvailable() const override {
return size() - readPointer;
}
- virtual void close() Q_DECL_OVERRIDE {
+ virtual void close() override {
readPointer = 0;
partOffsets.clear();
deviceSize = -1;
QIODevice::close();
}
- virtual qint64 bytesToWrite() const Q_DECL_OVERRIDE {
+ virtual qint64 bytesToWrite() const override {
return 0;
}
- virtual qint64 size() const Q_DECL_OVERRIDE;
- virtual bool isSequential() const Q_DECL_OVERRIDE;
- virtual bool reset() Q_DECL_OVERRIDE;
- virtual qint64 readData(char *data, qint64 maxSize) Q_DECL_OVERRIDE;
- virtual qint64 writeData(const char *data, qint64 maxSize) Q_DECL_OVERRIDE;
+ virtual qint64 size() const override;
+ virtual bool isSequential() const override;
+ virtual bool reset() override;
+ virtual qint64 readData(char *data, qint64 maxSize) override;
+ virtual qint64 writeData(const char *data, qint64 maxSize) override;
QHttpMultiPartPrivate *multiPart;
qint64 readPointer;
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index e6a15ccfc4..842a73a2f9 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -53,8 +53,6 @@
#include <qpair.h>
#include <qdebug.h>
-#ifndef QT_NO_HTTP
-
#ifndef QT_NO_SSL
# include <private/qsslsocket_p.h>
# include <QtNetwork/qsslkey.h>
@@ -83,10 +81,11 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host
networkLayerState(Unknown),
hostName(hostName), port(port), encrypt(encrypt), delayIpv4(true)
, activeChannelCount(type == QHttpNetworkConnection::ConnectionTypeHTTP2
+ || type == QHttpNetworkConnection::ConnectionTypeHTTP2Direct
#ifndef QT_NO_SSL
- || type == QHttpNetworkConnection::ConnectionTypeSPDY
+ || type == QHttpNetworkConnection::ConnectionTypeSPDY
#endif
- ? 1 : defaultHttpChannelCount)
+ ? 1 : defaultHttpChannelCount)
, channelCount(defaultHttpChannelCount)
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
@@ -122,7 +121,7 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate()
{
for (int i = 0; i < channelCount; ++i) {
if (channels[i].socket) {
- QObject::disconnect(channels[i].socket, Q_NULLPTR, &channels[i], Q_NULLPTR);
+ QObject::disconnect(channels[i].socket, nullptr, &channels[i], nullptr);
channels[i].socket->close();
delete channels[i].socket;
}
@@ -1065,6 +1064,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
}
break;
}
+ case QHttpNetworkConnection::ConnectionTypeHTTP2Direct:
case QHttpNetworkConnection::ConnectionTypeHTTP2:
case QHttpNetworkConnection::ConnectionTypeSPDY: {
if (channels[0].spdyRequestsToSend.isEmpty() && channels[0].switchedToHttp2)
@@ -1554,5 +1554,3 @@ void QHttpNetworkConnectionPrivate::emitProxyAuthenticationRequired(const QHttpN
QT_END_NAMESPACE
#include "moc_qhttpnetworkconnection_p.cpp"
-
-#endif // QT_NO_HTTP
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index d3450417aa..91827a6eb1 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -71,7 +71,7 @@
#include <private/qhttpnetworkconnectionchannel_p.h>
-#ifndef QT_NO_HTTP
+QT_REQUIRE_CONFIG(http);
QT_BEGIN_NAMESPACE
@@ -94,7 +94,8 @@ public:
enum ConnectionType {
ConnectionTypeHTTP,
ConnectionTypeSPDY,
- ConnectionTypeHTTP2
+ ConnectionTypeHTTP2,
+ ConnectionTypeHTTP2Direct
};
#ifndef QT_NO_BEARERMANAGEMENT
@@ -295,6 +296,4 @@ public:
QT_END_NAMESPACE
-#endif // QT_NO_HTTP
-
#endif
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 094a48a603..0ac14c78f6 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -45,8 +45,6 @@
#include <qpair.h>
#include <qdebug.h>
-#ifndef QT_NO_HTTP
-
#include <private/qhttp2protocolhandler_p.h>
#include <private/qhttpprotocolhandler_p.h>
#include <private/qspdyprotocolhandler_p.h>
@@ -438,6 +436,10 @@ void QHttpNetworkConnectionChannel::allDone()
return;
}
+ // For clear text HTTP/2 we tried to upgrade from HTTP/1.1 to HTTP/2; for
+ // ConnectionTypeHTTP2Direct we can never be here in case of failure
+ // (after an attempt to read HTTP/1.1 as HTTP/2 frames) or we have a normal
+ // HTTP/2 response and thus can skip this test:
if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
&& !ssl && !switchedToHttp2) {
if (Http2::is_protocol_upgraded(*reply)) {
@@ -891,6 +893,14 @@ void QHttpNetworkConnectionChannel::_q_connected()
connection->setSslContext(socketSslContext);
}
#endif
+ } else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
+ state = QHttpNetworkConnectionChannel::IdleState;
+ protocolHandler.reset(new QHttp2ProtocolHandler(this));
+ if (spdyRequestsToSend.count() > 0) {
+ // In case our peer has sent us its settings (window size, max concurrent streams etc.)
+ // let's give _q_receiveReply a chance to read them first ('invokeMethod', QueuedConnection).
+ QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
+ }
} else {
state = QHttpNetworkConnectionChannel::IdleState;
const bool tryProtocolUpgrade = connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2;
@@ -1125,7 +1135,10 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
QSslSocket *sslSocket = qobject_cast<QSslSocket *>(socket);
Q_ASSERT(sslSocket);
- if (!protocolHandler) {
+ if (!protocolHandler && connection->connectionType() != QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
+ // ConnectionTypeHTTP2Direct does not rely on ALPN/NPN to negotiate HTTP/2,
+ // after establishing a secure connection we immediately start sending
+ // HTTP/2 frames.
switch (sslSocket->sslConfiguration().nextProtocolNegotiationStatus()) {
case QSslConfiguration::NextProtocolNegotiationNegotiated:
case QSslConfiguration::NextProtocolNegotiationUnsupported: {
@@ -1191,7 +1204,8 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
emitFinishedWithError(QNetworkReply::SslHandshakeFailedError,
"detected unknown Next Protocol Negotiation protocol");
}
- } else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2) {
+ } else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2
+ || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
// We have to reset QHttp2ProtocolHandler's state machine, it's a new
// connection and the handler's state is unique per connection.
protocolHandler.reset(new QHttp2ProtocolHandler(this));
@@ -1203,10 +1217,12 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
pendingEncrypt = false;
if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY ||
- connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2) {
+ connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2 ||
+ connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
// we call setSpdyWasUsed(true) on the replies in the SPDY handler when the request is sent
if (spdyRequestsToSend.count() > 0) {
- // wait for data from the server first (e.g. initial window, max concurrent requests)
+ // In case our peer has sent us its settings (window size, max concurrent streams etc.)
+ // let's give _q_receiveReply a chance to read them first ('invokeMethod', QueuedConnection).
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
}
} else { // HTTP
@@ -1303,5 +1319,3 @@ void QHttpNetworkConnectionChannel::setConnection(QHttpNetworkConnection *c)
QT_END_NAMESPACE
#include "moc_qhttpnetworkconnectionchannel_p.cpp"
-
-#endif // QT_NO_HTTP
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
index 844a7d5d15..e9cdae5653 100644
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
@@ -68,8 +68,6 @@
#include <private/qhttpnetworkconnection_p.h>
#include <private/qabstractprotocolhandler_p.h>
-#ifndef QT_NO_HTTP
-
#ifndef QT_NO_SSL
# include <QtNetwork/qsslsocket.h>
# include <QtNetwork/qsslerror.h>
@@ -80,6 +78,8 @@
#include <QtCore/qscopedpointer.h>
+QT_REQUIRE_CONFIG(http);
+
QT_BEGIN_NAMESPACE
class QHttpNetworkRequest;
@@ -216,6 +216,4 @@ public:
QT_END_NAMESPACE
-#endif // QT_NO_HTTP
-
#endif
diff --git a/src/network/access/qhttpnetworkheader.cpp b/src/network/access/qhttpnetworkheader.cpp
index 7199abbf17..19a3dfcfe8 100644
--- a/src/network/access/qhttpnetworkheader.cpp
+++ b/src/network/access/qhttpnetworkheader.cpp
@@ -41,8 +41,6 @@
#include <algorithm>
-#ifndef QT_NO_HTTP
-
QT_BEGIN_NAMESPACE
QHttpNetworkHeaderPrivate::QHttpNetworkHeaderPrivate(const QUrl &newUrl)
@@ -121,5 +119,3 @@ bool QHttpNetworkHeaderPrivate::operator==(const QHttpNetworkHeaderPrivate &othe
QT_END_NAMESPACE
-
-#endif
diff --git a/src/network/access/qhttpnetworkheader_p.h b/src/network/access/qhttpnetworkheader_p.h
index 46aec1dd8c..f46c259919 100644
--- a/src/network/access/qhttpnetworkheader_p.h
+++ b/src/network/access/qhttpnetworkheader_p.h
@@ -53,11 +53,11 @@
#include <QtNetwork/private/qtnetworkglobal_p.h>
-#ifndef QT_NO_HTTP
-
#include <qshareddata.h>
#include <qurl.h>
+QT_REQUIRE_CONFIG(http);
+
QT_BEGIN_NAMESPACE
class Q_AUTOTEST_EXPORT QHttpNetworkHeader
@@ -99,10 +99,6 @@ public:
QT_END_NAMESPACE
-
-#endif // QT_NO_HTTP
-
-
#endif // QHTTPNETWORKHEADER_H
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index 778ba821e8..a657346958 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -40,8 +40,6 @@
#include "qhttpnetworkreply_p.h"
#include "qhttpnetworkconnection_p.h"
-#ifndef QT_NO_HTTP
-
#ifndef QT_NO_SSL
# include <QtNetwork/qsslkey.h>
# include <QtNetwork/qsslcipher.h>
@@ -1035,5 +1033,3 @@ void QHttpNetworkReply::ignoreSslErrors(const QList<QSslError> &errors)
QT_END_NAMESPACE
-
-#endif // QT_NO_HTTP
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
index faab03f056..863e21ea3e 100644
--- a/src/network/access/qhttpnetworkreply_p.h
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -53,8 +53,6 @@
#include <QtNetwork/private/qtnetworkglobal_p.h>
-#ifndef QT_NO_HTTP
-
#include <qplatformdefs.h>
#ifndef QT_NO_COMPRESS
@@ -77,6 +75,8 @@ struct z_stream_s;
#include <private/qringbuffer_p.h>
#include <private/qbytedata_p.h>
+QT_REQUIRE_CONFIG(http);
+
QT_BEGIN_NAMESPACE
class QHttpNetworkConnection;
@@ -92,18 +92,18 @@ public:
explicit QHttpNetworkReply(const QUrl &url = QUrl(), QObject *parent = 0);
virtual ~QHttpNetworkReply();
- QUrl url() const Q_DECL_OVERRIDE;
- void setUrl(const QUrl &url) Q_DECL_OVERRIDE;
+ QUrl url() const override;
+ void setUrl(const QUrl &url) override;
- int majorVersion() const Q_DECL_OVERRIDE;
- int minorVersion() const Q_DECL_OVERRIDE;
+ int majorVersion() const override;
+ int minorVersion() const override;
- qint64 contentLength() const Q_DECL_OVERRIDE;
- void setContentLength(qint64 length) Q_DECL_OVERRIDE;
+ qint64 contentLength() const override;
+ void setContentLength(qint64 length) override;
- QList<QPair<QByteArray, QByteArray> > header() const Q_DECL_OVERRIDE;
- QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const Q_DECL_OVERRIDE;
- void setHeaderField(const QByteArray &name, const QByteArray &data) Q_DECL_OVERRIDE;
+ QList<QPair<QByteArray, QByteArray> > header() const override;
+ QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const override;
+ void setHeaderField(const QByteArray &name, const QByteArray &data) override;
void parseHeader(const QByteArray &header); // mainly for testing
QHttpNetworkRequest request() const;
@@ -285,7 +285,4 @@ public:
QT_END_NAMESPACE
-#endif // QT_NO_HTTP
-
-
#endif // QHTTPNETWORKREPLY_H
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index 60b566299f..3fcf946945 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -40,15 +40,13 @@
#include "qhttpnetworkrequest_p.h"
#include "private/qnoncontiguousbytedevice_p.h"
-#ifndef QT_NO_HTTP
-
QT_BEGIN_NAMESPACE
QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op,
QHttpNetworkRequest::Priority pri, const QUrl &newUrl)
: QHttpNetworkHeaderPrivate(newUrl), operation(op), priority(pri), uploadByteDevice(0),
autoDecompress(false), pipeliningAllowed(false), spdyAllowed(false), http2Allowed(false),
- withCredentials(true), preConnect(false), redirectCount(0),
+ http2Direct(false), withCredentials(true), preConnect(false), redirectCount(0),
redirectPolicy(QNetworkRequest::ManualRedirectPolicy)
{
}
@@ -63,6 +61,7 @@ QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequest
pipeliningAllowed(other.pipeliningAllowed),
spdyAllowed(other.spdyAllowed),
http2Allowed(other.http2Allowed),
+ http2Direct(other.http2Direct),
withCredentials(other.withCredentials),
ssl(other.ssl),
preConnect(other.preConnect),
@@ -85,6 +84,7 @@ bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &ot
&& (pipeliningAllowed == other.pipeliningAllowed)
&& (spdyAllowed == other.spdyAllowed)
&& (http2Allowed == other.http2Allowed)
+ && (http2Direct == other.http2Direct)
// we do not clear the customVerb in setOperation
&& (operation != QHttpNetworkRequest::Custom || (customVerb == other.customVerb))
&& (withCredentials == other.withCredentials)
@@ -350,6 +350,16 @@ void QHttpNetworkRequest::setHTTP2Allowed(bool b)
d->http2Allowed = b;
}
+bool QHttpNetworkRequest::isHTTP2Direct() const
+{
+ return d->http2Direct;
+}
+
+void QHttpNetworkRequest::setHTTP2Direct(bool b)
+{
+ d->http2Direct = b;
+}
+
bool QHttpNetworkRequest::withCredentials() const
{
return d->withCredentials;
@@ -383,5 +393,3 @@ int QHttpNetworkRequest::minorVersion() const
QT_END_NAMESPACE
-#endif
-
diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h
index ecf8856ded..2cbb8e255e 100644
--- a/src/network/access/qhttpnetworkrequest_p.h
+++ b/src/network/access/qhttpnetworkrequest_p.h
@@ -52,12 +52,12 @@
//
#include <QtNetwork/private/qtnetworkglobal_p.h>
-#ifndef QT_NO_HTTP
-
#include <private/qhttpnetworkheader_p.h>
#include <QtNetwork/qnetworkrequest.h>
#include <qmetatype.h>
+QT_REQUIRE_CONFIG(http);
+
QT_BEGIN_NAMESPACE
class QNonContiguousByteDevice;
@@ -90,18 +90,18 @@ public:
QHttpNetworkRequest &operator=(const QHttpNetworkRequest &other);
bool operator==(const QHttpNetworkRequest &other) const;
- QUrl url() const Q_DECL_OVERRIDE;
- void setUrl(const QUrl &url) Q_DECL_OVERRIDE;
+ QUrl url() const override;
+ void setUrl(const QUrl &url) override;
- int majorVersion() const Q_DECL_OVERRIDE;
- int minorVersion() const Q_DECL_OVERRIDE;
+ int majorVersion() const override;
+ int minorVersion() const override;
- qint64 contentLength() const Q_DECL_OVERRIDE;
- void setContentLength(qint64 length) Q_DECL_OVERRIDE;
+ qint64 contentLength() const override;
+ void setContentLength(qint64 length) override;
- QList<QPair<QByteArray, QByteArray> > header() const Q_DECL_OVERRIDE;
- QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const Q_DECL_OVERRIDE;
- void setHeaderField(const QByteArray &name, const QByteArray &data) Q_DECL_OVERRIDE;
+ QList<QPair<QByteArray, QByteArray> > header() const override;
+ QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const override;
+ void setHeaderField(const QByteArray &name, const QByteArray &data) override;
Operation operation() const;
void setOperation(Operation operation);
@@ -121,6 +121,9 @@ public:
bool isHTTP2Allowed() const;
void setHTTP2Allowed(bool b);
+ bool isHTTP2Direct() const;
+ void setHTTP2Direct(bool b);
+
bool withCredentials() const;
void setWithCredentials(bool b);
@@ -172,6 +175,7 @@ public:
bool pipeliningAllowed;
bool spdyAllowed;
bool http2Allowed;
+ bool http2Direct;
bool withCredentials;
bool ssl;
bool preConnect;
@@ -184,7 +188,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QHttpNetworkRequest)
-#endif // QT_NO_HTTP
-
-
#endif // QHTTPNETWORKREQUEST_H
diff --git a/src/network/access/qhttpprotocolhandler.cpp b/src/network/access/qhttpprotocolhandler.cpp
index 37e8b9bed8..edcbdcbe0e 100644
--- a/src/network/access/qhttpprotocolhandler.cpp
+++ b/src/network/access/qhttpprotocolhandler.cpp
@@ -42,8 +42,6 @@
#include <private/qnoncontiguousbytedevice_p.h>
#include <private/qhttpnetworkconnectionchannel_p.h>
-#ifndef QT_NO_HTTP
-
QT_BEGIN_NAMESPACE
QHttpProtocolHandler::QHttpProtocolHandler(QHttpNetworkConnectionChannel *channel)
@@ -437,5 +435,3 @@ bool QHttpProtocolHandler::sendRequest()
}
QT_END_NAMESPACE
-
-#endif // QT_NO_HTTP
diff --git a/src/network/access/qhttpprotocolhandler_p.h b/src/network/access/qhttpprotocolhandler_p.h
index 863b988be3..8e766604bb 100644
--- a/src/network/access/qhttpprotocolhandler_p.h
+++ b/src/network/access/qhttpprotocolhandler_p.h
@@ -55,7 +55,7 @@
#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <private/qabstractprotocolhandler_p.h>
-#ifndef QT_NO_HTTP
+QT_REQUIRE_CONFIG(http);
QT_BEGIN_NAMESPACE
@@ -64,13 +64,11 @@ public:
QHttpProtocolHandler(QHttpNetworkConnectionChannel *channel);
private:
- virtual void _q_receiveReply() Q_DECL_OVERRIDE;
- virtual void _q_readyRead() Q_DECL_OVERRIDE;
- virtual bool sendRequest() Q_DECL_OVERRIDE;
+ virtual void _q_receiveReply() override;
+ virtual void _q_readyRead() override;
+ virtual bool sendRequest() override;
};
QT_END_NAMESPACE
-#endif // QT_NO_HTTP
-
#endif
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 3204f8da33..0e97acdd9d 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -50,8 +50,6 @@
#include "private/qnetworkaccesscache_p.h"
#include "private/qnoncontiguousbytedevice_p.h"
-#ifndef QT_NO_HTTP
-
QT_BEGIN_NAMESPACE
static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const QUrl &url)
@@ -197,7 +195,7 @@ public:
setShareable(true);
}
- virtual void dispose() Q_DECL_OVERRIDE
+ virtual void dispose() override
{
#if 0 // sample code; do this right with the API
Q_ASSERT(!isWorking());
@@ -292,11 +290,17 @@ void QHttpThreadDelegate::startRequest()
QHttpNetworkConnection::ConnectionType connectionType
= httpRequest.isHTTP2Allowed() ? QHttpNetworkConnection::ConnectionTypeHTTP2
: QHttpNetworkConnection::ConnectionTypeHTTP;
+ if (httpRequest.isHTTP2Direct()) {
+ Q_ASSERT(!httpRequest.isHTTP2Allowed());
+ connectionType = QHttpNetworkConnection::ConnectionTypeHTTP2Direct;
+ }
+
#ifndef QT_NO_SSL
if (ssl && !incomingSslConfiguration.data())
incomingSslConfiguration.reset(new QSslConfiguration);
if (httpRequest.isHTTP2Allowed() && ssl) {
+ // With HTTP2Direct we do not try any protocol negotiation.
QList<QByteArray> protocols;
protocols << QSslConfiguration::ALPNProtocolHTTP2
<< QSslConfiguration::NextProtocolHttp1_1;
@@ -762,6 +766,4 @@ void QHttpThreadDelegate::synchronousProxyAuthenticationRequiredSlot(const QNet
#endif
-#endif // QT_NO_HTTP
-
QT_END_NAMESPACE
diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h
index da115d6710..019a8b8b74 100644
--- a/src/network/access/qhttpthreaddelegate_p.h
+++ b/src/network/access/qhttpthreaddelegate_p.h
@@ -68,7 +68,7 @@
#include "qnetworkaccessauthenticationmanager_p.h"
#include <QtNetwork/private/http2protocol_p.h>
-#ifndef QT_NO_HTTP
+QT_REQUIRE_CONFIG(http);
QT_BEGIN_NAMESPACE
@@ -218,12 +218,12 @@ public:
{
}
- qint64 pos() const Q_DECL_OVERRIDE
+ qint64 pos() const override
{
return m_pos;
}
- const char* readPointer(qint64 maximumLength, qint64 &len) Q_DECL_OVERRIDE
+ const char* readPointer(qint64 maximumLength, qint64 &len) override
{
if (m_amount > 0) {
len = m_amount;
@@ -243,7 +243,7 @@ public:
return 0;
}
- bool advanceReadPointer(qint64 a) Q_DECL_OVERRIDE
+ bool advanceReadPointer(qint64 a) override
{
if (m_data == 0)
return false;
@@ -258,7 +258,7 @@ public:
return true;
}
- bool atEnd() const Q_DECL_OVERRIDE
+ bool atEnd() const override
{
if (m_amount > 0)
return false;
@@ -266,7 +266,7 @@ public:
return m_atEnd;
}
- bool reset() Q_DECL_OVERRIDE
+ bool reset() override
{
m_amount = 0;
m_data = 0;
@@ -288,7 +288,7 @@ public:
return b;
}
- qint64 size() const Q_DECL_OVERRIDE
+ qint64 size() const override
{
return m_size;
}
@@ -327,6 +327,4 @@ signals:
QT_END_NAMESPACE
-#endif // QT_NO_HTTP
-
#endif // QHTTPTHREADDELEGATE_H
diff --git a/src/network/access/qnetworkaccessauthenticationmanager.cpp b/src/network/access/qnetworkaccessauthenticationmanager.cpp
index 2b07833cda..b661cc45b3 100644
--- a/src/network/access/qnetworkaccessauthenticationmanager.cpp
+++ b/src/network/access/qnetworkaccessauthenticationmanager.cpp
@@ -95,7 +95,7 @@ public:
}
}
- virtual void dispose() Q_DECL_OVERRIDE { delete this; }
+ virtual void dispose() override { delete this; }
};
#ifndef QT_NO_NETWORKPROXY
diff --git a/src/network/access/qnetworkaccesscache_p.h b/src/network/access/qnetworkaccesscache_p.h
index 3732b5cbb4..69ea649a8a 100644
--- a/src/network/access/qnetworkaccesscache_p.h
+++ b/src/network/access/qnetworkaccesscache_p.h
@@ -106,7 +106,7 @@ signals:
void entryReady(QNetworkAccessCache::CacheableObject *);
protected:
- void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE;
+ void timerEvent(QTimerEvent *) override;
private:
// idea copied from qcache.h
diff --git a/src/network/access/qnetworkaccesscachebackend_p.h b/src/network/access/qnetworkaccesscachebackend_p.h
index 8db1a6b1d5..dfb0ce84d9 100644
--- a/src/network/access/qnetworkaccesscachebackend_p.h
+++ b/src/network/access/qnetworkaccesscachebackend_p.h
@@ -65,12 +65,12 @@ public:
QNetworkAccessCacheBackend();
~QNetworkAccessCacheBackend();
- void open() Q_DECL_OVERRIDE;
- void closeDownstreamChannel() Q_DECL_OVERRIDE;
+ void open() override;
+ void closeDownstreamChannel() override;
void closeUpstreamChannel();
void upstreamReadyRead();
- void downstreamReadyWrite() Q_DECL_OVERRIDE;
+ void downstreamReadyWrite() override;
private:
bool sendCacheContents();
diff --git a/src/network/access/qnetworkaccessdebugpipebackend_p.h b/src/network/access/qnetworkaccessdebugpipebackend_p.h
index 1d1af61dbd..d9a7aabdad 100644
--- a/src/network/access/qnetworkaccessdebugpipebackend_p.h
+++ b/src/network/access/qnetworkaccessdebugpipebackend_p.h
@@ -68,10 +68,10 @@ public:
QNetworkAccessDebugPipeBackend();
virtual ~QNetworkAccessDebugPipeBackend();
- virtual void open() Q_DECL_OVERRIDE;
- virtual void closeDownstreamChannel() Q_DECL_OVERRIDE;
+ virtual void open() override;
+ virtual void closeDownstreamChannel() override;
- virtual void downstreamReadyWrite() Q_DECL_OVERRIDE;
+ virtual void downstreamReadyWrite() override;
protected:
void pushFromSocketToDownstream();
@@ -101,9 +101,9 @@ private:
class QNetworkAccessDebugPipeBackendFactory: public QNetworkAccessBackendFactory
{
public:
- virtual QStringList supportedSchemes() const Q_DECL_OVERRIDE;
+ virtual QStringList supportedSchemes() const override;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
- const QNetworkRequest &request) const Q_DECL_OVERRIDE;
+ const QNetworkRequest &request) const override;
};
#endif // QT_BUILD_INTERNAL
diff --git a/src/network/access/qnetworkaccessfilebackend_p.h b/src/network/access/qnetworkaccessfilebackend_p.h
index 081ff2b9e7..2c01fb1121 100644
--- a/src/network/access/qnetworkaccessfilebackend_p.h
+++ b/src/network/access/qnetworkaccessfilebackend_p.h
@@ -66,10 +66,10 @@ public:
QNetworkAccessFileBackend();
virtual ~QNetworkAccessFileBackend();
- virtual void open() Q_DECL_OVERRIDE;
- virtual void closeDownstreamChannel() Q_DECL_OVERRIDE;
+ virtual void open() override;
+ virtual void closeDownstreamChannel() override;
- virtual void downstreamReadyWrite() Q_DECL_OVERRIDE;
+ virtual void downstreamReadyWrite() override;
public slots:
void uploadReadyReadSlot();
@@ -87,9 +87,9 @@ private:
class QNetworkAccessFileBackendFactory: public QNetworkAccessBackendFactory
{
public:
- virtual QStringList supportedSchemes() const Q_DECL_OVERRIDE;
+ virtual QStringList supportedSchemes() const override;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
- const QNetworkRequest &request) const Q_DECL_OVERRIDE;
+ const QNetworkRequest &request) const override;
};
QT_END_NAMESPACE
diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp
index 0df2569e87..c5404e4221 100644
--- a/src/network/access/qnetworkaccessftpbackend.cpp
+++ b/src/network/access/qnetworkaccessftpbackend.cpp
@@ -94,7 +94,7 @@ public:
setShareable(false);
}
- void dispose() Q_DECL_OVERRIDE
+ void dispose() override
{
connect(this, SIGNAL(done(bool)), this, SLOT(deleteLater()));
close();
diff --git a/src/network/access/qnetworkaccessftpbackend_p.h b/src/network/access/qnetworkaccessftpbackend_p.h
index 0f26d05327..4bd082fb67 100644
--- a/src/network/access/qnetworkaccessftpbackend_p.h
+++ b/src/network/access/qnetworkaccessftpbackend_p.h
@@ -84,10 +84,10 @@ public:
QNetworkAccessFtpBackend();
virtual ~QNetworkAccessFtpBackend();
- virtual void open() Q_DECL_OVERRIDE;
- virtual void closeDownstreamChannel() Q_DECL_OVERRIDE;
+ virtual void open() override;
+ virtual void closeDownstreamChannel() override;
- virtual void downstreamReadyWrite() Q_DECL_OVERRIDE;
+ virtual void downstreamReadyWrite() override;
enum CacheCleanupMode {
ReleaseCachedConnection,
@@ -115,9 +115,9 @@ private:
class QNetworkAccessFtpBackendFactory: public QNetworkAccessBackendFactory
{
public:
- virtual QStringList supportedSchemes() const Q_DECL_OVERRIDE;
+ virtual QStringList supportedSchemes() const override;
virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
- const QNetworkRequest &request) const Q_DECL_OVERRIDE;
+ const QNetworkRequest &request) const override;
};
QT_END_NAMESPACE
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index edf9dee78e..248b4ccd3b 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -66,10 +66,12 @@
#include "QtNetwork/private/qauthenticator_p.h"
#include "QtNetwork/qsslconfiguration.h"
#include "QtNetwork/qnetworkconfigmanager.h"
-#include "QtNetwork/qhttpmultipart.h"
-#include "qhttpmultipart_p.h"
+#if QT_CONFIG(http)
+#include "qhttpmultipart.h"
+#include "qhttpmultipart_p.h"
#include "qnetworkreplyhttpimpl_p.h"
+#endif
#include "qthread.h"
@@ -469,7 +471,7 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
qRegisterMetaType<QSslPreSharedKeyAuthenticator *>();
#endif
qRegisterMetaType<QList<QPair<QByteArray,QByteArray> > >();
-#ifndef QT_NO_HTTP
+#if QT_CONFIG(http)
qRegisterMetaType<QHttpNetworkRequest>();
#endif
qRegisterMetaType<QNetworkReply::NetworkError>();
@@ -877,6 +879,7 @@ QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, const
return reply;
}
+#if QT_CONFIG(http)
/*!
\since 4.8
@@ -916,6 +919,7 @@ QNetworkReply *QNetworkAccessManager::put(const QNetworkRequest &request, QHttpM
QNetworkReply *reply = put(newRequest, device);
return reply;
}
+#endif // QT_CONFIG(http)
/*!
Uploads the contents of \a data to the destination \a request and
@@ -1285,6 +1289,7 @@ QNetworkReply *QNetworkAccessManager::sendCustomRequest(const QNetworkRequest &r
return reply;
}
+#if QT_CONFIG(http)
/*!
\since 5.8
@@ -1306,6 +1311,7 @@ QNetworkReply *QNetworkAccessManager::sendCustomRequest(const QNetworkRequest &r
QNetworkReply *reply = sendCustomRequest(newRequest, verb, device);
return reply;
}
+#endif // QT_CONFIG(http)
/*!
Returns a new QNetworkReply object to handle the operation \a op
@@ -1419,7 +1425,7 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
}
}
-#ifndef QT_NO_HTTP
+#if QT_CONFIG(http)
// Since Qt 5 we use the new QNetworkReplyHttpImpl
if (scheme == QLatin1String("http") || scheme == QLatin1String("preconnect-http")
#ifndef QT_NO_SSL
@@ -1451,7 +1457,7 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
#endif
return reply;
}
-#endif // QT_NO_HTTP
+#endif // QT_CONFIG(http)
// first step: create the reply
QNetworkReplyImpl *reply = new QNetworkReplyImpl(this);
@@ -1527,7 +1533,7 @@ QStringList QNetworkAccessManager::supportedSchemesImplementation() const
QStringList schemes = d->backendSupportedSchemes();
// Those ones don't exist in backends
-#ifndef QT_NO_HTTP
+#if QT_CONFIG(http)
schemes << QStringLiteral("http");
#ifndef QT_NO_SSL
if (QSslSocket::supportsSsl())
@@ -1992,6 +1998,7 @@ void QNetworkAccessManagerPrivate::_q_networkSessionFailed(QNetworkSession::Sess
#endif // QT_NO_BEARERMANAGEMENT
+#if QT_CONFIG(http)
QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart)
{
// copy the request, we probably need to add some headers
@@ -2039,6 +2046,7 @@ QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkReq
return newRequest;
}
+#endif // QT_CONFIG(http)
QT_END_NAMESPACE
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index 4806ec0475..a0ce3eddcd 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -100,7 +100,7 @@ public:
Q_ENUM(NetworkAccessibility)
#endif
- explicit QNetworkAccessManager(QObject *parent = Q_NULLPTR);
+ explicit QNetworkAccessManager(QObject *parent = nullptr);
~QNetworkAccessManager();
// ### Qt 6: turn into virtual
@@ -134,14 +134,17 @@ public:
QNetworkReply *get(const QNetworkRequest &request);
QNetworkReply *post(const QNetworkRequest &request, QIODevice *data);
QNetworkReply *post(const QNetworkRequest &request, const QByteArray &data);
- QNetworkReply *post(const QNetworkRequest &request, QHttpMultiPart *multiPart);
QNetworkReply *put(const QNetworkRequest &request, QIODevice *data);
QNetworkReply *put(const QNetworkRequest &request, const QByteArray &data);
- QNetworkReply *put(const QNetworkRequest &request, QHttpMultiPart *multiPart);
QNetworkReply *deleteResource(const QNetworkRequest &request);
- QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = Q_NULLPTR);
+ QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = nullptr);
QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, const QByteArray &data);
+
+#if QT_CONFIG(http)
+ QNetworkReply *post(const QNetworkRequest &request, QHttpMultiPart *multiPart);
+ QNetworkReply *put(const QNetworkRequest &request, QHttpMultiPart *multiPart);
QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QHttpMultiPart *multiPart);
+#endif
#ifndef QT_NO_BEARERMANAGEMENT
void setConfiguration(const QNetworkConfiguration &config);
@@ -181,7 +184,7 @@ Q_SIGNALS:
protected:
virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request,
- QIODevice *outgoingData = Q_NULLPTR);
+ QIODevice *outgoingData = nullptr);
protected Q_SLOTS:
QStringList supportedSchemesImplementation() const;
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index e5257251a4..428110e8bc 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -164,7 +164,9 @@ public:
#endif
+#if QT_CONFIG(http)
QNetworkRequest prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart);
+#endif
// this is the cache for storing downloaded files
QAbstractNetworkCache *networkCache;
diff --git a/src/network/access/qnetworkcookiejar.h b/src/network/access/qnetworkcookiejar.h
index f9c1549e20..c3b2200443 100644
--- a/src/network/access/qnetworkcookiejar.h
+++ b/src/network/access/qnetworkcookiejar.h
@@ -54,7 +54,7 @@ class Q_NETWORK_EXPORT QNetworkCookieJar: public QObject
{
Q_OBJECT
public:
- explicit QNetworkCookieJar(QObject *parent = Q_NULLPTR);
+ explicit QNetworkCookieJar(QObject *parent = nullptr);
virtual ~QNetworkCookieJar();
virtual QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const;
diff --git a/src/network/access/qnetworkdiskcache.h b/src/network/access/qnetworkdiskcache.h
index 0e9258f6de..ff7d3192e8 100644
--- a/src/network/access/qnetworkdiskcache.h
+++ b/src/network/access/qnetworkdiskcache.h
@@ -53,7 +53,7 @@ class Q_NETWORK_EXPORT QNetworkDiskCache : public QAbstractNetworkCache
Q_OBJECT
public:
- explicit QNetworkDiskCache(QObject *parent = Q_NULLPTR);
+ explicit QNetworkDiskCache(QObject *parent = nullptr);
~QNetworkDiskCache();
QString cacheDirectory() const;
@@ -62,18 +62,18 @@ public:
qint64 maximumCacheSize() const;
void setMaximumCacheSize(qint64 size);
- qint64 cacheSize() const Q_DECL_OVERRIDE;
- QNetworkCacheMetaData metaData(const QUrl &url) Q_DECL_OVERRIDE;
- void updateMetaData(const QNetworkCacheMetaData &metaData) Q_DECL_OVERRIDE;
- QIODevice *data(const QUrl &url) Q_DECL_OVERRIDE;
- bool remove(const QUrl &url) Q_DECL_OVERRIDE;
- QIODevice *prepare(const QNetworkCacheMetaData &metaData) Q_DECL_OVERRIDE;
- void insert(QIODevice *device) Q_DECL_OVERRIDE;
+ qint64 cacheSize() const override;
+ QNetworkCacheMetaData metaData(const QUrl &url) override;
+ void updateMetaData(const QNetworkCacheMetaData &metaData) override;
+ QIODevice *data(const QUrl &url) override;
+ bool remove(const QUrl &url) override;
+ QIODevice *prepare(const QNetworkCacheMetaData &metaData) override;
+ void insert(QIODevice *device) override;
QNetworkCacheMetaData fileMetaData(const QString &fileName) const;
public Q_SLOTS:
- void clear() Q_DECL_OVERRIDE;
+ void clear() override;
protected:
virtual qint64 expire();
diff --git a/src/network/access/qnetworkfile_p.h b/src/network/access/qnetworkfile_p.h
index dd56b24bd8..e788308d82 100644
--- a/src/network/access/qnetworkfile_p.h
+++ b/src/network/access/qnetworkfile_p.h
@@ -67,7 +67,7 @@ public:
public Q_SLOTS:
void open();
- void close() Q_DECL_OVERRIDE;
+ void close() override;
Q_SIGNALS:
void finished(bool ok);
diff --git a/src/network/access/qnetworkreply.h b/src/network/access/qnetworkreply.h
index d858e07d84..63c2752caf 100644
--- a/src/network/access/qnetworkreply.h
+++ b/src/network/access/qnetworkreply.h
@@ -114,8 +114,8 @@ public:
~QNetworkReply();
// reimplemented from QIODevice
- virtual void close() Q_DECL_OVERRIDE;
- virtual bool isSequential() const Q_DECL_OVERRIDE;
+ virtual void close() override;
+ virtual bool isSequential() const override;
// like QAbstractSocket:
qint64 readBufferSize() const;
@@ -169,9 +169,9 @@ Q_SIGNALS:
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
protected:
- explicit QNetworkReply(QObject *parent = Q_NULLPTR);
+ explicit QNetworkReply(QObject *parent = nullptr);
QNetworkReply(QNetworkReplyPrivate &dd, QObject *parent);
- virtual qint64 writeData(const char *data, qint64 len) Q_DECL_OVERRIDE;
+ virtual qint64 writeData(const char *data, qint64 len) override;
void setOperation(QNetworkAccessManager::Operation operation);
void setRequest(const QNetworkRequest &request);
diff --git a/src/network/access/qnetworkreplydataimpl_p.h b/src/network/access/qnetworkreplydataimpl_p.h
index c8b44d7539..81d2110d69 100644
--- a/src/network/access/qnetworkreplydataimpl_p.h
+++ b/src/network/access/qnetworkreplydataimpl_p.h
@@ -67,15 +67,15 @@ class QNetworkReplyDataImpl: public QNetworkReply
public:
QNetworkReplyDataImpl(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op);
~QNetworkReplyDataImpl();
- virtual void abort() Q_DECL_OVERRIDE;
+ virtual void abort() override;
// reimplemented from QNetworkReply
- virtual void close() Q_DECL_OVERRIDE;
- virtual qint64 bytesAvailable() const Q_DECL_OVERRIDE;
- virtual bool isSequential () const Q_DECL_OVERRIDE;
- qint64 size() const Q_DECL_OVERRIDE;
+ virtual void close() override;
+ virtual qint64 bytesAvailable() const override;
+ virtual bool isSequential () const override;
+ qint64 size() const override;
- virtual qint64 readData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
+ virtual qint64 readData(char *data, qint64 maxlen) override;
Q_DECLARE_PRIVATE(QNetworkReplyDataImpl)
};
diff --git a/src/network/access/qnetworkreplyfileimpl_p.h b/src/network/access/qnetworkreplyfileimpl_p.h
index d6af66152e..55aece0bed 100644
--- a/src/network/access/qnetworkreplyfileimpl_p.h
+++ b/src/network/access/qnetworkreplyfileimpl_p.h
@@ -67,15 +67,15 @@ class QNetworkReplyFileImpl: public QNetworkReply
public:
QNetworkReplyFileImpl(QNetworkAccessManager *manager, const QNetworkRequest &req, const QNetworkAccessManager::Operation op);
~QNetworkReplyFileImpl();
- virtual void abort() Q_DECL_OVERRIDE;
+ virtual void abort() override;
// reimplemented from QNetworkReply
- virtual void close() Q_DECL_OVERRIDE;
- virtual qint64 bytesAvailable() const Q_DECL_OVERRIDE;
- virtual bool isSequential () const Q_DECL_OVERRIDE;
- qint64 size() const Q_DECL_OVERRIDE;
+ virtual void close() override;
+ virtual qint64 bytesAvailable() const override;
+ virtual bool isSequential () const override;
+ qint64 size() const override;
- virtual qint64 readData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
+ virtual qint64 readData(char *data, qint64 maxlen) override;
private Q_SLOTS:
void fileOpenFinished(bool isOpen);
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 382da0db5a..96016453c2 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -60,8 +60,6 @@
#include "qnetworkcookiejar.h"
-#ifndef QT_NO_HTTP
-
#include <string.h> // for strchr
QT_BEGIN_NAMESPACE
@@ -773,6 +771,12 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
if (request.attribute(QNetworkRequest::HTTP2AllowedAttribute).toBool())
httpRequest.setHTTP2Allowed(true);
+ if (request.attribute(QNetworkRequest::Http2DirectAttribute).toBool()) {
+ // Intentionally mutually exclusive - cannot be both direct and 'allowed'
+ httpRequest.setHTTP2Direct(true);
+ httpRequest.setHTTP2Allowed(false);
+ }
+
if (static_cast<QNetworkRequest::LoadControl>
(newHttpRequest.attribute(QNetworkRequest::AuthenticationReuseAttribute,
QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Manual)
@@ -1288,7 +1292,9 @@ void QNetworkReplyHttpImplPrivate::replyDownloadMetaData(const QList<QPair<QByte
q->setAttribute(QNetworkRequest::HttpPipeliningWasUsedAttribute, pu);
const QVariant http2Allowed = request.attribute(QNetworkRequest::HTTP2AllowedAttribute);
- if (http2Allowed.isValid() && http2Allowed.toBool()) {
+ const QVariant http2Direct = request.attribute(QNetworkRequest::Http2DirectAttribute);
+ if ((http2Allowed.isValid() && http2Allowed.toBool())
+ || (http2Direct.isValid() && http2Direct.toBool())) {
q->setAttribute(QNetworkRequest::HTTP2WasUsedAttribute, spdyWasUsed);
q->setAttribute(QNetworkRequest::SpdyWasUsedAttribute, false);
} else {
@@ -2375,5 +2381,3 @@ void QNetworkReplyHttpImplPrivate::completeCacheSave()
}
QT_END_NAMESPACE
-
-#endif // QT_NO_HTTP
diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h
index 9d47f65ce7..f5f01d0811 100644
--- a/src/network/access/qnetworkreplyhttpimpl_p.h
+++ b/src/network/access/qnetworkreplyhttpimpl_p.h
@@ -72,7 +72,7 @@
#include <QtNetwork/QSslConfiguration>
#endif
-#ifndef QT_NO_HTTP
+QT_REQUIRE_CONFIG(http);
QT_BEGIN_NAMESPACE
@@ -86,14 +86,14 @@ public:
QNetworkReplyHttpImpl(QNetworkAccessManager* const, const QNetworkRequest&, QNetworkAccessManager::Operation&, QIODevice* outgoingData);
virtual ~QNetworkReplyHttpImpl();
- void close() Q_DECL_OVERRIDE;
- void abort() Q_DECL_OVERRIDE;
- qint64 bytesAvailable() const Q_DECL_OVERRIDE;
- bool isSequential () const Q_DECL_OVERRIDE;
- qint64 size() const Q_DECL_OVERRIDE;
- qint64 readData(char*, qint64) Q_DECL_OVERRIDE;
- void setReadBufferSize(qint64 size) Q_DECL_OVERRIDE;
- bool canReadLine () const Q_DECL_OVERRIDE;
+ void close() override;
+ void abort() override;
+ qint64 bytesAvailable() const override;
+ bool isSequential () const override;
+ qint64 size() const override;
+ qint64 readData(char*, qint64) override;
+ void setReadBufferSize(qint64 size) override;
+ bool canReadLine () const override;
Q_DECLARE_PRIVATE(QNetworkReplyHttpImpl)
Q_PRIVATE_SLOT(d_func(), void _q_startOperation())
@@ -141,10 +141,10 @@ public:
#ifndef QT_NO_SSL
protected:
- void ignoreSslErrors() Q_DECL_OVERRIDE;
- void ignoreSslErrorsImplementation(const QList<QSslError> &errors) Q_DECL_OVERRIDE;
- void setSslConfigurationImplementation(const QSslConfiguration &configuration) Q_DECL_OVERRIDE;
- void sslConfigurationImplementation(QSslConfiguration &configuration) const Q_DECL_OVERRIDE;
+ void ignoreSslErrors() override;
+ void ignoreSslErrorsImplementation(const QList<QSslError> &errors) override;
+ void setSslConfigurationImplementation(const QSslConfiguration &configuration) override;
+ void sslConfigurationImplementation(QSslConfiguration &configuration) const override;
#endif
signals:
@@ -315,6 +315,4 @@ public:
QT_END_NAMESPACE
-#endif // QT_NO_HTTP
-
#endif
diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h
index 7cd99392d3..f4e8284ab6 100644
--- a/src/network/access/qnetworkreplyimpl_p.h
+++ b/src/network/access/qnetworkreplyimpl_p.h
@@ -76,15 +76,15 @@ class QNetworkReplyImpl: public QNetworkReply
public:
QNetworkReplyImpl(QObject *parent = 0);
~QNetworkReplyImpl();
- virtual void abort() Q_DECL_OVERRIDE;
+ virtual void abort() override;
// reimplemented from QNetworkReply / QIODevice
- virtual void close() Q_DECL_OVERRIDE;
- virtual qint64 bytesAvailable() const Q_DECL_OVERRIDE;
- virtual void setReadBufferSize(qint64 size) Q_DECL_OVERRIDE;
+ virtual void close() override;
+ virtual qint64 bytesAvailable() const override;
+ virtual void setReadBufferSize(qint64 size) override;
- virtual qint64 readData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
- virtual bool event(QEvent *) Q_DECL_OVERRIDE;
+ virtual qint64 readData(char *data, qint64 maxlen) override;
+ virtual bool event(QEvent *) override;
Q_DECLARE_PRIVATE(QNetworkReplyImpl)
Q_PRIVATE_SLOT(d_func(), void _q_startOperation())
@@ -101,10 +101,10 @@ public:
#ifndef QT_NO_SSL
protected:
- void sslConfigurationImplementation(QSslConfiguration &configuration) const Q_DECL_OVERRIDE;
- void setSslConfigurationImplementation(const QSslConfiguration &configuration) Q_DECL_OVERRIDE;
- virtual void ignoreSslErrors() Q_DECL_OVERRIDE;
- virtual void ignoreSslErrorsImplementation(const QList<QSslError> &errors) Q_DECL_OVERRIDE;
+ void sslConfigurationImplementation(QSslConfiguration &configuration) const override;
+ void setSslConfigurationImplementation(const QSslConfiguration &configuration) override;
+ virtual void ignoreSslErrors() override;
+ virtual void ignoreSslErrorsImplementation(const QList<QSslError> &errors) override;
#endif
};
@@ -219,9 +219,9 @@ public:
QNetworkAccessManager::Operation op);
~QDisabledNetworkReply();
- void abort() Q_DECL_OVERRIDE { }
+ void abort() override { }
protected:
- qint64 readData(char *, qint64) Q_DECL_OVERRIDE { return -1; }
+ qint64 readData(char *, qint64) override { return -1; }
};
#endif
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index 60701d45be..277190b3bd 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -298,6 +298,18 @@ QT_BEGIN_NAMESPACE
This attribute obsoletes FollowRedirectsAttribute.
(This value was introduced in 5.9.)
+ \value Http2DirectAttribute
+ Requests only, type: QMetaType::Bool (default: false)
+ If set, this attribute will force QNetworkAccessManager to use
+ HTTP/2 protocol without initial HTTP/2 protocol negotiation.
+ Use of this attribute implies prior knowledge that a particular
+ server supports HTTP/2. The attribute works with SSL or 'cleartext'
+ HTTP/2. If a server turns out to not support HTTP/2, when HTTP/2 direct
+ was specified, QNetworkAccessManager gives up, without attempting to
+ fall back to HTTP/1.1. If both HTTP2AllowedAttribute and
+ Http2DirectAttribute are set, Http2DirectAttribute takes priority.
+ (This value was introduced in 5.10.)
+
\value User
Special type. Additional information can be passed in
QVariants with types ranging from User to UserMax. The default
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index 68d4ae6d6b..cddd81bd19 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -92,6 +92,7 @@ public:
HTTP2WasUsedAttribute,
OriginalContentLengthAttribute,
RedirectPolicyAttribute,
+ Http2DirectAttribute,
User = 1000,
UserMax = 32767
diff --git a/src/network/access/qspdyprotocolhandler.cpp b/src/network/access/qspdyprotocolhandler.cpp
index 445a2a1c29..403c01e974 100644
--- a/src/network/access/qspdyprotocolhandler.cpp
+++ b/src/network/access/qspdyprotocolhandler.cpp
@@ -43,7 +43,7 @@
#include <private/qhttpnetworkconnectionchannel_p.h>
#include <QtCore/QtEndian>
-#if !defined(QT_NO_HTTP) && !defined(QT_NO_SSL)
+#if !defined(QT_NO_SSL)
QT_BEGIN_NAMESPACE
@@ -1294,4 +1294,4 @@ qint32 QSpdyProtocolHandler::generateNextStreamID()
QT_END_NAMESPACE
-#endif // !defined(QT_NO_HTTP) && !defined(QT_NO_SSL)
+#endif // !defined(QT_NO_SSL)
diff --git a/src/network/access/qspdyprotocolhandler_p.h b/src/network/access/qspdyprotocolhandler_p.h
index 0a18505b23..dd93a9aba2 100644
--- a/src/network/access/qspdyprotocolhandler_p.h
+++ b/src/network/access/qspdyprotocolhandler_p.h
@@ -58,7 +58,9 @@
#include <zlib.h>
-#if !defined(QT_NO_HTTP) && !defined(QT_NO_SSL)
+QT_REQUIRE_CONFIG(http);
+
+#if !defined(QT_NO_SSL)
QT_BEGIN_NAMESPACE
@@ -101,9 +103,9 @@ public:
Q_DECLARE_FLAGS(SETTINGS_ID_Flags, SETTINGS_ID_Flag)
- virtual void _q_receiveReply() Q_DECL_OVERRIDE;
- virtual void _q_readyRead() Q_DECL_OVERRIDE;
- virtual bool sendRequest() Q_DECL_OVERRIDE;
+ virtual void _q_receiveReply() override;
+ virtual void _q_readyRead() override;
+ virtual bool sendRequest() override;
private slots:
void _q_uploadDataReadyRead();
@@ -223,6 +225,6 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QSpdyProtocolHandler::SETTINGS_ID_Flags)
QT_END_NAMESPACE
-#endif // !defined(QT_NO_HTTP) && !defined(QT_NO_SSL)
+#endif // !defined(QT_NO_SSL)
#endif // QSPDYPROTOCOLHANDLER_H
diff --git a/src/network/bearer/qnetworkconfigmanager.h b/src/network/bearer/qnetworkconfigmanager.h
index da248bc7d0..e8866999c7 100644
--- a/src/network/bearer/qnetworkconfigmanager.h
+++ b/src/network/bearer/qnetworkconfigmanager.h
@@ -66,7 +66,7 @@ public:
Q_DECLARE_FLAGS(Capabilities, Capability)
- explicit QNetworkConfigurationManager(QObject *parent = Q_NULLPTR);
+ explicit QNetworkConfigurationManager(QObject *parent = nullptr);
virtual ~QNetworkConfigurationManager();
QNetworkConfigurationManager::Capabilities capabilities() const;
diff --git a/src/network/bearer/qnetworksession.h b/src/network/bearer/qnetworksession.h
index d96b8915eb..1b5ae9098b 100644
--- a/src/network/bearer/qnetworksession.h
+++ b/src/network/bearer/qnetworksession.h
@@ -87,7 +87,7 @@ public:
Q_DECLARE_FLAGS(UsagePolicies, UsagePolicy)
- explicit QNetworkSession(const QNetworkConfiguration &connConfig, QObject *parent = Q_NULLPTR);
+ explicit QNetworkSession(const QNetworkConfiguration &connConfig, QObject *parent = nullptr);
virtual ~QNetworkSession();
bool isOpen() const;
@@ -131,8 +131,8 @@ Q_SIGNALS:
void usagePoliciesChanged(QNetworkSession::UsagePolicies usagePolicies);
protected:
- virtual void connectNotify(const QMetaMethod &signal) Q_DECL_OVERRIDE;
- virtual void disconnectNotify(const QMetaMethod &signal) Q_DECL_OVERRIDE;
+ virtual void connectNotify(const QMetaMethod &signal) override;
+ virtual void disconnectNotify(const QMetaMethod &signal) override;
private:
Q_DISABLE_COPY(QNetworkSession)
diff --git a/src/network/configure.json b/src/network/configure.json
index d46fbfc101..ea01e8224d 100644
--- a/src/network/configure.json
+++ b/src/network/configure.json
@@ -116,6 +116,24 @@
},
"use": "network"
},
+ "linux-netlink": {
+ "label": "Linux AF_NETLINK sockets",
+ "type": "compile",
+ "test": {
+ "include": [ "asm/types.h", "linux/netlink.h", "linux/rtnetlink.h", "sys/socket.h" ],
+ "main": [
+ "struct rtattr rta = { };",
+ "struct ifinfomsg ifi = {};",
+ "struct ifaddrmsg ifa = {};",
+ "struct ifa_cacheinfo ci;",
+ "ci.ifa_prefered = ci.ifa_valid = 0;",
+ "(void)RTM_NEWLINK; (void)RTM_NEWADDR;",
+ "(void)IFLA_ADDRESS; (void)IFLA_IFNAME;",
+ "(void)IFA_ADDRESS; (void)IFA_LABEL; (void)IFA_CACHEINFO;",
+ "(void)(IFA_F_SECONDARY | IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_MANAGETEMPADDR);"
+ ]
+ }
+ },
"sctp": {
"label": "SCTP support",
"type": "compile",
@@ -161,6 +179,11 @@
"condition": "libs.libproxy",
"output": [ "privateFeature" ]
},
+ "linux-netlink": {
+ "label": "Linux AF_NETLINK",
+ "condition": "config.linux && tests.linux-netlink",
+ "output": [ "privateFeature" ]
+ },
"openssl": {
"label": "OpenSSL",
"enable": "input.openssl == 'yes' || input.openssl == 'linked' || input.openssl == 'runtime'",
@@ -270,6 +293,12 @@
"section": "Networking",
"condition": "features.temporaryfile",
"output": [ "publicFeature", "feature" ]
+ },
+ "dnslookup": {
+ "label": "QDnsLookup",
+ "purpose": "Provides API for DNS lookups.",
+ "section": "Networking",
+ "output": [ "publicFeature" ]
}
},
@@ -310,6 +339,11 @@ For example:
"getifaddrs", "ipv6ifname", "libproxy",
{
"type": "feature",
+ "args": "linux-netlink",
+ "condition": "config.linux"
+ },
+ {
+ "type": "feature",
"args": "securetransport",
"condition": "config.darwin"
},
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri
index b822a70e88..11b80d59d5 100644
--- a/src/network/kernel/kernel.pri
+++ b/src/network/kernel/kernel.pri
@@ -7,8 +7,6 @@ HEADERS += kernel/qtnetworkglobal.h \
kernel/qtnetworkglobal_p.h \
kernel/qauthenticator.h \
kernel/qauthenticator_p.h \
- kernel/qdnslookup.h \
- kernel/qdnslookup_p.h \
kernel/qhostaddress.h \
kernel/qhostaddress_p.h \
kernel/qhostinfo.h \
@@ -17,10 +15,10 @@ HEADERS += kernel/qtnetworkglobal.h \
kernel/qnetworkdatagram_p.h \
kernel/qnetworkinterface.h \
kernel/qnetworkinterface_p.h \
+ kernel/qnetworkinterface_unix_p.h \
kernel/qnetworkproxy.h
SOURCES += kernel/qauthenticator.cpp \
- kernel/qdnslookup.cpp \
kernel/qhostaddress.cpp \
kernel/qhostinfo.cpp \
kernel/qnetworkdatagram.cpp \
@@ -32,12 +30,22 @@ qtConfig(ftp) {
SOURCES += kernel/qurlinfo.cpp
}
+qtConfig(dnslookup) {
+ HEADERS += kernel/qdnslookup.h \
+ kernel/qdnslookup_p.h
+
+ SOURCES += kernel/qdnslookup.cpp
+}
+
unix {
- !integrity: SOURCES += kernel/qdnslookup_unix.cpp
- SOURCES += kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp
+ !integrity:qtConfig(dnslookup): SOURCES += kernel/qdnslookup_unix.cpp
+ SOURCES += kernel/qhostinfo_unix.cpp
+
+ qtConfig(linux-netlink): SOURCES += kernel/qnetworkinterface_linux.cpp
+ else: SOURCES += kernel/qnetworkinterface_unix.cpp
}
-android {
+android:qtConfig(dnslookup) {
SOURCES -= kernel/qdnslookup_unix.cpp
SOURCES += kernel/qdnslookup_android.cpp
}
@@ -46,12 +54,12 @@ win32: {
SOURCES += kernel/qhostinfo_win.cpp
!winrt {
- SOURCES += kernel/qdnslookup_win.cpp \
- kernel/qnetworkinterface_win.cpp
+ SOURCES += kernel/qnetworkinterface_win.cpp
+ qtConfig(dnslookup): SOURCES += kernel/qdnslookup_win.cpp
LIBS_PRIVATE += -ldnsapi -liphlpapi
} else {
- SOURCES += kernel/qdnslookup_winrt.cpp \
- kernel/qnetworkinterface_winrt.cpp
+ SOURCES += kernel/qnetworkinterface_winrt.cpp
+ qtConfig(dnslookup): SOURCES += kernel/qdnslookup_winrt.cpp
}
}
@@ -60,6 +68,7 @@ mac {
!uikit: LIBS_PRIVATE += -framework CoreServices -framework SystemConfiguration
}
+uikit:HEADERS += kernel/qnetworkinterface_uikit_p.h
osx:SOURCES += kernel/qnetworkproxy_mac.cpp
else:win32:!winrt: SOURCES += kernel/qnetworkproxy_win.cpp
else: qtConfig(libproxy) {
diff --git a/src/network/kernel/qdnslookup.h b/src/network/kernel/qdnslookup.h
index ead5e650f5..eebd0abe66 100644
--- a/src/network/kernel/qdnslookup.h
+++ b/src/network/kernel/qdnslookup.h
@@ -47,6 +47,8 @@
#include <QtCore/qsharedpointer.h>
#include <QtCore/qstring.h>
+QT_REQUIRE_CONFIG(dnslookup);
+
QT_BEGIN_NAMESPACE
class QHostAddress;
@@ -218,9 +220,9 @@ public:
};
Q_ENUM(Type)
- explicit QDnsLookup(QObject *parent = Q_NULLPTR);
- QDnsLookup(Type type, const QString &name, QObject *parent = Q_NULLPTR);
- QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent = Q_NULLPTR);
+ explicit QDnsLookup(QObject *parent = nullptr);
+ QDnsLookup(Type type, const QString &name, QObject *parent = nullptr);
+ QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent = nullptr);
~QDnsLookup();
Error error() const;
diff --git a/src/network/kernel/qdnslookup_p.h b/src/network/kernel/qdnslookup_p.h
index d070286383..4584396efe 100644
--- a/src/network/kernel/qdnslookup_p.h
+++ b/src/network/kernel/qdnslookup_p.h
@@ -60,6 +60,8 @@
#include "QtNetwork/qhostaddress.h"
#include "private/qobject_p.h"
+QT_REQUIRE_CONFIG(dnslookup);
+
QT_BEGIN_NAMESPACE
//#define QDNSLOOKUP_DEBUG
@@ -118,7 +120,7 @@ public:
, requestName(name)
, nameserver(nameserver)
{ }
- void run() Q_DECL_OVERRIDE;
+ void run() override;
signals:
void finished(const QDnsLookupReply &reply);
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index a1adc61c4c..bf00c6efce 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -64,32 +64,6 @@
QT_BEGIN_NAMESPACE
-
-class QHostAddressPrivate : public QSharedData
-{
-public:
- QHostAddressPrivate();
-
- void setAddress(quint32 a_ = 0);
- void setAddress(const quint8 *a_);
- void setAddress(const Q_IPV6ADDR &a_);
-
- bool parse(const QString &ipString);
- void clear();
-
- QString scopeId;
-
- union {
- Q_IPV6ADDR a6; // IPv6 address
- struct { quint64 c[2]; } a6_64;
- struct { quint32 c[4]; } a6_32;
- };
- quint32 a; // IPv4 address
- qint8 protocol;
-
- friend class QHostAddress;
-};
-
QHostAddressPrivate::QHostAddressPrivate()
: a(0), protocol(QAbstractSocket::UnknownNetworkLayerProtocol)
{
@@ -205,6 +179,75 @@ void QHostAddressPrivate::clear()
memset(&a6, 0, sizeof(a6));
}
+AddressClassification QHostAddressPrivate::classify() const
+{
+ if (a) {
+ // This is an IPv4 address or an IPv6 v4-mapped address includes all
+ // IPv6 v4-compat addresses, except for ::ffff:0.0.0.0 (because `a' is
+ // zero). See setAddress(quint8*) below, which calls convertToIpv4(),
+ // for details.
+ // Source: RFC 5735
+ if ((a & 0xff000000U) == 0x7f000000U) // 127.0.0.0/8
+ return LoopbackAddress;
+ if ((a & 0xf0000000U) == 0xe0000000U) // 224.0.0.0/4
+ return MulticastAddress;
+ if ((a & 0xffff0000U) == 0xa9fe0000U) // 169.254.0.0/16
+ return LinkLocalAddress;
+ if ((a & 0xff000000U) == 0) // 0.0.0.0/8 except 0.0.0.0 (handled below)
+ return LocalNetAddress;
+ if ((a & 0xf0000000U) == 0xf0000000U) { // 240.0.0.0/4
+ if (a == 0xffffffffU) // 255.255.255.255
+ return BroadcastAddress;
+ return UnknownAddress;
+ }
+
+ // Not testing for PrivateNetworkAddress and TestNetworkAddress
+ // since we don't need them yet.
+ return GlobalAddress;
+ }
+
+ // As `a' is zero, this address is either ::ffff:0.0.0.0 or a non-v4-mapped IPv6 address.
+ // Source: https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
+ if (a6_64.c[0]) {
+ quint32 high16 = qFromBigEndian(a6_32.c[0]) >> 16;
+ switch (high16 >> 8) {
+ case 0xff: // ff00::/8
+ return MulticastAddress;
+ case 0xfe:
+ switch (high16 & 0xffc0) {
+ case 0xfec0: // fec0::/10
+ return SiteLocalAddress;
+
+ case 0xfe80: // fe80::/10
+ return LinkLocalAddress;
+
+ default: // fe00::/9
+ return UnknownAddress;
+ }
+ case 0xfd: // fc00::/7
+ case 0xfc:
+ return UniqueLocalAddress;
+ default:
+ return GlobalAddress;
+ }
+ }
+
+ quint64 low64 = qFromBigEndian(a6_64.c[1]);
+ if (low64 == 1) // ::1
+ return LoopbackAddress;
+ if (low64 >> 32 == 0xffff) { // ::ffff:0.0.0.0/96
+ Q_ASSERT(quint32(low64) == 0);
+ return LocalNetAddress;
+ }
+ if (low64) // not ::
+ return GlobalAddress;
+
+ if (protocol == QAbstractSocket::UnknownNetworkLayerProtocol)
+ return UnknownAddress;
+
+ // only :: and 0.0.0.0 remain now
+ return LocalNetAddress;
+}
bool QNetmask::setAddress(const QHostAddress &address)
{
@@ -685,7 +728,7 @@ void QHostAddress::setAddress(SpecialAddress address)
*/
quint32 QHostAddress::toIPv4Address() const
{
- return toIPv4Address(Q_NULLPTR);
+ return toIPv4Address(nullptr);
}
/*!
@@ -1154,21 +1197,91 @@ QPair<QHostAddress, int> QHostAddress::parseSubnet(const QString &subnet)
*/
bool QHostAddress::isLoopback() const
{
- if ((d->a & 0xFF000000) == 0x7F000000)
- return true; // v4 range (including IPv6 wrapped IPv4 addresses)
- if (d->protocol == QAbstractSocket::IPv6Protocol) {
-#ifdef __SSE2__
- const __m128i loopback = _mm_setr_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
- __m128i ipv6 = _mm_loadu_si128((const __m128i *)d->a6.c);
- __m128i cmp = _mm_cmpeq_epi8(ipv6, loopback);
- return _mm_movemask_epi8(cmp) == 0xffff;
-#else
- if (d->a6_64.c[0] != 0 || qFromBigEndian(d->a6_64.c[1]) != 1)
- return false;
-#endif
- return true;
- }
- return false;
+ return d->classify() == LoopbackAddress;
+}
+
+/*!
+ \since 5.11
+
+ Returns \c true if the address is an IPv4 or IPv6 global address, \c false
+ otherwise. A global address is an address that is not reserved for
+ special purposes (like loopback or multicast) or future purposes.
+
+ Note that IPv6 unique local unicast addresses are considered global
+ addresses (see isUniqueLocalUnicast()), as are IPv4 addresses reserved for
+ local networks by \l {https://tools.ietf.org/html/rfc1918}{RFC 1918}.
+
+ Also note that IPv6 site-local addresses are deprecated and should be
+ considered as global in new applications. This function returns true for
+ site-local addresses too.
+
+ \sa isLoopback(), isSiteLocal(), isUniqueLocalUnicast()
+*/
+bool QHostAddress::isGlobal() const
+{
+ return d->classify() & GlobalAddress; // GlobalAddress is a bit
+}
+
+/*!
+ \since 5.11
+
+ Returns \c true if the address is an IPv4 or IPv6 link-local address, \c
+ false otherwise.
+
+ An IPv4 link-local address is an address in the network 169.254.0.0/16. An
+ IPv6 link-local address is one in the network fe80::/10. See the
+ \l{https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml}{IANA
+ IPv6 Address Space} registry for more information.
+
+ \sa isLoopback(), isGlobal(). isMulticast(), isSiteLocal(), isUniqueLocalUnicast()
+*/
+bool QHostAddress::isLinkLocal() const
+{
+ return d->classify() == LinkLocalAddress;
+}
+
+/*!
+ \since 5.11
+
+ Returns \c true if the address is an IPv6 site-local address, \c
+ false otherwise.
+
+ An IPv6 site-local address is one in the network fec0::/10. See the
+ \l{https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml}{IANA
+ IPv6 Address Space} registry for more information.
+
+ IPv6 site-local addresses are deprecated and should not be depended upon in
+ new applications. New applications should not depend on this function and
+ should consider site-local addresses the same as global (which is why
+ isGlobal() also returns true). Site-local addresses were replaced by Unique
+ Local Addresses (ULA).
+
+ \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast()
+*/
+bool QHostAddress::isSiteLocal() const
+{
+ return d->classify() == SiteLocalAddress;
+}
+
+/*!
+ \since 5.11
+
+ Returns \c true if the address is an IPv6 unique local unicast address, \c
+ false otherwise.
+
+ An IPv6 unique local unicast address is one in the network fc00::/7. See the
+ \l{https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml}
+ {IANA IPv6 Address Space} registry for more information.
+
+ Note that Unique local unicast addresses count as global addresses too. RFC
+ 4193 says that, in practice, "applications may treat these addresses like
+ global scoped addresses." Only routers need care about the distinction.
+
+ \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast()
+*/
+bool QHostAddress::isUniqueLocalUnicast() const
+{
+ return d->classify() == UniqueLocalAddress;
}
/*!
@@ -1176,14 +1289,29 @@ bool QHostAddress::isLoopback() const
Returns \c true if the address is an IPv4 or IPv6 multicast address, \c
false otherwise.
+
+ \sa isLoopback(), isGlobal(), isLinkLocal(), isSiteLocal(), isUniqueLocalUnicast()
*/
bool QHostAddress::isMulticast() const
{
- if ((d->a & 0xF0000000) == 0xE0000000)
- return true; // 224.0.0.0-239.255.255.255 (including v4-mapped IPv6 addresses)
- if (d->protocol == QAbstractSocket::IPv6Protocol)
- return d->a6.c[0] == 0xff;
- return false;
+ return d->classify() == MulticastAddress;
+}
+
+/*!
+ \since 5.11
+
+ Returns \c true if the address is the IPv4 broadcast address, \c false
+ otherwise. The IPv4 broadcast address is 255.255.255.255.
+
+ Note that this function does not return true for an IPv4 network's local
+ broadcast address. For that, please use \l QNetworkInterface to obtain the
+ broadcast addresses of the local machine.
+
+ \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast()
+*/
+bool QHostAddress::isBroadcast() const
+{
+ return d->classify() == BroadcastAddress;
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h
index fdbdbfc72c..00555f3d8e 100644
--- a/src/network/kernel/qhostaddress.h
+++ b/src/network/kernel/qhostaddress.h
@@ -148,12 +148,18 @@ public:
bool isInSubnet(const QPair<QHostAddress, int> &subnet) const;
bool isLoopback() const;
+ bool isGlobal() const;
+ bool isLinkLocal() const;
+ bool isSiteLocal() const;
+ bool isUniqueLocalUnicast() const;
bool isMulticast() const;
+ bool isBroadcast() const;
static QPair<QHostAddress, int> parseSubnet(const QString &subnet);
friend Q_NETWORK_EXPORT uint qHash(const QHostAddress &key, uint seed) Q_DECL_NOTHROW;
protected:
+ friend class QHostAddressPrivate;
QExplicitlySharedDataPointer<QHostAddressPrivate> d;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QHostAddress::ConversionMode)
diff --git a/src/network/kernel/qhostaddress_p.h b/src/network/kernel/qhostaddress_p.h
index 5106760ed9..4dc2989011 100644
--- a/src/network/kernel/qhostaddress_p.h
+++ b/src/network/kernel/qhostaddress_p.h
@@ -57,6 +57,22 @@
QT_BEGIN_NAMESPACE
+enum AddressClassification {
+ LoopbackAddress = 1,
+ LocalNetAddress, // RFC 1122
+ LinkLocalAddress, // RFC 4291 (v6), RFC 3927 (v4)
+ MulticastAddress, // RFC 4291 (v6), RFC 3171 (v4)
+ BroadcastAddress, // RFC 919, 922
+
+ GlobalAddress = 16,
+ TestNetworkAddress, // RFC 3849 (v6), RFC 5737 (v4),
+ PrivateNetworkAddress, // RFC 1918
+ UniqueLocalAddress, // RFC 4193
+ SiteLocalAddress, // RFC 4291 (deprecated by RFC 3879, should be treated as global)
+
+ UnknownAddress = 0 // unclassified or reserved
+};
+
class QNetmask
{
// stores 0-32 for IPv4, 0-128 for IPv6, or 255 for invalid
@@ -85,6 +101,35 @@ public:
{ return n1.length == n2.length; }
};
+class QHostAddressPrivate : public QSharedData
+{
+public:
+ QHostAddressPrivate();
+
+ void setAddress(quint32 a_ = 0);
+ void setAddress(const quint8 *a_);
+ void setAddress(const Q_IPV6ADDR &a_);
+
+ bool parse(const QString &ipString);
+ void clear();
+
+ QString scopeId;
+
+ union {
+ Q_IPV6ADDR a6; // IPv6 address
+ struct { quint64 c[2]; } a6_64;
+ struct { quint32 c[4]; } a6_32;
+ };
+ quint32 a; // IPv4 address
+ qint8 protocol;
+
+ AddressClassification classify() const;
+ static AddressClassification classify(const QHostAddress &address)
+ { return address.d->classify(); }
+
+ friend class QHostAddress;
+};
+
QT_END_NAMESPACE
#endif
diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h
index dd46818a19..d1da814e54 100644
--- a/src/network/kernel/qhostinfo_p.h
+++ b/src/network/kernel/qhostinfo_p.h
@@ -194,7 +194,7 @@ public:
QHostInfoRunnable(const QString &hn, int i);
QHostInfoRunnable(const QString &hn, int i, const QObject *receiver,
QtPrivate::QSlotObjectBase *slotObj);
- void run() Q_DECL_OVERRIDE;
+ void run() override;
QString toBeLookedUp;
int id;
@@ -225,7 +225,7 @@ public:
QHostInfoLookupManager();
~QHostInfoLookupManager();
- void clear() Q_DECL_OVERRIDE;
+ void clear() override;
void work();
// called from QHostInfo
diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp
index 8d2cffc304..d22608e22f 100644
--- a/src/network/kernel/qhostinfo_unix.cpp
+++ b/src/network/kernel/qhostinfo_unix.cpp
@@ -79,6 +79,11 @@ QT_BEGIN_NAMESPACE
# define Q_ADDRCONFIG AI_ADDRCONFIG
#endif
+enum LibResolvFeature {
+ NeedResInit,
+ NeedResNInit
+};
+
typedef struct __res_state *res_state_ptr;
typedef int (*res_init_proto)(void);
@@ -89,9 +94,29 @@ typedef void (*res_nclose_proto)(res_state_ptr);
static res_nclose_proto local_res_nclose = 0;
static res_state_ptr local_res = 0;
-static bool resolveLibraryInternal()
-{
#if QT_CONFIG(library) && !defined(Q_OS_QNX)
+namespace {
+struct LibResolv
+{
+ enum {
+#ifdef RES_NORELOAD
+ // If RES_NORELOAD is defined, then the libc is capable of watching
+ // /etc/resolv.conf for changes and reloading as necessary. So accept
+ // whatever is configured.
+ ReinitNecessary = false
+#else
+ ReinitNecessary = true
+#endif
+ };
+
+ QLibrary lib;
+ LibResolv();
+ ~LibResolv() { lib.unload(); }
+};
+}
+
+LibResolv::LibResolv()
+{
QLibrary lib;
#ifdef LIBRESOLV_SO
lib.setFileName(QStringLiteral(LIBRESOLV_SO));
@@ -100,32 +125,45 @@ static bool resolveLibraryInternal()
{
lib.setFileName(QLatin1String("resolv"));
if (!lib.load())
- return false;
+ return;
}
- local_res_init = res_init_proto(lib.resolve("__res_init"));
- if (!local_res_init)
- local_res_init = res_init_proto(lib.resolve("res_init"));
-
+ // res_ninit is required for localDomainName()
local_res_ninit = res_ninit_proto(lib.resolve("__res_ninit"));
if (!local_res_ninit)
local_res_ninit = res_ninit_proto(lib.resolve("res_ninit"));
-
- if (!local_res_ninit) {
- // if we can't get a thread-safe context, we have to use the global _res state
- local_res = res_state_ptr(lib.resolve("_res"));
- } else {
+ if (local_res_ninit) {
+ // we must now find res_nclose
local_res_nclose = res_nclose_proto(lib.resolve("res_nclose"));
if (!local_res_nclose)
local_res_nclose = res_nclose_proto(lib.resolve("__res_nclose"));
if (!local_res_nclose)
- local_res_ninit = 0;
+ local_res_ninit = nullptr;
}
-#endif
- return true;
+ if (ReinitNecessary || !local_res_ninit) {
+ local_res_init = res_init_proto(lib.resolve("__res_init"));
+ if (!local_res_init)
+ local_res_init = res_init_proto(lib.resolve("res_init"));
+
+ if (local_res_init && !local_res_ninit) {
+ // if we can't get a thread-safe context, we have to use the global _res state
+ local_res = res_state_ptr(lib.resolve("_res"));
+ }
+ }
+}
+Q_GLOBAL_STATIC(LibResolv, libResolv)
+
+static void resolveLibrary(LibResolvFeature f)
+{
+ if (LibResolv::ReinitNecessary || f == NeedResNInit)
+ libResolv();
+}
+#else // QT_CONFIG(library) || Q_OS_QNX
+static void resolveLibrary(LibResolvFeature)
+{
}
-Q_GLOBAL_STATIC_WITH_ARGS(bool, resolveLibrary, (resolveLibraryInternal()))
+#endif // QT_CONFIG(library) || Q_OS_QNX
QHostInfo QHostInfoAgent::fromName(const QString &hostName)
{
@@ -137,7 +175,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
#endif
// Load res_init on demand.
- resolveLibrary();
+ resolveLibrary(NeedResInit);
// If res_init is available, poll it.
if (local_res_init)
@@ -275,7 +313,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
QString QHostInfo::localDomainName()
{
#if !defined(Q_OS_VXWORKS) && !defined(Q_OS_ANDROID)
- resolveLibrary();
+ resolveLibrary(NeedResNInit);
if (local_res_ninit) {
// using thread-safe version
res_state_ptr state = res_state_ptr(malloc(sizeof(*state)));
diff --git a/src/network/kernel/qnetworkdatagram.h b/src/network/kernel/qnetworkdatagram.h
index fa994d6170..c7605d67ba 100644
--- a/src/network/kernel/qnetworkdatagram.h
+++ b/src/network/kernel/qnetworkdatagram.h
@@ -63,7 +63,7 @@ public:
QNetworkDatagram(QNetworkDatagram &&other) Q_DECL_NOTHROW
: d(other.d)
- { other.d = Q_NULLPTR; }
+ { other.d = nullptr; }
QNetworkDatagram &operator=(QNetworkDatagram &&other) Q_DECL_NOTHROW
{ swap(other); return *this; }
diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp
index 3857ff87b9..3fb0dc80ee 100644
--- a/src/network/kernel/qnetworkinterface.cpp
+++ b/src/network/kernel/qnetworkinterface.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2017 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -59,19 +59,15 @@ static QList<QNetworkInterfacePrivate *> postProcess(QList<QNetworkInterfacePriv
// The math is:
// broadcast = IP | ~netmask
- QList<QNetworkInterfacePrivate *>::Iterator it = list.begin();
- const QList<QNetworkInterfacePrivate *>::Iterator end = list.end();
- for ( ; it != end; ++it) {
- QList<QNetworkAddressEntry>::Iterator addr_it = (*it)->addressEntries.begin();
- const QList<QNetworkAddressEntry>::Iterator addr_end = (*it)->addressEntries.end();
- for ( ; addr_it != addr_end; ++addr_it) {
- if (addr_it->ip().protocol() != QAbstractSocket::IPv4Protocol)
+ for (QNetworkInterfacePrivate *interface : list) {
+ for (QNetworkAddressEntry &address : interface->addressEntries) {
+ if (address.ip().protocol() != QAbstractSocket::IPv4Protocol)
continue;
- if (!addr_it->netmask().isNull() && addr_it->broadcast().isNull()) {
- QHostAddress bcast = addr_it->ip();
- bcast = QHostAddress(bcast.toIPv4Address() | ~addr_it->netmask().toIPv4Address());
- addr_it->setBroadcast(bcast);
+ if (!address.netmask().isNull() && address.broadcast().isNull()) {
+ QHostAddress bcast = address.ip();
+ bcast = QHostAddress(bcast.toIPv4Address() | ~address.netmask().toIPv4Address());
+ address.setBroadcast(bcast);
}
}
}
@@ -91,17 +87,16 @@ QNetworkInterfaceManager::~QNetworkInterfaceManager()
QSharedDataPointer<QNetworkInterfacePrivate> QNetworkInterfaceManager::interfaceFromName(const QString &name)
{
- QList<QSharedDataPointer<QNetworkInterfacePrivate> > interfaceList = allInterfaces();
- QList<QSharedDataPointer<QNetworkInterfacePrivate> >::ConstIterator it = interfaceList.constBegin();
+ const auto interfaceList = allInterfaces();
bool ok;
uint index = name.toUInt(&ok);
- for ( ; it != interfaceList.constEnd(); ++it) {
- if (ok && (*it)->index == int(index))
- return *it;
- else if ((*it)->name == name)
- return *it;
+ for (const auto &interface : interfaceList) {
+ if (ok && interface->index == int(index))
+ return interface;
+ else if (interface->name == name)
+ return interface;
}
return empty;
@@ -109,11 +104,11 @@ QSharedDataPointer<QNetworkInterfacePrivate> QNetworkInterfaceManager::interface
QSharedDataPointer<QNetworkInterfacePrivate> QNetworkInterfaceManager::interfaceFromIndex(int index)
{
- QList<QSharedDataPointer<QNetworkInterfacePrivate> > interfaceList = allInterfaces();
- QList<QSharedDataPointer<QNetworkInterfacePrivate> >::ConstIterator it = interfaceList.constBegin();
- for ( ; it != interfaceList.constEnd(); ++it)
- if ((*it)->index == index)
- return *it;
+ const auto interfaceList = allInterfaces();
+ for (const auto &interface : interfaceList) {
+ if (interface->index == index)
+ return interface;
+ }
return empty;
}
@@ -124,8 +119,15 @@ QList<QSharedDataPointer<QNetworkInterfacePrivate> > QNetworkInterfaceManager::a
QList<QSharedDataPointer<QNetworkInterfacePrivate> > result;
result.reserve(list.size());
- for (QNetworkInterfacePrivate *ptr : list)
+ for (QNetworkInterfacePrivate *ptr : list) {
+ if ((ptr->flags & QNetworkInterface::IsUp) == 0) {
+ // if the network interface isn't UP, the addresses are ineligible for DNS
+ for (auto &addr : ptr->addressEntries)
+ addr.setDnsEligibility(QNetworkAddressEntry::DnsIneligible);
+ }
+
result << QSharedDataPointer<QNetworkInterfacePrivate>(ptr);
+ }
return result;
}
@@ -164,6 +166,32 @@ QString QNetworkInterfacePrivate::makeHwAddress(int len, uchar *data)
*/
/*!
+ \enum QNetworkAddressEntry::DnsEligilibilityStatus
+ \since 5.11
+
+ This enum indicates whether a given host address is eligible to be
+ published in the Domain Name System (DNS) or other similar name resolution
+ mechanisms. In general, an address is suitable for publication if it is an
+ address this machine will be reached at for an indeterminate amount of
+ time, though it need not be permanent. For example, addresses obtained via
+ DHCP are often eligible, but cryptographically-generated temporary IPv6
+ addresses are not.
+
+ \value DnsEligibilityUnknown Qt and the operating system could not determine
+ whether this address should be published or not.
+ The application may need to apply further
+ heuristics if it cannot find any eligible
+ addresses.
+ \value DnsEligible This address is eligible for publication in DNS.
+ \value DnsIneligible This address should not be published in DNS and
+ should not be transmitted to other parties,
+ except maybe as the source address of an outgoing
+ packet.
+
+ \sa dnsEligibility(), setDnsEligibility()
+*/
+
+/*!
Constructs an empty QNetworkAddressEntry object.
*/
QNetworkAddressEntry::QNetworkAddressEntry()
@@ -218,6 +246,39 @@ bool QNetworkAddressEntry::operator==(const QNetworkAddressEntry &other) const
}
/*!
+ \since 5.11
+
+ Returns whether this address is eligible for publication in the Domain Name
+ System (DNS) or similar name resolution mechanisms.
+
+ In general, an address is suitable for publication if it is an address this
+ machine will be reached at for an indeterminate amount of time, though it
+ need not be permanent. For example, addresses obtained via DHCP are often
+ eligible, but cryptographically-generated temporary IPv6 addresses are not.
+
+ On some systems, QNetworkInterface will need to heuristically determine
+ which addresses are eligible.
+
+ \sa isLifetimeKnown(), isPermanent(), setDnsEligibility()
+*/
+QNetworkAddressEntry::DnsEligibilityStatus QNetworkAddressEntry::dnsEligibility() const
+{
+ return d->dnsEligibility;
+}
+
+/*!
+ \since 5.11
+
+ Sets the DNS eligibility flag for this address to \a status.
+
+ \sa dnsEligibility()
+*/
+void QNetworkAddressEntry::setDnsEligibility(DnsEligibilityStatus status)
+{
+ d->dnsEligibility = status;
+}
+
+/*!
\fn bool QNetworkAddressEntry::operator!=(const QNetworkAddressEntry &other) const
Returns \c true if this network address entry is different from \a
@@ -340,6 +401,122 @@ void QNetworkAddressEntry::setBroadcast(const QHostAddress &newBroadcast)
}
/*!
+ \since 5.11
+
+ Returns \c true if the address lifetime is known, \c false if not. If the
+ lifetime is not known, both preferredLifetime() and validityLifetime() will
+ return QDeadlineTimer::Forever.
+
+ \sa preferredLifetime(), validityLifetime(), setAddressLifetime(), clearAddressLifetime()
+*/
+bool QNetworkAddressEntry::isLifetimeKnown() const
+{
+ return d->lifetimeKnown;
+}
+
+/*!
+ \since 5.11
+
+ Returns the deadline when this address becomes deprecated (no longer
+ preferred), if known. If the address lifetime is not known (see
+ isLifetimeKnown()), this function always returns QDeadlineTimer::Forever.
+
+ While an address is preferred, it may be used by the operating system as
+ the source address for new, outgoing packets. After it becomes deprecated,
+ it will remain valid for incoming packets for a while longer until finally
+ removed (see validityLifetime()).
+
+ \sa validityLifetime(), isLifetimeKnown(), setAddressLifetime(), clearAddressLifetime()
+*/
+QDeadlineTimer QNetworkAddressEntry::preferredLifetime() const
+{
+ return d->preferredLifetime;
+}
+
+/*!
+ \since 5.11
+
+ Returns the deadline when this address becomes invalid and will be removed
+ from the networking stack, if known. If the address lifetime is not known
+ (see isLifetimeKnown()), this function always returns
+ QDeadlineTimer::Forever.
+
+ While an address is valid, it will be accepted by the operating system as a
+ valid destination address for this machine. Whether it is used as a source
+ address for new, outgoing packets is controlled by, among other rules, the
+ preferred lifetime (see preferredLifetime()).
+
+ \sa preferredLifetime(), isLifetimeKnown(), setAddressLifetime(), clearAddressLifetime()
+*/
+QDeadlineTimer QNetworkAddressEntry::validityLifetime() const
+{
+ return d->validityLifetime;
+}
+
+/*!
+ \since 5.11
+
+ Sets both the preferred and valid lifetimes for this address to the \a
+ preferred and \a validity deadlines, respectively. After this call,
+ isLifetimeKnown() will return \c true, even if both parameters are
+ QDeadlineTimer::Forever.
+
+ \sa preferredLifetime(), validityLifetime(), isLifetimeKnown(), clearAddressLifetime()
+*/
+void QNetworkAddressEntry::setAddressLifetime(QDeadlineTimer preferred, QDeadlineTimer validity)
+{
+ d->preferredLifetime = preferred;
+ d->validityLifetime = validity;
+ d->lifetimeKnown = true;
+}
+
+/*!
+ \since 5.11
+
+ Resets both the preferred and valid lifetimes for this address. After this
+ call, isLifetimeKnown() will return \c false.
+
+ \sa preferredLifetime(), validityLifetime(), isLifetimeKnown(), setAddressLifetime()
+*/
+void QNetworkAddressEntry::clearAddressLifetime()
+{
+ d->preferredLifetime = QDeadlineTimer::Forever;
+ d->validityLifetime = QDeadlineTimer::Forever;
+ d->lifetimeKnown = false;
+}
+
+/*!
+ \since 5.11
+
+ Returns \c true if this address is permanent on this interface, \c false if
+ it's temporary. A permenant address is one which has no expiration time and
+ is often static (manually configured).
+
+ If this information could not be determined, this function returns \c true.
+
+ \note Depending on the operating system and the networking configuration
+ tool, it is possible for a temporary address to be interpreted as
+ permanent, if the tool did not inform the details correctly to the
+ operating system.
+
+ \sa isLifetimeKnown(), validityLifetime(), isTemporary()
+*/
+bool QNetworkAddressEntry::isPermanent() const
+{
+ return d->validityLifetime.isForever();
+}
+
+/*!
+ \fn bool QNetworkAddressEntry::isTemporary() const
+ \since 5.11
+
+ Returns \c true if this address is temporary on this interface, \c false if
+ it's permanent.
+
+ \sa isLifetimeKnown(), validityLifetime(), isPermanent()
+*/
+
+/*!
\class QNetworkInterface
\brief The QNetworkInterface class provides a listing of the host's IP
addresses and network interfaces.
@@ -396,6 +573,57 @@ void QNetworkAddressEntry::setBroadcast(const QHostAddress &newBroadcast)
*/
/*!
+ \enum QNetworkInterface::InterfaceType
+
+ Specifies the type of hardware (PHY layer, OSI level 1) this interface is,
+ if it could be determined. Interface types that are not among those listed
+ below will generally be listed as Unknown, though future versions of Qt may
+ add new enumeration values.
+
+ The possible values are:
+
+ \value Unknown The interface type could not be determined or is not
+ one of the other listed types.
+ \value Loopback The virtual loopback interface, which is assigned
+ the loopback IP addresses (127.0.0.1, ::1).
+ \value Virtual A type of interface determined to be virtual, but
+ not any of the other possible types. For example,
+ tunnel interfaces are (currently) detected as
+ virtual ones.
+ \value Ethernet IEEE 802.3 Ethernet interfaces, though on many
+ systems other types of IEEE 802 interfaces may also
+ be detected as Ethernet (especially Wi-Fi).
+ \value WiFi IEEE 802.11 Wi-Fi interfaces. Note that on some
+ systems, QNetworkInterface may be unable to
+ distinguish regular Ethernet from Wi-Fi and will
+ not return this enum value.
+ \value Ieee80211 An alias for WiFi.
+ \value CanBus ISO 11898 Controller Area Network bus interfaces,
+ usually found on automotive systems.
+ \value Fddi ANSI X3T12 Fiber Distributed Data Interface, a local area
+ network over optical fibers.
+ \value Ppp Point-to-Point Protocol interfaces, establishing a
+ direct connection between two nodes over a lower
+ transport layer (often serial over radio or physical
+ line).
+ \value Slip Serial Line Internet Protocol interfaces.
+ \value Phonet Interfaces using the Linux Phonet socket family, for
+ communication with cellular modems. See the
+ \l {https://www.kernel.org/doc/Documentation/networking/phonet.txt}{Linux kernel documentation}
+ for more information.
+ \value Ieee802154 IEEE 802.15.4 Personal Area Network interfaces, other
+ than 6LoWPAN (see below).
+ \value SixLoWPAN 6LoWPAN (IPv6 over Low-power Wireless Personal Area
+ Networks) interfaces, which operate on IEEE 802.15.4
+ PHY, but have specific header compression schemes
+ for IPv6 and UDP. This type of interface is often
+ used for mesh networking.
+ \value Ieee80216 IEEE 802.16 Wireless Metropolitan Area Network, also
+ known under the commercial name "WiMAX".
+ \value Ieee1394 IEEE 1394 interfaces (a.k.a. "FireWire").
+*/
+
+/*!
Constructs an empty network interface object.
*/
QNetworkInterface::QNetworkInterface()
@@ -461,6 +689,29 @@ int QNetworkInterface::index() const
}
/*!
+ \since 5.11
+
+ Returns the maximum transmission unit on this interface, if known, or 0
+ otherwise.
+
+ The maximum transmission unit is the largest packet that may be sent on
+ this interface without incurring link-level fragmentation. Applications may
+ use this value to calculate the size of the payload that will fit an
+ unfragmented UDP datagram. Remember to subtract the sizes of headers used
+ in your communication over the interface, e.g. TCP (20 bytes) or UDP (12),
+ IPv4 (20) or IPv6 (40, absent some form of header compression), when
+ computing how big a payload you can transmit. Also note that the MTU along
+ the full path (the Path MTU) to the destination may be smaller than the
+ interface's MTU.
+
+ \sa QUdpSocket
+*/
+int QNetworkInterface::maxTransmissionUnit() const
+{
+ return d ? d->mtu : 0;
+}
+
+/*!
Returns the name of this network interface. On Unix systems, this
is a string containing the type of the interface and optionally a
sequence number, such as "eth0", "lo" or "pcn0". On Windows, it's
@@ -499,6 +750,19 @@ QNetworkInterface::InterfaceFlags QNetworkInterface::flags() const
}
/*!
+ \since 5.11
+
+ Returns the type of this interface, if it could be determined. If it could
+ not be determined, this function returns QNetworkInterface::Unknown.
+
+ \sa hardwareAddress()
+*/
+QNetworkInterface::InterfaceType QNetworkInterface::type() const
+{
+ return d ? d->type : Unknown;
+}
+
+/*!
Returns the low-level hardware address for this interface. On
Ethernet interfaces, this will be a MAC address in string
representation, separated by colons.
@@ -506,6 +770,8 @@ QNetworkInterface::InterfaceFlags QNetworkInterface::flags() const
Other interface types may have other types of hardware
addresses. Implementations should not depend on this function
returning a valid MAC address.
+
+ \sa type()
*/
QString QNetworkInterface::hardwareAddress() const
{
@@ -691,4 +957,6 @@ QDebug operator<<(QDebug debug, const QNetworkInterface &networkInterface)
QT_END_NAMESPACE
+#include "moc_qnetworkinterface.cpp"
+
#endif // QT_NO_NETWORKINTERFACE
diff --git a/src/network/kernel/qnetworkinterface.h b/src/network/kernel/qnetworkinterface.h
index c31621c3cb..f7ef192dc0 100644
--- a/src/network/kernel/qnetworkinterface.h
+++ b/src/network/kernel/qnetworkinterface.h
@@ -49,13 +49,19 @@
QT_BEGIN_NAMESPACE
-
+class QDeadlineTimer;
template<typename T> class QList;
class QNetworkAddressEntryPrivate;
class Q_NETWORK_EXPORT QNetworkAddressEntry
{
public:
+ enum DnsEligibilityStatus : qint8 {
+ DnsEligibilityUnknown = -1,
+ DnsIneligible = 0,
+ DnsEligible = 1
+ };
+
QNetworkAddressEntry();
QNetworkAddressEntry(const QNetworkAddressEntry &other);
#ifdef Q_COMPILER_RVALUE_REFS
@@ -70,6 +76,9 @@ public:
inline bool operator!=(const QNetworkAddressEntry &other) const
{ return !(*this == other); }
+ DnsEligibilityStatus dnsEligibility() const;
+ void setDnsEligibility(DnsEligibilityStatus status);
+
QHostAddress ip() const;
void setIp(const QHostAddress &newIp);
@@ -81,6 +90,14 @@ public:
QHostAddress broadcast() const;
void setBroadcast(const QHostAddress &newBroadcast);
+ bool isLifetimeKnown() const;
+ QDeadlineTimer preferredLifetime() const;
+ QDeadlineTimer validityLifetime() const;
+ void setAddressLifetime(QDeadlineTimer preferred, QDeadlineTimer validity);
+ void clearAddressLifetime();
+ bool isPermanent() const;
+ bool isTemporary() const { return !isPermanent(); }
+
private:
QScopedPointer<QNetworkAddressEntryPrivate> d;
};
@@ -90,6 +107,7 @@ Q_DECLARE_SHARED(QNetworkAddressEntry)
class QNetworkInterfacePrivate;
class Q_NETWORK_EXPORT QNetworkInterface
{
+ Q_GADGET
public:
enum InterfaceFlag {
IsUp = 0x1,
@@ -100,6 +118,27 @@ public:
CanMulticast = 0x20
};
Q_DECLARE_FLAGS(InterfaceFlags, InterfaceFlag)
+ Q_FLAG(InterfaceFlags)
+
+ enum InterfaceType {
+ Loopback = 1,
+ Virtual,
+ Ethernet,
+ Slip,
+ CanBus,
+ Ppp,
+ Fddi,
+ Wifi,
+ Ieee80211 = Wifi, // alias
+ Phonet,
+ Ieee802154,
+ SixLoWPAN, // 6LoWPAN, but we can't start with a digit
+ Ieee80216,
+ Ieee1394,
+
+ Unknown = 0
+ };
+ Q_ENUM(InterfaceType)
QNetworkInterface();
QNetworkInterface(const QNetworkInterface &other);
@@ -114,9 +153,11 @@ public:
bool isValid() const;
int index() const;
+ int maxTransmissionUnit() const;
QString name() const;
QString humanReadableName() const;
InterfaceFlags flags() const;
+ InterfaceType type() const;
QString hardwareAddress() const;
QList<QNetworkAddressEntry> addressEntries() const;
diff --git a/src/network/kernel/qnetworkinterface_linux.cpp b/src/network/kernel/qnetworkinterface_linux.cpp
new file mode 100644
index 0000000000..620ee7202b
--- /dev/null
+++ b/src/network/kernel/qnetworkinterface_linux.cpp
@@ -0,0 +1,443 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnetworkinterface.h"
+#include "qnetworkinterface_p.h"
+#include "qnetworkinterface_unix_p.h"
+
+#include <qendian.h>
+#include <qobjectdefs.h>
+#include <qvarlengtharray.h>
+
+// accordding to rtnetlink(7)
+#include <asm/types.h>
+#include <linux/if.h>
+#include <linux/if_arp.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/wireless.h>
+#include <sys/socket.h>
+
+/* in case these aren't defined in linux/if_arp.h (added since 2.6.28) */
+#define ARPHRD_PHONET 820 /* v2.6.29: PhoNet media type */
+#define ARPHRD_PHONET_PIPE 821 /* v2.6.29: PhoNet pipe header */
+#define ARPHRD_IEEE802154 804 /* v2.6.31 */
+#define ARPHRD_6LOWPAN 825 /* v3.14: IPv6 over LoWPAN */
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ BufferSize = 8192
+};
+
+static QNetworkInterface::InterfaceType probeIfType(int socket, struct ifreq *req, short arptype)
+{
+ switch (ushort(arptype)) {
+ case ARPHRD_LOOPBACK:
+ return QNetworkInterface::Loopback;
+
+ case ARPHRD_ETHER:
+ // check if it's a WiFi interface
+ if (qt_safe_ioctl(socket, SIOCGIWMODE, req) >= 0)
+ return QNetworkInterface::Wifi;
+ return QNetworkInterface::Ethernet;
+
+ case ARPHRD_SLIP:
+ case ARPHRD_CSLIP:
+ case ARPHRD_SLIP6:
+ case ARPHRD_CSLIP6:
+ return QNetworkInterface::Slip;
+
+ case ARPHRD_CAN:
+ return QNetworkInterface::CanBus;
+
+ case ARPHRD_PPP:
+ return QNetworkInterface::Ppp;
+
+ case ARPHRD_FDDI:
+ return QNetworkInterface::Fddi;
+
+ case ARPHRD_IEEE80211:
+ case ARPHRD_IEEE80211_PRISM:
+ case ARPHRD_IEEE80211_RADIOTAP:
+ return QNetworkInterface::Ieee80211;
+
+ case ARPHRD_IEEE802154:
+ return QNetworkInterface::Ieee802154;
+
+ case ARPHRD_PHONET:
+ case ARPHRD_PHONET_PIPE:
+ return QNetworkInterface::Phonet;
+
+ case ARPHRD_6LOWPAN:
+ return QNetworkInterface::SixLoWPAN;
+
+ case ARPHRD_TUNNEL:
+ case ARPHRD_TUNNEL6:
+ case ARPHRD_NONE:
+ case ARPHRD_VOID:
+ return QNetworkInterface::Virtual;
+ }
+ return QNetworkInterface::Unknown;
+}
+
+
+namespace {
+struct NetlinkSocket
+{
+ int sock;
+ NetlinkSocket(int bufferSize)
+ {
+ sock = qt_safe_socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
+ if (Q_UNLIKELY(sock == -1))
+ qErrnoWarning("Could not create AF_NETLINK socket");
+
+ // set buffer length
+ socklen_t len = sizeof(bufferSize);
+ setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &bufferSize, len);
+ }
+
+ ~NetlinkSocket()
+ {
+ if (sock != -1)
+ qt_safe_close(sock);
+ }
+
+ operator int() const { return sock; }
+};
+
+template <typename Lambda> struct ProcessNetlinkRequest
+{
+ using FunctionTraits = QtPrivate::FunctionPointer<decltype(&Lambda::operator())>;
+ using FirstArgument = typename FunctionTraits::Arguments::Car;
+
+ static int expectedTypeForRequest(int rtype)
+ {
+ Q_STATIC_ASSERT(RTM_NEWADDR == RTM_GETADDR - 2);
+ Q_STATIC_ASSERT(RTM_NEWLINK == RTM_GETLINK - 2);
+ Q_ASSERT(rtype == RTM_GETADDR || rtype == RTM_GETLINK);
+ return rtype - 2;
+ }
+
+ void operator()(int sock, nlmsghdr *hdr, char *buf, size_t bufsize, Lambda &&func)
+ {
+ // send the request
+ if (send(sock, hdr, hdr->nlmsg_len, 0) != hdr->nlmsg_len)
+ return;
+
+ // receive and parse the request
+ int expectedType = expectedTypeForRequest(hdr->nlmsg_type);
+ const bool isDump = hdr->nlmsg_flags & NLM_F_DUMP;
+ forever {
+ qssize_t len = recv(sock, buf, bufsize, 0);
+ hdr = reinterpret_cast<struct nlmsghdr *>(buf);
+ if (!NLMSG_OK(hdr, len))
+ return;
+
+ auto arg = reinterpret_cast<FirstArgument>(NLMSG_DATA(hdr));
+ size_t payloadLen = NLMSG_PAYLOAD(hdr, 0);
+
+ // is this a multipart message?
+ Q_ASSERT(isDump == !!(hdr->nlmsg_flags & NLM_F_MULTI));
+ if (!isDump) {
+ // no, single message
+ if (hdr->nlmsg_type == expectedType && payloadLen >= sizeof(FirstArgument))
+ return void(func(arg, payloadLen));
+ } else {
+ // multipart, parse until done
+ do {
+ if (hdr->nlmsg_type == NLMSG_DONE)
+ return;
+ if (hdr->nlmsg_type != expectedType || payloadLen < sizeof(FirstArgument))
+ break;
+ func(arg, payloadLen);
+
+ // NLMSG_NEXT also updates the len variable
+ hdr = NLMSG_NEXT(hdr, len);
+ arg = reinterpret_cast<FirstArgument>(NLMSG_DATA(hdr));
+ payloadLen = NLMSG_PAYLOAD(hdr, 0);
+ } while (NLMSG_OK(hdr, len));
+
+ if (len == 0)
+ continue; // get new datagram
+ }
+
+#ifndef QT_NO_DEBUG
+ if (NLMSG_OK(hdr, len))
+ qWarning("QNetworkInterface/AF_NETLINK: received unknown packet type (%d) or too short (%u)",
+ hdr->nlmsg_type, hdr->nlmsg_len);
+ else
+ qWarning("QNetworkInterface/AF_NETLINK: received invalid packet with size %d", int(len));
+#endif
+ return;
+ }
+ }
+};
+
+template <typename Lambda>
+void processNetlinkRequest(int sock, struct nlmsghdr *hdr, char *buf, size_t bufsize, Lambda &&l)
+{
+ ProcessNetlinkRequest<Lambda>()(sock, hdr, buf, bufsize, std::forward<Lambda>(l));
+}
+}
+
+uint QNetworkInterfaceManager::interfaceIndexFromName(const QString &name)
+{
+ uint index = 0;
+ if (name.length() >= IFNAMSIZ)
+ return index;
+
+ int socket = qt_safe_socket(AF_INET, SOCK_DGRAM, 0);
+ if (socket >= 0) {
+ struct ifreq req;
+ req.ifr_ifindex = 0;
+ strcpy(req.ifr_name, name.toLatin1().constData());
+
+ if (qt_safe_ioctl(socket, SIOCGIFINDEX, &req) >= 0)
+ index = req.ifr_ifindex;
+ qt_safe_close(socket);
+ }
+ return index;
+}
+
+QString QNetworkInterfaceManager::interfaceNameFromIndex(uint index)
+{
+ int socket = qt_safe_socket(AF_INET, SOCK_DGRAM, 0);
+ if (socket >= 0) {
+ struct ifreq req;
+ req.ifr_ifindex = index;
+
+ if (qt_safe_ioctl(socket, SIOCGIFNAME, &req) >= 0) {
+ qt_safe_close(socket);
+ return QString::fromLatin1(req.ifr_name);
+ }
+ qt_safe_close(socket);
+ }
+ return QString();
+}
+
+static QList<QNetworkInterfacePrivate *> getInterfaces(int sock, char *buf)
+{
+ QList<QNetworkInterfacePrivate *> result;
+ struct ifreq req;
+
+ // request all links
+ struct {
+ struct nlmsghdr req;
+ struct ifinfomsg ifi;
+ } ifi_req;
+ memset(&ifi_req, 0, sizeof(ifi_req));
+
+ ifi_req.req.nlmsg_len = sizeof(ifi_req);
+ ifi_req.req.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+ ifi_req.req.nlmsg_type = RTM_GETLINK;
+
+ // parse the interfaces
+ processNetlinkRequest(sock, &ifi_req.req, buf, BufferSize, [&](ifinfomsg *ifi, size_t len) {
+ auto iface = new QNetworkInterfacePrivate;
+ iface->index = ifi->ifi_index;
+ iface->flags = convertFlags(ifi->ifi_flags);
+
+ // read attributes
+ auto rta = reinterpret_cast<struct rtattr *>(ifi + 1);
+ len -= sizeof(*ifi);
+ for ( ; RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) {
+ int payloadLen = RTA_PAYLOAD(rta);
+ auto payloadPtr = reinterpret_cast<char *>(RTA_DATA(rta));
+
+ switch (rta->rta_type) {
+ case IFLA_ADDRESS: // link-level address
+ iface->hardwareAddress =
+ iface->makeHwAddress(payloadLen, reinterpret_cast<uchar *>(payloadPtr));
+ break;
+
+ case IFLA_IFNAME: // interface name
+ Q_ASSERT(payloadLen <= int(sizeof(req.ifr_name)));
+ memcpy(req.ifr_name, payloadPtr, payloadLen); // including terminating NUL
+ iface->name = QString::fromLatin1(payloadPtr, payloadLen - 1);
+ break;
+
+ case IFLA_MTU:
+ Q_ASSERT(payloadLen == sizeof(int));
+ iface->mtu = *reinterpret_cast<int *>(payloadPtr);
+ break;
+
+ case IFLA_OPERSTATE: // operational state
+ if (*payloadPtr != IF_OPER_UNKNOWN) {
+ // override the flag
+ iface->flags &= ~QNetworkInterface::IsUp;
+ if (*payloadPtr == IF_OPER_UP)
+ iface->flags |= QNetworkInterface::IsUp;
+ }
+ break;
+ }
+ }
+
+ if (Q_UNLIKELY(iface->name.isEmpty())) {
+ qWarning("QNetworkInterface: found interface %d with no name", iface->index);
+ delete iface;
+ } else {
+ iface->type = probeIfType(sock, &req, ifi->ifi_type);
+ result.append(iface);
+ }
+ });
+ return result;
+}
+
+static void getAddresses(int sock, char *buf, QList<QNetworkInterfacePrivate *> &result)
+{
+ // request all addresses
+ struct {
+ struct nlmsghdr req;
+ struct ifaddrmsg ifa;
+ } ifa_req;
+ memset(&ifa_req, 0, sizeof(ifa_req));
+
+ ifa_req.req.nlmsg_len = sizeof(ifa_req);
+ ifa_req.req.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+ ifa_req.req.nlmsg_type = RTM_GETADDR;
+ ifa_req.req.nlmsg_seq = 1;
+
+ // parse the addresses
+ processNetlinkRequest(sock, &ifa_req.req, buf, BufferSize, [&](ifaddrmsg *ifa, size_t len) {
+ if (Q_UNLIKELY(ifa->ifa_family != AF_INET && ifa->ifa_family != AF_INET6)) {
+ // unknown address types
+ return;
+ }
+
+ // find the interface this is relevant to
+ QNetworkInterfacePrivate *iface = nullptr;
+ for (auto candidate : qAsConst(result)) {
+ if (candidate->index != int(ifa->ifa_index))
+ continue;
+ iface = candidate;
+ break;
+ }
+
+ if (Q_UNLIKELY(!iface)) {
+ qWarning("QNetworkInterface/AF_NETLINK: found unknown interface with index %d", ifa->ifa_index);
+ return;
+ }
+
+ QNetworkAddressEntry entry;
+ quint32 flags = ifa->ifa_flags; // may be overwritten by IFA_FLAGS
+
+ auto makeAddress = [=](uchar *ptr, int len) {
+ QHostAddress addr;
+ if (ifa->ifa_family == AF_INET) {
+ Q_ASSERT(len == 4);
+ addr.setAddress(qFromBigEndian<quint32>(ptr));
+ } else {
+ Q_ASSERT(len == 16);
+ addr.setAddress(ptr);
+
+ // do we need a scope ID?
+ if (addr.isLinkLocal())
+ addr.setScopeId(iface->name);
+ }
+ return addr;
+ };
+
+ // read attributes
+ auto rta = reinterpret_cast<struct rtattr *>(ifa + 1);
+ len -= sizeof(*ifa);
+ for ( ; RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) {
+ int payloadLen = RTA_PAYLOAD(rta);
+ auto payloadPtr = reinterpret_cast<uchar *>(RTA_DATA(rta));
+
+ switch (rta->rta_type) {
+ case IFA_ADDRESS: // address
+ entry.setIp(makeAddress(payloadPtr, payloadLen));
+ break;
+
+ case IFA_BROADCAST:
+ Q_ASSERT(ifa->ifa_family == AF_INET);
+ entry.setBroadcast(makeAddress(payloadPtr, payloadLen));
+ break;
+
+ case IFA_CACHEINFO:
+ if (size_t(payloadLen) >= sizeof(ifa_cacheinfo)) {
+ auto cacheinfo = reinterpret_cast<ifa_cacheinfo *>(payloadPtr);
+ auto toDeadline = [](quint32 lifetime) -> QDeadlineTimer {
+ if (lifetime == quint32(-1))
+ return QDeadlineTimer::Forever;
+ return QDeadlineTimer(lifetime * 1000);
+ };
+ entry.setAddressLifetime(toDeadline(cacheinfo->ifa_prefered), toDeadline(cacheinfo->ifa_valid));
+ }
+ break;
+
+ case IFA_FLAGS:
+ Q_ASSERT(payloadLen == 4);
+ flags = qFromUnaligned<quint32>(payloadPtr);
+ break;
+ }
+ }
+
+ // now handle flags
+ QNetworkInterfacePrivate::calculateDnsEligibility(&entry,
+ flags & IFA_F_TEMPORARY,
+ flags & IFA_F_DEPRECATED);
+
+
+ if (!entry.ip().isNull()) {
+ entry.setPrefixLength(ifa->ifa_prefixlen);
+ iface->addressEntries.append(entry);
+ }
+ });
+}
+
+QList<QNetworkInterfacePrivate *> QNetworkInterfaceManager::scan()
+{
+ // open netlink socket
+ QList<QNetworkInterfacePrivate *> result;
+ NetlinkSocket sock(BufferSize);
+ if (Q_UNLIKELY(sock == -1))
+ return result;
+
+ QByteArray buffer(BufferSize, Qt::Uninitialized);
+ char *buf = buffer.data();
+
+ result = getInterfaces(sock, buf);
+ getAddresses(sock, buf, result);
+
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/kernel/qnetworkinterface_p.h b/src/network/kernel/qnetworkinterface_p.h
index 51901eeda8..87a46b75fa 100644
--- a/src/network/kernel/qnetworkinterface_p.h
+++ b/src/network/kernel/qnetworkinterface_p.h
@@ -52,7 +52,9 @@
//
#include <QtNetwork/private/qtnetworkglobal_p.h>
+#include <QtNetwork/qnetworkinterface.h>
#include <QtCore/qatomic.h>
+#include <QtCore/qdeadlinetimer.h>
#include <QtCore/qlist.h>
#include <QtCore/qreadwritelock.h>
#include <QtCore/qstring.h>
@@ -69,7 +71,12 @@ class QNetworkAddressEntryPrivate
public:
QHostAddress address;
QHostAddress broadcast;
+ QDeadlineTimer preferredLifetime = QDeadlineTimer::Forever;
+ QDeadlineTimer validityLifetime = QDeadlineTimer::Forever;
+
QNetmask netmask;
+ bool lifetimeKnown = false;
+ QNetworkAddressEntry::DnsEligibilityStatus dnsEligibility = QNetworkAddressEntry::DnsEligibilityUnknown;
};
class QNetworkInterfacePrivate: public QSharedData
@@ -81,7 +88,9 @@ public:
{ }
int index; // interface index, if know
+ int mtu = 0;
QNetworkInterface::InterfaceFlags flags;
+ QNetworkInterface::InterfaceType type = QNetworkInterface::Unknown;
QString name;
QString friendlyName;
@@ -90,6 +99,20 @@ public:
QList<QNetworkAddressEntry> addressEntries;
static QString makeHwAddress(int len, uchar *data);
+ static void calculateDnsEligibility(QNetworkAddressEntry *entry, bool isTemporary,
+ bool isDeprecated)
+ {
+ // this implements an algorithm that yields the same results as Windows
+ // produces, for the same input (as far as I can test)
+ if (isTemporary || isDeprecated)
+ entry->setDnsEligibility(QNetworkAddressEntry::DnsIneligible);
+
+ AddressClassification cl = QHostAddressPrivate::classify(entry->ip());
+ if (cl == LoopbackAddress || cl == LinkLocalAddress)
+ entry->setDnsEligibility(QNetworkAddressEntry::DnsIneligible);
+ else
+ entry->setDnsEligibility(QNetworkAddressEntry::DnsEligible);
+ }
private:
// disallow copying -- avoid detaching
diff --git a/src/network/kernel/qnetworkinterface_uikit_p.h b/src/network/kernel/qnetworkinterface_uikit_p.h
new file mode 100644
index 0000000000..c32bc4446c
--- /dev/null
+++ b/src/network/kernel/qnetworkinterface_uikit_p.h
@@ -0,0 +1,241 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNETWORKINTERFACE_UIKIT_P_H
+#define QNETWORKINTERFACE_UIKIT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+// Platform SDK for iOS, tvOS and watchOS is missing those headers:
+// net/if_media.h, netinet/in_var.h, netinet6/in6_var.h This header is
+// a workaround, it provides missing macros and structs.
+
+// <net/if_media.h>:
+
+/*
+ * Ethernet
+ */
+#define IFM_ETHER 0x00000020
+/*
+ * FDDI
+ */
+#define IFM_FDDI 0x00000060
+/*
+ * IEEE 802.11 Wireless
+ */
+#define IFM_IEEE80211 0x00000080
+/*
+ * Masks
+ */
+#define IFM_NMASK 0x000000e0 /* Network type */
+/*
+ * Macros to extract various bits of information from the media word.
+ */
+#define IFM_TYPE(x) ((x) & IFM_NMASK)
+
+// <netinet6/in6_var.h>:
+
+struct in6_addrlifetime {
+ time_t ia6t_expire; /* valid lifetime expiration time */
+ time_t ia6t_preferred; /* preferred lifetime expiration time */
+ u_int32_t ia6t_vltime; /* valid lifetime */
+ u_int32_t ia6t_pltime; /* prefix lifetime */
+};
+
+/*
+ * IPv6 interface statistics, as defined in RFC2465 Ipv6IfStatsEntry (p12).
+ */
+struct in6_ifstat {
+ u_quad_t ifs6_in_receive; /* # of total input datagram */
+ u_quad_t ifs6_in_hdrerr; /* # of datagrams with invalid hdr */
+ u_quad_t ifs6_in_toobig; /* # of datagrams exceeded MTU */
+ u_quad_t ifs6_in_noroute; /* # of datagrams with no route */
+ u_quad_t ifs6_in_addrerr; /* # of datagrams with invalid dst */
+ u_quad_t ifs6_in_protounknown; /* # of datagrams with unknown proto */
+ /* NOTE: increment on final dst if */
+ u_quad_t ifs6_in_truncated; /* # of truncated datagrams */
+ u_quad_t ifs6_in_discard; /* # of discarded datagrams */
+ /* NOTE: fragment timeout is not here */
+ u_quad_t ifs6_in_deliver; /* # of datagrams delivered to ULP */
+ /* NOTE: increment on final dst if */
+ u_quad_t ifs6_out_forward; /* # of datagrams forwarded */
+ /* NOTE: increment on outgoing if */
+ u_quad_t ifs6_out_request; /* # of outgoing datagrams from ULP */
+ /* NOTE: does not include forwrads */
+ u_quad_t ifs6_out_discard; /* # of discarded datagrams */
+ u_quad_t ifs6_out_fragok; /* # of datagrams fragmented */
+ u_quad_t ifs6_out_fragfail; /* # of datagrams failed on fragment */
+ u_quad_t ifs6_out_fragcreat; /* # of fragment datagrams */
+ /* NOTE: this is # after fragment */
+ u_quad_t ifs6_reass_reqd; /* # of incoming fragmented packets */
+ /* NOTE: increment on final dst if */
+ u_quad_t ifs6_reass_ok; /* # of reassembled packets */
+ /* NOTE: this is # after reass */
+ /* NOTE: increment on final dst if */
+ u_quad_t ifs6_atmfrag_rcvd; /* # of atomic fragments received */
+ u_quad_t ifs6_reass_fail; /* # of reass failures */
+ /* NOTE: may not be packet count */
+ /* NOTE: increment on final dst if */
+ u_quad_t ifs6_in_mcast; /* # of inbound multicast datagrams */
+ u_quad_t ifs6_out_mcast; /* # of outbound multicast datagrams */
+
+ u_quad_t ifs6_cantfoward_icmp6; /* # of ICMPv6 packets received for unreachable dest */
+ u_quad_t ifs6_addr_expiry_cnt; /* # of address expiry events (excluding privacy addresses) */
+ u_quad_t ifs6_pfx_expiry_cnt; /* # of prefix expiry events */
+ u_quad_t ifs6_defrtr_expiry_cnt; /* # of default router expiry events */
+};
+
+/*
+ * ICMPv6 interface statistics, as defined in RFC2466 Ipv6IfIcmpEntry.
+ * XXX: I'm not sure if this file is the right place for this structure...
+ */
+struct icmp6_ifstat {
+ /*
+ * Input statistics
+ */
+ /* ipv6IfIcmpInMsgs, total # of input messages */
+ u_quad_t ifs6_in_msg;
+ /* ipv6IfIcmpInErrors, # of input error messages */
+ u_quad_t ifs6_in_error;
+ /* ipv6IfIcmpInDestUnreachs, # of input dest unreach errors */
+ u_quad_t ifs6_in_dstunreach;
+ /* ipv6IfIcmpInAdminProhibs, # of input admin. prohibited errs */
+ u_quad_t ifs6_in_adminprohib;
+ /* ipv6IfIcmpInTimeExcds, # of input time exceeded errors */
+ u_quad_t ifs6_in_timeexceed;
+ /* ipv6IfIcmpInParmProblems, # of input parameter problem errors */
+ u_quad_t ifs6_in_paramprob;
+ /* ipv6IfIcmpInPktTooBigs, # of input packet too big errors */
+ u_quad_t ifs6_in_pkttoobig;
+ /* ipv6IfIcmpInEchos, # of input echo requests */
+ u_quad_t ifs6_in_echo;
+ /* ipv6IfIcmpInEchoReplies, # of input echo replies */
+ u_quad_t ifs6_in_echoreply;
+ /* ipv6IfIcmpInRouterSolicits, # of input router solicitations */
+ u_quad_t ifs6_in_routersolicit;
+ /* ipv6IfIcmpInRouterAdvertisements, # of input router advertisements */
+ u_quad_t ifs6_in_routeradvert;
+ /* ipv6IfIcmpInNeighborSolicits, # of input neighbor solicitations */
+ u_quad_t ifs6_in_neighborsolicit;
+ /* ipv6IfIcmpInNeighborAdvertisements, # of input neighbor advs. */
+ u_quad_t ifs6_in_neighboradvert;
+ /* ipv6IfIcmpInRedirects, # of input redirects */
+ u_quad_t ifs6_in_redirect;
+ /* ipv6IfIcmpInGroupMembQueries, # of input MLD queries */
+ u_quad_t ifs6_in_mldquery;
+ /* ipv6IfIcmpInGroupMembResponses, # of input MLD reports */
+ u_quad_t ifs6_in_mldreport;
+ /* ipv6IfIcmpInGroupMembReductions, # of input MLD done */
+ u_quad_t ifs6_in_mlddone;
+
+ /*
+ * Output statistics. We should solve unresolved routing problem...
+ */
+ /* ipv6IfIcmpOutMsgs, total # of output messages */
+ u_quad_t ifs6_out_msg;
+ /* ipv6IfIcmpOutErrors, # of output error messages */
+ u_quad_t ifs6_out_error;
+ /* ipv6IfIcmpOutDestUnreachs, # of output dest unreach errors */
+ u_quad_t ifs6_out_dstunreach;
+ /* ipv6IfIcmpOutAdminProhibs, # of output admin. prohibited errs */
+ u_quad_t ifs6_out_adminprohib;
+ /* ipv6IfIcmpOutTimeExcds, # of output time exceeded errors */
+ u_quad_t ifs6_out_timeexceed;
+ /* ipv6IfIcmpOutParmProblems, # of output parameter problem errors */
+ u_quad_t ifs6_out_paramprob;
+ /* ipv6IfIcmpOutPktTooBigs, # of output packet too big errors */
+ u_quad_t ifs6_out_pkttoobig;
+ /* ipv6IfIcmpOutEchos, # of output echo requests */
+ u_quad_t ifs6_out_echo;
+ /* ipv6IfIcmpOutEchoReplies, # of output echo replies */
+ u_quad_t ifs6_out_echoreply;
+ /* ipv6IfIcmpOutRouterSolicits, # of output router solicitations */
+ u_quad_t ifs6_out_routersolicit;
+ /* ipv6IfIcmpOutRouterAdvertisements, # of output router advs. */
+ u_quad_t ifs6_out_routeradvert;
+ /* ipv6IfIcmpOutNeighborSolicits, # of output neighbor solicitations */
+ u_quad_t ifs6_out_neighborsolicit;
+ /* ipv6IfIcmpOutNeighborAdvertisements, # of output neighbor advs. */
+ u_quad_t ifs6_out_neighboradvert;
+ /* ipv6IfIcmpOutRedirects, # of output redirects */
+ u_quad_t ifs6_out_redirect;
+ /* ipv6IfIcmpOutGroupMembQueries, # of output MLD queries */
+ u_quad_t ifs6_out_mldquery;
+ /* ipv6IfIcmpOutGroupMembResponses, # of output MLD reports */
+ u_quad_t ifs6_out_mldreport;
+ /* ipv6IfIcmpOutGroupMembReductions, # of output MLD done */
+ u_quad_t ifs6_out_mlddone;
+};
+
+#define SCOPE6_ID_MAX 16
+
+struct in6_ifreq {
+ char ifr_name[IFNAMSIZ];
+ union {
+ struct sockaddr_in6 ifru_addr;
+ struct sockaddr_in6 ifru_dstaddr;
+ int ifru_flags;
+ int ifru_flags6;
+ int ifru_metric;
+ int ifru_intval;
+ caddr_t ifru_data;
+ struct in6_addrlifetime ifru_lifetime;
+ struct in6_ifstat ifru_stat;
+ struct icmp6_ifstat ifru_icmp6stat;
+ u_int32_t ifru_scope_id[SCOPE6_ID_MAX];
+ } ifr_ifru;
+};
+
+#define IN6_IFF_TEMPORARY 0x0080 /* temporary (anonymous) address. */
+#define IN6_IFF_DEPRECATED 0x0010 /* deprecated address */
+
+#define SIOCGIFAFLAG_IN6 _IOWR('i', 73, struct in6_ifreq)
+#define SIOCGIFALIFETIME_IN6 _IOWR('i', 81, struct in6_ifreq)
+
+#endif // QNETWORKINTERFACE_UIKIT_P_H
+
diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp
index afa6b4296e..078b8dd143 100644
--- a/src/network/kernel/qnetworkinterface_unix.cpp
+++ b/src/network/kernel/qnetworkinterface_unix.cpp
@@ -41,30 +41,19 @@
#include "qset.h"
#include "qnetworkinterface.h"
#include "qnetworkinterface_p.h"
+#include "qnetworkinterface_unix_p.h"
#include "qalgorithms.h"
-#include "private/qnet_unix_p.h"
#ifndef QT_NO_NETWORKINTERFACE
-#define IP_MULTICAST // make AIX happy and define IFF_MULTICAST
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#ifdef Q_OS_SOLARIS
-# include <sys/sockio.h>
+#if defined(QT_NO_CLOCK_MONOTONIC)
+# include "qdatetime.h"
#endif
-#include <net/if.h>
#if defined(QT_LINUXBASE)
# define QT_NO_GETIFADDRS
#endif
-#ifdef Q_OS_HAIKU
-# include <sys/sockio.h>
-# define IFF_RUNNING 0x0001
-#endif
-
#ifndef QT_NO_GETIFADDRS
# include <ifaddrs.h>
#endif
@@ -103,23 +92,6 @@ static QHostAddress addressFromSockaddr(sockaddr *sa, int ifindex = 0, const QSt
}
-static QNetworkInterface::InterfaceFlags convertFlags(uint rawFlags)
-{
- QNetworkInterface::InterfaceFlags flags = 0;
- flags |= (rawFlags & IFF_UP) ? QNetworkInterface::IsUp : QNetworkInterface::InterfaceFlag(0);
- flags |= (rawFlags & IFF_RUNNING) ? QNetworkInterface::IsRunning : QNetworkInterface::InterfaceFlag(0);
- flags |= (rawFlags & IFF_BROADCAST) ? QNetworkInterface::CanBroadcast : QNetworkInterface::InterfaceFlag(0);
- flags |= (rawFlags & IFF_LOOPBACK) ? QNetworkInterface::IsLoopBack : QNetworkInterface::InterfaceFlag(0);
-#ifdef IFF_POINTOPOINT //cygwin doesn't define IFF_POINTOPOINT
- flags |= (rawFlags & IFF_POINTOPOINT) ? QNetworkInterface::IsPointToPoint : QNetworkInterface::InterfaceFlag(0);
-#endif
-
-#ifdef IFF_MULTICAST
- flags |= (rawFlags & IFF_MULTICAST) ? QNetworkInterface::CanMulticast : QNetworkInterface::InterfaceFlag(0);
-#endif
- return flags;
-}
-
uint QNetworkInterfaceManager::interfaceIndexFromName(const QString &name)
{
#ifndef QT_NO_IPV6IFNAME
@@ -167,6 +139,15 @@ QString QNetworkInterfaceManager::interfaceNameFromIndex(uint index)
return QString::number(uint(index));
}
+static int getMtu(int socket, struct ifreq *req)
+{
+#ifdef SIOCGIFMTU
+ if (qt_safe_ioctl(socket, SIOCGIFMTU, req) == 0)
+ return req->ifr_mtu;
+#endif
+ return 0;
+}
+
#ifdef QT_NO_GETIFADDRS
// getifaddrs not available
@@ -306,6 +287,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
if (qt_safe_ioctl(socket, SIOCGIFFLAGS, &req) >= 0) {
iface->flags = convertFlags(req.ifr_flags);
}
+ iface->mtu = getMtu(socket, &req);
#ifdef SIOCGIFHWADDR
// Get the HW address
@@ -413,14 +395,92 @@ static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)
return interfaces;
}
+static void getAddressExtraInfo(QNetworkAddressEntry *entry, struct sockaddr *sa, const char *ifname)
+{
+ Q_UNUSED(entry);
+ Q_UNUSED(sa);
+ Q_UNUSED(ifname)
+}
+
# elif defined(Q_OS_BSD4)
QT_BEGIN_INCLUDE_NAMESPACE
# include <net/if_dl.h>
+# include <net/if_types.h>
+#if defined(QT_PLATFORM_UIKIT)
+# include "qnetworkinterface_uikit_p.h"
+#else
+# include <net/if_media.h>
+# include <netinet/in_var.h>
+#endif // QT_PLATFORM_UIKIT
QT_END_INCLUDE_NAMESPACE
+static int openSocket(int &socket)
+{
+ if (socket == -1)
+ socket = qt_safe_socket(AF_INET, SOCK_DGRAM, 0);
+ return socket;
+}
+
+static QNetworkInterface::InterfaceType probeIfType(int socket, int iftype, struct ifmediareq *req)
+{
+ // Determine the interface type.
+
+ // On Darwin, these are #defines, but on FreeBSD they're just an
+ // enum, so we can't #ifdef them. Use the authoritative list from
+ // https://www.iana.org/assignments/smi-numbers/smi-numbers.xhtml#smi-numbers-5
+ switch (iftype) {
+ case IFT_PPP:
+ return QNetworkInterface::Ppp;
+
+ case IFT_LOOP:
+ return QNetworkInterface::Loopback;
+
+ case IFT_SLIP:
+ return QNetworkInterface::Slip;
+
+ case 0x47: // IFT_IEEE80211
+ return QNetworkInterface::Ieee80211;
+
+ case IFT_IEEE1394:
+ return QNetworkInterface::Ieee1394;
+
+ case IFT_GIF:
+ case IFT_STF:
+ return QNetworkInterface::Virtual;
+ }
+
+ // For the remainder (including Ethernet), let's try SIOGIFMEDIA
+ req->ifm_count = 0;
+ if (qt_safe_ioctl(socket, SIOCGIFMEDIA, req) == 0) {
+ // see https://man.openbsd.org/ifmedia.4
+
+ switch (IFM_TYPE(req->ifm_current)) {
+ case IFM_ETHER:
+ return QNetworkInterface::Ethernet;
+
+ case IFM_FDDI:
+ return QNetworkInterface::Fddi;
+
+ case IFM_IEEE80211:
+ return QNetworkInterface::Ieee80211;
+ }
+ }
+
+ return QNetworkInterface::Unknown;
+}
+
static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)
{
QList<QNetworkInterfacePrivate *> interfaces;
+ union {
+ struct ifmediareq mediareq;
+ struct ifreq req;
+ };
+ int socket = -1;
+
+ // ensure both structs start with the name field, of size IFNAMESIZ
+ Q_STATIC_ASSERT(sizeof(mediareq.ifm_name) == sizeof(req.ifr_name));
+ Q_ASSERT(&mediareq.ifm_name == &req.ifr_name);
// on NetBSD we use AF_LINK and sockaddr_dl
// scan the list for that family
@@ -434,11 +494,68 @@ static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)
iface->name = QString::fromLatin1(ptr->ifa_name);
iface->flags = convertFlags(ptr->ifa_flags);
iface->hardwareAddress = iface->makeHwAddress(sdl->sdl_alen, (uchar*)LLADDR(sdl));
+
+ strlcpy(mediareq.ifm_name, ptr->ifa_name, sizeof(mediareq.ifm_name));
+ iface->type = probeIfType(openSocket(socket), sdl->sdl_type, &mediareq);
+ iface->mtu = getMtu(socket, &req);
}
+ if (socket != -1)
+ qt_safe_close(socket);
return interfaces;
}
+static void getAddressExtraInfo(QNetworkAddressEntry *entry, struct sockaddr *sa, const char *ifname)
+{
+ // get IPv6 address lifetimes
+ if (sa->sa_family != AF_INET6)
+ return;
+
+ struct in6_ifreq ifr;
+
+ int s6 = qt_safe_socket(AF_INET6, SOCK_DGRAM, 0);
+ if (Q_UNLIKELY(s6 < 0)) {
+ qErrnoWarning("QNetworkInterface: could not create IPv6 socket");
+ return;
+ }
+
+ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+
+ // get flags
+ ifr.ifr_addr = *reinterpret_cast<struct sockaddr_in6 *>(sa);
+ if (qt_safe_ioctl(s6, SIOCGIFAFLAG_IN6, &ifr) < 0) {
+ qt_safe_close(s6);
+ return;
+ }
+ int flags = ifr.ifr_ifru.ifru_flags6;
+ QNetworkInterfacePrivate::calculateDnsEligibility(entry,
+ flags & IN6_IFF_TEMPORARY,
+ flags & IN6_IFF_DEPRECATED);
+
+ // get lifetimes
+ ifr.ifr_addr = *reinterpret_cast<struct sockaddr_in6 *>(sa);
+ if (qt_safe_ioctl(s6, SIOCGIFALIFETIME_IN6, &ifr) < 0) {
+ qt_safe_close(s6);
+ return;
+ }
+ qt_safe_close(s6);
+
+ auto toDeadline = [](time_t when) {
+ QDeadlineTimer deadline = QDeadlineTimer::Forever;
+ if (when) {
+#if defined(QT_NO_CLOCK_MONOTONIC)
+ // no monotonic clock
+ deadline.setPreciseRemainingTime(when - QDateTime::currentSecsSinceEpoch());
+#else
+ deadline.setPreciseDeadline(when);
+#endif
+ }
+ return deadline;
+ };
+ entry->setAddressLifetime(toDeadline(ifr.ifr_ifru.ifru_lifetime.ia6t_preferred),
+ toDeadline(ifr.ifr_ifru.ifru_lifetime.ia6t_expire));
+}
+
# else // Generic version
static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)
@@ -470,9 +587,14 @@ static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)
return interfaces;
}
+static void getAddressExtraInfo(QNetworkAddressEntry *entry, struct sockaddr *sa, const char *ifname)
+{
+ Q_UNUSED(entry);
+ Q_UNUSED(sa);
+ Q_UNUSED(ifname)
+}
# endif
-
static QList<QNetworkInterfacePrivate *> interfaceListing()
{
QList<QNetworkInterfacePrivate *> interfaces;
@@ -521,6 +643,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
entry.setNetmask(addressFromSockaddr(ptr->ifa_netmask, iface->index, iface->name));
if (iface->flags & QNetworkInterface::CanBroadcast)
entry.setBroadcast(addressFromSockaddr(ptr->ifa_broadaddr, iface->index, iface->name));
+ getAddressExtraInfo(&entry, ptr->ifa_addr, name.latin1());
iface->addressEntries << entry;
}
diff --git a/src/network/kernel/qnetworkinterface_unix_p.h b/src/network/kernel/qnetworkinterface_unix_p.h
new file mode 100644
index 0000000000..c085194e3c
--- /dev/null
+++ b/src/network/kernel/qnetworkinterface_unix_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2017 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNETWORKINTERFACE_UNIX_P_H
+#define QNETWORKINTERFACE_UNIX_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qnetworkinterface_p.h"
+#include "private/qnet_unix_p.h"
+
+#ifndef QT_NO_NETWORKINTERFACE
+
+#define IP_MULTICAST // make AIX happy and define IFF_MULTICAST
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef Q_OS_SOLARIS
+# include <sys/sockio.h>
+#endif
+#ifdef Q_OS_HAIKU
+# include <sys/sockio.h>
+# define IFF_RUNNING 0x0001
+#endif
+#if QT_CONFIG(linux_netlink)
+// Same as net/if.h but contains other things we need in
+// qnetworkinterface_linux.cpp.
+# include <linux/if.h>
+#else
+# include <net/if.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+static QNetworkInterface::InterfaceFlags convertFlags(uint rawFlags)
+{
+ QNetworkInterface::InterfaceFlags flags = 0;
+ flags |= (rawFlags & IFF_UP) ? QNetworkInterface::IsUp : QNetworkInterface::InterfaceFlag(0);
+ flags |= (rawFlags & IFF_RUNNING) ? QNetworkInterface::IsRunning : QNetworkInterface::InterfaceFlag(0);
+ flags |= (rawFlags & IFF_BROADCAST) ? QNetworkInterface::CanBroadcast : QNetworkInterface::InterfaceFlag(0);
+ flags |= (rawFlags & IFF_LOOPBACK) ? QNetworkInterface::IsLoopBack : QNetworkInterface::InterfaceFlag(0);
+#ifdef IFF_POINTOPOINT //cygwin doesn't define IFF_POINTOPOINT
+ flags |= (rawFlags & IFF_POINTOPOINT) ? QNetworkInterface::IsPointToPoint : QNetworkInterface::InterfaceFlag(0);
+#endif
+
+#ifdef IFF_MULTICAST
+ flags |= (rawFlags & IFF_MULTICAST) ? QNetworkInterface::CanMulticast : QNetworkInterface::InterfaceFlag(0);
+#endif
+ return flags;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_NETWORKINTERFACE
+
+#endif // QNETWORKINTERFACE_UNIX_P_H
diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp
index 64c3fa6f83..150553f673 100644
--- a/src/network/kernel/qnetworkinterface_win.cpp
+++ b/src/network/kernel/qnetworkinterface_win.cpp
@@ -62,6 +62,10 @@
#include <qt_windows.h>
+// In case these aren't defined
+#define IF_TYPE_IEEE80216_WMAN 237
+#define IF_TYPE_IEEE802154 259
+
QT_BEGIN_NAMESPACE
static QHostAddress addressFromSockaddr(sockaddr *sa)
@@ -147,6 +151,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
else if (ptr->IfIndex != 0)
iface->index = ptr->IfIndex;
+ iface->mtu = qMin<qint64>(ptr->Mtu, INT_MAX);
iface->flags = QNetworkInterface::CanBroadcast;
if (ptr->OperStatus == IfOperStatusUp)
iface->flags |= QNetworkInterface::IsUp | QNetworkInterface::IsRunning;
@@ -155,6 +160,45 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
if (ptr->IfType == IF_TYPE_PPP)
iface->flags |= QNetworkInterface::IsPointToPoint;
+ switch (ptr->IfType) {
+ case IF_TYPE_ETHERNET_CSMACD:
+ iface->type = QNetworkInterface::Ethernet;
+ break;
+
+ case IF_TYPE_FDDI:
+ iface->type = QNetworkInterface::Fddi;
+ break;
+
+ case IF_TYPE_PPP:
+ iface->type = QNetworkInterface::Ppp;
+ break;
+
+ case IF_TYPE_SLIP:
+ iface->type = QNetworkInterface::Slip;
+ break;
+
+ case IF_TYPE_SOFTWARE_LOOPBACK:
+ iface->type = QNetworkInterface::Loopback;
+ iface->flags |= QNetworkInterface::IsLoopBack;
+ break;
+
+ case IF_TYPE_IEEE80211:
+ iface->type = QNetworkInterface::Ieee80211;
+ break;
+
+ case IF_TYPE_IEEE1394:
+ iface->type = QNetworkInterface::Ieee1394;
+ break;
+
+ case IF_TYPE_IEEE80216_WMAN:
+ iface->type = QNetworkInterface::Ieee80216;
+ break;
+
+ case IF_TYPE_IEEE802154:
+ iface->type = QNetworkInterface::Ieee802154;
+ break;
+ }
+
// use ConvertInterfaceLuidToNameW because that returns a friendlier name, though not
// as "friendly" as FriendlyName below
WCHAR buf[IF_MAX_STRING_SIZE + 1];
@@ -167,9 +211,6 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
if (ptr->PhysicalAddressLength)
iface->hardwareAddress = iface->makeHwAddress(ptr->PhysicalAddressLength,
ptr->PhysicalAddress);
- else
- // loopback if it has no address
- iface->flags |= QNetworkInterface::IsLoopBack;
// parse the IP (unicast) addresses
for (PIP_ADAPTER_UNICAST_ADDRESS addr = ptr->FirstUnicastAddress; addr; addr = addr->Next) {
@@ -182,6 +223,17 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
QNetworkAddressEntry entry;
entry.setIp(addressFromSockaddr(addr->Address.lpSockaddr));
entry.setPrefixLength(addr->OnLinkPrefixLength);
+
+ auto toDeadline = [](ULONG lifetime) -> QDeadlineTimer {
+ if (lifetime == 0xffffffffUL)
+ return QDeadlineTimer::Forever;
+ return QDeadlineTimer(lifetime * 1000);
+ };
+ entry.setAddressLifetime(toDeadline(addr->ValidLifetime), toDeadline(addr->PreferredLifetime));
+ entry.setDnsEligibility(addr->Flags & IP_ADAPTER_ADDRESS_DNS_ELIGIBLE ?
+ QNetworkAddressEntry::DnsEligible :
+ QNetworkAddressEntry::DnsIneligible);
+
iface->addressEntries << entry;
}
}
diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp
index 6b53b4b58e..3646a9526a 100644
--- a/src/network/kernel/qnetworkproxy.cpp
+++ b/src/network/kernel/qnetworkproxy.cpp
@@ -230,7 +230,11 @@
#if QT_CONFIG(socks5)
#include "private/qsocks5socketengine_p.h"
#endif
+
+#if QT_CONFIG(http)
#include "private/qhttpsocketengine_p.h"
+#endif
+
#include "qauthenticator.h"
#include "qdebug.h"
#include "qmutex.h"
@@ -256,7 +260,7 @@ public:
#if QT_CONFIG(socks5)
, socks5SocketEngineHandler(0)
#endif
-#ifndef QT_NO_HTTP
+#if QT_CONFIG(http)
, httpSocketEngineHandler(0)
#endif
#ifdef QT_USE_SYSTEM_PROXIES
@@ -268,7 +272,7 @@ public:
#if QT_CONFIG(socks5)
socks5SocketEngineHandler = new QSocks5SocketEngineHandler();
#endif
-#ifndef QT_NO_HTTP
+#if QT_CONFIG(http)
httpSocketEngineHandler = new QHttpSocketEngineHandler();
#endif
}
@@ -280,7 +284,7 @@ public:
#if QT_CONFIG(socks5)
delete socks5SocketEngineHandler;
#endif
-#ifndef QT_NO_HTTP
+#if QT_CONFIG(http)
delete httpSocketEngineHandler;
#endif
}
@@ -340,7 +344,7 @@ private:
#if QT_CONFIG(socks5)
QSocks5SocketEngineHandler *socks5SocketEngineHandler;
#endif
-#ifndef QT_NO_HTTP
+#if QT_CONFIG(http)
QHttpSocketEngineHandler *httpSocketEngineHandler;
#endif
bool useSystemProxies;
diff --git a/src/network/network.pro b/src/network/network.pro
index 98fbf82275..b8272d91d6 100644
--- a/src/network/network.pro
+++ b/src/network/network.pro
@@ -24,8 +24,6 @@ QMAKE_LIBS += $$QMAKE_LIBS_NETWORK
qtConfig(bearermanagement) {
ANDROID_BUNDLED_JAR_DEPENDENCIES = \
- jar/QtAndroidBearer-bundled.jar
- ANDROID_JAR_DEPENDENCIES = \
jar/QtAndroidBearer.jar
ANDROID_LIB_DEPENDENCIES = \
plugins/bearer/libqandroidbearer.so
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 7284b124c5..98baa0c047 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -387,6 +387,11 @@
(see \l{QAbstractSocket::}{setReadBufferSize()}).
This enum value has been introduced in Qt 5.3.
+ \value PathMtuSocketOption Retrieves the Path Maximum Transmission Unit
+ (PMTU) value currently known by the IP stack, if any. Some IP stacks also
+ allow setting the MTU for transmission.
+ This enum value was introduced in Qt 5.11.
+
Possible values for \e{TypeOfServiceOption} are:
\table
@@ -1354,15 +1359,29 @@ void QAbstractSocketPrivate::fetchConnectionParameters()
}
state = QAbstractSocket::ConnectedState;
- emit q->stateChanged(state);
- emit q->connected();
-
#if defined(QABSTRACTSOCKET_DEBUG)
qDebug("QAbstractSocketPrivate::fetchConnectionParameters() connection to %s:%i established",
host.toString().toLatin1().constData(), port);
#endif
+ emit q->stateChanged(state);
+ emit q->connected();
}
+/*! \internal
+*/
+qint64 QAbstractSocketPrivate::skip(qint64 maxSize)
+{
+ // if we're not connected, return -1 indicating EOF
+ if (!socketEngine || !socketEngine->isValid() || state != QAbstractSocket::ConnectedState)
+ return -1;
+
+ // Caller, QIODevice::skip(), has ensured buffer is empty. So, wait
+ // for more data in buffered mode.
+ if (isBuffered)
+ return 0;
+
+ return QIODevicePrivate::skip(maxSize);
+}
void QAbstractSocketPrivate::pauseSocketNotifiers(QAbstractSocket *socket)
{
@@ -2009,6 +2028,10 @@ void QAbstractSocket::setSocketOption(QAbstractSocket::SocketOption option, cons
case ReceiveBufferSizeSocketOption:
d_func()->socketEngine->setOption(QAbstractSocketEngine::ReceiveBufferSocketOption, value.toInt());
break;
+
+ case PathMtuSocketOption:
+ d_func()->socketEngine->setOption(QAbstractSocketEngine::PathMtuInformation, value.toInt());
+ break;
}
}
@@ -2051,6 +2074,10 @@ QVariant QAbstractSocket::socketOption(QAbstractSocket::SocketOption option)
case ReceiveBufferSizeSocketOption:
ret = d_func()->socketEngine->option(QAbstractSocketEngine::ReceiveBufferSocketOption);
break;
+
+ case PathMtuSocketOption:
+ ret = d_func()->socketEngine->option(QAbstractSocketEngine::PathMtuInformation);
+ break;
}
if (ret == -1)
return QVariant();
diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h
index 875609aa28..6d5e57ac52 100644
--- a/src/network/socket/qabstractsocket.h
+++ b/src/network/socket/qabstractsocket.h
@@ -120,7 +120,8 @@ public:
MulticastLoopbackOption, // IP_MULTICAST_LOOPBACK
TypeOfServiceOption, //IP_TOS
SendBufferSizeSocketOption, //SO_SNDBUF
- ReceiveBufferSizeSocketOption //SO_RCVBUF
+ ReceiveBufferSizeSocketOption, //SO_RCVBUF
+ PathMtuSocketOption // IP_MTU
};
Q_ENUM(SocketOption)
enum BindFlag {
@@ -154,10 +155,10 @@ public:
bool isValid() const;
- qint64 bytesAvailable() const Q_DECL_OVERRIDE;
- qint64 bytesToWrite() const Q_DECL_OVERRIDE;
+ qint64 bytesAvailable() const override;
+ qint64 bytesToWrite() const override;
- bool canReadLine() const Q_DECL_OVERRIDE; // ### Qt6: remove me
+ bool canReadLine() const override; // ### Qt6: remove me
quint16 localPort() const;
QHostAddress localAddress() const;
@@ -182,15 +183,15 @@ public:
SocketError error() const;
// from QIODevice
- void close() Q_DECL_OVERRIDE;
- bool isSequential() const Q_DECL_OVERRIDE;
- bool atEnd() const Q_DECL_OVERRIDE; // ### Qt6: remove me
+ void close() override;
+ bool isSequential() const override;
+ bool atEnd() const override; // ### Qt6: remove me
bool flush();
// for synchronous access
virtual bool waitForConnected(int msecs = 30000);
- bool waitForReadyRead(int msecs = 30000) Q_DECL_OVERRIDE;
- bool waitForBytesWritten(int msecs = 30000) Q_DECL_OVERRIDE;
+ bool waitForReadyRead(int msecs = 30000) override;
+ bool waitForBytesWritten(int msecs = 30000) override;
virtual bool waitForDisconnected(int msecs = 30000);
#ifndef QT_NO_NETWORKPROXY
@@ -209,9 +210,9 @@ Q_SIGNALS:
#endif
protected:
- qint64 readData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
- qint64 readLineData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
- qint64 writeData(const char *data, qint64 len) Q_DECL_OVERRIDE;
+ qint64 readData(char *data, qint64 maxlen) override;
+ qint64 readLineData(char *data, qint64 maxlen) override;
+ qint64 writeData(const char *data, qint64 len) override;
void setSocketState(SocketState state);
void setSocketError(SocketError socketError);
@@ -221,7 +222,7 @@ protected:
void setPeerAddress(const QHostAddress &address);
void setPeerName(const QString &name);
- QAbstractSocket(SocketType socketType, QAbstractSocketPrivate &dd, QObject *parent = Q_NULLPTR);
+ QAbstractSocket(SocketType socketType, QAbstractSocketPrivate &dd, QObject *parent = nullptr);
private:
Q_DECLARE_PRIVATE(QAbstractSocket)
diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h
index 5411133ea9..3d788319a8 100644
--- a/src/network/socket/qabstractsocket_p.h
+++ b/src/network/socket/qabstractsocket_p.h
@@ -71,6 +71,9 @@ public:
QAbstractSocketPrivate();
virtual ~QAbstractSocketPrivate();
+ // from QIODevicePrivate
+ qint64 skip(qint64 maxSize) override;
+
// from QAbstractSocketEngineReceiver
inline void readNotification() override { canReadNotification(); }
inline void writeNotification() override { canWriteNotification(); }
diff --git a/src/network/socket/qabstractsocketengine_p.h b/src/network/socket/qabstractsocketengine_p.h
index 0cb519ce90..b15dd73c96 100644
--- a/src/network/socket/qabstractsocketengine_p.h
+++ b/src/network/socket/qabstractsocketengine_p.h
@@ -105,7 +105,8 @@ public:
TypeOfServiceOption,
ReceivePacketInformation,
ReceiveHopLimit,
- MaxStreamsSocketOption
+ MaxStreamsSocketOption,
+ PathMtuInformation
};
enum PacketHeaderOption {
diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp
index 899c02fba6..b543ea7981 100644
--- a/src/network/socket/qhttpsocketengine.cpp
+++ b/src/network/socket/qhttpsocketengine.cpp
@@ -46,7 +46,7 @@
#include "qelapsedtimer.h"
#include "qnetworkinterface.h"
-#if !defined(QT_NO_NETWORKPROXY) && !defined(QT_NO_HTTP)
+#if !defined(QT_NO_NETWORKPROXY)
#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -572,18 +572,13 @@ void QHttpSocketEngine::slotSocketReadNotification()
}
if (d->state == ReadResponseContent) {
- char dummybuffer[4096];
- while (d->pendingResponseData) {
- int read = d->socket->read(dummybuffer, qMin(sizeof(dummybuffer), (size_t)d->pendingResponseData));
- if (read == 0)
- return;
- if (read == -1) {
- d->socket->disconnectFromHost();
- emitWriteNotification();
- return;
- }
- d->pendingResponseData -= read;
+ qint64 skipped = d->socket->skip(d->pendingResponseData);
+ if (skipped == -1) {
+ d->socket->disconnectFromHost();
+ emitWriteNotification();
+ return;
}
+ d->pendingResponseData -= uint(skipped);
if (d->pendingResponseData > 0)
return;
if (d->reply->d_func()->statusCode == 407)
@@ -871,4 +866,4 @@ QAbstractSocketEngine *QHttpSocketEngineHandler::createSocketEngine(qintptr, QOb
QT_END_NAMESPACE
-#endif
+#endif // !QT_NO_NETWORKPROXY
diff --git a/src/network/socket/qhttpsocketengine_p.h b/src/network/socket/qhttpsocketengine_p.h
index 07815a7e51..cb7798694a 100644
--- a/src/network/socket/qhttpsocketengine_p.h
+++ b/src/network/socket/qhttpsocketengine_p.h
@@ -57,9 +57,11 @@
#include "qnetworkproxy.h"
#include "private/qauthenticator_p.h"
+QT_REQUIRE_CONFIG(http);
+
QT_BEGIN_NAMESPACE
-#if !defined(QT_NO_NETWORKPROXY) && !defined(QT_NO_HTTP)
+#if !defined(QT_NO_NETWORKPROXY)
class QTcpSocket;
class QHttpNetworkReply;
@@ -80,62 +82,62 @@ public:
QHttpSocketEngine(QObject *parent = 0);
~QHttpSocketEngine();
- bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) Q_DECL_OVERRIDE;
- bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState) Q_DECL_OVERRIDE;
+ bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) override;
+ bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState) override;
void setProxy(const QNetworkProxy &networkProxy);
- qintptr socketDescriptor() const Q_DECL_OVERRIDE;
+ qintptr socketDescriptor() const override;
- bool isValid() const Q_DECL_OVERRIDE;
+ bool isValid() const override;
bool connectInternal();
- bool connectToHost(const QHostAddress &address, quint16 port) Q_DECL_OVERRIDE;
- bool connectToHostByName(const QString &name, quint16 port) Q_DECL_OVERRIDE;
- bool bind(const QHostAddress &address, quint16 port) Q_DECL_OVERRIDE;
- bool listen() Q_DECL_OVERRIDE;
- int accept() Q_DECL_OVERRIDE;
- void close() Q_DECL_OVERRIDE;
+ bool connectToHost(const QHostAddress &address, quint16 port) override;
+ bool connectToHostByName(const QString &name, quint16 port) override;
+ bool bind(const QHostAddress &address, quint16 port) override;
+ bool listen() override;
+ int accept() override;
+ void close() override;
- qint64 bytesAvailable() const Q_DECL_OVERRIDE;
+ qint64 bytesAvailable() const override;
- qint64 read(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
- qint64 write(const char *data, qint64 len) Q_DECL_OVERRIDE;
+ qint64 read(char *data, qint64 maxlen) override;
+ qint64 write(const char *data, qint64 len) override;
#ifndef QT_NO_UDPSOCKET
#ifndef QT_NO_NETWORKINTERFACE
bool joinMulticastGroup(const QHostAddress &groupAddress,
- const QNetworkInterface &interface) Q_DECL_OVERRIDE;
+ const QNetworkInterface &interface) override;
bool leaveMulticastGroup(const QHostAddress &groupAddress,
- const QNetworkInterface &interface) Q_DECL_OVERRIDE;
- QNetworkInterface multicastInterface() const Q_DECL_OVERRIDE;
- bool setMulticastInterface(const QNetworkInterface &iface) Q_DECL_OVERRIDE;
+ const QNetworkInterface &interface) override;
+ QNetworkInterface multicastInterface() const override;
+ bool setMulticastInterface(const QNetworkInterface &iface) override;
#endif // QT_NO_NETWORKINTERFACE
- bool hasPendingDatagrams() const Q_DECL_OVERRIDE;
- qint64 pendingDatagramSize() const Q_DECL_OVERRIDE;
+ bool hasPendingDatagrams() const override;
+ qint64 pendingDatagramSize() const override;
#endif // QT_NO_UDPSOCKET
qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader *,
- PacketHeaderOptions) Q_DECL_OVERRIDE;
- qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) Q_DECL_OVERRIDE;
- qint64 bytesToWrite() const Q_DECL_OVERRIDE;
+ PacketHeaderOptions) override;
+ qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) override;
+ qint64 bytesToWrite() const override;
- int option(SocketOption option) const Q_DECL_OVERRIDE;
- bool setOption(SocketOption option, int value) Q_DECL_OVERRIDE;
+ int option(SocketOption option) const override;
+ bool setOption(SocketOption option, int value) override;
- bool waitForRead(int msecs = 30000, bool *timedOut = 0) Q_DECL_OVERRIDE;
- bool waitForWrite(int msecs = 30000, bool *timedOut = 0) Q_DECL_OVERRIDE;
+ bool waitForRead(int msecs = 30000, bool *timedOut = 0) override;
+ bool waitForWrite(int msecs = 30000, bool *timedOut = 0) override;
bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
bool checkRead, bool checkWrite,
- int msecs = 30000, bool *timedOut = 0) Q_DECL_OVERRIDE;
+ int msecs = 30000, bool *timedOut = 0) override;
- bool isReadNotificationEnabled() const Q_DECL_OVERRIDE;
- void setReadNotificationEnabled(bool enable) Q_DECL_OVERRIDE;
- bool isWriteNotificationEnabled() const Q_DECL_OVERRIDE;
- void setWriteNotificationEnabled(bool enable) Q_DECL_OVERRIDE;
- bool isExceptionNotificationEnabled() const Q_DECL_OVERRIDE;
- void setExceptionNotificationEnabled(bool enable) Q_DECL_OVERRIDE;
+ bool isReadNotificationEnabled() const override;
+ void setReadNotificationEnabled(bool enable) override;
+ bool isWriteNotificationEnabled() const override;
+ void setWriteNotificationEnabled(bool enable) override;
+ bool isExceptionNotificationEnabled() const override;
+ void setExceptionNotificationEnabled(bool enable) override;
public slots:
void slotSocketConnected();
@@ -190,8 +192,8 @@ class Q_AUTOTEST_EXPORT QHttpSocketEngineHandler : public QSocketEngineHandler
{
public:
virtual QAbstractSocketEngine *createSocketEngine(QAbstractSocket::SocketType socketType,
- const QNetworkProxy &, QObject *parent) Q_DECL_OVERRIDE;
- virtual QAbstractSocketEngine *createSocketEngine(qintptr socketDescripter, QObject *parent) Q_DECL_OVERRIDE;
+ const QNetworkProxy &, QObject *parent) override;
+ virtual QAbstractSocketEngine *createSocketEngine(qintptr socketDescripter, QObject *parent) override;
};
#endif
diff --git a/src/network/socket/qlocalserver.h b/src/network/socket/qlocalserver.h
index 454ac30c9b..211aa94d85 100644
--- a/src/network/socket/qlocalserver.h
+++ b/src/network/socket/qlocalserver.h
@@ -71,7 +71,7 @@ public:
Q_DECLARE_FLAGS(SocketOptions, SocketOption)
Q_FLAG(SocketOptions)
- explicit QLocalServer(QObject *parent = Q_NULLPTR);
+ explicit QLocalServer(QObject *parent = nullptr);
~QLocalServer();
void close();
@@ -87,7 +87,7 @@ public:
static bool removeServer(const QString &name);
QAbstractSocket::SocketError serverError() const;
void setMaxPendingConnections(int numConnections);
- bool waitForNewConnection(int msec = 0, bool *timedOut = Q_NULLPTR);
+ bool waitForNewConnection(int msec = 0, bool *timedOut = nullptr);
void setSocketOptions(SocketOptions options);
SocketOptions socketOptions() const;
diff --git a/src/network/socket/qlocalsocket.h b/src/network/socket/qlocalsocket.h
index 9905d3a86c..1876a6ac0d 100644
--- a/src/network/socket/qlocalsocket.h
+++ b/src/network/socket/qlocalsocket.h
@@ -79,7 +79,7 @@ public:
ClosingState = QAbstractSocket::ClosingState
};
- QLocalSocket(QObject *parent = Q_NULLPTR);
+ QLocalSocket(QObject *parent = nullptr);
~QLocalSocket();
void connectToServer(OpenMode openMode = ReadWrite);
@@ -91,12 +91,12 @@ public:
QString fullServerName() const;
void abort();
- virtual bool isSequential() const Q_DECL_OVERRIDE;
- virtual qint64 bytesAvailable() const Q_DECL_OVERRIDE;
- virtual qint64 bytesToWrite() const Q_DECL_OVERRIDE;
- virtual bool canReadLine() const Q_DECL_OVERRIDE;
- virtual bool open(OpenMode openMode = ReadWrite) Q_DECL_OVERRIDE;
- virtual void close() Q_DECL_OVERRIDE;
+ virtual bool isSequential() const override;
+ virtual qint64 bytesAvailable() const override;
+ virtual qint64 bytesToWrite() const override;
+ virtual bool canReadLine() const override;
+ virtual bool open(OpenMode openMode = ReadWrite) override;
+ virtual void close() override;
LocalSocketError error() const;
bool flush();
bool isValid() const;
@@ -109,10 +109,10 @@ public:
qintptr socketDescriptor() const;
LocalSocketState state() const;
- bool waitForBytesWritten(int msecs = 30000) Q_DECL_OVERRIDE;
+ bool waitForBytesWritten(int msecs = 30000) override;
bool waitForConnected(int msecs = 30000);
bool waitForDisconnected(int msecs = 30000);
- bool waitForReadyRead(int msecs = 30000) Q_DECL_OVERRIDE;
+ bool waitForReadyRead(int msecs = 30000) override;
Q_SIGNALS:
void connected();
@@ -121,8 +121,8 @@ Q_SIGNALS:
void stateChanged(QLocalSocket::LocalSocketState socketState);
protected:
- virtual qint64 readData(char*, qint64) Q_DECL_OVERRIDE;
- virtual qint64 writeData(const char*, qint64) Q_DECL_OVERRIDE;
+ virtual qint64 readData(char*, qint64) override;
+ virtual qint64 writeData(const char*, qint64) override;
private:
Q_DISABLE_COPY(QLocalSocket)
diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h
index eb59af5577..8b72da397f 100644
--- a/src/network/socket/qlocalsocket_p.h
+++ b/src/network/socket/qlocalsocket_p.h
@@ -120,6 +120,7 @@ public:
void init();
#if defined(QT_LOCALSOCKET_TCP)
+ qint64 skip(qint64 maxSize) override;
QLocalUnixSocket* tcpSocket;
bool ownsTcpSocket;
void setSocket(QLocalUnixSocket*);
@@ -139,6 +140,7 @@ public:
QWindowsPipeReader *pipeReader;
QLocalSocket::LocalSocketError error;
#else
+ qint64 skip(qint64 maxSize) override;
QLocalUnixSocket unixSocket;
QString generateErrorString(QLocalSocket::LocalSocketError, const QString &function) const;
void errorOccurred(QLocalSocket::LocalSocketError, const QString &function);
diff --git a/src/network/socket/qlocalsocket_tcp.cpp b/src/network/socket/qlocalsocket_tcp.cpp
index 379cdd096d..41e5b47627 100644
--- a/src/network/socket/qlocalsocket_tcp.cpp
+++ b/src/network/socket/qlocalsocket_tcp.cpp
@@ -83,6 +83,11 @@ void QLocalSocketPrivate::setSocket(QLocalUnixSocket* socket)
tcpSocket->setParent(q);
}
+qint64 QLocalSocketPrivate::skip(qint64 maxSize)
+{
+ return tcpSocket->skip(maxSize);
+}
+
void QLocalSocketPrivate::_q_error(QAbstractSocket::SocketError socketError)
{
Q_Q(QLocalSocket);
diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp
index c1d79e8137..d1df26d9f1 100644
--- a/src/network/socket/qlocalsocket_unix.cpp
+++ b/src/network/socket/qlocalsocket_unix.cpp
@@ -88,6 +88,11 @@ void QLocalSocketPrivate::init()
unixSocket.setParent(q);
}
+qint64 QLocalSocketPrivate::skip(qint64 maxSize)
+{
+ return unixSocket.skip(maxSize);
+}
+
void QLocalSocketPrivate::_q_error(QAbstractSocket::SocketError socketError)
{
Q_Q(QLocalSocket);
diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h
index d488ce150c..aa61b74823 100644
--- a/src/network/socket/qnativesocketengine_p.h
+++ b/src/network/socket/qnativesocketengine_p.h
@@ -128,43 +128,43 @@ public:
QNativeSocketEngine(QObject *parent = 0);
~QNativeSocketEngine();
- bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) Q_DECL_OVERRIDE;
- bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState) Q_DECL_OVERRIDE;
+ bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) override;
+ bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState) override;
- qintptr socketDescriptor() const Q_DECL_OVERRIDE;
+ qintptr socketDescriptor() const override;
- bool isValid() const Q_DECL_OVERRIDE;
+ bool isValid() const override;
- bool connectToHost(const QHostAddress &address, quint16 port) Q_DECL_OVERRIDE;
- bool connectToHostByName(const QString &name, quint16 port) Q_DECL_OVERRIDE;
- bool bind(const QHostAddress &address, quint16 port) Q_DECL_OVERRIDE;
- bool listen() Q_DECL_OVERRIDE;
- int accept() Q_DECL_OVERRIDE;
- void close() Q_DECL_OVERRIDE;
+ bool connectToHost(const QHostAddress &address, quint16 port) override;
+ bool connectToHostByName(const QString &name, quint16 port) override;
+ bool bind(const QHostAddress &address, quint16 port) override;
+ bool listen() override;
+ int accept() override;
+ void close() override;
- qint64 bytesAvailable() const Q_DECL_OVERRIDE;
+ qint64 bytesAvailable() const override;
- qint64 read(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
- qint64 write(const char *data, qint64 len) Q_DECL_OVERRIDE;
+ qint64 read(char *data, qint64 maxlen) override;
+ qint64 write(const char *data, qint64 len) override;
#ifndef QT_NO_UDPSOCKET
#ifndef QT_NO_NETWORKINTERFACE
bool joinMulticastGroup(const QHostAddress &groupAddress,
- const QNetworkInterface &iface) Q_DECL_OVERRIDE;
+ const QNetworkInterface &iface) override;
bool leaveMulticastGroup(const QHostAddress &groupAddress,
- const QNetworkInterface &iface) Q_DECL_OVERRIDE;
- QNetworkInterface multicastInterface() const Q_DECL_OVERRIDE;
- bool setMulticastInterface(const QNetworkInterface &iface) Q_DECL_OVERRIDE;
+ const QNetworkInterface &iface) override;
+ QNetworkInterface multicastInterface() const override;
+ bool setMulticastInterface(const QNetworkInterface &iface) override;
#endif
- bool hasPendingDatagrams() const Q_DECL_OVERRIDE;
- qint64 pendingDatagramSize() const Q_DECL_OVERRIDE;
+ bool hasPendingDatagrams() const override;
+ qint64 pendingDatagramSize() const override;
#endif // QT_NO_UDPSOCKET
qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader * = 0,
- PacketHeaderOptions = WantNone) Q_DECL_OVERRIDE;
- qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) Q_DECL_OVERRIDE;
- qint64 bytesToWrite() const Q_DECL_OVERRIDE;
+ PacketHeaderOptions = WantNone) override;
+ qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) override;
+ qint64 bytesToWrite() const override;
#if 0 // currently unused
qint64 receiveBufferSize() const;
@@ -174,21 +174,21 @@ public:
void setSendBufferSize(qint64 bufferSize);
#endif
- int option(SocketOption option) const Q_DECL_OVERRIDE;
- bool setOption(SocketOption option, int value) Q_DECL_OVERRIDE;
+ int option(SocketOption option) const override;
+ bool setOption(SocketOption option, int value) override;
- bool waitForRead(int msecs = 30000, bool *timedOut = 0) Q_DECL_OVERRIDE;
- bool waitForWrite(int msecs = 30000, bool *timedOut = 0) Q_DECL_OVERRIDE;
+ bool waitForRead(int msecs = 30000, bool *timedOut = 0) override;
+ bool waitForWrite(int msecs = 30000, bool *timedOut = 0) override;
bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
bool checkRead, bool checkWrite,
- int msecs = 30000, bool *timedOut = 0) Q_DECL_OVERRIDE;
-
- bool isReadNotificationEnabled() const Q_DECL_OVERRIDE;
- void setReadNotificationEnabled(bool enable) Q_DECL_OVERRIDE;
- bool isWriteNotificationEnabled() const Q_DECL_OVERRIDE;
- void setWriteNotificationEnabled(bool enable) Q_DECL_OVERRIDE;
- bool isExceptionNotificationEnabled() const Q_DECL_OVERRIDE;
- void setExceptionNotificationEnabled(bool enable) Q_DECL_OVERRIDE;
+ int msecs = 30000, bool *timedOut = 0) override;
+
+ bool isReadNotificationEnabled() const override;
+ void setReadNotificationEnabled(bool enable) override;
+ bool isWriteNotificationEnabled() const override;
+ void setWriteNotificationEnabled(bool enable) override;
+ bool isExceptionNotificationEnabled() const override;
+ void setExceptionNotificationEnabled(bool enable) override;
public Q_SLOTS:
// non-virtual override;
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index cb0a521360..b380b0f7d6 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -226,6 +226,20 @@ static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt,
#endif
}
break;
+
+ case QNativeSocketEngine::PathMtuInformation:
+ if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
+#ifdef IPV6_MTU
+ level = IPPROTO_IPV6;
+ n = IPV6_MTU;
+#endif
+ } else {
+#ifdef IP_MTU
+ level = IPPROTO_IP;
+ n = IP_MTU;
+#endif
+ }
+ break;
}
}
@@ -331,6 +345,20 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co
return -1;
}
+ case QNativeSocketEngine::PathMtuInformation:
+#if defined(IPV6_PATHMTU) && !defined(IPV6_MTU)
+ // Prefer IPV6_MTU (handled by convertToLevelAndOption), if available
+ // (Linux); fall back to IPV6_PATHMTU otherwise (FreeBSD):
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ ip6_mtuinfo mtuinfo;
+ QT_SOCKOPTLEN_T len = sizeof(mtuinfo);
+ if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_PATHMTU, &mtuinfo, &len) == 0)
+ return int(mtuinfo.ip6m_mtu);
+ return -1;
+ }
+#endif
+ break;
+
default:
break;
}
@@ -420,6 +448,8 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
}
#endif
+ if (n == -1)
+ return false;
return ::setsockopt(socketDescriptor, level, n, (char *) &v, sizeof(v)) == 0;
}
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index bd368ac42f..afdc4cf319 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -209,7 +209,7 @@ static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, const qt
static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt,
QAbstractSocket::NetworkLayerProtocol socketProtocol, int &level, int &n)
{
- n = 0;
+ n = -1;
level = SOL_SOCKET; // default
switch (opt) {
@@ -281,6 +281,9 @@ static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt,
n = IP_HOPLIMIT;
}
break;
+
+ case QAbstractSocketEngine::PathMtuInformation:
+ break; // not supported on Windows
}
}
@@ -471,9 +474,11 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co
QT_SOCKOPTLEN_T len = sizeof(v);
convertToLevelAndOption(opt, socketProtocol, level, n);
- if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) == 0)
- return v;
- WS_ERROR_DEBUG(WSAGetLastError());
+ if (n != -1) {
+ if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) == 0)
+ return v;
+ WS_ERROR_DEBUG(WSAGetLastError());
+ }
return -1;
}
@@ -491,9 +496,7 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
switch (opt) {
case QNativeSocketEngine::SendBufferSocketOption:
// see QTBUG-30478 SO_SNDBUF should not be used on Vista or later
- if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA)
- return false;
- break;
+ return false;
case QNativeSocketEngine::NonBlockingSocketOption:
{
unsigned long buf = v;
@@ -516,6 +519,8 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
int n, level;
convertToLevelAndOption(opt, socketProtocol, level, n);
+ if (n == -1)
+ return false;
if (::setsockopt(socketDescriptor, level, n, (char*)&v, sizeof(v)) != 0) {
WS_ERROR_DEBUG(WSAGetLastError());
return false;
@@ -571,7 +576,6 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters()
DWORD ipv6only = 0;
QT_SOCKOPTLEN_T optlen = sizeof(ipv6only);
if (localAddress == QHostAddress::AnyIPv6
- && QSysInfo::windowsVersion() >= QSysInfo::WV_6_0
&& !getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, &optlen )) {
if (!ipv6only) {
socketProtocol = QAbstractSocket::AnyIPProtocol;
@@ -632,10 +636,8 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
if ((socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) && address.toIPv4Address()) {
//IPV6_V6ONLY option must be cleared to connect to a V4 mapped address
- if (QSysInfo::windowsVersion() >= QSysInfo::WV_6_0) {
- DWORD ipv6only = 0;
- ipv6only = ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) );
- }
+ DWORD ipv6only = 0;
+ ipv6only = ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) );
}
forever {
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp
index b7d7042923..9df5f0c500 100644
--- a/src/network/socket/qnativesocketengine_winrt.cpp
+++ b/src/network/socket/qnativesocketengine_winrt.cpp
@@ -1340,7 +1340,7 @@ QNativeSocketEnginePrivate::QNativeSocketEnginePrivate()
, closingDown(false)
, socketDescriptor(-1)
, worker(new SocketEngineWorker(this))
- , sslSocket(Q_NULLPTR)
+ , sslSocket(nullptr)
, connectionToken( { -1 } )
{
}
@@ -1514,6 +1514,7 @@ int QNativeSocketEnginePrivate::option(QAbstractSocketEngine::SocketOption opt)
case QAbstractSocketEngine::MulticastLoopbackOption:
case QAbstractSocketEngine::TypeOfServiceOption:
case QAbstractSocketEngine::MaxStreamsSocketOption:
+ case QAbstractSocketEngine::PathMtuInformation:
default:
return -1;
}
@@ -1573,6 +1574,7 @@ bool QNativeSocketEnginePrivate::setOption(QAbstractSocketEngine::SocketOption o
case QAbstractSocketEngine::MulticastLoopbackOption:
case QAbstractSocketEngine::TypeOfServiceOption:
case QAbstractSocketEngine::MaxStreamsSocketOption:
+ case QAbstractSocketEngine::PathMtuInformation:
default:
return false;
}
diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h
index 5359872f96..e038352352 100644
--- a/src/network/socket/qnet_unix_p.h
+++ b/src/network/socket/qnet_unix_p.h
@@ -78,7 +78,6 @@ QT_BEGIN_NAMESPACE
# define QT_SOCKOPTLEN_T QT_SOCKLEN_T
#endif
-// UnixWare 7 redefines socket -> _socket
static inline int qt_safe_socket(int domain, int type, int protocol, int flags = 0)
{
Q_ASSERT((flags & ~O_NONBLOCK) == 0);
@@ -105,7 +104,6 @@ static inline int qt_safe_socket(int domain, int type, int protocol, int flags =
#endif
}
-// Tru64 redefines accept -> _accept with _XOPEN_SOURCE_EXTENDED
static inline int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *addrlen, int flags = 0)
{
Q_ASSERT((flags & ~O_NONBLOCK) == 0);
@@ -137,7 +135,6 @@ static inline int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *add
#endif
}
-// UnixWare 7 redefines listen -> _listen
static inline int qt_safe_listen(int s, int backlog)
{
return ::listen(s, backlog);
diff --git a/src/network/socket/qsctpserver.h b/src/network/socket/qsctpserver.h
index 1afdab28a0..b678ba053d 100644
--- a/src/network/socket/qsctpserver.h
+++ b/src/network/socket/qsctpserver.h
@@ -63,7 +63,7 @@ public:
QSctpSocket *nextPendingDatagramConnection();
protected:
- void incomingConnection(qintptr handle) Q_DECL_OVERRIDE;
+ void incomingConnection(qintptr handle) override;
private:
Q_DISABLE_COPY(QSctpServer)
diff --git a/src/network/socket/qsctpserver_p.h b/src/network/socket/qsctpserver_p.h
index 274939fc3d..8816cc150e 100644
--- a/src/network/socket/qsctpserver_p.h
+++ b/src/network/socket/qsctpserver_p.h
@@ -66,7 +66,7 @@ public:
int maximumChannelCount;
- void configureCreatedSocket() Q_DECL_OVERRIDE;
+ void configureCreatedSocket() override;
};
#endif // QT_NO_SCTP
diff --git a/src/network/socket/qsctpsocket.h b/src/network/socket/qsctpsocket.h
index 9bed1890ff..5288da6129 100644
--- a/src/network/socket/qsctpsocket.h
+++ b/src/network/socket/qsctpsocket.h
@@ -56,8 +56,8 @@ public:
explicit QSctpSocket(QObject *parent = nullptr);
virtual ~QSctpSocket();
- void close() Q_DECL_OVERRIDE;
- void disconnectFromHost() Q_DECL_OVERRIDE;
+ void close() override;
+ void disconnectFromHost() override;
void setMaximumChannelCount(int count);
int maximumChannelCount() const;
@@ -67,8 +67,8 @@ public:
bool writeDatagram(const QNetworkDatagram &datagram);
protected:
- qint64 readData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
- qint64 readLineData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
+ qint64 readData(char *data, qint64 maxlen) override;
+ qint64 readLineData(char *data, qint64 maxlen) override;
private:
Q_DISABLE_COPY(QSctpSocket)
diff --git a/src/network/socket/qsctpsocket_p.h b/src/network/socket/qsctpsocket_p.h
index 3f765ebed9..8f9413cb47 100644
--- a/src/network/socket/qsctpsocket_p.h
+++ b/src/network/socket/qsctpsocket_p.h
@@ -70,8 +70,8 @@ public:
QSctpSocketPrivate();
virtual ~QSctpSocketPrivate();
- bool canReadNotification() Q_DECL_OVERRIDE;
- bool writeToSocket() Q_DECL_OVERRIDE;
+ bool canReadNotification() override;
+ bool writeToSocket() override;
QByteArray incomingDatagram;
int maximumChannelCount;
@@ -80,7 +80,7 @@ public:
QVector<IpHeaderList> readHeaders;
QVector<IpHeaderList> writeHeaders;
- void configureCreatedSocket() Q_DECL_OVERRIDE;
+ void configureCreatedSocket() override;
};
#endif // QT_NO_SCTP
diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp
index fa5f198bf2..a07ea65046 100644
--- a/src/network/socket/qsocks5socketengine.cpp
+++ b/src/network/socket/qsocks5socketengine.cpp
@@ -320,7 +320,7 @@ public:
QSocks5BindData *retrieve(qintptr socketDescriptor);
protected:
- void timerEvent(QTimerEvent * event) Q_DECL_OVERRIDE;
+ void timerEvent(QTimerEvent * event) override;
QMutex mutex;
int sweepTimerId;
diff --git a/src/network/socket/qsocks5socketengine_p.h b/src/network/socket/qsocks5socketengine_p.h
index b248554ae5..1942eff4ca 100644
--- a/src/network/socket/qsocks5socketengine_p.h
+++ b/src/network/socket/qsocks5socketengine_p.h
@@ -68,62 +68,62 @@ public:
QSocks5SocketEngine(QObject *parent = 0);
~QSocks5SocketEngine();
- bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) Q_DECL_OVERRIDE;
- bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState) Q_DECL_OVERRIDE;
+ bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) override;
+ bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState) override;
void setProxy(const QNetworkProxy &networkProxy);
- qintptr socketDescriptor() const Q_DECL_OVERRIDE;
+ qintptr socketDescriptor() const override;
- bool isValid() const Q_DECL_OVERRIDE;
+ bool isValid() const override;
bool connectInternal();
- bool connectToHost(const QHostAddress &address, quint16 port) Q_DECL_OVERRIDE;
- bool connectToHostByName(const QString &name, quint16 port) Q_DECL_OVERRIDE;
- bool bind(const QHostAddress &address, quint16 port) Q_DECL_OVERRIDE;
- bool listen() Q_DECL_OVERRIDE;
- int accept() Q_DECL_OVERRIDE;
- void close() Q_DECL_OVERRIDE;
+ bool connectToHost(const QHostAddress &address, quint16 port) override;
+ bool connectToHostByName(const QString &name, quint16 port) override;
+ bool bind(const QHostAddress &address, quint16 port) override;
+ bool listen() override;
+ int accept() override;
+ void close() override;
- qint64 bytesAvailable() const Q_DECL_OVERRIDE;
+ qint64 bytesAvailable() const override;
- qint64 read(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
- qint64 write(const char *data, qint64 len) Q_DECL_OVERRIDE;
+ qint64 read(char *data, qint64 maxlen) override;
+ qint64 write(const char *data, qint64 len) override;
#ifndef QT_NO_UDPSOCKET
#ifndef QT_NO_NETWORKINTERFACE
bool joinMulticastGroup(const QHostAddress &groupAddress,
- const QNetworkInterface &interface) Q_DECL_OVERRIDE;
+ const QNetworkInterface &interface) override;
bool leaveMulticastGroup(const QHostAddress &groupAddress,
- const QNetworkInterface &interface) Q_DECL_OVERRIDE;
- QNetworkInterface multicastInterface() const Q_DECL_OVERRIDE;
- bool setMulticastInterface(const QNetworkInterface &iface) Q_DECL_OVERRIDE;
+ const QNetworkInterface &interface) override;
+ QNetworkInterface multicastInterface() const override;
+ bool setMulticastInterface(const QNetworkInterface &iface) override;
#endif // QT_NO_NETWORKINTERFACE
- bool hasPendingDatagrams() const Q_DECL_OVERRIDE;
- qint64 pendingDatagramSize() const Q_DECL_OVERRIDE;
+ bool hasPendingDatagrams() const override;
+ qint64 pendingDatagramSize() const override;
#endif // QT_NO_UDPSOCKET
qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader * = 0,
- PacketHeaderOptions = WantNone) Q_DECL_OVERRIDE;
- qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) Q_DECL_OVERRIDE;
- qint64 bytesToWrite() const Q_DECL_OVERRIDE;
+ PacketHeaderOptions = WantNone) override;
+ qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) override;
+ qint64 bytesToWrite() const override;
- int option(SocketOption option) const Q_DECL_OVERRIDE;
- bool setOption(SocketOption option, int value) Q_DECL_OVERRIDE;
+ int option(SocketOption option) const override;
+ bool setOption(SocketOption option, int value) override;
- bool waitForRead(int msecs = 30000, bool *timedOut = 0) Q_DECL_OVERRIDE;
- bool waitForWrite(int msecs = 30000, bool *timedOut = 0) Q_DECL_OVERRIDE;
+ bool waitForRead(int msecs = 30000, bool *timedOut = 0) override;
+ bool waitForWrite(int msecs = 30000, bool *timedOut = 0) override;
bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
bool checkRead, bool checkWrite,
- int msecs = 30000, bool *timedOut = 0) Q_DECL_OVERRIDE;
+ int msecs = 30000, bool *timedOut = 0) override;
- bool isReadNotificationEnabled() const Q_DECL_OVERRIDE;
- void setReadNotificationEnabled(bool enable) Q_DECL_OVERRIDE;
- bool isWriteNotificationEnabled() const Q_DECL_OVERRIDE;
- void setWriteNotificationEnabled(bool enable) Q_DECL_OVERRIDE;
- bool isExceptionNotificationEnabled() const Q_DECL_OVERRIDE;
- void setExceptionNotificationEnabled(bool enable) Q_DECL_OVERRIDE;
+ bool isReadNotificationEnabled() const override;
+ void setReadNotificationEnabled(bool enable) override;
+ bool isWriteNotificationEnabled() const override;
+ void setWriteNotificationEnabled(bool enable) override;
+ bool isExceptionNotificationEnabled() const override;
+ void setExceptionNotificationEnabled(bool enable) override;
private:
Q_DECLARE_PRIVATE(QSocks5SocketEngine)
@@ -166,11 +166,11 @@ class QSocks5PasswordAuthenticator : public QSocks5Authenticator
{
public:
QSocks5PasswordAuthenticator(const QString &userName, const QString &password);
- char methodId() Q_DECL_OVERRIDE;
- bool beginAuthenticate(QTcpSocket *socket, bool *completed) Q_DECL_OVERRIDE;
- bool continueAuthenticate(QTcpSocket *socket, bool *completed) Q_DECL_OVERRIDE;
+ char methodId() override;
+ bool beginAuthenticate(QTcpSocket *socket, bool *completed) override;
+ bool continueAuthenticate(QTcpSocket *socket, bool *completed) override;
- QString errorString() Q_DECL_OVERRIDE;
+ QString errorString() override;
private:
QString userName;
@@ -287,8 +287,8 @@ class Q_AUTOTEST_EXPORT QSocks5SocketEngineHandler : public QSocketEngineHandler
{
public:
virtual QAbstractSocketEngine *createSocketEngine(QAbstractSocket::SocketType socketType,
- const QNetworkProxy &, QObject *parent) Q_DECL_OVERRIDE;
- virtual QAbstractSocketEngine *createSocketEngine(qintptr socketDescriptor, QObject *parent) Q_DECL_OVERRIDE;
+ const QNetworkProxy &, QObject *parent) override;
+ virtual QAbstractSocketEngine *createSocketEngine(qintptr socketDescriptor, QObject *parent) override;
};
QT_END_NAMESPACE
diff --git a/src/network/socket/qtcpserver.h b/src/network/socket/qtcpserver.h
index 192cbce54c..37df12919f 100644
--- a/src/network/socket/qtcpserver.h
+++ b/src/network/socket/qtcpserver.h
@@ -58,7 +58,7 @@ class Q_NETWORK_EXPORT QTcpServer : public QObject
{
Q_OBJECT
public:
- explicit QTcpServer(QObject *parent = Q_NULLPTR);
+ explicit QTcpServer(QObject *parent = nullptr);
virtual ~QTcpServer();
bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
@@ -75,7 +75,7 @@ public:
qintptr socketDescriptor() const;
bool setSocketDescriptor(qintptr socketDescriptor);
- bool waitForNewConnection(int msec = 0, bool *timedOut = Q_NULLPTR);
+ bool waitForNewConnection(int msec = 0, bool *timedOut = nullptr);
virtual bool hasPendingConnections() const;
virtual QTcpSocket *nextPendingConnection();
@@ -95,7 +95,7 @@ protected:
void addPendingConnection(QTcpSocket* socket);
QTcpServer(QAbstractSocket::SocketType socketType, QTcpServerPrivate &dd,
- QObject *parent = Q_NULLPTR);
+ QObject *parent = nullptr);
Q_SIGNALS:
void newConnection();
diff --git a/src/network/socket/qtcpserver_p.h b/src/network/socket/qtcpserver_p.h
index b7fae4c105..6ee8c5f0b1 100644
--- a/src/network/socket/qtcpserver_p.h
+++ b/src/network/socket/qtcpserver_p.h
@@ -93,13 +93,13 @@ public:
virtual void configureCreatedSocket();
// from QAbstractSocketEngineReceiver
- void readNotification() Q_DECL_OVERRIDE;
- void closeNotification() Q_DECL_OVERRIDE { readNotification(); }
- void writeNotification() Q_DECL_OVERRIDE {}
- void exceptionNotification() Q_DECL_OVERRIDE {}
- void connectionNotification() Q_DECL_OVERRIDE {}
+ void readNotification() override;
+ void closeNotification() override { readNotification(); }
+ void writeNotification() override {}
+ void exceptionNotification() override {}
+ void connectionNotification() override {}
#ifndef QT_NO_NETWORKPROXY
- void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *) Q_DECL_OVERRIDE {}
+ void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *) override {}
#endif
};
diff --git a/src/network/socket/qtcpsocket.h b/src/network/socket/qtcpsocket.h
index 3c3e3b69fd..b2c8bcc884 100644
--- a/src/network/socket/qtcpsocket.h
+++ b/src/network/socket/qtcpsocket.h
@@ -53,13 +53,13 @@ class Q_NETWORK_EXPORT QTcpSocket : public QAbstractSocket
{
Q_OBJECT
public:
- explicit QTcpSocket(QObject *parent = Q_NULLPTR);
+ explicit QTcpSocket(QObject *parent = nullptr);
virtual ~QTcpSocket();
protected:
- QTcpSocket(QTcpSocketPrivate &dd, QObject *parent = Q_NULLPTR);
+ QTcpSocket(QTcpSocketPrivate &dd, QObject *parent = nullptr);
QTcpSocket(QAbstractSocket::SocketType socketType, QTcpSocketPrivate &dd,
- QObject *parent = Q_NULLPTR);
+ QObject *parent = nullptr);
private:
Q_DISABLE_COPY(QTcpSocket)
diff --git a/src/network/socket/qudpsocket.h b/src/network/socket/qudpsocket.h
index 6ef10e2edb..ce4429d1cd 100644
--- a/src/network/socket/qudpsocket.h
+++ b/src/network/socket/qudpsocket.h
@@ -57,7 +57,7 @@ class Q_NETWORK_EXPORT QUdpSocket : public QAbstractSocket
{
Q_OBJECT
public:
- explicit QUdpSocket(QObject *parent = Q_NULLPTR);
+ explicit QUdpSocket(QObject *parent = nullptr);
virtual ~QUdpSocket();
#ifndef QT_NO_NETWORKINTERFACE
@@ -75,7 +75,7 @@ public:
bool hasPendingDatagrams() const;
qint64 pendingDatagramSize() const;
QNetworkDatagram receiveDatagram(qint64 maxSize = -1);
- qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *host = Q_NULLPTR, quint16 *port = Q_NULLPTR);
+ qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *host = nullptr, quint16 *port = nullptr);
qint64 writeDatagram(const QNetworkDatagram &datagram);
qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port);
diff --git a/src/network/socket/socket.pri b/src/network/socket/socket.pri
index b2ee1a8054..a8a37492b7 100644
--- a/src/network/socket/socket.pri
+++ b/src/network/socket/socket.pri
@@ -1,7 +1,6 @@
# Qt network socket
HEADERS += socket/qabstractsocketengine_p.h \
- socket/qhttpsocketengine_p.h \
socket/qabstractsocket.h \
socket/qabstractsocket_p.h \
socket/qtcpsocket.h \
@@ -11,7 +10,6 @@ HEADERS += socket/qabstractsocketengine_p.h \
socket/qtcpserver_p.h
SOURCES += socket/qabstractsocketengine.cpp \
- socket/qhttpsocketengine.cpp \
socket/qabstractsocket.cpp \
socket/qtcpsocket.cpp \
socket/qudpsocket.cpp \
@@ -26,6 +24,13 @@ qtConfig(socks5) {
socket/qsocks5socketengine.cpp
}
+qtConfig(http) {
+ HEADERS += \
+ socket/qhttpsocketengine_p.h
+ SOURCES += \
+ socket/qhttpsocketengine.cpp
+}
+
# SCTP support.
qtConfig(sctp) {
diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h
index 8b051a5c88..6cd66fd20f 100644
--- a/src/network/ssl/qsslcertificate.h
+++ b/src/network/ssl/qsslcertificate.h
@@ -154,7 +154,7 @@ public:
static bool importPkcs12(QIODevice *device,
QSslKey *key, QSslCertificate *cert,
- QList<QSslCertificate> *caCertificates = Q_NULLPTR,
+ QList<QSslCertificate> *caCertificates = nullptr,
const QByteArray &passPhrase=QByteArray());
Qt::HANDLE handle() const;
diff --git a/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp b/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
index 5ebad822f1..00e9be91d8 100644
--- a/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
+++ b/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
@@ -161,12 +161,12 @@ void QSslDiffieHellmanParametersPrivate::decodePem(const QByteArray &pem)
return;
}
- DH *dh = Q_NULLPTR;
+ DH *dh = nullptr;
q_PEM_read_bio_DHparams(bio, &dh, 0, 0);
if (dh) {
if (isSafeDH(dh)) {
- char *buf = Q_NULLPTR;
+ char *buf = nullptr;
int len = q_i2d_DHparams(dh, reinterpret_cast<unsigned char **>(&buf));
if (len > 0)
derData = QByteArray(buf, len);
diff --git a/src/network/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp
index 3c5dc830d3..817317f303 100644
--- a/src/network/ssl/qsslkey_qt.cpp
+++ b/src/network/ssl/qsslkey_qt.cpp
@@ -43,6 +43,7 @@
#include <QtCore/qdatastream.h>
#include <QtCore/qcryptographichash.h>
+#include <QtCore/qrandom.h>
QT_USE_NAMESPACE
@@ -286,10 +287,8 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const
if (type == QSsl::PrivateKey && !passPhrase.isEmpty()) {
// ### use a cryptographically secure random number generator
- QByteArray iv;
- iv.resize(8);
- for (int i = 0; i < iv.size(); ++i)
- iv[i] = (qrand() & 0xff);
+ quint64 random = QRandomGenerator::system()->generate64();
+ QByteArray iv = QByteArray::fromRawData(reinterpret_cast<const char *>(&random), sizeof(random));
Cipher cipher = DesEde3Cbc;
const QByteArray key = deriveKey(cipher, passPhrase, iv);
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index adff568f5b..145ae1a3c8 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -2659,6 +2659,20 @@ QByteArray QSslSocketPrivate::peek(qint64 maxSize)
/*!
\internal
*/
+qint64 QSslSocketPrivate::skip(qint64 maxSize)
+{
+ if (mode == QSslSocket::UnencryptedMode && !autoStartHandshake)
+ return plainSocket->skip(maxSize);
+
+ // In encrypted mode, the SSL backend writes decrypted data directly into the
+ // QIODevice's read buffer. As this buffer is always emptied by the caller,
+ // we need to wait for more incoming data.
+ return (state == QAbstractSocket::ConnectedState) ? Q_INT64_C(0) : Q_INT64_C(-1);
+}
+
+/*!
+ \internal
+*/
bool QSslSocketPrivate::flush()
{
#ifdef QSSLSOCKET_DEBUG
diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h
index 39e70bccda..c66ebdde54 100644
--- a/src/network/ssl/qsslsocket.h
+++ b/src/network/ssl/qsslsocket.h
@@ -79,22 +79,22 @@ public:
AutoVerifyPeer
};
- explicit QSslSocket(QObject *parent = Q_NULLPTR);
+ explicit QSslSocket(QObject *parent = nullptr);
~QSslSocket();
- void resume() Q_DECL_OVERRIDE; // to continue after proxy authentication required, SSL errors etc.
+ void resume() override; // to continue after proxy authentication required, SSL errors etc.
// Autostarting the SSL client handshake.
void connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode mode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol);
void connectToHostEncrypted(const QString &hostName, quint16 port, const QString &sslPeerName, OpenMode mode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol);
bool setSocketDescriptor(qintptr socketDescriptor, SocketState state = ConnectedState,
- OpenMode openMode = ReadWrite) Q_DECL_OVERRIDE;
+ OpenMode openMode = ReadWrite) override;
using QAbstractSocket::connectToHost;
- void connectToHost(const QString &hostName, quint16 port, OpenMode openMode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol) Q_DECL_OVERRIDE;
- void disconnectFromHost() Q_DECL_OVERRIDE;
+ void connectToHost(const QString &hostName, quint16 port, OpenMode openMode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol) override;
+ void disconnectFromHost() override;
- virtual void setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value) Q_DECL_OVERRIDE;
- virtual QVariant socketOption(QAbstractSocket::SocketOption option) Q_DECL_OVERRIDE;
+ virtual void setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value) override;
+ virtual QVariant socketOption(QAbstractSocket::SocketOption option) override;
SslMode mode() const;
bool isEncrypted() const;
@@ -112,16 +112,16 @@ public:
void setPeerVerifyName(const QString &hostName);
// From QIODevice
- qint64 bytesAvailable() const Q_DECL_OVERRIDE;
- qint64 bytesToWrite() const Q_DECL_OVERRIDE;
- bool canReadLine() const Q_DECL_OVERRIDE;
- void close() Q_DECL_OVERRIDE;
- bool atEnd() const Q_DECL_OVERRIDE;
+ qint64 bytesAvailable() const override;
+ qint64 bytesToWrite() const override;
+ bool canReadLine() const override;
+ void close() override;
+ bool atEnd() const override;
bool flush(); // ### Qt6: remove me (implementation moved to private flush())
void abort();
// From QAbstractSocket:
- void setReadBufferSize(qint64 size) Q_DECL_OVERRIDE;
+ void setReadBufferSize(qint64 size) override;
// Similar to QIODevice's:
qint64 encryptedBytesAvailable() const;
@@ -179,11 +179,11 @@ public:
QT_DEPRECATED_X("Use QSslConfiguration::systemCaCertificates()") static QList<QSslCertificate> systemCaCertificates();
#endif // QT_DEPRECATED_SINCE(5, 5)
- bool waitForConnected(int msecs = 30000) Q_DECL_OVERRIDE;
+ bool waitForConnected(int msecs = 30000) override;
bool waitForEncrypted(int msecs = 30000);
- bool waitForReadyRead(int msecs = 30000) Q_DECL_OVERRIDE;
- bool waitForBytesWritten(int msecs = 30000) Q_DECL_OVERRIDE;
- bool waitForDisconnected(int msecs = 30000) Q_DECL_OVERRIDE;
+ bool waitForReadyRead(int msecs = 30000) override;
+ bool waitForBytesWritten(int msecs = 30000) override;
+ bool waitForDisconnected(int msecs = 30000) override;
QList<QSslError> sslErrors() const;
@@ -209,8 +209,8 @@ Q_SIGNALS:
void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator);
protected:
- qint64 readData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
- qint64 writeData(const char *data, qint64 len) Q_DECL_OVERRIDE;
+ qint64 readData(char *data, qint64 maxlen) override;
+ qint64 writeData(const char *data, qint64 len) override;
private:
Q_DECLARE_PRIVATE(QSslSocket)
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp
index 8d2efe74be..5c2bd55198 100644
--- a/src/network/ssl/qsslsocket_mac.cpp
+++ b/src/network/ssl/qsslsocket_mac.cpp
@@ -48,6 +48,7 @@
#include <QtCore/qmessageauthenticationcode.h>
#include <QtCore/qcryptographichash.h>
+#include <QtCore/qsystemdetection.h>
#include <QtCore/qdatastream.h>
#include <QtCore/qsysinfo.h>
#include <QtCore/qvector.h>
@@ -160,14 +161,15 @@ EphemeralSecKeychain::~EphemeralSecKeychain()
}
#endif // Q_OS_MACOS
-}
+
+} // unnamed namespace
static SSLContextRef qt_createSecureTransportContext(QSslSocket::SslMode mode)
{
const bool isServer = mode == QSslSocket::SslServerMode;
const SSLProtocolSide side = isServer ? kSSLServerSide : kSSLClientSide;
// We never use kSSLDatagramType, so it's kSSLStreamType unconditionally.
- SSLContextRef context = SSLCreateContext(Q_NULLPTR, side, kSSLStreamType);
+ SSLContextRef context = SSLCreateContext(nullptr, side, kSSLStreamType);
if (!context)
qCWarning(lcSsl) << "SSLCreateContext failed";
return context;
@@ -356,7 +358,7 @@ void QSslSocketPrivate::resetDefaultEllipticCurves()
}
QSslSocketBackendPrivate::QSslSocketBackendPrivate()
- : context(Q_NULLPTR)
+ : context(nullptr)
{
}
@@ -372,6 +374,43 @@ void QSslSocketBackendPrivate::continueHandshake()
#endif
Q_Q(QSslSocket);
connectionEncrypted = true;
+
+#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, __IPHONE_11_0, __TVOS_11_0, __WATCHOS_4_0)
+ // Unlike OpenSSL, Secure Transport does not allow to negotiate protocols via
+ // a callback during handshake. We can only set our list of preferred protocols
+ // (and send it during handshake) and then receive what our peer has sent to us.
+ // And here we can finally try to find a match (if any).
+ if (__builtin_available(iOS 11.0, tvOS 11.0, watchOS 4.0, *)) {
+ const auto &requestedProtocols = configuration.nextAllowedProtocols;
+ if (const int requestedCount = requestedProtocols.size()) {
+ configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNone;
+ configuration.nextNegotiatedProtocol.clear();
+
+ QCFType<CFArrayRef> cfArray;
+ const OSStatus result = SSLCopyALPNProtocols(context, &cfArray);
+ if (result == errSecSuccess && cfArray && CFArrayGetCount(cfArray)) {
+ const int size = CFArrayGetCount(cfArray);
+ QVector<QString> peerProtocols(size);
+ for (int i = 0; i < size; ++i)
+ peerProtocols[i] = QString::fromCFString((CFStringRef)CFArrayGetValueAtIndex(cfArray, i));
+
+ for (int i = 0; i < requestedCount; ++i) {
+ const auto requestedName = QString::fromLatin1(requestedProtocols[i]);
+ for (int j = 0; j < size; ++j) {
+ if (requestedName == peerProtocols[j]) {
+ configuration.nextNegotiatedProtocol = requestedName.toLatin1();
+ configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNegotiated;
+ break;
+ }
+ }
+ if (configuration.nextProtocolNegotiationStatus == QSslConfiguration::NextProtocolNegotiationNegotiated)
+ break;
+ }
+ }
+ }
+ }
+#endif // QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE
+
emit q->encrypted();
if (autoStartHandshake && pendingClose) {
pendingClose = false;
@@ -838,6 +877,29 @@ bool QSslSocketBackendPrivate::initSslContext()
return false;
}
+#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, __IPHONE_11_0, __TVOS_11_0, __WATCHOS_4_0)
+ if (__builtin_available(iOS 11.0, tvOS 11.0, watchOS 4.0, *)) {
+ const auto protocolNames = configuration.nextAllowedProtocols;
+ QCFType<CFMutableArrayRef> cfNames(CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks));
+ if (cfNames) {
+ for (const QByteArray &name : protocolNames) {
+ QCFString cfName(QString::fromLatin1(name).toCFString());
+ CFArrayAppendValue(cfNames, cfName);
+ }
+
+ if (CFArrayGetCount(cfNames)) {
+ // Up to the application layer to check that negotiation
+ // failed, and handle this non-TLS error, we do not handle
+ // the result of this call as an error:
+ if (SSLSetALPNProtocols(context, cfNames) != errSecSuccess)
+ qCWarning(lcSsl) << "SSLSetALPNProtocols failed - too long protocol names?";
+ }
+ } else {
+ qCWarning(lcSsl) << "failed to allocate ALPN names array";
+ }
+ }
+#endif // QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE
+
if (mode == QSslSocket::SslClientMode) {
// enable Server Name Indication (SNI)
QString tlsHostName(verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName);
@@ -885,7 +947,7 @@ bool QSslSocketBackendPrivate::initSslContext()
void QSslSocketBackendPrivate::destroySslContext()
{
- context.reset(Q_NULLPTR);
+ context.reset(nullptr);
}
static QByteArray _q_makePkcs12(const QList<QSslCertificate> &certs, const QSslKey &key, const QString &passPhrase);
diff --git a/src/network/ssl/qsslsocket_mac_p.h b/src/network/ssl/qsslsocket_mac_p.h
index 9e1d18981e..34e30ebb16 100644
--- a/src/network/ssl/qsslsocket_mac_p.h
+++ b/src/network/ssl/qsslsocket_mac_p.h
@@ -86,14 +86,14 @@ public:
virtual ~QSslSocketBackendPrivate();
// Final-overriders (QSslSocketPrivate):
- void continueHandshake() Q_DECL_OVERRIDE;
- void disconnected() Q_DECL_OVERRIDE;
- void disconnectFromHost() Q_DECL_OVERRIDE;
- QSslCipher sessionCipher() const Q_DECL_OVERRIDE;
- QSsl::SslProtocol sessionProtocol() const Q_DECL_OVERRIDE;
- void startClientEncryption() Q_DECL_OVERRIDE;
- void startServerEncryption() Q_DECL_OVERRIDE;
- void transmit() Q_DECL_OVERRIDE;
+ void continueHandshake() override;
+ void disconnected() override;
+ void disconnectFromHost() override;
+ QSslCipher sessionCipher() const override;
+ QSsl::SslProtocol sessionProtocol() const override;
+ void startClientEncryption() override;
+ void startServerEncryption() override;
+ void transmit() override;
static QList<QSslError> verify(QList<QSslCertificate> certificateChain,
const QString &hostName);
diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h
index 7f9e884045..2a800cdc34 100644
--- a/src/network/ssl/qsslsocket_openssl_p.h
+++ b/src/network/ssl/qsslsocket_openssl_p.h
@@ -132,22 +132,22 @@ public:
#endif
// Platform specific functions
- void startClientEncryption() Q_DECL_OVERRIDE;
- void startServerEncryption() Q_DECL_OVERRIDE;
- void transmit() Q_DECL_OVERRIDE;
+ void startClientEncryption() override;
+ void startServerEncryption() override;
+ void transmit() override;
bool startHandshake();
- void disconnectFromHost() Q_DECL_OVERRIDE;
- void disconnected() Q_DECL_OVERRIDE;
- QSslCipher sessionCipher() const Q_DECL_OVERRIDE;
- QSsl::SslProtocol sessionProtocol() const Q_DECL_OVERRIDE;
- void continueHandshake() Q_DECL_OVERRIDE;
+ void disconnectFromHost() override;
+ void disconnected() override;
+ QSslCipher sessionCipher() const override;
+ QSsl::SslProtocol sessionProtocol() const override;
+ void continueHandshake() override;
bool checkSslErrors();
void storePeerCertificates();
unsigned int tlsPskClientCallback(const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len);
unsigned int tlsPskServerCallback(const char *identity, unsigned char *psk, unsigned int max_psk_len);
#ifdef Q_OS_WIN
void fetchCaRootForCert(const QSslCertificate &cert);
- void _q_caRootLoaded(QSslCertificate,QSslCertificate) Q_DECL_OVERRIDE;
+ void _q_caRootLoaded(QSslCertificate,QSslCertificate) override;
#endif
Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 3a236a1300..1b73135935 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -1017,7 +1017,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(EC_GROUP_get_degree)
#endif
RESOLVEFUNC(BN_num_bits)
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if QT_CONFIG(opensslv11)
RESOLVEFUNC(BN_is_word)
#endif
RESOLVEFUNC(BN_mod_word)
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index 796bf2d4f5..4cad0231cd 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -232,9 +232,10 @@ BIO *q_BIO_new_mem_buf(void *a, int b);
int q_BIO_read(BIO *a, void *b, int c);
Q_AUTOTEST_EXPORT int q_BIO_write(BIO *a, const void *b, int c);
int q_BN_num_bits(const BIGNUM *a);
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+
+#if QT_CONFIG(opensslv11)
int q_BN_is_word(BIGNUM *a, BN_ULONG w);
-#else
+#else // opensslv11
// BN_is_word is implemented purely as a
// macro in OpenSSL < 1.1. It doesn't
// call any functions.
@@ -245,7 +246,8 @@ int q_BN_is_word(BIGNUM *a, BN_ULONG w);
//
// Users are required to include <openssl/bn.h>.
#define q_BN_is_word BN_is_word
-#endif // OPENSSL_VERSION_NUMBER >= 0x10100000L
+#endif // !opensslv11
+
BN_ULONG q_BN_mod_word(const BIGNUM *a, BN_ULONG w);
#ifndef OPENSSL_NO_EC
const EC_GROUP* q_EC_KEY_get0_group(const EC_KEY* k);
diff --git a/src/network/ssl/qsslsocket_opensslpre11.cpp b/src/network/ssl/qsslsocket_opensslpre11.cpp
index e51888c5f2..8ad4d5b521 100644
--- a/src/network/ssl/qsslsocket_opensslpre11.cpp
+++ b/src/network/ssl/qsslsocket_opensslpre11.cpp
@@ -290,8 +290,7 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
//its own cert bundle rather than the system one.
//Same logic that disables the unix on demand cert loading.
//Unlike unix, we do preload the certificates from the cert store.
- if ((QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) >= QSysInfo::WV_6_0)
- s_loadRootCertsOnDemand = true;
+ s_loadRootCertsOnDemand = true;
#endif
}
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index 00fda43b7e..ced861805b 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -170,7 +170,7 @@ public:
static void checkSettingSslContext(QSslSocket*, QSharedPointer<QSslContext>);
static QSharedPointer<QSslContext> sslContext(QSslSocket *socket);
bool isPaused() const;
- bool bind(const QHostAddress &address, quint16, QAbstractSocket::BindMode) Q_DECL_OVERRIDE;
+ bool bind(const QHostAddress &address, quint16, QAbstractSocket::BindMode) override;
void _q_connectedSlot();
void _q_hostFoundSlot();
void _q_disconnectedSlot();
@@ -190,9 +190,10 @@ public:
static QList<QByteArray> unixRootCertDirectories(); // used also by QSslContext
- virtual qint64 peek(char *data, qint64 maxSize) Q_DECL_OVERRIDE;
- virtual QByteArray peek(qint64 maxSize) Q_DECL_OVERRIDE;
- bool flush() Q_DECL_OVERRIDE;
+ virtual qint64 peek(char *data, qint64 maxSize) override;
+ virtual QByteArray peek(qint64 maxSize) override;
+ qint64 skip(qint64 maxSize) override;
+ bool flush() override;
// Platform specific functions
virtual void startClientEncryption() = 0;
diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp
index ca65f8a015..6c5a09962b 100644
--- a/src/network/ssl/qsslsocket_winrt.cpp
+++ b/src/network/ssl/qsslsocket_winrt.cpp
@@ -518,7 +518,7 @@ HRESULT QSslSocketBackendPrivate::onSslUpgrade(IAsyncAction *action, AsyncStatus
QList<QSslCertificate> peerCertificateChain;
if (certificate) {
ComPtr<IAsyncOperation<CertificateChain *>> op;
- hr = certificate->BuildChainAsync(Q_NULLPTR, &op);
+ hr = certificate->BuildChainAsync(nullptr, &op);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<ICertificateChain> certificateChain;
hr = QWinRTFunctions::await(op, certificateChain.GetAddressOf());
diff --git a/src/network/ssl/qsslsocket_winrt_p.h b/src/network/ssl/qsslsocket_winrt_p.h
index 1043aeee11..030db6d4fa 100644
--- a/src/network/ssl/qsslsocket_winrt_p.h
+++ b/src/network/ssl/qsslsocket_winrt_p.h
@@ -80,14 +80,14 @@ public:
~QSslSocketBackendPrivate();
// Platform specific functions
- void startClientEncryption() Q_DECL_OVERRIDE;
- void startServerEncryption() Q_DECL_OVERRIDE;
- void transmit() Q_DECL_OVERRIDE;
- void disconnectFromHost() Q_DECL_OVERRIDE;
- void disconnected() Q_DECL_OVERRIDE;
- QSslCipher sessionCipher() const Q_DECL_OVERRIDE;
- QSsl::SslProtocol sessionProtocol() const Q_DECL_OVERRIDE;
- void continueHandshake() Q_DECL_OVERRIDE;
+ void startClientEncryption() override;
+ void startServerEncryption() override;
+ void transmit() override;
+ void disconnectFromHost() override;
+ void disconnected() override;
+ QSslCipher sessionCipher() const override;
+ QSsl::SslProtocol sessionProtocol() const override;
+ void continueHandshake() override;
static QList<QSslCipher> defaultCiphers();
static QList<QSslError> verify(const QList<QSslCertificate> &certificateChain, const QString &hostName);