summaryrefslogtreecommitdiffstats
path: root/src/network/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/kernel')
-rw-r--r--src/network/kernel/kernel.pri5
-rw-r--r--src/network/kernel/qhostaddress.cpp136
-rw-r--r--src/network/kernel/qhostaddress.h2
-rw-r--r--src/network/kernel/qhostinfo.cpp16
-rw-r--r--src/network/kernel/qhostinfo_unix.cpp9
-rw-r--r--src/network/kernel/qhostinfo_win.cpp19
-rw-r--r--src/network/kernel/qhostinfo_winrt.cpp39
-rw-r--r--src/network/kernel/qnetworkinterface.cpp14
-rw-r--r--src/network/kernel/qnetworkinterface.h3
-rw-r--r--src/network/kernel/qnetworkinterface_unix.cpp52
-rw-r--r--src/network/kernel/qnetworkinterface_win.cpp140
-rw-r--r--src/network/kernel/qnetworkinterface_win_p.h262
-rw-r--r--src/network/kernel/qnetworkproxy_mac.cpp1
13 files changed, 189 insertions, 509 deletions
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri
index e539388b81..435bfd6c27 100644
--- a/src/network/kernel/kernel.pri
+++ b/src/network/kernel/kernel.pri
@@ -34,11 +34,12 @@ android {
win32: {
!winrt {
- HEADERS += kernel/qnetworkinterface_win_p.h
SOURCES += kernel/qdnslookup_win.cpp \
kernel/qhostinfo_win.cpp \
kernel/qnetworkinterface_win.cpp
- LIBS_PRIVATE += -ldnsapi
+ LIBS_PRIVATE += -ldnsapi -liphlpapi
+ DEFINES += WINVER=0x0600 _WIN32_WINNT=0x0600
+
} else {
SOURCES += kernel/qdnslookup_winrt.cpp \
kernel/qhostinfo_winrt.cpp \
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index 58c0de1f3b..935af04e31 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -46,6 +46,9 @@
#ifndef QT_NO_DATASTREAM
#include <qdatastream.h>
#endif
+#ifdef __SSE2__
+# include <private/qsimd_p.h>
+#endif
#ifdef QT_LINUXBASE
# include <arpa/inet.h>
@@ -106,7 +109,11 @@ public:
QString scopeId;
quint32 a; // IPv4 address
- Q_IPV6ADDR a6; // IPv6 address
+ union {
+ Q_IPV6ADDR a6; // IPv6 address
+ struct { quint64 c[2]; } a6_64;
+ struct { quint32 c[4]; } a6_32;
+ };
QAbstractSocket::NetworkLayerProtocol protocol;
bool isParsed;
@@ -123,24 +130,17 @@ QHostAddressPrivate::QHostAddressPrivate()
void QHostAddressPrivate::setAddress(quint32 a_)
{
a = a_;
+ protocol = QAbstractSocket::IPv4Protocol;
+ isParsed = true;
+
//create mapped address, except for a_ == 0 (any)
- memset(&a6, 0, sizeof(a6));
+ a6_64.c[0] = 0;
if (a) {
- a6[11] = 0xFF;
- a6[10] = 0xFF;
+ a6_32.c[2] = qToBigEndian(0xffff);
+ a6_32.c[3] = qToBigEndian(a);
} else {
- a6[11] = 0;
- a6[10] = 0;
+ a6_64.c[1] = 0;
}
-
- int i;
- for (i=15; a_ != 0; i--) {
- a6[i] = a_ & 0xFF;
- a_ >>=8;
- }
- Q_ASSERT(i >= 11);
- protocol = QAbstractSocket::IPv4Protocol;
- isParsed = true;
}
/// parses v4-mapped addresses or the AnyIPv6 address and stores in \a a;
@@ -163,21 +163,16 @@ static bool convertToIpv4(quint32& a, const Q_IPV6ADDR &a6)
void QHostAddressPrivate::setAddress(const quint8 *a_)
{
- for (int i = 0; i < 16; i++)
- a6[i] = a_[i];
- a = 0;
- convertToIpv4(a, a6);
protocol = QAbstractSocket::IPv6Protocol;
isParsed = true;
+ memcpy(a6.c, a_, sizeof(a6));
+ a = 0;
+ convertToIpv4(a, a6);
}
void QHostAddressPrivate::setAddress(const Q_IPV6ADDR &a_)
{
- a6 = a_;
- a = 0;
- convertToIpv4(a, a6);
- protocol = QAbstractSocket::IPv6Protocol;
- isParsed = true;
+ setAddress(a_.c);
}
static bool parseIp6(const QString &address, QIPAddressUtils::IPv6Address &addr, QString *scopeId)
@@ -193,7 +188,7 @@ static bool parseIp6(const QString &address, QIPAddressUtils::IPv6Address &addr,
return QIPAddressUtils::parseIp6(addr, tmp.constBegin(), tmp.constEnd()) == 0;
}
-bool QHostAddressPrivate::parse()
+Q_NEVER_INLINE bool QHostAddressPrivate::parse()
{
isParsed = true;
protocol = QAbstractSocket::UnknownNetworkLayerProtocol;
@@ -486,31 +481,35 @@ QHostAddress::QHostAddress(SpecialAddress address)
{
Q_IPV6ADDR ip6;
memset(&ip6, 0, sizeof ip6);
+ quint32 ip4 = INADDR_ANY;
switch (address) {
case Null:
- break;
+ return;
+
case Broadcast:
- d->setAddress(quint32(-1));
+ ip4 = INADDR_BROADCAST;
break;
case LocalHost:
- d->setAddress(0x7f000001);
- break;
- case LocalHostIPv6:
- ip6[15] = 1;
- d->setAddress(ip6);
+ ip4 = INADDR_LOOPBACK;
break;
case AnyIPv4:
- setAddress(0u);
break;
+
+ case LocalHostIPv6:
+ ip6[15] = 1;
+ // fall through
case AnyIPv6:
d->setAddress(ip6);
- break;
+ return;
+
case Any:
- d->clear();
d->protocol = QAbstractSocket::AnyIPProtocol;
- break;
+ return;
}
+
+ // common IPv4 part
+ d->setAddress(ip4);
}
/*!
@@ -775,11 +774,6 @@ QString QHostAddress::toString() const
on your host. Link-local addresses ("fe80...") are generated from the MAC
address of the local network adaptor, and are not guaranteed to be unique.
- \li Site-local: Addresses that are local to the site / private network
- (e.g., the company intranet). Site-local addresses ("fec0...") are
- usually distributed by the site router, and are not guaranteed to be
- unique outside of the local site.
-
\li Global: For globally routable addresses, such as public servers on the
Internet.
@@ -790,7 +784,7 @@ QString QHostAddress::toString() const
usually the same as the interface name (e.g., "eth0", "en1") or number
(e.g., "1", "2").
- \sa setScopeId()
+ \sa setScopeId(), QNetworkInterface, QNetworkInterface::interfaceFromName
*/
QString QHostAddress::scopeId() const
{
@@ -801,8 +795,14 @@ QString QHostAddress::scopeId() const
/*!
\since 4.1
- Sets the IPv6 scope ID of the address to \a id. If the address
- protocol is not IPv6, this function does nothing.
+ Sets the IPv6 scope ID of the address to \a id. If the address protocol is
+ not IPv6, this function does nothing. The scope ID may be set as an
+ interface name (such as "eth0" or "en1") or as an integer representing the
+ interface index. If \a id is an interface name, QtNetwork will convert to
+ an interface index using QNetworkInterface::interfaceIndexFromName() before
+ calling the operating system networking functions.
+
+ \sa scopeId(), QNetworkInterface, QNetworkInterface::interfaceFromName
*/
void QHostAddress::setScopeId(const QString &id)
{
@@ -836,34 +836,36 @@ bool QHostAddress::operator==(const QHostAddress &other) const
bool QHostAddress::operator ==(SpecialAddress other) const
{
QT_ENSURE_PARSED(this);
+ quint32 ip4 = INADDR_ANY;
switch (other) {
case Null:
return d->protocol == QAbstractSocket::UnknownNetworkLayerProtocol;
case Broadcast:
- return d->protocol == QAbstractSocket::IPv4Protocol && d->a == INADDR_BROADCAST;
+ ip4 = INADDR_BROADCAST;
+ break;
case LocalHost:
- return d->protocol == QAbstractSocket::IPv4Protocol && d->a == INADDR_LOOPBACK;
+ ip4 = INADDR_LOOPBACK;
+ break;
case Any:
return d->protocol == QAbstractSocket::AnyIPProtocol;
case AnyIPv4:
- return d->protocol == QAbstractSocket::IPv4Protocol && d->a == INADDR_ANY;
+ break;
case LocalHostIPv6:
case AnyIPv6:
if (d->protocol == QAbstractSocket::IPv6Protocol) {
- Q_IPV6ADDR ip6 = { { 0 } };
- ip6[15] = quint8(other == LocalHostIPv6); // 1 for localhost, 0 for any
- return memcmp(&d->a6, &ip6, sizeof ip6) == 0;
+ quint64 second = quint8(other == LocalHostIPv6); // 1 for localhost, 0 for any
+ return d->a6_64.c[0] == 0 && d->a6_64.c[1] == qToBigEndian(second);
}
return false;
}
- Q_UNREACHABLE();
- return false;
+ // common IPv4 part
+ return d->protocol == QAbstractSocket::IPv4Protocol && d->a == ip4;
}
/*!
@@ -1085,16 +1087,36 @@ bool QHostAddress::isLoopback() const
if ((d->a & 0xFF000000) == 0x7F000000)
return true; // v4 range (including IPv6 wrapped IPv4 addresses)
if (d->protocol == QAbstractSocket::IPv6Protocol) {
- if (d->a6.c[15] != 1)
+#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;
- for (int i = 0; i < 15; i++)
- if (d->a6[i] != 0)
- return false;
+#endif
return true;
}
return false;
}
+/*!
+ \since 5.6
+
+ Returns \c true if the address is an IPv4 or IPv6 multicast address, \c
+ false otherwise.
+*/
+bool QHostAddress::isMulticast() const
+{
+ QT_ENSURE_PARSED(this);
+ 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;
+}
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const QHostAddress &address)
{
@@ -1112,7 +1134,7 @@ uint qHash(const QHostAddress &key, uint seed)
{
// both lines might throw
QT_ENSURE_PARSED(&key);
- return qHash(QByteArray::fromRawData(reinterpret_cast<const char *>(key.d->a6.c), 16), seed);
+ return qHashBits(key.d->a6.c, 16, seed);
}
#ifndef QT_NO_DATASTREAM
diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h
index 8478240d28..9e3ee43d04 100644
--- a/src/network/kernel/qhostaddress.h
+++ b/src/network/kernel/qhostaddress.h
@@ -124,6 +124,7 @@ public:
bool isInSubnet(const QPair<QHostAddress, int> &subnet) const;
bool isLoopback() const;
+ bool isMulticast() const;
static QPair<QHostAddress, int> parseSubnet(const QString &subnet);
@@ -131,6 +132,7 @@ public:
protected:
QScopedPointer<QHostAddressPrivate> d;
};
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QHostAddress)
inline bool operator ==(QHostAddress::SpecialAddress address1, const QHostAddress &address2)
{ return address2 == address1; }
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp
index a2ac9065fd..c6c09542e7 100644
--- a/src/network/kernel/qhostinfo.cpp
+++ b/src/network/kernel/qhostinfo.cpp
@@ -415,10 +415,22 @@ void QHostInfo::setErrorString(const QString &str)
/*!
\fn QString QHostInfo::localHostName()
- Returns the host name of this machine.
+ Returns this machine's host name, if one is configured. Note that hostnames
+ are not guaranteed to be globally unique, especially if they were
+ configured automatically.
- \sa hostName()
+ This function does not guarantee the returned host name is a Fully
+ Qualified Domain Name (FQDN). For that, use fromName() to resolve the
+ returned name to an FQDN.
+
+ This function returns the same as QSysInfo::machineHostName().
+
+ \sa hostName(), localDomainName()
*/
+QString QHostInfo::localHostName()
+{
+ return QSysInfo::machineHostName();
+}
/*!
\fn QString QHostInfo::localDomainName()
diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp
index 90a6f763f7..266a67771c 100644
--- a/src/network/kernel/qhostinfo_unix.cpp
+++ b/src/network/kernel/qhostinfo_unix.cpp
@@ -315,15 +315,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
return results;
}
-QString QHostInfo::localHostName()
-{
- char hostName[512];
- if (gethostname(hostName, sizeof(hostName)) == -1)
- return QString();
- hostName[sizeof(hostName) - 1] = '\0';
- return QString::fromLocal8Bit(hostName);
-}
-
QString QHostInfo::localDomainName()
{
#if !defined(Q_OS_VXWORKS) && !defined(Q_OS_ANDROID)
diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp
index e044728198..da28cd48c1 100644
--- a/src/network/kernel/qhostinfo_win.cpp
+++ b/src/network/kernel/qhostinfo_win.cpp
@@ -111,7 +111,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
QMutexLocker locker(&qPrivCEMutex);
#endif
- QWindowsSockInit winSock;
+ QSysInfo::machineHostName(); // this initializes ws2_32.dll
// Load res_init on demand.
static QBasicAtomicInt triedResolve = Q_BASIC_ATOMIC_INITIALIZER(false);
@@ -136,7 +136,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
// Reverse lookup
if (local_getnameinfo) {
sockaddr_in sa4;
- qt_sockaddr_in6 sa6;
+ sockaddr_in6 sa6;
sockaddr *sa;
QT_SOCKLEN_T saSize;
if (address.protocol() == QAbstractSocket::IPv4Protocol) {
@@ -150,7 +150,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
saSize = sizeof(sa6);
memset(&sa6, 0, sizeof(sa6));
sa6.sin6_family = AF_INET6;
- memcpy(sa6.sin6_addr.qt_s6_addr, address.toIPv6Address().c, sizeof(sa6.sin6_addr.qt_s6_addr));
+ memcpy(&sa6.sin6_addr, address.toIPv6Address().c, sizeof(sa6.sin6_addr));
}
char hbuf[NI_MAXHOST];
@@ -197,7 +197,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
break;
case AF_INET6: {
QHostAddress addr;
- addr.setAddress(((qt_sockaddr_in6 *) p->ai_addr)->sin6_addr.qt_s6_addr);
+ addr.setAddress(((sockaddr_in6 *) p->ai_addr)->sin6_addr.s6_addr);
if (!addresses.contains(addr))
addresses.append(addr);
}
@@ -256,17 +256,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
return results;
}
-QString QHostInfo::localHostName()
-{
- QWindowsSockInit winSock;
-
- char hostName[512];
- if (gethostname(hostName, sizeof(hostName)) == -1)
- return QString();
- hostName[sizeof(hostName) - 1] = '\0';
- return QString::fromLocal8Bit(hostName);
-}
-
// QString QHostInfo::localDomainName() defined in qnetworkinterface_win.cpp
QT_END_NAMESPACE
diff --git a/src/network/kernel/qhostinfo_winrt.cpp b/src/network/kernel/qhostinfo_winrt.cpp
index 1a97fe0e40..3d2344726b 100644
--- a/src/network/kernel/qhostinfo_winrt.cpp
+++ b/src/network/kernel/qhostinfo_winrt.cpp
@@ -130,45 +130,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
return results;
}
-QString QHostInfo::localHostName()
-{
- ComPtr<INetworkInformationStatics> statics;
- GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &statics);
-
- ComPtr<IVectorView<HostName *>> hostNames;
- statics->GetHostNames(&hostNames);
- if (!hostNames)
- return QString();
-
- unsigned int size;
- hostNames->get_Size(&size);
- if (size == 0)
- return QString();
-
- for (unsigned int i = 0; i < size; ++i) {
- ComPtr<IHostName> hostName;
- hostNames->GetAt(i, &hostName);
- HostNameType type;
- hostName->get_Type(&type);
- if (type != HostNameType_DomainName)
- continue;
-
- HString name;
- hostName->get_CanonicalName(name.GetAddressOf());
- UINT32 length;
- PCWSTR rawString = name.GetRawBuffer(&length);
- return QString::fromWCharArray(rawString, length);
- }
- ComPtr<IHostName> firstHost;
- hostNames->GetAt(0, &firstHost);
-
- HString name;
- firstHost->get_CanonicalName(name.GetAddressOf());
- UINT32 length;
- PCWSTR rawString = name.GetRawBuffer(&length);
- return QString::fromWCharArray(rawString, length);
-}
-
// QString QHostInfo::localDomainName() defined in qnetworkinterface_win.cpp
QT_END_NAMESPACE
diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp
index 2fbbf56e0f..4a527052d1 100644
--- a/src/network/kernel/qnetworkinterface.cpp
+++ b/src/network/kernel/qnetworkinterface.cpp
@@ -86,9 +86,16 @@ QSharedDataPointer<QNetworkInterfacePrivate> QNetworkInterfaceManager::interface
{
QList<QSharedDataPointer<QNetworkInterfacePrivate> > interfaceList = allInterfaces();
QList<QSharedDataPointer<QNetworkInterfacePrivate> >::ConstIterator it = interfaceList.constBegin();
- for ( ; it != interfaceList.constEnd(); ++it)
- if ((*it)->name == name)
+
+ 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;
+ }
return empty;
}
@@ -516,6 +523,9 @@ QList<QNetworkAddressEntry> QNetworkInterface::addressEntries() const
name. If no such interface exists, this function returns an
invalid QNetworkInterface object.
+ The string \a name may be either an actual interface name (such as "eth0"
+ or "en1") or an interface index in string form ("1", "2", etc.).
+
\sa name(), isValid()
*/
QNetworkInterface QNetworkInterface::interfaceFromName(const QString &name)
diff --git a/src/network/kernel/qnetworkinterface.h b/src/network/kernel/qnetworkinterface.h
index 31d3b7b128..b3daa3d4a0 100644
--- a/src/network/kernel/qnetworkinterface.h
+++ b/src/network/kernel/qnetworkinterface.h
@@ -133,6 +133,9 @@ Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QNetworkInterface &networ
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QNetworkAddressEntry)
+Q_DECLARE_METATYPE(QNetworkInterface)
+
#endif // QT_NO_NETWORKINTERFACE
#endif
diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp
index 9c5ba4e799..cc53087024 100644
--- a/src/network/kernel/qnetworkinterface_unix.cpp
+++ b/src/network/kernel/qnetworkinterface_unix.cpp
@@ -127,14 +127,13 @@ static QNetworkInterface::InterfaceFlags convertFlags(uint rawFlags)
#ifdef QT_NO_GETIFADDRS
// getifaddrs not available
-static const int STORAGEBUFFER_GROWTH = 256;
-
static QSet<QByteArray> interfaceNames(int socket)
{
QSet<QByteArray> result;
#ifdef QT_NO_IPV6IFNAME
QByteArray storageBuffer;
struct ifconf interfaceList;
+ static const int STORAGEBUFFER_GROWTH = 256;
forever {
// grow the storage buffer
@@ -186,9 +185,14 @@ static QNetworkInterfacePrivate *findInterface(int socket, QList<QNetworkInterfa
QNetworkInterfacePrivate *iface = 0;
int ifindex = 0;
-#ifndef QT_NO_IPV6IFNAME
+#if !defined(QT_NO_IPV6IFNAME) || defined(SIOCGIFINDEX)
// Get the interface index
+# ifdef SIOCGIFINDEX
+ if (qt_safe_ioctl(socket, SIOCGIFINDEX, &req) >= 0)
+ ifindex = req.ifr_ifindex;
+# else
ifindex = if_nametoindex(req.ifr_name);
+# endif
// find the interface data
QList<QNetworkInterfacePrivate *>::Iterator if_it = interfaces.begin();
@@ -214,6 +218,27 @@ static QNetworkInterfacePrivate *findInterface(int socket, QList<QNetworkInterfa
iface = new QNetworkInterfacePrivate;
iface->index = ifindex;
interfaces << iface;
+ }
+
+ return iface;
+}
+
+static QList<QNetworkInterfacePrivate *> interfaceListing()
+{
+ QList<QNetworkInterfacePrivate *> interfaces;
+
+ int socket;
+ if ((socket = qt_safe_socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1)
+ return interfaces; // error
+
+ QSet<QByteArray> names = interfaceNames(socket);
+ QSet<QByteArray>::ConstIterator it = names.constBegin();
+ for ( ; it != names.constEnd(); ++it) {
+ ifreq req;
+ memset(&req, 0, sizeof(ifreq));
+ memcpy(req.ifr_name, *it, qMin<int>(it->length() + 1, sizeof(req.ifr_name) - 1));
+
+ QNetworkInterfacePrivate *iface = findInterface(socket, interfaces, req);
#ifdef SIOCGIFNAME
// Get the canonical name
@@ -242,27 +267,6 @@ static QNetworkInterfacePrivate *findInterface(int socket, QList<QNetworkInterfa
iface->hardwareAddress = iface->makeHwAddress(6, addr);
}
#endif
- }
-
- return iface;
-}
-
-static QList<QNetworkInterfacePrivate *> interfaceListing()
-{
- QList<QNetworkInterfacePrivate *> interfaces;
-
- int socket;
- if ((socket = qt_safe_socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1)
- return interfaces; // error
-
- QSet<QByteArray> names = interfaceNames(socket);
- QSet<QByteArray>::ConstIterator it = names.constBegin();
- for ( ; it != names.constEnd(); ++it) {
- ifreq req;
- memset(&req, 0, sizeof(ifreq));
- memcpy(req.ifr_name, *it, qMin<int>(it->length() + 1, sizeof(req.ifr_name) - 1));
-
- QNetworkInterfacePrivate *iface = findInterface(socket, interfaces, req);
// Get the interface broadcast address
QNetworkAddressEntry entry;
diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp
index ddeb6c111f..907638f73e 100644
--- a/src/network/kernel/qnetworkinterface_win.cpp
+++ b/src/network/kernel/qnetworkinterface_win.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Intel Corporation.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -31,7 +32,7 @@
**
****************************************************************************/
-#include "qnetworkinterface_win_p.h"
+#define WIN32_LEAN_AND_MEAN 1
#include "qnetworkinterface.h"
#include "qnetworkinterface_p.h"
@@ -41,16 +42,23 @@
#include <qhostinfo.h>
#include <qhash.h>
#include <qurl.h>
-#include <private/qsystemlibrary_p.h>
+
+// Since we need to include winsock2.h, we need to define WIN32_LEAN_AND_MEAN
+// (above) so windows.h won't include winsock.h.
+// In addition, we need to include winsock2.h before iphlpapi.h and we need
+// to include ws2ipdef.h to work around an MinGW-w64 bug
+// (http://sourceforge.net/p/mingw-w64/mailman/message/32935366/)
+#include <winsock2.h>
+#include <ws2ipdef.h>
+#include <iphlpapi.h>
+#include <ws2tcpip.h>
+
+#include <qt_windows.h>
QT_BEGIN_NAMESPACE
-typedef DWORD (WINAPI *PtrGetAdaptersInfo)(PIP_ADAPTER_INFO, PULONG);
-static PtrGetAdaptersInfo ptrGetAdaptersInfo = 0;
-typedef ULONG (WINAPI *PtrGetAdaptersAddresses)(ULONG, ULONG, PVOID, PIP_ADAPTER_ADDRESSES, PULONG);
-static PtrGetAdaptersAddresses ptrGetAdaptersAddresses = 0;
-typedef DWORD (WINAPI *PtrGetNetworkParams)(PFIXED_INFO, PULONG);
-static PtrGetNetworkParams ptrGetNetworkParams = 0;
+typedef NETIO_STATUS (WINAPI *PtrConvertInterfaceLuidToName)(const NET_LUID *, PWSTR, SIZE_T);
+static PtrConvertInterfaceLuidToName ptrConvertInterfaceLuidToName = 0;
static void resolveLibs()
{
@@ -58,21 +66,17 @@ static void resolveLibs()
static bool done = false;
if (!done) {
- done = true;
-
- HINSTANCE iphlpapiHnd = QSystemLibrary::load(L"iphlpapi");
- if (iphlpapiHnd == NULL)
- return;
+ HINSTANCE iphlpapiHnd = GetModuleHandle(L"iphlpapi");
+ Q_ASSERT(iphlpapiHnd);
#if defined(Q_OS_WINCE)
- ptrGetAdaptersInfo = (PtrGetAdaptersInfo)GetProcAddress(iphlpapiHnd, L"GetAdaptersInfo");
- ptrGetAdaptersAddresses = (PtrGetAdaptersAddresses)GetProcAddress(iphlpapiHnd, L"GetAdaptersAddresses");
- ptrGetNetworkParams = (PtrGetNetworkParams)GetProcAddress(iphlpapiHnd, L"GetNetworkParams");
+ // since Windows Embedded Compact 7
+ ptrConvertInterfaceLuidToName = (PtrConvertInterfaceLuidToName)GetProcAddress(iphlpapiHnd, L"ConvertInterfaceLuidToNameW");
#else
- ptrGetAdaptersInfo = (PtrGetAdaptersInfo)GetProcAddress(iphlpapiHnd, "GetAdaptersInfo");
- ptrGetAdaptersAddresses = (PtrGetAdaptersAddresses)GetProcAddress(iphlpapiHnd, "GetAdaptersAddresses");
- ptrGetNetworkParams = (PtrGetNetworkParams)GetProcAddress(iphlpapiHnd, "GetNetworkParams");
+ // since Windows Vista
+ ptrConvertInterfaceLuidToName = (PtrConvertInterfaceLuidToName)GetProcAddress(iphlpapiHnd, "ConvertInterfaceLuidToNameW");
#endif
+ done = true;
}
}
@@ -85,8 +89,8 @@ static QHostAddress addressFromSockaddr(sockaddr *sa)
if (sa->sa_family == AF_INET)
address.setAddress(htonl(((sockaddr_in *)sa)->sin_addr.s_addr));
else if (sa->sa_family == AF_INET6) {
- address.setAddress(((qt_sockaddr_in6 *)sa)->sin6_addr.qt_s6_addr);
- int scope = ((qt_sockaddr_in6 *)sa)->sin6_scope_id;
+ address.setAddress(((sockaddr_in6 *)sa)->sin6_addr.s6_addr);
+ int scope = ((sockaddr_in6 *)sa)->sin6_scope_id;
if (scope)
address.setScopeId(QString::number(scope));
} else
@@ -103,14 +107,14 @@ static QHash<QHostAddress, QHostAddress> ipv4Netmasks()
ULONG bufSize = sizeof staticBuf;
QHash<QHostAddress, QHostAddress> ipv4netmasks;
- DWORD retval = ptrGetAdaptersInfo(pAdapter, &bufSize);
+ DWORD retval = GetAdaptersInfo(pAdapter, &bufSize);
if (retval == ERROR_BUFFER_OVERFLOW) {
// need more memory
pAdapter = (IP_ADAPTER_INFO *)malloc(bufSize);
if (!pAdapter)
return ipv4netmasks;
// try again
- if (ptrGetAdaptersInfo(pAdapter, &bufSize) != ERROR_SUCCESS) {
+ if (GetAdaptersInfo(pAdapter, &bufSize) != ERROR_SUCCESS) {
free(pAdapter);
return ipv4netmasks;
}
@@ -145,14 +149,14 @@ static QList<QNetworkInterfacePrivate *> interfaceListingWinXP()
ULONG flags = GAA_FLAG_INCLUDE_PREFIX |
GAA_FLAG_SKIP_DNS_SERVER |
GAA_FLAG_SKIP_MULTICAST;
- ULONG retval = ptrGetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapter, &bufSize);
+ ULONG retval = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapter, &bufSize);
if (retval == ERROR_BUFFER_OVERFLOW) {
// need more memory
pAdapter = (IP_ADAPTER_ADDRESSES *)malloc(bufSize);
if (!pAdapter)
return interfaces;
// try again
- if (ptrGetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapter, &bufSize) != ERROR_SUCCESS) {
+ if (GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapter, &bufSize) != ERROR_SUCCESS) {
free(pAdapter);
return interfaces;
}
@@ -180,7 +184,16 @@ static QList<QNetworkInterfacePrivate *> interfaceListingWinXP()
if (ptr->IfType == IF_TYPE_PPP)
iface->flags |= QNetworkInterface::IsPointToPoint;
- iface->name = QString::fromLocal8Bit(ptr->AdapterName);
+ if (ptrConvertInterfaceLuidToName && ptr->Length >= offsetof(IP_ADAPTER_ADDRESSES, Luid)) {
+ // use ConvertInterfaceLuidToName because that returns a friendlier name, though not
+ // as friendly as FriendlyName below
+ WCHAR buf[IF_MAX_STRING_SIZE + 1];
+ if (ptrConvertInterfaceLuidToName(&ptr->Luid, buf, sizeof(buf)/sizeof(buf[0])) == NO_ERROR)
+ iface->name = QString::fromWCharArray(buf);
+ }
+ if (iface->name.isEmpty())
+ iface->name = QString::fromLocal8Bit(ptr->AdapterName);
+
iface->friendlyName = QString::fromWCharArray(ptr->FriendlyName);
if (ptr->PhysicalAddressLength)
iface->hardwareAddress = iface->makeHwAddress(ptr->PhysicalAddressLength,
@@ -221,92 +234,25 @@ static QList<QNetworkInterfacePrivate *> interfaceListingWinXP()
return interfaces;
}
-static QList<QNetworkInterfacePrivate *> interfaceListingWin2k()
-{
- QList<QNetworkInterfacePrivate *> interfaces;
- IP_ADAPTER_INFO staticBuf[2]; // 2 is arbitrary
- PIP_ADAPTER_INFO pAdapter = staticBuf;
- ULONG bufSize = sizeof staticBuf;
-
- DWORD retval = ptrGetAdaptersInfo(pAdapter, &bufSize);
- if (retval == ERROR_BUFFER_OVERFLOW) {
- // need more memory
- pAdapter = (IP_ADAPTER_INFO *)malloc(bufSize);
- if (!pAdapter)
- return interfaces;
- // try again
- if (ptrGetAdaptersInfo(pAdapter, &bufSize) != ERROR_SUCCESS) {
- free(pAdapter);
- return interfaces;
- }
- } else if (retval != ERROR_SUCCESS) {
- // error
- return interfaces;
- }
-
- // iterate over the list and add the entries to our listing
- for (PIP_ADAPTER_INFO ptr = pAdapter; ptr; ptr = ptr->Next) {
- QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;
- interfaces << iface;
-
- iface->index = ptr->Index;
- iface->flags = QNetworkInterface::IsUp | QNetworkInterface::IsRunning;
- if (ptr->Type == MIB_IF_TYPE_PPP)
- iface->flags |= QNetworkInterface::IsPointToPoint;
- else
- iface->flags |= QNetworkInterface::CanBroadcast;
- iface->name = QString::fromLocal8Bit(ptr->AdapterName);
- iface->hardwareAddress = QNetworkInterfacePrivate::makeHwAddress(ptr->AddressLength,
- ptr->Address);
-
- for (PIP_ADDR_STRING addr = &ptr->IpAddressList; addr; addr = addr->Next) {
- QNetworkAddressEntry entry;
- entry.setIp(QHostAddress(QLatin1String(addr->IpAddress.String)));
- entry.setNetmask(QHostAddress(QLatin1String(addr->IpMask.String)));
- // broadcast address is set on postProcess()
-
- iface->addressEntries << entry;
- }
- }
-
- if (pAdapter != staticBuf)
- free(pAdapter);
-
- return interfaces;
-}
-
-static QList<QNetworkInterfacePrivate *> interfaceListing()
-{
- resolveLibs();
- if (ptrGetAdaptersAddresses != NULL)
- return interfaceListingWinXP();
- else if (ptrGetAdaptersInfo != NULL)
- return interfaceListingWin2k();
-
- // failed
- return QList<QNetworkInterfacePrivate *>();
-}
-
QList<QNetworkInterfacePrivate *> QNetworkInterfaceManager::scan()
{
- return interfaceListing();
+ resolveLibs();
+ return interfaceListingWinXP();
}
QString QHostInfo::localDomainName()
{
resolveLibs();
- if (ptrGetNetworkParams == NULL)
- return QString(); // couldn't resolve
FIXED_INFO info, *pinfo;
ULONG bufSize = sizeof info;
pinfo = &info;
- if (ptrGetNetworkParams(pinfo, &bufSize) == ERROR_BUFFER_OVERFLOW) {
+ if (GetNetworkParams(pinfo, &bufSize) == ERROR_BUFFER_OVERFLOW) {
pinfo = (FIXED_INFO *)malloc(bufSize);
if (!pinfo)
return QString();
// try again
- if (ptrGetNetworkParams(pinfo, &bufSize) != ERROR_SUCCESS) {
+ if (GetNetworkParams(pinfo, &bufSize) != ERROR_SUCCESS) {
free(pinfo);
return QString(); // error
}
diff --git a/src/network/kernel/qnetworkinterface_win_p.h b/src/network/kernel/qnetworkinterface_win_p.h
deleted file mode 100644
index 88c1945fe6..0000000000
--- a/src/network/kernel/qnetworkinterface_win_p.h
+++ /dev/null
@@ -1,262 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtNetwork module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://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 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QNETWORKINTERFACE_WIN_P_H
-#define QNETWORKINTERFACE_WIN_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-#include <winsock2.h>
-#include <qt_windows.h>
-#include <time.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef GAA_FLAG_INCLUDE_ALL_INTERFACES
-# define GAA_FLAG_INCLUDE_ALL_INTERFACES 0x0100
-#endif
-#ifndef MAX_ADAPTER_ADDRESS_LENGTH
-// definitions from iptypes.h
-# define MAX_ADAPTER_DESCRIPTION_LENGTH 128 // arb.
-# define MAX_ADAPTER_NAME_LENGTH 256 // arb.
-# define MAX_ADAPTER_ADDRESS_LENGTH 8 // arb.
-# define DEFAULT_MINIMUM_ENTITIES 32 // arb.
-# define MAX_HOSTNAME_LEN 128 // arb.
-# define MAX_DOMAIN_NAME_LEN 128 // arb.
-# define MAX_SCOPE_ID_LEN 256 // arb.
-
-# define GAA_FLAG_SKIP_UNICAST 0x0001
-# define GAA_FLAG_SKIP_ANYCAST 0x0002
-# define GAA_FLAG_SKIP_MULTICAST 0x0004
-# define GAA_FLAG_SKIP_DNS_SERVER 0x0008
-# define GAA_FLAG_INCLUDE_PREFIX 0x0010
-# define GAA_FLAG_SKIP_FRIENDLY_NAME 0x0020
-
-# define IP_ADAPTER_DDNS_ENABLED 0x01
-# define IP_ADAPTER_REGISTER_ADAPTER_SUFFIX 0x02
-# define IP_ADAPTER_DHCP_ENABLED 0x04
-# define IP_ADAPTER_RECEIVE_ONLY 0x08
-# define IP_ADAPTER_NO_MULTICAST 0x10
-# define IP_ADAPTER_IPV6_OTHER_STATEFUL_CONFIG 0x20
-
-# define MIB_IF_TYPE_OTHER 1
-# define MIB_IF_TYPE_ETHERNET 6
-# define MIB_IF_TYPE_TOKENRING 9
-# define MIB_IF_TYPE_FDDI 15
-# define MIB_IF_TYPE_PPP 23
-# define MIB_IF_TYPE_LOOPBACK 24
-# define MIB_IF_TYPE_SLIP 28
-
-// definitions from Ipifcons.h
-#define IF_TYPE_PPP 23
-
-#endif
-// copied from qnativesocketengine_win.cpp
-struct qt_in6_addr {
- u_char qt_s6_addr[16];
-};
-typedef struct {
- short sin6_family; /* AF_INET6 */
- u_short sin6_port; /* Transport level port number */
- u_long sin6_flowinfo; /* IPv6 flow information */
- struct qt_in6_addr sin6_addr; /* IPv6 address */
- u_long sin6_scope_id; /* set of interfaces for a scope */
-} qt_sockaddr_in6;
-
-// copied from MSDN online help
-typedef enum {
- IpPrefixOriginOther = 0,
- IpPrefixOriginManual,
- IpPrefixOriginWellKnown,
- IpPrefixOriginDhcp,
- IpPrefixOriginRouterAdvertisement
-} IP_PREFIX_ORIGIN;
-
-typedef enum {
- IpSuffixOriginOther = 0,
- IpSuffixOriginManual,
- IpSuffixOriginWellKnown,
- IpSuffixOriginDhcp,
- IpSuffixOriginLinkLayerAddress,
- IpSuffixOriginRandom
-} IP_SUFFIX_ORIGIN;
-
-typedef enum {
- IpDadStateInvalid = 0,
- IpDadStateTentative,
- IpDadStateDuplicate,
- IpDadStateDeprecated,
- IpDadStatePreferred,
-} IP_DAD_STATE;
-
-typedef enum {
- IfOperStatusUp = 1,
- IfOperStatusDown,
- IfOperStatusTesting,
- IfOperStatusUnknown,
- IfOperStatusDormant,
- IfOperStatusNotPresent,
- IfOperStatusLowerLayerDown
-} IF_OPER_STATUS;
-
-typedef struct _IP_ADAPTER_UNICAST_ADDRESS {
- union {
- ULONGLONG Alignment;
- struct {
- ULONG Length;
- DWORD Flags;
- };
- };
- struct _IP_ADAPTER_UNICAST_ADDRESS* Next;
- SOCKET_ADDRESS Address;
- IP_PREFIX_ORIGIN PrefixOrigin;
- IP_SUFFIX_ORIGIN SuffixOrigin;
- IP_DAD_STATE DadState;
- ULONG ValidLifetime;
- ULONG PreferredLifetime;
- ULONG LeaseLifetime;
-} IP_ADAPTER_UNICAST_ADDRESS, *PIP_ADAPTER_UNICAST_ADDRESS;
-
-typedef struct _IP_ADAPTER_ANYCAST_ADDRESS
- IP_ADAPTER_ANYCAST_ADDRESS, *PIP_ADAPTER_ANYCAST_ADDRESS;
-
-typedef struct _IP_ADAPTER_MULTICAST_ADDRESS
- IP_ADAPTER_MULTICAST_ADDRESS,
- *PIP_ADAPTER_MULTICAST_ADDRESS;
-
-typedef struct _IP_ADAPTER_DNS_SERVER_ADDRESS
- IP_ADAPTER_DNS_SERVER_ADDRESS,
- *PIP_ADAPTER_DNS_SERVER_ADDRESS;
-
-typedef struct _IP_ADAPTER_PREFIX {
- union {
- ULONGLONG Alignment;
- struct {
- ULONG Length;
- DWORD Flags;
- };
- };
- struct _IP_ADAPTER_PREFIX* Next;
- SOCKET_ADDRESS Address;
- ULONG PrefixLength;
-} IP_ADAPTER_PREFIX,
- *PIP_ADAPTER_PREFIX;
-
-typedef struct _IP_ADAPTER_ADDRESSES {
- union {
- ULONGLONG Alignment;
- struct {
- ULONG Length;
- DWORD IfIndex;
- };
- };
- struct _IP_ADAPTER_ADDRESSES* Next;
- PCHAR AdapterName;
- PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress;
- PIP_ADAPTER_ANYCAST_ADDRESS FirstAnycastAddress;
- PIP_ADAPTER_MULTICAST_ADDRESS FirstMulticastAddress;
- PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress;
- PWCHAR DnsSuffix;
- PWCHAR Description;
- PWCHAR FriendlyName;
- BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH];
- DWORD PhysicalAddressLength;
- DWORD Flags;
- DWORD Mtu;
- DWORD IfType;
- IF_OPER_STATUS OperStatus;
- DWORD Ipv6IfIndex;
- DWORD ZoneIndices[16];
- PIP_ADAPTER_PREFIX FirstPrefix;
-} IP_ADAPTER_ADDRESSES,
- *PIP_ADAPTER_ADDRESSES;
-
-typedef struct {
- char String[4 * 4];
-} IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
-
-typedef struct _IP_ADDR_STRING {
- struct _IP_ADDR_STRING* Next;
- IP_ADDRESS_STRING IpAddress;
- IP_MASK_STRING IpMask;
- DWORD Context;
-} IP_ADDR_STRING,
- *PIP_ADDR_STRING;
-
-typedef struct _IP_ADAPTER_INFO {
- struct _IP_ADAPTER_INFO* Next;
- DWORD ComboIndex;
- char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
- char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
- UINT AddressLength;
- BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];
- DWORD Index;
- UINT Type;
- UINT DhcpEnabled;
- PIP_ADDR_STRING CurrentIpAddress;
- IP_ADDR_STRING IpAddressList;
- IP_ADDR_STRING GatewayList;
- IP_ADDR_STRING DhcpServer;
- BOOL HaveWins;
- IP_ADDR_STRING PrimaryWinsServer;
- IP_ADDR_STRING SecondaryWinsServer;
- time_t LeaseObtained;
- time_t LeaseExpires;
-} IP_ADAPTER_INFO,
- *PIP_ADAPTER_INFO;
-
-typedef struct {
- char HostName[MAX_HOSTNAME_LEN + 4];
- char DomainName[MAX_DOMAIN_NAME_LEN + 4];
- PIP_ADDR_STRING CurrentDnsServer;
- IP_ADDR_STRING DnsServerList;
- UINT NodeType;
- char ScopeId[MAX_SCOPE_ID_LEN + 4];
- UINT EnableRouting;
- UINT EnableProxy;
- UINT EnableDns;
-} FIXED_INFO, *PFIXED_INFO;
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp
index 51400f55bb..05d4c6955a 100644
--- a/src/network/kernel/qnetworkproxy_mac.cpp
+++ b/src/network/kernel/qnetworkproxy_mac.cpp
@@ -35,6 +35,7 @@
#ifndef QT_NO_NETWORKPROXY
+#include <CFNetwork/CFNetwork.h>
#include <CoreFoundation/CoreFoundation.h>
#include <SystemConfiguration/SystemConfiguration.h>