diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2017-08-20 15:50:41 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2017-11-14 15:54:51 +0000 |
commit | aaa187cd9951b71127c11c375e6a3954a187e1d3 (patch) | |
tree | 54dcee410994b3d64058ed6dde9e95c519fee83a /tests/auto/network/kernel/qnetworkinterface | |
parent | aa494d826ace02ffff5f29ae20b7738630913777 (diff) |
QAbstractSocket: Add socketOption for the Path MTU
This allow retrieving the value of the known PMTU for the current
socket. This works on Linux (IPv6 and IPv4) and FreeBSD (IPv6 only) --
the other OSes don't have the necessary API.
Note: do we need add IP_MTU_DISCOVER?
Change-Id: I6e9274c1e7444ad48c81fffd14dcaf97a18ce335
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'tests/auto/network/kernel/qnetworkinterface')
-rw-r--r-- | tests/auto/network/kernel/qnetworkinterface/BLACKLIST | 2 | ||||
-rw-r--r-- | tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp | 62 |
2 files changed, 58 insertions, 6 deletions
diff --git a/tests/auto/network/kernel/qnetworkinterface/BLACKLIST b/tests/auto/network/kernel/qnetworkinterface/BLACKLIST deleted file mode 100644 index 23bb688d9a..0000000000 --- a/tests/auto/network/kernel/qnetworkinterface/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[localAddress] -linux diff --git a/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp b/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp index 93dd73d64a..0b4ed4870d 100644 --- a/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp +++ b/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp @@ -40,6 +40,8 @@ #include "../../../network-settings.h" #include "emulationdetector.h" +Q_DECLARE_METATYPE(QHostAddress) + class tst_QNetworkInterface : public QObject { Q_OBJECT @@ -57,6 +59,7 @@ private slots: void consistencyCheck(); void loopbackIPv4(); void loopbackIPv6(); + void localAddress_data(); void localAddress(); void interfaceFromXXX_data(); void interfaceFromXXX(); @@ -210,18 +213,69 @@ void tst_QNetworkInterface::loopbackIPv6() QList<QHostAddress> all = QNetworkInterface::allAddresses(); QVERIFY(all.contains(QHostAddress(QHostAddress::LocalHostIPv6))); } +void tst_QNetworkInterface::localAddress_data() +{ + QTest::addColumn<QHostAddress>("target"); + + QTest::newRow("localhost-ipv4") << QHostAddress(QHostAddress::LocalHost); + if (isIPv6Working()) + 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()) + continue; + QTest::addRow("linklocal-ipv6-%s", qPrintable(scope)) + << QHostAddress("fe80::1234%" + scope); + } + } +} void tst_QNetworkInterface::localAddress() { + QFETCH(QHostAddress, target); QUdpSocket socket; - socket.connectToHost(QtNetworkSettings::serverName(), 80); + socket.connectToHost(target, 80); QVERIFY(socket.waitForConnected(5000)); QHostAddress local = socket.localAddress(); - // test that we can find the address that QUdpSocket reported - QList<QHostAddress> all = QNetworkInterface::allAddresses(); - QVERIFY(all.contains(local)); + // find the interface that contains the address QUdpSocket reported + QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces(); + const QNetworkInterface *outgoingIface = nullptr; + for (const QNetworkInterface &iface : ifaces) { + QList<QNetworkAddressEntry> addrs = iface.addressEntries(); + for (const QNetworkAddressEntry &entry : addrs) { + if (entry.ip() == local) { + outgoingIface = &iface; + break; + } + } + if (outgoingIface) + break; + } + QVERIFY(outgoingIface); + + // we get QVariant() if the QNativeSocketEngine doesn't know how to get the PMTU + int pmtu = socket.socketOption(QAbstractSocket::PathMtuSocketOption).toInt(); + qDebug() << "Connected to" << target.toString() << "via interface" << outgoingIface->name() + << "pmtu" << pmtu; + + // check that the Path MTU is less than or equal the interface's MTU + QVERIFY(pmtu <= outgoingIface->maxTransmissionUnit()); } void tst_QNetworkInterface::interfaceFromXXX_data() |