summaryrefslogtreecommitdiffstats
path: root/src/network/socket/qnativesocketengine_unix.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2025-10-16 10:09:03 -0700
committerThiago Macieira <thiago.macieira@intel.com>2025-10-21 16:56:17 -0700
commitaaf908e3cf90cab8e203b7343e9e3dbd150c243f (patch)
treea3a68779d6d3a3d03823798e861d2a711f5a26de /src/network/socket/qnativesocketengine_unix.cpp
parent9c77130f5617232b2aab85a8a76ec346015d708d (diff)
QNativeSocketEngine/Unix: implement IP_RECVIF in setOption()
This amends and complements abe269bb72233b360bccbc8f54d3f13e8dc10b5a, which added QNativeSocketEngine::ReceivePacketInformation and actually did implement the heretofore-dead code to handle the IP_RECVIF ancilary data in nativeReceiveDatagram(), but we never asked the OS for the information via setsockopt(). Similar to what e9778dfe6ead0c4d704570816a56aead084a0263 did for Windows. Tested on FreeBSD. dtruss says: socket(PF_INET,SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK,0) = 7 (0x7) setsockopt(7,SOL_SOCKET,SO_BROADCAST,0xb1cf40aece4,4) = 0 (0x0) setsockopt(7,IPPROTO_IP,IP_RECVDSTADDR,0xb1cf40aece4,4) = 0 (0x0) setsockopt(7,IPPROTO_IP,IP_RECVIF,0xb1cf40aece4,4) = 0 (0x0) setsockopt(7,IPPROTO_IP,IP_RECVTTL,0xb1cf40aece4,4) = 0 (0x0) bind(7,{ AF_INET 127.0.0.1:0 },16) = 0 (0x0) ... ppoll({ 7/POLLIN },1,{ 8.999999439 },0x0) = 1 (0x1) recvfrom(7,"@",1,MSG_PEEK,NULL,0x0) = 1 (0x1) recvmsg(7,{{ AF_INET 127.0.0.1:55621 },16,[{"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"...,1200}],1, { {level=IPPROTO_IP,type=IP_RECVDSTADDR,data={0x7f,0x00,0x00,0x01}}, {level=IPPROTO_IP,type=IP_RECVTTL,data={0x40}}, {level=IPPROTO_IP,type=IP_RECVIF,data={0x38,0x12,0x02,0x00,0x18,0x03,0x00,0x00,0x6c,0x6f,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} },120,0},0) = 600 (0x258) lldb decodes the sockaddr_dl as: (lldb) p *sdl (sockaddr_dl) { sdl_len = '8' sdl_family = '\x12' sdl_index = 2 sdl_type = '\x18' sdl_nlen = '\x03' sdl_alen = '\0' sdl_slen = '\0' sdl_data = "lo0" } And interface index 2 is lo0: lo0: flags=1008049<UP,LOOPBACK,RUNNING,MULTICAST,LOWER_UP> metric 0 mtu 16384 options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6> inet 127.0.0.1 netmask 0xff000000 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 groups: lo nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> Change-Id: I37b88bfce40421117d99fffd1110eced5d102430 Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/network/socket/qnativesocketengine_unix.cpp')
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp16
1 files changed, 12 insertions, 4 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;