Skip to content

Commit

Permalink
Merge branch 'maint'
Browse files Browse the repository at this point in the history
* maint:
  Bugfix: skip the value when skipping the option
  Inherit appropriate options in `gen_sctp:peeloff/2`, like in `gen_tcp:accept/1,2`
  • Loading branch information
RaimoNiskanen committed Oct 1, 2024
2 parents 6e1b3d8 + dbeadc8 commit f45e69d
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 8 deletions.
17 changes: 13 additions & 4 deletions erts/emulator/drivers/common/inet_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -8154,6 +8154,7 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)
arg_sz = sizeof ( arg.ival);
break;
#else
curr += 4;
continue;
#endif

Expand All @@ -8164,6 +8165,7 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)
"sctp_set_opts -> REUSEPORT_LB\r\n",
__LINE__, desc->s, driver_caller(desc->port)) );
#if defined(__WIN32__)
curr += 4;
continue;
#elif defined(SO_REUSEPORT_LB) || (defined(__linux__) && defined(SO_REUSEPORT))
arg.ival= get_int32 (curr); curr += 4;
Expand All @@ -8178,6 +8180,7 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)
arg_sz = sizeof ( arg.ival);
break;
#else
curr += 4;
continue;
#endif
}
Expand All @@ -8198,6 +8201,7 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)
arg_sz = sizeof ( arg.ival);
break;
#else
curr += 4;
continue;
#endif
}
Expand Down Expand Up @@ -8229,8 +8233,10 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)
}
new_ra = (compat & ra_bits) == ra_bits;
desc->bsd_compat = compat;
if (old_ra == new_ra)
if (old_ra == new_ra) {
curr += 4;
continue;
}
}
#endif
arg.ival= get_int32 (curr); curr += 4;
Expand Down Expand Up @@ -8277,7 +8283,8 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)
# else
/* inet_fill_opts always returns a value for this option,
* so we need to ignore it if not implemented, just in case */
continue;
curr += 4;
continue;
# endif

case INET_OPT_TOS:
Expand All @@ -8299,7 +8306,8 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)
# else
/* inet_fill_opts always returns a value for this option,
* so we need to ignore it if not implemented, just in case */
continue;
curr += 4;
continue;
# endif

# if defined(IPV6_TCLASS) && defined(IPPROTO_IPV6)
Expand Down Expand Up @@ -8430,7 +8438,8 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)
# elif defined(__WIN32__) && defined(HAVE_IN6) && defined(AF_INET6)
# error Here is a fix for Win IPv6 SCTP missing
# else
continue; /* Option not supported -- ignore it */
curr += 4;
continue; /* Option not supported -- ignore it */
# endif

#ifdef SO_BINDTODEVICE
Expand Down
21 changes: 19 additions & 2 deletions lib/kernel/src/inet6_sctp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand Down
20 changes: 18 additions & 2 deletions lib/kernel/src/inet_sctp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions lib/kernel/test/gen_sctp_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1513,6 +1513,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,P1,S1Ai}, {S2,P2,S2Ai}} =
socket_pair_open(Addr, StartTime, Timeout),
Expand All @@ -1533,12 +1538,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,
Expand Down

0 comments on commit f45e69d

Please sign in to comment.