summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2012-05-09 16:13:59 (GMT)
committerQt by Nokia <qt-info@nokia.com>2012-05-24 03:39:37 (GMT)
commit1573663182afd3d3371c131c564f4aeaf99d63d7 (patch)
treef21438fd53297289bc9b6ba4ae0b49dc4bc072dc /src/network
parent5e905619285b538cd94882f44a39fe748206f1fb (diff)
downloadQt-1573663182afd3d3371c131c564f4aeaf99d63d7.zip
Qt-1573663182afd3d3371c131c564f4aeaf99d63d7.tar.gz
Qt-1573663182afd3d3371c131c564f4aeaf99d63d7.tar.bz2
Fix sending UDP packets to link local addresses
When the scope ID is not set, Mac and Windows will not transmit packets to link local addresses. This patch implements setting the scope in the native socket engines and adds a test case. (it was partially implemented already, though UDP specific code paths were missed in the unix engine) Task-number: QTBUG-25634 Change-Id: I23300bdc9856e38458078e913daaa59cd05a74b5 Reviewed-by: Martin Petersson <Martin.Petersson@nokia.com> (back ported from commit 6abc66e076826b24cc3700c3a0702f552ab50429) Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/network')
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp35
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp10
2 files changed, 27 insertions, 18 deletions
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index 0a087d5..b7b4f55 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -873,23 +873,30 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
#if !defined(QT_NO_IPV6)
struct sockaddr_in6 sockAddrIPv6;
if (host.protocol() == QAbstractSocket::IPv6Protocol) {
- memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6));
- sockAddrIPv6.sin6_family = AF_INET6;
- sockAddrIPv6.sin6_port = htons(port);
-
- Q_IPV6ADDR tmp = host.toIPv6Address();
- memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp));
- sockAddrSize = sizeof(sockAddrIPv6);
- sockAddrPtr = (struct sockaddr *)&sockAddrIPv6;
+ memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6));
+ sockAddrIPv6.sin6_family = AF_INET6;
+ sockAddrIPv6.sin6_port = htons(port);
+
+ Q_IPV6ADDR tmp = host.toIPv6Address();
+ memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp));
+ QString scopeid = host.scopeId();
+ bool ok;
+ sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok);
+#ifndef QT_NO_IPV6IFNAME
+ if (!ok)
+ sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1());
+#endif
+ sockAddrSize = sizeof(sockAddrIPv6);
+ sockAddrPtr = (struct sockaddr *)&sockAddrIPv6;
} else
#endif
if (host.protocol() == QAbstractSocket::IPv4Protocol) {
- memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4));
- sockAddrIPv4.sin_family = AF_INET;
- sockAddrIPv4.sin_port = htons(port);
- sockAddrIPv4.sin_addr.s_addr = htonl(host.toIPv4Address());
- sockAddrSize = sizeof(sockAddrIPv4);
- sockAddrPtr = (struct sockaddr *)&sockAddrIPv4;
+ memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4));
+ sockAddrIPv4.sin_family = AF_INET;
+ sockAddrIPv4.sin_port = htons(port);
+ sockAddrIPv4.sin_addr.s_addr = htonl(host.toIPv4Address());
+ sockAddrSize = sizeof(sockAddrIPv4);
+ sockAddrPtr = (struct sockaddr *)&sockAddrIPv4;
}
// ignore the SIGPIPE signal
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index d4b77a6..75cc052 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -176,10 +176,12 @@ static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, const qt
Q_IPV6ADDR tmp;
for (int i = 0; i < 16; ++i)
tmp.c[i] = sa6->sin6_addr.qt_s6_addr[i];
- QHostAddress a;
- a.setAddress(tmp);
- if (address)
- *address = a;
+ if (address) {
+ QHostAddress a;
+ a.setAddress(tmp);
+ a.setScopeId(QString::number(sa6->sin6_scope_id));
+ *address = a;
+ }
if (port)
WSANtohs(socketDescriptor, sa6->sin6_port, port);
} else