Packages

otpbp

7.3.2
7.18.0 7.16.1 7.15.0 7.14.0 7.13.0 7.12.0 7.11.0 7.10.2 7.9.3 7.9.2 7.9.1 7.8.7 7.8.6 7.8.5 7.8.4 7.7.1 7.7.0 7.6.3 7.6.2 7.6.1 7.6.0 7.5.1 7.5.0 7.4.0 7.3.4 7.3.3 7.3.2 7.3.1 7.3.0 7.2.0 7.1.1 7.1.0 7.0.4 7.0.3 7.0.2 7.0.1 6.26.0 6.25.0 6.24.0 6.23.0 6.22.2 6.21.3 6.21.2 6.21.1 6.20.2 6.19.1 6.19.0 6.18.3 6.18.2 6.18.1 6.18.0 6.17.1 6.17.0 6.16.0 6.15.4 6.15.3 6.15.2 6.15.1 6.15.0 6.14.0 6.13.5 6.13.4 6.13.3 6.13.2 6.13.1 6.13.0 6.12.0 6.11.2 6.11.1 6.10.0 6.9.2 6.9.1 6.9.0 6.8.0 6.7.1 6.7.0 6.6.4 6.6.3 6.6.2 6.6.1 6.6.0 6.5.0 6.4.0 6.3.3 6.3.2 6.3.1 6.3.0 6.2.1 6.2.0 6.1.0 6.0.0 5.39.0 5.38.0 5.37.0 5.36.0 5.35.2 5.34.3 5.34.2 5.34.1 5.33.1 5.32.1 5.32.0 5.31.3 5.31.2 5.31.1 5.31.0 5.30.1 5.30.0 5.29.0 5.28.4 5.28.3 5.28.2 5.28.1 5.28.0 5.27.0 5.26.5 5.26.4 5.26.3 5.26.2 5.26.1 5.26.0 5.25.0 5.24.2 5.24.1 5.23.0 5.22.2 5.22.1 5.22.0 5.21.0 5.20.1 5.20.0 5.19.4 5.19.3 5.19.2 5.19.1 5.19.0 5.18.0 5.17.0 5.16.3 5.16.1 5.16.0 5.15.1 5.15.0 5.14.0 5.13.1 5.13.0 5.12.1 5.12.0 5.11.2 5.11.1 5.10.1 5.10.0 5.9.0 5.8.0 5.7.0 5.6.1 5.6.0 5.5.0 5.4.2 5.4.1 5.4.0 5.3.0 5.2.2 5.2.1 5.2.0 5.1.2 5.1.1 4.79.0 4.78.0 4.77.0 4.76.2 4.75.3 4.75.2 4.75.1 4.74.0 4.73.1 4.73.0 4.72.3 4.72.2 4.72.1 4.72.0 4.71.1 4.71.0 4.70.0 4.69.4 4.69.3 4.69.2 4.69.1 4.69.0 4.68.0 4.67.5 4.67.4 4.67.3 4.67.2 4.67.0 4.66.0 4.65.2 4.65.1 4.64.0 4.63.2 4.63.1 4.63.0 4.62.0 4.61.1 4.61.0 4.60.4 4.60.3 4.60.2 4.60.1 4.60.0 4.59.0 4.58.0 4.57.2 4.57.1 4.57.0 4.56.2 4.56.1 4.56.0 4.55.0 4.54.0 4.53.0 4.52.1 4.52.0 4.51.3 4.51.2 4.51.0 4.50.0 4.49.3 4.49.2

OTP backports

Current section

Files

Jump to
otpbp src otpbp_erl_epmd.erl
Raw

src/otpbp_erl_epmd.erl

-module(otpbp_erl_epmd).
-ifndef(HAVE_erl_epmd__listen_port_please_2).
% OTP 21.0
-export([listen_port_please/2]).
-endif.
-ifndef(HAVE_erl_epmd__port_please_2).
% OTP 21.0
-export([port_please/2]).
-endif.
-ifndef(HAVE_erl_epmd__port_please_3).
% OTP 21.0
-export([port_please/3]).
-include_lib("kernel/include/dist.hrl").
-include_lib("kernel/include/inet.hrl").
-endif.
-ifndef(HAVE_erl_epmd__port_please_2).
-ifdef(HAVE_erl_epmd__port_please_3).
-import(erl_epmd, [port_please/3]).
-endif.
-endif.
-ifndef(HAVE_erl_epmd__port_please_3).
-ifdef(HAVE_erl_epmd__listen_port_please_2).
-import(erl_epmd, [listen_port_please/2]).
-endif.
-endif.
-ifndef(HAVE_erl_epmd__listen_port_please_2).
listen_port_please(_Name, _Host) ->
{ok,
case init:get_argument(erl_epmd_port) of
{ok, [[StringPort]]} -> list_to_integer(StringPort);
_ -> 0
end}.
-endif.
-ifndef(HAVE_erl_epmd__port_please_2).
port_please(Node, HostName) -> port_please(Node, HostName, infinity).
-endif.
-ifndef(HAVE_erl_epmd__port_please_3).
-ifdef(ERL_DIST_VER_HIGH).
-define(epmd_dist_high, ?ERL_DIST_VER_HIGH).
-else.
-define(epmd_dist_high, 5).
-endif.
-ifdef(ERL_DIST_VER_LOW).
-define(epmd_dist_low, ?ERL_DIST_VER_LOW).
-else.
-define(epmd_dist_low, 5).
-endif.
port_please(Node, HostName, Timeout) ->
case listen_port_please(Node, HostName) of
{ok, 0} ->
case getepmdbyname(HostName, Timeout) of
{ok, EpmdAddr} -> get_port(Node, EpmdAddr, Timeout);
_Error -> noport
end;
{ok, Prt} -> {port, Prt, ?epmd_dist_low}
end.
getepmdbyname(HostName, Timeout) when is_list(HostName) ->
case inet:gethostbyname(HostName,
case inet_db:res_option(inet6) of
true -> inet6;
false -> inet
end,
Timeout) of
{ok, #hostent{h_addr_list = [EpmdAddr|_]}} -> {ok, EpmdAddr};
Else -> Else
end;
getepmdbyname(HostName, Timeout) when is_atom(HostName) -> getepmdbyname(atom_to_list(HostName), Timeout);
getepmdbyname(HostName, _Timeout) -> {ok, HostName}.
-define(int16(X), [((X) bsr 8) band 16#FF, (X) band 16#FF]).
-define(EPMD_PORT_PLEASE2_REQ, $z).
get_port(Node, EpmdAddress, Timeout) ->
case erl_epmd:open(EpmdAddress, Timeout) of
{ok, Socket} ->
Name = to_string(Node),
case gen_tcp:send(Socket, [?int16(length(Name) + 1), ?EPMD_PORT_PLEASE2_REQ, Name]) of
ok -> wait_for_port_reply(Socket, []);
_Error -> noport
end;
_Error -> noport
end.
to_string(S) when is_list(S) -> S;
to_string(S) when is_atom(S) -> atom_to_list(S).
-define(u16(X1, X0), (((X1) bsl 8) bor (X0))).
wait_for_port_reply(Socket, SoFar) ->
receive
{tcp, Socket, Data0} ->
case SoFar ++ Data0 of
[$w, 0|Rest] -> wait_for_port_reply_cont(Socket, Rest);
[$w, _|_] -> wait_for_close(Socket, noport);
[_, _|_] = Garbage -> {error, {garbage_from_epmd, Garbage}};
Data -> wait_for_port_reply(Socket, Data)
end;
{tcp_closed, Socket} -> closed
after 10000 ->
gen_tcp:close(Socket),
noport
end.
wait_for_port_reply_cont(Socket, SoFar) when length(SoFar) >= 10 -> wait_for_port_reply_cont2(Socket, SoFar);
wait_for_port_reply_cont(Socket, SoFar) ->
receive
{tcp, Socket, Data0} ->
case SoFar ++ Data0 of
Data when length(Data) >= 10 -> wait_for_port_reply_cont2(Socket, Data);
Data -> wait_for_port_reply_cont(Socket, Data)
end;
{tcp_closed, Socket} -> noport
after 10000 ->
gen_tcp:close(Socket),
noport
end.
wait_for_port_reply_cont2(Socket, [A, B, _Type, _Proto, HighA, HighB, LowA, LowB, NLenA, NLenB|Rest]) ->
wait_for_port_reply_name(Socket, ?u16(NLenA, NLenB), Rest),
{port, ?u16(A, B), best_version(?u16(LowA, LowB), ?u16(HighA, HighB))}.
wait_for_port_reply_name(Socket, Len, Sofar) ->
receive
{tcp, Socket, _Data} -> wait_for_port_reply_name(Socket, Len, Sofar);
{tcp_closed, Socket} -> ok
end.
best_version(Low, High) -> select_best_version(epmd_dist_low(), epmd_dist_high(), Low, High).
select_best_version(L1, H1, L2, H2) when L1 > H2; L2 > H1 -> 0;
select_best_version(_L1, H1, _L2, H2) -> min(H1, H2).
wait_for_close(Socket, Reply) ->
receive
{tcp_closed, Socket} -> Reply
after 10000 ->
gen_tcp:close(Socket),
Reply
end.
epmd_dist_high() ->
case os:getenv("ERL_EPMD_DIST_HIGH") of
false -> ?epmd_dist_high;
Version ->
try list_to_integer(Version) of
N when N < ?epmd_dist_high -> N;
_ -> ?epmd_dist_high
catch
_:_ -> ?epmd_dist_high
end
end.
epmd_dist_low() ->
case os:getenv("ERL_EPMD_DIST_LOW") of
false -> ?epmd_dist_low;
Version ->
try list_to_integer(Version) of
N when N > ?epmd_dist_low -> N;
_ -> ?epmd_dist_low
catch
_:_ -> ?epmd_dist_low
end
end.
-endif.