diff options
author | Robin Burchell <robin+qt@viroteck.net> | 2012-03-30 16:23:24 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-04-02 12:49:38 +0200 |
commit | c82d40749dc1ce816333e84d7f3232e59fbe2058 (patch) | |
tree | 340231cf80134be4ac7b3b82cbd522ec320a3e5d /src/network/socket | |
parent | c7f8f459bd9bb388aa06d2fb4564012d3eec3906 (diff) |
Fix multicast join/leave when binding to QHostAddress::Any.
On OS X and Windows, this was not working, because the socket was being bound
in v6 mode (due to ::Any being for dual mode), but the address passed was a v4
address, meaning it took the wrong codepath. Linux, strangely, apparently works
anyway.
This is fixable in OS X (by using the v6 join path when bound in v6/dual mode),
but the same fix doesn't work on Windows, failing with WSAEADDRNOTAVAIL.
Don't allow this behaviour, and provide a sane error message telling the user
what to do instead.
Done-with: Shane Kearns
Task-number: QTBUG-25047
Change-Id: Iaf5bbee82e13ac92e11b60c558f5af9ce26f474b
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
Diffstat (limited to 'src/network/socket')
-rw-r--r-- | src/network/socket/qnativesocketengine.cpp | 13 | ||||
-rw-r--r-- | src/network/socket/qudpsocket.cpp | 4 |
2 files changed, 17 insertions, 0 deletions
diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp index a34b19f7ef..8fac3613c0 100644 --- a/src/network/socket/qnativesocketengine.cpp +++ b/src/network/socket/qnativesocketengine.cpp @@ -637,6 +637,19 @@ bool QNativeSocketEngine::joinMulticastGroup(const QHostAddress &groupAddress, Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::joinMulticastGroup(), false); Q_CHECK_STATE(QNativeSocketEngine::joinMulticastGroup(), QAbstractSocket::BoundState, false); Q_CHECK_TYPE(QNativeSocketEngine::joinMulticastGroup(), QAbstractSocket::UdpSocket, false); + + // if the user binds a socket to an IPv6 address (or QHostAddress::Any) and + // then attempts to join an IPv4 multicast group, this won't work on + // Windows. In order to make this cross-platform, we warn & fail on all + // platforms. + if (groupAddress.protocol() == QAbstractSocket::IPv4Protocol && + (d->socketProtocol == QAbstractSocket::IPv6Protocol || + d->socketProtocol == QAbstractSocket::AnyIPProtocol)) { + qWarning("QAbstractSocket: cannot bind to QHostAddress::Any (or an IPv6 address) and join an IPv4 multicast group"); + qWarning("QAbstractSocket: bind to QHostAddress::AnyIPv4 instead if you want to do this"); + return false; + } + return d->nativeJoinMulticastGroup(groupAddress, iface); } diff --git a/src/network/socket/qudpsocket.cpp b/src/network/socket/qudpsocket.cpp index ec751c289e..23c1956ec5 100644 --- a/src/network/socket/qudpsocket.cpp +++ b/src/network/socket/qudpsocket.cpp @@ -178,6 +178,10 @@ QUdpSocket::~QUdpSocket() interface chosen by the operating system. The socket must be in BoundState, otherwise an error occurs. + Note that if you are attempting to join an IPv4 group, your socket must not + be bound using IPv6 (or in dual mode, using QHostAddress::Any). You must use + QHostAddress::AnyIPv4 instead. + This function returns true if successful; otherwise it returns false and sets the socket error accordingly. |