aboutsummaryrefslogtreecommitdiffstats
path: root/erts/preloaded/src
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-07-19 16:39:13 +0200
committerMicael Karlberg <[email protected]>2018-09-18 14:50:18 +0200
commit7a5b320b5bb5ec45b21839005e8538172908fb57 (patch)
treea901cc18fb10ed7fe6352a0205456f89f378c29a /erts/preloaded/src
parentf0a2e68a31ac585780ad05f777f1b7551770420e (diff)
downloadotp-7a5b320b5bb5ec45b21839005e8538172908fb57.tar.gz
otp-7a5b320b5bb5ec45b21839005e8538172908fb57.tar.bz2
otp-7a5b320b5bb5ec45b21839005e8538172908fb57.zip
[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
Diffstat (limited to 'erts/preloaded/src')
-rw-r--r--erts/preloaded/src/socket.erl31
1 files changed, 27 insertions, 4 deletions
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) ->