%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 2007-2009. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. %% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. %% %% %CopyrightEnd% %% %% -module(old_transport_accept_SUITE). -include("test_server.hrl"). -include("test_server_line.hrl"). %% Default timetrap timeout (set in init_per_testcase). -define(default_timeout, ?t:minutes(1)). -define(application, ssh). -export([all/1, init_per_testcase/2, fin_per_testcase/2, config/1, echo_once/1, echo_twice/1, close_before_ssl_accept/1, server/5, tolerant_server/5, client/5 ]). init_per_testcase(_Case, Config) -> WatchDog = ssl_test_lib:timetrap(?default_timeout), [{watchdog, WatchDog}, {protomod, gen_tcp}, {serialize_accept, true}| Config]. fin_per_testcase(_Case, Config) -> WatchDog = ?config(watchdog, Config), test_server:timetrap_cancel(WatchDog). all(doc) -> "Test transport_accept and ssl_accept"; all(suite) -> [config, echo_once, echo_twice, close_before_ssl_accept]. config(doc) -> "Want to se what Config contains."; config(suite) -> []; config(Config) -> io:format("Config: ~p~n", [Config]), ok. echo_once(doc) -> "Client sends 256 bytes to server, that receives them, sends them " "back, and closes. Client waits for close. Both have certs."; echo_once(suite) -> []; echo_once(Config) when list(Config) -> process_flag(trap_exit, true), LPort = 3456, {ok, Host} = inet:gethostname(), {ok, {COpts, SOpts}} = ssl_test_MACHINE:mk_ssl_cert_opts(Config), N = 1, Msg = lists:seq(0, 255), Self = self(), Params = "-pa " ++ filename:dirname(code:which(?MODULE)), Node = start_node(server, Params), CNode = start_node(client, Params), Server = spawn_link(Node, ?MODULE, server, [Self, LPort, SOpts, Msg, N]), Client = spawn_link(Node, ?MODULE, client, [Host, LPort, COpts, Msg, N]), ok = receive {Server, listening} -> Client ! {Server, listening}, ok; E -> io:format("bad receive (1) ~p\n", [E]), E end, receive {Server, done} -> ok end, test_server:stop_node(Node), test_server:stop_node(CNode). close_before_ssl_accept(doc) -> "Client sends 256 bytes to server, that receives them, sends them " "back, and closes. Client waits for close. Both have certs."; close_before_ssl_accept(suite) -> []; close_before_ssl_accept(Config) when list(Config) -> process_flag(trap_exit, true), LPort = 3456, {ok, Host} = inet:gethostname(), {ok, {COpts, SOpts}} = ssl_test_MACHINE:mk_ssl_cert_opts(Config), Msg = lists:seq(0, 255), Self = self(), Params = "-pa " ++ filename:dirname(code:which(?MODULE)), Node = start_node(server, Params), CNode = start_node(client, Params), Server = spawn_link(Node, ?MODULE, tolerant_server, [Self, LPort, SOpts, Msg, 2]), Client = spawn_link(Node, ?MODULE, client, [Host, LPort, COpts, Msg, 1]), ok = receive {Server, listening} -> {ok, S} = gen_tcp:connect(Host, LPort, []), gen_tcp:close(S), Client ! {Server, listening}, ok; E -> io:format("bad receive (1) ~p\n", [E]), E end, receive {Server, done} -> ok end, test_server:stop_node(Node), test_server:stop_node(CNode). client(Host, LPort, COpts, Msg, N) -> ok = receive {_Server, listening} -> ok; E -> io:format("bad receive (2) ~p\n", [E]), E end, Opts = COpts ++ [{packet, raw}, {active, false}], app(), lists:foreach(fun(_) -> {ok, S} = ssl:connect(Host, LPort, Opts), ssl:send(S, Msg), {ok, Msg} = ssl:recv(S, length(Msg)), ssl:close(S) end, lists:seq(1, N)). echo_twice(doc) -> "Two clients sends 256 bytes to server, that receives them, sends them " "back, and closes. Client waits for close. Both have certs."; echo_twice(suite) -> []; echo_twice(Config) when list(Config) -> process_flag(trap_exit, true), LPort = 3456, {ok, Host} = inet:gethostname(), {ok, {COpts, SOpts}} = ssl_test_MACHINE:mk_ssl_cert_opts(Config), N = 2, Msg = lists:seq(0, 255), Self = self(), Params = "-pa " ++ filename:dirname(code:which(?MODULE)), Node = start_node(server, Params), CNode = start_node(client, Params), Server = spawn_link(Node, ?MODULE, server, [Self, LPort, SOpts, Msg, N]), Client = spawn_link(Node, ?MODULE, client, [Host, LPort, COpts, Msg, N]), ok = receive {Server, listening} -> Client ! {Server, listening}, ok; E -> io:format("bad receive (3) ~p\n", [E]), E end, receive {Server, done} -> ok end, test_server:stop_node(Node), test_server:stop_node(CNode). server(Client, Port, SOpts, Msg, N) -> app(), process_flag(trap_exit, true), Opts = SOpts ++ [{packet, raw}, {active, false}], {ok, LSock} = ssl:listen(Port, Opts), Client ! {self(), listening}, server_loop(Client, LSock, Msg, N). server_loop(Client, _, _, 0) -> Client ! {self(), done}; server_loop(Client, LSock, Msg, N) -> {ok, S} = ssl:transport_accept(LSock), ok = ssl:ssl_accept(S), %% P = ssl:controlling_process(S, Proxy), {ok, Msg} = ssl:recv(S, length(Msg)), ok = ssl:send(S, Msg), ok = ssl:close(S), server_loop(Client, LSock, Msg, N-1). tolerant_server(Client, Port, SOpts, Msg, N) -> app(), process_flag(trap_exit, true), Opts = SOpts ++ [{packet, raw}, {active, false}], {ok, LSock} = ssl:listen(Port, Opts), Client ! {self(), listening}, tolerant_server_loop(Client, LSock, Msg, N). tolerant_server_loop(Client, _, _, 0) -> Client ! {self(), done}; tolerant_server_loop(Client, LSock, Msg, N) -> {ok, S} = ssl:transport_accept(LSock), case ssl:ssl_accept(S) of ok -> %% P = ssl:controlling_process(S, Proxy), {ok, Msg} = ssl:recv(S, length(Msg)), ok = ssl:send(S, Msg), ok = ssl:close(S); E -> io:format("ssl_accept error: ~p\n", [E]) end, tolerant_server_loop(Client, LSock, Msg, N-1). app() -> case application:get_application(ssl) of undefined -> application:start(ssl); _ -> ok end. start_node(Kind, Params) -> S = atom_to_list(?MODULE)++"_" ++ atom_to_list(Kind), {ok, Node} = test_server:start_node(list_to_atom(S), slave, [{args, Params}]), Node.