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/qnetworkinterface.h"
#include "private/qabstractsocketengine_p.h"
#include "qplatformdefs.h"
#ifndef Q_OS_WIN
# include "qplatformdefs.h"
# include <netinet/in.h>
#else
# include <winsock2.h>
# include <ws2tcpip.h>
# include <mswsock.h>
#endif
QT_BEGIN_NAMESPACE
@ -35,12 +41,58 @@ namespace {
namespace SetSALen {
template <typename T> void set(T *sa, typename std::enable_if<(&T::sa_len, true), QT_SOCKLEN_T>::type 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)
{ sin6->sin6_len = len; }
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;
#ifndef QT_NO_NETWORKINTERFACE
class QNetworkInterface;

View File

@ -155,38 +155,29 @@ public:
bool checkProxy(const QHostAddress &address);
bool fetchConnectionParameters();
#if QT_CONFIG(networkinterface)
static uint scopeIdFromString(const QString &scopeid)
{ return QNetworkInterface::interfaceIndexFromName(scopeid); }
#endif
/*! \internal
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.
*/
void setPortAndAddress(quint16 port, const QHostAddress &address, qt_sockaddr *aa, QT_SOCKLEN_T *sockAddrSize)
{
if (address.protocol() == QAbstractSocket::IPv6Protocol
|| address.protocol() == QAbstractSocket::AnyIPProtocol
|| socketProtocol == QAbstractSocket::IPv6Protocol
|| socketProtocol == QAbstractSocket::AnyIPProtocol) {
memset(&aa->a6, 0, sizeof(sockaddr_in6));
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));
switch (socketProtocol) {
case QHostAddress::IPv6Protocol:
case QHostAddress::AnyIPProtocol:
// force to IPv6
setSockaddr(&aa->a6, address, port);
*sockAddrSize = sizeof(sockaddr_in6);
SetSALen::set(&aa->a, sizeof(sockaddr_in6));
} else {
memset(&aa->a, 0, sizeof(sockaddr_in));
aa->a4.sin_family = AF_INET;
aa->a4.sin_port = htons(port);
aa->a4.sin_addr.s_addr = htonl(address.toIPv4Address());
return;
case QHostAddress::IPv4Protocol:
// force to IPv4
setSockaddr(&aa->a4, address, port);
*sockAddrSize = sizeof(sockaddr_in);
SetSALen::set(&aa->a, sizeof(sockaddr_in));
return;
case QHostAddress::UnknownNetworkLayerProtocol:
// don't force
*sockAddrSize = setSockaddr(&aa->a, address, port);
}
}