diff options
author | Micael Karlberg <[email protected]> | 2018-07-19 18:22:05 +0200 |
---|---|---|
committer | Micael Karlberg <[email protected]> | 2018-09-18 14:50:18 +0200 |
commit | 8b96072a94d590ad545fa888911e5d613b32281e (patch) | |
tree | 07fb1801315128ab4dcfe5ec37a66f9dcd15e7ac /erts/preloaded/src | |
parent | 08ce39bbc2cd3006475c87807042c2d08a68736f (diff) | |
download | otp-8b96072a94d590ad545fa888911e5d613b32281e.tar.gz otp-8b96072a94d590ad545fa888911e5d613b32281e.tar.bz2 otp-8b96072a94d590ad545fa888911e5d613b32281e.zip |
[socket-nif] Add preliminary bind/3 for sctp
Added a preliminary bind/3 that shall map to sctp_bindx.
We need similar functions for sctp_connectx, and maybe a bunch
of other specific sctp function(s).
Diffstat (limited to 'erts/preloaded/src')
-rw-r--r-- | erts/preloaded/src/socket.erl | 73 |
1 files changed, 70 insertions, 3 deletions
diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl index 1c24c75dac..cadbf1131c 100644 --- a/erts/preloaded/src/socket.erl +++ b/erts/preloaded/src/socket.erl @@ -31,7 +31,7 @@ -export([ open/2, open/3, open/4, - bind/2, + bind/2, bind/3, connect/2, connect/3, listen/1, listen/2, accept/1, accept/2, @@ -901,6 +901,70 @@ bind(#socket{ref = SockRef} = _Socket, Addr) when is_map(Addr) -> %% =========================================================================== %% +%% bind - Add or remove a bind addresses on a socket +%% +%% Calling this function is only valid if the socket is: +%% type = seqpacket +%% protocol = sctp +%% +%% If the domain is inet, then all addresses *must* be IPv4. +%% If the domain is inet6, the addresses can be aither IPv4 or IPv6. +%% + +-spec bind(Socket, Addrs, Action) -> ok | {error, Reason} when + Socket :: socket(), + Addrs :: [sockaddr()], + Action :: add | remove, + Reason :: term(). + +bind(#socket{ref = SockRef, + info = #{domain := Domain, + type := seqpacket, + protocol := sctp}} = _Socket, Addrs, Action) + when is_list(Addrs) andalso ((Action =:= add) orelse (Action =:= remove)) -> + try + begin + validate_addrs(Domain, Addrs), + nif_bind(SockRef, Addrs, Action) + end + catch + throw:ERROR -> + ERROR + end. + + +validate_addrs(inet = _Domain, Addrs) -> + validate_inet_addrs(Addrs); +validate_addrs(inet6 = _Domain, Addrs) -> + validate_inet6_addrs(Addrs). + +validate_inet_addrs(Addrs) -> + Validator = fun(#{family := inet, + addrs := Addr}) when is_tuple(Addr) andalso + (size(Addr) =:= 4) -> + ok; + (X) -> + throw({error, {invalid_address, X}}) + end, + lists:foreach(Validator, Addrs). + +validate_inet6_addrs(Addrs) -> + Validator = fun(#{family := inet, + addrs := Addr}) when is_tuple(Addr) andalso + (size(Addr) =:= 4) -> + ok; + (#{family := inet6, + addrs := Addr}) when is_tuple(Addr) andalso + (size(Addr) =:= 8) -> + ok; + (X) -> + throw({error, {invalid_address, X}}) + end, + lists:foreach(Validator, Addrs). + + +%% =========================================================================== +%% %% connect - initiate a connection on a socket %% @@ -2699,8 +2763,8 @@ enc_sockopt_key(sctp = _L, rtoinfo = _Opt, _Dir, _D, _T, _P) -> ?SOCKET_OPT_SCTP_RTOINFO; enc_sockopt_key(sctp = L, set_peer_primary_addr = Opt, _Dir, _D, _T, _P) -> not_supported({L, Opt}); -enc_sockopt_key(sctp = L, status = Opt, _Dir, _D, _T, _P) -> - not_supported({L, Opt}); +enc_sockopt_key(sctp = L, status = Opt, get = _Dir, _D, _T, _P) -> + not_supported({L, Opt}); % ?SOCKET_OPT_SCTP_RTOINFO; enc_sockopt_key(sctp = L, use_exp_recvinfo = Opt, _Dir, _D, _T, _P) -> not_supported({L, Opt}); enc_sockopt_key(sctp = L, UnknownOpt, _Dir, _D, _T, _P) -> @@ -2869,6 +2933,9 @@ nif_open(_Domain, _Type, _Protocol, _Extra) -> nif_bind(_SRef, _SockAddr) -> erlang:error(badarg). +nif_bind(_SRef, _SockAddrs, _Action) -> + erlang:error(badarg). + nif_connect(_SRef, _SockAddr) -> erlang:error(badarg). |