diff options
-rw-r--r-- | examples/network/multicastreceiver/receiver.cpp | 2 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine.cpp | 13 | ||||
-rw-r--r-- | src/network/socket/qudpsocket.cpp | 4 | ||||
-rw-r--r-- | tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp | 3 |
4 files changed, 21 insertions, 1 deletions
diff --git a/examples/network/multicastreceiver/receiver.cpp b/examples/network/multicastreceiver/receiver.cpp index 6448817410..041812f56a 100644 --- a/examples/network/multicastreceiver/receiver.cpp +++ b/examples/network/multicastreceiver/receiver.cpp @@ -52,7 +52,7 @@ Receiver::Receiver(QWidget *parent) quitButton = new QPushButton(tr("&Quit")); udpSocket = new QUdpSocket(this); - udpSocket->bind(45454, QUdpSocket::ShareAddress); + udpSocket->bind(QHostAddress::AnyIPv4, 45454, QUdpSocket::ShareAddress); udpSocket->joinMulticastGroup(groupAddress); connect(udpSocket, SIGNAL(readyRead()), 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. diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index c53450eec6..f63c593f91 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -1202,6 +1202,7 @@ void tst_QUdpSocket::multicast_data() QHostAddress groupAddress = QHostAddress("239.255.118.62"); QHostAddress any6Address = QHostAddress(QHostAddress::AnyIPv6); QHostAddress group6Address = QHostAddress("FF01::114"); + QHostAddress dualAddress = QHostAddress(QHostAddress::Any); QTest::addColumn<QHostAddress>("bindAddress"); QTest::addColumn<bool>("bindResult"); @@ -1213,6 +1214,8 @@ void tst_QUdpSocket::multicast_data() QTest::newRow("valid bind, group ipv6 address") << any6Address << true << group6Address << true; QTest::newRow("valid bind, invalid group ipv6 address") << any6Address << true << any6Address << false; QTest::newRow("same bind, group ipv6 address") << group6Address << true << group6Address << true; + QTest::newRow("dual bind, group ipv4 address") << dualAddress << true << groupAddress << false; + QTest::newRow("dual bind, group ipv6 address") << dualAddress << true << group6Address << true; } void tst_QUdpSocket::multicast() |