From 7a5b320b5bb5ec45b21839005e8538172908fb57 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Thu, 19 Jul 2018 16:39:13 +0200 Subject: [socket-nif] Add (partial) support for socket (level sctp) option associnfo Added support for the SCTP option ASSOCINFO. This option is a bit tricky. As the underlying structure (sctp_assocparams) contains the assoc_id, it begs the question what happens if this option is fetched for: * The own assoc (which means that we might have the assoc id in the descriptor and can initiate that part of the struct accordningly). * Another assoc: From assoc A asks for info with assoc_id set to that of assoc B. * The "owning" endpoint. * Another endpoint (an endpoint to which the assoc does not belong). So, if the user calls socket:[getopt|setopt] for an association socket, shall we require that the assoc_id field is set to -1? Or not set at all and therefor filled in automatically by the nif-code? And, if the user calls socket:[getopt|setopt] for an endpoint socket, shall we require that the assoc_id field is set to a valid id? Or shall it not be allowed? Questions, questions... OTP-14831 --- erts/preloaded/ebin/socket.beam | Bin 52640 -> 53256 bytes erts/preloaded/src/socket.erl | 31 +++++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) (limited to 'erts/preloaded') diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam index 63887692f9..0c496443bf 100644 Binary files a/erts/preloaded/ebin/socket.beam and b/erts/preloaded/ebin/socket.beam differ diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl index e3fb417a35..feb2e25312 100644 --- a/erts/preloaded/src/socket.erl +++ b/erts/preloaded/src/socket.erl @@ -95,6 +95,7 @@ ipv6_mreq/0, ipv6_pmtudisc/0, sctp_event_subscribe/0, + sctp_assocparams/0, msg_hdr/0 @@ -187,6 +188,13 @@ authentication := boolean(), sender_dry := boolean()}. +-type sctp_assocparams() :: #{assoc_id := integer(), + max_rxt := non_neg_integer(), + num_peer_dests := non_neg_integer(), + peer_rwnd := non_neg_integer(), + local_rwnd := non_neg_integer(), + cookie_life := non_neg_integer()}. + -type sockaddr_un() :: #{family := local, path := binary() | string()}. -type sockaddr_in4() :: #{family := inet, @@ -637,7 +645,7 @@ -define(SOCKET_OPT_UDP_CORK, 1). %% -define(SOCKET_OPT_SCTP_ADAPTION_LAYER, 1). -%% -define(SOCKET_OPT_SCTP_ASSOCINFO, 2). +-define(SOCKET_OPT_SCTP_ASSOCINFO, 2). %% -define(SOCKET_OPT_SCTP_AUTH_ACTIVE_KEY, 3). %% -define(SOCKET_OPT_SCTP_AUTH_ASCONF, 4). %% -define(SOCKET_OPT_SCTP_AUTH_CHUNK, 5). @@ -2172,8 +2180,23 @@ enc_setopt_value(udp, cork, V, _D, T, P) enc_setopt_value(udp = L, Opt, _V, _D, _T, _P) -> not_supported({L, Opt}); +enc_setopt_value(sctp, associnfo, #{assoc_id := AssocId, + asocmaxrxt := MaxRxt, + num_peer_dests := NumPeerDests, + peer_rwnd := PeerRWND, + local_rwnd := LocalRWND, + cookie_life := CLife} = V, + _D, _T, P) + when is_integer(AssocId) andalso + is_integer(MaxRxt) andalso (MaxRxt >= 0) andalso + is_integer(NumPeerDests) andalso (NumPeerDests >= 0) andalso + is_integer(PeerRWND) andalso (PeerRWND >= 0) andalso + is_integer(LocalRWND) andalso (LocalRWND >= 0) andalso + is_integer(CLife) andalso (CLife >= 0) andalso + (P =:= sctp) -> + V; enc_setopt_value(sctp, autoclose, V, _D, _T, P) - when is_integer(V) andalso (P =:= sctp) -> + when is_integer(V) andalso (V >= 0) andalso (P =:= sctp) -> V; enc_setopt_value(sctp, disable_fragments, V, _D, _T, P) when is_boolean(V) andalso (P =:= sctp) -> @@ -2595,8 +2618,8 @@ enc_sockopt_key(udp = L, UnknownOpt, _Dir, _D, _T, _P) -> %% SCTP socket options enc_sockopt_key(sctp = L, adaption_layer = Opt, _Dir, _D, _T, _P) -> not_supported({L, Opt}); -enc_sockopt_key(sctp = L, associnfo = Opt, _Dir, _D, _T, _P) -> - not_supported({L, Opt}); +enc_sockopt_key(sctp = _L, associnfo = _Opt, _Dir, _D, _T, _P) -> + ?SOCKET_OPT_SCTP_ASSOCINFO; enc_sockopt_key(sctp = L, auth_active_key = Opt, _Dir, _D, _T, _P) -> not_supported({L, Opt}); enc_sockopt_key(sctp = L, auth_asconf = Opt, _Dir, _D, _T, _P) -> -- cgit v1.2.3