summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/network/kernel/qhostaddress.cpp27
-rw-r--r--src/network/kernel/qhostaddress.h1
-rw-r--r--src/network/kernel/qhostaddress_p.h29
-rw-r--r--src/network/kernel/qnetworkinterface.cpp68
-rw-r--r--src/network/kernel/qnetworkinterface.h9
-rw-r--r--src/network/kernel/qnetworkinterface_linux.cpp5
-rw-r--r--src/network/kernel/qnetworkinterface_p.h15
-rw-r--r--src/network/kernel/qnetworkinterface_unix.cpp11
-rw-r--r--src/network/kernel/qnetworkinterface_win.cpp3
9 files changed, 139 insertions, 29 deletions
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index 72b6d2dc70..bf00c6efce 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -64,33 +64,6 @@
QT_BEGIN_NAMESPACE
-class QHostAddressPrivate : public QSharedData
-{
-public:
- QHostAddressPrivate();
-
- void setAddress(quint32 a_ = 0);
- void setAddress(const quint8 *a_);
- void setAddress(const Q_IPV6ADDR &a_);
-
- bool parse(const QString &ipString);
- void clear();
-
- QString scopeId;
-
- union {
- Q_IPV6ADDR a6; // IPv6 address
- struct { quint64 c[2]; } a6_64;
- struct { quint32 c[4]; } a6_32;
- };
- quint32 a; // IPv4 address
- qint8 protocol;
-
- AddressClassification classify() const;
-
- friend class QHostAddress;
-};
-
QHostAddressPrivate::QHostAddressPrivate()
: a(0), protocol(QAbstractSocket::UnknownNetworkLayerProtocol)
{
diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h
index bb1424826d..00555f3d8e 100644
--- a/src/network/kernel/qhostaddress.h
+++ b/src/network/kernel/qhostaddress.h
@@ -159,6 +159,7 @@ public:
friend Q_NETWORK_EXPORT uint qHash(const QHostAddress &key, uint seed) Q_DECL_NOTHROW;
protected:
+ friend class QHostAddressPrivate;
QExplicitlySharedDataPointer<QHostAddressPrivate> d;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QHostAddress::ConversionMode)
diff --git a/src/network/kernel/qhostaddress_p.h b/src/network/kernel/qhostaddress_p.h
index f06feb0559..4dc2989011 100644
--- a/src/network/kernel/qhostaddress_p.h
+++ b/src/network/kernel/qhostaddress_p.h
@@ -101,6 +101,35 @@ public:
{ return n1.length == n2.length; }
};
+class QHostAddressPrivate : public QSharedData
+{
+public:
+ QHostAddressPrivate();
+
+ void setAddress(quint32 a_ = 0);
+ void setAddress(const quint8 *a_);
+ void setAddress(const Q_IPV6ADDR &a_);
+
+ bool parse(const QString &ipString);
+ void clear();
+
+ QString scopeId;
+
+ union {
+ Q_IPV6ADDR a6; // IPv6 address
+ struct { quint64 c[2]; } a6_64;
+ struct { quint32 c[4]; } a6_32;
+ };
+ quint32 a; // IPv4 address
+ qint8 protocol;
+
+ AddressClassification classify() const;
+ static AddressClassification classify(const QHostAddress &address)
+ { return address.d->classify(); }
+
+ friend class QHostAddress;
+};
+
QT_END_NAMESPACE
#endif
diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp
index e546c8d949..ec58fa65c0 100644
--- a/src/network/kernel/qnetworkinterface.cpp
+++ b/src/network/kernel/qnetworkinterface.cpp
@@ -119,8 +119,15 @@ QList<QSharedDataPointer<QNetworkInterfacePrivate> > QNetworkInterfaceManager::a
QList<QSharedDataPointer<QNetworkInterfacePrivate> > result;
result.reserve(list.size());
- for (QNetworkInterfacePrivate *ptr : list)
+ for (QNetworkInterfacePrivate *ptr : list) {
+ if ((ptr->flags & QNetworkInterface::IsUp) == 0) {
+ // if the network interface isn't UP, the addresses are ineligible for DNS
+ for (auto &addr : ptr->addressEntries)
+ addr.setDnsEligibility(QNetworkAddressEntry::DnsIneligible);
+ }
+
result << QSharedDataPointer<QNetworkInterfacePrivate>(ptr);
+ }
return result;
}
@@ -159,6 +166,32 @@ QString QNetworkInterfacePrivate::makeHwAddress(int len, uchar *data)
*/
/*!
+ \enum QNetworkAddressEntry::DnsEligilibilityStatus
+ \since 5.11
+
+ This enum indicates whether a given host address is eligible to be
+ published in the Domain Name System (DNS) or other similar name resolution
+ mechanisms. In general, an address is suitable for publication if it is an
+ address this machine will be reached at for an indeterminate amount of
+ time, though it need not be permanent. For example, addresses obtained via
+ DHCP are often eligible, but cryptographically-generated temporary IPv6
+ addresses are not.
+
+ \value DnsEligibilityUnknown Qt and the operating system could not determine
+ whether this address should be published or not.
+ The application may need to apply further
+ heuristics if it cannot find any eligible
+ addresses.
+ \value DnsEligible This address is eligible for publication in DNS.
+ \value DnsIneligible This address should not be published in DNS and
+ should not be transmitted to other parties,
+ except maybe as the source address of an outgoing
+ packet.
+
+ \sa dnsEligibility(), setDnsEligibility()
+*/
+
+/*!
Constructs an empty QNetworkAddressEntry object.
*/
QNetworkAddressEntry::QNetworkAddressEntry()
@@ -213,6 +246,39 @@ bool QNetworkAddressEntry::operator==(const QNetworkAddressEntry &other) const
}
/*!
+ \since 5.11
+
+ Returns whether this address is eligible for publication in the Domain Name
+ System (DNS) or similar name resolution mechanisms.
+
+ In general, an address is suitable for publication if it is an address this
+ machine will be reached at for an indeterminate amount of time, though it
+ need not be permanent. For example, addresses obtained via DHCP are often
+ eligible, but cryptographically-generated temporary IPv6 addresses are not.
+
+ On some systems, QNetworkInterface will need to heuristically determine
+ which addresses are eligible.
+
+ \sa isLifetimeKnown(), isPermanent(), setDnsEligibility()
+*/
+QNetworkAddressEntry::DnsEligibilityStatus QNetworkAddressEntry::dnsEligibility() const
+{
+ return d->dnsEligibility;
+}
+
+/*!
+ \since 5.11
+
+ Sets the DNS eligibility flag for this address to \a status.
+
+ \sa dnsEligibility()
+*/
+void QNetworkAddressEntry::setDnsEligibility(DnsEligibilityStatus status)
+{
+ d->dnsEligibility = status;
+}
+
+/*!
\fn bool QNetworkAddressEntry::operator!=(const QNetworkAddressEntry &other) const
Returns \c true if this network address entry is different from \a
diff --git a/src/network/kernel/qnetworkinterface.h b/src/network/kernel/qnetworkinterface.h
index d39615e430..32b358eb8f 100644
--- a/src/network/kernel/qnetworkinterface.h
+++ b/src/network/kernel/qnetworkinterface.h
@@ -56,6 +56,12 @@ class QNetworkAddressEntryPrivate;
class Q_NETWORK_EXPORT QNetworkAddressEntry
{
public:
+ enum DnsEligibilityStatus : qint8 {
+ DnsEligibilityUnknown = -1,
+ DnsIneligible = 0,
+ DnsEligible = 1
+ };
+
QNetworkAddressEntry();
QNetworkAddressEntry(const QNetworkAddressEntry &other);
#ifdef Q_COMPILER_RVALUE_REFS
@@ -70,6 +76,9 @@ public:
inline bool operator!=(const QNetworkAddressEntry &other) const
{ return !(*this == other); }
+ DnsEligibilityStatus dnsEligibility() const;
+ void setDnsEligibility(DnsEligibilityStatus status);
+
QHostAddress ip() const;
void setIp(const QHostAddress &newIp);
diff --git a/src/network/kernel/qnetworkinterface_linux.cpp b/src/network/kernel/qnetworkinterface_linux.cpp
index cc66c310cb..5940f80dfa 100644
--- a/src/network/kernel/qnetworkinterface_linux.cpp
+++ b/src/network/kernel/qnetworkinterface_linux.cpp
@@ -406,7 +406,10 @@ static void getAddresses(int sock, char *buf, QList<QNetworkInterfacePrivate *>
}
// now handle flags
- Q_UNUSED(flags);
+ QNetworkInterfacePrivate::calculateDnsEligibility(&entry,
+ flags & IFA_F_TEMPORARY,
+ flags & IFA_F_DEPRECATED);
+
if (!entry.ip().isNull()) {
entry.setPrefixLength(ifa->ifa_prefixlen);
diff --git a/src/network/kernel/qnetworkinterface_p.h b/src/network/kernel/qnetworkinterface_p.h
index 305a8fe020..b16149e12f 100644
--- a/src/network/kernel/qnetworkinterface_p.h
+++ b/src/network/kernel/qnetworkinterface_p.h
@@ -76,6 +76,7 @@ public:
QNetmask netmask;
bool lifetimeKnown = false;
+ QNetworkAddressEntry::DnsEligibilityStatus dnsEligibility = QNetworkAddressEntry::DnsEligibilityUnknown;
};
class QNetworkInterfacePrivate: public QSharedData
@@ -97,6 +98,20 @@ public:
QList<QNetworkAddressEntry> addressEntries;
static QString makeHwAddress(int len, uchar *data);
+ static void calculateDnsEligibility(QNetworkAddressEntry *entry, bool isTemporary,
+ bool isDeprecated)
+ {
+ // this implements an algorithm that yields the same results as Windows
+ // produces, for the same input (as far as I can test)
+ if (isTemporary || isDeprecated)
+ entry->setDnsEligibility(QNetworkAddressEntry::DnsIneligible);
+
+ AddressClassification cl = QHostAddressPrivate::classify(entry->ip());
+ if (cl == LoopbackAddress || cl == LinkLocalAddress)
+ entry->setDnsEligibility(QNetworkAddressEntry::DnsIneligible);
+ else
+ entry->setDnsEligibility(QNetworkAddressEntry::DnsEligible);
+ }
private:
// disallow copying -- avoid detaching
diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp
index 7733f073d0..1c2f5d335a 100644
--- a/src/network/kernel/qnetworkinterface_unix.cpp
+++ b/src/network/kernel/qnetworkinterface_unix.cpp
@@ -499,6 +499,17 @@ static void getAddressExtraInfo(QNetworkAddressEntry *entry, struct sockaddr *sa
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+ // get flags
+ ifr.ifr_addr = *reinterpret_cast<struct sockaddr_in6 *>(sa);
+ if (qt_safe_ioctl(s6, SIOCGIFAFLAG_IN6, &ifr) < 0) {
+ qt_safe_close(s6);
+ return;
+ }
+ int flags = ifr.ifr_ifru.ifru_flags6;
+ QNetworkInterfacePrivate::calculateDnsEligibility(entry,
+ flags & IN6_IFF_TEMPORARY,
+ flags & IN6_IFF_DEPRECATED);
+
// get lifetimes
ifr.ifr_addr = *reinterpret_cast<struct sockaddr_in6 *>(sa);
if (qt_safe_ioctl(s6, SIOCGIFALIFETIME_IN6, &ifr) < 0) {
diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp
index 34d253a6d2..705bc24c32 100644
--- a/src/network/kernel/qnetworkinterface_win.cpp
+++ b/src/network/kernel/qnetworkinterface_win.cpp
@@ -229,6 +229,9 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
return QDeadlineTimer(lifetime * 1000);
};
entry.setAddressLifetime(toDeadline(addr->ValidLifetime), toDeadline(addr->PreferredLifetime));
+ entry.setDnsEligibility(addr->Flags & IP_ADAPTER_ADDRESS_DNS_ELIGIBLE ?
+ QNetworkAddressEntry::DnsEligible :
+ QNetworkAddressEntry::DnsIneligible);
iface->addressEntries << entry;
}