diff options
Diffstat (limited to 'src/network/kernel')
-rw-r--r-- | src/network/kernel/kernel.pri | 11 | ||||
-rw-r--r-- | src/network/kernel/qhostaddress.cpp | 114 | ||||
-rw-r--r-- | src/network/kernel/qhostaddress_p.h | 27 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface.cpp | 4 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface_p.h | 2 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface_win.cpp | 91 | ||||
-rw-r--r-- | src/network/kernel/qnetworkproxy.cpp | 10 | ||||
-rw-r--r-- | src/network/kernel/qurlinfo.cpp | 4 | ||||
-rw-r--r-- | src/network/kernel/qurlinfo_p.h | 7 |
9 files changed, 92 insertions, 178 deletions
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index ac6bebbfae..716f745bc9 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -17,8 +17,7 @@ HEADERS += kernel/qtnetworkglobal.h \ kernel/qnetworkdatagram_p.h \ kernel/qnetworkinterface.h \ kernel/qnetworkinterface_p.h \ - kernel/qnetworkproxy.h \ - kernel/qurlinfo_p.h + kernel/qnetworkproxy.h SOURCES += kernel/qauthenticator.cpp \ kernel/qdnslookup.cpp \ @@ -26,8 +25,12 @@ SOURCES += kernel/qauthenticator.cpp \ kernel/qhostinfo.cpp \ kernel/qnetworkdatagram.cpp \ kernel/qnetworkinterface.cpp \ - kernel/qnetworkproxy.cpp \ - kernel/qurlinfo.cpp + kernel/qnetworkproxy.cpp + +qtConfig(ftp) { + HEADERS += kernel/qurlinfo_p.h + SOURCES += kernel/qurlinfo.cpp +} unix { !integrity: SOURCES += kernel/qdnslookup_unix.cpp diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index 7d8de71421..4f4c674d20 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -44,6 +44,7 @@ #include "qdebug.h" #if defined(Q_OS_WIN) # include <winsock2.h> +# include <ws2tcpip.h> #else # include <netinet/in.h> #endif @@ -63,36 +64,6 @@ QT_BEGIN_NAMESPACE -#ifdef Q_OS_WIN -// sockaddr_in6 size changed between old and new SDK -// Only the new version is the correct one, so always -// use this structure. -#if defined(Q_OS_WINRT) -# if !defined(u_char) -# define u_char unsigned char -# endif -# if !defined(u_short) -# define u_short unsigned short -# endif -# if !defined(u_long) -# define u_long unsigned long -# endif -#endif -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; -#else -#define qt_sockaddr_in6 sockaddr_in6 -#define qt_s6_addr s6_addr -#endif - class QHostAddressPrivate : public QSharedData { @@ -235,18 +206,8 @@ void QHostAddressPrivate::clear() } -bool QNetmaskAddress::setAddress(const QString &address) -{ - d.detach(); - length = -1; - QHostAddress other; - return other.setAddress(address) && setAddress(other); -} - -bool QNetmaskAddress::setAddress(const QHostAddress &address) +bool QNetmask::setAddress(const QHostAddress &address) { - d.detach(); - static const quint8 zeroes[16] = { 0 }; union { quint32 v4; @@ -258,16 +219,13 @@ bool QNetmaskAddress::setAddress(const QHostAddress &address) quint8 *end; length = -1; - QHostAddress::operator=(address); - - if (d->protocol == QAbstractSocket::IPv4Protocol) { - ip.v4 = qToBigEndian(d->a); + if (address.protocol() == QAbstractSocket::IPv4Protocol) { + ip.v4 = qToBigEndian(address.toIPv4Address()); end = ptr + 4; - } else if (d->protocol == QAbstractSocket::IPv6Protocol) { - memcpy(ip.v6, d->a6.c, 16); + } else if (address.protocol() == QAbstractSocket::IPv6Protocol) { + memcpy(ip.v6, address.toIPv6Address().c, 16); end = ptr + 16; } else { - d->clear(); return false; } @@ -279,7 +237,6 @@ bool QNetmaskAddress::setAddress(const QHostAddress &address) continue; default: - d->clear(); return false; // invalid IP-style netmask case 254: @@ -310,10 +267,8 @@ bool QNetmaskAddress::setAddress(const QHostAddress &address) } // confirm that the rest is only zeroes - if (ptr < end && memcmp(ptr + 1, zeroes, end - ptr - 1) != 0) { - d->clear(); + if (ptr < end && memcmp(ptr + 1, zeroes, end - ptr - 1) != 0) return false; - } length = netmask; return true; @@ -333,35 +288,25 @@ static void clearBits(quint8 *where, int start, int end) memset(where + (start + 7) / 8, 0, end / 8 - (start + 7) / 8); } -int QNetmaskAddress::prefixLength() const +QHostAddress QNetmask::address(QAbstractSocket::NetworkLayerProtocol protocol) const { - return length; -} - -void QNetmaskAddress::setPrefixLength(QAbstractSocket::NetworkLayerProtocol proto, int newLength) -{ - d.detach(); - length = newLength; - if (length < 0 || length > (proto == QAbstractSocket::IPv4Protocol ? 32 : - proto == QAbstractSocket::IPv6Protocol ? 128 : -1)) { - // invalid information, reject - d->protocol = QAbstractSocket::UnknownNetworkLayerProtocol; - length = -1; - return; - } - - d->protocol = proto; - if (d->protocol == QAbstractSocket::IPv4Protocol) { - if (length == 0) { - d->a = 0; - } else if (length == 32) { - d->a = quint32(0xffffffff); - } else { - d->a = quint32(0xffffffff) >> (32 - length) << (32 - length); - } + if (length == 255 || protocol == QAbstractSocket::AnyIPProtocol || + protocol == QAbstractSocket::UnknownNetworkLayerProtocol) { + return QHostAddress(); + } else if (protocol == QAbstractSocket::IPv4Protocol) { + quint32 a; + if (length == 0) + a = 0; + else if (length == 32) + a = quint32(0xffffffff); + else + a = quint32(0xffffffff) >> (32 - length) << (32 - length); + return QHostAddress(a); } else { - memset(d->a6.c, 0xFF, sizeof(d->a6)); - clearBits(d->a6.c, length, 128); + Q_IPV6ADDR a6; + memset(a6.c, 0xFF, sizeof(a6)); + clearBits(a6.c, length, 128); + return QHostAddress(a6); } } @@ -495,7 +440,7 @@ QHostAddress::QHostAddress(const struct sockaddr *sockaddr) if (sockaddr->sa_family == AF_INET) setAddress(htonl(((const sockaddr_in *)sockaddr)->sin_addr.s_addr)); else if (sockaddr->sa_family == AF_INET6) - setAddress(((const qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr); + setAddress(((const sockaddr_in6 *)sockaddr)->sin6_addr.s6_addr); #else Q_UNUSED(sockaddr) #endif @@ -718,7 +663,7 @@ void QHostAddress::setAddress(const struct sockaddr *sockaddr) if (sockaddr->sa_family == AF_INET) setAddress(htonl(((const sockaddr_in *)sockaddr)->sin_addr.s_addr)); else if (sockaddr->sa_family == AF_INET6) - setAddress(((const qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr); + setAddress(((const sockaddr_in6 *)sockaddr)->sin6_addr.s6_addr); #else Q_UNUSED(sockaddr) #endif @@ -1133,8 +1078,11 @@ QPair<QHostAddress, int> QHostAddress::parseSubnet(const QString &subnet) // is the netmask given in IP-form or in bit-count form? if (!isIpv6 && subnet.indexOf(QLatin1Char('.'), slash + 1) != -1) { // IP-style, convert it to bit-count form - QNetmaskAddress parser; - if (!parser.setAddress(subnet.mid(slash + 1))) + QHostAddress mask; + QNetmask parser; + if (!mask.setAddress(subnet.mid(slash + 1))) + return invalid; + if (!parser.setAddress(mask)) return invalid; netmask = parser.prefixLength(); } else { diff --git a/src/network/kernel/qhostaddress_p.h b/src/network/kernel/qhostaddress_p.h index 55c3e5afde..5106760ed9 100644 --- a/src/network/kernel/qhostaddress_p.h +++ b/src/network/kernel/qhostaddress_p.h @@ -57,17 +57,32 @@ QT_BEGIN_NAMESPACE -class QNetmaskAddress: public QHostAddress +class QNetmask { - int length; + // stores 0-32 for IPv4, 0-128 for IPv6, or 255 for invalid + quint8 length; public: - QNetmaskAddress() : QHostAddress(), length(-1) { } + Q_DECL_CONSTEXPR QNetmask() : length(255) {} - bool setAddress(const QString &address); bool setAddress(const QHostAddress &address); + QHostAddress address(QAbstractSocket::NetworkLayerProtocol protocol) const; - int prefixLength() const; - void setPrefixLength(QAbstractSocket::NetworkLayerProtocol proto, int len); + int prefixLength() const { return length == 255 ? -1 : length; } + void setPrefixLength(QAbstractSocket::NetworkLayerProtocol proto, int len) + { + int maxlen = -1; + if (proto == QAbstractSocket::IPv4Protocol) + maxlen = 32; + else if (proto == QAbstractSocket::IPv6Protocol) + maxlen = 128; + if (len > maxlen || len < 0) + length = 255U; + else + length = unsigned(len); + } + + friend bool operator==(QNetmask n1, QNetmask n2) + { return n1.length == n2.length; } }; QT_END_NAMESPACE diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp index c5d1adbef0..2c28ae9ed9 100644 --- a/src/network/kernel/qnetworkinterface.cpp +++ b/src/network/kernel/qnetworkinterface.cpp @@ -257,7 +257,7 @@ void QNetworkAddressEntry::setIp(const QHostAddress &newIp) */ QHostAddress QNetworkAddressEntry::netmask() const { - return d->netmask; + return d->netmask.address(d->address.protocol()); } /*! @@ -270,7 +270,7 @@ QHostAddress QNetworkAddressEntry::netmask() const void QNetworkAddressEntry::setNetmask(const QHostAddress &newNetmask) { if (newNetmask.protocol() != ip().protocol()) { - d->netmask = QNetmaskAddress(); + d->netmask = QNetmask(); return; } diff --git a/src/network/kernel/qnetworkinterface_p.h b/src/network/kernel/qnetworkinterface_p.h index ec25fdf37e..51901eeda8 100644 --- a/src/network/kernel/qnetworkinterface_p.h +++ b/src/network/kernel/qnetworkinterface_p.h @@ -68,8 +68,8 @@ class QNetworkAddressEntryPrivate { public: QHostAddress address; - QNetmaskAddress netmask; QHostAddress broadcast; + QNetmask netmask; }; class QNetworkInterfacePrivate: public QSharedData diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp index c2efcea625..8344fb04c2 100644 --- a/src/network/kernel/qnetworkinterface_win.cpp +++ b/src/network/kernel/qnetworkinterface_win.cpp @@ -103,53 +103,13 @@ QString QNetworkInterfaceManager::interfaceNameFromIndex(uint index) return QString::number(index); } -static QHash<QHostAddress, QHostAddress> ipv4Netmasks() -{ - //Retrieve all the IPV4 addresses & netmasks - IP_ADAPTER_INFO staticBuf[2]; // 2 is arbitrary - PIP_ADAPTER_INFO pAdapter = staticBuf; - ULONG bufSize = sizeof staticBuf; - QHash<QHostAddress, QHostAddress> ipv4netmasks; - - 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 (GetAdaptersInfo(pAdapter, &bufSize) != ERROR_SUCCESS) { - free(pAdapter); - return ipv4netmasks; - } - } else if (retval != ERROR_SUCCESS) { - // error - return ipv4netmasks; - } - - // iterate over the list and add the entries to our listing - for (PIP_ADAPTER_INFO ptr = pAdapter; ptr; ptr = ptr->Next) { - for (PIP_ADDR_STRING addr = &ptr->IpAddressList; addr; addr = addr->Next) { - QHostAddress address(QLatin1String(addr->IpAddress.String)); - QHostAddress mask(QLatin1String(addr->IpMask.String)); - ipv4netmasks[address] = mask; - } - } - if (pAdapter != staticBuf) - free(pAdapter); - - return ipv4netmasks; - -} - -static QList<QNetworkInterfacePrivate *> interfaceListingWinXP() +static QList<QNetworkInterfacePrivate *> interfaceListing() { QList<QNetworkInterfacePrivate *> interfaces; IP_ADAPTER_ADDRESSES staticBuf[2]; // 2 is arbitrary PIP_ADAPTER_ADDRESSES pAdapter = staticBuf; ULONG bufSize = sizeof staticBuf; - const QHash<QHostAddress, QHostAddress> &ipv4netmasks = ipv4Netmasks(); ULONG flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_MULTICAST; @@ -171,11 +131,17 @@ static QList<QNetworkInterfacePrivate *> interfaceListingWinXP() // iterate over the list and add the entries to our listing for (PIP_ADAPTER_ADDRESSES ptr = pAdapter; ptr; ptr = ptr->Next) { + // the structure grows over time, so let's make sure the fields + // introduced in Windows Vista are present (Luid is the furthest + // field we access from IP_ADAPTER_ADDRESSES_LH) + Q_ASSERT(ptr->Length >= offsetof(IP_ADAPTER_ADDRESSES, Luid)); + Q_ASSERT(ptr->Length >= offsetof(IP_ADAPTER_ADDRESSES, Ipv6IfIndex)); + QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate; interfaces << iface; iface->index = 0; - if (ptr->Length >= offsetof(IP_ADAPTER_ADDRESSES, Ipv6IfIndex) && ptr->Ipv6IfIndex != 0) + if (ptr->Ipv6IfIndex != 0) iface->index = ptr->Ipv6IfIndex; else if (ptr->IfIndex != 0) iface->index = ptr->IfIndex; @@ -188,13 +154,11 @@ static QList<QNetworkInterfacePrivate *> interfaceListingWinXP() if (ptr->IfType == IF_TYPE_PPP) iface->flags |= QNetworkInterface::IsPointToPoint; - if (ptr->Length >= offsetof(IP_ADAPTER_ADDRESSES, Luid)) { - // use ConvertInterfaceLuidToNameW because that returns a friendlier name, though not - // as friendly as FriendlyName below - WCHAR buf[IF_MAX_STRING_SIZE + 1]; - if (ConvertInterfaceLuidToNameW(&ptr->Luid, buf, sizeof(buf)/sizeof(buf[0])) == NO_ERROR) - iface->name = QString::fromWCharArray(buf); - } + // use ConvertInterfaceLuidToNameW because that returns a friendlier name, though not + // as "friendly" as FriendlyName below + WCHAR buf[IF_MAX_STRING_SIZE + 1]; + if (ConvertInterfaceLuidToNameW(&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); @@ -206,28 +170,17 @@ static QList<QNetworkInterfacePrivate *> interfaceListingWinXP() // loopback if it has no address iface->flags |= QNetworkInterface::IsLoopBack; - // The GetAdaptersAddresses call has an interesting semantic: - // It can return a number N of addresses and a number M of prefixes. - // But if you have IPv6 addresses, generally N > M. - // I cannot find a way to relate the Address to the Prefix, aside from stopping - // the iteration at the last Prefix entry and assume that it applies to all addresses - // from that point on. - PIP_ADAPTER_PREFIX pprefix = 0; - if (ptr->Length >= offsetof(IP_ADAPTER_ADDRESSES, FirstPrefix)) - pprefix = ptr->FirstPrefix; + // parse the IP (unicast) addresses for (PIP_ADAPTER_UNICAST_ADDRESS addr = ptr->FirstUnicastAddress; addr; addr = addr->Next) { + Q_ASSERT(addr->Length >= offsetof(IP_ADAPTER_UNICAST_ADDRESS, OnLinkPrefixLength)); + + // skip addresses in invalid state + if (addr->DadState == IpDadStateInvalid) + continue; + QNetworkAddressEntry entry; entry.setIp(addressFromSockaddr(addr->Address.lpSockaddr)); - if (pprefix) { - if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) { - entry.setNetmask(ipv4netmasks[entry.ip()]); - - // broadcast address is set on postProcess() - } else { //IPV6 - entry.setPrefixLength(pprefix->PrefixLength); - } - pprefix = pprefix->Next ? pprefix->Next : pprefix; - } + entry.setPrefixLength(addr->OnLinkPrefixLength); iface->addressEntries << entry; } } @@ -240,7 +193,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListingWinXP() QList<QNetworkInterfacePrivate *> QNetworkInterfaceManager::scan() { - return interfaceListingWinXP(); + return interfaceListing(); } QString QHostInfo::localDomainName() diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp index 37f3f84653..6b53b4b58e 100644 --- a/src/network/kernel/qnetworkproxy.cpp +++ b/src/network/kernel/qnetworkproxy.cpp @@ -227,7 +227,9 @@ #ifndef QT_NO_NETWORKPROXY #include "private/qnetworkrequest_p.h" +#if QT_CONFIG(socks5) #include "private/qsocks5socketengine_p.h" +#endif #include "private/qhttpsocketengine_p.h" #include "qauthenticator.h" #include "qdebug.h" @@ -251,7 +253,7 @@ public: : mutex(QMutex::Recursive) , applicationLevelProxy(0) , applicationLevelProxyFactory(0) -#ifndef QT_NO_SOCKS5 +#if QT_CONFIG(socks5) , socks5SocketEngineHandler(0) #endif #ifndef QT_NO_HTTP @@ -263,7 +265,7 @@ public: , useSystemProxies(false) #endif { -#ifndef QT_NO_SOCKS5 +#if QT_CONFIG(socks5) socks5SocketEngineHandler = new QSocks5SocketEngineHandler(); #endif #ifndef QT_NO_HTTP @@ -275,7 +277,7 @@ public: { delete applicationLevelProxy; delete applicationLevelProxyFactory; -#ifndef QT_NO_SOCKS5 +#if QT_CONFIG(socks5) delete socks5SocketEngineHandler; #endif #ifndef QT_NO_HTTP @@ -335,7 +337,7 @@ private: QMutex mutex; QNetworkProxy *applicationLevelProxy; QNetworkProxyFactory *applicationLevelProxyFactory; -#ifndef QT_NO_SOCKS5 +#if QT_CONFIG(socks5) QSocks5SocketEngineHandler *socks5SocketEngineHandler; #endif #ifndef QT_NO_HTTP diff --git a/src/network/kernel/qurlinfo.cpp b/src/network/kernel/qurlinfo.cpp index 300a51d3e7..7ae6822fb4 100644 --- a/src/network/kernel/qurlinfo.cpp +++ b/src/network/kernel/qurlinfo.cpp @@ -39,8 +39,6 @@ #include "qurlinfo_p.h" -#ifndef QT_NO_FTP - #include "qurl.h" #include "qdir.h" #include <limits.h> @@ -727,5 +725,3 @@ bool QUrlInfo::isValid() const } QT_END_NAMESPACE - -#endif // QT_NO_FTP diff --git a/src/network/kernel/qurlinfo_p.h b/src/network/kernel/qurlinfo_p.h index 3a430a3321..8180796f49 100644 --- a/src/network/kernel/qurlinfo_p.h +++ b/src/network/kernel/qurlinfo_p.h @@ -56,10 +56,9 @@ #include <QtCore/qstring.h> #include <QtCore/qiodevice.h> -QT_BEGIN_NAMESPACE - +QT_REQUIRE_CONFIG(ftp); -#ifndef QT_NO_FTP +QT_BEGIN_NAMESPACE class QUrl; class QUrlInfoPrivate; @@ -129,8 +128,6 @@ private: QUrlInfoPrivate *d; }; -#endif // QT_NO_FTP - QT_END_NAMESPACE #endif // QURLINFO_H |