diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/network/kernel/qnetworkinterface.cpp | 46 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface.h | 2 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface_p.h | 3 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface_unix.cpp | 58 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface_win.cpp | 43 | ||||
-rw-r--r-- | src/network/kernel/qnetworkinterface_winrt.cpp | 14 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine_p.h | 4 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine_unix.cpp | 26 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine_win.cpp | 6 |
9 files changed, 162 insertions, 40 deletions
diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp index 4a527052d1..81906edc47 100644 --- a/src/network/kernel/qnetworkinterface.cpp +++ b/src/network/kernel/qnetworkinterface.cpp @@ -519,6 +519,31 @@ QList<QNetworkAddressEntry> QNetworkInterface::addressEntries() const } /*! + \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 invalid QNetworkInterface object. @@ -553,6 +578,27 @@ QNetworkInterface QNetworkInterface::interfaceFromIndex(int index) } /*! + \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. */ diff --git a/src/network/kernel/qnetworkinterface.h b/src/network/kernel/qnetworkinterface.h index b3daa3d4a0..bd57aea1cb 100644 --- a/src/network/kernel/qnetworkinterface.h +++ b/src/network/kernel/qnetworkinterface.h @@ -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(); diff --git a/src/network/kernel/qnetworkinterface_p.h b/src/network/kernel/qnetworkinterface_p.h index 140a28c536..146ba7820c 100644 --- a/src/network/kernel/qnetworkinterface_p.h +++ b/src/network/kernel/qnetworkinterface_p.h @@ -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; diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp index cc53087024..541c78d838 100644 --- a/src/network/kernel/qnetworkinterface_unix.cpp +++ b/src/network/kernel/qnetworkinterface_unix.cpp @@ -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 diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp index 907638f73e..238f913846 100644 --- a/src/network/kernel/qnetworkinterface_win.cpp +++ b/src/network/kernel/qnetworkinterface_win.cpp @@ -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 diff --git a/src/network/kernel/qnetworkinterface_winrt.cpp b/src/network/kernel/qnetworkinterface_winrt.cpp index 0234154427..88c0eae2f7 100644 --- a/src/network/kernel/qnetworkinterface_winrt.cpp +++ b/src/network/kernel/qnetworkinterface_winrt.cpp @@ -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; diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h index 0fa1d8f96e..5cc5e529fc 100644 --- a/src/network/socket/qnativesocketengine_p.h +++ b/src/network/socket/qnativesocketengine_p.h @@ -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. diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index c40eef769e..fab4d1c532 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -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) { diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 9aed0caa25..a7fb5f5502 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -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) { |