QNativeSocketEngine: move some code from the _p_p.h to _p.h file

So I can use it in qdnslookup_unix.cpp.

Change-Id: I3e3bfef633af4130a03afffd175d506949968990
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Thiago Macieira 2023-05-08 16:57:28 -07:00
parent 3b0536bbe8
commit 45a03fc506
2 changed files with 68 additions and 25 deletions

View File

@ -20,8 +20,14 @@
#include "QtNetwork/qhostaddress.h" #include "QtNetwork/qhostaddress.h"
#include "QtNetwork/qnetworkinterface.h" #include "QtNetwork/qnetworkinterface.h"
#include "private/qabstractsocketengine_p.h" #include "private/qabstractsocketengine_p.h"
#include "qplatformdefs.h"
#ifndef Q_OS_WIN #ifndef Q_OS_WIN
# include "qplatformdefs.h" # include <netinet/in.h>
#else
# include <winsock2.h>
# include <ws2tcpip.h>
# include <mswsock.h>
#endif #endif
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -35,12 +41,58 @@ namespace {
namespace SetSALen { namespace SetSALen {
template <typename T> void set(T *sa, typename std::enable_if<(&T::sa_len, true), QT_SOCKLEN_T>::type len) template <typename T> void set(T *sa, typename std::enable_if<(&T::sa_len, true), QT_SOCKLEN_T>::type len)
{ sa->sa_len = len; } { sa->sa_len = len; }
template <typename T> void set(T *sa, typename std::enable_if<(&T::sin_len, true), QT_SOCKLEN_T>::type len)
{ sa->sin_len = len; }
template <typename T> void set(T *sin6, typename std::enable_if<(&T::sin6_len, true), QT_SOCKLEN_T>::type len) template <typename T> void set(T *sin6, typename std::enable_if<(&T::sin6_len, true), QT_SOCKLEN_T>::type len)
{ sin6->sin6_len = len; } { sin6->sin6_len = len; }
template <typename T> void set(T *, ...) {} template <typename T> void set(T *, ...) {}
} }
inline QT_SOCKLEN_T setSockaddr(sockaddr_in *sin, const QHostAddress &addr, quint16 port = 0)
{
*sin = {};
SetSALen::set(sin, sizeof(*sin));
sin->sin_family = AF_INET;
sin->sin_port = htons(port);
sin->sin_addr.s_addr = htonl(addr.toIPv4Address());
return sizeof(*sin);
} }
inline QT_SOCKLEN_T setSockaddr(sockaddr_in6 *sin6, const QHostAddress &addr, quint16 port = 0)
{
*sin6 = {};
SetSALen::set(sin6, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
sin6->sin6_port = htons(port);
memcpy(sin6->sin6_addr.s6_addr, addr.toIPv6Address().c, sizeof(sin6->sin6_addr));
#if QT_CONFIG(networkinterface)
sin6->sin6_scope_id = QNetworkInterface::interfaceIndexFromName(addr.scopeId());
#else
// it had better be a number then, if it is not empty
sin6->sin6_scope_id = addr.scopeId().toUInt();
#endif
return sizeof(*sin6);
}
inline QT_SOCKLEN_T setSockaddr(sockaddr *sa, const QHostAddress &addr, quint16 port = 0)
{
switch (addr.protocol()) {
case QHostAddress::IPv4Protocol:
return setSockaddr(reinterpret_cast<sockaddr_in *>(sa), addr, port);
case QHostAddress::IPv6Protocol:
case QHostAddress::AnyIPProtocol:
return setSockaddr(reinterpret_cast<sockaddr_in6 *>(sa), addr, port);
case QHostAddress::UnknownNetworkLayerProtocol:
break;
}
*sa = {};
sa->sa_family = AF_UNSPEC;
return 0;
}
} // unnamed namespace
class QNativeSocketEnginePrivate; class QNativeSocketEnginePrivate;
#ifndef QT_NO_NETWORKINTERFACE #ifndef QT_NO_NETWORKINTERFACE
class QNetworkInterface; class QNetworkInterface;

View File

@ -155,38 +155,29 @@ public:
bool checkProxy(const QHostAddress &address); bool checkProxy(const QHostAddress &address);
bool fetchConnectionParameters(); bool fetchConnectionParameters();
#if QT_CONFIG(networkinterface)
static uint scopeIdFromString(const QString &scopeid)
{ return QNetworkInterface::interfaceIndexFromName(scopeid); }
#endif
/*! \internal /*! \internal
Sets \a address and \a port in the \a aa sockaddr structure and the size in \a sockAddrSize. Sets \a address and \a port in the \a aa sockaddr structure and the size in \a sockAddrSize.
The address \a is converted to IPv6 if the current socket protocol is also IPv6. The address \a is converted to IPv6 if the current socket protocol is also IPv6.
*/ */
void setPortAndAddress(quint16 port, const QHostAddress &address, qt_sockaddr *aa, QT_SOCKLEN_T *sockAddrSize) void setPortAndAddress(quint16 port, const QHostAddress &address, qt_sockaddr *aa, QT_SOCKLEN_T *sockAddrSize)
{ {
if (address.protocol() == QAbstractSocket::IPv6Protocol switch (socketProtocol) {
|| address.protocol() == QAbstractSocket::AnyIPProtocol case QHostAddress::IPv6Protocol:
|| socketProtocol == QAbstractSocket::IPv6Protocol case QHostAddress::AnyIPProtocol:
|| socketProtocol == QAbstractSocket::AnyIPProtocol) { // force to IPv6
memset(&aa->a6, 0, sizeof(sockaddr_in6)); setSockaddr(&aa->a6, address, port);
aa->a6.sin6_family = AF_INET6;
#if QT_CONFIG(networkinterface)
aa->a6.sin6_scope_id = scopeIdFromString(address.scopeId());
#endif
aa->a6.sin6_port = htons(port);
Q_IPV6ADDR tmp = address.toIPv6Address();
memcpy(&aa->a6.sin6_addr, &tmp, sizeof(tmp));
*sockAddrSize = sizeof(sockaddr_in6); *sockAddrSize = sizeof(sockaddr_in6);
SetSALen::set(&aa->a, sizeof(sockaddr_in6)); return;
} else {
memset(&aa->a, 0, sizeof(sockaddr_in)); case QHostAddress::IPv4Protocol:
aa->a4.sin_family = AF_INET; // force to IPv4
aa->a4.sin_port = htons(port); setSockaddr(&aa->a4, address, port);
aa->a4.sin_addr.s_addr = htonl(address.toIPv4Address());
*sockAddrSize = sizeof(sockaddr_in); *sockAddrSize = sizeof(sockaddr_in);
SetSALen::set(&aa->a, sizeof(sockaddr_in)); return;
case QHostAddress::UnknownNetworkLayerProtocol:
// don't force
*sockAddrSize = setSockaddr(&aa->a, address, port);
} }
} }