diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2019-12-05 16:02:56 -0800 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2019-12-07 10:20:27 -0800 |
commit | c4b0ff4855e81aa8017664a2f1a4353b274c27fd (patch) | |
tree | c5bb75a1b1f8f88177bff7e493db5fd35cda1be9 /tests/auto/network | |
parent | 29adc0eed9b9dc3cce92f8acaaeaed3ab1bc6414 (diff) | |
download | qtbase-c4b0ff4855e81aa8017664a2f1a4353b274c27fd.tar.gz |
tst_QNetworkInterface: don't force an IPv4 link-local address
Windows apparently has special code to deal with those addresses. If all
your network interfaces are up and have acquired addresses, then the
link-local network at 169.254.0.0/16 is unreachable. I had never caught
this because both my Windows VM and my bare metal Windows have inactive
interfaces (like the Bluetooth PAN one) and, when inactive, Windows
assigns a link-local address. But in the CI, the interface(s) were all
up and running, causing this issue.
Unix systems don't treat IPv4 link-local any differently, so they always
worked, so long as any interface was up and there had to be one to reach
the network test server.
This commit reworks the test to add test addresses based on the
addresses found on up & running interfaces (see tst_qudpsocket.cpp). For
IPv4, we flip the bits in the local portion of the address. For IPv6, we
add a node with an address I generated randomly (non-universal), with
the same scope.
Fixes: QTBUG-65667
Change-Id: I568dea4813b448fe9ba6fffd15dd9f482db34991
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'tests/auto/network')
-rw-r--r-- | tests/auto/network/kernel/qnetworkinterface/BLACKLIST | 4 | ||||
-rw-r--r-- | tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp | 48 |
2 files changed, 31 insertions, 21 deletions
diff --git a/tests/auto/network/kernel/qnetworkinterface/BLACKLIST b/tests/auto/network/kernel/qnetworkinterface/BLACKLIST deleted file mode 100644 index 33bdf540b6..0000000000 --- a/tests/auto/network/kernel/qnetworkinterface/BLACKLIST +++ /dev/null @@ -1,4 +0,0 @@ -# QTBUG-65667 -[localAddress:linklocal-ipv4] -msvc-2015 ci -msvc-2017 ci diff --git a/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp b/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp index 0c7ba99be5..bc6e5435df 100644 --- a/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp +++ b/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp @@ -215,31 +215,45 @@ void tst_QNetworkInterface::loopbackIPv6() } void tst_QNetworkInterface::localAddress_data() { + bool ipv6 = isIPv6Working(); QTest::addColumn<QHostAddress>("target"); QTest::newRow("localhost-ipv4") << QHostAddress(QHostAddress::LocalHost); - if (isIPv6Working()) + if (ipv6) QTest::newRow("localhost-ipv6") << QHostAddress(QHostAddress::LocalHostIPv6); QTest::newRow("test-server") << QtNetworkSettings::serverIP(); - // Since we don't actually transmit anything, we can list any IPv4 address - // and it should work. But we're using a linklocal address so that this - // test can pass even machines that failed to reach a DHCP server. - QTest::newRow("linklocal-ipv4") << QHostAddress("169.254.0.1"); - - if (isIPv6Working()) { - // On the other hand, we can't list just any IPv6 here. It's very - // likely that this machine has not received a route via ICMPv6-RA or - // DHCPv6, so it won't have a global route. On some OSes, IPv6 may be - // enabled per interface, so we need to know which ones work. - const QList<QHostAddress> addrs = QNetworkInterface::allAddresses(); - for (const QHostAddress &addr : addrs) { - QString scope = addr.scopeId(); - if (scope.isEmpty()) + QSet<QHostAddress> added; + const QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces(); + for (const QNetworkInterface &iface : ifaces) { + if ((iface.flags() & QNetworkInterface::IsUp) == 0) + continue; + const QList<QNetworkAddressEntry> addrs = iface.addressEntries(); + for (const QNetworkAddressEntry &entry : addrs) { + QHostAddress addr = entry.ip(); + if (addr.isLoopback()) + continue; // added above + + if (addr.protocol() == QAbstractSocket::IPv4Protocol) { + // add an IPv4 address with bits in the host portion of the address flipped + quint32 ip4 = entry.ip().toIPv4Address(); + addr.setAddress(ip4 ^ ~entry.netmask().toIPv4Address()); + } else if (!ipv6 || entry.prefixLength() != 64) { + continue; + } else { + // add a random node in this IPv6 network + quint64 randomid = qFromBigEndian(Q_UINT64_C(0x8f41f072e5733caa)); + QIPv6Address ip6 = addr.toIPv6Address(); + memcpy(&ip6[8], &randomid, sizeof(randomid)); + addr.setAddress(ip6); + } + + if (added.contains(addr)) continue; - QTest::addRow("linklocal-ipv6-%s", qPrintable(scope)) - << QHostAddress("fe80::1234%" + scope); + added.insert(addr); + + QTest::addRow("%s-%s", qPrintable(iface.name()), qPrintable(addr.toString())) << addr; } } } |