diff options
Diffstat (limited to 'lib/erl_interface/test/ei_tmo_SUITE.erl')
-rw-r--r-- | lib/erl_interface/test/ei_tmo_SUITE.erl | 779 |
1 files changed, 340 insertions, 439 deletions
diff --git a/lib/erl_interface/test/ei_tmo_SUITE.erl b/lib/erl_interface/test/ei_tmo_SUITE.erl index f506b3dbb0..4cd4202116 100644 --- a/lib/erl_interface/test/ei_tmo_SUITE.erl +++ b/lib/erl_interface/test/ei_tmo_SUITE.erl @@ -27,176 +27,148 @@ -define(dummy_host,test01). --export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, - init_per_testcase/2, end_per_testcase/2, - framework_check/1, ei_accept_tmo/1, ei_connect_tmo/1, ei_send_tmo/1, - ei_recv_tmo/1]). +-export([all/0, suite/0, + init_per_testcase/2, end_per_testcase/2, + framework_check/1, ei_accept_tmo/1, ei_connect_tmo/1, ei_send_tmo/1, + ei_recv_tmo/1]). -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap, {minutes, 1}}]. all() -> [framework_check, ei_accept_tmo, ei_connect_tmo, ei_send_tmo, ei_recv_tmo]. -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - init_per_testcase(_Case, Config) -> - Dog = ?t:timetrap(?t:minutes(1)), % test if platform is vxworks_simso - ?line {_,Host} = split(node()), + {_,Host} = split(node()), Bool = case atom_to_list(Host) of - [$v,$x,$s,$i,$m | _] -> true; - _ -> false - end, - [{vxsim,Bool},{watchdog, Dog}|Config]. - -end_per_testcase(_Case, Config) -> - Dog = ?config(watchdog, Config), - test_server:timetrap_cancel(Dog), + [$v,$x,$s,$i,$m | _] -> true; + _ -> false + end, + [{vxsim,Bool}|Config]. + +end_per_testcase(_Case, _Config) -> ok. -framework_check(doc) -> - ["Check the framework."]; -framework_check(suite) -> - []; +%% Check the framework. framework_check(Config) when is_list(Config) -> %%dbg:tracer(), %%dbg:p(self()), - ?line P = runner:start(?framework_check), - ?line runner:send_term(P,{hello,world}), - ?line {term, {hello,world}} = runner:get_term(P), - ?line runner:recv_eot(P), + P = runner:start(?framework_check), + runner:send_term(P,{hello,world}), + {term, {hello,world}} = runner:get_term(P), + runner:recv_eot(P), ok. -ei_recv_tmo(doc) -> - ["Check recv with timeouts."]; -ei_recv_tmo(suite) -> - []; +%% Check recv with timeouts. ei_recv_tmo(Config) when is_list(Config) -> - ?line do_one_recv(Config,c_node_recv_tmo_1), - ?line do_one_recv_failure(Config,c_node_recv_tmo_2), + do_one_recv(Config,c_node_recv_tmo_1), + do_one_recv_failure(Config,c_node_recv_tmo_2), ok. do_one_recv(Config,CNode) -> - ?line {_,Host} = split(node()), - ?line P1 = runner:start(?recv_tmo), - ?line runner:send_term(P1,{CNode, - erlang:get_cookie(), - node()}), - ?line {term, X} = runner:get_term(P1, 10000), - ?line true = is_integer(X), - ?line CNode1 = join(CNode,Host), - ?line Term1 = {hej,[hopp,{i,[lingon,"skogen"]}]}, - ?line {test,CNode1} ! Term1, - ?line {term, Term1} = runner:get_term(P1, 10000), - ?line runner:recv_eot(P1). - + {_,Host} = split(node()), + P1 = runner:start(?recv_tmo), + runner:send_term(P1,{CNode, + erlang:get_cookie(), + node()}), + {term, X} = runner:get_term(P1, 10000), + true = is_integer(X), + CNode1 = join(CNode,Host), + Term1 = {hej,[hopp,{i,[lingon,"skogen"]}]}, + {test,CNode1} ! Term1, + {term, Term1} = runner:get_term(P1, 10000), + runner:recv_eot(P1). + do_one_recv_failure(Config,CNode) -> - ?line P1 = runner:start(?recv_tmo), - ?line runner:send_term(P1,{CNode, - erlang:get_cookie(), - node()}), - ?line {term, X} = runner:get_term(P1, 10000), - ?line true = is_integer(X), - ?line {term, {Ret,ETimedout,ETimedout}} = runner:get_term(P1, 10000), - ?line true = (Ret < 0), - ?line runner:recv_eot(P1). - - -ei_send_tmo(doc) -> - ["Check send with timeouts."]; -ei_send_tmo(suite) -> - []; + P1 = runner:start(?recv_tmo), + runner:send_term(P1,{CNode, + erlang:get_cookie(), + node()}), + {term, X} = runner:get_term(P1, 10000), + true = is_integer(X), + {term, {Ret,ETimedout,ETimedout}} = runner:get_term(P1, 10000), + true = (Ret < 0), + runner:recv_eot(P1). + + +%% Check send with timeouts. ei_send_tmo(Config) when is_list(Config) -> %dbg:tracer(), %dbg:p(self()), - VxSim = ?config(vxsim, Config), - ?line register(ei_send_tmo_1,self()), - ?line do_one_send(Config,self(),c_node_send_tmo_1), - ?line do_one_send(Config,ei_send_tmo_1,c_node_send_tmo_2), - ?line do_one_send_failure(Config,self(),cccc1,c_nod_send_tmo_3,VxSim), - ?line do_one_send_failure(Config,ei_send_tmo_1,cccc2,c_nod_send_tmo_4,VxSim), + VxSim = proplists:get_value(vxsim, Config), + register(ei_send_tmo_1,self()), + do_one_send(Config,self(),c_node_send_tmo_1), + do_one_send(Config,ei_send_tmo_1,c_node_send_tmo_2), + do_one_send_failure(Config,self(),cccc1,c_nod_send_tmo_3,VxSim), + do_one_send_failure(Config,ei_send_tmo_1,cccc2,c_nod_send_tmo_4,VxSim), ok. - + do_one_send(Config,From,CNode) -> - ?line {_,Host} = split(node()), - ?line P1 = runner:start(?send_tmo), - ?line runner:send_term(P1,{CNode, - erlang:get_cookie(), - node()}), - ?line {term, X} = runner:get_term(P1, 10000), - ?line true = is_integer(X), - ?line CNode1 = join(CNode,Host), - ?line Term1 = {hej,[hopp,{i,[lingon,"skogen"]}]}, - ?line {test,CNode1} ! {From,1,Term1}, - ?line ok = receive - Term1 -> - ok - after 2000 -> - error - end, - ?line {term, 0} = runner:get_term(P1, 10000), - ?line runner:recv_eot(P1). + {_,Host} = split(node()), + P1 = runner:start(?send_tmo), + runner:send_term(P1,{CNode, + erlang:get_cookie(), + node()}), + {term, X} = runner:get_term(P1, 10000), + true = is_integer(X), + CNode1 = join(CNode,Host), + Term1 = {hej,[hopp,{i,[lingon,"skogen"]}]}, + {test,CNode1} ! {From,1,Term1}, + ok = receive + Term1 -> + ok + after 2000 -> + error + end, + {term, 0} = runner:get_term(P1, 10000), + runner:recv_eot(P1). do_one_send_failure(Config,From,FakeName,CName,VxSim) -> - ?line {_,Host} = split(node()), - ?line OurName = join(FakeName,Host), - ?line Node = join(CName,Host), - ?line LSocket = case gen_tcp:listen(0, [{active, false}, {packet,2}]) of - {ok, Socket} -> - ?line Socket; - Else -> - ?line exit(Else) - end, - ?line EpmdSocket = register(OurName, LSocket, 1, 5), - ?line P3 = runner:start(?send_tmo), - ?line Cookie = kaksmula_som_ingen_bryr_sig_om, - ?line runner:send_term(P3,{CName, - Cookie, - OurName}), - ?line SocketB = case gen_tcp:accept(LSocket) of - {ok, Socket1} -> - ?line Socket1; - Else2 -> - ?line exit(Else2) - end, - ?line {hidden,Node,5} = recv_name(SocketB), % See 1) - ?line send_status(SocketB, ok), - ?line MyChallengeB = gen_challenge(), - ?line send_challenge(SocketB, OurName, MyChallengeB, 5), - ?line HisChallengeB = recv_challenge_reply( - SocketB, - MyChallengeB, - Cookie), - ?line DigestB = gen_digest(HisChallengeB,Cookie), - ?line send_challenge_ack(SocketB, DigestB), - ?line inet:setopts(SocketB, [{active, false}, - {packet, 4}]), - ?line {term, X} = runner:get_term(P3, 10000), - ?line true = is_integer(X), - ?line Message = [112,term_to_binary({6,self(),'',test}), - term_to_binary({From,10000, - {app,["lapp",{sa,["att",du,{slapp, - sitta}]}]}})], - ?line gen_tcp:send(SocketB,Message), + {_,Host} = split(node()), + OurName = join(FakeName,Host), + Node = join(CName,Host), + LSocket = case gen_tcp:listen(0, [{active, false}, {packet,2}]) of + {ok, Socket} -> + Socket; + Else -> + exit(Else) + end, + EpmdSocket = register(OurName, LSocket, 1, 5), + P3 = runner:start(?send_tmo), + Cookie = kaksmula_som_ingen_bryr_sig_om, + runner:send_term(P3,{CName, + Cookie, + OurName}), + SocketB = case gen_tcp:accept(LSocket) of + {ok, Socket1} -> + Socket1; + Else2 -> + exit(Else2) + end, + {hidden,Node,5} = recv_name(SocketB), % See 1) + send_status(SocketB, ok), + MyChallengeB = gen_challenge(), + send_challenge(SocketB, OurName, MyChallengeB, 5), + HisChallengeB = recv_challenge_reply(SocketB, + MyChallengeB, + Cookie), + DigestB = gen_digest(HisChallengeB,Cookie), + send_challenge_ack(SocketB, DigestB), + inet:setopts(SocketB, [{active, false}, + {packet, 4}]), + {term, X} = runner:get_term(P3, 10000), + true = is_integer(X), + Message = [112,term_to_binary({6,self(),'',test}), + term_to_binary({From,10000, + {app,["lapp",{sa,["att",du,{slapp, + sitta}]}]}})], + gen_tcp:send(SocketB,Message), %% At this point the test program starts sending messages (max 10000). Since %% we're not receiving, eventually the send buffer fills up. Then no more @@ -204,152 +176,145 @@ do_one_send_failure(Config,From,FakeName,CName,VxSim) -> %% before this happens is returned in Iters. The timeout value for get_term/2 %% must be large enough so there's time for the select() to time out and %% the test program to return the error tuple (below). - Res0 = - if VxSim == false -> - ?line {term,{Res,ETO,Iters,ETO}} = runner:get_term(P3, 20000), - Res; - true -> % relax the test for vxsim - ?line case runner:get_term(P3, 20000) of - {term,{Res,ETO,Iters,ETO}} -> - Res; - {term,{Res,_,Iters,ETO}} -> % EIO? - Res - end - end, - ?line runner:recv_eot(P3), - ?line true = ((Res0 < 0) and (Iters > 0)), - ?line gen_tcp:close(SocketB), - ?line gen_tcp:close(EpmdSocket), + + Res0 = if VxSim == false -> + {term,{Res,ETO,Iters,ETO}} = runner:get_term(P3, 20000), + Res; + true -> % relax the test for vxsim + case runner:get_term(P3, 20000) of + {term,{Res,ETO,Iters,ETO}} -> + Res; + {term,{Res,_,Iters,_ETO}} -> % EIO? + Res + end + end, + runner:recv_eot(P3), + true = ((Res0 < 0) and (Iters > 0)), + gen_tcp:close(SocketB), + gen_tcp:close(EpmdSocket), ok. - -ei_connect_tmo(doc) -> - ["Check accept with timeouts."]; -ei_connect_tmo(suite) -> - []; + +%% Check accept with timeouts. ei_connect_tmo(Config) when is_list(Config) -> %dbg:tracer(), %dbg:p(self()), - VxSim = ?config(vxsim, Config), + VxSim = proplists:get_value(vxsim, Config), DummyNode = make_and_check_dummy(), - ?line P = runner:start(?connect_tmo), - ?line runner:send_term(P,{c_nod_connect_tmo_1, - kaksmula_som_ingen_bryr_sig_om, - DummyNode}), + P = runner:start(?connect_tmo), + runner:send_term(P,{c_nod_connect_tmo_1, + kaksmula_som_ingen_bryr_sig_om, + DummyNode}), ETimedout = - if VxSim == false -> - ?line {term,{-3,ETO,ETO}} = runner:get_term(P, 10000), - ?line ETO; - true -> % relax the test for vxsim - ?line case runner:get_term(P, 10000) of - {term,{-3,ETO,ETO}} -> - ?line ETO; - {term,{-1,_,ETO}} -> % EHOSTUNREACH = ok - ?line ETO - end - end, - ?line runner:recv_eot(P), - ?line P2 = runner:start(?connect_tmo), - ?line runner:send_term(P2,{c_nod_connect_tmo_2, - erlang:get_cookie(), - node()}), - ?line {term, X} = runner:get_term(P2, 10000), - ?line runner:recv_eot(P2), - ?line true = is_integer(X), + if VxSim == false -> + {term,{-3,ETO,ETO}} = runner:get_term(P, 10000), + ETO; + true -> % relax the test for vxsim + case runner:get_term(P, 10000) of + {term,{-3,ETO,ETO}} -> + ETO; + {term,{-1,_,ETO}} -> % EHOSTUNREACH = ok + ETO + end + end, + runner:recv_eot(P), + P2 = runner:start(?connect_tmo), + runner:send_term(P2,{c_nod_connect_tmo_2, + erlang:get_cookie(), + node()}), + {term, X} = runner:get_term(P2, 10000), + runner:recv_eot(P2), + true = is_integer(X), %% Aborted handshake test... - ?line {_,Host} = split(node()), - ?line OurName = join(cccc,Host), - ?line Node = join(c_nod_connect_tmo_3,Host), - ?line LSocket = case gen_tcp:listen(0, [{active, false}, {packet,2}]) of - {ok, Socket} -> - ?line Socket; - Else -> - ?line exit(Else) - end, - ?line EpmdSocket = register(OurName, LSocket, 1, 5), - ?line P3 = runner:start(?connect_tmo), - ?line Cookie = kaksmula_som_ingen_bryr_sig_om, - ?line runner:send_term(P3,{c_nod_connect_tmo_3, - Cookie, - OurName}), - ?line SocketB = case gen_tcp:accept(LSocket) of - {ok, Socket1} -> - ?line Socket1; - Else2 -> - ?line exit(Else2) - end, - ?line {hidden,Node,5} = recv_name(SocketB), % See 1) - ?line send_status(SocketB, ok), - ?line MyChallengeB = gen_challenge(), - ?line send_challenge(SocketB, OurName, MyChallengeB, 5), - ?line HisChallengeB = recv_challenge_reply( - SocketB, - MyChallengeB, - Cookie), - ?line {term,{-1,ETimedout,ETimedout}} = runner:get_term(P3, 10000), - ?line runner:recv_eot(P3), - ?line gen_tcp:close(SocketB), - ?line gen_tcp:close(EpmdSocket), + {_,Host} = split(node()), + OurName = join(cccc,Host), + Node = join(c_nod_connect_tmo_3,Host), + LSocket = case gen_tcp:listen(0, [{active, false}, {packet,2}]) of + {ok, Socket} -> + Socket; + Else -> + exit(Else) + end, + EpmdSocket = register(OurName, LSocket, 1, 5), + P3 = runner:start(?connect_tmo), + Cookie = kaksmula_som_ingen_bryr_sig_om, + runner:send_term(P3,{c_nod_connect_tmo_3, + Cookie, + OurName}), + SocketB = case gen_tcp:accept(LSocket) of + {ok, Socket1} -> + Socket1; + Else2 -> + exit(Else2) + end, + {hidden,Node,5} = recv_name(SocketB), % See 1) + send_status(SocketB, ok), + MyChallengeB = gen_challenge(), + send_challenge(SocketB, OurName, MyChallengeB, 5), + _HisChallengeB = recv_challenge_reply(SocketB, + MyChallengeB, + Cookie), + {term,{-1,ETimedout,ETimedout}} = runner:get_term(P3, 10000), + runner:recv_eot(P3), + gen_tcp:close(SocketB), + gen_tcp:close(EpmdSocket), ok. - -ei_accept_tmo(doc) -> - ["Check accept with timeouts."]; -ei_accept_tmo(suite) -> - []; + +%% Check accept with timeouts. ei_accept_tmo(Config) when is_list(Config) -> %%dbg:tracer(), %%dbg:p(self()), - ?line P = runner:start(?accept_tmo), - ?line runner:send_term(P,{c_nod_som_ingen_kontaktar_1, - kaksmula_som_ingen_bryr_sig_om}), - ?line {term,{-1,ETimedout,ETimedout}} = runner:get_term(P, 10000), - ?line runner:recv_eot(P), - ?line P2 = runner:start(?accept_tmo), - ?line runner:send_term(P2,{c_nod_som_vi_kontaktar_1, - erlang:get_cookie()}), - ?line receive after 1000 -> ok end, - ?line CNode1 = make_node(c_nod_som_vi_kontaktar_1), - ?line {ignored,CNode1} ! tjenare, - ?line {term, X} = runner:get_term(P2, 10000), - ?line runner:recv_eot(P2), - ?line true = is_integer(X), - ?line P3 = runner:start(?accept_tmo), - ?line runner:send_term(P3,{c_nod_som_vi_kontaktar_2, - erlang:get_cookie()}), - ?line receive after 1000 -> ok end, - ?line CNode2 = make_node(c_nod_som_vi_kontaktar_2), - ?line {NA,NB} = split(CNode2), - ?line {_,Host} = split(node()), - ?line OurName = join(ccc,Host), - ?line {port,PortNo,_} = erl_epmd:port_please(NA,NB), - ?line {ok, SocketA} = gen_tcp:connect(atom_to_list(NB),PortNo, - [{active,false}, - {packet,2}]), - ?line send_name(SocketA,OurName,5), - ?line ok = recv_status(SocketA), - ?line {hidden,Node,5,HisChallengeA} = recv_challenge(SocketA), % See 1) - ?line OurChallengeA = gen_challenge(), - ?line OurDigestA = gen_digest(HisChallengeA, erlang:get_cookie()), + P = runner:start(?accept_tmo), + runner:send_term(P,{c_nod_som_ingen_kontaktar_1, + kaksmula_som_ingen_bryr_sig_om}), + {term,{-1,ETimedout,ETimedout}} = runner:get_term(P, 10000), + runner:recv_eot(P), + P2 = runner:start(?accept_tmo), + runner:send_term(P2,{c_nod_som_vi_kontaktar_1, + erlang:get_cookie()}), + receive after 1000 -> ok end, + CNode1 = make_node(c_nod_som_vi_kontaktar_1), + {ignored,CNode1} ! tjenare, + {term, X} = runner:get_term(P2, 10000), + runner:recv_eot(P2), + true = is_integer(X), + P3 = runner:start(?accept_tmo), + runner:send_term(P3,{c_nod_som_vi_kontaktar_2, + erlang:get_cookie()}), + receive after 1000 -> ok end, + CNode2 = make_node(c_nod_som_vi_kontaktar_2), + {NA,NB} = split(CNode2), + {_,Host} = split(node()), + OurName = join(ccc,Host), + {port,PortNo,_} = erl_epmd:port_please(NA,NB), + {ok, SocketA} = gen_tcp:connect(atom_to_list(NB),PortNo, + [{active,false}, + {packet,2}]), + send_name(SocketA,OurName,5), + ok = recv_status(SocketA), + {hidden,_Node,5,HisChallengeA} = recv_challenge(SocketA), % See 1) + _OurChallengeA = gen_challenge(), + _OurDigestA = gen_digest(HisChallengeA, erlang:get_cookie()), %% Dont do the last two steps of the connection setup... %% send_challenge_reply(SocketA, OurChallengeA, OurDigestA), %% ok = recv_challenge_ack(SocketA, OurChallengeA, erlang:get_cookie()), - ?line {term, {-1,ETimedout,ETimedout}} = runner:get_term(P3, 10000), - ?line runner:recv_eot(P3), - ?line gen_tcp:close(SocketA), + {term, {-1,ETimedout,ETimedout}} = runner:get_term(P3, 10000), + runner:recv_eot(P3), + gen_tcp:close(SocketA), ok. make_node(X) -> list_to_atom(atom_to_list(X) ++ "@" ++ - hd(tl(string:tokens(atom_to_list(node()),"@")))). + hd(tl(string:tokens(atom_to_list(node()),"@")))). make_and_check_dummy() -> % First check that the host has an ip and is *not* reachable - ?line case gen_tcp:connect(?dummy_host,23,[{active,false}],5000) of - {error,timeout} -> ok; - {error,ehostunreach} -> ok - end, + case gen_tcp:connect(?dummy_host,23,[{active,false}],5000) of + {error,timeout} -> ok; + {error,ehostunreach} -> ok + end, list_to_atom("dummy@"++atom_to_list(?dummy_host)). @@ -359,12 +324,12 @@ make_and_check_dummy() -> %% -define(to_port(Socket, Data), - case inet_tcp:send(Socket, Data) of - {error, closed} -> - self() ! {tcp_closed, Socket}, - {error, closed}; - R -> - R + case inet_tcp:send(Socket, Data) of + {error, closed} -> + self() ! {tcp_closed, Socket}, + {error, closed}; + R -> + R end). -define(DFLAG_PUBLISHED,1). @@ -382,8 +347,8 @@ make_and_check_dummy() -> -define(int16(X), [((X) bsr 8) band 16#ff, (X) band 16#ff]). -define(int32(X), - [((X) bsr 24) band 16#ff, ((X) bsr 16) band 16#ff, - ((X) bsr 8) band 16#ff, (X) band 16#ff]). + [((X) bsr 24) band 16#ff, ((X) bsr 16) band 16#ff, + ((X) bsr 8) band 16#ff, (X) band 16#ff]). -define(i16(X1,X0), (?u16(X1,X0) - @@ -406,9 +371,9 @@ make_and_check_dummy() -> %% This is no proper random number, but that is not really important in %% this test gen_challenge() -> - {_,_,N} = erlang:now(), + {_,_,N} = os:timestamp(), N. - + %% Generate a message digest from Challenge number and Cookie gen_digest(Challenge, Cookie) when is_integer(Challenge), is_atom(Cookie) -> C0 = erlang:md5_init(), @@ -423,95 +388,93 @@ gen_digest(Challenge, Cookie) when is_integer(Challenge), is_atom(Cookie) -> send_status(Socket, Stat) -> case gen_tcp:send(Socket, [$s | atom_to_list(Stat)]) of - {error, _} -> - ?shutdown(could_not_send_status); - _ -> - true + {error, _} -> ?shutdown(could_not_send_status); + _ -> true end. recv_status(Socket) -> case gen_tcp:recv(Socket, 0) of - {ok, [$s|StrStat]} -> - list_to_atom(StrStat); - Bad -> - exit(Bad) + {ok, [$s|StrStat]} -> + list_to_atom(StrStat); + Bad -> + exit(Bad) end. send_challenge(Socket, Node, Challenge, Version) -> send_challenge(Socket, Node, Challenge, Version, ?COMPULSORY_DFLAGS). send_challenge(Socket, Node, Challenge, Version, Flags) -> - {ok, {{Ip1,Ip2,Ip3,Ip4}, _}} = inet:sockname(Socket), + {ok, {{_Ip1,_Ip2,_Ip3,_Ip4}, _}} = inet:sockname(Socket), ?to_port(Socket, [$n,?int16(Version),?int32(Flags), - ?int32(Challenge), atom_to_list(Node)]). + ?int32(Challenge), atom_to_list(Node)]). recv_challenge(Socket) -> case gen_tcp:recv(Socket, 0) of - {ok,[$n,V1,V0,Fl1,Fl2,Fl3,Fl4,CA3,CA2,CA1,CA0 | Ns]} -> - Flags = ?u32(Fl1,Fl2,Fl3,Fl4), - Type = case Flags band ?DFLAG_PUBLISHED of - 0 -> - hidden; - _ -> - normal - end, - Node =list_to_atom(Ns), - Version = ?u16(V1,V0), - Challenge = ?u32(CA3,CA2,CA1,CA0), - {Type,Node,Version,Challenge}; - _ -> - ?shutdown(no_node) + {ok,[$n,V1,V0,Fl1,Fl2,Fl3,Fl4,CA3,CA2,CA1,CA0 | Ns]} -> + Flags = ?u32(Fl1,Fl2,Fl3,Fl4), + Type = case Flags band ?DFLAG_PUBLISHED of + 0 -> + hidden; + _ -> + normal + end, + Node =list_to_atom(Ns), + Version = ?u16(V1,V0), + Challenge = ?u32(CA3,CA2,CA1,CA0), + {Type,Node,Version,Challenge}; + _ -> + ?shutdown(no_node) end. -send_challenge_reply(Socket, Challenge, Digest) -> - ?to_port(Socket, [$r,?int32(Challenge),Digest]). +%send_challenge_reply(Socket, Challenge, Digest) -> +% ?to_port(Socket, [$r,?int32(Challenge),Digest]). recv_challenge_reply(Socket, ChallengeA, Cookie) -> case gen_tcp:recv(Socket, 0) of - {ok,[$r,CB3,CB2,CB1,CB0 | SumB]} when length(SumB) == 16 -> - SumA = gen_digest(ChallengeA, Cookie), - ChallengeB = ?u32(CB3,CB2,CB1,CB0), - if SumB == SumA -> - ChallengeB; - true -> - ?shutdown(bad_challenge_reply) - end; - _ -> - ?shutdown(no_node) + {ok,[$r,CB3,CB2,CB1,CB0 | SumB]} when length(SumB) == 16 -> + SumA = gen_digest(ChallengeA, Cookie), + ChallengeB = ?u32(CB3,CB2,CB1,CB0), + if SumB == SumA -> + ChallengeB; + true -> + ?shutdown(bad_challenge_reply) + end; + _ -> + ?shutdown(no_node) end. send_challenge_ack(Socket, Digest) -> ?to_port(Socket, [$a,Digest]). -recv_challenge_ack(Socket, ChallengeB, CookieA) -> - case gen_tcp:recv(Socket, 0) of - {ok,[$a | SumB]} when length(SumB) == 16 -> - SumA = gen_digest(ChallengeB, CookieA), - if SumB == SumA -> - ok; - true -> - ?shutdown(bad_challenge_ack) - end; - _ -> - ?shutdown(bad_challenge_ack) - end. +%recv_challenge_ack(Socket, ChallengeB, CookieA) -> +% case gen_tcp:recv(Socket, 0) of +% {ok,[$a | SumB]} when length(SumB) == 16 -> +% SumA = gen_digest(ChallengeB, CookieA), +% if SumB == SumA -> +% ok; +% true -> +% ?shutdown(bad_challenge_ack) +% end; +% _ -> +% ?shutdown(bad_challenge_ack) +% end. send_name(Socket, MyNode0, Version) -> send_name(Socket, MyNode0, Version, ?COMPULSORY_DFLAGS). send_name(Socket, MyNode0, Version, Flags) -> MyNode = atom_to_list(MyNode0), ?to_port(Socket, [$n,?int16(Version),?int32(Flags)] ++ - MyNode). + MyNode). %% %% recv_name is common for both old and new handshake. %% recv_name(Socket) -> case gen_tcp:recv(Socket, 0) of - {ok,Data} -> - get_name(Data); - Res -> - ?shutdown({no_node,Res}) + {ok,Data} -> + get_name(Data); + Res -> + ?shutdown({no_node,Res}) end. get_name([$m,VersionA,VersionB,_Ip1,_Ip2,_Ip3,_Ip4|OtherNode]) -> @@ -520,11 +483,9 @@ get_name([$h,VersionA,VersionB,_Ip1,_Ip2,_Ip3,_Ip4|OtherNode]) -> {hidden, list_to_atom(OtherNode), ?u16(VersionA,VersionB)}; get_name([$n,VersionA, VersionB, Flag1, Flag2, Flag3, Flag4 | OtherNode]) -> Type = case ?u32(Flag1, Flag2, Flag3, Flag4) band ?DFLAG_PUBLISHED of - 0 -> - hidden; - _ -> - normal - end, + 0 -> hidden; + _ -> normal + end, {Type, list_to_atom(OtherNode), ?u16(VersionA,VersionB)}; get_name(Data) -> @@ -533,74 +494,73 @@ get_name(Data) -> %% %% tell_name is for old handshake %% -tell_name(Socket, MyNode0, Version) -> - MyNode = atom_to_list(MyNode0), - {ok, {{Ip1,Ip2,Ip3,Ip4}, _}} = inet:sockname(Socket), - ?to_port(Socket, [$h,?int16(Version),Ip1,Ip2,Ip3,Ip4] ++ - MyNode). +%tell_name(Socket, MyNode0, Version) -> +% MyNode = atom_to_list(MyNode0), +% {ok, {{Ip1,Ip2,Ip3,Ip4}, _}} = inet:sockname(Socket), +% ?to_port(Socket, [$h,?int16(Version),Ip1,Ip2,Ip3,Ip4] ++ MyNode). %% %% The communication with EPMD follows %% do_register_node(NodeName, TcpPort, VLow, VHigh) -> case gen_tcp:connect({127,0,0,1}, get_epmd_port(), []) of - {ok, Socket} -> - {N0,_} = split(NodeName), - Name = atom_to_list(N0), - Extra = "", - Elen = length(Extra), - Len = 1+2+1+1+2+2+2+length(Name)+2+Elen, - gen_tcp:send(Socket, [?int16(Len), $x, - ?int16(TcpPort), - $M, - 0, - ?int16(VHigh), - ?int16(VLow), - ?int16(length(Name)), - Name, - ?int16(Elen), - Extra]), - case wait_for_reg_reply(Socket, []) of - {error, epmd_close} -> - exit(epmd_broken); - Other -> - Other - end; - Error -> - Error + {ok, Socket} -> + {N0,_} = split(NodeName), + Name = atom_to_list(N0), + Extra = "", + Elen = length(Extra), + Len = 1+2+1+1+2+2+2+length(Name)+2+Elen, + gen_tcp:send(Socket, [?int16(Len), $x, + ?int16(TcpPort), + $M, + 0, + ?int16(VHigh), + ?int16(VLow), + ?int16(length(Name)), + Name, + ?int16(Elen), + Extra]), + case wait_for_reg_reply(Socket, []) of + {error, epmd_close} -> + exit(epmd_broken); + Other -> + Other + end; + Error -> + Error end. wait_for_reg_reply(Socket, SoFar) -> receive - {tcp, Socket, Data0} -> - case SoFar ++ Data0 of - [$y, Result, A, B] -> - case Result of - 0 -> - {alive, Socket, ?u16(A, B)}; - _ -> - {error, duplicate_name} - end; - Data when length(Data) < 4 -> - wait_for_reg_reply(Socket, Data); - Garbage -> - {error, {garbage_from_epmd, Garbage}} - end; - {tcp_closed, Socket} -> - {error, epmd_close} + {tcp, Socket, Data0} -> + case SoFar ++ Data0 of + [$y, Result, A, B] -> + case Result of + 0 -> + {alive, Socket, ?u16(A, B)}; + _ -> + {error, duplicate_name} + end; + Data when length(Data) < 4 -> + wait_for_reg_reply(Socket, Data); + Garbage -> + {error, {garbage_from_epmd, Garbage}} + end; + {tcp_closed, Socket} -> + {error, epmd_close} after 10000 -> - gen_tcp:close(Socket), - {error, no_reg_reply_from_epmd} + gen_tcp:close(Socket), + {error, no_reg_reply_from_epmd} end. register(NodeName, ListenSocket, VLow, VHigh) -> {ok,{_,TcpPort}} = inet:sockname(ListenSocket), case do_register_node(NodeName, TcpPort, VLow, VHigh) of - {alive, Socket, Creation} -> - Socket; - Other -> - exit(Other) + {alive, Socket, _Creation} -> + Socket; + Other -> + exit(Other) end. @@ -618,69 +578,10 @@ split(Atom) -> {A,B} = split(atom_to_list(Atom),[]), {list_to_atom(A),list_to_atom(B)}. -%% Build a simple distribution message -build_message(Cookie) -> - [$?,term_to_binary({6,self(),Cookie,rex}),term_to_binary(plupp)]. - -%% Build a distribution message that will make rex answer -build_rex_message(Cookie,OurName) -> - [$?,term_to_binary({6,self(),Cookie,rex}), - term_to_binary({'$gen_cast', - {cast, - rpc, - cast, - [OurName, hello, world, []], - self()} })]. - -%% Receive a distribution message -recv_message(Socket) -> - case gen_tcp:recv(Socket, 0) of - {ok,Data} -> - B0 = list_to_binary(Data), - {_,B1} = erlang:split_binary(B0,1), - Header = erlang:binary_to_term(B1), - Siz = size(term_to_binary(Header)), - {_,B2} = erlang:split_binary(B1,Siz), - Message = case (catch erlang:binary_to_term(B2)) of - {'EXIT', _} -> - could_not_digest_message; - Other -> - Other - end, - {Header, Message}; - Res -> - exit({no_message,Res}) - end. - %% Build a nodename join(Name,Host) -> list_to_atom(atom_to_list(Name) ++ "@" ++ atom_to_list(Host)). -%% start/stop slave. -start_node(Name, Param) -> - ?t:start_node(Name, slave, [{args, Param}]). - -stop_node(Node) -> - ?t:stop_node(Node). - - -get_nodenames(N, T) -> - get_nodenames(N, T, []). - -get_nodenames(0, _, Acc) -> - Acc; -get_nodenames(N, T, Acc) -> - {A, B, C} = now(), - get_nodenames(N-1, T, [list_to_atom(atom_to_list(?MODULE) - ++ "-" - ++ atom_to_list(T) - ++ "-" - ++ integer_to_list(A) - ++ "-" - ++ integer_to_list(B) - ++ "-" - ++ integer_to_list(C)) | Acc]). - get_epmd_port() -> case init:get_argument(epmd_port) of {ok, [[PortStr|_]|_]} when is_list(PortStr) -> |