Network - Add QHostAddress::isLoopback API.
authorShane Kearns <shane.kearns@accenture.com>
Mon, 24 Oct 2011 10:01:09 +0000 (11:01 +0100)
committerQt by Nokia <qt-info@nokia.com>
Mon, 24 Oct 2011 11:56:41 +0000 (13:56 +0200)
The standard IPv4 loopback address is 127.0.0.1, however anything in
the 127.0.0.0/8 range is also a loopback address.

isLoopback returns true for any address that is in the IPv4 loopback
address range, or is the single IPv6 loopback address ::1

Task-number: QTBUG-22246
Change-Id: Ic39100e2e97a52db700e01b109998a1cfd4335e3
Reviewed-by: Thiago Macieira (Intel) <thiago.macieira@intel.com>
dist/changes-5.0.0
src/network/kernel/qhostaddress.cpp
src/network/kernel/qhostaddress.h
tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp

index 92b4664..b17353e 100644 (file)
@@ -70,6 +70,8 @@ QtWidgets
 
 QtNetwork
 ---------
+* QHostAddress::isLoopback() API added. Returns true if the address is
+  one of the IP loopback addresses.
 
 QtOpenGL
 --------
index d66d471..cbd804c 100644 (file)
@@ -1109,6 +1109,28 @@ QPair<QHostAddress, int> QHostAddress::parseSubnet(const QString &subnet)
     return qMakePair(QHostAddress(addr), netmask);
 }
 
+/*!
+    \since 5.0
+
+    returns true if the address is the IPv6 loopback address, or any
+    of the IPv4 loopback addresses.
+*/
+bool QHostAddress::isLoopback() const
+{
+    QT_ENSURE_PARSED(this);
+    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)
+            return false;
+        for (int i = 0; i < 15; i++)
+            if (d->a6[i] != 0)
+                return false;
+        return true;
+    }
+    return false;
+}
+
 #ifndef QT_NO_DEBUG_STREAM
 QDebug operator<<(QDebug d, const QHostAddress &address)
 {
index 3d364de..83e8a7c 100644 (file)
@@ -120,6 +120,8 @@ public:
     bool isInSubnet(const QHostAddress &subnet, int netmask) const;
     bool isInSubnet(const QPair<QHostAddress, int> &subnet) const;
 
+    bool isLoopback() const;
+
     static QPair<QHostAddress, int> parseSubnet(const QString &subnet);
 
 protected:
index b20e07b..7e35830 100644 (file)
@@ -82,6 +82,8 @@ private slots:
     void parseSubnet();
     void isInSubnet_data();
     void isInSubnet();
+    void isLoopback_data();
+    void isLoopback();
 };
 
 QT_BEGIN_NAMESPACE
@@ -607,5 +609,43 @@ void tst_QHostAddress::isInSubnet()
     QTEST(address.isInSubnet(prefix, prefixLength), "result");
 }
 
+void tst_QHostAddress::isLoopback_data()
+{
+    QTest::addColumn<QHostAddress>("address");
+    QTest::addColumn<bool>("result");
+
+    QTest::newRow("ipv6_loop") << QHostAddress(QHostAddress::LocalHostIPv6) << true;
+    QTest::newRow("::1") << QHostAddress("::1") << true;
+
+    QTest::newRow("ipv4_loop") << QHostAddress(QHostAddress::LocalHost) << true;
+    QTest::newRow("127.0.0.1") << QHostAddress("127.0.0.1") << true;
+    QTest::newRow("127.0.0.2") << QHostAddress("127.0.0.2") << true;
+    QTest::newRow("127.3.2.1") << QHostAddress("127.3.2.1") << true;
+
+    QTest::newRow("default") << QHostAddress() << false;
+    QTest::newRow("1.2.3.4") << QHostAddress("1.2.3.4") << false;
+    QTest::newRow("10.0.0.4") << QHostAddress("10.0.0.4") << false;
+    QTest::newRow("192.168.3.4") << QHostAddress("192.168.3.4") << false;
+
+    QTest::newRow("::") << QHostAddress("::") << false;
+    QTest::newRow("Any") << QHostAddress(QHostAddress::Any) << false;
+    QTest::newRow("AnyIPv4") << QHostAddress(QHostAddress::AnyIPv4) << false;
+    QTest::newRow("AnyIPv6") << QHostAddress(QHostAddress::AnyIPv6) << false;
+    QTest::newRow("Broadcast") << QHostAddress(QHostAddress::Broadcast) << false;
+    QTest::newRow("Null") << QHostAddress(QHostAddress::Null) << false;
+
+    QTest::newRow("::ffff:127.0.0.1") << QHostAddress("::ffff:127.0.0.1") << true;
+    QTest::newRow("::ffff:127.0.0.2") << QHostAddress("::ffff:127.0.0.2") << true;
+    QTest::newRow("::ffff:127.3.2.1") << QHostAddress("::ffff:127.3.2.1") << true;
+}
+
+void tst_QHostAddress::isLoopback()
+{
+    QFETCH(QHostAddress, address);
+    QFETCH(bool, result);
+
+    QCOMPARE(address.isLoopback(), result);
+}
+
 QTEST_MAIN(tst_QHostAddress)
 #include "tst_qhostaddress.moc"