summaryrefslogtreecommitdiffstats
path: root/src/network/socket/qnativesocketengine_unix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/socket/qnativesocketengine_unix.cpp')
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp45
1 files changed, 25 insertions, 20 deletions
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index bcd9aecdea9..430197ccc6e 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -33,7 +33,7 @@
#include <sys/socket.h>
#include <netinet/sctp.h>
#endif
-#ifdef Q_OS_BSD4
+#ifdef AF_LINK
# include <net/if_dl.h>
#endif
@@ -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;
@@ -326,6 +322,11 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co
*/
bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt, int v)
{
+#ifdef QNATIVESOCKETENGINE_DEBUG
+# define perrorDebug(msg) perror("QNativeSocketEnginePrivate::setOption(): " msg)
+#else
+# define perrorDebug(msg) (void)0
+#endif
Q_Q(QNativeSocketEngine);
if (!q->isValid())
return false;
@@ -337,25 +338,16 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
#if !defined(Q_OS_VXWORKS)
int flags = ::fcntl(socketDescriptor, F_GETFL, 0);
if (flags == -1) {
-#ifdef QNATIVESOCKETENGINE_DEBUG
- perror("QNativeSocketEnginePrivate::setOption(): fcntl(F_GETFL) failed");
-#endif
+ perrorDebug("fcntl(F_GETFL) failed");
return false;
}
if (::fcntl(socketDescriptor, F_SETFL, flags | O_NONBLOCK) == -1) {
-#ifdef QNATIVESOCKETENGINE_DEBUG
- perror("QNativeSocketEnginePrivate::setOption(): fcntl(F_SETFL) failed");
-#endif
+ perrorDebug("fcntl(F_SETFL) failed");
return false;
}
#else // Q_OS_VXWORKS
- int onoff = 1;
-
- if (qt_safe_ioctl(socketDescriptor, FIONBIO, &onoff) < 0) {
-
-#ifdef QNATIVESOCKETENGINE_DEBUG
- perror("QNativeSocketEnginePrivate::setOption(): ioctl(FIONBIO, 1) failed");
-#endif
+ if (qt_safe_ioctl(socketDescriptor, FIONBIO, &v) < 0) {
+ perrorDebug("ioctl(FIONBIO, 1) failed");
return false;
}
#endif // Q_OS_VXWORKS
@@ -364,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;
@@ -417,6 +421,7 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
if (n == -1)
return false;
return ::setsockopt(socketDescriptor, level, n, (char *) &v, sizeof(v)) == 0;
+#undef perrorDebug
}
bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 port)
@@ -918,7 +923,7 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS
{
// we use quintptr to force the alignment
quintptr cbuf[(CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int))
-#if !defined(IP_PKTINFO) && defined(IP_RECVIF) && defined(Q_OS_BSD4)
+#if !defined(IP_PKTINFO) && defined(IP_RECVIF) && defined(AF_LINK)
+ CMSG_SPACE(sizeof(sockaddr_dl))
#endif
#ifndef QT_NO_SCTP
@@ -1010,7 +1015,7 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS
header->destinationAddress.setAddress(ntohl(addr->s_addr));
}
# endif
-# if defined(IP_RECVIF) && defined(Q_OS_BSD4)
+# if defined(IP_RECVIF) && defined(AF_LINK)
if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_RECVIF
&& cmsgptr->cmsg_len >= CMSG_LEN(sizeof(sockaddr_dl))) {
sockaddr_dl *sdl = reinterpret_cast<sockaddr_dl *>(CMSG_DATA(cmsgptr));