diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2017-08-20 15:50:41 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2017-11-14 15:54:51 +0000 |
commit | aaa187cd9951b71127c11c375e6a3954a187e1d3 (patch) | |
tree | 54dcee410994b3d64058ed6dde9e95c519fee83a /src/network/socket/qnativesocketengine_unix.cpp | |
parent | aa494d826ace02ffff5f29ae20b7738630913777 (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.cpp | 30 |
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; } |