Permalink
Browse files

add support for dedup and multi options

  • Loading branch information...
1 parent 7b3b89d commit d40525188bfc779188f1fef185b12cb7a60c0856 @gleber gleber committed Apr 28, 2012
Showing with 43 additions and 11 deletions.
  1. +2 −0 .gitignore
  2. +34 −10 src/gen_icmp.erl
  3. +1 −1 src/tracert.erl
  4. +6 −0 test/gen_icmp_tests.erl
View
@@ -1,3 +1,5 @@
*.[oa]
*.beam
/ebin/gen_icmp.app
+/deps/*
+/.eunit/
View
@@ -111,9 +111,11 @@ ping(Socket, Hosts, Options) when is_pid(Socket), is_list(Hosts), is_list(Option
Data = proplists:get_value(data, Options, payload(echo)),
Timeout = proplists:get_value(timeout, Options, ?PING_TIMEOUT),
Timestamp = proplists:get_value(timestamp, Options, true),
- Hosts2 = addr_list(Hosts),
+ Dedup = proplists:get_value(dedup, Options, true),
+ Multi = proplists:get_value(multi, Options, false),
+ Hosts2 = addr_list(Hosts, Dedup, Multi),
{Addresses, Errors} = lists:partition(fun({ok, _, _}) -> true;
- (_) -> false
+ (_) -> false
end, Hosts2),
case Addresses of
[] ->
@@ -375,21 +377,43 @@ payload(echo) ->
%%
%% ping
%%
-addr_list(Hosts) ->
- sets:to_list(sets:from_list(lists:flatten([ parse(Host) || Host <- Hosts ]))).
+addr_list(Hosts, false, Multi) ->
+ addr_list0(Hosts, Multi);
+addr_list(Hosts, true, Multi) ->
+ resdedup(addr_list0(Hosts, Multi)).
+
+resdedup(List) ->
+ resdedup0(lists:keysort(3, List)).
+resdedup0([{ok, _, IP} = A, {ok, _, IP} | List]) ->
+ resdedup0([A | List]);
+resdedup0([A|List]) ->
+ [A | resdedup0(List)];
+resdedup0([]) ->
+ [].
+
+addr_list0(Hosts, true) ->
+ [ begin
+ {ok, Host, Ips} = parse(Host),
+ [ {ok, Host, Ip} || Ip <- Ips ]
+ end || Host <- Hosts ];
+addr_list0(Hosts, false) ->
+ [ begin
+ {ok, Host, [IP|_]} = parse(Host),
+ {ok, Host, IP}
+ end || Host <- Hosts ].
parse(Addr) when is_list(Addr) ->
parse_or_resolve(Addr, inet_parse:address(Addr));
parse(Addr) when is_tuple(Addr) ->
- {ok, Addr, Addr}.
+ {ok, Addr, [Addr]}.
parse_or_resolve(Addr, {ok, IP}) ->
- {ok, Addr, IP};
+ {ok, Addr, [IP]};
parse_or_resolve(Addr, {error, einval}) ->
- case inet_res:gethostbyname(Addr) of
- {ok, #hostent{h_addr_list = IPs}} ->
- [ {ok, Addr, IP} || IP <- IPs ];
- _ ->
+ case inet:gethostbyname(Addr) of
+ {ok, #hostent{h_addr_list = IPs}} ->
+ {ok, Addr, lists:usort(IPs)};
+ _ ->
[ {error, Addr, nxdomain} ]
end.
View
@@ -94,7 +94,7 @@ host(Host, Options) ->
Path.
host(Ref, Host, Options) ->
- [{ok, _, Daddr}] = gen_icmp:parse(Host),
+ {ok, _, [Daddr]} = gen_icmp:parse(Host),
State = proplist_to_record(Options),
ok = gen_server:call(Ref, {handler, State#state.handler}, infinity),
trace(Ref, State#state{daddr = Daddr}).
View
@@ -47,6 +47,12 @@ multiple_hosts_ok_test() ->
{ok,{127,0,0,1}, {127,0,0,1}, {{_,_,_}, <<" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJK">>}}] =
gen_icmp:ping(["www.google.com", {127,0,0,1}, "127.0.0.1"]).
+multiple_hosts_no_dedup_ok_test() ->
+ [{ok,"www.google.com", {_,_,_,_}, {{_,_,_}, <<" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJK">>}},
+ {ok,"127.0.0.1", {127,0,0,1}, {{_,_,_}, <<" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJK">>}},
+ {ok,{127,0,0,1}, {127,0,0,1}, {{_,_,_}, <<" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJK">>}}] =
+ gen_icmp:ping(["www.google.com", {127,0,0,1}, "127.0.0.1"], [{dedup, false}]).
+
single_host_timeout_test() ->
[{{error,timeout},"192.168.209.244",{192,168,209,244}}] = gen_icmp:ping("192.168.209.244", [{timeout, 5}]).

0 comments on commit d405251

Please sign in to comment.