1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 1998-2017. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20-module(epmd_SUITE).
21-include_lib("common_test/include/ct.hrl").
22-include_lib("kernel/include/file.hrl").
23
24
25% Timeout for test cases (rather long to work on slow machines)
26-define(MEDIUM_TEST_TIMEOUT, {minutes,3}).
27-define(LONG_TEST_TIMEOUT, {minutes,10}).
28
29% Delay inserted into code
30-define(SHORT_PAUSE, 100).
31-define(MEDIUM_PAUSE, 1000).
32-define(LONG_PAUSE, 5000).
33
34% Information about nodes
35-record(node_info, {port, node_type, prot, lvsn, hvsn, node_name, extra}).
36
37% Test server specific exports
38-export([all/0, suite/0, groups/0, init_per_testcase/2, end_per_testcase/2]).
39
40-export([register_name/1,
41         register_name_ipv6/1,
42         register_names_1/1,
43         register_names_2/1,
44         register_duplicate_name/1,
45         unicode_name/1,
46         long_unicode_name/1,
47         get_port_nr/1,
48         slow_get_port_nr/1,
49         unregister_others_name_1/1,
50         unregister_others_name_2/1,
51         register_overflow/1,
52         name_with_null_inside/1,
53         name_null_terminated/1,
54         stupid_names_req/1,
55
56         no_data/1,
57         one_byte/1,
58         two_bytes/1,
59         partial_packet/1,
60         zero_length/1,
61         too_large/1,
62         alive_req_too_small_1/1,
63         alive_req_too_small_2/1,
64         alive_req_too_large/1,
65
66         returns_valid_empty_extra/1,
67         returns_valid_populated_extra_with_nulls/1,
68
69         names_stdout/1,
70
71         buffer_overrun_1/1,
72         buffer_overrun_2/1,
73         no_nonlocal_register/1,
74         no_nonlocal_kill/1,
75         no_live_killing/1,
76
77         socket_reset_before_alive2_reply_is_written/1]).
78
79
80% Port we use for testing
81-define(PORT,2243).
82-define(EPMDARGS,"-packet_timeout 1").
83
84-define(DUMMY_PORT, 1000).			% Port number to register
85% not in real use.
86
87% Timeouts etc inside test cases. Time is in milliseconds.
88-define(CONN_RETRY, 4).				% Times to retry connecting
89-define(CONN_SLEEP, 500).
90-define(CONN_TIMEOUT, 100).
91-define(RECV_TIMEOUT, 2000).
92-define(REG_REPEAT_LIM,1000).
93
94% Message codes in epmd protocol
95-define(EPMD_ALIVE2_REQ,	$x).
96-define(EPMD_ALIVE2_RESP,	$y).
97-define(EPMD_PORT_PLEASE2_REQ,	$z).
98-define(EPMD_PORT2_RESP,	$w).
99-define(EPMD_NAMES_REQ,	$n).
100-define(EPMD_DUMP_REQ,	$d).
101-define(EPMD_KILL_REQ,	$k).
102-define(EPMD_STOP_REQ,	$s).
103
104%%
105%% all/1
106%%
107
108suite() ->
109    [{ct_hooks,[ts_install_cth]},
110     {timetrap, ?MEDIUM_TEST_TIMEOUT}].
111
112all() ->
113    [register_name, register_name_ipv6,
114     register_names_1, register_names_2,
115     register_duplicate_name, unicode_name, long_unicode_name,
116     get_port_nr, slow_get_port_nr,
117     unregister_others_name_1, unregister_others_name_2,
118     register_overflow, name_with_null_inside,
119     name_null_terminated, stupid_names_req, no_data,
120     one_byte, two_bytes, partial_packet, zero_length,
121     too_large, alive_req_too_small_1, alive_req_too_small_2,
122     alive_req_too_large, returns_valid_empty_extra,
123     returns_valid_populated_extra_with_nulls,
124     names_stdout,
125     {group, buffer_overrun}, no_nonlocal_register,
126     no_nonlocal_kill, no_live_killing,
127     socket_reset_before_alive2_reply_is_written].
128
129groups() ->
130    [{buffer_overrun, [],
131      [buffer_overrun_1, buffer_overrun_2]}].
132
133%%
134%% Run before and after each test case
135%%
136
137init_per_testcase(_Func, Config) ->
138    cleanup(),
139    Config.
140
141end_per_testcase(_Func, _Config) ->
142    cleanup(),
143    ok.
144
145%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146
147%% Register a name
148register_name(Config) when is_list(Config) ->
149    ok = epmdrun(),
150    {ok,Sock} = register_node("foobar"),
151    ok = close(Sock),			% Unregister
152    ok.
153
154%% Register a name over IPv6
155register_name_ipv6(Config) when is_list(Config) ->
156    % Test if the host has an IPv6 loopback address
157    Res = gen_tcp:listen(0, [inet6, {ip, {0,0,0,0,0,0,0,1}}]),
158    case Res of
159        {ok,LSock} ->
160            gen_tcp:close(LSock),
161            ok = epmdrun(),
162            {ok,Sock} = register_node6("foobar6"),
163            ok = close(Sock),         % Unregister
164            ok;
165        _Error ->
166            {skip, "Host does not have an IPv6 loopback address"}
167    end.
168
169%% Register and unregister two nodes
170register_names_1(Config) when is_list(Config) ->
171    ok = epmdrun(),
172    {ok,Sock1} = register_node("foobar"),
173    {ok,Sock2} = register_node("foozap"),
174    ok = close(Sock1),			% Unregister
175    ok = close(Sock2),			% Unregister
176    ok.
177
178%% Register and unregister two nodes
179register_names_2(Config) when is_list(Config) ->
180    ok = epmdrun(),
181    {ok,Sock1} = register_node("foobar"),
182    {ok,Sock2} = register_node("foozap"),
183    ok = close(Sock2),			% Unregister
184    ok = close(Sock1),			% Unregister
185    ok.
186
187%% Two nodes with the same name
188register_duplicate_name(Config) when is_list(Config) ->
189    ok = epmdrun(),
190    {ok,Sock} = register_node("foobar"),
191    error = register_node("foobar"),
192    ok = close(Sock),			% Unregister
193    ok.
194
195%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
196
197%% Check that we can register and lookup a unicode name
198unicode_name(Config) when is_list(Config) ->
199    ok = epmdrun(),
200    NodeName = [16#1f608],
201    {ok,Sock} = register_node_v2(4711, 72, 0, 5, 5, NodeName, []),
202    {ok,NodeInfo} = port_please_v2(NodeName),
203    NodeName = NodeInfo#node_info.node_name,
204    ok = close(Sock),
205    ok.
206
207%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
208
209%% Check that we can register and lookup a long unicode name
210long_unicode_name(Config) when is_list(Config) ->
211    ok = epmdrun(),
212    BaseChar = 16#1f600,
213    NodeName = lists:seq(BaseChar, BaseChar+200), % will be 800 bytes long
214    {ok,Sock} = register_node_v2(4711, 72, 0, 5, 5, NodeName, []),
215    {ok,NodeInfo} = port_please_v2(NodeName),
216    NodeName = NodeInfo#node_info.node_name,
217    ok = close(Sock),
218    ok.
219
220% Internal function to register a node name, no close, i.e. unregister
221
222register_node(Name) ->
223    register_node_v2(?DUMMY_PORT,$M,0,5,5,Name,"").
224register_node(Name,Port) ->
225    register_node_v2(Port,$M,0,5,5,Name,"").
226
227register_node6(Name) ->
228    register_node_v2({0,0,0,0,0,0,0,1},?DUMMY_PORT,$M,0,5,5,Name,"").
229
230register_node_v2(Port, NodeType, Prot, HVsn, LVsn, Name, Extra) ->
231    register_node_v2("localhost", Port, NodeType, Prot, HVsn, LVsn, Name, Extra).
232register_node_v2(Addr, Port, NodeType, Prot, HVsn, LVsn, Name, Extra) ->
233    Req = alive2_req(Port, NodeType, Prot, HVsn, LVsn, Name, Extra),
234    case send_req(Req, Addr) of
235        {ok,Sock} ->
236            case recv(Sock,4) of
237                {ok, [?EPMD_ALIVE2_RESP,_Res=0,_C0,_C1]} ->
238                    {ok,Sock};
239                Other ->
240                    io:format("recv on sock ~w: ~p~n", [Sock,Other]),
241                    error
242            end;
243        error ->
244            error
245    end.
246
247% Internal function to fetch information about a node
248
249port_please_v2(Name) ->
250    case send_req([?EPMD_PORT_PLEASE2_REQ,
251                   binary_to_list(unicode:characters_to_binary(Name))]) of
252        {ok,Sock} ->
253            case recv_until_sock_closes(Sock) of
254                {ok, Resp} ->
255                    parse_port2_resp(Resp);
256                Other ->
257                    io:format("recv on sock ~w: ~p~n", [Sock,Other]),
258                    error
259            end;
260        error ->
261            error
262    end.
263
264parse_port2_resp(Resp) ->
265    case list_to_binary(Resp) of
266        <<?EPMD_PORT2_RESP,Res,Port:16,NodeType,Prot,HVsn:16,LVsn:16,
267          NLen:16,NodeName:NLen/binary,
268          ELen:16,Extra:ELen/binary>> when Res =:= 0 ->
269            {ok, #node_info{port=Port,node_type=NodeType,prot=Prot,
270                            hvsn=HVsn,lvsn=LVsn,
271                            node_name=unicode:characters_to_list(NodeName),
272                            extra=binary_to_list(Extra)}};
273        _Other ->
274            io:format("invalid port2 resp: ~p~n", [Resp]),
275            error
276    end.
277
278%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279
280%% Register a name with a null char in it
281name_with_null_inside(Config) when is_list(Config) ->
282    ok = epmdrun(),
283    error = register_node("foo\000bar"),
284    ok.
285
286%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
287
288%% Register a name with terminating null byte
289name_null_terminated(Config) when is_list(Config) ->
290    ok = epmdrun(),
291    error = register_node("foobar\000"),
292    ok.
293
294%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
295
296%% Read names from epmd in a stupid way
297stupid_names_req(Config) when is_list(Config) ->
298    ok = epmdrun(),
299    [FirstConn | Conn] = register_many(1, ?REG_REPEAT_LIM, "foo"),
300    unregister_many([FirstConn]),
301    sleep(?MEDIUM_PAUSE),
302    ok = check_names(Conn),
303    ok = unregister_many(Conn),
304    ok.
305
306check_names(Conn) ->
307    {ok,Sock} = connect_active(),
308    {ok,Reply} = do_get_names(Sock),
309    SortConn  = lists:sort(Conn),
310    SortReply = lists:sort(Reply),
311    ok = check_names_cmp(SortConn, SortReply),
312    ok.
313
314
315% Compare if the result was the same as was registered
316
317check_names_cmp([], []) ->
318    ok;
319check_names_cmp([{Name,Port,_Sock} | Conn], [{Name,Port} | Reply]) ->
320    check_names_cmp(Conn, Reply).
321
322
323% This code is taken directly from "erl_epmd.erl" in R3A01
324
325-define(int16(X), [(X bsr 8) band 16#ff, X band 16#ff]).
326-define(u32(X1,X2,X3,X4),
327        (((X1) bsl 24) bor ((X2) bsl 16) bor ((X3) bsl 8) bor X4)).
328
329do_get_names(Socket) ->
330    inet_tcp:send(Socket, [?int16(1),?EPMD_NAMES_REQ]),
331    receive
332        {tcp, Socket, [P0,P1,P2,P3 | T]} ->
333            EpmdPort = ?u32(P0,P1,P2,P3),
334            if EpmdPort == ?PORT ->
335                   names_loop(Socket, T, []);
336               true ->
337                   close(Socket),
338                   {error, address}
339            end;
340        {tcp_closed, Socket} ->
341            {ok, []}
342    end.
343
344names_loop(Socket, Acc, Ps) ->
345    receive
346        {tcp, Socket, Bytes} ->
347            {NAcc, NPs} = scan_names(Acc ++ Bytes, Ps),
348            names_loop(Socket, NAcc, NPs);
349        {tcp_closed, Socket} ->
350            {_, NPs} = scan_names(Acc, Ps),	% Really needed?
351            {ok, NPs}
352    end.
353
354scan_names(Buf, Ps) ->
355    case scan_line(Buf, []) of
356        {Line, NBuf} ->
357            case parse_line(Line) of
358                {ok, Entry} ->
359                    scan_names(NBuf, [Entry | Ps]);
360                error ->
361                    scan_names(NBuf, Ps)
362            end;
363        [] -> {Buf, Ps}
364    end.
365
366scan_line([$\n | Buf], Line) -> {lists:reverse(Line), Buf};
367scan_line([C | Buf], Line) -> scan_line(Buf, [C|Line]);
368scan_line([], _) -> [].
369
370parse_line([$n,$a,$m,$e,$ | Buf0]) ->
371    case parse_name(Buf0, []) of
372        {Name, Buf1}  ->
373            case Buf1 of
374                [$a,$t,$ ,$p,$o,$r,$t,$ | Buf2] ->
375                    case catch list_to_integer(Buf2) of
376                        {'EXIT', _} -> error;
377                        Port -> {ok, {Name, Port}}
378                    end;
379                _ -> error
380            end;
381        error -> error
382    end;
383parse_line(_) -> error.
384
385
386parse_name([$  | Buf], Name) -> {lists:reverse(Name), Buf};
387parse_name([C | Buf], Name) -> parse_name(Buf, [C|Name]);
388parse_name([], _Name) -> error.
389
390
391%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
392
393%% Register a name on a port and ask about port nr
394get_port_nr(Config) when is_list(Config) ->
395    port_request([?EPMD_PORT_PLEASE2_REQ,"foo"]).
396
397%% Register with slow write and ask about port nr
398slow_get_port_nr(Config) when is_list(Config) ->
399    port_request([?EPMD_PORT_PLEASE2_REQ,d,$f,d,$o,d,$o]).
400
401
402% Internal function used above
403
404port_request(M) ->
405    ok = epmdrun(),
406    Port = 1042,
407    {ok,RSock} = register_node("foo", Port),
408    {ok,Sock} = connect(),
409    ok = send(Sock,[size16(M),M]),
410    case recv_until_sock_closes(Sock) of
411        {ok, Resp} ->
412            close(RSock),
413            {ok,Rec} = parse_port2_resp(Resp),
414            Port = Rec#node_info.port,
415            ok;
416        Other ->
417            close(RSock),
418            io:format("recv on sock ~w: ~p~n", [Sock,Other]),
419            throw({error,Other})
420    end,
421    ok.
422
423%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
424
425%% Unregister name of other node
426unregister_others_name_1(Config) when is_list(Config) ->
427    ok = epmdrun("-relaxed_command_check"),
428    {ok,RSock} = register_node("foo"),
429    {ok,Sock} = connect(),
430    M = [?EPMD_STOP_REQ,"foo"],
431    ok = send(Sock,[size16(M),M]),
432    R = "STOPPED",
433    {ok,R} = recv(Sock,length(R)),
434    ok = close(RSock),
435    ok.
436
437%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
438
439%% Unregister name of other node
440unregister_others_name_2(Config) when is_list(Config) ->
441    ok = epmdrun("-relaxed_command_check"),
442    {ok,Sock} = connect(),
443    M = [?EPMD_STOP_REQ,"xxx42"],
444    ok = send(Sock,[size16(M),M]),
445    R = "NOEXIST",
446    {ok,R} = recv(Sock,length(R)),
447    ok.
448
449%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
450
451%% Register too many, clean and redo 10 times
452register_overflow(Config) when is_list(Config) ->
453    ct:timetrap(?LONG_TEST_TIMEOUT),
454    ok = epmdrun(),
455    Conn = register_many(1, ?REG_REPEAT_LIM, "foo"),
456    Count = length(Conn),
457    ok = unregister_many(Conn),
458    sleep(?MEDIUM_PAUSE),
459    io:format("Limit was ~w names, now reg/unreg all 10 times~n", [Count]),
460    ok = register_repeat(Count),
461    sleep(?MEDIUM_PAUSE),
462    ok = rregister_repeat(Count),
463    sleep(?MEDIUM_PAUSE),
464    ok = register_repeat(Count),
465    sleep(?MEDIUM_PAUSE),
466    ok = rregister_repeat(Count),
467    sleep(?MEDIUM_PAUSE),
468    ok = register_repeat(Count),
469    sleep(?MEDIUM_PAUSE),
470    ok = rregister_repeat(Count),
471    sleep(?MEDIUM_PAUSE),
472    ok = register_repeat(Count),
473    sleep(?MEDIUM_PAUSE),
474    ok = rregister_repeat(Count),
475    sleep(?MEDIUM_PAUSE),
476    ok = register_repeat(Count),
477    sleep(?MEDIUM_PAUSE),
478    ok = rregister_repeat(Count),
479    ok.
480
481register_repeat(Count) ->
482    Conn = register_many(1, ?REG_REPEAT_LIM, "foo"),
483    ok = unregister_many(Conn),
484    if
485        length(Conn) == Count ->
486            ok;
487        true ->
488            error
489    end.
490
491rregister_repeat(Count) ->
492    Conn = register_many(1, ?REG_REPEAT_LIM, "foo"),
493    ok = unregister_many(lists:reverse(Conn)),
494    if
495        length(Conn) == Count ->
496            ok;
497        true ->
498            error
499    end.
500
501% Return count of successful registrations
502
503register_many(I, N, _Prefix) when I > N ->
504    io:format("Done with all ~n", []),
505    [];
506register_many(I, N, Prefix) ->
507    Name = gen_name(Prefix, I),
508    Port = ?DUMMY_PORT + I,				% Just make it up
509    case register_node(Name, Port) of
510        {ok,Sock} ->
511            [{Name,Port,Sock} | register_many(I + 1, N, Prefix)];
512        Any ->
513            test_server:format("Can't register: ~w of 1..~w ~w~n", [Name,N,Any]),
514            []
515    end.
516
517unregister_many([]) ->
518    ok;
519unregister_many([{Name,_Port,Sock} | Socks]) ->
520    case close(Sock) of
521        ok ->
522            unregister_many(Socks);
523        Any ->
524            test_server:format("Can't unregister: ~w reason ~w~n", [Name,Any]),
525            error
526    end.
527
528gen_name(Str,Int) ->
529    Str ++ integer_to_list(Int).
530
531%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
532
533%% Open but send no data
534no_data(Config) when is_list(Config) ->
535    ok = epmdrun(),
536    {ok,Sock} = connect(),
537    sleep(?LONG_PAUSE),
538    closed = recv(Sock,1),
539    ok.
540
541%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
542
543%% Send one byte only
544one_byte(Config) when is_list(Config) ->
545    ok = epmdrun(),
546    {ok,Sock} = connect(),
547    ok = send(Sock,[0]),
548    sleep(?LONG_PAUSE),
549    closed = recv(Sock,1),
550    ok.
551
552%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
553
554%% Send packet size only
555two_bytes(Config) when is_list(Config) ->
556    ok = epmdrun(),
557    {ok,Sock} = connect(),
558    ok = send(Sock,[put16(3)]),
559    sleep(?LONG_PAUSE),
560    closed = recv(Sock,1),
561    ok.
562
563%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
564
565%% Got only part of a packet
566partial_packet(Config) when is_list(Config) ->
567    ok = epmdrun(),
568    {ok,Sock} = connect(),
569    ok = send(Sock,[put16(100),"only a few bytes"]),
570    sleep(?LONG_PAUSE),
571    closed = recv(Sock,1),
572    ok.
573
574%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
575
576%% Invalid zero packet size
577zero_length(Config) when is_list(Config) ->
578    ok = epmdrun(),
579    {ok,Sock} = connect(),
580    ok = send(Sock,[0,0,0,0,0,0,0,0,0,0]),
581    sleep(?MEDIUM_PAUSE),
582    closed = recv(Sock,1),
583    ok.
584
585%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
586
587%% Invalid large packet
588too_large(Config) when is_list(Config) ->
589    ok = epmdrun(),
590    {ok,Sock} = connect(),
591    Size = 63000,
592    M = lists:duplicate(Size, $z),
593    ok = send(Sock,[put16(Size),M]),
594    sleep(?MEDIUM_PAUSE),
595    % With such a large packet, even the writes can fail as the
596    % daemon closes before everything is delivered -> econnaborted
597    case recv(Sock,1) of
598        closed -> ok;
599        {error,econnaborted} -> ok;
600        Other -> exit({unexpected,Other})
601    end.
602
603%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604
605%% Try to register but not enough data
606alive_req_too_small_1(Config) when is_list(Config) ->
607    ok = epmdrun(),
608    {ok,Sock} = connect(),
609    M = [?EPMD_ALIVE2_REQ, put16(?DUMMY_PORT),$M,0, put16(5),
610         put16(5),put16(0)],
611    ok = send(Sock, [size16(M), M]),
612    sleep(?MEDIUM_PAUSE),
613    closed = recv(Sock,1),
614    ok.
615
616%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
617
618%% Try to register but not enough data
619alive_req_too_small_2(Config) when is_list(Config) ->
620    ok = epmdrun(),
621    {ok,Sock} = connect(),
622    M =  [?EPMD_ALIVE2_REQ, put16(?DUMMY_PORT),$M,0, put16(5),
623          put16(5)],
624    ok = send(Sock, [size16(M), M]),
625    sleep(?MEDIUM_PAUSE),
626    closed = recv(Sock,1),
627    ok.
628
629%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
630
631%% Try to register but node name too large
632alive_req_too_large(Config) when is_list(Config) ->
633    ok = epmdrun(),
634    {ok,Sock} = connect(),
635    L = ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
636         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
637         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
638         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
639         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
640         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
641         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
642         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
643         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
644         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
645         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
646         "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"],
647    S = length(lists:flatten(L)),
648    M = [?EPMD_ALIVE2_REQ, put16(?DUMMY_PORT),$M,0, put16(5),
649         put16(5), put16(S),L,put16(0)],
650    ok = send(Sock, [size16(M), M]),
651    sleep(?MEDIUM_PAUSE),
652    {ok,[?EPMD_ALIVE2_RESP,1]} = recv(Sock,2),
653    ok.
654
655%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
656
657%% Check that an empty extra is prefixed by a two byte length
658returns_valid_empty_extra(Config) when is_list(Config) ->
659    ok = epmdrun(),
660    {ok,Sock} = register_node_v2(4711, 72, 0, 5, 5, "foo", []),
661    {ok,#node_info{extra=[]}} = port_please_v2("foo"),
662    ok = close(Sock),
663    ok.
664
665%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
666
667%% Check a populated extra with embedded null characters
668returns_valid_populated_extra_with_nulls(Config) when is_list(Config) ->
669    ok = epmdrun(),
670    {ok,Sock} = register_node_v2(4711, 72, 0, 5, 5, "foo", "ABC\000\000"),
671    {ok,#node_info{extra="ABC\000\000"}} = port_please_v2("foo"),
672    ok = close(Sock),
673    ok.
674
675%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
676
677%% Test that epmd -names prints registered nodes to stdout
678names_stdout(Config) when is_list(Config) ->
679    ok = epmdrun(),
680    {ok,Sock} = register_node("foobar"),
681    ok = epmdrun("-names"),
682    {ok, Data} = receive {_Port, {data, D}} -> {ok, D}
683                 after 10000 -> {error, timeout}
684                 end,
685    {match,_} = re:run(Data, "^epmd: up and running", [multiline]),
686    {match,_} = re:run(Data, "^name foobar at port", [multiline]),
687    ok = close(Sock),
688    ok.
689
690%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
691
692%% Test security vulnerability in fake extra lengths in alive2_req
693buffer_overrun_1(Config) when is_list(Config) ->
694    ok = epmdrun(),
695    true = alltrue([hostile(N) || N <- lists:seq(1,10000)]),
696    ok.
697
698%% Test security vulnerability in fake extra lengths in alive2_req
699buffer_overrun_2(Config) when is_list(Config) ->
700    ok = epmdrun(),
701    [false | Rest] = [hostile2(N) || N <- lists:seq(255*4,10000)],
702    true = alltrue(Rest),
703    ok.
704hostile(N) ->
705    try
706        Bin= <<$x:8,4747:16,$M:8,0:8,5:16,5:16,5:16,"gurka",N:16>>,
707        S = size(Bin),
708        {ok,E}=connect_sturdy(),
709        gen_tcp:send(E,[<<S:16>>,Bin]),
710        closed = recv(E,1),
711        gen_tcp:close(E),
712        true
713    catch
714        _:_ ->
715            false
716    end.
717hostile2(N) ->
718    try
719        B2 = list_to_binary(lists:duplicate(N,255)),
720        Bin= <<$x:8,4747:16,$M:8,0:8,5:16,5:16,5:16,"gurka",N:16,B2/binary>>,
721        S = size(Bin),
722        {ok,E}=connect_sturdy(),
723        gen_tcp:send(E,[<<S:16>>,Bin]),
724        Z = recv(E,2),
725        gen_tcp:close(E),
726        (Z =:= closed) or (Z =:= {ok, [$y,1]})
727    catch
728        _A:_B ->
729            false
730    end.
731
732alltrue([]) ->
733    true;
734alltrue([true|T]) ->
735    alltrue(T);
736alltrue([_|_]) ->
737    false.
738%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
739
740%% Ensure that we cannot register throug a nonlocal connection
741no_nonlocal_register(Config) when is_list(Config) ->
742    case {os:find_executable("ssh"),ct:get_config(ssh_proxy_host)} of
743        {SSH,Name} when is_list(Name), is_list(SSH) ->
744            do_no_nonlocal_register(Config,Name);
745        {false,_} ->
746            {skip, "No ssh command found to create proxy"};
747        _ ->
748            {skip, "No ssh_proxy_host configured in ts.config"}
749    end.
750do_no_nonlocal_register(Config,SSHHost) when is_list(Config) ->
751    ok = epmdrun(),
752    ProxyPort = proxy_port(),
753    ok = ssh_proxy(SSHHost,ProxyPort),
754    Res = try
755              Name = "gurka_"
756              %++
757              %integer_to_list(A1)++"_"++
758              %integer_to_list(A2)++"_"++
759              %integer_to_list(A3)++"_"++
760              %integer_to_list(A4)
761              ,
762              Bname = list_to_binary(Name),
763              NameS = byte_size(Bname),
764              Bin= <<$x:8,4747:16,$M:8,0:8,5:16,
765                     5:16,NameS:16,Bname/binary,
766                     0:16>>,
767              S = size(Bin),
768              {ok, E} = connect("localhost",ProxyPort,passive),
769              gen_tcp:send(E,[<<S:16>>,Bin]),
770              closed = recv(E,1),
771              gen_tcp:close(E),
772              true
773          catch
774              _:_ ->
775                  false
776          end,
777    %erlang:display(Res),
778    true = Res,
779    ok.
780
781%% Ensure that we cannot kill through nonlocal connection
782no_nonlocal_kill(Config) when is_list(Config) ->
783    case {os:find_executable("ssh"),ct:get_config(ssh_proxy_host)} of
784        {SSH,Name} when is_list(Name), is_list(SSH) ->
785            do_no_nonlocal_kill(Config,Name);
786        {false,_} ->
787            {skip, "No ssh command found to create proxy"};
788        _ ->
789            {skip, "No ssh_proxy_host configured in ts.config"}
790    end.
791do_no_nonlocal_kill(Config,SSHHost) when is_list(Config) ->
792    ok = epmdrun(),
793    ProxyPort = proxy_port(),
794    ok = ssh_proxy(SSHHost,ProxyPort),
795    Res = try
796              {ok, E} = connect("localhost",ProxyPort,passive),
797              M = [?EPMD_KILL_REQ],
798              send(E, [size16(M), M]),
799              closed = recv(E,2),
800              gen_tcp:close(E),
801              sleep(?MEDIUM_PAUSE),
802              {ok, E2} = connect("localhost",ProxyPort,passive),
803              gen_tcp:close(E2),
804              true
805          catch
806              _:_ ->
807                  false
808          end,
809    %erlang:display(Res),
810    true = Res,
811    ok.
812%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
813
814%% Dont allow killing with live nodes or any unregistering w/o -relaxed_command_check
815no_live_killing(Config) when is_list(Config) ->
816    ok = epmdrun(),
817    {ok,RSock} = register_node("foo"),
818    {ok,Sock} = connect(),
819    M = [?EPMD_KILL_REQ],
820    ok = send(Sock,[size16(M),M]),
821    {ok,"NO"} = recv(Sock,2),
822    close(Sock),
823    {ok,Sock2} = connect(),
824    M2 = [?EPMD_STOP_REQ,"foo"],
825    ok = send(Sock2,[size16(M2),M2]),
826    closed = recv(Sock2,1),
827    close(Sock2),
828    close(RSock),
829    sleep(?MEDIUM_PAUSE),
830    {ok,Sock3} = connect(),
831    M3 = [?EPMD_KILL_REQ],
832    ok = send(Sock3,[size16(M3),M3]),
833    {ok,"OK"} = recv(Sock3,2),
834    close(Sock3),
835    ok.
836
837%% Check for regression - don't make zombie from node which
838%% sends TCP RST at wrong time
839socket_reset_before_alive2_reply_is_written(Config) when is_list(Config) ->
840    %% - delay_write for easier triggering of race condition
841    %% - relaxed_command_check for graceful shutdown of epmd even if there
842    %%   is stuck node.
843    ok = epmdrun("-delay_write 1 -relaxed_command_check"),
844
845    %% We can't use send_req/1 directly as we want to do inet:setopts/2
846    %% on our socket.
847    {ok, Sock} = connect(),
848
849    %% Issuing close/1 on such socket will result in immediate RST packet.
850    ok = inet:setopts(Sock, [{linger, {true, 0}}]),
851
852    Req = alive2_req(4711, 77, 0, 5, 5, "test", []),
853    ok = send(Sock, [size16(Req), Req]),
854
855    timer:sleep(500), %% Wait for the first 1/2 of delay_write before closing
856    ok = close(Sock),
857
858    timer:sleep(500 + ?SHORT_PAUSE), %% Wait for the other 1/2 of delay_write
859
860    %% Wait another delay_write interval, due to delay doubling in epmd.
861    %% Should be removed when this is issue is fixed there.
862    timer:sleep(1000),
863
864    {ok, SockForNames} = connect_active(),
865
866    %% And there should be no stuck nodes
867    {ok, []} = do_get_names(SockForNames),
868    ok = close(SockForNames),
869    ok.
870
871%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
872% Terminate all tests with killing epmd.
873
874cleanup() ->
875    sleep(?MEDIUM_PAUSE),
876    case connect() of
877        {ok,Sock} ->
878            M = [?EPMD_KILL_REQ],
879            send(Sock, [size16(M), M]),
880            recv(Sock,length("OK")),
881            close(Sock),
882            sleep(?MEDIUM_PAUSE);
883        _ ->
884            true
885    end.
886
887%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
888% Start an ssh channel to simulate remote access
889
890proxy_port() ->
891    ?PORT+1.
892
893ssh_proxy(SSHHost,ProxyPort) ->
894    Host = lists:nth(2,string:tokens(atom_to_list(node()),"@")),
895    % Requires proxy to be a unix host with the command 'read' accessible
896    osrun("ssh -L "++integer_to_list(ProxyPort)++":"++Host++":"
897          ++integer_to_list(?PORT)++" "++SSHHost++" read").
898
899
900
901%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
902% Normal debug start of epmd
903
904epmdrun() ->
905    epmdrun([]).
906epmdrun(Args) ->
907    case os:find_executable(epmd) of
908        false ->
909            {error, {could_not_find_epmd_in_path}};
910        Path ->
911            epmdrun(Path,Args)
912    end.
913
914epmdrun(Epmd,Args0) ->
915    %% test_server:format("epmdrun() => Epmd = ~p",[Epmd]),
916    Args = case Args0 of
917               [] ->
918                   [];
919               O ->
920                   " "++O
921           end,
922    osrun("\"" ++ Epmd ++ "\"" ++ " " ?EPMDARGS " -port " ++ integer_to_list(?PORT) ++ Args).
923
924
925%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
926% Start an external process
927
928osrun(Cmd) ->
929    _ = open_port({spawn, Cmd}, []),
930    ok.
931
932%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
933% Wrappers of TCP functions
934
935% These functions is the interface for connect.
936% Passive mode is the default
937
938connect() ->
939    connect("localhost",?PORT, passive).
940
941connect(Addr) ->
942    connect(Addr,?PORT, passive).
943
944connect_active() ->
945    connect("localhost",?PORT, active).
946
947%% Retry after 15 seconds, to avoid TIME_WAIT socket exhaust.
948connect_sturdy() ->
949    connect("localhost",?PORT, passive, 15000, 3).
950
951% Try a few times before giving up
952connect(Addr, Port, Mode) ->
953    connect(Addr, Port, Mode, ?CONN_SLEEP, ?CONN_RETRY).
954connect(Addr, Port, Mode, Sleep, Retry) ->
955    case connect_repeat(Addr, Retry, Port, Mode, Sleep) of
956        {ok,Sock} ->
957            {ok,Sock};
958        {error,timeout} ->
959            timeout;
960        {error,Reason} ->
961            test_server:format("connect: error: ~w~n",[Reason]),
962            error;
963        Any ->
964            test_server:format("connect: unknown message: ~w~n",[Any]),
965            exit(1)
966    end.
967
968
969% Try a few times before giving up. Pause a small time between
970% each try.
971
972connect_repeat(Addr, 1, Port, Mode, _Sleep) ->
973    connect_mode(Addr,Port, Mode);
974connect_repeat(Addr,Retry, Port, Mode, Sleep) ->
975    case connect_mode(Addr,Port, Mode) of
976        {ok,Sock} ->
977            {ok,Sock};
978        {error,Reason} ->
979            test_server:format("connect: error: ~w~n",[Reason]),
980            timer:sleep(Sleep),
981            connect_repeat(Addr, Retry - 1, Port, Mode, Sleep);
982        Any ->
983            test_server:format("connect: unknown message: ~w~n",[Any]),
984            exit(1)
985    end.
986
987connect_mode(Addr,Port, active) ->
988    gen_tcp:connect(Addr, Port, [{packet, 0}], ?CONN_TIMEOUT);
989connect_mode(Addr, Port, passive) ->
990    gen_tcp:connect(Addr, Port, [{packet, 0}, {active, false}],
991                    ?CONN_TIMEOUT).
992
993
994close(Sock) ->
995    case gen_tcp:close(Sock) of
996        {error,_} ->
997            error;
998        ok ->
999            ok;
1000        Any ->
1001            test_server:format("unknown message: ~w~n",[Any]),
1002            exit(1)
1003    end.
1004
1005recv(Sock, Len) ->
1006    recv(Sock, Len, ?RECV_TIMEOUT).
1007
1008recv(Sock, Len, Timeout) ->
1009    case gen_tcp:recv(Sock, Len, Timeout) of
1010        {ok,[]} ->				% Should not be the case
1011            recv(Sock, 1, 1);			% any longer
1012        {ok,Data} ->
1013            {ok,Data};
1014        {error,timeout} ->
1015            timeout;
1016        {error,closed} ->
1017            closed;
1018        {error,_}=Error ->
1019            Error;
1020        Any ->
1021            test_server:format("unknown message: ~w~n",[Any]),
1022            exit(1)
1023    end.
1024
1025%% Send data to socket. The list can be non flat and contain
1026%% the atom 'd' or tuple {d,Seconds} where this is delay
1027%% put in between the sent characters.
1028
1029send(Sock, SendSpec) ->
1030    case send(SendSpec, [], Sock) of
1031        {ok,[]} ->
1032            ok;
1033        {ok,RevBytes} ->
1034            send_direct(Sock, lists:reverse(RevBytes));
1035        Any ->
1036            Any
1037    end.
1038
1039
1040% If an error, return immediately
1041% Collect real characters in the first argument to form
1042% a string to send. Only perform "actions", like a delay,
1043% when this argument is empty.
1044
1045send([], RevBytes, _Sock) ->
1046    {ok,RevBytes};
1047send([Byte | Spec], RevBytes, Sock) when is_integer(Byte) ->
1048    send(Spec, [Byte | RevBytes], Sock);
1049send([List | Spec], RevBytes, Sock) when is_list(List) ->
1050    case send(List, RevBytes, Sock) of
1051        {ok,Left} ->
1052            send(Spec, Left, Sock);
1053        Other ->
1054            Other
1055    end;
1056send([d | Spec], RevBytes, Sock) ->
1057    send([{d,1000} | Spec], RevBytes, Sock);
1058send([{d,S} | Spec], RevBytes, Sock) ->
1059    case send_direct(Sock, lists:reverse(RevBytes)) of
1060        ok ->
1061            timer:sleep(S),
1062            send(Spec, [], Sock);
1063        Any ->
1064            Any
1065    end.
1066
1067%%%%
1068
1069send_direct(Sock, Bytes) ->
1070    case gen_tcp:send(Sock, Bytes) of
1071        ok ->
1072            ok;
1073        {error, closed} ->
1074            closed;
1075        {error, _Reason} ->
1076            error;
1077        Any ->
1078            test_server:format("unknown message: ~w~n",[Any]),
1079            Any
1080    end.
1081
1082send_req(Req) ->
1083    send_req(Req, "localhost").
1084send_req(Req, Addr) ->
1085    case connect(Addr) of
1086        {ok,Sock} ->
1087            case send(Sock, [size16(Req), Req]) of
1088                ok ->
1089                    {ok,Sock};
1090                Other ->
1091                    test_server:format("Failed to send ~w on sock ~w: ~w~n",
1092                                       [Req,Sock,Other]),
1093                    error
1094            end;
1095        Other ->
1096            test_server:format("Connect failed when sending ~w: ~p~n",
1097                               [Req, Other]),
1098            error
1099    end.
1100
1101recv_until_sock_closes(Sock) ->
1102    recv_until_sock_closes_2(Sock,[]).
1103
1104recv_until_sock_closes_2(Sock,AccData) ->
1105    case recv(Sock,0) of
1106        {ok,Data} ->
1107            recv_until_sock_closes_2(Sock,AccData++Data);
1108        closed ->
1109            {ok,AccData};
1110        Other ->
1111            Other
1112    end.
1113
1114sleep(MilliSeconds) ->
1115    timer:sleep(MilliSeconds).
1116
1117%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1118
1119put16(N) ->
1120    [N bsr 8, N band 16#ff].
1121
1122size16(List) ->
1123    N = flat_count(List, 0),
1124    [N bsr 8, N  band 16#ff].
1125
1126flat_count([H|T], N) when is_integer(H) ->
1127    flat_count(T, N+1);
1128flat_count([H|T], N) when is_list(H) ->
1129    flat_count(T, flat_count(H, N));
1130flat_count([_|T], N) ->
1131    flat_count(T, N);
1132flat_count([], N) -> N.
1133
1134
1135%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1136
1137alive2_req(Port, NodeType, Prot, HVsn, LVsn, Name, Extra) ->
1138    Utf8Name = unicode:characters_to_binary(Name),
1139    [?EPMD_ALIVE2_REQ, put16(Port), NodeType, Prot,
1140     put16(HVsn), put16(LVsn),
1141     put16(size(Utf8Name)), binary_to_list(Utf8Name),
1142     size16(Extra), Extra].
1143