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>bb10
parent
29adc0eed9
commit
c4b0ff4855
|
|
@ -1,4 +0,0 @@
|
|||
# QTBUG-65667
|
||||
[localAddress:linklocal-ipv4]
|
||||
msvc-2015 ci
|
||||
msvc-2017 ci
|
||||
|
|
@ -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");
|
||||
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 (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())
|
||||
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;
|
||||
QTest::addRow("linklocal-ipv6-%s", qPrintable(scope))
|
||||
<< QHostAddress("fe80::1234%" + scope);
|
||||
} 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;
|
||||
added.insert(addr);
|
||||
|
||||
QTest::addRow("%s-%s", qPrintable(iface.name()), qPrintable(addr.toString())) << addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue