summaryrefslogtreecommitdiffstats
path: root/src/network/kernel/qhostaddress.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/kernel/qhostaddress.cpp')
-rw-r--r--src/network/kernel/qhostaddress.cpp168
1 files changed, 27 insertions, 141 deletions
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index 230abb86aa..3c08717d11 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -41,6 +41,7 @@
#include "qhostaddress.h"
#include "qhostaddress_p.h"
+#include "private/qipaddress_p.h"
#include "qdebug.h"
#if defined(Q_OS_WIN)
#include <winsock2.h>
@@ -107,13 +108,14 @@ public:
bool parse();
void clear();
+ QString ipString;
+ QString scopeId;
+
quint32 a; // IPv4 address
Q_IPV6ADDR a6; // IPv6 address
QAbstractSocket::NetworkLayerProtocol protocol;
- QString ipString;
bool isParsed;
- QString scopeId;
friend class QHostAddress;
};
@@ -175,28 +177,7 @@ void QHostAddressPrivate::setAddress(const Q_IPV6ADDR &a_)
isParsed = true;
}
-static bool parseIp4(const QString& address, quint32 *addr)
-{
- QStringList ipv4 = address.split(QLatin1String("."));
- if (ipv4.count() != 4)
- return false;
-
- quint32 ipv4Address = 0;
- for (int i = 0; i < 4; ++i) {
- bool ok = false;
- uint byteValue = ipv4.at(i).toUInt(&ok);
- if (!ok || byteValue > 255)
- return false;
-
- ipv4Address <<= 8;
- ipv4Address += byteValue;
- }
-
- *addr = ipv4Address;
- return true;
-}
-
-static bool parseIp6(const QString &address, quint8 *addr, QString *scopeId)
+static bool parseIp6(const QString &address, QIPAddressUtils::IPv6Address &addr, QString *scopeId)
{
QString tmp = address;
int scopeIdPos = tmp.lastIndexOf(QLatin1Char('%'));
@@ -206,77 +187,7 @@ static bool parseIp6(const QString &address, quint8 *addr, QString *scopeId)
} else {
scopeId->clear();
}
-
- QStringList ipv6 = tmp.split(QLatin1String(":"));
- int count = ipv6.count();
- if (count < 3 || count > 8)
- return false;
-
- int colonColon = tmp.count(QLatin1String("::"));
- if(count == 8 && colonColon > 1)
- return false;
-
- // address can be compressed with a "::", but that
- // may only appear once (see RFC 1884)
- // the statement below means:
- // if(shortened notation is not used AND
- // ((pure IPv6 notation AND less than 8 parts) OR
- // ((mixed IPv4/6 notation AND less than 7 parts)))
- if(colonColon != 1 && count < (tmp.contains(QLatin1Char('.')) ? 7 : 8))
- return false;
-
- int mc = 16;
- int fillCount = 9 - count; // number of 0 words to fill in the middle
- for (int i = count - 1; i >= 0; --i) {
- if (mc <= 0)
- return false;
-
- if (ipv6.at(i).isEmpty()) {
- if (i == count - 1) {
- // special case: ":" is last character
- if (!ipv6.at(i - 1).isEmpty())
- return false;
- addr[--mc] = 0;
- addr[--mc] = 0;
- } else if (i == 0) {
- // special case: ":" is first character
- if (!ipv6.at(i + 1).isEmpty())
- return false;
- addr[--mc] = 0;
- addr[--mc] = 0;
- } else {
- for (int j = 0; j < fillCount; ++j) {
- if (mc <= 0)
- return false;
- addr[--mc] = 0;
- addr[--mc] = 0;
- }
- }
- } else {
- bool ok = false;
- uint byteValue = ipv6.at(i).toUInt(&ok, 16);
- if (ok && byteValue <= 0xffff) {
- addr[--mc] = byteValue & 0xff;
- addr[--mc] = (byteValue >> 8) & 0xff;
- } else {
- if (i != count - 1)
- return false;
-
- // parse the ipv4 part of a mixed type
- quint32 maybeIp4;
- if (!parseIp4(ipv6.at(i), &maybeIp4))
- return false;
-
- addr[--mc] = maybeIp4 & 0xff;
- addr[--mc] = (maybeIp4 >> 8) & 0xff;
- addr[--mc] = (maybeIp4 >> 16) & 0xff;
- addr[--mc] = (maybeIp4 >> 24) & 0xff;
- --fillCount;
- }
- }
- }
-
- return true;
+ return QIPAddressUtils::parseIp6(addr, tmp.constBegin(), tmp.constEnd());
}
bool QHostAddressPrivate::parse()
@@ -284,6 +195,8 @@ bool QHostAddressPrivate::parse()
isParsed = true;
protocol = QAbstractSocket::UnknownNetworkLayerProtocol;
QString a = ipString.simplified();
+ if (a.isEmpty())
+ return false;
// All IPv6 addresses contain a ':', and may contain a '.'.
if (a.contains(QLatin1Char(':'))) {
@@ -295,14 +208,11 @@ bool QHostAddressPrivate::parse()
}
}
- // All IPv4 addresses contain a '.'.
- if (a.contains(QLatin1Char('.'))) {
- quint32 maybeIp4 = 0;
- if (parseIp4(a, &maybeIp4)) {
- setAddress(maybeIp4);
- protocol = QAbstractSocket::IPv4Protocol;
- return true;
- }
+ quint32 maybeIp4 = 0;
+ if (QIPAddressUtils::parseIp4(maybeIp4, a.constBegin(), a.constEnd())) {
+ setAddress(maybeIp4);
+ protocol = QAbstractSocket::IPv4Protocol;
+ return true;
}
return false;
@@ -556,23 +466,27 @@ QHostAddress::QHostAddress(const QHostAddress &address)
QHostAddress::QHostAddress(SpecialAddress address)
: d(new QHostAddressPrivate)
{
+ Q_IPV6ADDR ip6;
+ memset(&ip6, 0, sizeof ip6);
+
switch (address) {
case Null:
break;
case Broadcast:
- setAddress(QLatin1String("255.255.255.255"));
+ d->setAddress(quint32(-1));
break;
case LocalHost:
- setAddress(QLatin1String("127.0.0.1"));
+ d->setAddress(0x7f000001);
break;
case LocalHostIPv6:
- setAddress(QLatin1String("::1"));
+ ip6[15] = 1;
+ d->setAddress(ip6);
break;
case AnyIPv4:
- setAddress(QLatin1String("0.0.0.0"));
+ setAddress(0u);
break;
case AnyIPv6:
- setAddress(QLatin1String("::"));
+ d->setAddress(ip6);
break;
case Any:
d->clear();
@@ -761,42 +675,13 @@ QString QHostAddress::toString() const
|| d->protocol == QAbstractSocket::AnyIPProtocol) {
quint32 i = toIPv4Address();
QString s;
- s.sprintf("%d.%d.%d.%d", (i>>24) & 0xff, (i>>16) & 0xff,
- (i >> 8) & 0xff, i & 0xff);
+ QIPAddressUtils::toString(s, i);
return s;
}
if (d->protocol == QAbstractSocket::IPv6Protocol) {
- quint16 ugle[8];
- for (int i = 0; i < 8; i++) {
- ugle[i] = (quint16(d->a6[2*i]) << 8) | quint16(d->a6[2*i+1]);
- }
QString s;
- QString temp;
- bool zeroDetected = false;
- bool zeroShortened = false;
- for (int i = 0; i < 8; i++) {
- if ((ugle[i] != 0) || zeroShortened) {
- temp.sprintf("%X", ugle[i]);
- s.append(temp);
- if (zeroDetected)
- zeroShortened = true;
- } else {
- if (!zeroDetected) {
- if (i<7 && (ugle[i+1] == 0)) {
- s.append(QLatin1Char(':'));
- zeroDetected = true;
- } else {
- temp.sprintf("%X", ugle[i]);
- s.append(temp);
- if (i<7)
- s.append(QLatin1Char(':'));
- }
- }
- }
- if (i<7 && ((ugle[i] != 0) || zeroShortened || (i==0 && zeroDetected)))
- s.append(QLatin1Char(':'));
- }
+ QIPAddressUtils::toString(s, d->a6.c);
if (!d->scopeId.isEmpty())
s.append(QLatin1Char('%') + d->scopeId);
@@ -1142,9 +1027,10 @@ QDebug operator<<(QDebug d, const QHostAddress &address)
}
#endif
-uint qHash(const QHostAddress &key)
+uint qHash(const QHostAddress &key, uint seed)
{
- return qHash(key.toString());
+ QT_ENSURE_PARSED(&key);
+ return qHash(QByteArray::fromRawData(reinterpret_cast<const char *>(key.d->a6.c), 16), seed);
}
#ifndef QT_NO_DATASTREAM