From 4ef269963bad7a76ed03e81b91b94058c812e31b Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Mon, 2 May 2016 12:08:00 +0300 Subject: Avoid use of v4-mapped QHostAddress::AnyIPv4 local address on Windows Some Windows kernels return a v4-mapped QHostAddress::AnyIPv4 as a local address of the socket which bound on both IPv4 and IPv6 interfaces. This address does not match to any special address and should not be used to send the data. To allow handling of the local addresses properly, replace it with QHostAddress::Any. Already tested by tst_qudpsocket. Task-number: QTBUG-52714 Change-Id: Icb7cb75f48cd7ec9b0a9dfaf861ffe0d3093e20d Reviewed-by: Thiago Macieira --- src/network/socket/qnativesocketengine_win.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 770bae7bf3..41834b21ae 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -573,6 +573,19 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() } } + // Some Windows kernels return a v4-mapped QHostAddress::AnyIPv4 as a + // local address of the socket which bound on both IPv4 and IPv6 interfaces. + // This address does not match to any special address and should not be used + // to send the data. So, replace it with QHostAddress::Any. + if (socketProtocol == QAbstractSocket::IPv6Protocol) { + bool ok = false; + const quint32 localIPv4 = localAddress.toIPv4Address(&ok); + if (ok && localIPv4 == INADDR_ANY) { + socketProtocol = QAbstractSocket::AnyIPProtocol; + localAddress = QHostAddress::Any; + } + } + memset(&sa, 0, sizeof(sa)); if (::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0) { qt_socket_getPortAndAddress(socketDescriptor, &sa, &peerPort, &peerAddress); -- cgit v1.2.3