mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
SERVER-69175 transport::SocketOption class template
This commit is contained in:
parent
79d393bff2
commit
a52ef30f9b
@ -51,6 +51,73 @@
|
||||
|
||||
namespace mongo::transport {
|
||||
|
||||
/**
|
||||
* Generic wrapper for making an ASIO socket get_option or set_option call
|
||||
* having a payload of type `T`, which is usually just `int` so it's the default.
|
||||
* Can be value-initializd with a `T`. A reference to the payload is available
|
||||
* using the dereferencing operators.
|
||||
*
|
||||
* Models Asio GettableSocketOption and SettableSocketOption.
|
||||
* https://www.boost.org/doc/libs/1_80_0/doc/html/boost_asio/reference/GettableSocketOption.html
|
||||
* https://www.boost.org/doc/libs/1_80_0/doc/html/boost_asio/reference/SettableSocketOption.html
|
||||
*
|
||||
* The Asio-required accessors must accept a `Protocol` argument, which we ignore.
|
||||
* The kinds of options we use don't need it.
|
||||
* https://www.boost.org/doc/libs/1_80_0/doc/html/boost_asio/reference/Protocol.html
|
||||
*
|
||||
* Example:
|
||||
* using TcpInfoOption = SocketOption<IPPROTO_TCP, TCP_INFO, tcp_info>;
|
||||
* ...
|
||||
* TcpInfoOption tcpiOption;
|
||||
* socket.get_option(tcpiOption);
|
||||
* tcp_info& infoOut = *tcpiOption;
|
||||
*/
|
||||
template <int optLevel, int optName, typename T = int>
|
||||
class SocketOption {
|
||||
public:
|
||||
SocketOption() = default;
|
||||
explicit SocketOption(T d) : _data{std::move(d)} {}
|
||||
template <typename Protocol>
|
||||
int level(const Protocol&) const {
|
||||
return optLevel;
|
||||
}
|
||||
template <typename Protocol>
|
||||
int name(const Protocol&) const {
|
||||
return optName;
|
||||
}
|
||||
template <typename Protocol>
|
||||
T* data(const Protocol&) {
|
||||
return &**this;
|
||||
}
|
||||
template <typename Protocol>
|
||||
const T* data(const Protocol&) const {
|
||||
return &**this;
|
||||
}
|
||||
template <typename Protocol>
|
||||
size_t size(const Protocol&) const {
|
||||
return sizeof(_data);
|
||||
}
|
||||
template <typename Protocol>
|
||||
void resize(const Protocol&, size_t) const {}
|
||||
|
||||
T& operator*() {
|
||||
return _data;
|
||||
}
|
||||
const T& operator*() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
T* operator->() {
|
||||
return &**this;
|
||||
}
|
||||
const T* operator->() const {
|
||||
return &**this;
|
||||
}
|
||||
|
||||
private:
|
||||
T _data{};
|
||||
};
|
||||
|
||||
inline SockAddr endpointToSockAddr(const asio::generic::stream_protocol::endpoint& endPoint) {
|
||||
SockAddr wrappedAddr(endPoint.data(), endPoint.size());
|
||||
return wrappedAddr;
|
||||
|
@ -35,6 +35,10 @@
|
||||
#include <fmt/format.h>
|
||||
#include <fstream>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
|
||||
#include <asio.hpp>
|
||||
#include <asio/system_timer.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
@ -81,8 +85,18 @@ namespace mongo {
|
||||
namespace transport {
|
||||
|
||||
namespace {
|
||||
|
||||
using TcpKeepaliveOption = SocketOption<SOL_SOCKET, SO_KEEPALIVE>;
|
||||
#ifdef __linux__
|
||||
using TcpInfoOption = SocketOption<IPPROTO_TCP, TCP_INFO, tcp_info>;
|
||||
using TcpKeepaliveCountOption = SocketOption<IPPROTO_TCP, TCP_KEEPCNT>;
|
||||
using TcpKeepaliveIdleSecsOption = SocketOption<IPPROTO_TCP, TCP_KEEPIDLE>;
|
||||
using TcpKeepaliveIntervalSecsOption = SocketOption<IPPROTO_TCP, TCP_KEEPINTVL>;
|
||||
using TcpUserTimeoutMillisOption = SocketOption<IPPROTO_TCP, TCP_USER_TIMEOUT, unsigned>;
|
||||
#endif // __linux__
|
||||
|
||||
#ifdef TCP_FASTOPEN
|
||||
using TCPFastOpen = asio::detail::socket_option::integer<IPPROTO_TCP, TCP_FASTOPEN>;
|
||||
using TcpFastOpenOption = SocketOption<IPPROTO_TCP, TCP_FASTOPEN>;
|
||||
#endif
|
||||
/**
|
||||
* On systems with TCP_FASTOPEN_CONNECT (linux >= 4.11),
|
||||
@ -92,7 +106,7 @@ using TCPFastOpen = asio::detail::socket_option::integer<IPPROTO_TCP, TCP_FASTOP
|
||||
* https://github.com/torvalds/linux/commit/19f6d3f3c8422d65b5e3d2162e30ef07c6e21ea2
|
||||
*/
|
||||
#ifdef TCP_FASTOPEN_CONNECT
|
||||
using TCPFastOpenConnect = asio::detail::socket_option::boolean<IPPROTO_TCP, TCP_FASTOPEN_CONNECT>;
|
||||
using TcpFastOpenConnectOption = SocketOption<IPPROTO_TCP, TCP_FASTOPEN_CONNECT>;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -682,7 +696,7 @@ StatusWith<TransportLayerASIO::ASIOSessionHandle> TransportLayerASIO::_doSyncCon
|
||||
const auto family = protocol.family();
|
||||
if ((family == AF_INET) || (family == AF_INET6)) {
|
||||
setSocketOption(sock,
|
||||
TCPFastOpenConnect(gTCPFastOpenClient),
|
||||
TcpFastOpenConnectOption(gTCPFastOpenClient),
|
||||
"connect (sync) TCP fast open",
|
||||
logv2::LogSeverity::Info(),
|
||||
ec);
|
||||
@ -868,7 +882,7 @@ Future<SessionHandle> TransportLayerASIO::asyncConnect(
|
||||
#ifdef TCP_FASTOPEN_CONNECT
|
||||
std::error_code ec;
|
||||
setSocketOption(connector->socket,
|
||||
TCPFastOpenConnect(gTCPFastOpenClient),
|
||||
TcpFastOpenConnectOption(gTCPFastOpenClient),
|
||||
"connect (async) TCP fast open",
|
||||
logv2::LogSeverity::Info(),
|
||||
ec);
|
||||
@ -1208,7 +1222,7 @@ Status TransportLayerASIO::setup() {
|
||||
#ifdef TCP_FASTOPEN
|
||||
if (gTCPFastOpenServer && ((addr.family() == AF_INET) || (addr.family() == AF_INET6))) {
|
||||
setSocketOption(acceptor,
|
||||
TCPFastOpen(gTCPFastOpenQueueSize),
|
||||
TcpFastOpenOption(gTCPFastOpenQueueSize),
|
||||
"acceptor TCP fast open",
|
||||
logv2::LogSeverity::Info(),
|
||||
ec);
|
||||
@ -1433,11 +1447,12 @@ void TransportLayerASIO::_acceptConnection(GenericAcceptor& acceptor) {
|
||||
}
|
||||
|
||||
#ifdef TCPI_OPT_SYN_DATA
|
||||
struct tcp_info info;
|
||||
socklen_t info_len = sizeof(info);
|
||||
if (!getsockopt(peerSocket.native_handle(), IPPROTO_TCP, TCP_INFO, &info, &info_len) &&
|
||||
(info.tcpi_options & TCPI_OPT_SYN_DATA)) {
|
||||
networkCounter.acceptedTFOIngress();
|
||||
try {
|
||||
TcpInfoOption tcpi{};
|
||||
peerSocket.get_option(tcpi);
|
||||
if (tcpi->tcpi_options & TCPI_OPT_SYN_DATA)
|
||||
networkCounter.acceptedTFOIngress();
|
||||
} catch (const asio::system_error&) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user