From 09276f8cbe1b62ea0c1c44c5d6eb605fd49dd80a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Mon, 24 Dec 2018 16:20:18 +0100 Subject: ssl: Add support for {active,N} --- lib/ssl/src/dtls_packet_demux.erl | 12 +++ lib/ssl/src/dtls_socket.erl | 49 ++++++++++- lib/ssl/src/ssl_connection.erl | 48 ++++++++++- lib/ssl/src/tls_socket.erl | 52 ++++++++++- lib/ssl/test/ssl_basic_SUITE.erl | 176 +++++++++++++++++++++++++++++++++++++- 5 files changed, 327 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/ssl/src/dtls_packet_demux.erl b/lib/ssl/src/dtls_packet_demux.erl index dccc22a448..4945ef3c10 100644 --- a/lib/ssl/src/dtls_packet_demux.erl +++ b/lib/ssl/src/dtls_packet_demux.erl @@ -297,6 +297,18 @@ do_set_emulated_opts([], Opts) -> Opts; do_set_emulated_opts([{mode, Value} | Rest], Opts) -> do_set_emulated_opts(Rest, Opts#socket_options{mode = Value}); +do_set_emulated_opts([{active, N0} | Rest], Opts=#socket_options{active = Active}) when is_integer(N0) -> + N = case Active of + N1 when is_integer(N1), N0 + N1 =< 0 -> + false; + N1 when is_integer(N1) -> + N0 + N1; + _ when N0 =< 0 -> + false; + _ -> + N0 + end, + do_set_emulated_opts(Rest, Opts#socket_options{active = N}); do_set_emulated_opts([{active, Value} | Rest], Opts) -> do_set_emulated_opts(Rest, Opts#socket_options{active = Value}). diff --git a/lib/ssl/src/dtls_socket.erl b/lib/ssl/src/dtls_socket.erl index 2001afd02f..4d07372e31 100644 --- a/lib/ssl/src/dtls_socket.erl +++ b/lib/ssl/src/dtls_socket.erl @@ -38,7 +38,9 @@ listen(Port, #config{transport_info = TransportInfo, case dtls_listener_sup:start_child([Port, TransportInfo, emulated_socket_options(EmOpts, #socket_options{}), Options ++ internal_inet_values(), SslOpts]) of {ok, Pid} -> - {ok, #sslsocket{pid = {dtls, Config#config{dtls_handler = {Pid, Port}}}}}; + Socket = #sslsocket{pid = {dtls, Config#config{dtls_handler = {Pid, Port}}}}, + check_active_n(EmOpts, Socket), + {ok, Socket}; Err = {error, _} -> Err end. @@ -81,8 +83,9 @@ socket(Pids, Transport, Socket, ConnectionCb) -> #sslsocket{pid = Pids, %% "The name "fd" is keept for backwards compatibility fd = {Transport, Socket, ConnectionCb}}. -setopts(_, #sslsocket{pid = {dtls, #config{dtls_handler = {ListenPid, _}}}}, Options) -> - SplitOpts = tls_socket:split_options(Options), +setopts(_, Socket = #sslsocket{pid = {dtls, #config{dtls_handler = {ListenPid, _}}}}, Options) -> + SplitOpts = {_, EmOpts} = tls_socket:split_options(Options), + check_active_n(EmOpts, Socket), dtls_packet_demux:set_sock_opts(ListenPid, SplitOpts); %%% Following clauses will not be called for emulated options, they are handled in the connection process setopts(gen_udp, Socket, Options) -> @@ -90,6 +93,32 @@ setopts(gen_udp, Socket, Options) -> setopts(Transport, Socket, Options) -> Transport:setopts(Socket, Options). +check_active_n(EmulatedOpts, Socket = #sslsocket{pid = {dtls, #config{dtls_handler = {ListenPid, _}}}}) -> + %% We check the resulting options to send an ssl_passive message if necessary. + case proplists:lookup(active, EmulatedOpts) of + %% The provided value is out of bound. + {_, N} when is_integer(N), N < -32768 -> + throw(einval); + {_, N} when is_integer(N), N > 32767 -> + throw(einval); + {_, N} when is_integer(N) -> + {ok, #socket_options{active = Active}, _} = dtls_packet_demux:get_all_opts(ListenPid), + case Active of + Atom when is_atom(Atom), N =< 0 -> + self() ! {ssl_passive, Socket}; + %% The result of the addition is out of bound. + %% We do not need to check < -32768 because Active can't be below 1. + A when is_integer(A), A + N > 32767 -> + throw(einval); + A when is_integer(A), A + N =< 0 -> + self() ! {ssl_passive, Socket}; + _ -> + ok + end; + _ -> + ok + end. + getopts(_, #sslsocket{pid = {dtls, #config{dtls_handler = {ListenPid, _}}}}, Options) -> SplitOpts = tls_socket:split_options(Options), dtls_packet_demux:get_sock_opts(ListenPid, SplitOpts); @@ -161,9 +190,18 @@ emulated_socket_options(InetValues, #socket_options{ mode = proplists:get_value(mode, InetValues, Mode), packet = proplists:get_value(packet, InetValues, Packet), packet_size = proplists:get_value(packet_size, InetValues, PacketSize), - active = proplists:get_value(active, InetValues, Active) + active = emulated_active_option(InetValues, Active) }. +emulated_active_option([], Active) -> + Active; +emulated_active_option([{active, Active} | _], _) when Active =< 0 -> + false; +emulated_active_option([{active, Active} | _], _) -> + Active; +emulated_active_option([_|Tail], Active) -> + emulated_active_option(Tail, Active). + emulated_options([{mode, Value} = Opt |Opts], Inet, Emulated) -> validate_inet_option(mode, Value), emulated_options(Opts, Inet, [Opt | proplists:delete(mode, Emulated)]); @@ -184,6 +222,9 @@ emulated_options([], Inet,Emulated) -> validate_inet_option(mode, Value) when Value =/= list, Value =/= binary -> throw({error, {options, {mode,Value}}}); +validate_inet_option(active, Value) + when Value >= -32768, Value =< 32767 -> + ok; validate_inet_option(active, Value) when Value =/= true, Value =/= false, Value =/= once -> throw({error, {options, {active,Value}}}); diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 6206d15c13..9e0b0a40c2 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -1258,10 +1258,21 @@ handle_call({get_opts, OptTags}, From, _, {keep_state_and_data, [{reply, From, OptsReply}]}; handle_call({set_opts, Opts0}, From, StateName, #state{static_env = #static_env{socket = Socket, - transport_cb = Transport}, + transport_cb = Transport, + tracker = Tracker}, + user_application = {_Mon, Pid}, socket_options = Opts1 } = State0, Connection) -> {Reply, Opts} = set_socket_opts(Connection, Transport, Socket, Opts0, Opts1, []), + case {proplists:lookup(active, Opts0), Opts} of + {{_, N}, #socket_options{active=false}} when is_integer(N) -> + send_user( + Pid, + format_passive( + Connection:pids(State0), Transport, Socket, Tracker, Connection)); + _ -> + ok + end, State = State0#state{socket_options = Opts}, handle_active_option(Opts#socket_options.active, StateName, From, Reply, State); @@ -2336,6 +2347,30 @@ set_socket_opts(ConnectionCb, Transport, Socket, [{active, Active}| Opts], SockO Active == false -> set_socket_opts(ConnectionCb, Transport, Socket, Opts, SockOpts#socket_options{active = Active}, Other); +set_socket_opts(ConnectionCb, Transport, Socket, [{active, Active1} = Opt| Opts], + SockOpts=#socket_options{active = Active0}, Other) + when Active1 >= -32768, Active1 =< 32767 -> + Active = if + is_integer(Active0), Active0 + Active1 < -32768 -> + error; + is_integer(Active0), Active0 + Active1 =< 0 -> + false; + is_integer(Active0), Active0 + Active1 > 32767 -> + error; + Active1 =< 0 -> + false; + is_integer(Active0) -> + Active0 + Active1; + true -> + Active1 + end, + case Active of + error -> + {{error, {options, {socket_options, Opt}} }, SockOpts}; + _ -> + set_socket_opts(ConnectionCb, Transport, Socket, Opts, + SockOpts#socket_options{active = Active}, Other) + end; set_socket_opts(_,_, _, [{active, _} = Opt| _], SockOpts, _) -> {{error, {options, {socket_options, Opt}} }, SockOpts}; set_socket_opts(ConnectionCb, Transport, Socket, [Opt | Opts], SockOpts, Other) -> @@ -2639,6 +2674,14 @@ deliver_app_data( case Active of once -> SO#socket_options{active=false}; + 1 -> + send_user( + Pid, + format_passive( + CPids, Transport, Socket, Tracker, Connection)), + SO#socket_options{active=false}; + N when is_integer(N) -> + SO#socket_options{active=N - 1}; _ -> SO end. @@ -2675,6 +2718,9 @@ do_format_reply(list, Packet, _, Data) do_format_reply(list, _,_, Data) -> binary_to_list(Data). +format_passive(CPids, Transport, Socket, Tracker, Connection) -> + {ssl_passive, Connection:socket(CPids, Transport, Socket, Connection, Tracker)}. + header(0, <<>>) -> <<>>; header(_, <<>>) -> diff --git a/lib/ssl/src/tls_socket.erl b/lib/ssl/src/tls_socket.erl index a391bc53de..9794ba39de 100644 --- a/lib/ssl/src/tls_socket.erl +++ b/lib/ssl/src/tls_socket.erl @@ -51,7 +51,9 @@ listen(Transport, Port, #config{transport_info = {Transport, _, _, _}, case Transport:listen(Port, Options ++ internal_inet_values()) of {ok, ListenSocket} -> {ok, Tracker} = inherit_tracker(ListenSocket, EmOpts, SslOpts), - {ok, #sslsocket{pid = {ListenSocket, Config#config{emulated = Tracker}}}}; + Socket = #sslsocket{pid = {ListenSocket, Config#config{emulated = Tracker}}}, + check_active_n(EmOpts, Socket), + {ok, Socket}; Err = {error, _} -> Err end. @@ -117,14 +119,16 @@ socket(Pids, Transport, Socket, ConnectionCb, Tracker) -> #sslsocket{pid = Pids, %% "The name "fd" is keept for backwards compatibility fd = {Transport, Socket, ConnectionCb, Tracker}}. -setopts(gen_tcp, #sslsocket{pid = {ListenSocket, #config{emulated = Tracker}}}, Options) -> +setopts(gen_tcp, Socket = #sslsocket{pid = {ListenSocket, #config{emulated = Tracker}}}, Options) -> {SockOpts, EmulatedOpts} = split_options(Options), ok = set_emulated_opts(Tracker, EmulatedOpts), + check_active_n(EmulatedOpts, Socket), inet:setopts(ListenSocket, SockOpts); -setopts(_, #sslsocket{pid = {ListenSocket, #config{transport_info = {Transport,_,_,_}, +setopts(_, Socket = #sslsocket{pid = {ListenSocket, #config{transport_info = {Transport,_,_,_}, emulated = Tracker}}}, Options) -> {SockOpts, EmulatedOpts} = split_options(Options), ok = set_emulated_opts(Tracker, EmulatedOpts), + check_active_n(EmulatedOpts, Socket), Transport:setopts(ListenSocket, SockOpts); %%% Following clauses will not be called for emulated options, they are handled in the connection process setopts(gen_tcp, Socket, Options) -> @@ -132,6 +136,31 @@ setopts(gen_tcp, Socket, Options) -> setopts(Transport, Socket, Options) -> Transport:setopts(Socket, Options). +check_active_n(EmulatedOpts, Socket = #sslsocket{pid = {_, #config{emulated = Tracker}}}) -> + %% We check the resulting options to send an ssl_passive message if necessary. + case proplists:lookup(active, EmulatedOpts) of + %% The provided value is out of bound. + {_, N} when is_integer(N), N < -32768 -> + throw(einval); + {_, N} when is_integer(N), N > 32767 -> + throw(einval); + {_, N} when is_integer(N) -> + case get_emulated_opts(Tracker, [active]) of + [{_, false}] -> + self() ! {ssl_passive, Socket}, + ok; + %% The result of the addition is out of bound. + [{_, A}] when is_integer(A), A < -32768 -> + throw(einval); + [{_, A}] when is_integer(A), A > 32767 -> + throw(einval); + _ -> + ok + end; + _ -> + ok + end. + getopts(gen_tcp, #sslsocket{pid = {ListenSocket, #config{emulated = Tracker}}}, Options) -> {SockOptNames, EmulatedOptNames} = split_options(Options), EmulatedOpts = get_emulated_opts(Tracker, EmulatedOptNames), @@ -209,7 +238,7 @@ start_link(Port, SockOpts, SslOpts) -> init([Port, Opts, SslOpts]) -> process_flag(trap_exit, true), true = link(Port), - {ok, #state{emulated_opts = Opts, port = Port, ssl_opts = SslOpts}}. + {ok, #state{emulated_opts = do_set_emulated_opts(Opts, []), port = Port, ssl_opts = SslOpts}}. %%-------------------------------------------------------------------- -spec handle_call(msg(), from(), #state{}) -> {reply, reply(), #state{}}. @@ -304,6 +333,18 @@ split_options([Name | Opts], Emu, SocketOptNames, EmuOptNames) -> do_set_emulated_opts([], Opts) -> Opts; +do_set_emulated_opts([{active, N0} | Rest], Opts) when is_integer(N0) -> + N = case proplists:lookup(active, Opts) of + {_, N1} when is_integer(N1), N0 + N1 =< 0 -> + false; + {_, N1} when is_integer(N1) -> + N0 + N1; + _ when N0 =< 0 -> + false; + _ -> + N0 + end, + do_set_emulated_opts(Rest, [{active, N} | proplists:delete(active, Opts)]); do_set_emulated_opts([{Name,_} = Opt | Rest], Opts) -> do_set_emulated_opts(Rest, [Opt | proplists:delete(Name, Opts)]). @@ -365,6 +406,9 @@ validate_inet_option(packet_size, Value) validate_inet_option(header, Value) when not is_integer(Value) -> throw({error, {options, {header,Value}}}); +validate_inet_option(active, Value) + when Value >= -32768, Value =< 32767 -> + ok; validate_inet_option(active, Value) when Value =/= true, Value =/= false, Value =/= once -> throw({error, {options, {active,Value}}}); diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index d0fa0443f2..8fe28bd901 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -164,6 +164,7 @@ api_tests() -> accept_pool, prf, socket_options, + active_n, cipher_suites, handshake_continue, handshake_continue_timeout, @@ -243,6 +244,7 @@ error_handling_tests()-> [close_transport_accept, recv_active, recv_active_once, + recv_active_n, recv_error_handling, call_in_error_state, close_in_error_state, @@ -1978,7 +1980,7 @@ recv_active(Config) when is_list(Config) -> %%-------------------------------------------------------------------- recv_active_once() -> - [{doc,"Test recv on active socket"}]. + [{doc,"Test recv on active (once) socket"}]. recv_active_once(Config) when is_list(Config) -> ClientOpts = ssl_test_lib:ssl_options(client_opts, Config), @@ -2002,6 +2004,178 @@ recv_active_once(Config) when is_list(Config) -> ssl_test_lib:close(Server), ssl_test_lib:close(Client). +%%-------------------------------------------------------------------- +recv_active_n() -> + [{doc,"Test recv on active (n) socket"}]. + +recv_active_n(Config) when is_list(Config) -> + ClientOpts = ssl_test_lib:ssl_options(client_opts, Config), + ServerOpts = ssl_test_lib:ssl_options(server_opts, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = + ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, try_recv_active_once, []}}, + {options, [{active, 1} | ServerOpts]}]), + Port = ssl_test_lib:inet_port(Server), + Client = + ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, try_recv_active_once, []}}, + {options, [{active, 1} | ClientOpts]}]), + + ssl_test_lib:check_result(Server, ok, Client, ok), + + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- +%% Test case adapted from gen_tcp_misc_SUITE. +active_n() -> + [{doc,"Test {active,N} option"}]. + +active_n(Config) when is_list(Config) -> + ClientOpts = ssl_test_lib:ssl_options(client_opts, Config), + ServerOpts = ssl_test_lib:ssl_options(server_opts, Config), + Port = ssl_test_lib:inet_port(node()), + N = 3, + LS = ok(ssl:listen(Port, [{active,N}|ServerOpts])), + [{active,N}] = ok(ssl:getopts(LS, [active])), + active_n_common(LS, N), + Self = self(), + spawn_link(fun() -> + S0 = ok(ssl:transport_accept(LS)), + {ok, S} = ssl:handshake(S0), + ok = ssl:setopts(S, [{active,N}]), + [{active,N}] = ok(ssl:getopts(S, [active])), + ssl:controlling_process(S, Self), + Self ! {server, S} + end), + C = ok(ssl:connect("localhost", Port, [{active,N}|ClientOpts])), + [{active,N}] = ok(ssl:getopts(C, [active])), + S = receive + {server, S0} -> S0 + after + 1000 -> + exit({error, connect}) + end, + active_n_common(C, N), + active_n_common(S, N), + ok = ssl:setopts(C, [{active,N}]), + ok = ssl:setopts(S, [{active,N}]), + ReceiveMsg = fun(Socket, Msg) -> + receive + {ssl,Socket,Msg} -> + ok; + {ssl,Socket,Begin} -> + receive + {ssl,Socket,End} -> + Msg = Begin ++ End, + ok + after 1000 -> + exit(timeout) + end + after 1000 -> + exit(timeout) + end + end, + repeat(3, fun(I) -> + Msg = "message "++integer_to_list(I), + ok = ssl:send(C, Msg), + ReceiveMsg(S, Msg), + ok = ssl:send(S, Msg), + ReceiveMsg(C, Msg) + end), + receive + {ssl_passive,S} -> + [{active,false}] = ok(ssl:getopts(S, [active])) + after + 1000 -> + exit({error,ssl_passive}) + end, + receive + {ssl_passive,C} -> + [{active,false}] = ok(ssl:getopts(C, [active])) + after + 1000 -> + exit({error,ssl_passive}) + end, + LS2 = ok(ssl:listen(0, [{active,0}])), + receive + {ssl_passive,LS2} -> + [{active,false}] = ok(ssl:getopts(LS2, [active])) + after + 1000 -> + exit({error,ssl_passive}) + end, + ok = ssl:close(LS2), + ok = ssl:close(C), + ok = ssl:close(S), + ok = ssl:close(LS), + ok. + +active_n_common(S, N) -> + ok = ssl:setopts(S, [{active,-N}]), + receive + {ssl_passive, S} -> ok + after + 1000 -> + error({error,ssl_passive_failure}) + end, + [{active,false}] = ok(ssl:getopts(S, [active])), + ok = ssl:setopts(S, [{active,0}]), + receive + {ssl_passive, S} -> ok + after + 1000 -> + error({error,ssl_passive_failure}) + end, + ok = ssl:setopts(S, [{active,32767}]), + {error,{options,_}} = ssl:setopts(S, [{active,1}]), + {error,{options,_}} = ssl:setopts(S, [{active,-32769}]), + ok = ssl:setopts(S, [{active,-32768}]), + receive + {ssl_passive, S} -> ok + after + 1000 -> + error({error,ssl_passive_failure}) + end, + [{active,false}] = ok(ssl:getopts(S, [active])), + ok = ssl:setopts(S, [{active,N}]), + ok = ssl:setopts(S, [{active,true}]), + [{active,true}] = ok(ssl:getopts(S, [active])), + receive + _ -> error({error,active_n}) + after + 0 -> + ok + end, + ok = ssl:setopts(S, [{active,N}]), + ok = ssl:setopts(S, [{active,once}]), + [{active,once}] = ok(ssl:getopts(S, [active])), + receive + _ -> error({error,active_n}) + after + 0 -> + ok + end, + {error,{options,_}} = ssl:setopts(S, [{active,32768}]), + ok = ssl:setopts(S, [{active,false}]), + [{active,false}] = ok(ssl:getopts(S, [active])), + ok. + +ok({ok,V}) -> V. + +repeat(N, Fun) -> + repeat(N, N, Fun). + +repeat(N, T, Fun) when is_integer(N), N > 0 -> + Fun(T-N), + repeat(N-1, T, Fun); +repeat(_, _, _) -> + ok. + %%-------------------------------------------------------------------- dh_params() -> [{doc,"Test to specify DH-params file in server."}]. -- cgit v1.2.3 From 4f0b8e5eb61a2019285bfc7a8e50af1d338ffd63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Mon, 11 Feb 2019 17:04:35 +0100 Subject: ssl: Document {active,N} --- lib/ssl/doc/src/ssl.xml | 21 ++++++++++++--------- lib/ssl/src/ssl.erl | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml index 21ea1be4b4..78106b8502 100644 --- a/lib/ssl/doc/src/ssl.xml +++ b/lib/ssl/doc/src/ssl.xml @@ -97,9 +97,12 @@ -

When an TLS/DTLS socket is in active mode (the default), data from the +

When a TLS/DTLS socket is in active mode (the default), data from the socket is delivered to the owner of the socket in the form of messages as described above.

+

The ssl_passive message is sent only when the socket is in + {active, N} mode and the counter dropped to 0. It indicates + that the socket has transitioned to passive ({active, false}) mode.

@@ -1169,8 +1172,8 @@ fun(srp, Username :: string(), UserState :: term()) -> marker="#handshake_cancel-1">handshake_cancel/1.

-

If the option active is set to once or true the - process owning the sslsocket will receive messages of type +

If the option active is set to once, true or an integer value, + the process owning the sslsocket will receive messages of type active_msgs()

@@ -1217,8 +1220,8 @@ fun(srp, Username :: string(), UserState :: term()) -> marker="#handshake_cancel-1">handshake_cancel/1.

-

If the option active is set to once or true the - process owning the sslsocket will receive messages of type +

If the option active is set to once, true or an integer value, + the process owning the sslsocket will receive messages of type active_msgs()

@@ -1379,8 +1382,8 @@ fun(srp, Username :: string(), UserState :: term()) ->

Performs the SSL/TLS/DTLS server-side handshake.

Returns a new TLS/DTLS socket if the handshake is successful.

-

If the option active is set to once or true the - process owning the sslsocket will receive messages of type +

If the option active is set to once, true or an integer value, + the process owning the sslsocket will receive messages of type active_msgs()

@@ -1424,8 +1427,8 @@ fun(srp, Username :: string(), UserState :: term()) -> marker="#handshake_cancel-1">handshake_cancel/1.

-

If the option active is set to once or true the - process owning the sslsocket will receive messages of type +

If the option active is set to once, true or an integer value, + the process owning the sslsocket will receive messages of type active_msgs()

diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index c39a6f1603..c95d29df2c 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -99,7 +99,7 @@ -type tls_client_option() :: client_option() | socket_connect_option() | transport_option(). -type tls_server_option() :: server_option() | socket_listen_option() | transport_option(). -type active_msgs() :: {ssl, sslsocket(), Data::binary() | list()} | {ssl_closed, sslsocket()} | - {ssl_error, sslsocket(), Reason::term()}. + {ssl_error, sslsocket(), Reason::term()} | {ssl_passive, sslsocket()}. -type transport_option() :: {cb_info, {CallbackModule::atom(), DataTag::atom(), ClosedTag::atom(), ErrTag::atom()}}. -type path() :: file:filename(). -- cgit v1.2.3 From 33a9c7d4c916996708694428f8b285f51c1256ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Sat, 16 Feb 2019 10:25:48 +0100 Subject: ssl: Use common fonction to update {active,N} --- lib/ssl/src/dtls_packet_demux.erl | 11 +---------- lib/ssl/src/tls_socket.erl | 24 ++++++++++++++---------- 2 files changed, 15 insertions(+), 20 deletions(-) (limited to 'lib') diff --git a/lib/ssl/src/dtls_packet_demux.erl b/lib/ssl/src/dtls_packet_demux.erl index 4945ef3c10..092366b7c0 100644 --- a/lib/ssl/src/dtls_packet_demux.erl +++ b/lib/ssl/src/dtls_packet_demux.erl @@ -298,16 +298,7 @@ do_set_emulated_opts([], Opts) -> do_set_emulated_opts([{mode, Value} | Rest], Opts) -> do_set_emulated_opts(Rest, Opts#socket_options{mode = Value}); do_set_emulated_opts([{active, N0} | Rest], Opts=#socket_options{active = Active}) when is_integer(N0) -> - N = case Active of - N1 when is_integer(N1), N0 + N1 =< 0 -> - false; - N1 when is_integer(N1) -> - N0 + N1; - _ when N0 =< 0 -> - false; - _ -> - N0 - end, + N = tls_socket:update_active_n(N0, Active), do_set_emulated_opts(Rest, Opts#socket_options{active = N}); do_set_emulated_opts([{active, Value} | Rest], Opts) -> do_set_emulated_opts(Rest, Opts#socket_options{active = Value}). diff --git a/lib/ssl/src/tls_socket.erl b/lib/ssl/src/tls_socket.erl index 9794ba39de..c3c41d3e12 100644 --- a/lib/ssl/src/tls_socket.erl +++ b/lib/ssl/src/tls_socket.erl @@ -32,6 +32,7 @@ emulated_socket_options/2, get_emulated_opts/1, set_emulated_opts/2, get_all_opts/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3]). +-export([update_active_n/2]). -record(state, { emulated_opts, @@ -334,20 +335,23 @@ split_options([Name | Opts], Emu, SocketOptNames, EmuOptNames) -> do_set_emulated_opts([], Opts) -> Opts; do_set_emulated_opts([{active, N0} | Rest], Opts) when is_integer(N0) -> - N = case proplists:lookup(active, Opts) of - {_, N1} when is_integer(N1), N0 + N1 =< 0 -> - false; - {_, N1} when is_integer(N1) -> - N0 + N1; - _ when N0 =< 0 -> - false; - _ -> - N0 - end, + N = update_active_n(N0, proplists:get_value(active, Opts, false)), do_set_emulated_opts(Rest, [{active, N} | proplists:delete(active, Opts)]); do_set_emulated_opts([{Name,_} = Opt | Rest], Opts) -> do_set_emulated_opts(Rest, [Opt | proplists:delete(Name, Opts)]). +update_active_n(New, Current) -> + if + is_integer(Current), New + Current =< 0 -> + false; + is_integer(Current) -> + New + Current; + New =< 0 -> + false; + true -> + New + end. + get_socket_opts(_, [], _) -> []; get_socket_opts(ListenSocket, SockOptNames, Cb) -> -- cgit v1.2.3 From 59c1634e7972746ab3f144bbd65922bcb1d9c630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Tue, 19 Feb 2019 11:00:43 +0100 Subject: fixup! ssl: Add support for {active,N} --- lib/ssl/src/ssl_connection.erl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 9e0b0a40c2..86b39a1712 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -542,7 +542,11 @@ read_application_data( undefined, undefined) end; {more, Buffer} -> % no reply, we need more data - {no_record, State#state{user_data_buffer = Buffer}}; + {no_record, + State#state{ + user_data_buffer = Buffer, + socket_options = SocketOpts0 + }}; {passive, Buffer} -> {no_record, State#state{user_data_buffer = Buffer}}; {error,_Reason} -> %% Invalid packet in packet mode @@ -1260,7 +1264,8 @@ handle_call({set_opts, Opts0}, From, StateName, #state{static_env = #static_env{socket = Socket, transport_cb = Transport, tracker = Tracker}, - user_application = {_Mon, Pid}, + connection_env = + #connection_env{user_application = {_Mon, Pid}}, socket_options = Opts1 } = State0, Connection) -> {Reply, Opts} = set_socket_opts(Connection, Transport, Socket, Opts0, Opts1, []), -- cgit v1.2.3