summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp15
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp16
-rw-r--r--tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp36
-rw-r--r--tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp4
4 files changed, 70 insertions, 1 deletions
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index ae7e239309..09aed255d6 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -922,6 +922,21 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters()
return false;
}
+#if defined (IPV6_V6ONLY)
+ // determine if local address is dual mode
+ int ipv6only = 0;
+ socklen_t optlen = sizeof(ipv6only);
+ if (localAddress == QHostAddress::AnyIPv6
+ && !getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, &optlen )) {
+ if (optlen != sizeof(ipv6only))
+ qWarning("unexpected size of IPV6_V6ONLY socket option");
+ if (!ipv6only) {
+ socketProtocol = QAbstractSocket::AnyIPProtocol;
+ localAddress = QHostAddress::Any;
+ }
+ }
+#endif
+
// Determine the remote address
if (!::getpeername(socketDescriptor, &sa.a, &sockAddrSize))
qt_socket_getPortAndAddress(&sa, &peerPort, &peerAddress);
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 4be930bb20..247de01072 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -554,6 +554,22 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters()
}
}
+#if defined (IPV6_V6ONLY)
+ // determine if local address is dual mode
+ DWORD ipv6only = 0;
+ int optlen = sizeof(ipv6only);
+ if (localAddress == QHostAddress::AnyIPv6
+ && QSysInfo::windowsVersion() >= QSysInfo::WV_6_0
+ && !getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, &optlen )) {
+ if (optlen != sizeof(ipv6only))
+ qWarning("unexpected size of IPV6_V6ONLY socket option");
+ if (!ipv6only) {
+ socketProtocol = QAbstractSocket::AnyIPProtocol;
+ localAddress = QHostAddress::Any;
+ }
+ }
+#endif
+
memset(&sa, 0, sizeof(sa));
if (::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0) {
qt_socket_getPortAndAddress(socketDescriptor, &sa, &peerPort, &peerAddress);
diff --git a/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp b/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp
index 0cdd3a7120..769544e17e 100644
--- a/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp
+++ b/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp
@@ -116,6 +116,8 @@ private slots:
void qtbug14268_peek();
+ void serverAddress_data();
+ void serverAddress();
private:
#ifndef QT_NO_BEARERMANAGEMENT
QNetworkSession *networkSession;
@@ -789,5 +791,39 @@ void tst_QTcpServer::qtbug14268_peek()
QVERIFY(helper.lastDataPeeked == QByteArray("6162630a6465660a6768690a"));
}
+void tst_QTcpServer::serverAddress_data()
+{
+ QTest::addColumn<QHostAddress>("listenAddress");
+ QTest::addColumn<QHostAddress>("serverAddress");
+#ifdef Q_OS_WIN
+ if (QSysInfo::windowsVersion() < QSysInfo::WV_6_0)
+ QTest::newRow("Any") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv4); //windows XP doesn't support dual stack sockets
+ else
+#endif
+ QTest::newRow("Any") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::Any);
+ QTest::newRow("AnyIPv4") << QHostAddress(QHostAddress::AnyIPv4) << QHostAddress(QHostAddress::AnyIPv4);
+ QTest::newRow("AnyIPv6") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv6);
+ foreach (const QHostAddress& addr, QNetworkInterface::allAddresses()) {
+ if (addr.isInSubnet(QHostAddress::parseSubnet("fe80::/10"))
+ || addr.isInSubnet(QHostAddress::parseSubnet("169.254/16")))
+ continue; //cannot bind on link local addresses
+ QTest::newRow(qPrintable(addr.toString())) << addr << addr;
+ }
+}
+
+void tst_QTcpServer::serverAddress()
+{
+ QFETCH_GLOBAL(bool, setProxy);
+ if (setProxy)
+ return;
+
+ QFETCH(QHostAddress, listenAddress);
+ QFETCH(QHostAddress, serverAddress);
+ QTcpServer server;
+ if (!server.listen(listenAddress))
+ QSKIP(qPrintable(server.errorString()));
+ QCOMPARE(server.serverAddress(), serverAddress);
+}
+
QTEST_MAIN(tst_QTcpServer)
#include "tst_qtcpserver.moc"
diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
index 9c87ac04a0..00a9ed2d40 100644
--- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
+++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
@@ -1542,7 +1542,9 @@ void tst_QTcpSocket::dontCloseOnTimeout()
QVERIFY(server.listen());
QHostAddress serverAddress = QHostAddress::LocalHost;
- if (!(server.serverAddress() == QHostAddress::AnyIPv4) && !(server.serverAddress() == QHostAddress::AnyIPv6))
+ if (!(server.serverAddress() == QHostAddress::AnyIPv4)
+ && !(server.serverAddress() == QHostAddress::AnyIPv6)
+ && !(server.serverAddress() == QHostAddress::Any))
serverAddress = server.serverAddress();
QTcpSocket *socket = newSocket();