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>
This commit is contained in:
Thiago Macieira 2017-08-10 00:22:56 -07:00
parent 18ec85a80c
commit 05012f4285
7 changed files with 51 additions and 1 deletions

View File

@ -688,6 +688,29 @@ int QNetworkInterface::index() const
return d ? d->index : 0;
}
/*!
\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

View File

@ -153,6 +153,7 @@ public:
bool isValid() const;
int index() const;
int maxTransmissionUnit() const;
QString name() const;
QString humanReadableName() const;
InterfaceFlags flags() const;

View File

@ -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

View File

@ -88,6 +88,7 @@ public:
{ }
int index; // interface index, if know
int mtu = 0;
QNetworkInterface::InterfaceFlags flags;
QNetworkInterface::InterfaceType type = QNetworkInterface::Unknown;

View File

@ -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)

View File

@ -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;

View File

@ -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()) {