summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@theqtcompany.com>2015-03-16 10:31:07 +0100
committerSimon Hausmann <simon.hausmann@theqtcompany.com>2015-03-16 10:31:07 +0100
commit198606f6dbca95ba3a170fff387327d8271018cd (patch)
tree79e8c632f5277fc7f0ae30ae7fb1e1c41745c815 /src/network
parent77c0c1ca6505eb66bd75b3766f9a498574822bd1 (diff)
parent0d5ffd67a4748bcbf19dc3a4b9a36ae6314e58a6 (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.cpp35
-rw-r--r--src/network/kernel/qhostaddress.h6
-rw-r--r--src/network/kernel/qnetworkinterface_unix.cpp2
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp246
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp173
-rw-r--r--src/network/ssl/qsslcertificate_openssl.cpp2
-rw-r--r--src/network/ssl/qsslkey_openssl.cpp8
-rw-r--r--src/network/ssl/qsslkey_p.h5
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp21
-rw-r--r--src/network/ssl/qsslsocket_mac_p.h1
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp2
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);
}
}