Avoid one extra if_indextoname per address in QNetworkInterface

Given an IPv6 address associated with a network interface, there's a
fairly high chance (of 100%) that any scope ID found is that of the
interface.

Change-Id: Id7315473f39b68ee4c169207168dc2e60fd7d570
Reviewed-by: Richard J. Moore <rich@kde.org>
Reviewed-by: Peter Hartmann <phartmann@blackberry.com>
Reviewed-by: Jonas Gastal <gastal@intel.com>
This commit is contained in:
Thiago Macieira 2013-07-13 12:02:57 +02:00 committed by The Qt Project
parent 7a3653887c
commit dae087b30f

View File

@ -81,7 +81,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
static QHostAddress addressFromSockaddr(sockaddr *sa) static QHostAddress addressFromSockaddr(sockaddr *sa, int ifindex = 0, const QString &ifname = QString())
{ {
QHostAddress address; QHostAddress address;
if (!sa) if (!sa)
@ -92,7 +92,11 @@ static QHostAddress addressFromSockaddr(sockaddr *sa)
else if (sa->sa_family == AF_INET6) { else if (sa->sa_family == AF_INET6) {
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 && scope == ifindex) {
// 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 #ifndef QT_NO_IPV6IFNAME
char scopeid[IFNAMSIZ]; char scopeid[IFNAMSIZ];
if (::if_indextoname(scope, scopeid)) { if (::if_indextoname(scope, scopeid)) {
@ -434,14 +438,14 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
} }
QNetworkAddressEntry entry; QNetworkAddressEntry entry;
entry.setIp(addressFromSockaddr(ptr->ifa_addr)); entry.setIp(addressFromSockaddr(ptr->ifa_addr, iface->index, iface->name));
if (entry.ip().isNull()) if (entry.ip().isNull())
// could not parse the address // could not parse the address
continue; continue;
entry.setNetmask(addressFromSockaddr(ptr->ifa_netmask)); entry.setNetmask(addressFromSockaddr(ptr->ifa_netmask, iface->index, iface->name));
if (iface->flags & QNetworkInterface::CanBroadcast) if (iface->flags & QNetworkInterface::CanBroadcast)
entry.setBroadcast(addressFromSockaddr(ptr->ifa_broadaddr)); entry.setBroadcast(addressFromSockaddr(ptr->ifa_broadaddr, iface->index, iface->name));
iface->addressEntries << entry; iface->addressEntries << entry;
} }