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