diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2014-12-24 15:40:21 -0200 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2015-03-06 07:53:55 +0000 |
commit | ab8d36d6f36119dc9ef211acc391d8c2bfb5ee83 (patch) | |
tree | 89d924c59ac422b3ad626be56c737afdee8dc8f8 /src/network | |
parent | c64d27a9f7e33c9d8748e98e3c3a41ff1ce79729 (diff) |
QHostAddress: Convert AnyIPv4 to AnyIPv6 instead of ::ffff:0.0.0.0
Unlike localhost (127.0.0.1), there's really no point in using
::ffff:0.0.0.0, since you shouldn't be sending packets to it. Linux
transforms 0.0.0.0 to localhost, but that's non-standard and won't work
on other OSs, so it's still a bad idea.
Change-Id: I5982b21bf953e11e04fc19893f94be90ed29089b
Reviewed-by: Richard J. Moore <rich@kde.org>
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/kernel/qhostaddress.cpp | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index d9de0202ef..8d32711de3 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -123,28 +123,41 @@ QHostAddressPrivate::QHostAddressPrivate() void QHostAddressPrivate::setAddress(quint32 a_) { a = a_; - //create mapped address + //create mapped address, except for a_ == 0 (any) memset(&a6, 0, sizeof(a6)); + if (a) { + a6[11] = 0xFF; + a6[10] = 0xFF; + } else { + a6[11] = 0; + a6[10] = 0; + } + int i; for (i=15; a_ != 0; i--) { a6[i] = a_ & 0xFF; a_ >>=8; } Q_ASSERT(i >= 11); - a6[11] = 0xFF; - a6[10] = 0xFF; protocol = QAbstractSocket::IPv4Protocol; isParsed = true; } -static bool parseMappedAddress(quint32& a, const Q_IPV6ADDR &a6) +/// parses v4-mapped addresses or the AnyIPv6 address and stores in \a a; +/// returns true if the address was one of those +static bool convertToIpv4(quint32& a, const Q_IPV6ADDR &a6) { - int i; - for (i=0;i<10;i++) - if (a6[i]) return false; - for (;i<12;i++) - if (a6[i] != 0xFF) return false; - a=(a6[12] << 24) | (a6[13] << 16) | (a6[14] << 8) | a6[15]; + const uchar *ptr = a6.c; + if (qFromUnaligned<quint64>(ptr) != 0) + return false; + if (qFromBigEndian<quint32>(ptr + 8) == 0) { + // is it AnyIPv6? + a = 0; + return qFromBigEndian<quint32>(ptr + 12) == 0; + } + if (qFromBigEndian<quint32>(ptr + 8) != 0xFFFF) + return false; + a = qFromBigEndian<quint32>(ptr + 12); return true; } @@ -153,7 +166,7 @@ void QHostAddressPrivate::setAddress(const quint8 *a_) for (int i = 0; i < 16; i++) a6[i] = a_[i]; a = 0; - parseMappedAddress(a, a6); + convertToIpv4(a, a6); protocol = QAbstractSocket::IPv6Protocol; isParsed = true; } @@ -162,7 +175,7 @@ void QHostAddressPrivate::setAddress(const Q_IPV6ADDR &a_) { a6 = a_; a = 0; - parseMappedAddress(a, a6); + convertToIpv4(a, a6); protocol = QAbstractSocket::IPv6Protocol; isParsed = true; } |