diff options
Diffstat (limited to 'lib/ssl/test/ssl_test_MACHINE.erl')
-rw-r--r-- | lib/ssl/test/ssl_test_MACHINE.erl | 940 |
1 files changed, 0 insertions, 940 deletions
diff --git a/lib/ssl/test/ssl_test_MACHINE.erl b/lib/ssl/test/ssl_test_MACHINE.erl deleted file mode 100644 index e0ffa15d80..0000000000 --- a/lib/ssl/test/ssl_test_MACHINE.erl +++ /dev/null @@ -1,940 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2003-2010. 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(ssl_test_MACHINE). - --export([many_conns/0, mk_ssl_cert_opts/1, test_one_listener/7, - test_server_only/6]). - --export([process_init/3, do_start/1]). - - --include("test_server.hrl"). --include("ssl_test_MACHINE.hrl"). - --define(WAIT_TIMEOUT, 10000). --define(CLOSE_WAIT, 1000). - -%% -%% many_conns() -> ManyConnections -%% -%% Choose a suitable number of "many connections" depending on platform -%% and current limit for file descriptors. -%% -many_conns() -> - case os:type() of - {unix,_} -> many_conns_1(); - _ -> 10 - end. - -many_conns_1() -> - N0 = os:cmd("ulimit -n"), - N1 = lists:reverse(N0), - N2 = lists:dropwhile(fun($\r) -> true; - ($\n) -> true; - (_) -> false - end, N1), - N = list_to_integer(lists:reverse(N2)), - lists:min([(N - 10) div 2, 501]). - -%% -%% mk_ssl_cert_opts(Config) -> {ok, {COpts, SOpts}} -%% -%% -mk_ssl_cert_opts(_Config) -> - Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), - COpts = [{ssl_imp, old}, - {cacertfile, filename:join([Dir, "client", "cacerts.pem"])}, - {certfile, filename:join([Dir, "client", "cert.pem"])}, - {keyfile, filename:join([Dir, "client", "key.pem"])}], - SOpts = [{ssl_imp, old}, - {cacertfile, filename:join([Dir, "server", "cacerts.pem"])}, - {certfile, filename:join([Dir, "server", "cert.pem"])}, - {keyfile, filename:join([Dir, "server", "key.pem"])}], - {ok, {COpts, SOpts}}. - -%% -%% Cmds: -%% {protomod, gen_tcp | ssl} default = ssl -%% {serialize_accept, true | false} default = false -%% {timeout, Timeout} -%% {sockopts, Opts} -%% {sslopts, Opts} -%% {protocols, Protocols} [sslv2|sslv3|tlsv1] -%% {listen, Port} -%% {lsock, LSock} listen socket for acceptor -%% peercert -%% accept -%% {connect, {Host, Port}} -%% {recv, N} -%% {send, N} -%% {echo, N} async echo back -%% close close connection socket -%% {close, Time} wait time and then close socket -%% lclose close listen socket -%% await_close wait for close -%% wait_sync listener's wait for sync from parent -%% connection_info -%% {exit, Reason} exit -%% -%% -%% We cannot have more than `backlog' acceptors at the same time. -%% - - -%% -%% test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, Suite, Config) -%% -%% Creates one client and one server node, and runs one listener on -%% the server node (according to LCmds), and creates NConns acceptors -%% on the server node, and the same number of connectors on the client -%% node. The acceptors and and connectors execute according to ACmds -%% and CCmds, respectively. -%% -%% It is a good idea to have the backlog size in LCmds set to -%% be at least as large as NConns. -%% -test_one_listener(NConns, LCmds0, ACmds0, CCmds0, Timeout, Suite, Config) -> - ProtoMod = get_protomod(Config), - SerializeAccept = get_serialize_accept(Config), - ?line {ok, {CNode, SNode}} = start_client_server_nodes(Suite), - case ProtoMod of - ssl -> - ?line ok = start_ssl([CNode, SNode], Config); - gen_tcp -> - ok - end, - LCmds = [{protomod, ProtoMod}| LCmds0], - ACmds = [{protomod, ProtoMod}, {serialize_accept, SerializeAccept}| - ACmds0], - CCmds = [{protomod, ProtoMod}| CCmds0], - - ?line {ok, Listener} = start_process(SNode, self(), LCmds, listener), - ?line {ok, LSock} = wait_lsock(Listener, ?WAIT_TIMEOUT), - ?line {ok, Accs0} = start_processes(NConns, SNode, self(), - [{lsock, LSock}| ACmds], acceptor), - Accs = case ProtoMod of - gen_tcp -> - [Acc1| Accs1] = Accs0, - Acc1 ! {continue_accept, self()}, - Accs1; - ssl -> - Accs0 - end, - ?line {ok, Conns} = start_processes(NConns, CNode, self(), - CCmds, connector), - ?line case wait_ack(Accs, Accs0 ++ Conns, Timeout) of - ok -> - ?line sync([Listener]), - ?line wait_ack([], [Listener], ?WAIT_TIMEOUT); - {error, Reason} -> - ?line stop_node(SNode), - ?line stop_node(CNode), - exit(Reason) - end, - ?line stop_node(SNode), - ?line stop_node(CNode), - ok. - -%% -%% test_server_only(NConns, LCmds, ACmds, Timeout, Suite, Config) -%% -%% Creates only one server node, and runs one listener on -%% the server node (according to LCmds), and creates NConns acceptors -%% on the server node. The acceptors execute according to ACmds. -%% There are no connectors. -%% -test_server_only(NConns, LCmds0, ACmds0, Timeout, Suite, Config) -> - ProtoMod = get_protomod(Config), - ?line {ok, SNode} = start_server_node(Suite), - case ProtoMod of - ssl -> - ?line ok = start_ssl([SNode], Config); - gen_tcp -> - ok - end, - LCmds = [{protomod, ProtoMod}| LCmds0], - ACmds = [{protomod, ProtoMod}| ACmds0], - ?line {ok, Listener} = start_process(SNode, self(), LCmds, listener), - ?line {ok, LSock} = wait_lsock(Listener, ?WAIT_TIMEOUT), - ?line {ok, Accs0} = start_processes(NConns, SNode, self(), - [{lsock, LSock}| ACmds], acceptor), - Accs = case ProtoMod of - gen_tcp -> - [Acc1| Accs1] = Accs0, - Acc1 ! {continue_accept, self()}, - Accs1; - ssl -> - Accs0 - end, - ?line case wait_ack(Accs, Accs0, Timeout) of - ok -> - ?line sync([Listener]), - ?line wait_ack([], [Listener], ?WAIT_TIMEOUT); - {error, Reason} -> - ?line stop_node(SNode), - exit(Reason) - end, - ?line stop_node(SNode), - ok. - -%% -%% start_client_server_nodes(Suite) -> {ok, {CNode, SNode}} -%% -start_client_server_nodes(Suite) -> - {ok, CNode} = start_client_node(Suite), - {ok, SNode} = start_server_node(Suite), - {ok, {CNode, SNode}}. - -start_client_node(Suite) -> - start_node(lists:concat([Suite, "_client"])). - -start_server_node(Suite) -> - start_node(lists:concat([Suite, "_server"])). - -%% -%% start_ssl(Nodes, Config) -%% -start_ssl(Nodes, Config) -> - Env0 = lists:flatten([Env00 || {env, Env00} <- Config]), - Env1 = case os:getenv("SSL_DEBUG") of - false -> - []; - _ -> - Dir = ?config(priv_dir, Config), - [{debug, true}, {debugdir, Dir}] - end, - Env = Env0 ++ Env1, - lists:foreach( - fun(Node) -> rpc:call(Node, ?MODULE, do_start, [Env]) end, Nodes), - ok. - -do_start(Env) -> - application:start(crypto), - application:start(public_key), - application:load(ssl), - lists:foreach( - fun({Par, Val}) -> application:set_env(ssl, Par, Val) end, Env), - application:start(ssl). - - -%% -%% start_node(Name) -> {ok, Node} -%% start_node(Name, ExtraParams) -> {ok, Node} -%% -start_node(Name) -> - start_node(Name, []). -start_node(Name, ExtraParams) -> - Params = "-pa " ++ filename:dirname(code:which(?MODULE)) ++ " " ++ - ExtraParams, - test_server:start_node(Name, slave, [{args, Params}]). - -stop_node(Node) -> - test_server:stop_node(Node). - -%% -%% start_processes(N, Node, Parent, Cmds, Type) -> {ok, Pids} -%% -start_processes(M, Node, Parent, Cmds, Type) -> - start_processes1(0, M, Node, Parent, Cmds, Type, []). -start_processes1(M, M, _, _, _, _, Pids) -> - {ok, lists:reverse(Pids)}; -start_processes1(N, M, Node, Parent, Cmds, Type, Pids) -> - {ok, Pid} = start_process(Node, Parent, Cmds, {Type, N + 1}), - start_processes1(N + 1, M, Node, Parent, Cmds, Type, [Pid| Pids]). - -%% -%% start_process(Node, Parent, Cmds, Type) -> {ok, Pid} -%% -start_process(Node, Parent, Cmds0, Type) -> - Cmds = case os:type() of - {win32, _} -> - lists:map(fun(close) -> {close, ?CLOSE_WAIT}; - (Term) -> Term end, Cmds0); - _ -> - Cmds0 - end, - Pid = spawn_link(Node, ?MODULE, process_init, [Parent, Cmds, Type]), - {ok, Pid}. - -process_init(Parent, Cmds, Type) -> - ?debug("#### ~w start~n", [{Type, self()}]), - pre_main_loop(Cmds, #st{parent = Parent, type = Type}). - -%% -%% pre_main_loop -%% -pre_main_loop([], St) -> - ?debug("#### ~w end~n", [{St#st.type, self()}]), - main_loop([], St); -pre_main_loop(Cmds, St) -> - ?debug("#### ~w -> ~w~n", - [{St#st.type, self(), St#st.sock, St#st.port, - St#st.peer, St#st.active}, hd(Cmds)]), - main_loop(Cmds, St). - -%% -%% main_loop(Cmds, St) -%% -main_loop([{protomod, ProtoMod}| Cmds], St) -> - pre_main_loop(Cmds, St#st{protomod = ProtoMod}); - -main_loop([{serialize_accept, Bool}| Cmds], St) -> - pre_main_loop(Cmds, St#st{serialize_accept = Bool}); - -main_loop([{sockopts, Opts}| Cmds], St) -> - pre_main_loop(Cmds, St#st{sockopts = Opts}); - -main_loop([{sslopts, Opts}| Cmds], St) -> - pre_main_loop(Cmds, St#st{sslopts = Opts}); - -main_loop([{protocols, Protocols}| Cmds], St) -> - pre_main_loop(Cmds, St#st{protocols = Protocols}); - -main_loop([{timeout, T}| Cmds], St) -> - pre_main_loop(Cmds, St#st{timeout = T}); - -main_loop([{lsock, LSock}| Cmds], St) -> - pre_main_loop(Cmds, St#st{lsock = LSock}); - -main_loop([{seed, Data}| Cmds], St) -> - case ssl:seed("tjosan") of - ok -> - pre_main_loop(Cmds, St); - {error, Reason} -> - ?error("#### ~w(~w) in seed: error: ~w~n", - [St#st.type, self(), Reason]), - exit(Reason) - end; - -main_loop([{listen, Port}| Cmds], St) -> - case listen(St, Port) of - {ok, LSock} -> - ack_lsock(St#st.parent, LSock), - NSt = get_active(St#st{port = Port, sock = LSock, lsock = LSock}), - pre_main_loop(Cmds, St); - {error, Reason} -> - ?error("#### ~w(~w) in listen: error: ~w~n", - [St#st.type, self(), Reason]), - exit(Reason) - end; - -main_loop([accept| Cmds], St) -> - case St#st.serialize_accept of - true -> - Parent = St#st.parent, - receive - {continue_accept, Parent} -> - ok - end; - false -> - ok - end, - case accept(St) of - {ok, Sock, Port, Peer} -> - case St#st.serialize_accept of - true -> - St#st.parent ! {one_accept_done, self()}; - false -> - ok - end, - NSt = get_active(St#st{sock = Sock, port = Port, peer = Peer}), - pre_main_loop(Cmds, NSt); - {error, Reason} -> - ?error("#### ~w(~w) in accept: error: ~w~n", - [St#st.type, self(), Reason]), - exit(Reason) - end; - -main_loop([accept_timeout| Cmds], St) -> - case accept(St) of - {error, timeout} -> - pre_main_loop(Cmds, St); - {error, Reason} -> - ?error("#### ~w(~w) in accept_timeout: error: ~w~n", - [St#st.type, self(), Reason]), - exit(Reason) - end; - - -main_loop([{connect, {Host, Port}}| Cmds], St) -> - case connect(St, Host, Port) of - {ok, Sock, LPort, Peer} -> - NSt = get_active(St#st{sock = Sock, port = LPort, peer = Peer}), - pre_main_loop(Cmds, NSt); - {error, Reason} -> - ?error("#### ~w(~w) in connect: error: ~w~n", - [St#st.type, self(), Reason]), - exit(Reason) - end; - -main_loop([connection_info| Cmds], St) -> - case connection_info(St) of - {ok, ProtoInfo} -> - io:fwrite("Got connection_info:~n~p~n", [ProtoInfo]), - pre_main_loop(Cmds, St); - {error, Reason} -> - ?error("#### ~w(~w) in connection_info: error: ~w~n", - [St#st.type, self(), Reason]), - exit(Reason) - end; - -main_loop([peercert| Cmds], St) -> - case peercert(St) of - {ok, Cert} -> - io:fwrite("Got cert:~n~p~n", [Cert]), - pre_main_loop(Cmds, St); - {error, Reason} -> - ?error("#### ~w(~w) in peercert: error: ~w~n", - [St#st.type, self(), Reason]), - exit(Reason) - end; - -main_loop([nopeercert| Cmds], St) -> - case peercert(St) of - {error, Reason} -> - io:fwrite("Got no cert as expected. reason:~n~p~n", [Reason]), - pre_main_loop(Cmds, St); - {ok, Cert} -> - ?error("#### ~w(~w) in peercert: error: got cert: ~p~n", - [St#st.type, self(), Cert]), - exit(peercert) - end; - -main_loop([{recv, N}| Cmds], St) -> - recv_loop([{recv, N}| Cmds], fun recv/1, St); % Returns to main_loop/2. - -main_loop([{send, N}| Cmds], St) -> - Msg = mk_msg(N), - case send(St, Msg) of - ok -> - pre_main_loop(Cmds, St); - {error, Reason} -> - ?error("#### ~w(~w) in send: error: ~w~n", - [St#st.type, self(), Reason]), - exit(Reason) - end; - -main_loop([{echo, N}| Cmds], St) -> - recv_loop([{echo, N}| Cmds], fun echo/1, St); % Returns to main_loop/2. - -main_loop([{close, WaitTime}| Cmds], St) -> - wait(WaitTime), - pre_main_loop([close| Cmds], St); - -main_loop([close| Cmds], St) -> - case close(St) of - ok -> - pre_main_loop(Cmds, St#st{sock = nil}); - {error, Reason} -> - ?error("#### ~w(~w) in close: error: ~w~n", - [St#st.type, self(), Reason]), - exit(Reason) - end; - -main_loop([lclose| Cmds], St) -> - case lclose(St) of - ok -> - pre_main_loop(Cmds, St#st{lsock = nil}); - {error, Reason} -> - ?error("#### ~w(~w) in lclose: error: ~w~n", - [St#st.type, self(), Reason]), - exit(Reason) - end; - -main_loop([await_close| Cmds], St) -> - case await_close(St) of - ok -> - pre_main_loop(Cmds, St#st{sock = nil}); - {error, Reason} -> - ?error("#### ~w(~w) in await_close: error: ~w~n", - [St#st.type, self(), Reason]), - exit(Reason) - end; - -main_loop([wait_sync| Cmds], St) -> - wait_sync(St), - pre_main_loop(Cmds, St); - -main_loop({exit, Reason}, _St) -> - exit(Reason); - -main_loop([], _St) -> - ok. - -%% -%% recv_loop(Cmds, F, St) -%% -%% F = recv/1 | echo/1 -%% -recv_loop([{_Tag, 0}| Cmds], _, St) -> - pre_main_loop(Cmds, St); -recv_loop([{_Tag, N}| _Cmds], _, St) when N < 0 -> - ?error("#### ~w(~w) in recv_loop: error: too much: ~w~n", - [St#st.type, self(), N]), - exit(toomuch); % XXX or {error, Reason}? -recv_loop([{Tag, N}| Cmds], F, St) -> - case F(St) of - {ok, Len} -> - NSt = St#st{active = new_active(St#st.active)}, - if - Len == N -> - pre_main_loop(Cmds, NSt); - true -> - ?debug("#### ~w -> ~w~n", - [{NSt#st.type, self(), NSt#st.sock, NSt#st.port, - NSt#st.peer, NSt#st.active}, {Tag, N - Len}]), - recv_loop([{Tag, N - Len}| Cmds], F, NSt) - end; - {error, Reason} -> - ?error("#### ~w(~w) in recv_loop: error: ~w, ~w bytes remain~n", - [St#st.type, self(), Reason, N]), - exit(Reason) - end. - -new_active(once) -> - false; -new_active(A) -> - A. - -get_active(St) -> - A = case proplists:get_value(active, St#st.sockopts, undefined) of - undefined -> - Mod = case St#st.protomod of - ssl -> - ssl; - gen_tcp -> - inet - end, - {ok, [{active, Ax}]} = Mod:getopts(St#st.sock, [active]), - Ax; - Ay -> - Ay - end, - ?debug("#### ~w(~w) get_active: ~p\n", [St#st.type, self(), A]), - St#st{active = A}. - - -%% -%% SOCKET FUNCTIONS -%% - -%% -%% ssl -%% - -%% -%% listen(St, LPort) -> {ok, LSock} | {error, Reason} -%% -listen(St, LPort) -> - case St#st.protomod of - ssl -> - ssl:listen(LPort, [{ssl_imp, old} | St#st.sockopts ++ St#st.sslopts]); - gen_tcp -> - gen_tcp:listen(LPort, St#st.sockopts) - end. - -%% -%% accept(St) -> {ok, Sock} | {error, Reason} -%% -accept(St) -> - case St#st.protomod of - ssl -> - case ssl:transport_accept(St#st.lsock, St#st.timeout) of - {ok, Sock} -> - case ssl:ssl_accept(Sock, St#st.timeout) of - ok -> - {ok, Port} = ssl:sockname(Sock), - {ok, Peer} = ssl:peername(Sock), - {ok, Sock, Port, Peer}; - Other -> - Other - end; - Other -> - Other - end; - gen_tcp -> - case gen_tcp:accept(St#st.lsock, St#st.timeout) of - {ok, Sock} -> - {ok, Port} = inet:port(Sock), - {ok, Peer} = inet:peername(Sock), - {ok, Sock, Port, Peer}; - Other -> - Other - end - end. - -%% -%% connect(St, Host, Port) -> {ok, Sock} | {error, Reason} -%% -connect(St, Host, Port) -> - - case St#st.protomod of - ssl -> - case ssl:connect(Host, Port, - [{ssl_imp, old} | St#st.sockopts ++ St#st.sslopts], - St#st.timeout) of - {ok, Sock} -> - {ok, LPort} = ssl:sockname(Sock), - {ok, Peer} = ssl:peername(Sock), - {ok, Sock, LPort, Peer}; - Other -> - Other - end; - gen_tcp -> - case gen_tcp:connect(Host, Port, St#st.sockopts, St#st.timeout) of - {ok, Sock} -> - {ok, LPort} = inet:port(Sock), - {ok, Peer} = inet:peername(Sock), - {ok, Sock, LPort, Peer}; - Other -> - Other - end - end. - -%% -%% peercert(St) -> {ok, Cert} | {error, Reason} -%% -peercert(St) -> - case St#st.protomod of - ssl -> - ssl:peercert(St#st.sock, [ssl]); - gen_tcp -> - {ok, <<>>} - end. - -%% -%% connection_info(St) -> {ok, ProtoInfo} | {error, Reason} -%% -connection_info(St) -> - case St#st.protomod of - ssl -> - case ssl:connection_info(St#st.sock) of - Res = {ok, {Proto, _}} -> - case St#st.protocols of - [] -> - Res; - Protocols -> - case lists:member(Proto, Protocols) of - true -> - Res; - false -> - {error, Proto} - end - end; - Error -> - Error - end; - gen_tcp -> - {ok, <<>>} - end. - -%% -%% close(St) -> ok | {error, Reason} -%% - -close(St) -> - Mod = St#st.protomod, - case St#st.sock of - nil -> - ok; - _ -> - Mod:close(St#st.sock) - end. - -%% -%% lclose(St) -> ok | {error, Reason} -%% -lclose(St) -> - Mod = St#st.protomod, - case St#st.lsock of - nil -> - ok; - _ -> - Mod:close(St#st.lsock) - end. - -%% -%% recv(St) = {ok, Len} | {error, Reason} -%% -recv(St) -> - case do_recv(St) of - {ok, Msg} -> - {ok, length(Msg)}; - {error, Reason} -> - {error, Reason} - end. - -do_recv(St) when St#st.active == false -> - %% First check that we do *not* have any ssl/gen_tcp messages in the - %% message queue, then call the receive function. - Sock = St#st.sock, - case St#st.protomod of - ssl -> - receive - M = {ssl, Sock, _Msg} -> - {error, {unexpected_messagex, M}}; - M = {ssl_closed, Sock} -> - {error, {unexpected_message, M}}; - M = {ssl_error, Sock, _Reason} -> - {error, {unexpected_message, M}} - after 0 -> - ssl:recv(St#st.sock, 0, St#st.timeout) - end; - gen_tcp -> - receive - M = {tcp, Sock, _Msg} -> - {error, {unexpected_message, M}}; - M = {tcp_closed, Sock} -> - {error, {unexpected_message, M}}; - M = {tcp_error, Sock, _Reason} -> - {error, {unexpected_message, M}} - after 0 -> - gen_tcp:recv(St#st.sock, 0, St#st.timeout) - end - end; -do_recv(St) -> - Sock = St#st.sock, - Timeout = St#st.timeout, - case St#st.protomod of - ssl -> - receive - {ssl, Sock, Msg} -> - {ok, Msg}; - {ssl_closed, Sock} -> - {error, closed}; - {ssl_error, Sock, Reason} -> - {error, Reason} - after Timeout -> - {error, timeout} - end; - gen_tcp -> - receive - {tcp, Sock, Msg} -> - {ok, Msg}; - {tcp_closed, Sock} -> - {error, closed}; - {tcp_error, Sock, Reason} -> - {error, Reason} - after Timeout -> - {error, timeout} - end - end. - -%% -%% echo(St) = {ok, Len} | {error, Reason} -%% -echo(St) -> - Sock = St#st.sock, - case do_recv(St) of - {ok, Msg} -> - Mod = St#st.protomod, - case Mod:send(Sock, Msg) of - ok -> - {ok, length(Msg)}; - {error, Reason} -> - {error, Reason} - end; - {error, Reason} -> - {error, Reason} - end. - -%% -%% send(St, Msg) -> ok | {error, Reason} -%% -send(St, Msg) -> - Mod = St#st.protomod, - Mod:send(St#st.sock, Msg). - -%% -%% await_close(St) -> ok | {error, Reason} -%% -await_close(St) when St#st.active == false -> - %% First check that we do *not* have any ssl/gen_tcp messages in the - %% message queue, then call the receive function. - Sock = St#st.sock, - Res = case St#st.protomod of - ssl -> - receive - M = {ssl, Sock, _Msg0} -> - {error, {unexpected_message, M}}; - M = {ssl_closed, Sock} -> - {error, {unexpected_message, M}}; - M = {ssl_error, Sock, _Reason} -> - {error, {unexpected_message, M}} - after 0 -> - ok - end; - gen_tcp -> - receive - M = {tcp, Sock, _Msg0} -> - {error, {unexpected_message, M}}; - M = {tcp_closed, Sock} -> - {error, {unexpected_message, M}}; - M = {tcp_error, Sock, _Reason} -> - {error, {unexpected_message, M}} - after 0 -> - ok - end - end, - case Res of - ok -> - Mod = St#st.protomod, - case Mod:recv(St#st.sock, 0, St#st.timeout) of - {ok, _Msg} -> - {error, toomuch}; - {error, _} -> - ok - end; - _ -> - Res - end; -await_close(St) -> - Sock = St#st.sock, - Timeout = St#st.timeout, - case St#st.protomod of - ssl -> - receive - {ssl, Sock, _Msg} -> - {error, toomuch}; - {ssl_closed, Sock} -> - ok; - {ssl_error, Sock, Reason} -> - {error, Reason} - after Timeout -> - {error, timeout} - end; - gen_tcp -> - receive - {tcp, Sock, _Msg} -> - {error, toomuch}; - {tcp_closed, Sock} -> - ok; - {tcp_error, Sock, Reason} -> - {error, Reason} - after Timeout -> - {error, timeout} - end - end. - - -%% -%% HELP FUNCTIONS -%% - -wait_ack(_, [], _) -> - ok; -wait_ack(AccPids0, Pids, Timeout) -> - ?debug("#### CONTROLLER: waiting for ~w~n", [Pids]), - receive - {one_accept_done, Pid} -> - case lists:delete(Pid, AccPids0) of - [] -> - wait_ack([], Pids, Timeout); - [AccPid| AccPids1] -> - AccPid ! {continue_accept, self()}, - wait_ack(AccPids1, Pids, Timeout) - end; - {'EXIT', Pid, normal} -> - wait_ack(AccPids0, lists:delete(Pid, Pids), Timeout); - {'EXIT', Pid, Reason} -> - ?error("#### CONTROLLER got abnormal exit: ~w, ~w~n", - [Pid, Reason]), - {error, Reason} - after Timeout -> - ?error("#### CONTROLLER exiting because of timeout = ~w~n", - [Timeout]), - {error, Timeout} - end. - - -%% -%% ack_lsock(Pid, LSock) -%% -ack_lsock(Pid, LSock) -> - Pid ! {lsock, self(), LSock}. - -wait_lsock(Pid, Timeout) -> - receive - {lsock, Pid, LSock} -> - {ok, LSock} - after Timeout -> - exit(timeout) - end. - -%% -%% sync(Pids) -%% -sync(Pids) -> - lists:foreach(fun (Pid) -> Pid ! {self(), sync} end, Pids). - -%% -%% wait_sync(St) -%% -wait_sync(St) -> - Pid = St#st.parent, - receive - {Pid, sync} -> - ok - end. - -%% -%% wait(Time) -%% -wait(Time) -> - receive - after Time -> - ok - end. - -%% -%% mk_msg(Size) -%% -mk_msg(Size) -> - mk_msg(0, Size, []). - -mk_msg(_, 0, Acc) -> - Acc; -mk_msg(Pos, Size, Acc) -> - C = (((Pos + Size) rem 256) - 1) band 255, - mk_msg(Pos, Size - 1, [C| Acc]). - -%% -%% get_protomod(Config) -%% -get_protomod(Config) -> - case lists:keysearch(protomod, 1, Config) of - {value, {_, ProtoMod}} -> - ProtoMod; - false -> - ssl - end. - -%% -%% get_serialize_accept(Config) -%% -get_serialize_accept(Config) -> - case lists:keysearch(serialize_accept, 1, Config) of - {value, {_, Val}} -> - Val; - false -> - false - end. - |