diff options
Diffstat (limited to 'src/network/kernel')
-rw-r--r-- | src/network/kernel/kernel.pri | 5 | ||||
-rw-r--r-- | src/network/kernel/qhostaddress.cpp | 136 | ||||
-rw-r--r-- | src/network/kernel/qhostaddress.h | 2 | ||||
-rw-r--r-- | src/network/kernel/qhostinfo.cpp | 16 | ||||
-rw-r--r-- | src/network/kernel/qhostinfo_unix.cpp | 9 | ||||
-rw-r--r-- | src/network/kernel/qhostinfo_win.cpp | 19 | ||||
-rw-r--r-- | src/network/kernel/qhostinfo_winrt.cpp | 39 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface.cpp | 14 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface.h | 3 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface_unix.cpp | 52 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface_win.cpp | 140 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface_win_p.h | 262 | ||||
-rw-r--r-- | src/network/kernel/qnetworkproxy_mac.cpp | 1 |
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> |