summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2010-08-06 06:16:02 (GMT)
committerBradley T. Hughes <bradley.hughes@nokia.com>2010-09-01 12:24:47 (GMT)
commita06052ce8212f3ab35e9b89573b92322a3978bc6 (patch)
treed56e80eee4231a118419b8b022340b4a8dafdc37
parent615e39c255e39c4372602daf44ce8576c257c845 (diff)
downloadQt-a06052ce8212f3ab35e9b89573b92322a3978bc6.zip
Qt-a06052ce8212f3ab35e9b89573b92322a3978bc6.tar.gz
Qt-a06052ce8212f3ab35e9b89573b92322a3978bc6.tar.bz2
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).
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp13
1 files 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