Detect MTU on macOS and FreeBSD to adaptively reduce discovery packet

Detect the MTU on macOS and FreeBSD (which share the network parts of FreeBSD) and adaptively remove the outgoing and incoming capabilities.
The incoming capabilities are usually shorter, fit the size and help initialize the plugin list on the peer. This should fix an empty plugin list when the identity packet is sent by the macOS app.

If the MTU is still too short, both the capabilities need to be removed, which is not likely to happen.
This commit is contained in:
Weixuan Xiao 2022-07-11 20:51:18 +00:00 committed by Philip Cohn-Cort
parent 87b41a96a9
commit fd8b8078de

View file

@ -144,10 +144,33 @@ void LanLinkProvider::broadcastToNetwork()
NetworkPacket np;
NetworkPacket::createIdentityPacket(&np);
np.set(QStringLiteral("tcpPort"), m_tcpPort);
#ifdef Q_OS_MAC
//On macOS, remove capacitilities to avoid incomplete transmission of too large UDP packet
np.set(QStringLiteral("incomingCapabilities"), QStringList());
np.set(QStringLiteral("outgoingCapabilities"), QStringList());
#if defined(Q_OS_MAC) || defined(Q_OS_FREEBSD)
//On macOS and FreeBSD, the too large UDP packet (larger than MTU) causes
//incomplete transmission.
//We remove the capacitilities to reduce the discovery packet to the min
//MTU of the interfaces with broadcast feature.
int mtu = 1500;
for (const QNetworkInterface& iface : QNetworkInterface::allInterfaces()) {
if ((iface.flags() & QNetworkInterface::IsUp)
&& (iface.flags() & QNetworkInterface::IsRunning)
&& (iface.flags() & QNetworkInterface::CanBroadcast)) {
int ifaceMtu = iface.maximumTransmissionUnit();
if (ifaceMtu < mtu && ifaceMtu > 0) {
mtu = ifaceMtu;
}
}
}
QByteArray payload = np.serialize();
if (payload.length() > mtu) {
//First try to drop the less important outgoing capabilities
np.set(QStringLiteral("outgoingCapabilities"), QStringList());
payload = np.serialize();
}
if (payload.length() > mtu) {
//If still too large, drop the incoming capabilities
np.set(QStringLiteral("incomingCapabilities"), QStringList());
payload = np.serialize();
}
#endif
#ifdef Q_OS_WIN