Add QNetworkInterface::interface{IndexFromName,NameFromIndex}
These are for faster lookups between ID and name when one doesn't need the full information set about the interface. Change-Id: I7de033f80b0e4431b7f1ffff13f98d448a705c3e Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com> Reviewed-by: Oliver Wolff <oliver.wolff@theqtcompany.com> Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
This commit is contained in:
parent
7db9c610f1
commit
3d52b05a63
@ -518,6 +518,31 @@ QList<QNetworkAddressEntry> QNetworkInterface::addressEntries() const
|
||||
return d ? d->addressEntries : QList<QNetworkAddressEntry>();
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 5.7
|
||||
|
||||
Returns the index of the interface whose name is \a name or 0 if there is
|
||||
no interface with that name. This function should produce the same result
|
||||
as the following code, but will probably execute faster.
|
||||
|
||||
\code
|
||||
QNetworkInterface::interfaceFromName(name).index()
|
||||
\endcode
|
||||
|
||||
\sa interfaceFromName(), interfaceNameFromIndex(), QUdpDatagram::interfaceIndex()
|
||||
*/
|
||||
int QNetworkInterface::interfaceIndexFromName(const QString &name)
|
||||
{
|
||||
if (name.isEmpty())
|
||||
return 0;
|
||||
|
||||
bool ok;
|
||||
uint id = name.toUInt(&ok);
|
||||
if (!ok)
|
||||
id = QNetworkInterfaceManager::interfaceIndexFromName(name);
|
||||
return int(id);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a QNetworkInterface object for the interface named \a
|
||||
name. If no such interface exists, this function returns an
|
||||
@ -552,6 +577,27 @@ QNetworkInterface QNetworkInterface::interfaceFromIndex(int index)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 5.7
|
||||
|
||||
Returns the name of the interface whose index is \a index or an empty
|
||||
string if there is no interface with that index. This function should
|
||||
produce the same result as the following code, but will probably execute
|
||||
faster.
|
||||
|
||||
\code
|
||||
QNetworkInterface::interfaceFromIndex(index).name()
|
||||
\endcode
|
||||
|
||||
\sa interfaceFromIndex(), interfaceIndexFromName(), QUdpDatagram::interfaceIndex()
|
||||
*/
|
||||
QString QNetworkInterface::interfaceNameFromIndex(int index)
|
||||
{
|
||||
if (!index)
|
||||
return QString();
|
||||
return QNetworkInterfaceManager::interfaceNameFromIndex(index);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a listing of all the network interfaces found on the host
|
||||
machine. In case of failure it returns a list with zero elements.
|
||||
|
@ -113,8 +113,10 @@ public:
|
||||
QString hardwareAddress() const;
|
||||
QList<QNetworkAddressEntry> addressEntries() const;
|
||||
|
||||
static int interfaceIndexFromName(const QString &name);
|
||||
static QNetworkInterface interfaceFromName(const QString &name);
|
||||
static QNetworkInterface interfaceFromIndex(int index);
|
||||
static QString interfaceNameFromIndex(int index);
|
||||
static QList<QNetworkInterface> allInterfaces();
|
||||
static QList<QHostAddress> allAddresses();
|
||||
|
||||
|
@ -100,6 +100,9 @@ public:
|
||||
QSharedDataPointer<QNetworkInterfacePrivate> interfaceFromIndex(int index);
|
||||
QList<QSharedDataPointer<QNetworkInterfacePrivate> > allInterfaces();
|
||||
|
||||
static uint interfaceIndexFromName(const QString &name);
|
||||
static QString interfaceNameFromIndex(uint index);
|
||||
|
||||
// convenience:
|
||||
QSharedDataPointer<QNetworkInterfacePrivate> empty;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Copyright (C) 2015 Intel Corporation.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtNetwork module of the Qt Toolkit.
|
||||
@ -93,14 +94,8 @@ static QHostAddress addressFromSockaddr(sockaddr *sa, int ifindex = 0, const QSt
|
||||
// this is the most likely scenario:
|
||||
// a scope ID in a socket is that of the interface this address came from
|
||||
address.setScopeId(ifname);
|
||||
} else if (scope) {
|
||||
#ifndef QT_NO_IPV6IFNAME
|
||||
char scopeid[IFNAMSIZ];
|
||||
if (::if_indextoname(scope, scopeid)) {
|
||||
address.setScopeId(QLatin1String(scopeid));
|
||||
} else
|
||||
#endif
|
||||
address.setScopeId(QString::number(uint(scope)));
|
||||
} else if (scope) {
|
||||
address.setScopeId(QNetworkInterfaceManager::interfaceNameFromIndex(scope));
|
||||
}
|
||||
}
|
||||
return address;
|
||||
@ -124,6 +119,53 @@ static QNetworkInterface::InterfaceFlags convertFlags(uint rawFlags)
|
||||
return flags;
|
||||
}
|
||||
|
||||
uint QNetworkInterfaceManager::interfaceIndexFromName(const QString &name)
|
||||
{
|
||||
#ifndef QT_NO_IPV6IFNAME
|
||||
return ::if_nametoindex(name.toLatin1());
|
||||
#elif defined(SIOCGIFINDEX)
|
||||
struct ifreq req;
|
||||
int socket = qt_safe_socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (socket < 0)
|
||||
return 0;
|
||||
|
||||
QByteArray name8bit = name.toLatin1();
|
||||
memset(&req, 0, sizeof(ifreq));
|
||||
memcpy(req.ifr_name, name8bit, qMin<int>(name8bit.length() + 1, sizeof(req.ifr_name) - 1));
|
||||
|
||||
uint id = 0;
|
||||
if (qt_safe_ioctl(socket, SIOCGIFINDEX, &req) >= 0)
|
||||
id = req.ifr_ifindex;
|
||||
qt_safe_close(socket);
|
||||
return id;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
QString QNetworkInterfaceManager::interfaceNameFromIndex(uint index)
|
||||
{
|
||||
#ifndef QT_NO_IPV6IFNAME
|
||||
char buf[IF_NAMESIZE];
|
||||
if (::if_indextoname(index, buf))
|
||||
return QString::fromLatin1(buf);
|
||||
#elif defined(SIOCGIFNAME)
|
||||
struct ifreq req;
|
||||
int socket = qt_safe_socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (socket >= 0) {
|
||||
memset(&req, 0, sizeof(ifreq));
|
||||
req.ifr_ifindex = index;
|
||||
|
||||
if (qt_safe_ioctl(socket, SIOCGIFNAME, &req) >= 0) {
|
||||
qt_safe_close(socket);
|
||||
return QString::fromLatin1(req.ifr_name);
|
||||
}
|
||||
qt_safe_close(socket);
|
||||
}
|
||||
#endif
|
||||
return QString::number(uint(index));
|
||||
}
|
||||
|
||||
#ifdef QT_NO_GETIFADDRS
|
||||
// getifaddrs not available
|
||||
|
||||
|
@ -57,8 +57,14 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
typedef NETIO_STATUS (WINAPI *PtrConvertInterfaceIndexToLuid)(NET_IFINDEX, PNET_LUID);
|
||||
typedef NETIO_STATUS (WINAPI *PtrConvertInterfaceLuidToName)(const NET_LUID *, PWSTR, SIZE_T);
|
||||
typedef NETIO_STATUS (WINAPI *PtrConvertInterfaceLuidToIndex)(const NET_LUID *, PNET_IFINDEX);
|
||||
typedef NETIO_STATUS (WINAPI *PtrConvertInterfaceNameToLuid)(const WCHAR *, PNET_LUID);
|
||||
static PtrConvertInterfaceIndexToLuid ptrConvertInterfaceIndexToLuid = 0;
|
||||
static PtrConvertInterfaceLuidToName ptrConvertInterfaceLuidToName = 0;
|
||||
static PtrConvertInterfaceLuidToIndex ptrConvertInterfaceLuidToIndex = 0;
|
||||
static PtrConvertInterfaceNameToLuid ptrConvertInterfaceNameToLuid = 0;
|
||||
|
||||
static void resolveLibs()
|
||||
{
|
||||
@ -71,10 +77,16 @@ static void resolveLibs()
|
||||
|
||||
#if defined(Q_OS_WINCE)
|
||||
// since Windows Embedded Compact 7
|
||||
ptrConvertInterfaceIndexToLuid = (PtrConvertInterfaceIndexToLuid)GetProcAddress(iphlpapiHnd, L"ConvertInterfaceIndexToLuid");
|
||||
ptrConvertInterfaceLuidToName = (PtrConvertInterfaceLuidToName)GetProcAddress(iphlpapiHnd, L"ConvertInterfaceLuidToNameW");
|
||||
ptrConvertInterfaceLuidToIndex = (PtrConvertInterfaceLuidToIndex)GetProcAddress(iphlpapiHnd, L"ConvertInterfaceLuidToIndex");
|
||||
ptrConvertInterfaceNameToLuid = (PtrConvertInterfaceNameToLuid)GetProcAddress(iphlpapiHnd, L"ConvertInterfaceNameToLuidW");
|
||||
#else
|
||||
// since Windows Vista
|
||||
ptrConvertInterfaceIndexToLuid = (PtrConvertInterfaceIndexToLuid)GetProcAddress(iphlpapiHnd, "ConvertInterfaceIndexToLuid");
|
||||
ptrConvertInterfaceLuidToName = (PtrConvertInterfaceLuidToName)GetProcAddress(iphlpapiHnd, "ConvertInterfaceLuidToNameW");
|
||||
ptrConvertInterfaceLuidToIndex = (PtrConvertInterfaceLuidToIndex)GetProcAddress(iphlpapiHnd, "ConvertInterfaceLuidToIndex");
|
||||
ptrConvertInterfaceNameToLuid = (PtrConvertInterfaceNameToLuid)GetProcAddress(iphlpapiHnd, "ConvertInterfaceNameToLuidW");
|
||||
#endif
|
||||
done = true;
|
||||
}
|
||||
@ -92,13 +104,42 @@ static QHostAddress addressFromSockaddr(sockaddr *sa)
|
||||
address.setAddress(((sockaddr_in6 *)sa)->sin6_addr.s6_addr);
|
||||
int scope = ((sockaddr_in6 *)sa)->sin6_scope_id;
|
||||
if (scope)
|
||||
address.setScopeId(QString::number(scope));
|
||||
address.setScopeId(QNetworkInterfaceManager::interfaceNameFromIndex(scope));
|
||||
} else
|
||||
qWarning("Got unknown socket family %d", sa->sa_family);
|
||||
return address;
|
||||
|
||||
}
|
||||
|
||||
uint QNetworkInterfaceManager::interfaceIndexFromName(const QString &name)
|
||||
{
|
||||
resolveLibs();
|
||||
if (!ptrConvertInterfaceNameToLuid || !ptrConvertInterfaceLuidToIndex)
|
||||
return 0;
|
||||
|
||||
NET_IFINDEX id;
|
||||
NET_LUID luid;
|
||||
if (ptrConvertInterfaceNameToLuid(reinterpret_cast<const wchar_t *>(name.constData()), &luid) == NO_ERROR
|
||||
&& ptrConvertInterfaceLuidToIndex(&luid, &id) == NO_ERROR)
|
||||
return uint(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString QNetworkInterfaceManager::interfaceNameFromIndex(uint index)
|
||||
{
|
||||
resolveLibs();
|
||||
if (ptrConvertInterfaceIndexToLuid && ptrConvertInterfaceLuidToName) {
|
||||
NET_LUID luid;
|
||||
if (ptrConvertInterfaceIndexToLuid(index, &luid) == NO_ERROR) {
|
||||
WCHAR buf[IF_MAX_STRING_SIZE + 1];
|
||||
if (ptrConvertInterfaceLuidToName(&luid, buf, sizeof(buf)/sizeof(buf[0])) == NO_ERROR)
|
||||
return QString::fromWCharArray(buf);
|
||||
}
|
||||
}
|
||||
|
||||
return QString::number(index);
|
||||
}
|
||||
|
||||
static QHash<QHostAddress, QHostAddress> ipv4Netmasks()
|
||||
{
|
||||
//Retrieve all the IPV4 addresses & netmasks
|
||||
|
@ -59,6 +59,20 @@ struct HostNameInfo {
|
||||
QString address;
|
||||
};
|
||||
|
||||
uint QNetworkInterfaceManager::interfaceIndexFromName(const QString &name)
|
||||
{
|
||||
// TBD - may not be possible
|
||||
Q_UNUSED(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString QNetworkInterfaceManager::interfaceNameFromIndex(uint index)
|
||||
{
|
||||
// TBD - may not be possible
|
||||
return QString::number(index);
|
||||
}
|
||||
|
||||
|
||||
static QList<QNetworkInterfacePrivate *> interfaceListing()
|
||||
{
|
||||
QList<QNetworkInterfacePrivate *> interfaces;
|
||||
|
@ -45,6 +45,7 @@
|
||||
// We mean it.
|
||||
//
|
||||
#include "QtNetwork/qhostaddress.h"
|
||||
#include "QtNetwork/qnetworkinterface.h"
|
||||
#include "private/qabstractsocketengine_p.h"
|
||||
#ifndef Q_OS_WIN
|
||||
# include "qplatformdefs.h"
|
||||
@ -264,7 +265,8 @@ public:
|
||||
bool checkProxy(const QHostAddress &address);
|
||||
bool fetchConnectionParameters();
|
||||
|
||||
static uint scopeIdFromString(const QString &scopeid);
|
||||
static uint scopeIdFromString(const QString &scopeid)
|
||||
{ return QNetworkInterface::interfaceIndexFromName(scopeid); }
|
||||
|
||||
/*! \internal
|
||||
Sets \a address and \a port in the \a aa sockaddr structure and the size in \a sockAddrSize.
|
||||
|
@ -107,15 +107,8 @@ static inline void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *po
|
||||
QHostAddress tmpAddress;
|
||||
tmpAddress.setAddress(tmp);
|
||||
*addr = tmpAddress;
|
||||
if (s->a6.sin6_scope_id) {
|
||||
#ifndef QT_NO_IPV6IFNAME
|
||||
char scopeid[IFNAMSIZ];
|
||||
if (::if_indextoname(s->a6.sin6_scope_id, scopeid)) {
|
||||
addr->setScopeId(QLatin1String(scopeid));
|
||||
} else
|
||||
#endif
|
||||
addr->setScopeId(QString::number(s->a6.sin6_scope_id));
|
||||
}
|
||||
if (s->a6.sin6_scope_id)
|
||||
addr->setScopeId(QNetworkInterface::interfaceNameFromIndex(s->a6.sin6_scope_id));
|
||||
}
|
||||
if (port)
|
||||
*port = ntohs(s->a6.sin6_port);
|
||||
@ -131,21 +124,6 @@ static inline void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *po
|
||||
}
|
||||
}
|
||||
|
||||
// inline on purpose
|
||||
inline uint QNativeSocketEnginePrivate::scopeIdFromString(const QString &scopeid)
|
||||
{
|
||||
if (scopeid.isEmpty())
|
||||
return 0;
|
||||
|
||||
bool ok;
|
||||
uint id = scopeid.toUInt(&ok);
|
||||
#ifndef QT_NO_IPV6IFNAME
|
||||
if (!ok)
|
||||
id = ::if_nametoindex(scopeid.toLatin1());
|
||||
#endif
|
||||
return id;
|
||||
}
|
||||
|
||||
static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt,
|
||||
QAbstractSocket::NetworkLayerProtocol socketProtocol, int &level, int &n)
|
||||
{
|
||||
|
@ -322,12 +322,6 @@ static inline int qt_socket_getMaxMsgSize(qintptr socketDescriptor)
|
||||
# define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
|
||||
#endif
|
||||
|
||||
// inline on purpose
|
||||
inline uint QNativeSocketEnginePrivate::scopeIdFromString(const QString &scopeid)
|
||||
{
|
||||
return scopeid.toUInt();
|
||||
}
|
||||
|
||||
bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol)
|
||||
{
|
||||
|
||||
|
@ -203,6 +203,11 @@ void tst_QNetworkInterface::interfaceFromXXX()
|
||||
QFETCH(QNetworkInterface, iface);
|
||||
|
||||
QVERIFY(QNetworkInterface::interfaceFromName(iface.name()).isValid());
|
||||
if (int idx = iface.index()) {
|
||||
QVERIFY(QNetworkInterface::interfaceFromIndex(idx).isValid());
|
||||
QCOMPARE(QNetworkInterface::interfaceNameFromIndex(idx), iface.name());
|
||||
QCOMPARE(QNetworkInterface::interfaceIndexFromName(iface.name()), idx);
|
||||
}
|
||||
foreach (QNetworkAddressEntry entry, iface.addressEntries()) {
|
||||
QVERIFY(!entry.ip().isNull());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user