diff options
author | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-03-16 10:31:07 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-03-16 10:31:07 +0100 |
commit | 198606f6dbca95ba3a170fff387327d8271018cd (patch) | |
tree | 79e8c632f5277fc7f0ae30ae7fb1e1c41745c815 /src/network | |
parent | 77c0c1ca6505eb66bd75b3766f9a498574822bd1 (diff) | |
parent | 0d5ffd67a4748bcbf19dc3a4b9a36ae6314e58a6 (diff) |
Merge remote-tracking branch 'origin/5.5' into dev
Conflicts:
src/plugins/platforms/xcb/qxcbnativeinterface.cpp
src/plugins/platforms/xcb/qxcbnativeinterface.h
Change-Id: I31b38ba439b9341d51a01c0fd54bea33f7410076
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/kernel/qhostaddress.cpp | 35 | ||||
-rw-r--r-- | src/network/kernel/qhostaddress.h | 6 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface_unix.cpp | 2 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine_unix.cpp | 246 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine_win.cpp | 173 | ||||
-rw-r--r-- | src/network/ssl/qsslcertificate_openssl.cpp | 2 | ||||
-rw-r--r-- | src/network/ssl/qsslkey_openssl.cpp | 8 | ||||
-rw-r--r-- | src/network/ssl/qsslkey_p.h | 5 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_mac.cpp | 21 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_mac_p.h | 1 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_openssl.cpp | 2 |
11 files changed, 239 insertions, 262 deletions
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 @@ -415,6 +415,19 @@ QHostAddress::QHostAddress(quint8 *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. */ QHostAddress::QHostAddress(const Q_IPV6ADDR &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 @@ -575,6 +588,20 @@ void QHostAddress::setAddress(quint8 *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 Set the IPv6 address specified by \a ip6Addr. */ @@ -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); 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 da36e4a6da..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. @@ -127,6 +128,83 @@ 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.toUInt(&ok); +#ifndef QT_NO_IPV6IFNAME + if (!ok) + id = ::if_nametoindex(scopeid.toLatin1()); +#endif + 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 @@ -193,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) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_HOPS; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_TTL; - } - break; - case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { - 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; @@ -268,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) @@ -310,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) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_HOPS; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_TTL; - } - break; - case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { - 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; } @@ -382,17 +366,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 +476,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); @@ -749,7 +716,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 +746,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); } @@ -918,19 +885,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) { @@ -1037,7 +995,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..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 @@ -209,7 +268,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)); @@ -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) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_HOPS; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_TTL; - } - break; - case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { - 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) { - level = IPPROTO_IPV6; - n = IPV6_MULTICAST_HOPS; - } else - { - level = IPPROTO_IP; - n = IP_MULTICAST_TTL; - } - break; - case QNativeSocketEngine::MulticastLoopbackOption: - if (socketProtocol == QAbstractSocket::IPv6Protocol) { - 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; @@ -658,7 +633,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 +1010,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 +1044,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); } 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<QSslCertificate> 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<char *>(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<uchar *>((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<uchar *>((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<uchar *>((const uchar *)passPhrase.data()), passPhrase.size(), 0, 0)) { fail = true; } } 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() 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(); 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); } } |