From 121f9febc759a8ad2eb16ce04a59c8058a58e6c7 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Thu, 2 Mar 2023 17:56:27 -0800 Subject: [PATCH] ircd::net: Add TCP_CORK support to socket options interface. --- include/ircd/net/sock_opts.h | 3 +++ ircd/net.cc | 50 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/include/ircd/net/sock_opts.h b/include/ircd/net/sock_opts.h index 6b251ad8b..14eb72f1c 100644 --- a/include/ircd/net/sock_opts.h +++ b/include/ircd/net/sock_opts.h @@ -17,6 +17,7 @@ namespace ircd::net bool v6only(const socket &); bool blocking(const socket &); + bool nopush(const socket &); bool nodelay(const socket &); bool quickack(const socket &); bool keepalive(const socket &); @@ -30,6 +31,7 @@ namespace ircd::net // returns true if supported, false if unsupported; failures will throw. bool v6only(socket &, const bool &); bool blocking(socket &, const bool &); + bool nopush(socket &, const bool &); bool nodelay(socket &, const bool &); bool quickack(socket &, const bool &); bool keepalive(socket &, const bool &); @@ -57,6 +59,7 @@ struct ircd::net::sock_opts int8_t v6only { IGN }; int8_t blocking { IGN }; // Simulates blocking behavior + int8_t nopush { IGN }; int8_t nodelay { IGN }; int8_t quickack { IGN }; int8_t keepalive { IGN }; diff --git a/ircd/net.cc b/ircd/net.cc index ab53cc654..9b4e0172d 100644 --- a/ircd/net.cc +++ b/ircd/net.cc @@ -825,6 +825,7 @@ ircd::net::open(socket &socket, ircd::net::sock_opts::sock_opts(const socket &socket) :v6only{net::v6only(socket)} ,blocking{net::blocking(socket)} +,nopush{net::nopush(socket)} ,nodelay{net::nodelay(socket)} ,quickack{net::quickack(socket)} ,keepalive{net::keepalive(socket)} @@ -848,6 +849,9 @@ ircd::net::set(socket &socket, if(opts.blocking != opts.IGN) net::blocking(socket, opts.blocking); + if(opts.nopush != opts.IGN) + net::nopush(socket, opts.nopush); + if(opts.nodelay != opts.IGN) net::nodelay(socket, opts.nodelay); @@ -1056,6 +1060,29 @@ ircd::net::nodelay(socket &socket, return true; } +bool +ircd::net::nopush(socket &socket, + const bool &b) +#if defined(TCP_CORK) && defined(SOL_SOCKET) +{ + ip::tcp::socket &sd(socket); + const auto &fd + { + sd.lowest_layer().native_handle() + }; + + const int val(b); + const socklen_t len(sizeof(val)); + syscall(::setsockopt, fd, SOL_SOCKET, TCP_CORK, &val, len); + return true; +} +#else +{ + #warning "TCP_CORK is not defined on this platform." + return false; +} +#endif + /// Toggles the behavior of non-async asio calls. /// /// This option affects very little in practice and only sets a flag in @@ -1207,6 +1234,29 @@ ircd::net::nodelay(const socket &socket) return option.value(); } +bool +ircd::net::nopush(const socket &socket) +#if defined(TCP_CORK) && defined(SOL_SOCKET) +{ + const ip::tcp::socket &sd(socket); + const auto &fd + { + mutable_cast(sd).lowest_layer().native_handle() + }; + + uint32_t ret; + socklen_t len(sizeof(ret)); + syscall(::getsockopt, fd, SOL_SOCKET, TCP_CORK, &ret, &len); + assert(len <= sizeof(ret)); + return ret; +} +#else +{ + #warning "TCP_CORK is not defined on this platform." + return false; +} +#endif + bool ircd::net::blocking(const socket &socket) {