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>();
|
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
|
Returns a QNetworkInterface object for the interface named \a
|
||||||
name. If no such interface exists, this function returns an
|
name. If no such interface exists, this function returns an
|
||||||
@ -552,6 +577,27 @@ QNetworkInterface QNetworkInterface::interfaceFromIndex(int index)
|
|||||||
return result;
|
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
|
Returns a listing of all the network interfaces found on the host
|
||||||
machine. In case of failure it returns a list with zero elements.
|
machine. In case of failure it returns a list with zero elements.
|
||||||
|
@ -113,8 +113,10 @@ public:
|
|||||||
QString hardwareAddress() const;
|
QString hardwareAddress() const;
|
||||||
QList<QNetworkAddressEntry> addressEntries() const;
|
QList<QNetworkAddressEntry> addressEntries() const;
|
||||||
|
|
||||||
|
static int interfaceIndexFromName(const QString &name);
|
||||||
static QNetworkInterface interfaceFromName(const QString &name);
|
static QNetworkInterface interfaceFromName(const QString &name);
|
||||||
static QNetworkInterface interfaceFromIndex(int index);
|
static QNetworkInterface interfaceFromIndex(int index);
|
||||||
|
static QString interfaceNameFromIndex(int index);
|
||||||
static QList<QNetworkInterface> allInterfaces();
|
static QList<QNetworkInterface> allInterfaces();
|
||||||
static QList<QHostAddress> allAddresses();
|
static QList<QHostAddress> allAddresses();
|
||||||
|
|
||||||
|
@ -100,6 +100,9 @@ public:
|
|||||||
QSharedDataPointer<QNetworkInterfacePrivate> interfaceFromIndex(int index);
|
QSharedDataPointer<QNetworkInterfacePrivate> interfaceFromIndex(int index);
|
||||||
QList<QSharedDataPointer<QNetworkInterfacePrivate> > allInterfaces();
|
QList<QSharedDataPointer<QNetworkInterfacePrivate> > allInterfaces();
|
||||||
|
|
||||||
|
static uint interfaceIndexFromName(const QString &name);
|
||||||
|
static QString interfaceNameFromIndex(uint index);
|
||||||
|
|
||||||
// convenience:
|
// convenience:
|
||||||
QSharedDataPointer<QNetworkInterfacePrivate> empty;
|
QSharedDataPointer<QNetworkInterfacePrivate> empty;
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
** Copyright (C) 2015 Intel Corporation.
|
||||||
** Contact: http://www.qt.io/licensing/
|
** Contact: http://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the QtNetwork module of the Qt Toolkit.
|
** 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:
|
// this is the most likely scenario:
|
||||||
// a scope ID in a socket is that of the interface this address came from
|
// a scope ID in a socket is that of the interface this address came from
|
||||||
address.setScopeId(ifname);
|
address.setScopeId(ifname);
|
||||||
} else if (scope) {
|
} else if (scope) {
|
||||||
#ifndef QT_NO_IPV6IFNAME
|
address.setScopeId(QNetworkInterfaceManager::interfaceNameFromIndex(scope));
|
||||||
char scopeid[IFNAMSIZ];
|
|
||||||
if (::if_indextoname(scope, scopeid)) {
|
|
||||||
address.setScopeId(QLatin1String(scopeid));
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
address.setScopeId(QString::number(uint(scope)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return address;
|
return address;
|
||||||
@ -124,6 +119,53 @@ static QNetworkInterface::InterfaceFlags convertFlags(uint rawFlags)
|
|||||||
return flags;
|
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
|
#ifdef QT_NO_GETIFADDRS
|
||||||
// getifaddrs not available
|
// getifaddrs not available
|
||||||
|
|
||||||
|
@ -57,8 +57,14 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
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 *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 PtrConvertInterfaceLuidToName ptrConvertInterfaceLuidToName = 0;
|
||||||
|
static PtrConvertInterfaceLuidToIndex ptrConvertInterfaceLuidToIndex = 0;
|
||||||
|
static PtrConvertInterfaceNameToLuid ptrConvertInterfaceNameToLuid = 0;
|
||||||
|
|
||||||
static void resolveLibs()
|
static void resolveLibs()
|
||||||
{
|
{
|
||||||
@ -71,10 +77,16 @@ static void resolveLibs()
|
|||||||
|
|
||||||
#if defined(Q_OS_WINCE)
|
#if defined(Q_OS_WINCE)
|
||||||
// since Windows Embedded Compact 7
|
// since Windows Embedded Compact 7
|
||||||
|
ptrConvertInterfaceIndexToLuid = (PtrConvertInterfaceIndexToLuid)GetProcAddress(iphlpapiHnd, L"ConvertInterfaceIndexToLuid");
|
||||||
ptrConvertInterfaceLuidToName = (PtrConvertInterfaceLuidToName)GetProcAddress(iphlpapiHnd, L"ConvertInterfaceLuidToNameW");
|
ptrConvertInterfaceLuidToName = (PtrConvertInterfaceLuidToName)GetProcAddress(iphlpapiHnd, L"ConvertInterfaceLuidToNameW");
|
||||||
|
ptrConvertInterfaceLuidToIndex = (PtrConvertInterfaceLuidToIndex)GetProcAddress(iphlpapiHnd, L"ConvertInterfaceLuidToIndex");
|
||||||
|
ptrConvertInterfaceNameToLuid = (PtrConvertInterfaceNameToLuid)GetProcAddress(iphlpapiHnd, L"ConvertInterfaceNameToLuidW");
|
||||||
#else
|
#else
|
||||||
// since Windows Vista
|
// since Windows Vista
|
||||||
|
ptrConvertInterfaceIndexToLuid = (PtrConvertInterfaceIndexToLuid)GetProcAddress(iphlpapiHnd, "ConvertInterfaceIndexToLuid");
|
||||||
ptrConvertInterfaceLuidToName = (PtrConvertInterfaceLuidToName)GetProcAddress(iphlpapiHnd, "ConvertInterfaceLuidToNameW");
|
ptrConvertInterfaceLuidToName = (PtrConvertInterfaceLuidToName)GetProcAddress(iphlpapiHnd, "ConvertInterfaceLuidToNameW");
|
||||||
|
ptrConvertInterfaceLuidToIndex = (PtrConvertInterfaceLuidToIndex)GetProcAddress(iphlpapiHnd, "ConvertInterfaceLuidToIndex");
|
||||||
|
ptrConvertInterfaceNameToLuid = (PtrConvertInterfaceNameToLuid)GetProcAddress(iphlpapiHnd, "ConvertInterfaceNameToLuidW");
|
||||||
#endif
|
#endif
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
@ -92,13 +104,42 @@ static QHostAddress addressFromSockaddr(sockaddr *sa)
|
|||||||
address.setAddress(((sockaddr_in6 *)sa)->sin6_addr.s6_addr);
|
address.setAddress(((sockaddr_in6 *)sa)->sin6_addr.s6_addr);
|
||||||
int scope = ((sockaddr_in6 *)sa)->sin6_scope_id;
|
int scope = ((sockaddr_in6 *)sa)->sin6_scope_id;
|
||||||
if (scope)
|
if (scope)
|
||||||
address.setScopeId(QString::number(scope));
|
address.setScopeId(QNetworkInterfaceManager::interfaceNameFromIndex(scope));
|
||||||
} else
|
} else
|
||||||
qWarning("Got unknown socket family %d", sa->sa_family);
|
qWarning("Got unknown socket family %d", sa->sa_family);
|
||||||
return address;
|
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()
|
static QHash<QHostAddress, QHostAddress> ipv4Netmasks()
|
||||||
{
|
{
|
||||||
//Retrieve all the IPV4 addresses & netmasks
|
//Retrieve all the IPV4 addresses & netmasks
|
||||||
|
@ -59,6 +59,20 @@ struct HostNameInfo {
|
|||||||
QString address;
|
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()
|
static QList<QNetworkInterfacePrivate *> interfaceListing()
|
||||||
{
|
{
|
||||||
QList<QNetworkInterfacePrivate *> interfaces;
|
QList<QNetworkInterfacePrivate *> interfaces;
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
// We mean it.
|
// We mean it.
|
||||||
//
|
//
|
||||||
#include "QtNetwork/qhostaddress.h"
|
#include "QtNetwork/qhostaddress.h"
|
||||||
|
#include "QtNetwork/qnetworkinterface.h"
|
||||||
#include "private/qabstractsocketengine_p.h"
|
#include "private/qabstractsocketengine_p.h"
|
||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
# include "qplatformdefs.h"
|
# include "qplatformdefs.h"
|
||||||
@ -264,7 +265,8 @@ public:
|
|||||||
bool checkProxy(const QHostAddress &address);
|
bool checkProxy(const QHostAddress &address);
|
||||||
bool fetchConnectionParameters();
|
bool fetchConnectionParameters();
|
||||||
|
|
||||||
static uint scopeIdFromString(const QString &scopeid);
|
static uint scopeIdFromString(const QString &scopeid)
|
||||||
|
{ return QNetworkInterface::interfaceIndexFromName(scopeid); }
|
||||||
|
|
||||||
/*! \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.
|
||||||
|
@ -107,15 +107,8 @@ static inline void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *po
|
|||||||
QHostAddress tmpAddress;
|
QHostAddress tmpAddress;
|
||||||
tmpAddress.setAddress(tmp);
|
tmpAddress.setAddress(tmp);
|
||||||
*addr = tmpAddress;
|
*addr = tmpAddress;
|
||||||
if (s->a6.sin6_scope_id) {
|
if (s->a6.sin6_scope_id)
|
||||||
#ifndef QT_NO_IPV6IFNAME
|
addr->setScopeId(QNetworkInterface::interfaceNameFromIndex(s->a6.sin6_scope_id));
|
||||||
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 (port)
|
if (port)
|
||||||
*port = ntohs(s->a6.sin6_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,
|
static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt,
|
||||||
QAbstractSocket::NetworkLayerProtocol socketProtocol, int &level, int &n)
|
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)
|
# define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// inline on purpose
|
|
||||||
inline uint QNativeSocketEnginePrivate::scopeIdFromString(const QString &scopeid)
|
|
||||||
{
|
|
||||||
return scopeid.toUInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol)
|
bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -203,6 +203,11 @@ void tst_QNetworkInterface::interfaceFromXXX()
|
|||||||
QFETCH(QNetworkInterface, iface);
|
QFETCH(QNetworkInterface, iface);
|
||||||
|
|
||||||
QVERIFY(QNetworkInterface::interfaceFromName(iface.name()).isValid());
|
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()) {
|
foreach (QNetworkAddressEntry entry, iface.addressEntries()) {
|
||||||
QVERIFY(!entry.ip().isNull());
|
QVERIFY(!entry.ip().isNull());
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user