From 2c790b251d9e3a30abe8ac63ab50f81c9c7631ce Mon Sep 17 00:00:00 2001 From: "Jonas M. Gastal" Date: Fri, 4 May 2012 10:18:39 -0300 Subject: Fallback to IPv4 when IPv6 is not present. In tests when IPv6 is not present QSKIP IPv6 tests. Task-number: QTBUG-23660 Change-Id: I02abc7322d765a93cbf661e53c76257f03dca73e Reviewed-by: Shane Kearns --- src/network/socket/qnativesocketengine_p.h | 2 +- src/network/socket/qnativesocketengine_unix.cpp | 16 +++++++++++++++- src/network/socket/qnativesocketengine_win.cpp | 2 +- src/network/socket/qtcpserver.cpp | 8 ++++++-- 4 files changed, 23 insertions(+), 5 deletions(-) (limited to 'src/network/socket') diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h index 67e7038e00..90c3fbe56c 100644 --- a/src/network/socket/qnativesocketengine_p.h +++ b/src/network/socket/qnativesocketengine_p.h @@ -244,7 +244,7 @@ public: int option(QNativeSocketEngine::SocketOption option) const; bool setOption(QNativeSocketEngine::SocketOption option, int value); - bool createNewSocket(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol); + bool createNewSocket(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol &protocol); bool nativeConnect(const QHostAddress &address, quint16 port); bool nativeBind(const QHostAddress &address, quint16 port); diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index f5f9bba1ff..a01186a1f4 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -159,12 +159,17 @@ static inline void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *po and \a socketProtocol. Returns -1 on failure. */ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, - QAbstractSocket::NetworkLayerProtocol socketProtocol) + QAbstractSocket::NetworkLayerProtocol &socketProtocol) { int protocol = (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) ? AF_INET6 : AF_INET; int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM; int socket = qt_safe_socket(protocol, type, 0); + if (socket <= 0 && socketProtocol == QAbstractSocket::AnyIPProtocol && errno == EAFNOSUPPORT) { + protocol = AF_INET; + socket = qt_safe_socket(protocol, type, 0); + socketProtocol = QAbstractSocket::IPv4Protocol; + } if (socket <= 0) { switch (errno) { @@ -527,6 +532,15 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 } int bindResult = QT_SOCKET_BIND(socketDescriptor, sockAddrPtr, 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); + } if (bindResult < 0) { switch(errno) { diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index db6ace1d46..bc26a7f9c2 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -294,7 +294,7 @@ QWindowsSockInit::~QWindowsSockInit() # define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) #endif -bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol socketProtocol) +bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol) { //### no ip6 support on winsocket 1.1 but we will try not to use this !!!!!!!!!!!!1 diff --git a/src/network/socket/qtcpserver.cpp b/src/network/socket/qtcpserver.cpp index 9cca943189..4d8aad0dba 100644 --- a/src/network/socket/qtcpserver.cpp +++ b/src/network/socket/qtcpserver.cpp @@ -267,11 +267,12 @@ bool QTcpServer::listen(const QHostAddress &address, quint16 port) } QAbstractSocket::NetworkLayerProtocol proto = address.protocol(); + QHostAddress addr = address; #ifdef QT_NO_NETWORKPROXY static const QNetworkProxy &proxy = *(QNetworkProxy *)0; #else - QNetworkProxy proxy = d->resolveProxy(address, port); + QNetworkProxy proxy = d->resolveProxy(addr, port); #endif delete d->socketEngine; @@ -290,6 +291,9 @@ bool QTcpServer::listen(const QHostAddress &address, quint16 port) d->serverSocketErrorString = d->socketEngine->errorString(); return false; } + proto = d->socketEngine->protocol(); + if (addr.protocol() == QAbstractSocket::AnyIPProtocol && proto == QAbstractSocket::IPv4Protocol) + addr = QHostAddress::AnyIPv4; #if defined(Q_OS_UNIX) // Under Unix, we want to be able to bind to the port, even if a socket on @@ -303,7 +307,7 @@ bool QTcpServer::listen(const QHostAddress &address, quint16 port) d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1); #endif - if (!d->socketEngine->bind(address, port)) { + if (!d->socketEngine->bind(addr, port)) { d->serverSocketError = d->socketEngine->error(); d->serverSocketErrorString = d->socketEngine->errorString(); return false; -- cgit v1.2.3