newbie having difficulty with inet_res:nslookup
Jeff Macdonald
macfisherman@REDACTED
Sun Sep 13 17:27:46 CEST 2009
Hi All,
I wrote a fairly simple program to look up MX records for domains and
then look up the exhanger's A and AAAA records. I'm trying to see how
many MX's have IPv6 capable hosts.
My program simply reads a file which contains a domain per line and
spawns a processes/thread/child for each domain. The spawned process
then does the MX, A and AAAA lookups and prints the results to STDOUT
as a erlang tupple. This seems to work fine for a small sample set of
10 rows but when trying 100 rows or more I get:
=ERROR REPORT==== 12-Sep-2009::23:06:41 ===
Error in process <0.11161.0> with exit value:
{function_clause,[{lists,map,[#Fun<mx.0.117750125>,emfile]},{mx,do_lookups,1}]}
My program is below. Usage is:
mx:init({192,168, 1, 1}). (replace that tupple with the IP of your DNS server)
mx:process_file("file-with-domains").
I currently can't share a list of domains because it is customer data,
but I sure there is some lists somewhere.
I suspect that I'm overloading the DNS server at home. That is just
whatever is running in my linksys router. Any other suggestions about
the code welcomed. I know I could probably run the A and AAAA queries
in parallel. I also can probably skip queries when the data is present
in the MX results. For now, I'm just trying to get the basics.
TIA
%% Author: jeff
%% Created: Sep 10, 2009
%% Description: TODO: Add description to mx
-module(mx).
%%
%% Include files
%%
-include_lib("kernel/src/inet_dns.hrl").
%%
%% Exported Functions
%%
-export([init/1, process_file/1, do_lookups/1]).
%%
%% API Functions
%%
init(Resolver) ->
inet_db:add_ns(Resolver).
process_file(Filename) ->
{ok,Fh}=file:open(Filename, [read]),
read_file(Fh).
do_lookups(Domain) ->
MX_list=lookup_mx(Domain),
Address=lists:map(fun lookup_address/1, MX_list),
io:format("~p:~n\t~p~n~n", [Domain, Address]).
%%
%% Local Functions
%%
read_file(Fh) ->
case io:get_line(Fh, "") of
eof -> done;
{error, Reason} -> {error, Reason};
Data ->
process_data(string:strip(Data,right,$\n)),
read_file(Fh)
end.
process_data(Data) ->
spawn(mx, do_lookups, [Data]).
lookup_mx(Domain) ->
case inet_res:nslookup(Domain, 1, mx) of
{error, Reason} -> Reason;
{ok, #dns_rec{ anlist = Ans }} -> lists:map(fun parse_mx/1, Ans)
end.
lookup_address(Host) ->
{ Host, {a, lookup_address(Host, a)},
{aaaa, lookup_address(Host, aaaa)} }.
lookup_address(Host, a) ->
case inet_res:nslookup(Host, 1, a) of
{error, Reason} -> Reason;
{ok, #dns_rec{ anlist = Ans }} -> lists:map(fun parse_a/1, Ans)
end;
lookup_address(Host, aaaa) ->
case inet_res:nslookup(Host, 1, aaaa) of
{error, Reason} -> Reason;
{ok, #dns_rec{ anlist = Ans }} -> Host,lists:map(fun parse_aaaa/1, Ans)
end.
parse_mx( RR ) ->
#dns_rr{ type=mx, data={ _Pref, Exchange} } = RR,
Exchange.
parse_a( RR ) ->
#dns_rr{ type=a, data=Address } = RR,
Address.
parse_aaaa( RR ) ->
#dns_rr{ type=aaaa, data=Address } = RR,
Address.
--
Jeff Macdonald
Ayer, MA
More information about the erlang-questions
mailing list