summaryrefslogtreecommitdiffstats
path: root/src/network/socket/qnativesocketengine_unix.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2017-08-20 15:50:41 -0700
committerThiago Macieira <thiago.macieira@intel.com>2017-11-14 15:54:51 +0000
commitaaa187cd9951b71127c11c375e6a3954a187e1d3 (patch)
tree54dcee410994b3d64058ed6dde9e95c519fee83a /src/network/socket/qnativesocketengine_unix.cpp
parentaa494d826ace02ffff5f29ae20b7738630913777 (diff)
QAbstractSocket: Add socketOption for the Path MTU
This allow retrieving the value of the known PMTU for the current socket. This works on Linux (IPv6 and IPv4) and FreeBSD (IPv6 only) -- the other OSes don't have the necessary API. Note: do we need add IP_MTU_DISCOVER? Change-Id: I6e9274c1e7444ad48c81fffd14dcaf97a18ce335 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/network/socket/qnativesocketengine_unix.cpp')
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index cb0a521360..b380b0f7d6 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -226,6 +226,20 @@ static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt,
#endif
}
break;
+
+ case QNativeSocketEngine::PathMtuInformation:
+ if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
+#ifdef IPV6_MTU
+ level = IPPROTO_IPV6;
+ n = IPV6_MTU;
+#endif
+ } else {
+#ifdef IP_MTU
+ level = IPPROTO_IP;
+ n = IP_MTU;
+#endif
+ }
+ break;
}
}
@@ -331,6 +345,20 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co
return -1;
}
+ case QNativeSocketEngine::PathMtuInformation:
+#if defined(IPV6_PATHMTU) && !defined(IPV6_MTU)
+ // Prefer IPV6_MTU (handled by convertToLevelAndOption), if available
+ // (Linux); fall back to IPV6_PATHMTU otherwise (FreeBSD):
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ ip6_mtuinfo mtuinfo;
+ QT_SOCKOPTLEN_T len = sizeof(mtuinfo);
+ if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_PATHMTU, &mtuinfo, &len) == 0)
+ return int(mtuinfo.ip6m_mtu);
+ return -1;
+ }
+#endif
+ break;
+
default:
break;
}
@@ -420,6 +448,8 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
}
#endif
+ if (n == -1)
+ return false;
return ::setsockopt(socketDescriptor, level, n, (char *) &v, sizeof(v)) == 0;
}