summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp16
-rw-r--r--tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp31
2 files changed, 42 insertions, 5 deletions
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index 120d2ecbc78..885af248ea7 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -142,10 +142,6 @@ static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt,
level = IPPROTO_IP;
#ifdef IP_PKTINFO
n = IP_PKTINFO;
-#elif defined(IP_RECVDSTADDR)
- // variant found in QNX and FreeBSD; it will get us only the
- // destination address, not the interface; we need IP_RECVIF for that.
- n = IP_RECVDSTADDR;
#endif
}
break;
@@ -360,6 +356,18 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
case QNativeSocketEngine::BindExclusively:
return true;
+ case QNativeSocketEngine::ReceivePacketInformation:
+ if (socketProtocol == QAbstractSocket::IPv4Protocol) {
+#if !defined(IP_PKTINFO) && defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
+ // Seen on FreeBSD and QNX. We need both to get the information we want.
+ int r = 0;
+ r += ::setsockopt(socketDescriptor, IPPROTO_IP, IP_RECVDSTADDR, &v, sizeof(v));
+ r += ::setsockopt(socketDescriptor, IPPROTO_IP, IP_RECVIF, &v, sizeof(v));
+ return r == 0;
+#endif
+ }
+ break;
+
case QNativeSocketEngine::MaxStreamsSocketOption: {
#ifndef QT_NO_SCTP
sctp_initmsg sctpInitMsg;
diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
index 4814206cd75..7d52c9cc01a 100644
--- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
+++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
@@ -132,6 +132,7 @@ private:
bool m_skipUnsupportedIPv6Tests;
bool m_workaroundLinuxKernelBug;
+ int loopbackInterface = 0; // unknown by default
QList<QHostAddress> allAddresses;
QHostAddress multicastGroup4, multicastGroup6;
QList<QHostAddress> linklocalMulticastGroups;
@@ -246,7 +247,23 @@ void tst_QUdpSocket::initTestCase()
if (!QtNetworkSettings::verifyTestNetworkSettings())
QSKIP("No network test server available");
#endif
- allAddresses = QNetworkInterface::allAddresses();
+
+ allAddresses.clear();
+ for (const QNetworkInterface &iface : QNetworkInterface::allInterfaces()) {
+ if (!iface.flags().testAnyFlags(QNetworkInterface::IsUp))
+ continue;
+ if (iface.flags().testAnyFlags(QNetworkInterface::IsLoopBack))
+ loopbackInterface = iface.index();
+
+ // add this interface's addresses
+ const QList<QNetworkAddressEntry> addresses = iface.addressEntries();
+ for (const QNetworkAddressEntry &entry : addresses) {
+ allAddresses += entry.ip();
+ if (!loopbackInterface && entry.ip().isLoopback())
+ loopbackInterface = iface.index();
+ }
+ }
+
m_skipUnsupportedIPv6Tests = shouldSkipIpv6TestsForBrokenSetsockopt();
// Create a pair of random multicast groups so we avoid clashing with any
@@ -754,6 +771,11 @@ void tst_QUdpSocket::loop()
QCOMPARE(paulDatagram.destinationAddress(), makeNonAny(paul.localAddress()));
QVERIFY(peterDatagram.destinationAddress().isEqual(makeNonAny(peter.localAddress())));
QVERIFY(paulDatagram.destinationAddress().isEqual(makeNonAny(paul.localAddress())));
+
+ if (loopbackInterface) {
+ QCOMPARE(peterDatagram.interfaceIndex(), loopbackInterface);
+ QCOMPARE(paulDatagram.interfaceIndex(), loopbackInterface);
+ }
}
}
@@ -820,6 +842,11 @@ void tst_QUdpSocket::ipv6Loop()
QCOMPARE(paulDatagram.destinationAddress(), makeNonAny(paul.localAddress()));
QCOMPARE(peterDatagram.destinationPort(), peterPort);
QCOMPARE(paulDatagram.destinationPort(), paulPort);
+
+ if (loopbackInterface) {
+ QCOMPARE(peterDatagram.interfaceIndex(), loopbackInterface);
+ QCOMPARE(paulDatagram.interfaceIndex(), loopbackInterface);
+ }
}
void tst_QUdpSocket::dualStack()
@@ -895,6 +922,8 @@ void tst_QUdpSocket::dualStack()
if (dgram.destinationPort() != -1) {
QCOMPARE(dgram.destinationPort(), int(v4Sock.localPort()));
QCOMPARE(dgram.destinationAddress(), makeNonAny(v4Sock.localAddress(), QHostAddress::LocalHost));
+ if (loopbackInterface)
+ QCOMPARE(dgram.interfaceIndex(), loopbackInterface);
}
}