aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngela Anderton Andin <[email protected]>2019-07-23 14:35:05 +0200
committerIngela Anderton Andin <[email protected]>2019-07-25 10:23:55 +0200
commitbb72bc0dadd121457019178a2a21e458a998e835 (patch)
tree4dbf0ab7ea46f1feea4e276f66db42f9ecdb8707
parentfc2fb193f1c28e0581530e0f4cebac6c8237879f (diff)
downloadotp-bb72bc0dadd121457019178a2a21e458a998e835.tar.gz
otp-bb72bc0dadd121457019178a2a21e458a998e835.tar.bz2
otp-bb72bc0dadd121457019178a2a21e458a998e835.zip
ssl: Add ssl_socket_SUITE
-rw-r--r--lib/ssl/test/Makefile1
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl356
-rw-r--r--lib/ssl/test/ssl_socket_SUITE.erl437
3 files changed, 439 insertions, 355 deletions
diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile
index 06cafd124f..2fb0dcb114 100644
--- a/lib/ssl/test/Makefile
+++ b/lib/ssl/test/Makefile
@@ -82,6 +82,7 @@ MODULES = \
tls_1_3_record_SUITE\
openssl_tls_1_3_version_SUITE\
tls_1_3_version_SUITE\
+ ssl_socket_SUITE\
make_certs \
x509_test \
inet_crypto_dist
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 542876a1b7..71c9e55c2b 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -99,14 +99,6 @@ basic_tests() ->
options_tests() ->
[
ssl_options_not_proplist,
- raw_ssl_option,
- invalid_inet_get_option,
- invalid_inet_get_option_not_list,
- invalid_inet_get_option_improper_list,
- invalid_inet_set_option,
- invalid_inet_set_option_not_list,
- invalid_inet_set_option_improper_list,
- invalid_options,
protocol_versions,
empty_protocol_versions,
reuseaddr,
@@ -120,9 +112,7 @@ options_tests_tls() ->
api_tests() ->
[eccs,
- getstat,
accept_pool,
- socket_options,
internal_active_1,
cipher_suites
].
@@ -257,14 +247,7 @@ init_per_testcase(TestCase, Config) when TestCase == clear_pem_cache;
ssl:start(),
ct:timetrap({seconds, 20}),
Config;
-init_per_testcase(raw_ssl_option, Config) ->
- ct:timetrap({seconds, 5}),
- case os:type() of
- {unix,linux} ->
- Config;
- _ ->
- {skip, "Raw options are platform-specific"}
- end;
+
init_per_testcase(accept_pool, Config) ->
ct:timetrap({seconds, 5}),
@@ -387,73 +370,6 @@ empty_protocol_versions(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-getstat() ->
- [{doc,"Test API function getstat/2"}].
-
-getstat(Config) when is_list(Config) ->
- ClientOpts = ?config(client_opts, Config),
- ServerOpts = ?config(server_opts, Config),
- {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- Server1 =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{active, false} | ServerOpts]}]),
- Port1 = ssl_test_lib:inet_port(Server1),
- Server2 =
- ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {ssl_test_lib, send_recv_result, []}},
- {options, [{active, false} | ServerOpts]}]),
- Port2 = ssl_test_lib:inet_port(Server2),
- {ok, ActiveC} = rpc:call(ClientNode, ssl, connect,
- [Hostname,Port1,[{active, once}|ClientOpts]]),
- {ok, PassiveC} = rpc:call(ClientNode, ssl, connect,
- [Hostname,Port2,[{active, false}|ClientOpts]]),
-
- ct:log("Testcase ~p, Client ~p Servers ~p, ~p ~n",
- [self(), self(), Server1, Server2]),
-
- %% We only check that the values are non-zero initially
- %% (due to the handshake), and that sending more changes the values.
-
- %% Passive socket.
-
- {ok, InitialStats} = ssl:getstat(PassiveC),
- ct:pal("InitialStats ~p~n", [InitialStats]),
- [true] = lists:usort([0 =/= proplists:get_value(Name, InitialStats)
- || Name <- [recv_cnt, recv_oct, recv_avg, recv_max, send_cnt, send_oct, send_avg, send_max]]),
-
- ok = ssl:send(PassiveC, "Hello world"),
- wait_for_send(PassiveC),
- {ok, SStats} = ssl:getstat(PassiveC, [send_cnt, send_oct]),
- ct:pal("SStats ~p~n", [SStats]),
- [true] = lists:usort([proplists:get_value(Name, SStats) =/= proplists:get_value(Name, InitialStats)
- || Name <- [send_cnt, send_oct]]),
-
- %% Active socket.
-
- {ok, InitialAStats} = ssl:getstat(ActiveC),
- ct:pal("InitialAStats ~p~n", [InitialAStats]),
- [true] = lists:usort([0 =/= proplists:get_value(Name, InitialAStats)
- || Name <- [recv_cnt, recv_oct, recv_avg, recv_max, send_cnt, send_oct, send_avg, send_max]]),
-
- _ = receive
- {ssl, ActiveC, _} ->
- ok
- after
- ?SLEEP ->
- exit(timeout)
- end,
-
- ok = ssl:send(ActiveC, "Hello world"),
- wait_for_send(ActiveC),
- {ok, ASStats} = ssl:getstat(ActiveC, [send_cnt, send_oct]),
- ct:pal("ASStats ~p~n", [ASStats]),
- [true] = lists:usort([proplists:get_value(Name, ASStats) =/= proplists:get_value(Name, InitialAStats)
- || Name <- [send_cnt, send_oct]]),
-
- ok.
%%--------------------------------------------------------------------
connect_dist() ->
@@ -706,244 +622,6 @@ tls_socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues)
ct:log("All opts ~p~n", [All]),
ok.
-
-%%--------------------------------------------------------------------
-socket_options() ->
- [{doc,"Test API function getopts/2 and setopts/2"}].
-
-socket_options(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),
- Values = [{mode, list}, {active, true}],
- %% Shall be the reverse order of Values!
- Options = [active, mode],
-
- NewValues = [{mode, binary}, {active, once}],
- %% Shall be the reverse order of NewValues!
- NewOptions = [active, mode],
-
- Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
- {from, self()},
- {mfa, {?MODULE, socket_options_result,
- [Options, Values, NewOptions, NewValues]}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, socket_options_result,
- [Options, Values, NewOptions, NewValues]}},
- {options, ClientOpts}]),
-
- ssl_test_lib:check_result(Server, ok, Client, ok),
-
- ssl_test_lib:close(Server),
-
- {ok, Listen} = ssl:listen(0, ServerOpts),
- {ok,[{mode,list}]} = ssl:getopts(Listen, [mode]),
- ok = ssl:setopts(Listen, [{mode, binary}]),
- {ok,[{mode, binary}]} = ssl:getopts(Listen, [mode]),
- {ok,[{recbuf, _}]} = ssl:getopts(Listen, [recbuf]),
- ssl:close(Listen).
-
-
-socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
- %% Test get/set emulated opts
- {ok, DefaultValues} = ssl:getopts(Socket, Options),
- ssl:setopts(Socket, NewValues),
- {ok, NewValues} = ssl:getopts(Socket, NewOptions),
- %% Test get/set inet opts
- {ok,[{reuseaddr, _}]} = ssl:getopts(Socket, [reuseaddr]),
- {ok, All} = ssl:getopts(Socket, []),
- ct:log("All opts ~p~n", [All]),
- ok.
-
-
-%%--------------------------------------------------------------------
-invalid_inet_get_option() ->
- [{doc,"Test handling of invalid inet options in getopts"}].
-
-invalid_inet_get_option(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, get_invalid_inet_option, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-%%--------------------------------------------------------------------
-invalid_inet_get_option_not_list() ->
- [{doc,"Test handling of invalid type in getopts"}].
-
-invalid_inet_get_option_not_list(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, get_invalid_inet_option_not_list, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-
-get_invalid_inet_option_not_list(Socket) ->
- {error, {options, {socket_options, some_invalid_atom_here}}}
- = ssl:getopts(Socket, some_invalid_atom_here),
- ok.
-
-%%--------------------------------------------------------------------
-invalid_inet_get_option_improper_list() ->
- [{doc,"Test handling of invalid type in getopts"}].
-
-invalid_inet_get_option_improper_list(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, get_invalid_inet_option_improper_list, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-
-get_invalid_inet_option_improper_list(Socket) ->
- {error, {options, {socket_options, foo,_}}} = ssl:getopts(Socket, [packet | foo]),
- ok.
-
-%%--------------------------------------------------------------------
-invalid_inet_set_option() ->
- [{doc,"Test handling of invalid inet options in setopts"}].
-
-invalid_inet_set_option(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, set_invalid_inet_option, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-set_invalid_inet_option(Socket) ->
- {error, {options, {socket_options, {packet, foo}}}} = ssl:setopts(Socket, [{packet, foo}]),
- {error, {options, {socket_options, {header, foo}}}} = ssl:setopts(Socket, [{header, foo}]),
- {error, {options, {socket_options, {active, foo}}}} = ssl:setopts(Socket, [{active, foo}]),
- {error, {options, {socket_options, {mode, foo}}}} = ssl:setopts(Socket, [{mode, foo}]),
- ok.
-%%--------------------------------------------------------------------
-invalid_inet_set_option_not_list() ->
- [{doc,"Test handling of invalid type in setopts"}].
-
-invalid_inet_set_option_not_list(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, set_invalid_inet_option_not_list, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-
-set_invalid_inet_option_not_list(Socket) ->
- {error, {options, {not_a_proplist, some_invalid_atom_here}}}
- = ssl:setopts(Socket, some_invalid_atom_here),
- ok.
-
-%%--------------------------------------------------------------------
-invalid_inet_set_option_improper_list() ->
- [{doc,"Test handling of invalid tye in setopts"}].
-
-invalid_inet_set_option_improper_list(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, set_invalid_inet_option_improper_list, []}},
- {options, ServerOpts}]),
- Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, no_result, []}},
- {options, ClientOpts}]),
-
- ct:log("Testcase ~p, Client ~p Server ~p ~n",
- [self(), Client, Server]),
-
- ssl_test_lib:check_result(Server, ok),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
-
-set_invalid_inet_option_improper_list(Socket) ->
- {error, {options, {not_a_proplist, [{packet, 0} | {foo, 2}]}}} =
- ssl:setopts(Socket, [{packet, 0} | {foo, 2}]),
- ok.
-
%%--------------------------------------------------------------------
tls_misc_ssl_options() ->
[{doc,"Test what happens when we give valid options"}].
@@ -991,24 +669,7 @@ ssl_options_not_proplist(Config) when is_list(Config) ->
ssl:connect("twitter.com", 443, [binary, {active, false},
BadOption]).
-%%--------------------------------------------------------------------
-raw_ssl_option() ->
- [{doc,"Ensure that a single 'raw' option is passed to ssl:listen correctly."}].
-
-raw_ssl_option(Config) when is_list(Config) ->
- % 'raw' option values are platform-specific; these are the Linux values:
- IpProtoTcp = 6,
- % Use TCP_KEEPIDLE, because (e.g.) TCP_MAXSEG can't be read back reliably.
- TcpKeepIdle = 4,
- KeepAliveTimeSecs = 55,
- LOptions = [{raw, IpProtoTcp, TcpKeepIdle, <<KeepAliveTimeSecs:32/native>>}],
- {ok, LSocket} = ssl:listen(0, LOptions),
- % Per http://www.erlang.org/doc/man/inet.html#getopts-2, we have to specify
- % exactly which raw option we want, and the size of the buffer.
- {ok, [{raw, IpProtoTcp, TcpKeepIdle, <<KeepAliveTimeSecs:32/native>>}]} = ssl:getopts(LSocket, [{raw, IpProtoTcp, TcpKeepIdle, 4}]).
-
-%%--------------------------------------------------------------------
eccs() ->
[{doc, "Test API functions eccs/0 and eccs/1"}].
@@ -1695,19 +1356,11 @@ connect_dist_c(S) ->
{ok, Test} = ssl:recv(S, 0, 10000),
ok.
-
-get_invalid_inet_option(Socket) ->
- {error, {options, {socket_options, foo, _}}} = ssl:getopts(Socket, [foo]),
- ok.
-
-
dummy(_Socket) ->
%% Should not happen as the ssl connection will not be established
%% due to fatal handshake failiure
exit(kill).
-
-
version_option_test(Config, Version) ->
ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
ServerOpts = ssl_test_lib:ssl_options(server_opts, Config),
@@ -1733,13 +1386,6 @@ version_option_test(Config, Version) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
-
-
-wait_for_send(Socket) ->
- %% Make sure TLS process processed send message event
- _ = ssl:connection_information(Socket).
-
-
connection_info_result(Socket) ->
{ok, Info} = ssl:connection_information(Socket, [protocol, selected_cipher_suite]),
{ok, {proplists:get_value(protocol, Info), proplists:get_value(selected_cipher_suite, Info)}}.
diff --git a/lib/ssl/test/ssl_socket_SUITE.erl b/lib/ssl/test/ssl_socket_SUITE.erl
new file mode 100644
index 0000000000..d648f2f9e1
--- /dev/null
+++ b/lib/ssl/test/ssl_socket_SUITE.erl
@@ -0,0 +1,437 @@
+%%
+%% Copyright Ericsson AB 2019-2019. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_socket_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+-define(SLEEP, 500).
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+all() ->
+ [
+ {group, tls},
+ {group, dtls}
+ ].
+
+groups() ->
+ [
+ {tls,[], socket_tests() ++ raw_inet_opt()},
+ {dtls,[], socket_tests()}
+ ].
+
+socket_tests() ->
+ [
+ getstat,
+ socket_options,
+ invalid_inet_get_option,
+ invalid_inet_get_option_not_list,
+ invalid_inet_get_option_improper_list,
+ invalid_inet_set_option,
+ invalid_inet_set_option_not_list,
+ invalid_inet_set_option_improper_list
+ ].
+
+raw_inet_opt() ->
+ [
+ raw_inet_option
+ ].
+
+
+init_per_suite(Config0) ->
+ catch crypto:stop(),
+ try crypto:start() of
+ ok ->
+ ssl_test_lib:clean_start(),
+ ssl_test_lib:make_rsa_cert(Config0)
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:unload(ssl),
+ application:stop(crypto).
+
+init_per_group(dtls, Config) ->
+ [{protocol_opts, [{protocol, dtls}]} | proplists:delete(protocol_opts, Config)];
+init_per_group(tls, Config) ->
+ [{protocol_opts, [{protocol, tls}]} | proplists:delete(protocol_opts, Config)];
+init_per_group(_GroupName, Config) ->
+ [{client_type, erlang},
+ {server_type, erlang} | Config].
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_testcase(raw_inet_option, Config) ->
+ ct:timetrap({seconds, 5}),
+ case os:type() of
+ {unix,linux} ->
+ Config;
+ _ ->
+ {skip, "Raw options are platform-specific"}
+ end;
+init_per_testcase(_TestCase, Config) ->
+ ct:timetrap({seconds, 5}),
+ Config.
+
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+getstat() ->
+ [{doc,"Test API function getstat/2"}].
+
+getstat(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_rsa_opts, Config),
+ ServerOpts = ?config(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server1 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port1 = ssl_test_lib:inet_port(Server1),
+ Server2 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port2 = ssl_test_lib:inet_port(Server2),
+ {ok, ActiveC} = rpc:call(ClientNode, ssl, connect,
+ [Hostname,Port1,[{active, once}|ClientOpts]]),
+ {ok, PassiveC} = rpc:call(ClientNode, ssl, connect,
+ [Hostname,Port2,[{active, false}|ClientOpts]]),
+
+ ct:log("Testcase ~p, Client ~p Servers ~p, ~p ~n",
+ [self(), self(), Server1, Server2]),
+
+ %% We only check that the values are non-zero initially
+ %% (due to the handshake), and that sending more changes the values.
+
+ %% Passive socket.
+
+ {ok, InitialStats} = ssl:getstat(PassiveC),
+ ct:pal("InitialStats ~p~n", [InitialStats]),
+ [true] = lists:usort([0 =/= proplists:get_value(Name, InitialStats)
+ || Name <- [recv_cnt, recv_oct, recv_avg, recv_max, send_cnt, send_oct, send_avg, send_max]]),
+
+ ok = ssl:send(PassiveC, "Hello world"),
+ wait_for_send(PassiveC),
+ {ok, SStats} = ssl:getstat(PassiveC, [send_cnt, send_oct]),
+ ct:pal("SStats ~p~n", [SStats]),
+ [true] = lists:usort([proplists:get_value(Name, SStats) =/= proplists:get_value(Name, InitialStats)
+ || Name <- [send_cnt, send_oct]]),
+
+ %% Active socket.
+
+ {ok, InitialAStats} = ssl:getstat(ActiveC),
+ ct:pal("InitialAStats ~p~n", [InitialAStats]),
+ [true] = lists:usort([0 =/= proplists:get_value(Name, InitialAStats)
+ || Name <- [recv_cnt, recv_oct, recv_avg, recv_max, send_cnt, send_oct, send_avg, send_max]]),
+
+ _ = receive
+ {ssl, ActiveC, _} ->
+ ok
+ after
+ ?SLEEP ->
+ exit(timeout)
+ end,
+
+ ok = ssl:send(ActiveC, "Hello world"),
+ wait_for_send(ActiveC),
+ {ok, ASStats} = ssl:getstat(ActiveC, [send_cnt, send_oct]),
+ ct:pal("ASStats ~p~n", [ASStats]),
+ [true] = lists:usort([proplists:get_value(Name, ASStats) =/= proplists:get_value(Name, InitialAStats)
+ || Name <- [send_cnt, send_oct]]),
+
+ ok.
+%%--------------------------------------------------------------------
+socket_options() ->
+ [{doc,"Test API function getopts/2 and setopts/2"}].
+
+socket_options(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Values = [{mode, list}, {active, true}],
+ %% Shall be the reverse order of Values!
+ Options = [active, mode],
+
+ NewValues = [{mode, binary}, {active, once}],
+ %% Shall be the reverse order of NewValues!
+ NewOptions = [active, mode],
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, socket_options_result,
+ [Options, Values, NewOptions, NewValues]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, socket_options_result,
+ [Options, Values, NewOptions, NewValues]}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+
+ {ok, Listen} = ssl:listen(0, ServerOpts),
+ {ok,[{mode,list}]} = ssl:getopts(Listen, [mode]),
+ ok = ssl:setopts(Listen, [{mode, binary}]),
+ {ok,[{mode, binary}]} = ssl:getopts(Listen, [mode]),
+ {ok,[{recbuf, _}]} = ssl:getopts(Listen, [recbuf]),
+ ssl:close(Listen).
+
+%%--------------------------------------------------------------------
+raw_inet_option() ->
+ [{doc,"Ensure that a single 'raw' option is passed to ssl:listen correctly."}].
+
+raw_inet_option(Config) when is_list(Config) ->
+ % 'raw' option values are platform-specific; these are the Linux values:
+ IpProtoTcp = 6,
+ % Use TCP_KEEPIDLE, because (e.g.) TCP_MAXSEG can't be read back reliably.
+ TcpKeepIdle = 4,
+ KeepAliveTimeSecs = 55,
+ LOptions = [{raw, IpProtoTcp, TcpKeepIdle, <<KeepAliveTimeSecs:32/native>>}],
+ {ok, LSocket} = ssl:listen(0, LOptions),
+ % Per http://www.erlang.org/doc/man/inet.html#getopts-2, we have to specify
+ % exactly which raw option we want, and the size of the buffer.
+ {ok, [{raw, IpProtoTcp, TcpKeepIdle, <<KeepAliveTimeSecs:32/native>>}]} =
+ ssl:getopts(LSocket, [{raw, IpProtoTcp, TcpKeepIdle, 4}]).
+
+%%--------------------------------------------------------------------
+
+invalid_inet_get_option() ->
+ [{doc,"Test handling of invalid inet options in getopts"}].
+
+invalid_inet_get_option(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_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, get_invalid_inet_option, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+invalid_inet_get_option_not_list() ->
+ [{doc,"Test handling of invalid type in getopts"}].
+
+invalid_inet_get_option_not_list(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_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, get_invalid_inet_option_not_list, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+invalid_inet_get_option_improper_list() ->
+ [{doc,"Test handling of invalid type in getopts"}].
+
+invalid_inet_get_option_improper_list(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_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, get_invalid_inet_option_improper_list, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+invalid_inet_set_option() ->
+ [{doc,"Test handling of invalid inet options in setopts"}].
+
+invalid_inet_set_option(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_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, set_invalid_inet_option, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+invalid_inet_set_option_not_list() ->
+ [{doc,"Test handling of invalid type in setopts"}].
+
+invalid_inet_set_option_not_list(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_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, set_invalid_inet_option_not_list, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+invalid_inet_set_option_improper_list() ->
+ [{doc,"Test handling of invalid tye in setopts"}].
+
+invalid_inet_set_option_improper_list(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_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, set_invalid_inet_option_improper_list, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+
+ ct:log("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
+ %% Test get/set emulated opts
+ {ok, DefaultValues} = ssl:getopts(Socket, Options),
+ ssl:setopts(Socket, NewValues),
+ {ok, NewValues} = ssl:getopts(Socket, NewOptions),
+ %% Test get/set inet opts
+ {ok,[{reuseaddr, _}]} = ssl:getopts(Socket, [reuseaddr]),
+ {ok, All} = ssl:getopts(Socket, []),
+ ct:log("All opts ~p~n", [All]),
+ ok.
+
+get_invalid_inet_option(Socket) ->
+ {error, {options, {socket_options, foo, _}}} = ssl:getopts(Socket, [foo]),
+ ok.
+
+get_invalid_inet_option_not_list(Socket) ->
+ {error, {options, {socket_options, some_invalid_atom_here}}}
+ = ssl:getopts(Socket, some_invalid_atom_here),
+ ok.
+
+get_invalid_inet_option_improper_list(Socket) ->
+ {error, {options, {socket_options, foo,_}}} = ssl:getopts(Socket, [packet | foo]),
+ ok.
+
+set_invalid_inet_option(Socket) ->
+ {error, {options, {socket_options, {packet, foo}}}} = ssl:setopts(Socket, [{packet, foo}]),
+ {error, {options, {socket_options, {header, foo}}}} = ssl:setopts(Socket, [{header, foo}]),
+ {error, {options, {socket_options, {active, foo}}}} = ssl:setopts(Socket, [{active, foo}]),
+ {error, {options, {socket_options, {mode, foo}}}} = ssl:setopts(Socket, [{mode, foo}]),
+ ok.
+
+set_invalid_inet_option_not_list(Socket) ->
+ {error, {options, {not_a_proplist, some_invalid_atom_here}}}
+ = ssl:setopts(Socket, some_invalid_atom_here),
+ ok.
+
+set_invalid_inet_option_improper_list(Socket) ->
+ {error, {options, {not_a_proplist, [{packet, 0} | {foo, 2}]}}} =
+ ssl:setopts(Socket, [{packet, 0} | {foo, 2}]),
+ ok.
+
+wait_for_send(Socket) ->
+ %% Make sure TLS process processed send message event
+ _ = ssl:connection_information(Socket).
+