/*! \internal Sets the port and address to a sockaddr. Requires that sa point to the IPv6 struct if the address is IPv6. */ static inline void qt_socket_setPortAndAddress(SOCKET socketDescriptor, sockaddr_in * sockAddrIPv4, qt_sockaddr_in6 * sockAddrIPv6, quint16 port, const QHostAddress & address, sockaddr ** sockAddrPtr, QT_SOCKLEN_T *sockAddrSize) { #if !defined(QT_NO_IPV6) if (address.protocol() == QAbstractSocket::IPv6Protocol) { memset(sockAddrIPv6, 0, sizeof(qt_sockaddr_in6)); sockAddrIPv6->sin6_family = AF_INET6; sockAddrIPv6->sin6_scope_id = address.scopeId().toInt(); WSAHtons(socketDescriptor, port, &(sockAddrIPv6->sin6_port)); Q_IPV6ADDR tmp = address.toIPv6Address(); memcpy(&(sockAddrIPv6->sin6_addr.qt_s6_addr), &tmp, sizeof(tmp)); *sockAddrSize = sizeof(qt_sockaddr_in6); *sockAddrPtr = (struct sockaddr *) sockAddrIPv6; } else #endif if (address.protocol() == QAbstractSocket::IPv4Protocol || address.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol) { memset(sockAddrIPv4, 0, sizeof(sockaddr_in)); sockAddrIPv4->sin_family = AF_INET; WSAHtons(socketDescriptor, port, &(sockAddrIPv4->sin_port)); WSAHtonl(socketDescriptor, address.toIPv4Address(), &(sockAddrIPv4->sin_addr.s_addr)); *sockAddrSize = sizeof(sockaddr_in); *sockAddrPtr = (struct sockaddr *) sockAddrIPv4; } else { // unreachable } }
qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port) { struct sockaddr_in sockAddrIPv4; struct sockaddr *sockAddrPtr = 0; QT_SOCKLEN_T sockAddrSize = 0; #if !defined(QT_NO_IPV6) struct sockaddr_in6 sockAddrIPv6; if (host.protocol() == QAbstractSocket::IPv6Protocol) { memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6)); sockAddrIPv6.sin6_family = AF_INET6; sockAddrIPv6.sin6_port = htons(port); Q_IPV6ADDR tmp = host.toIPv6Address(); memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp)); QString scopeid = host.scopeId(); bool ok; sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); #ifndef QT_NO_IPV6IFNAME if (!ok) sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1()); #endif sockAddrSize = sizeof(sockAddrIPv6); sockAddrPtr = (struct sockaddr *)&sockAddrIPv6; } else #endif if (host.protocol() == QAbstractSocket::IPv4Protocol) { memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4)); sockAddrIPv4.sin_family = AF_INET; sockAddrIPv4.sin_port = htons(port); sockAddrIPv4.sin_addr.s_addr = htonl(host.toIPv4Address()); sockAddrSize = sizeof(sockAddrIPv4); sockAddrPtr = (struct sockaddr *)&sockAddrIPv4; } // ignore the SIGPIPE signal qt_ignore_sigpipe(); ssize_t sentBytes = qt_safe_sendto(socketDescriptor, data, len, 0, sockAddrPtr, sockAddrSize); if (sentBytes < 0) { switch (errno) { case EMSGSIZE: setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString); break; default: setError(QAbstractSocket::NetworkError, SendDatagramErrorString); } } #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEngine::sendDatagram(%p \"%s\", %lli, \"%s\", %i) == %lli", data, qt_prettyDebug(data, qMin<int>(len, 16), len).data(), len, host.toString().toLatin1().constData(), port, (qint64) sentBytes); #endif return qint64(sentBytes); }
static bool contains(QNetworkAddressEntry host, QHostAddress addr) { #if !defined(QT_NO_IPV6) if (addr.protocol() == QAbstractSocket::IPv6Protocol && addr.isInSubnet(kLinkLocal6) && host.ip().scopeId() != addr.scopeId()) { return false; } #endif return addr.isInSubnet(host.ip(), host.prefixLength()); }
bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 port) { struct sockaddr_in sockAddrIPv4; struct sockaddr *sockAddrPtr = 0; QT_SOCKLEN_T sockAddrSize = 0; #if !defined(QT_NO_IPV6) struct sockaddr_in6 sockAddrIPv6; if (address.protocol() == QAbstractSocket::IPv6Protocol) { memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6)); sockAddrIPv6.sin6_family = AF_INET6; sockAddrIPv6.sin6_port = htons(port); #ifndef QT_NO_IPV6IFNAME sockAddrIPv6.sin6_scope_id = ::if_nametoindex(address.scopeId().toLatin1().data()); #else sockAddrIPv6.sin6_scope_id = address.scopeId().toInt(); #endif Q_IPV6ADDR tmp = address.toIPv6Address(); memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp)); sockAddrSize = sizeof(sockAddrIPv6); sockAddrPtr = (struct sockaddr *) &sockAddrIPv6; } else #endif 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); if (bindResult < 0) { switch(errno) { case EADDRINUSE: setError(QAbstractSocket::AddressInUseError, AddressInuseErrorString); break; case EACCES: setError(QAbstractSocket::SocketAccessError, AddressProtectedErrorString); break; case EINVAL: setError(QAbstractSocket::UnsupportedSocketOperationError, OperationUnsupportedErrorString); break; case EADDRNOTAVAIL: setError(QAbstractSocket::SocketAddressNotAvailableError, AddressNotAvailableErrorString); break; default: break; } #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == false (%s)", address.toString().toLatin1().constData(), port, socketErrorString.toLatin1().constData()); #endif return false; } #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == true", address.toString().toLatin1().constData(), port); #endif socketState = QAbstractSocket::BoundState; return true; }
bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 port) { struct sockaddr_in sockAddrIPv4; struct sockaddr *sockAddrPtr = 0; QT_SOCKLEN_T sockAddrSize = 0; #if !defined(QT_NO_IPV6) struct sockaddr_in6 sockAddrIPv6; if (addr.protocol() == QAbstractSocket::IPv6Protocol) { memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6)); sockAddrIPv6.sin6_family = AF_INET6; sockAddrIPv6.sin6_port = htons(port); #ifndef QT_NO_IPV6IFNAME sockAddrIPv6.sin6_scope_id = ::if_nametoindex(addr.scopeId().toLatin1().data()); #else sockAddrIPv6.sin6_scope_id = addr.scopeId().toInt(); #endif Q_IPV6ADDR ip6 = addr.toIPv6Address(); memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &ip6, sizeof(ip6)); sockAddrSize = sizeof(sockAddrIPv6); sockAddrPtr = (struct sockaddr *) &sockAddrIPv6; } else #if 0 {} #endif #endif 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 } int connectResult = QT_SOCKET_CONNECT(socketDescriptor, sockAddrPtr, sockAddrSize); if (connectResult == -1) { switch (errno) { case EISCONN: socketState = QAbstractSocket::ConnectedState; break; case ECONNREFUSED: case EINVAL: setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString); socketState = QAbstractSocket::UnconnectedState; break; case ETIMEDOUT: setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString); break; case EHOSTUNREACH: setError(QAbstractSocket::NetworkError, HostUnreachableErrorString); socketState = QAbstractSocket::UnconnectedState; break; case ENETUNREACH: setError(QAbstractSocket::NetworkError, NetworkUnreachableErrorString); socketState = QAbstractSocket::UnconnectedState; break; case EADDRINUSE: setError(QAbstractSocket::NetworkError, AddressInuseErrorString); break; case EINPROGRESS: case EALREADY: setError(QAbstractSocket::UnfinishedSocketOperationError, InvalidSocketErrorString); socketState = QAbstractSocket::ConnectingState; break; case EAGAIN: setError(QAbstractSocket::UnfinishedSocketOperationError, InvalidSocketErrorString); setError(QAbstractSocket::SocketResourceError, ResourceErrorString); break; case EACCES: case EPERM: setError(QAbstractSocket::SocketAccessError, AccessErrorString); socketState = QAbstractSocket::UnconnectedState; break; case EAFNOSUPPORT: case EBADF: case EFAULT: case ENOTSOCK: socketState = QAbstractSocket::UnconnectedState; default: break; } if (socketState != QAbstractSocket::ConnectedState) { #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == false (%s)", addr.toString().toLatin1().constData(), port, socketState == QAbstractSocket::ConnectingState ? "Connection in progress" : socketErrorString.toLatin1().constData()); #endif return false; } } #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == true", addr.toString().toLatin1().constData(), port); #endif socketState = QAbstractSocket::ConnectedState; return true; }
QUrl TcpServerDevice::externalAddress() const { const QHostAddress address(m_server->serverAddress()); QString myHost; #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) if (address == QHostAddress::LocalHost || address == QHostAddress::LocalHostIPv6) { #else if (address.isLoopback()) { #endif myHost = address.toString(); } else { foreach (const QNetworkInterface &inter, QNetworkInterface::allInterfaces()) { if (!(inter.flags() & QNetworkInterface::IsUp) || !(inter.flags() & QNetworkInterface::IsRunning) || (inter.flags() & QNetworkInterface::IsLoopBack)) continue; foreach (const QNetworkAddressEntry &addrEntry, inter.addressEntries()) { const QHostAddress addr = addrEntry.ip(); // Return the ip according to the listening server protocol. if (addr.protocol() != m_server->serverAddress().protocol() || !addr.scopeId().isEmpty()) continue; myHost = addr.toString(); break; } if (!myHost.isEmpty()) break; } } // if localhost is all we got, use that rather than nothing if (myHost.isEmpty()) { switch (m_server->serverAddress().protocol()) { case QAbstractSocket::IPv4Protocol: #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) case QAbstractSocket::AnyIPProtocol: #endif myHost = QHostAddress(QHostAddress::LocalHost).toString(); break; case QAbstractSocket::IPv6Protocol: myHost = QHostAddress(QHostAddress::LocalHostIPv6).toString(); break; case QAbstractSocket::UnknownNetworkLayerProtocol: Q_ASSERT_X(false, "TcpServerDevice::externalAddress", "unknown TCP protocol"); break; } } QUrl url; url.setScheme(QStringLiteral("tcp")); url.setHost(myHost); url.setPort(m_server->serverPort()); return url; } void TcpServerDevice::broadcast(const QByteArray &data) { const QHostAddress address = m_server->serverAddress(); // broadcast announcement only if we are actually listinging to remote connections #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) if (address == QHostAddress::LocalHost || address == QHostAddress::LocalHostIPv6) #else if (address.isLoopback()) #endif return; m_broadcastSocket->writeDatagram(data.data(), data.size(), QHostAddress::Broadcast, Server::broadcastPort()); }
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; if (address.protocol() == QAbstractSocket::IPv6Protocol || address.protocol() == QAbstractSocket::AnyIPProtocol) { #ifdef IPV6_V6ONLY 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); #ifndef QT_NO_IPV6IFNAME sockAddrIPv6.sin6_scope_id = ::if_nametoindex(address.scopeId().toLatin1().data()); #else sockAddrIPv6.sin6_scope_id = address.scopeId().toInt(); #endif 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); if (bindResult < 0) { switch(errno) { case EADDRINUSE: setError(QAbstractSocket::AddressInUseError, AddressInuseErrorString); break; case EACCES: setError(QAbstractSocket::SocketAccessError, AddressProtectedErrorString); break; case EINVAL: setError(QAbstractSocket::UnsupportedSocketOperationError, OperationUnsupportedErrorString); break; case EADDRNOTAVAIL: setError(QAbstractSocket::SocketAddressNotAvailableError, AddressNotAvailableErrorString); break; default: break; } #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == false (%s)", address.toString().toLatin1().constData(), port, socketErrorString.toLatin1().constData()); #endif return false; } localPort = port; localAddress = address; #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == true", address.toString().toLatin1().constData(), port); #endif socketState = QAbstractSocket::BoundState; return true; }