From 64a1e01cacd9b4435136a598c7f34dc9421b397d Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Sat, 30 Mar 2024 02:20:01 +0200 Subject: [PATCH] extract the scope from the socket address (sockaddr pointer) obviously something which was not done before by QHostAddress itself, it is now tho Signed-off-by: Ivailo Monev --- src/network/kernel/qhostaddress.cpp | 32 +++++++++++++++-- src/network/kernel/qhostinfo_unix.cpp | 3 -- src/network/kernel/qnetworkinterface_unix.cpp | 34 ++----------------- .../socket/qabstractsocketengine_unix.cpp | 33 ++++++++---------- 4 files changed, 48 insertions(+), 54 deletions(-) diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index 72a09b940..832e43053 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -32,6 +32,10 @@ #include #include +#ifndef QT_NO_IPV6IFNAME +# include +#endif + QT_BEGIN_NAMESPACE static const char addrscopeseparator = '%'; @@ -250,6 +254,7 @@ bool QHostAddress::setAddress(const QByteArray &address) d->scopeId.clear(); return true; } + clear(); return false; } @@ -263,24 +268,47 @@ bool QHostAddress::setAddress(const QByteArray &address) */ void QHostAddress::setAddress(const struct sockaddr *sockaddr) { - clear(); + if (!sockaddr) { + clear(); + return; + } if (sockaddr->sa_family == AF_INET) { QSTACKARRAY(char, ntopbuffer, INET_ADDRSTRLEN + 1); if (inet_ntop(AF_INET, &((sockaddr_in *)sockaddr)->sin_addr, ntopbuffer, INET_ADDRSTRLEN) != NULL) { d->protocol = QAbstractSocket::IPv4Protocol; d->ipString = ntopbuffer; + d->scopeId.clear(); + } else { + clear(); } return; } #ifndef QT_NO_IPV6 if (sockaddr->sa_family == AF_INET6) { QSTACKARRAY(char, ntopbuffer, INET6_ADDRSTRLEN + 1); - if (inet_ntop(AF_INET6, &((sockaddr_in6 *)sockaddr)->sin6_addr, ntopbuffer, INET6_ADDRSTRLEN) != NULL) { + const sockaddr_in6* si6 = (sockaddr_in6 *)sockaddr; + if (inet_ntop(AF_INET6, &(si6->sin6_addr), ntopbuffer, INET6_ADDRSTRLEN) != NULL) { d->protocol = QAbstractSocket::IPv6Protocol; d->ipString = ntopbuffer; + d->scopeId.clear(); + if (si6->sin6_scope_id) { +#ifndef QT_NO_IPV6IFNAME + QSTACKARRAY(char, indexofnamebuffer, IFNAMSIZ); + if (::if_indextoname(si6->sin6_scope_id, indexofnamebuffer)) { + d->scopeId = indexofnamebuffer; + } +#endif + if (d->scopeId.isEmpty()) { + d->scopeId = QByteArray::number(si6->sin6_scope_id); + } + } + } else { + clear(); } + return; } #endif + clear(); } /*! diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp index 36745b6c2..9f79a7014 100644 --- a/src/network/kernel/qhostinfo_unix.cpp +++ b/src/network/kernel/qhostinfo_unix.cpp @@ -195,10 +195,7 @@ QHostInfo QHostInfoPrivate::fromName(const QString &hostName) } #ifndef QT_NO_IPV6 else if (node->ai_family == AF_INET6) { - sockaddr_in6 *sa6 = (sockaddr_in6 *) node->ai_addr; QHostAddress addr(node->ai_addr); - if (sa6->sin6_scope_id) - addr.setScopeId(QByteArray::number(sa6->sin6_scope_id)); if (!addresses.contains(addr)) addresses.append(addr); } diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp index abc045ed7..109272672 100644 --- a/src/network/kernel/qnetworkinterface_unix.cpp +++ b/src/network/kernel/qnetworkinterface_unix.cpp @@ -56,34 +56,6 @@ static QString makeHwAddress(const uchar *data) return QString::fromLatin1(snprintfbuf, sizeof(snprintfbuf) - 1); } - -static QHostAddress addressFromSockaddr(sockaddr *sa) -{ - QHostAddress address; - if (!sa) - return address; - - if (sa->sa_family == AF_INET) - address.setAddress(sa); -#ifndef QT_NO_IPV6 - else if (sa->sa_family == AF_INET6) { - address.setAddress(sa); - int scope = ((sockaddr_in6 *)sa)->sin6_scope_id; - if (scope) { -#ifndef QT_NO_IPV6IFNAME - QSTACKARRAY(char, scopeid, IFNAMSIZ); - if (::if_indextoname(scope, scopeid) != 0) { - address.setScopeId(QByteArray(scopeid)); - } else -#endif - address.setScopeId(QByteArray::number(scope)); - } - } -#endif - return address; - -} - QList QNetworkInterfacePrivate::scan() { QList interfaces; @@ -133,15 +105,15 @@ QList QNetworkInterfacePrivate::scan() } QNetworkAddressEntry entry; - entry.d->address = addressFromSockaddr(ifiter->ifa_addr); + entry.d->address = QHostAddress(ifiter->ifa_addr); if (entry.ip().isNull()) { // could not parse the address continue; } - entry.d->netmask = addressFromSockaddr(ifiter->ifa_netmask); + entry.d->netmask = QHostAddress(ifiter->ifa_netmask); if (iface->flags & QNetworkInterface::CanBroadcast) { - entry.d->broadcast = addressFromSockaddr(ifiter->ifa_broadaddr); + entry.d->broadcast = QHostAddress(ifiter->ifa_broadaddr); } iface->addressEntries << entry; diff --git a/src/network/socket/qabstractsocketengine_unix.cpp b/src/network/socket/qabstractsocketengine_unix.cpp index 0d353d643..638997abd 100644 --- a/src/network/socket/qabstractsocketengine_unix.cpp +++ b/src/network/socket/qabstractsocketengine_unix.cpp @@ -39,7 +39,7 @@ #include #ifndef QT_NO_IPV6IFNAME -#include +# include #endif #ifdef Q_OS_SOLARIS @@ -59,13 +59,6 @@ static inline void qt_socket_getPortAndAddress(const struct sockaddr_storage *ss const struct sockaddr_in6 *si6 = (const struct sockaddr_in6 *)ss; if (addr) { addr->setAddress((const struct sockaddr *) ss); -#ifndef QT_NO_IPV6IFNAME - QSTACKARRAY(char, scopeid, IFNAMSIZ); - if (::if_indextoname(si6->sin6_scope_id, scopeid)) { - addr->setScopeId(QByteArray(scopeid)); - } else -#endif - addr->setScopeId(QByteArray::number(si6->sin6_scope_id)); } if (port) *port = ntohs(si6->sin6_port); @@ -296,12 +289,13 @@ bool QAbstractSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint sockAddrIPv6.sin6_family = AF_INET6; sockAddrIPv6.sin6_port = htons(port); - QString scopeid = addr.scopeId(); + const QByteArray scopeid = addr.scopeId(); bool ok = false; sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); #ifndef QT_NO_IPV6IFNAME - if (!ok) - sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1()); + if (!ok) { + sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.constData()); + } #endif struct in6_addr inAddrIPv6; inet_pton(AF_INET6, addrStr.constData(), &inAddrIPv6); @@ -406,10 +400,12 @@ bool QAbstractSocketEnginePrivate::nativeBind(const QHostAddress &address, quint memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6)); sockAddrIPv6.sin6_family = AF_INET6; sockAddrIPv6.sin6_port = htons(port); + bool ok = false; + sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); #ifndef QT_NO_IPV6IFNAME - sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.constData()); -#else - sockAddrIPv6.sin6_scope_id = scopeid.toInt(); + if (!ok) { + sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.constData()); + } #endif struct in6_addr inAddrIPv6; inet_pton(AF_INET6, addrStr.constData(), &inAddrIPv6); @@ -803,12 +799,13 @@ qint64 QAbstractSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 struct in6_addr ia6; inet_pton(AF_INET6, hostStr.constData(), &ia6); sockAddrIPv6.sin6_addr = ia6; - QString scopeid = host.scopeId(); - bool ok; + const QByteArray scopeid = host.scopeId(); + bool ok = false; sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); #ifndef QT_NO_IPV6IFNAME - if (!ok) - sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1()); + if (!ok) { + sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.constData()); + } #endif sockAddrSize = sizeof(sockAddrIPv6); sockAddrPtr = (struct sockaddr *)&sockAddrIPv6;