summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2017-08-10 00:22:56 -0700
committerThiago Macieira <thiago.macieira@intel.com>2017-11-07 22:15:39 +0000
commit05012f4285ac38c7975138b7f839e158a6f961a3 (patch)
treedd9bfc554ee34feb74084fae87bbad65aa50dfef
parent18ec85a80c06d770c3943d98f3981ac829fd75ca (diff)
QNetworkInterface: add MTU
[ChangeLog][QtNetwork][QNetworkInterface] Added maxTransmissionUnit(). Change-Id: Iaf4157b7efa2416d898cfffd14d96b2970d6af87 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
-rw-r--r--src/network/kernel/qnetworkinterface.cpp23
-rw-r--r--src/network/kernel/qnetworkinterface.h1
-rw-r--r--src/network/kernel/qnetworkinterface_linux.cpp5
-rw-r--r--src/network/kernel/qnetworkinterface_p.h1
-rw-r--r--src/network/kernel/qnetworkinterface_unix.cpp20
-rw-r--r--src/network/kernel/qnetworkinterface_win.cpp1
-rw-r--r--tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp1
7 files changed, 51 insertions, 1 deletions
diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp
index ec58fa65c0..3fb0dc80ee 100644
--- a/src/network/kernel/qnetworkinterface.cpp
+++ b/src/network/kernel/qnetworkinterface.cpp
@@ -689,6 +689,29 @@ int QNetworkInterface::index() const
}
/*!
+ \since 5.11
+
+ Returns the maximum transmission unit on this interface, if known, or 0
+ otherwise.
+
+ The maximum transmission unit is the largest packet that may be sent on
+ this interface without incurring link-level fragmentation. Applications may
+ use this value to calculate the size of the payload that will fit an
+ unfragmented UDP datagram. Remember to subtract the sizes of headers used
+ in your communication over the interface, e.g. TCP (20 bytes) or UDP (12),
+ IPv4 (20) or IPv6 (40, absent some form of header compression), when
+ computing how big a payload you can transmit. Also note that the MTU along
+ the full path (the Path MTU) to the destination may be smaller than the
+ interface's MTU.
+
+ \sa QUdpSocket
+*/
+int QNetworkInterface::maxTransmissionUnit() const
+{
+ return d ? d->mtu : 0;
+}
+
+/*!
Returns the name of this network interface. On Unix systems, this
is a string containing the type of the interface and optionally a
sequence number, such as "eth0", "lo" or "pcn0". On Windows, it's
diff --git a/src/network/kernel/qnetworkinterface.h b/src/network/kernel/qnetworkinterface.h
index 32b358eb8f..f7ef192dc0 100644
--- a/src/network/kernel/qnetworkinterface.h
+++ b/src/network/kernel/qnetworkinterface.h
@@ -153,6 +153,7 @@ public:
bool isValid() const;
int index() const;
+ int maxTransmissionUnit() const;
QString name() const;
QString humanReadableName() const;
InterfaceFlags flags() const;
diff --git a/src/network/kernel/qnetworkinterface_linux.cpp b/src/network/kernel/qnetworkinterface_linux.cpp
index 5940f80dfa..620ee7202b 100644
--- a/src/network/kernel/qnetworkinterface_linux.cpp
+++ b/src/network/kernel/qnetworkinterface_linux.cpp
@@ -293,6 +293,11 @@ static QList<QNetworkInterfacePrivate *> getInterfaces(int sock, char *buf)
iface->name = QString::fromLatin1(payloadPtr, payloadLen - 1);
break;
+ case IFLA_MTU:
+ Q_ASSERT(payloadLen == sizeof(int));
+ iface->mtu = *reinterpret_cast<int *>(payloadPtr);
+ break;
+
case IFLA_OPERSTATE: // operational state
if (*payloadPtr != IF_OPER_UNKNOWN) {
// override the flag
diff --git a/src/network/kernel/qnetworkinterface_p.h b/src/network/kernel/qnetworkinterface_p.h
index b16149e12f..87a46b75fa 100644
--- a/src/network/kernel/qnetworkinterface_p.h
+++ b/src/network/kernel/qnetworkinterface_p.h
@@ -88,6 +88,7 @@ public:
{ }
int index; // interface index, if know
+ int mtu = 0;
QNetworkInterface::InterfaceFlags flags;
QNetworkInterface::InterfaceType type = QNetworkInterface::Unknown;
diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp
index 1c2f5d335a..2f3c940d25 100644
--- a/src/network/kernel/qnetworkinterface_unix.cpp
+++ b/src/network/kernel/qnetworkinterface_unix.cpp
@@ -139,6 +139,15 @@ QString QNetworkInterfaceManager::interfaceNameFromIndex(uint index)
return QString::number(uint(index));
}
+static int getMtu(int socket, struct ifreq *req)
+{
+#ifdef SIOCGIFMTU
+ if (qt_safe_ioctl(socket, SIOCGIFMTU, req) == 0)
+ return req->ifr_mtu;
+#endif
+ return 0;
+}
+
#ifdef QT_NO_GETIFADDRS
// getifaddrs not available
@@ -278,6 +287,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
if (qt_safe_ioctl(socket, SIOCGIFFLAGS, &req) >= 0) {
iface->flags = convertFlags(req.ifr_flags);
}
+ iface->mtu = getMtu(socket, &req);
#ifdef SIOCGIFHWADDR
// Get the HW address
@@ -458,9 +468,16 @@ static QNetworkInterface::InterfaceType probeIfType(int socket, int iftype, stru
static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)
{
QList<QNetworkInterfacePrivate *> interfaces;
- struct ifmediareq mediareq;
+ union {
+ struct ifmediareq mediareq;
+ struct ifreq req;
+ };
int socket = -1;
+ // ensure both structs start with the name field, of size IFNAMESIZ
+ Q_STATIC_ASSERT(sizeof(mediareq.ifm_name) == sizeof(req.ifr_name));
+ Q_ASSERT(&mediareq.ifm_name == &req.ifr_name);
+
// on NetBSD we use AF_LINK and sockaddr_dl
// scan the list for that family
for (ifaddrs *ptr = rawList; ptr; ptr = ptr->ifa_next)
@@ -476,6 +493,7 @@ static QList<QNetworkInterfacePrivate *> createInterfaces(ifaddrs *rawList)
strlcpy(mediareq.ifm_name, ptr->ifa_name, sizeof(mediareq.ifm_name));
iface->type = probeIfType(openSocket(socket), sdl->sdl_type, &mediareq);
+ iface->mtu = getMtu(socket, &req);
}
if (socket != -1)
diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp
index 705bc24c32..857e40215c 100644
--- a/src/network/kernel/qnetworkinterface_win.cpp
+++ b/src/network/kernel/qnetworkinterface_win.cpp
@@ -151,6 +151,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
else if (ptr->IfIndex != 0)
iface->index = ptr->IfIndex;
+ iface->mtu = ptr->Mtu;
iface->flags = QNetworkInterface::CanBroadcast;
if (ptr->OperStatus == IfOperStatusUp)
iface->flags |= QNetworkInterface::IsUp | QNetworkInterface::IsRunning;
diff --git a/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp b/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp
index 2f2937fcdb..ae5082fecb 100644
--- a/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp
+++ b/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp
@@ -140,6 +140,7 @@ void tst_QNetworkInterface::dump()
qDebug() << " flags: " << qPrintable(flags);
qDebug() << " type: " << i.type();
qDebug() << " hw address:" << qPrintable(i.hardwareAddress());
+ qDebug() << " MTU: " << i.maxTransmissionUnit();
int count = 0;
foreach (const QNetworkAddressEntry &e, i.addressEntries()) {