diff options
Diffstat (limited to 'src/network/kernel/qhostaddress.cpp')
-rw-r--r-- | src/network/kernel/qhostaddress.cpp | 208 |
1 files changed, 96 insertions, 112 deletions
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index ea46d76ee0..0330fb091b 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Copyright (C) 2016 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$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qhostaddress.h" #include "qhostaddress_p.h" @@ -65,7 +29,7 @@ QT_BEGIN_NAMESPACE QHostAddressPrivate::QHostAddressPrivate() - : a(0), protocol(QAbstractSocket::UnknownNetworkLayerProtocol) + : a(0), protocol(QHostAddress::UnknownNetworkLayerProtocol) { memset(&a6, 0, sizeof(a6)); } @@ -73,7 +37,7 @@ QHostAddressPrivate::QHostAddressPrivate() void QHostAddressPrivate::setAddress(quint32 a_) { a = a_; - protocol = QAbstractSocket::IPv4Protocol; + protocol = QHostAddress::IPv4Protocol; //create mapped address, except for a_ == 0 (any) a6_64.c[0] = 0; @@ -122,7 +86,7 @@ static bool convertToIpv4(quint32& a, const Q_IPV6ADDR &a6, const QHostAddress:: void QHostAddressPrivate::setAddress(const quint8 *a_) { - protocol = QAbstractSocket::IPv6Protocol; + protocol = QHostAddress::IPv6Protocol; memcpy(a6.c, a_, sizeof(a6)); a = 0; convertToIpv4(a, a6, (QHostAddress::ConvertV4MappedToIPv4 @@ -137,7 +101,7 @@ void QHostAddressPrivate::setAddress(const Q_IPV6ADDR &a_) static bool parseIp6(const QString &address, QIPAddressUtils::IPv6Address &addr, QString *scopeId) { QStringView tmp(address); - int scopeIdPos = tmp.lastIndexOf(QLatin1Char('%')); + qsizetype scopeIdPos = tmp.lastIndexOf(u'%'); if (scopeIdPos != -1) { *scopeId = tmp.mid(scopeIdPos + 1).toString(); tmp.chop(tmp.size() - scopeIdPos); @@ -149,13 +113,13 @@ static bool parseIp6(const QString &address, QIPAddressUtils::IPv6Address &addr, bool QHostAddressPrivate::parse(const QString &ipString) { - protocol = QAbstractSocket::UnknownNetworkLayerProtocol; + protocol = QHostAddress::UnknownNetworkLayerProtocol; QString a = ipString.simplified(); if (a.isEmpty()) return false; // All IPv6 addresses contain a ':', and may contain a '.'. - if (a.contains(QLatin1Char(':'))) { + if (a.contains(u':')) { quint8 maybeIp6[16]; if (parseIp6(a, maybeIp6, &scopeId)) { setAddress(maybeIp6); @@ -175,7 +139,7 @@ bool QHostAddressPrivate::parse(const QString &ipString) void QHostAddressPrivate::clear() { a = 0; - protocol = QAbstractSocket::UnknownNetworkLayerProtocol; + protocol = QHostAddress::UnknownNetworkLayerProtocol; memset(&a6, 0, sizeof(a6)); } @@ -200,8 +164,12 @@ AddressClassification QHostAddressPrivate::classify() const return BroadcastAddress; return UnknownAddress; } + if (((a & 0xff000000U) == 0x0a000000U) // 10.0.0.0/8 + || ((a & 0xfff00000U) == 0xac100000U) // 172.16.0.0/12 + || ((a & 0xffff0000U) == 0xc0a80000U)) // 192.168.0.0/16 + return PrivateNetworkAddress; - // Not testing for PrivateNetworkAddress and TestNetworkAddress + // Not testing for TestNetworkAddress // since we don't need them yet. return GlobalAddress; } @@ -242,7 +210,7 @@ AddressClassification QHostAddressPrivate::classify() const if (low64) // not :: return GlobalAddress; - if (protocol == QAbstractSocket::UnknownNetworkLayerProtocol) + if (protocol == QHostAddress::UnknownNetworkLayerProtocol) return UnknownAddress; // only :: and 0.0.0.0 remain now @@ -262,10 +230,10 @@ bool QNetmask::setAddress(const QHostAddress &address) quint8 *end; length = 255; - if (address.protocol() == QAbstractSocket::IPv4Protocol) { + if (address.protocol() == QHostAddress::IPv4Protocol) { ip.v4 = qToBigEndian(address.toIPv4Address()); end = ptr + 4; - } else if (address.protocol() == QAbstractSocket::IPv6Protocol) { + } else if (address.protocol() == QHostAddress::IPv6Protocol) { memcpy(ip.v6, address.toIPv6Address().c, 16); end = ptr + 16; } else { @@ -331,12 +299,12 @@ static void clearBits(quint8 *where, int start, int end) memset(where + (start + 7) / 8, 0, end / 8 - (start + 7) / 8); } -QHostAddress QNetmask::address(QAbstractSocket::NetworkLayerProtocol protocol) const +QHostAddress QNetmask::address(QHostAddress::NetworkLayerProtocol protocol) const { - if (length == 255 || protocol == QAbstractSocket::AnyIPProtocol || - protocol == QAbstractSocket::UnknownNetworkLayerProtocol) { + if (length == 255 || protocol == QHostAddress::AnyIPProtocol || + protocol == QHostAddress::UnknownNetworkLayerProtocol) { return QHostAddress(); - } else if (protocol == QAbstractSocket::IPv4Protocol) { + } else if (protocol == QHostAddress::IPv4Protocol) { quint32 a; if (length == 0) a = 0; @@ -657,7 +625,7 @@ void QHostAddress::setAddress(SpecialAddress address) return; case Any: - d->protocol = QAbstractSocket::AnyIPProtocol; + d->protocol = QHostAddress::AnyIPProtocol; return; } @@ -684,8 +652,8 @@ quint32 QHostAddress::toIPv4Address(bool *ok) const { quint32 dummy; if (ok) - *ok = d->protocol == QAbstractSocket::IPv4Protocol || d->protocol == QAbstractSocket::AnyIPProtocol - || (d->protocol == QAbstractSocket::IPv6Protocol + *ok = d->protocol == QHostAddress::IPv4Protocol || d->protocol == QHostAddress::AnyIPProtocol + || (d->protocol == QHostAddress::IPv6Protocol && convertToIpv4(dummy, d->a6, ConversionMode(QHostAddress::ConvertV4MappedToIPv4 | QHostAddress::ConvertUnspecifiedAddress))); return d->a; @@ -694,9 +662,9 @@ quint32 QHostAddress::toIPv4Address(bool *ok) const /*! Returns the network layer protocol of the host address. */ -QAbstractSocket::NetworkLayerProtocol QHostAddress::protocol() const +QHostAddress::NetworkLayerProtocol QHostAddress::protocol() const { - return QAbstractSocket::NetworkLayerProtocol(d->protocol); + return QHostAddress::NetworkLayerProtocol(d->protocol); } /*! @@ -709,7 +677,7 @@ QAbstractSocket::NetworkLayerProtocol QHostAddress::protocol() const \l{QAbstractSocket::}{IPv6Protocol}. If the protocol is \l{QAbstractSocket::}{IPv4Protocol}, - then the address is returned an an IPv4 mapped IPv6 address. (RFC4291) + then the address is returned as an IPv4 mapped IPv6 address. (RFC4291) \sa toString() */ @@ -731,14 +699,14 @@ Q_IPV6ADDR QHostAddress::toIPv6Address() const QString QHostAddress::toString() const { QString s; - if (d->protocol == QAbstractSocket::IPv4Protocol - || d->protocol == QAbstractSocket::AnyIPProtocol) { + if (d->protocol == QHostAddress::IPv4Protocol + || d->protocol == QHostAddress::AnyIPProtocol) { quint32 i = toIPv4Address(); QIPAddressUtils::toString(s, i); - } else if (d->protocol == QAbstractSocket::IPv6Protocol) { + } else if (d->protocol == QHostAddress::IPv6Protocol) { QIPAddressUtils::toString(s, d->a6.c); if (!d->scopeId.isEmpty()) - s.append(QLatin1Char('%') + d->scopeId); + s += u'%' + d->scopeId; } return s; } @@ -781,7 +749,7 @@ QString QHostAddress::toString() const */ QString QHostAddress::scopeId() const { - return (d->protocol == QAbstractSocket::IPv6Protocol) ? d->scopeId : QString(); + return (d->protocol == QHostAddress::IPv6Protocol) ? d->scopeId : QString(); } /*! @@ -799,7 +767,7 @@ QString QHostAddress::scopeId() const void QHostAddress::setScopeId(const QString &id) { d.detach(); - if (d->protocol == QAbstractSocket::IPv6Protocol) + if (d->protocol == QHostAddress::IPv6Protocol) d->scopeId = id; } @@ -820,7 +788,7 @@ bool QHostAddress::operator==(const QHostAddress &other) const Returns \c true if this host address is the same as the \a other address given; otherwise returns \c false. - The parameter \a mode controls which conversions are preformed between addresses + The parameter \a mode controls which conversions are performed between addresses of differing protocols. If no \a mode is given, \c TolerantConversion is performed by default. @@ -831,41 +799,41 @@ bool QHostAddress::isEqual(const QHostAddress &other, ConversionMode mode) const if (d == other.d) return true; - if (d->protocol == QAbstractSocket::IPv4Protocol) { + if (d->protocol == QHostAddress::IPv4Protocol) { switch (other.d->protocol) { - case QAbstractSocket::IPv4Protocol: + case QHostAddress::IPv4Protocol: return d->a == other.d->a; - case QAbstractSocket::IPv6Protocol: + case QHostAddress::IPv6Protocol: quint32 a4; return convertToIpv4(a4, other.d->a6, mode) && (a4 == d->a); - case QAbstractSocket::AnyIPProtocol: + case QHostAddress::AnyIPProtocol: return (mode & QHostAddress::ConvertUnspecifiedAddress) && d->a == 0; - case QAbstractSocket::UnknownNetworkLayerProtocol: + case QHostAddress::UnknownNetworkLayerProtocol: return false; } } - if (d->protocol == QAbstractSocket::IPv6Protocol) { + if (d->protocol == QHostAddress::IPv6Protocol) { switch (other.d->protocol) { - case QAbstractSocket::IPv4Protocol: + case QHostAddress::IPv4Protocol: quint32 a4; return convertToIpv4(a4, d->a6, mode) && (a4 == other.d->a); - case QAbstractSocket::IPv6Protocol: + case QHostAddress::IPv6Protocol: return memcmp(&d->a6, &other.d->a6, sizeof(Q_IPV6ADDR)) == 0; - case QAbstractSocket::AnyIPProtocol: + case QHostAddress::AnyIPProtocol: return (mode & QHostAddress::ConvertUnspecifiedAddress) - && (other.d->a6_64.c[0] == 0) && (other.d->a6_64.c[1] == 0); - case QAbstractSocket::UnknownNetworkLayerProtocol: + && (d->a6_64.c[0] == 0) && (d->a6_64.c[1] == 0); + case QHostAddress::UnknownNetworkLayerProtocol: return false; } } - if ((d->protocol == QAbstractSocket::AnyIPProtocol) + if ((d->protocol == QHostAddress::AnyIPProtocol) && (mode & QHostAddress::ConvertUnspecifiedAddress)) { switch (other.d->protocol) { - case QAbstractSocket::IPv4Protocol: + case QHostAddress::IPv4Protocol: return other.d->a == 0; - case QAbstractSocket::IPv6Protocol: + case QHostAddress::IPv6Protocol: return (other.d->a6_64.c[0] == 0) && (other.d->a6_64.c[1] == 0); default: break; @@ -884,7 +852,7 @@ bool QHostAddress::operator ==(SpecialAddress other) const quint32 ip4 = INADDR_ANY; switch (other) { case Null: - return d->protocol == QAbstractSocket::UnknownNetworkLayerProtocol; + return d->protocol == QHostAddress::UnknownNetworkLayerProtocol; case Broadcast: ip4 = INADDR_BROADCAST; @@ -895,14 +863,14 @@ bool QHostAddress::operator ==(SpecialAddress other) const break; case Any: - return d->protocol == QAbstractSocket::AnyIPProtocol; + return d->protocol == QHostAddress::AnyIPProtocol; case AnyIPv4: break; case LocalHostIPv6: case AnyIPv6: - if (d->protocol == QAbstractSocket::IPv6Protocol) { + if (d->protocol == QHostAddress::IPv6Protocol) { 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); } @@ -910,7 +878,7 @@ bool QHostAddress::operator ==(SpecialAddress other) const } // common IPv4 part - return d->protocol == QAbstractSocket::IPv4Protocol && d->a == ip4; + return d->protocol == QHostAddress::IPv4Protocol && d->a == ip4; } /*! @@ -922,7 +890,7 @@ bool QHostAddress::operator ==(SpecialAddress other) const */ bool QHostAddress::isNull() const { - return d->protocol == QAbstractSocket::UnknownNetworkLayerProtocol; + return d->protocol == QHostAddress::UnknownNetworkLayerProtocol; } /*! @@ -955,14 +923,14 @@ bool QHostAddress::isInSubnet(const QHostAddress &subnet, int netmask) const } ip4, net4; const quint8 *ip; const quint8 *net; - if (d->protocol == QAbstractSocket::IPv4Protocol) { + if (d->protocol == QHostAddress::IPv4Protocol) { if (netmask > 32) netmask = 32; ip4.ip = qToBigEndian(d->a); net4.ip = qToBigEndian(subnet.d->a); ip = ip4.data; net = net4.data; - } else if (d->protocol == QAbstractSocket::IPv6Protocol) { + } else if (d->protocol == QHostAddress::IPv6Protocol) { if (netmask > 128) netmask = 128; ip = d->a6.c; @@ -1043,17 +1011,17 @@ QPair<QHostAddress, int> QHostAddress::parseSubnet(const QString &subnet) if (subnet.isEmpty()) return invalid; - int slash = subnet.indexOf(QLatin1Char('/')); + qsizetype slash = subnet.indexOf(u'/'); QStringView netStr(subnet); if (slash != -1) netStr.truncate(slash); int netmask = -1; - bool isIpv6 = netStr.contains(QLatin1Char(':')); + bool isIpv6 = netStr.contains(u':'); if (slash != -1) { // is the netmask given in IP-form or in bit-count form? - if (!isIpv6 && subnet.indexOf(QLatin1Char('.'), slash + 1) != -1) { + if (!isIpv6 && subnet.indexOf(u'.', slash + 1) != -1) { // IP-style, convert it to bit-count form QHostAddress mask; QNetmask parser; @@ -1089,15 +1057,15 @@ QPair<QHostAddress, int> QHostAddress::parseSubnet(const QString &subnet) return invalid; // invalid netmask // parse the address manually - auto parts = netStr.split(QLatin1Char('.')); - if (parts.isEmpty() || parts.count() > 4) + auto parts = netStr.split(u'.'); + if (parts.isEmpty() || parts.size() > 4) return invalid; // invalid IPv4 address if (parts.constLast().isEmpty()) parts.removeLast(); quint32 addr = 0; - for (int i = 0; i < parts.count(); ++i) { + for (int i = 0; i < parts.size(); ++i) { bool ok; uint byteValue = parts.at(i).toUInt(&ok); if (!ok || byteValue > 255) @@ -1106,9 +1074,9 @@ QPair<QHostAddress, int> QHostAddress::parseSubnet(const QString &subnet) addr <<= 8; addr += byteValue; } - addr <<= 8 * (4 - parts.count()); + addr <<= 8 * (4 - parts.size()); if (netmask == -1) { - netmask = 8 * parts.count(); + netmask = 8 * parts.size(); } else if (netmask == 0) { // special case here // x86's instructions "shr" and "shl" do not operate when @@ -1143,13 +1111,13 @@ bool QHostAddress::isLoopback() const 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}. + local networks by \l {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() + \sa isLoopback(), isSiteLocal(), isUniqueLocalUnicast(), isPrivateUse() */ bool QHostAddress::isGlobal() const { @@ -1167,7 +1135,7 @@ bool QHostAddress::isGlobal() const \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() + \sa isLoopback(), isGlobal(), isMulticast(), isSiteLocal(), isUniqueLocalUnicast(), isPrivateUse() */ bool QHostAddress::isLinkLocal() const { @@ -1190,7 +1158,7 @@ bool QHostAddress::isLinkLocal() const isGlobal() also returns true). Site-local addresses were replaced by Unique Local Addresses (ULA). - \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast() + \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast(), isPrivateUse() */ bool QHostAddress::isSiteLocal() const { @@ -1211,7 +1179,7 @@ bool QHostAddress::isSiteLocal() const 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() + \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast(), isPrivateUse() */ bool QHostAddress::isUniqueLocalUnicast() const { @@ -1224,7 +1192,7 @@ bool QHostAddress::isUniqueLocalUnicast() const Returns \c true if the address is an IPv4 or IPv6 multicast address, \c false otherwise. - \sa isLoopback(), isGlobal(), isLinkLocal(), isSiteLocal(), isUniqueLocalUnicast() + \sa isLoopback(), isGlobal(), isLinkLocal(), isSiteLocal(), isUniqueLocalUnicast(), isPrivateUse() */ bool QHostAddress::isMulticast() const { @@ -1241,13 +1209,27 @@ bool QHostAddress::isMulticast() const broadcast address. For that, please use \l QNetworkInterface to obtain the broadcast addresses of the local machine. - \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast() + \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast(), isPrivateUse() */ bool QHostAddress::isBroadcast() const { return d->classify() == BroadcastAddress; } +/*! + \since 6.6 + + Returns \c true if the address is an IPv6 unique local unicast address or + IPv4 address reserved for local networks by \l {RFC 1918}, \c false otherwise. + + \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast(), isBroadcast() +*/ +bool QHostAddress::isPrivateUse() const +{ + const AddressClassification classification = d->classify(); + return (classification == PrivateNetworkAddress) || (classification == UniqueLocalAddress); +} + #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const QHostAddress &address) { @@ -1305,13 +1287,13 @@ QDataStream &operator<<(QDataStream &out, const QHostAddress &address) prot = qint8(address.protocol()); out << prot; switch (address.protocol()) { - case QAbstractSocket::UnknownNetworkLayerProtocol: - case QAbstractSocket::AnyIPProtocol: + case QHostAddress::UnknownNetworkLayerProtocol: + case QHostAddress::AnyIPProtocol: break; - case QAbstractSocket::IPv4Protocol: + case QHostAddress::IPv4Protocol: out << address.toIPv4Address(); break; - case QAbstractSocket::IPv6Protocol: + case QHostAddress::IPv6Protocol: { Q_IPV6ADDR ipv6 = address.toIPv6Address(); for (int i = 0; i < 16; ++i) @@ -1334,18 +1316,18 @@ QDataStream &operator>>(QDataStream &in, QHostAddress &address) { qint8 prot; in >> prot; - switch (QAbstractSocket::NetworkLayerProtocol(prot)) { - case QAbstractSocket::UnknownNetworkLayerProtocol: + switch (QHostAddress::NetworkLayerProtocol(prot)) { + case QHostAddress::UnknownNetworkLayerProtocol: address.clear(); break; - case QAbstractSocket::IPv4Protocol: + case QHostAddress::IPv4Protocol: { quint32 ipv4; in >> ipv4; address.setAddress(ipv4); } break; - case QAbstractSocket::IPv6Protocol: + case QHostAddress::IPv6Protocol: { Q_IPV6ADDR ipv6; for (int i = 0; i < 16; ++i) @@ -1357,7 +1339,7 @@ QDataStream &operator>>(QDataStream &in, QHostAddress &address) address.setScopeId(scope); } break; - case QAbstractSocket::AnyIPProtocol: + case QHostAddress::AnyIPProtocol: address = QHostAddress::Any; break; default: @@ -1370,3 +1352,5 @@ QDataStream &operator>>(QDataStream &in, QHostAddress &address) #endif //QT_NO_DATASTREAM QT_END_NAMESPACE + +#include "moc_qhostaddress.cpp" |