diff options
author | Ingela Anderton Andin <[email protected]> | 2018-12-27 09:40:01 +0100 |
---|---|---|
committer | Ingela Anderton Andin <[email protected]> | 2019-01-08 15:22:20 +0100 |
commit | a1e2f6e6789e804a56b795905f56b891b21c738e (patch) | |
tree | effcdea19cfaad4409adb9238c0c2eb6263663c1 | |
parent | f0ea49125815ec9197ffb6c74e20ebb5f10732d4 (diff) | |
download | otp-a1e2f6e6789e804a56b795905f56b891b21c738e.tar.gz otp-a1e2f6e6789e804a56b795905f56b891b21c738e.tar.bz2 otp-a1e2f6e6789e804a56b795905f56b891b21c738e.zip |
ssl: Guarantee active once data delivery
New internal active N changed timing, and
new check is needed.
-rw-r--r-- | lib/ssl/src/tls_connection.erl | 6 | ||||
-rw-r--r-- | lib/ssl/test/ssl_payload_SUITE.erl | 54 |
2 files changed, 58 insertions, 2 deletions
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl index 798b853026..80a8c6b72c 100644 --- a/lib/ssl/src/tls_connection.erl +++ b/lib/ssl/src/tls_connection.erl @@ -901,6 +901,12 @@ handle_alerts([], Result) -> Result; handle_alerts(_, {stop, _, _} = Stop) -> Stop; +handle_alerts([#alert{level = ?WARNING, description = ?CLOSE_NOTIFY} | _Alerts], + {next_state, connection = StateName, #state{user_data_buffer = Buffer, + protocol_buffers = #protocol_buffers{tls_cipher_texts = CTs}} = + State}) when (Buffer =/= <<>>) orelse + (CTs =/= []) -> + {next_state, StateName, State#state{terminated = true}}; handle_alerts([Alert | Alerts], {next_state, StateName, State}) -> handle_alerts(Alerts, ssl_connection:handle_alert(Alert, StateName, State)); handle_alerts([Alert | Alerts], {next_state, StateName, State, _Actions}) -> diff --git a/lib/ssl/test/ssl_payload_SUITE.erl b/lib/ssl/test/ssl_payload_SUITE.erl index 1f9b6a5772..0f5a041a1b 100644 --- a/lib/ssl/test/ssl_payload_SUITE.erl +++ b/lib/ssl/test/ssl_payload_SUITE.erl @@ -64,7 +64,8 @@ payload_tests() -> server_echos_active_huge, client_echos_passive_huge, client_echos_active_once_huge, - client_echos_active_huge]. + client_echos_active_huge, + client_active_once_server_close]. init_per_suite(Config) -> catch crypto:stop(), @@ -397,6 +398,23 @@ client_echos_active_huge(Config) when is_list(Config) -> client_echos_active( Data, ClientOpts, ServerOpts, ClientNode, ServerNode, Hostname). + +%%-------------------------------------------------------------------- +client_active_once_server_close() -> + [{doc, "Server sends 500000 bytes and immediately after closes the connection" + "Make sure client recives all data if possible"}]. + +client_active_once_server_close(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), + %% + Data = binary:copy(<<"1234567890">>, 50000), + client_active_once_server_close( + Data, ClientOpts, ServerOpts, ClientNode, ServerNode, Hostname). + + + %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- @@ -541,6 +559,25 @@ client_echos_active( ssl_test_lib:close(Server), ssl_test_lib:close(Client). +client_active_once_server_close( + Data, ClientOpts, ServerOpts, ClientNode, ServerNode, Hostname) -> + Length = byte_size(Data), + Server = + ssl_test_lib:start_server( + [{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, send_close, [Data]}}, + {options, [{active, once}, {mode, binary} | ServerOpts]}]), + Port = ssl_test_lib:inet_port(Server), + Client = + ssl_test_lib:start_client( + [{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, active_once_recv, [Length]}}, + {options,[{active, once}, {mode, binary} | ClientOpts]}]), + %% + ssl_test_lib:check_result(Server, ok, Client, ok). send(Socket, Data, Count, Verify) -> send(Socket, Data, Count, <<>>, Verify). @@ -552,7 +589,11 @@ send(Socket, Data, Count, Acc, Verify) -> NewAcc = Verify(Acc), send(Socket, Data, Count - 1, NewAcc, Verify). - + +send_close(Socket, Data) -> + ok = ssl:send(Socket, Data), + ssl:close(Socket). + sender(Socket, Data) -> ct:log("Sender recv: ~p~n", [ssl:getopts(Socket, [active])]), <<>> = @@ -688,3 +729,12 @@ verify_active(Socket, SentData, Acc) -> <<>> end end. + +active_once_recv(_Socket, 0) -> + ok; +active_once_recv(Socket, N) -> + receive + {ssl, Socket, Bytes} -> + ssl:setopts(Socket, [{active, once}]), + active_once_recv(Socket, N-byte_size(Bytes)) + end. |