From 210665e8a252faecf28ccebade999e734ab92582 Mon Sep 17 00:00:00 2001 From: Igor Slepchin Date: Mon, 24 Sep 2018 22:44:03 -0400 Subject: Add nopush TCP socket option This translates to TCP_CORK on Linux and TCP_NOPUSH on BSD. In effect, this acts as super-Nagle: no partial TCP segments are sent out until this option is turned off. Once turned off, all accumulated unsent data is sent out immediately. The latter is *not* the case on OSX, hence the implementation ignores "nopush" on OSX to reduce confusion. --- lib/kernel/doc/src/inet.xml | 12 ++++++++++++ lib/kernel/src/inet_int.hrl | 1 + lib/kernel/test/inet_sockopt_SUITE.erl | 9 +++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index ed775d67eb..9fc361a234 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -1039,6 +1039,18 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp is turned on for the socket, which means that also small amounts of data are sent immediately.

+ {nopush, Boolean}(TCP/IP sockets) + +

This translates to TCP_NOPUSH on BSD and + to TCP_CORK on Linux.

+

If Boolean == true, the corresponding option + is turned on for the socket, which means that small + amounts of data are accumulated until a full MSS-worth + of data is available or this option is turned off.

+

Note that while TCP_NOPUSH socket option is available on OSX, its semantics + is very different (e.g., unsetting it does not cause immediate send + of accumulated data). Hence, nopush option is intentionally ignored on OSX.

+
{packet, PacketType}(TCP/IP sockets)

Defines the type of packets to use for a socket. diff --git a/lib/kernel/src/inet_int.hrl b/lib/kernel/src/inet_int.hrl index c8e09d18ad..f6525d7261 100644 --- a/lib/kernel/src/inet_int.hrl +++ b/lib/kernel/src/inet_int.hrl @@ -162,6 +162,7 @@ -define(INET_OPT_PKTOPTIONS, 45). -define(INET_OPT_TTL, 46). -define(INET_OPT_RECVTTL, 47). +-define(TCP_OPT_NOPUSH, 48). % Specific SCTP options: separate range: -define(SCTP_OPT_RTOINFO, 100). -define(SCTP_OPT_ASSOCINFO, 101). diff --git a/lib/kernel/test/inet_sockopt_SUITE.erl b/lib/kernel/test/inet_sockopt_SUITE.erl index ada9c2689c..27ff74e309 100644 --- a/lib/kernel/test/inet_sockopt_SUITE.erl +++ b/lib/kernel/test/inet_sockopt_SUITE.erl @@ -110,9 +110,14 @@ simple(Config) when is_list(Config) -> {S1,S2} = create_socketpair(Opt, Opt), {ok,Opt} = inet:getopts(S1,OptTags), {ok,Opt} = inet:getopts(S2,OptTags), - COpt = [{X,case X of nodelay -> false;_ -> Y end} || {X,Y} <- Opt], + NoPushOpt = case os:type() of + {unix, Osname} when Osname =:= linux; Osname =:= freebsd -> {nopush, true}; + {_,_} -> {nopush, false} + end, + COpt = [{X,case X of nodelay -> false;_ -> Y end} || {X,Y} <- [NoPushOpt|Opt]], + COptTags = [X || {X,_} <- COpt], inet:setopts(S1,COpt), - {ok,COpt} = inet:getopts(S1,OptTags), + {ok,COpt} = inet:getopts(S1,COptTags), {ok,Opt} = inet:getopts(S2,OptTags), gen_tcp:close(S1), gen_tcp:close(S2), -- cgit v1.2.3