From a06052ce8212f3ab35e9b89573b92322a3978bc6 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 6 Aug 2010 08:16:02 +0200 Subject: Fix IPv6 multicast on UNIX The setsockopt() to join/leave a group should change level depending on the type of socket/address being used (and not always use IPPROTO_IP). --- src/network/socket/qnativesocketengine_unix.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index e7f6c7e..360dab5 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -635,6 +635,7 @@ static bool multicastMembershipHelper(QNativeSocketEnginePrivate *d, const QHostAddress &groupAddress, const QNetworkInterface &interface) { + int level = 0; int sockOpt = 0; void *sockArg; int sockArgSize; @@ -644,7 +645,8 @@ static bool multicastMembershipHelper(QNativeSocketEnginePrivate *d, ipv6_mreq mreq6; if (groupAddress.protocol() == QAbstractSocket::IPv6Protocol) { - sockOpt = how6; + level = IPPROTO_IPV6; + sockOpt = how6; sockArg = &mreq6; sockArgSize = sizeof(mreq6); memset(&mreq6, 0, sizeof(mreq6)); @@ -654,6 +656,7 @@ static bool multicastMembershipHelper(QNativeSocketEnginePrivate *d, } else #endif if (groupAddress.protocol() == QAbstractSocket::IPv4Protocol) { + level = IPPROTO_IP; sockOpt = how4; sockArg = &mreq4; sockArgSize = sizeof(mreq4); @@ -680,13 +683,17 @@ static bool multicastMembershipHelper(QNativeSocketEnginePrivate *d, return false; } - int res = setsockopt(d->socketDescriptor, IPPROTO_IP, sockOpt, sockArg, sockArgSize); + int res = setsockopt(d->socketDescriptor, level, sockOpt, sockArg, sockArgSize); if (res == -1) { switch (errno) { case ENOPROTOOPT: d->setError(QAbstractSocket::UnsupportedSocketOperationError, QNativeSocketEnginePrivate::OperationUnsupportedErrorString); break; + case EADDRNOTAVAIL: + d->setError(QAbstractSocket::SocketAddressNotAvailableError, + QNativeSocketEnginePrivate::AddressNotAvailableErrorString); + break; default: d->setError(QAbstractSocket::UnknownSocketError, QNativeSocketEnginePrivate::UnknownSocketErrorString); @@ -763,7 +770,7 @@ bool QNativeSocketEnginePrivate::nativeSetMulticastInterface(const QNetworkInter { #ifndef QT_NO_IPV6 if (socketProtocol == QAbstractSocket::IPv6Protocol) { - uint v = iface.isValid() ? iface.index() : 0; + uint v = iface.index(); return (::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, &v, sizeof(v)) != -1); } #endif -- cgit v0.12