From 08e45154fb508162cb4bab104f6a7c9d00c2e50d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 5 Mar 2015 22:25:45 -0800 Subject: QtNetwork: Fix const correctness in old style casts Found with GCC's -Wcast-qual. Change-Id: Ia0aac2f09e9245339951ffff13c946859c282001 Reviewed-by: Richard J. Moore --- src/network/ssl/qsslcertificate_openssl.cpp | 2 +- src/network/ssl/qsslkey_openssl.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/network') diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp index 0ef845bf55..ad88ea5d56 100644 --- a/src/network/ssl/qsslcertificate_openssl.cpp +++ b/src/network/ssl/qsslcertificate_openssl.cpp @@ -691,7 +691,7 @@ QList QSslCertificatePrivate::certificatesFromDer(const QByteAr } else { break; } - size -= ((char *)data - der.data()); + size -= ((const char *)data - der.data()); } return certificates; diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp index 8741ab524f..33cb81ce71 100644 --- a/src/network/ssl/qsslkey_openssl.cpp +++ b/src/network/ssl/qsslkey_openssl.cpp @@ -139,7 +139,7 @@ void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhra if (!bio) return; - void *phrase = (void *)passPhrase.constData(); + void *phrase = const_cast(passPhrase.constData()); if (algorithm == QSsl::Rsa) { RSA *result = (type == QSsl::PublicKey) @@ -201,7 +201,7 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const bio, rsa, // ### the cipher should be selectable in the API: passPhrase.isEmpty() ? (const EVP_CIPHER *)0 : q_EVP_des_ede3_cbc(), - (uchar *)passPhrase.data(), passPhrase.size(), 0, 0)) { + const_cast((const uchar *)passPhrase.data()), passPhrase.size(), 0, 0)) { fail = true; } } @@ -214,7 +214,7 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const bio, dsa, // ### the cipher should be selectable in the API: passPhrase.isEmpty() ? (const EVP_CIPHER *)0 : q_EVP_des_ede3_cbc(), - (uchar *)passPhrase.data(), passPhrase.size(), 0, 0)) { + const_cast((const uchar *)passPhrase.data()), passPhrase.size(), 0, 0)) { fail = true; } } @@ -228,7 +228,7 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const bio, ec, // ### the cipher should be selectable in the API: passPhrase.isEmpty() ? (const EVP_CIPHER *)0 : q_EVP_des_ede3_cbc(), - (uchar *)passPhrase.data(), passPhrase.size(), 0, 0)) { + const_cast((const uchar *)passPhrase.data()), passPhrase.size(), 0, 0)) { fail = true; } } -- cgit v1.2.3 From aa246e487cc2daeee43e478dc969fa5649cafef4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 5 Mar 2015 23:39:22 -0800 Subject: QHostAddress: add IPv6 address overloads that take const data It has been a historical mistake that there wasn't a const overload. Change-Id: Ia0aac2f09e9245339951ffff13c8d8b70f206a99 Reviewed-by: Giuseppe D'Angelo Reviewed-by: Richard J. Moore --- src/network/kernel/qhostaddress.cpp | 35 +++++++++++++++++++++++++++++++---- src/network/kernel/qhostaddress.h | 6 ++++-- 2 files changed, 35 insertions(+), 6 deletions(-) (limited to 'src/network') diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index 9a993392e9..58c0de1f3b 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -414,6 +414,19 @@ QHostAddress::QHostAddress(quint8 *ip6Addr) setAddress(ip6Addr); } +/*! + \since 5.5 + Constructs a host address object with the IPv6 address \a ip6Addr. + + \a ip6Addr must be a 16-byte array in network byte order (big + endian). +*/ +QHostAddress::QHostAddress(const quint8 *ip6Addr) + : d(new QHostAddressPrivate) +{ + setAddress(ip6Addr); +} + /*! Constructs a host address object with the IPv6 address \a ip6Addr. */ @@ -449,9 +462,9 @@ QHostAddress::QHostAddress(const struct sockaddr *sockaddr) { #ifndef Q_OS_WINRT if (sockaddr->sa_family == AF_INET) - setAddress(htonl(((sockaddr_in *)sockaddr)->sin_addr.s_addr)); + setAddress(htonl(((const sockaddr_in *)sockaddr)->sin_addr.s_addr)); else if (sockaddr->sa_family == AF_INET6) - setAddress(((qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr); + setAddress(((const qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr); #else Q_UNUSED(sockaddr) #endif @@ -573,6 +586,20 @@ void QHostAddress::setAddress(quint8 *ip6Addr) d->setAddress(ip6Addr); } +/*! + \overload + \since 5.5 + + Set the IPv6 address specified by \a ip6Addr. + + \a ip6Addr must be an array of 16 bytes in network byte order + (high-order byte first). +*/ +void QHostAddress::setAddress(const quint8 *ip6Addr) +{ + d->setAddress(ip6Addr); +} + /*! \overload @@ -610,9 +637,9 @@ void QHostAddress::setAddress(const struct sockaddr *sockaddr) #ifndef Q_OS_WINRT clear(); if (sockaddr->sa_family == AF_INET) - setAddress(htonl(((sockaddr_in *)sockaddr)->sin_addr.s_addr)); + setAddress(htonl(((const sockaddr_in *)sockaddr)->sin_addr.s_addr)); else if (sockaddr->sa_family == AF_INET6) - setAddress(((qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr); + setAddress(((const qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr); #else Q_UNUSED(sockaddr) #endif diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h index de3a79278e..0c2229c334 100644 --- a/src/network/kernel/qhostaddress.h +++ b/src/network/kernel/qhostaddress.h @@ -75,7 +75,8 @@ public: QHostAddress(); explicit QHostAddress(quint32 ip4Addr); - explicit QHostAddress(quint8 *ip6Addr); + explicit QHostAddress(quint8 *ip6Addr); // ### Qt 6: remove me + explicit QHostAddress(const quint8 *ip6Addr); explicit QHostAddress(const Q_IPV6ADDR &ip6Addr); explicit QHostAddress(const sockaddr *address); explicit QHostAddress(const QString &address); @@ -87,7 +88,8 @@ public: QHostAddress &operator=(const QString &address); void setAddress(quint32 ip4Addr); - void setAddress(quint8 *ip6Addr); + void setAddress(quint8 *ip6Addr); // ### Qt 6: remove me + void setAddress(const quint8 *ip6Addr); void setAddress(const Q_IPV6ADDR &ip6Addr); void setAddress(const sockaddr *address); bool setAddress(const QString &address); -- cgit v1.2.3 From e5e1e056e8141e97321bde1ed0ce109fe8f19890 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 5 Mar 2015 15:23:53 -0800 Subject: Silence MSVC warning about 64-bit conversion (loss of data) One of the reasons why we use "int" everywhere: to avoid this annoyance about different types and having to explicitly cast to silence the compiler. qsslsocket_openssl.cpp(690) : warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data Change-Id: Ia0aac2f09e9245339951ffff13c8bdad334ce108 Reviewed-by: Richard J. Moore --- src/network/ssl/qsslsocket_openssl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/network') diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 4c1fc0f768..4d092a8109 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -687,7 +687,7 @@ void QSslSocketPrivate::resetDefaultEllipticCurves() if (q_EC_get_builtin_curves(builtinCurves.data(), curveCount) == curveCount) { for (size_t i = 0; i < curveCount; ++i) { QSslEllipticCurve curve; - curve.id = builtinCurves[i].nid; + curve.id = builtinCurves[int(i)].nid; curves.append(curve); } } -- cgit v1.2.3 From 53207e820c894a1408aa77aa2237cc664eabc119 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 2 Mar 2015 17:29:55 +0100 Subject: Secure Transport - handle errSSLBadCert in server mode Suddenly :(( With Security Framework v 7.0 dated by 17/02 SSLHandshake works differently when our server socket is requesting a client side authentication and client provides no certificate. Despite of kTryAuthenticate (this means, auth. _can_ fail) server receives an error from SSLHandshake too early. We have to handle this in startHandshake (when serveMode && canIgnore). Change-Id: Ie55540078e2944e80cf2f4ade8b000acf29d6ca2 Reviewed-by: Richard J. Moore --- src/network/ssl/qsslsocket_mac.cpp | 21 +++++++++++++++++---- src/network/ssl/qsslsocket_mac_p.h | 1 + 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'src/network') diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 3326362d66..e833bb70c5 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -942,6 +942,15 @@ bool QSslSocketBackendPrivate::setSessionProtocol() return err == noErr; } +bool QSslSocketBackendPrivate::canIgnoreTrustVerificationFailure() const +{ + const QSslSocket::PeerVerifyMode verifyMode = configuration.peerVerifyMode; + return mode == QSslSocket::SslServerMode + && (verifyMode == QSslSocket::QueryPeer + || verifyMode == QSslSocket::AutoVerifyPeer + || verifyMode == QSslSocket::VerifyNone); +} + bool QSslSocketBackendPrivate::verifySessionProtocol() const { bool protocolOk = false; @@ -962,10 +971,7 @@ bool QSslSocketBackendPrivate::verifyPeerTrust() Q_Q(QSslSocket); const QSslSocket::PeerVerifyMode verifyMode = configuration.peerVerifyMode; - const bool canIgnoreVerify = mode == QSslSocket::SslServerMode - && (verifyMode == QSslSocket::QueryPeer - || verifyMode == QSslSocket::AutoVerifyPeer - || verifyMode == QSslSocket::VerifyNone); + const bool canIgnoreVerify = canIgnoreTrustVerificationFailure(); Q_ASSERT_X(context, Q_FUNC_INFO, "invalid SSL context (null)"); Q_ASSERT(plainSocket); @@ -1164,6 +1170,13 @@ bool QSslSocketBackendPrivate::startHandshake() return startHandshake(); } } else if (err != errSecSuccess) { + if (err == errSSLBadCert && canIgnoreTrustVerificationFailure()) { + // We're on the server side and client did not provide any + // certificate. This is the new 'nice' error returned by + // Security Framework after it was recently updated. + return startHandshake(); + } + setError(QStringLiteral("Error during SSL handshake: %1").arg(err), QAbstractSocket::SslHandshakeFailedError); plainSocket->disconnectFromHost(); diff --git a/src/network/ssl/qsslsocket_mac_p.h b/src/network/ssl/qsslsocket_mac_p.h index 4901a8576f..868b816957 100644 --- a/src/network/ssl/qsslsocket_mac_p.h +++ b/src/network/ssl/qsslsocket_mac_p.h @@ -94,6 +94,7 @@ private: QAbstractSocket::SocketError &errorCode); bool setSessionProtocol(); // Aux. functions to do a verification during handshake phase: + bool canIgnoreTrustVerificationFailure() const; bool verifySessionProtocol() const; bool verifyPeerTrust(); -- cgit v1.2.3 From f1a365dbd8843413a9d0dc1a53825459c9d9c939 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 9 Mar 2015 22:12:03 -0700 Subject: Make sure we also treat QAbstractSocket::AnyIPProtocol as IPv6 The native socket engine sets the socketProtocol to that when it means it's using IPv6 with v4 compatibility on (v6only = false). We mustn't have faced problems so far because the multicast tests set don't test v6only = false. Change-Id: Iee8cbc07c4434ce9b560ffff13ca0aff60673940 Reviewed-by: Richard J. Moore --- src/network/socket/qnativesocketengine_unix.cpp | 14 +++++++------- src/network/socket/qnativesocketengine_win.cpp | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src/network') diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index da36e4a6da..f12aedef35 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -223,7 +223,7 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co n = SO_KEEPALIVE; break; case QNativeSocketEngine::MulticastTtlOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { level = IPPROTO_IPV6; n = IPV6_MULTICAST_HOPS; } else @@ -233,7 +233,7 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co } break; case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { level = IPPROTO_IPV6; n = IPV6_MULTICAST_LOOP; } else @@ -336,7 +336,7 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt n = SO_KEEPALIVE; break; case QNativeSocketEngine::MulticastTtlOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { level = IPPROTO_IPV6; n = IPV6_MULTICAST_HOPS; } else @@ -346,7 +346,7 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt } break; case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { level = IPPROTO_IPV6; n = IPV6_MULTICAST_LOOP; } else @@ -749,7 +749,7 @@ bool QNativeSocketEnginePrivate::nativeLeaveMulticastGroup(const QHostAddress &g QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const { - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { uint v; QT_SOCKOPTLEN_T sizeofv = sizeof(v); if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, &v, &sizeofv) == -1) @@ -779,7 +779,7 @@ QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const bool QNativeSocketEnginePrivate::nativeSetMulticastInterface(const QNetworkInterface &iface) { - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { uint v = iface.index(); return (::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, &v, sizeof(v)) != -1); } @@ -1037,7 +1037,7 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() #if defined (QNATIVESOCKETENGINE_DEBUG) QString socketProtocolStr = QStringLiteral("UnknownProtocol"); if (socketProtocol == QAbstractSocket::IPv4Protocol) socketProtocolStr = QStringLiteral("IPv4Protocol"); - else if (socketProtocol == QAbstractSocket::IPv6Protocol) socketProtocolStr = QStringLiteral("IPv6Protocol"); + else if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) socketProtocolStr = QStringLiteral("IPv6Protocol"); QString socketTypeStr = QStringLiteral("UnknownSocketType"); if (socketType == QAbstractSocket::TcpSocket) socketTypeStr = QStringLiteral("TcpSocket"); diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 3dff11ec32..a6e4b222cc 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -443,7 +443,7 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co break; case QNativeSocketEngine::MulticastTtlOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { level = IPPROTO_IPV6; n = IPV6_MULTICAST_HOPS; } else @@ -453,7 +453,7 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co } break; case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { level = IPPROTO_IPV6; n = IPV6_MULTICAST_LOOP; } else @@ -533,7 +533,7 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt n = SO_KEEPALIVE; break; case QNativeSocketEngine::MulticastTtlOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { level = IPPROTO_IPV6; n = IPV6_MULTICAST_HOPS; } else @@ -543,7 +543,7 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt } break; case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { level = IPPROTO_IPV6; n = IPV6_MULTICAST_LOOP; } else @@ -658,7 +658,7 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin setPortAndAddress(&sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize); - if (socketProtocol == QAbstractSocket::IPv6Protocol && address.toIPv4Address()) { + if ((socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) && address.toIPv4Address()) { //IPV6_V6ONLY option must be cleared to connect to a V4 mapped address if (QSysInfo::windowsVersion() >= QSysInfo::WV_6_0) { DWORD ipv6only = 0; @@ -1035,7 +1035,7 @@ bool QNativeSocketEnginePrivate::nativeLeaveMulticastGroup(const QHostAddress &g QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const { - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { uint v; QT_SOCKOPTLEN_T sizeofv = sizeof(v); if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &v, &sizeofv) == -1) @@ -1069,7 +1069,7 @@ QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const bool QNativeSocketEnginePrivate::nativeSetMulticastInterface(const QNetworkInterface &iface) { - if (socketProtocol == QAbstractSocket::IPv6Protocol) { + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { uint v = iface.isValid() ? iface.index() : 0; return (::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &v, sizeof(v)) != -1); } -- cgit v1.2.3 From bc59424ed496f298fb7ebb4ed0d946e85aae12a7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 8 Mar 2015 22:22:07 -0700 Subject: QNativeSocketEngine: merge duplicated code for sin6_scope_id Let's make sure we don't accidentally have it wrong in one of the three versions. Change-Id: Iee8cbc07c4434ce9b560ffff13c9bcf75ba66a66 Reviewed-by: Richard J. Moore --- src/network/socket/qnativesocketengine_unix.cpp | 47 ++++++++++--------------- 1 file changed, 18 insertions(+), 29 deletions(-) (limited to 'src/network') diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index f12aedef35..fe7864d7f3 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -127,6 +127,21 @@ static inline void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *po } } +static inline uint makeScopeId(const QHostAddress &addr) +{ + QString scopeid = addr.scopeId(); + if (scopeid.isEmpty()) + return 0; + + bool ok; + uint id = scopeid.toInt(&ok); +#ifndef QT_NO_IPV6IFNAME + if (!ok) + id = ::if_nametoindex(scopeid.toLatin1()); +#endif + return id; +} + /*! \internal Creates and returns a new socket descriptor of type \a socketType @@ -382,17 +397,8 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6)); sockAddrIPv6.sin6_family = AF_INET6; sockAddrIPv6.sin6_port = htons(port); + sockAddrIPv6.sin6_scope_id = makeScopeId(addr); - QString scopeid = addr.scopeId(); - - if (!scopeid.isEmpty()) { - bool ok; - sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); -#ifndef QT_NO_IPV6IFNAME - if (!ok) - sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1()); -#endif - } Q_IPV6ADDR ip6 = addr.toIPv6Address(); memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &ip6, sizeof(ip6)); @@ -501,16 +507,8 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6)); sockAddrIPv6.sin6_family = AF_INET6; sockAddrIPv6.sin6_port = htons(port); - QString scopeid = address.scopeId(); + sockAddrIPv6.sin6_scope_id = makeScopeId(address); - if (!scopeid.isEmpty()) { - bool ok; - sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); -#ifndef QT_NO_IPV6IFNAME - if (!ok) - sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1()); -#endif - } Q_IPV6ADDR tmp = address.toIPv6Address(); memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp)); sockAddrSize = sizeof(sockAddrIPv6); @@ -918,19 +916,10 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6)); sockAddrIPv6.sin6_family = AF_INET6; sockAddrIPv6.sin6_port = htons(port); + sockAddrIPv6.sin6_scope_id = makeScopeId(host); Q_IPV6ADDR tmp = host.toIPv6Address(); memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp)); - QString scopeid = host.scopeId(); - - if (!scopeid.isEmpty()) { - 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 if (host.protocol() == QAbstractSocket::IPv4Protocol) { -- cgit v1.2.3 From f5edf2b6fb20722bb63c8855793bc2552721748c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 8 Mar 2015 22:23:47 -0700 Subject: IPv6 scope IDs are unsigned We need to make sure that a large scope ID saved in a QString does get converted properly back to an integer. Change-Id: Iee8cbc07c4434ce9b560ffff13c9bd0e9008bd9c Reviewed-by: Richard J. Moore --- src/network/kernel/qnetworkinterface_unix.cpp | 2 +- src/network/socket/qnativesocketengine_unix.cpp | 2 +- src/network/socket/qnativesocketengine_win.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/network') diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp index 165d4eff7d..9c5ba4e799 100644 --- a/src/network/kernel/qnetworkinterface_unix.cpp +++ b/src/network/kernel/qnetworkinterface_unix.cpp @@ -100,7 +100,7 @@ static QHostAddress addressFromSockaddr(sockaddr *sa, int ifindex = 0, const QSt address.setScopeId(QLatin1String(scopeid)); } else #endif - address.setScopeId(QString::number(scope)); + address.setScopeId(QString::number(uint(scope))); } } return address; diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index fe7864d7f3..e7056ad250 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -134,7 +134,7 @@ static inline uint makeScopeId(const QHostAddress &addr) return 0; bool ok; - uint id = scopeid.toInt(&ok); + uint id = scopeid.toUInt(&ok); #ifndef QT_NO_IPV6IFNAME if (!ok) id = ::if_nametoindex(scopeid.toLatin1()); diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index a6e4b222cc..ab43f0a55e 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -209,7 +209,7 @@ void QNativeSocketEnginePrivate::setPortAndAddress(sockaddr_in * sockAddrIPv4, q || socketProtocol == QAbstractSocket::AnyIPProtocol) { memset(sockAddrIPv6, 0, sizeof(qt_sockaddr_in6)); sockAddrIPv6->sin6_family = AF_INET6; - sockAddrIPv6->sin6_scope_id = address.scopeId().toInt(); + sockAddrIPv6->sin6_scope_id = address.scopeId().toUInt(); WSAHtons(socketDescriptor, port, &(sockAddrIPv6->sin6_port)); Q_IPV6ADDR tmp = address.toIPv6Address(); memcpy(&(sockAddrIPv6->sin6_addr.qt_s6_addr), &tmp, sizeof(tmp)); -- cgit v1.2.3 From 32d1803d60d06b62a55e2cfb9f084eb9e527cc54 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 13 Mar 2015 18:12:05 +0100 Subject: Please valgrind by not accessing uninitialized memory Fix access or uninitialized memory. It is safe in this case, but causes valgrind's memcheck to complain unnecessarily. Change-Id: I01ad09d282b07f7099ad6bed85f4327b3c7c677f Reviewed-by: Thiago Macieira --- src/network/ssl/qsslkey_p.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/network') diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h index acd16044e8..be981bb484 100644 --- a/src/network/ssl/qsslkey_p.h +++ b/src/network/ssl/qsslkey_p.h @@ -61,9 +61,10 @@ class QSslKeyPrivate { public: inline QSslKeyPrivate() - : opaque(0) + : algorithm(QSsl::Opaque) + , opaque(0) { - clear(); + clear(false); } inline ~QSslKeyPrivate() -- cgit v1.2.3 From d1cd75e81af809a46fcf40cd2b39858e238a4d97 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 10 Mar 2015 14:45:18 -0700 Subject: QNativeSocketEngine: merge the get/setsockopt level constants No point in having them separate, as that's a recipe for mistakes. Change-Id: Iee8cbc07c4434ce9b560ffff13ca4132cd1879ed Reviewed-by: Richard J. Moore --- src/network/socket/qnativesocketengine_unix.cpp | 193 ++++++++++-------------- src/network/socket/qnativesocketengine_win.cpp | 165 +++++++++----------- 2 files changed, 151 insertions(+), 207 deletions(-) (limited to 'src/network') diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index e7056ad250..4648a3cb5a 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Intel Corporation. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtNetwork module of the Qt Toolkit. @@ -142,6 +143,68 @@ static inline uint makeScopeId(const QHostAddress &addr) return id; } +static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt, + QAbstractSocket::NetworkLayerProtocol socketProtocol, int &level, int &n) +{ + n = -1; + level = SOL_SOCKET; // default + + switch (opt) { + case QNativeSocketEngine::NonBlockingSocketOption: // fcntl, not setsockopt + case QNativeSocketEngine::BindExclusively: // not handled on Unix + Q_UNREACHABLE(); + + case QNativeSocketEngine::BroadcastSocketOption: + n = SO_BROADCAST; + break; + case QNativeSocketEngine::ReceiveBufferSocketOption: + n = SO_RCVBUF; + break; + case QNativeSocketEngine::SendBufferSocketOption: + n = SO_SNDBUF; + break; + case QNativeSocketEngine::AddressReusable: + n = SO_REUSEADDR; + break; + case QNativeSocketEngine::ReceiveOutOfBandData: + n = SO_OOBINLINE; + break; + case QNativeSocketEngine::LowDelayOption: + level = IPPROTO_TCP; + n = TCP_NODELAY; + break; + case QNativeSocketEngine::KeepAliveOption: + n = SO_KEEPALIVE; + break; + case QNativeSocketEngine::MulticastTtlOption: + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { + level = IPPROTO_IPV6; + n = IPV6_MULTICAST_HOPS; + } else + { + level = IPPROTO_IP; + n = IP_MULTICAST_TTL; + } + break; + case QNativeSocketEngine::MulticastLoopbackOption: + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { + level = IPPROTO_IPV6; + n = IPV6_MULTICAST_LOOP; + } else + { + level = IPPROTO_IP; + n = IP_MULTICAST_LOOP; + } + break; + case QNativeSocketEngine::TypeOfServiceOption: + if (socketProtocol == QAbstractSocket::IPv4Protocol) { + level = IPPROTO_IP; + n = IP_TOS; + } + break; + } +} + /*! \internal Creates and returns a new socket descriptor of type \a socketType @@ -208,65 +271,16 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co if (!q->isValid()) return -1; - int n = -1; - int level = SOL_SOCKET; // default - - switch (opt) { - case QNativeSocketEngine::ReceiveBufferSocketOption: - n = SO_RCVBUF; - break; - case QNativeSocketEngine::SendBufferSocketOption: - n = SO_SNDBUF; - break; - case QNativeSocketEngine::NonBlockingSocketOption: - break; - case QNativeSocketEngine::BroadcastSocketOption: - break; - case QNativeSocketEngine::AddressReusable: - n = SO_REUSEADDR; - break; - case QNativeSocketEngine::BindExclusively: + // handle non-getsockopt cases first + if (opt == QNativeSocketEngine::BindExclusively || opt == QNativeSocketEngine::NonBlockingSocketOption + || opt == QNativeSocketEngine::BroadcastSocketOption) return true; - case QNativeSocketEngine::ReceiveOutOfBandData: - n = SO_OOBINLINE; - break; - case QNativeSocketEngine::LowDelayOption: - level = IPPROTO_TCP; - n = TCP_NODELAY; - break; - case QNativeSocketEngine::KeepAliveOption: - n = SO_KEEPALIVE; - break; - case QNativeSocketEngine::MulticastTtlOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_HOPS; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_TTL; - } - break; - case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_LOOP; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_LOOP; - } - break; - case QNativeSocketEngine::TypeOfServiceOption: - if (socketProtocol == QAbstractSocket::IPv4Protocol) { - level = IPPROTO_IP; - n = IP_TOS; - } - break; - } + int n, level; int v = -1; QT_SOCKOPTLEN_T len = sizeof(v); + + convertToLevelAndOption(opt, socketProtocol, level, n); if (::getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1) return v; @@ -283,19 +297,8 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt if (!q->isValid()) return false; - int n = 0; - int level = SOL_SOCKET; // default - + // handle non-setsockopt cases first switch (opt) { - case QNativeSocketEngine::ReceiveBufferSocketOption: - n = SO_RCVBUF; - break; - case QNativeSocketEngine::SendBufferSocketOption: - n = SO_SNDBUF; - break; - case QNativeSocketEngine::BroadcastSocketOption: - n = SO_BROADCAST; - break; case QNativeSocketEngine::NonBlockingSocketOption: { // Make the socket nonblocking. #if !defined(Q_OS_VXWORKS) @@ -325,58 +328,24 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt #endif // Q_OS_VXWORKS return true; } - case QNativeSocketEngine::AddressReusable: + case QNativeSocketEngine::BindExclusively: + return true; + + default: + break; + } + + int n, level; + convertToLevelAndOption(opt, socketProtocol, level, n); #if defined(SO_REUSEPORT) + if (opt == QNativeSocketEngine::AddressReusable) { // 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 - break; - case QNativeSocketEngine::BindExclusively: - return true; - case QNativeSocketEngine::ReceiveOutOfBandData: - n = SO_OOBINLINE; - break; - case QNativeSocketEngine::LowDelayOption: - level = IPPROTO_TCP; - n = TCP_NODELAY; - break; - case QNativeSocketEngine::KeepAliveOption: - n = SO_KEEPALIVE; - break; - case QNativeSocketEngine::MulticastTtlOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_HOPS; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_TTL; - } - break; - case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_LOOP; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_LOOP; - } - break; - case QNativeSocketEngine::TypeOfServiceOption: - if (socketProtocol == QAbstractSocket::IPv4Protocol) { - level = IPPROTO_IP; - n = IP_TOS; - } - break; } +#endif return ::setsockopt(socketDescriptor, level, n, (char *) &v, sizeof(v)) == 0; } diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index ab43f0a55e..72f85c831f 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Intel Corporation. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtNetwork module of the Qt Toolkit. @@ -195,6 +196,64 @@ static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, const qt } } +static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt, + QAbstractSocket::NetworkLayerProtocol socketProtocol, int &level, int &n) +{ + n = 0; + level = SOL_SOCKET; // default + + switch (opt) { + case QNativeSocketEngine::NonBlockingSocketOption: // WSAIoctl + case QNativeSocketEngine::TypeOfServiceOption: // not supported + Q_UNREACHABLE(); + + case QNativeSocketEngine::ReceiveBufferSocketOption: + n = SO_RCVBUF; + break; + case QNativeSocketEngine::SendBufferSocketOption: + n = SO_SNDBUF; + break; + case QNativeSocketEngine::BroadcastSocketOption: + n = SO_BROADCAST; + break; + case QNativeSocketEngine::AddressReusable: + n = SO_REUSEADDR; + break; + case QNativeSocketEngine::BindExclusively: + n = SO_EXCLUSIVEADDRUSE; + break; + case QNativeSocketEngine::ReceiveOutOfBandData: + n = SO_OOBINLINE; + break; + case QNativeSocketEngine::LowDelayOption: + level = IPPROTO_TCP; + n = TCP_NODELAY; + break; + case QNativeSocketEngine::KeepAliveOption: + n = SO_KEEPALIVE; + break; + case QNativeSocketEngine::MulticastTtlOption: + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { + level = IPPROTO_IPV6; + n = IPV6_MULTICAST_HOPS; + } else + { + level = IPPROTO_IP; + n = IP_MULTICAST_TTL; + } + break; + case QNativeSocketEngine::MulticastLoopbackOption: + if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { + level = IPPROTO_IPV6; + n = IPV6_MULTICAST_LOOP; + } else + { + level = IPPROTO_IP; + n = IP_MULTICAST_LOOP; + } + break; + } +} /*! \internal @@ -404,19 +463,8 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co if (!q->isValid()) return -1; - int n = -1; - int level = SOL_SOCKET; // default - + // handle non-getsockopt switch (opt) { - case QNativeSocketEngine::ReceiveBufferSocketOption: - n = SO_RCVBUF; - break; - case QNativeSocketEngine::SendBufferSocketOption: - n = SO_SNDBUF; - break; - case QNativeSocketEngine::BroadcastSocketOption: - n = SO_BROADCAST; - break; case QNativeSocketEngine::NonBlockingSocketOption: { unsigned long buf = 0; if (WSAIoctl(socketDescriptor, FIONBIO, 0,0, &buf, sizeof(buf), 0,0,0) == 0) @@ -425,53 +473,21 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co return -1; break; } - case QNativeSocketEngine::AddressReusable: - n = SO_REUSEADDR; - break; - case QNativeSocketEngine::BindExclusively: - n = SO_EXCLUSIVEADDRUSE; - break; - case QNativeSocketEngine::ReceiveOutOfBandData: - n = SO_OOBINLINE; - break; - case QNativeSocketEngine::LowDelayOption: - level = IPPROTO_TCP; - n = TCP_NODELAY; - break; - case QNativeSocketEngine::KeepAliveOption: - n = SO_KEEPALIVE; - break; - case QNativeSocketEngine::MulticastTtlOption: - - if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_HOPS; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_TTL; - } - break; - case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_LOOP; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_LOOP; - } - break; case QNativeSocketEngine::TypeOfServiceOption: return -1; + + default: break; } #if Q_BYTE_ORDER != Q_LITTLE_ENDIAN #error code assumes windows is little endian #endif + int n, level; int v = 0; //note: windows doesn't write to all bytes if the option type is smaller than int QT_SOCKOPTLEN_T len = sizeof(v); + + convertToLevelAndOption(opt, socketProtocol, level, n); if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) == 0) return v; WS_ERROR_DEBUG(WSAGetLastError()); @@ -488,21 +504,12 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt if (!q->isValid()) return false; - int n = 0; - int level = SOL_SOCKET; // default - + // handle non-setsockopt options switch (opt) { - case QNativeSocketEngine::ReceiveBufferSocketOption: - n = SO_RCVBUF; - break; case QNativeSocketEngine::SendBufferSocketOption: // see QTBUG-30478 SO_SNDBUF should not be used on Vista or later if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA) return false; - n = SO_SNDBUF; - break; - case QNativeSocketEngine::BroadcastSocketOption: - n = SO_BROADCAST; break; case QNativeSocketEngine::NonBlockingSocketOption: { @@ -516,47 +523,15 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt return true; break; } - case QNativeSocketEngine::AddressReusable: - n = SO_REUSEADDR; - break; - case QNativeSocketEngine::BindExclusively: - n = SO_EXCLUSIVEADDRUSE; - break; - case QNativeSocketEngine::ReceiveOutOfBandData: - n = SO_OOBINLINE; - break; - case QNativeSocketEngine::LowDelayOption: - level = IPPROTO_TCP; - n = TCP_NODELAY; - break; - case QNativeSocketEngine::KeepAliveOption: - n = SO_KEEPALIVE; - break; - case QNativeSocketEngine::MulticastTtlOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_HOPS; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_TTL; - } - break; - case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_LOOP; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_LOOP; - } - break; case QNativeSocketEngine::TypeOfServiceOption: return false; + + default: break; } + int n, level; + convertToLevelAndOption(opt, socketProtocol, level, n); if (::setsockopt(socketDescriptor, level, n, (char*)&v, sizeof(v)) != 0) { WS_ERROR_DEBUG(WSAGetLastError()); return false; -- cgit v1.2.3