diff options
author | Micael Karlberg <[email protected]> | 2018-05-17 14:22:52 +0200 |
---|---|---|
committer | Micael Karlberg <[email protected]> | 2018-09-18 13:01:37 +0200 |
commit | 24bcbd2040fad723648e25af87cd848da8aa27bc (patch) | |
tree | 8211fdd0a0cb2c829a059ccbad763ffb3b070686 /erts/preloaded/src/socket.erl | |
parent | bbf415b274224e273a89a706ca5b0250a1523302 (diff) | |
download | otp-24bcbd2040fad723648e25af87cd848da8aa27bc.tar.gz otp-24bcbd2040fad723648e25af87cd848da8aa27bc.tar.bz2 otp-24bcbd2040fad723648e25af87cd848da8aa27bc.zip |
[socket-nif] getopt partially implemented
There are still many options not implemented (just as
for setopt), but this will have to do for now...
Diffstat (limited to 'erts/preloaded/src/socket.erl')
-rw-r--r-- | erts/preloaded/src/socket.erl | 71 |
1 files changed, 54 insertions, 17 deletions
diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl index 7b53f271ef..f8aa75bf8f 100644 --- a/erts/preloaded/src/socket.erl +++ b/erts/preloaded/src/socket.erl @@ -272,6 +272,7 @@ v6only. -type tcp_socket_option() :: congestion | + cork | maxseg | nodelay. @@ -451,10 +452,11 @@ -define(SOCKET_OPT_IPV6_HOPLIMIT, 12). -define(SOCKET_OPT_TCP_CONGESTION, 0). --define(SOCKET_OPT_TCP_MAXSEG, 1). --define(SOCKET_OPT_TCP_NODELAY, 2). +-define(SOCKET_OPT_TCP_CORK, 2). +-define(SOCKET_OPT_TCP_MAXSEG, 3). +-define(SOCKET_OPT_TCP_NODELAY, 4). --define(SOCKET_OPT_UDP_CORK, 1). +-define(SOCKET_OPT_UDP_CORK, 0). -define(SOCKET_OPT_SCTP_AUTOCLOSE, 7). -define(SOCKET_OPT_SCTP_NODELAY, 22). @@ -1370,6 +1372,10 @@ setopt(#socket{info = Info, ref = SockRef}, Level, Key, Value) -> %% If its an "invalid" option, we should not crash but return some %% useful error... %% +%% When specifying level as an integer, and therefor using "native mode", +%% we should make it possible to specify common types instead of the +%% value size. Example: int | bool | {string, pos_integer()} | non_neg_integer() +%% -spec getopt(Socket, Level, Key) -> {ok, Value} | {error, Reason} when Socket :: socket(), @@ -1412,7 +1418,15 @@ setopt(#socket{info = Info, ref = SockRef}, Level, Key, Value) -> Level :: sctp, Key :: sctp_socket_option(), Value :: term(), - Reason :: term(). + Reason :: term() + ; (Socket, Level, Key) -> ok | {ok, Value} | {error, Reason} when + Socket :: socket(), + Level :: integer(), + Key :: {NativeOpt, ValueSize}, + NativeOpt :: integer(), + ValueSize :: non_neg_integer(), + Value :: term(), + Reason :: term(). getopt(#socket{info = Info, ref = SockRef}, Level, Key) -> try @@ -1425,6 +1439,8 @@ getopt(#socket{info = Info, ref = SockRef}, Level, Key) -> %% We may need to decode the value (for the same reason %% we needed to encode the value for setopt). case nif_getopt(SockRef, EIsEncoded, ELevel, EKey) of + ok -> + ok; {ok, EVal} -> Val = dec_getopt_value(Level, Key, EVal, Domain, Type, Protocol), @@ -1716,10 +1732,14 @@ enc_getopt_key(Level, Opt, Domain, Type, Protocol) -> %% +++ Decode getopt value +++ +%% +%% For the most part, we simply let the value pass through, but for some +%% values we do an actual decode. +%% -%% We should ...really... do something with the domain, type and protocol args... -dec_getopt_value(otp, debug, B, _, _, _) when is_boolean(B) -> - B. +%% Let the user deal with this... +dec_getopt_value(_L, _Opt, V, _D, _T, _P) -> + V. @@ -1731,64 +1751,74 @@ dec_getopt_value(otp, debug, B, _, _, _) when is_boolean(B) -> Direction, Domain, Type, Protocol) -> non_neg_integer() when Level :: otp, - Opt :: otp_socket_option(), Direction :: set | get, + Opt :: otp_socket_option(), Domain :: domain(), Type :: type(), Protocol :: protocol() ; (Level, Direction, Opt, Domain, Type, Protocol) -> non_neg_integer() when Level :: socket, - Opt :: socket_option(), Direction :: set | get, + Opt :: socket_option(), Domain :: domain(), Type :: type(), Protocol :: protocol() ; (Level, Direction, Opt, Domain, Type, Protocol) -> non_neg_integer() when Level :: ip, - Opt :: ip_socket_option(), Direction :: set | get, + Opt :: ip_socket_option(), Domain :: domain(), Type :: type(), Protocol :: protocol() ; (Level, Direction, Opt, Domain, Type, Protocol) -> non_neg_integer() when Level :: ipv6, - Opt :: ipv6_socket_option(), Direction :: set | get, + Opt :: ipv6_socket_option(), Domain :: domain(), Type :: type(), Protocol :: protocol() ; (Level, Direction, Opt, Domain, Type, Protocol) -> non_neg_integer() when Level :: tcp, - Opt :: tcp_socket_option(), Direction :: set | get, + Opt :: tcp_socket_option(), Domain :: domain(), Type :: type(), Protocol :: protocol() ; (Level, Direction, Opt, Domain, Type, Protocol) -> non_neg_integer() when Level :: udp, - Opt :: udp_socket_option(), Direction :: set | get, + Opt :: udp_socket_option(), Domain :: domain(), Type :: type(), Protocol :: protocol() ; (Level, Direction, Opt, Domain, Type, Protocol) -> non_neg_integer() when Level :: sctp, - Opt :: sctp_socket_option(), Direction :: set | get, + Opt :: sctp_socket_option(), Domain :: domain(), Type :: type(), Protocol :: protocol() ; (Level, Direction, Opt, Domain, Type, Protocol) -> non_neg_integer() when Level :: integer(), + Direction :: set, Opt :: integer(), - Direction :: set | get, + Domain :: domain(), + Type :: type(), + Protocol :: protocol() + ; (Level, Direction, Opt, + Domain, Type, Protocol) -> non_neg_integer() when + Level :: integer(), + Direction :: get, + Opt :: {NativeOpt, ValueSize}, + NativeOpt :: integer(), + ValueSize :: non_neg_integer(), Domain :: domain(), Type :: type(), Protocol :: protocol(). @@ -1960,6 +1990,8 @@ enc_sockopt_key(ipv6, UnknownOpt, _Dir, _D, _T, _P) -> %% but they are difficult to get portable... enc_sockopt_key(tcp, congestion = _Opt, _Dir, _D, _T, _P) -> ?SOCKET_OPT_TCP_CONGESTION; +enc_sockopt_key(tcp, cork = Opt, _Dir, _D, _T, _P) -> + not_supported(Opt); enc_sockopt_key(tcp, maxseg = _Opt, _Dir, _D, _T, _P) -> ?SOCKET_OPT_TCP_MAXSEG; enc_sockopt_key(tcp, nodelay = _Opt, _Dir, _D, _T, _P) -> @@ -1981,10 +2013,15 @@ enc_sockopt_key(sctp, nodelay = _Opt, _Dir, _D, _T, _P) -> enc_sockopt_key(sctp, UnknownOpt, _Dir, _D, _T, _P) -> unknown(UnknownOpt); -%% +++ Plain socket options +++ -enc_sockopt_key(Level, Opt, _Dir, _D, _T, _P) +%% +++ "Native" socket options +++ +enc_sockopt_key(Level, Opt, set = _Dir, _D, _T, _P) when is_integer(Level) andalso is_integer(Opt) -> Opt; +enc_sockopt_key(Level, {NativeOpt, ValueSize} = Opt, get = _Dir, _D, _T, _P) + when is_integer(Level) andalso + is_integer(NativeOpt) andalso + is_integer(ValueSize) andalso (ValueSize >= 0) -> + Opt; enc_sockopt_key(Level, Opt, _Dir, _Domain, _Type, _Protocol) -> unknown({Level, Opt}). |