summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Burchell <robin+qt@viroteck.net>2012-03-30 19:21:40 (GMT)
committerQt by Nokia <qt-info@nokia.com>2012-04-03 13:07:13 (GMT)
commitda3baf5e2b9fb9ea1a57b35a757c7c8b850e9a56 (patch)
tree762d60e13ea9e00fc6c36c78d76fa39009474197
parent8fb24b24e2986943c0838d3e3680a3064c963b1c (diff)
downloadQt-da3baf5e2b9fb9ea1a57b35a757c7c8b850e9a56.zip
Qt-da3baf5e2b9fb9ea1a57b35a757c7c8b850e9a56.tar.gz
Qt-da3baf5e2b9fb9ea1a57b35a757c7c8b850e9a56.tar.bz2
Fix QTcpServer::listen() returning true when the port is in use on OS X.
Way back in the mists of time, someone added SO_REUSEPORT to socket binding, which was great, because otherwise it meant that multiple UDP sockets couldn't share the same port on OS X (as platforms with SO_REUSEPORT apparently don't support rebinding with SO_REUSEADDR). However: SO_REUSEPORT also means that *any* bind on a port will succeed, which is most definitely not wanted in the case of TCP sockets, so check the socket type before performing the actual bind. Also test that multiple listens don't take effect. Cherry-picked-from: qtbase/master/a84b42e6194be0f40bd8f961effef9947c07c832 Change-Id: I2f8d450bcfb8a7f3abd8918a4e789a850281dd13 Done-with: Thiago Macieira Done-with: Shane Kearns Task-number: QTBUG-6305 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp8
-rw-r--r--tests/auto/qtcpserver/tst_qtcpserver.cpp17
2 files changed, 24 insertions, 1 deletions
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index b32755d..0a087d5 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -325,7 +325,13 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
}
case QNativeSocketEngine::AddressReusable:
#if defined(SO_REUSEPORT)
- n = SO_REUSEPORT;
+ // on OS X, SO_REUSEADDR isn't sufficient to allow multiple binds to the
+ // same port (which is useful for multicast UDP). SO_REUSEPORT is, but
+ // we most definitely do not want to use this for TCP. See QTBUG-6305.
+ if (socketType == QAbstractSocket::UdpSocket)
+ n = SO_REUSEPORT;
+ else
+ n = SO_REUSEADDR;
#else
n = SO_REUSEADDR;
#endif
diff --git a/tests/auto/qtcpserver/tst_qtcpserver.cpp b/tests/auto/qtcpserver/tst_qtcpserver.cpp
index 9f862b9..0052518 100644
--- a/tests/auto/qtcpserver/tst_qtcpserver.cpp
+++ b/tests/auto/qtcpserver/tst_qtcpserver.cpp
@@ -113,6 +113,8 @@ private slots:
void qtbug14268_peek();
+ void qtbug6305();
+
private:
#ifndef QT_NO_BEARERMANAGEMENT
QNetworkSession *networkSession;
@@ -788,5 +790,20 @@ void tst_QTcpServer::qtbug14268_peek()
QVERIFY(helper.lastDataPeeked == QByteArray("6162630a6465660a6768690a"));
}
+// on OS X, calling listen() multiple times would succeed each time, which is
+// most definitely not wanted.
+void tst_QTcpServer::qtbug6305()
+{
+ QFETCH_GLOBAL(bool, setProxy);
+ if (setProxy)
+ return;
+
+ QTcpServer server;
+ QVERIFY2(server.listen(QHostAddress::Any), qPrintable(server.errorString()));
+
+ QTcpServer server2;
+ QVERIFY(!server2.listen(QHostAddress::Any, server.serverPort())); // second listen should fail
+}
+
QTEST_MAIN(tst_QTcpServer)
#include "tst_qtcpserver.moc"