diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2015-03-11 18:58:29 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2015-08-22 22:26:47 +0000 |
commit | 452924c6ffc9624062bfb83eda8499044cc4719f (patch) | |
tree | afb5bb1f7c9b306ece7efe0fe1ee9761b80ba5bb /src/network/socket/qnativesocketengine_unix.cpp | |
parent | 2c64e05d497b460f95cd39ea20c4e805b2c8c402 (diff) | |
download | qtbase-452924c6ffc9624062bfb83eda8499044cc4719f.tar.gz |
QNativeSocketEngine Unix: do the same as for Windows
Change-Id: Iee8cbc07c4434ce9b560ffff13ca9d9858cf7111
Reviewed-by: Richard J. Moore <rich@kde.org>
Diffstat (limited to 'src/network/socket/qnativesocketengine_unix.cpp')
-rw-r--r-- | src/network/socket/qnativesocketengine_unix.cpp | 110 |
1 files changed, 22 insertions, 88 deletions
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index f2fac66cd6..0e14c175c5 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -131,9 +131,9 @@ static inline void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *po } } -static inline uint makeScopeId(const QHostAddress &addr) +// inline on purpose +inline uint QNativeSocketEnginePrivate::scopeIdFromString(const QString &scopeid) { - QString scopeid = addr.scopeId(); if (scopeid.isEmpty()) return 0; @@ -389,37 +389,11 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 qDebug() << "QNativeSocketEnginePrivate::nativeConnect() " << socketDescriptor; #endif - struct sockaddr_in sockAddrIPv4; - struct sockaddr *sockAddrPtr = 0; - QT_SOCKLEN_T sockAddrSize = 0; - - struct sockaddr_in6 sockAddrIPv6; - - if (addr.protocol() == QAbstractSocket::IPv6Protocol) { - memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6)); - sockAddrIPv6.sin6_family = AF_INET6; - sockAddrIPv6.sin6_port = htons(port); - sockAddrIPv6.sin6_scope_id = makeScopeId(addr); - - Q_IPV6ADDR ip6 = addr.toIPv6Address(); - memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &ip6, sizeof(ip6)); - - sockAddrSize = sizeof(sockAddrIPv6); - sockAddrPtr = (struct sockaddr *) &sockAddrIPv6; - } else - if (addr.protocol() == QAbstractSocket::IPv4Protocol) { - memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4)); - sockAddrIPv4.sin_family = AF_INET; - sockAddrIPv4.sin_port = htons(port); - sockAddrIPv4.sin_addr.s_addr = htonl(addr.toIPv4Address()); - - sockAddrSize = sizeof(sockAddrIPv4); - sockAddrPtr = (struct sockaddr *) &sockAddrIPv4; - } else { - // unreachable - } + qt_sockaddr aa; + QT_SOCKLEN_T sockAddrSize; + setPortAndAddress(port, addr, &aa, &sockAddrSize); - int connectResult = qt_safe_connect(socketDescriptor, sockAddrPtr, sockAddrSize); + int connectResult = qt_safe_connect(socketDescriptor, &aa.a, sockAddrSize); #if defined (QNATIVESOCKETENGINE_DEBUG) int ecopy = errno; #endif @@ -491,51 +465,28 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 port) { - struct sockaddr_in sockAddrIPv4; - struct sockaddr *sockAddrPtr = 0; - QT_SOCKLEN_T sockAddrSize = 0; - - - struct sockaddr_in6 sockAddrIPv6; + qt_sockaddr aa; + QT_SOCKLEN_T sockAddrSize; + setPortAndAddress(port, address, &aa, &sockAddrSize); - if (address.protocol() == QAbstractSocket::IPv6Protocol || address.protocol() == QAbstractSocket::AnyIPProtocol) { #ifdef IPV6_V6ONLY + if (aa.a.sa_family == AF_INET6) { int ipv6only = 0; if (address.protocol() == QAbstractSocket::IPv6Protocol) ipv6only = 1; //default value of this socket option varies depending on unix variant (or system configuration on BSD), so always set it explicitly ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) ); + } #endif - memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6)); - sockAddrIPv6.sin6_family = AF_INET6; - sockAddrIPv6.sin6_port = htons(port); - sockAddrIPv6.sin6_scope_id = makeScopeId(address); - - Q_IPV6ADDR tmp = address.toIPv6Address(); - memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp)); - sockAddrSize = sizeof(sockAddrIPv6); - sockAddrPtr = (struct sockaddr *) &sockAddrIPv6; - } else - if (address.protocol() == QAbstractSocket::IPv4Protocol) { - memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4)); - sockAddrIPv4.sin_family = AF_INET; - sockAddrIPv4.sin_port = htons(port); - sockAddrIPv4.sin_addr.s_addr = htonl(address.toIPv4Address()); - sockAddrSize = sizeof(sockAddrIPv4); - sockAddrPtr = (struct sockaddr *) &sockAddrIPv4; - } else { - // unreachable - } - int bindResult = QT_SOCKET_BIND(socketDescriptor, sockAddrPtr, sockAddrSize); + int bindResult = QT_SOCKET_BIND(socketDescriptor, &aa.a, sockAddrSize); if (bindResult < 0 && errno == EAFNOSUPPORT && address.protocol() == QAbstractSocket::AnyIPProtocol) { - memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4)); - sockAddrIPv4.sin_family = AF_INET; - sockAddrIPv4.sin_port = htons(port); - sockAddrIPv4.sin_addr.s_addr = htonl(address.toIPv4Address()); - sockAddrSize = sizeof(sockAddrIPv4); - sockAddrPtr = (struct sockaddr *) &sockAddrIPv4; - bindResult = QT_SOCKET_BIND(socketDescriptor, sockAddrPtr, sockAddrSize); + // retry with v4 + aa.a4.sin_family = AF_INET; + aa.a4.sin_port = htons(port); + aa.a4.sin_addr.s_addr = htonl(address.toIPv4Address()); + sockAddrSize = sizeof(aa.a4); + bindResult = QT_SOCKET_BIND(socketDescriptor, &aa.a, sockAddrSize); } if (bindResult < 0) { @@ -992,17 +943,9 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l msg.msg_name = &aa.a; msg.msg_control = &cbuf; - if (header.destinationAddress.protocol() == QAbstractSocket::IPv6Protocol - || socketProtocol == QAbstractSocket::IPv6Protocol - || socketProtocol == QAbstractSocket::AnyIPProtocol) { - aa.a6.sin6_family = AF_INET6; - aa.a6.sin6_port = htons(header.destinationPort); - aa.a6.sin6_scope_id = makeScopeId(header.destinationAddress); - - Q_IPV6ADDR tmp = header.destinationAddress.toIPv6Address(); - memcpy(&aa.a6.sin6_addr, &tmp, sizeof(tmp)); - msg.msg_namelen = sizeof(aa.a6); + setPortAndAddress(header.destinationPort, header.destinationAddress, &aa, &msg.msg_namelen); + if (msg.msg_namelen == sizeof(aa.a6)) { if (header.hopLimit != -1) { msg.msg_controllen += CMSG_SPACE(sizeof(int)); cmsgptr->cmsg_len = CMSG_LEN(sizeof(int)); @@ -1020,16 +963,11 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l cmsgptr->cmsg_type = IPV6_PKTINFO; data->ipi6_ifindex = header.ifindex; - tmp = header.senderAddress.toIPv6Address(); + QIPv6Address tmp = header.senderAddress.toIPv6Address(); memcpy(&data->ipi6_addr, &tmp, sizeof(tmp)); cmsgptr = reinterpret_cast<cmsghdr *>(reinterpret_cast<char *>(cmsgptr) + CMSG_SPACE(sizeof(*data))); } - } else if (header.destinationAddress.protocol() == QAbstractSocket::IPv4Protocol) { - aa.a4.sin_family = AF_INET; - aa.a4.sin_port = htons(header.destinationPort); - aa.a4.sin_addr.s_addr = htonl(header.destinationAddress.toIPv4Address()); - msg.msg_namelen = sizeof(aa.a4); - + } else { if (header.hopLimit != -1) { msg.msg_controllen += CMSG_SPACE(sizeof(int)); cmsgptr->cmsg_len = CMSG_LEN(sizeof(int)); @@ -1058,10 +996,6 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l cmsgptr = reinterpret_cast<cmsghdr *>(reinterpret_cast<char *>(cmsgptr) + CMSG_SPACE(sizeof(*data))); } #endif - } else { - // Don't know what IP type this is, let's hope it sends - msg.msg_name = 0; - msg.msg_namelen = 0; } if (msg.msg_controllen == 0) |