File 7991-Inherit-appropriate-options-in-gen_sctp-peeloff-2-li.patch of Package erlang
From 57a8e4fac64f56d684ef9e318986aeb33eb48480 Mon Sep 17 00:00:00 2001
From: Raimo Niskanen <raimo@erlang.org>
Date: Wed, 11 Sep 2024 18:15:10 +0200
Subject: [PATCH 1/2] Inherit appropriate options in `gen_sctp:peeloff/2`, like
in `gen_tcp:accept/1,2`
---
lib/kernel/src/inet6_sctp.erl | 21 +++++++++++++++++++--
lib/kernel/src/inet_sctp.erl | 20 ++++++++++++++++++--
lib/kernel/test/gen_sctp_SUITE.erl | 9 +++++++++
3 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/lib/kernel/src/inet6_sctp.erl b/lib/kernel/src/inet6_sctp.erl
index b55bfc0298..ef75ec193a 100644
--- a/lib/kernel/src/inet6_sctp.erl
+++ b/lib/kernel/src/inet6_sctp.erl
@@ -70,12 +70,29 @@ listen(S, Flag) ->
peeloff(S, AssocId) ->
case prim_inet:peeloff(S, AssocId) of
- {ok, NewS}=Result ->
+ {ok, NewS} ->
inet_db:register_socket(NewS, ?MODULE),
- Result;
+ peeloff_opts(S, NewS);
Error -> Error
end.
+peeloff_opts(S, NewS) ->
+ InheritOpts =
+ [active, sctp_nodelay, priority, linger, reuseaddr,
+ tclass, recvtclass],
+ case prim_inet:getopts(S, InheritOpts) of
+ {ok, Opts} ->
+ case prim_inet:setopts(S, Opts) of
+ ok ->
+ {ok, NewS};
+ Error1 ->
+ close(NewS), Error1
+ end;
+ Error2 ->
+ close(NewS), Error2
+ end.
+
+
connect(S, SockAddr, Opts, Timer) ->
inet_sctp:connect(S, SockAddr, Opts, Timer).
diff --git a/lib/kernel/src/inet_sctp.erl b/lib/kernel/src/inet_sctp.erl
index d5251d9ec6..2acaf213ab 100644
--- a/lib/kernel/src/inet_sctp.erl
+++ b/lib/kernel/src/inet_sctp.erl
@@ -69,12 +69,28 @@ listen(S, Flag) ->
peeloff(S, AssocId) ->
case prim_inet:peeloff(S, AssocId) of
- {ok, NewS}=Result ->
+ {ok, NewS} ->
inet_db:register_socket(NewS, ?MODULE),
- Result;
+ peeloff_opts(S, NewS);
Error -> Error
end.
+peeloff_opts(S, NewS) ->
+ InheritOpts =
+ [active, sctp_nodelay, priority, linger, reuseaddr,
+ tos, ttl, recvtos, recvttl],
+ case prim_inet:getopts(S, InheritOpts) of
+ {ok, Opts} ->
+ case prim_inet:setopts(NewS, Opts) of
+ ok ->
+ {ok, NewS};
+ Error1 ->
+ close(NewS), Error1
+ end;
+ Error2 ->
+ close(NewS), Error2
+ end.
+
%% A non-blocking connect is implemented when the initial call is to
%% gen_sctp:connect_init which passes the value nowait as the Timer
diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl
index 1b55e9a407..5f8b997b74 100644
--- a/lib/kernel/test/gen_sctp_SUITE.erl
+++ b/lib/kernel/test/gen_sctp_SUITE.erl
@@ -1506,6 +1506,11 @@ peeloff(Config, SockOpts) when is_list(Config) ->
Addr = {127,0,0,1},
Stream = 0,
Timeout = 333,
+ InheritOpts = [{priority, 3}, {sctp_nodelay, true}, {linger, {true, 7}}],
+ %% Verify the last inherit option to make sure no earlier
+ %% option does a silent bailout
+ SurelyInheritedOpt = lists:last(InheritOpts),
+ InheritOptnames = [Opt || {Opt,_} <- InheritOpts],
StartTime = timestamp(),
S1 = socket_open([{ifaddr,Addr}|SockOpts], Timeout),
?LOGVAR(S1),
@@ -1526,12 +1531,16 @@ peeloff(Config, SockOpts) when is_list(Config) ->
after Timeout ->
socket_bailout([S1,S2], StartTime)
end,
+ socket_call(S1, {setopts, InheritOpts}),
+ InheritedOpts = socket_call(S1, {getopts, InheritOptnames}),
+ SurelyInheritedOpt = lists:last(InheritedOpts),
%%
S3 = socket_peeloff(Socket1, S1Ai, SockOpts, Timeout),
?LOGVAR(S3),
P3_X = socket_call(S3, get_port),
?LOGVAR(P3_X),
P3 = case P3_X of 0 -> P1; _ -> P3_X end,
+ InheritedOpts = socket_call(S3, {getopts, InheritOptnames}),
[{_,#sctp_paddrinfo{assoc_id=S3Ai,state=active}}] =
socket_call(S3,
{getopts,[{sctp_get_peer_addr_info,
--
2.43.0