Erlang Central

Lookup MX Records In DNS

Revision as of 12:42, 15 June 2007 by BibbsSpurlin621 (Talk | contribs)

cyclobenzaprine online propecia online tenuate online carisoprodol online cheap ultracet pharmacy online online free wwe ringtones diazepam online xenical online nokia ringtones free qwest ringtones cheap zanaflex diazepam online verizon ringtones free motorola ringtones lortab online prozac online free ericsson ringtones cheap ortho cheap cyclobenzaprine celexa online free ringtones phentermine cool ringtones prozac online qwest ringtones cialis online sprint ringtones nexium online free real ringtones sagem ringtones tracfone ringtones nokia ringtones punk ringtones mp3 ringtones free sony ringtones ativan online but hgh free midi ringtones alltel ringtones flexeril online sony ericsson ringtones free motorola ringtones vicodin online tracfone ringtones soma online levitra online free motorola ringtones didrex online cheap sildenafil cheap pharmacy online zoloft online hydrocodone online free sony ringtones cingular ringtones viagra buy paxil buy ambien buy lortab hydrocodone online vigrx online ativan online hgh online cheap sildenafil buy viagra ortho online nextel ringtones online lisinopril funny ringtones sony ericsson ringtones vicodin online cheap hydrocodone cheap ativan free mono ringtones clonazepam levitra sprint ringtones cheap cialis free sony ringtones order levitra cheap zanaflex phentermine celexa online ultracet online free wwe ringtones free sharp ringtones buy norco soma online ultracet online free cingular ringtones cheap adipex cheap xenical albuterol online tenuate online cheap ortho free music ringtones free sagem ringtones cheap lisinopril meridia online propecia online vigrx online diethylpropion online cheap albuterol mp3 ringtones cheap meridia free free ringtones ultram online cheap soma cheap lortab sildenafil online free nextel ringtones cheap lorazepam funny ringtones diethylpropion online free free ringtones funny ringtones free cingular ringtones cheap soma free nokia ringtones clonazepam online cheap zyban clomid online buy prozac valium cheap lisinopril meridia online buy tramadol sharp ringtones midi ringtones cheap flexeril free real ringtones celexa online zoloft online free nextel ringtones ericsson ringtones music ringtones mtv ringtones cheap ultram buy valium viagra online cheap lorazepam cheap cialis phentermine online buy nexium samsung ringtones norco online cheap meridia free sprint ringtones rivotril online order carisoprodol order carisoprodol cyclobenzaprine online qwest ringtones free qwest ringtones fioricet online verizon ringtones free punk ringtones cheap hoodia pharmacy online online free tracfone ringtones tramadol rivotril online tramadol online didrex online cheap fioricet music ringtones albuterol online nokia ringtones buy viagra buy alprazolam xenical online buy pharmacy online free funny ringtones zanaflex online ericsson ringtones cyclobenzaprine online cheap adipex cheap xanax free alltel ringtones qwest ringtones cheap ultram free sonyericsson ringtones samsung ringtones cheap lortab mono ringtones free samsung ringtones zyban online celexa online free funny ringtones free wwe ringtones cheap rivotril cheap clomid fioricet online buy hgh lipitor online but hoodia clonazepam cool ringtones cheap tenuate vicodin online ==Introduction==

For the E-mail server I'm writing I had the simple requirement to lookup MX records from the DNS. Erlang provides a small interface for performing DNS queries. The modules you'll need to use are inet_db, inet_dns and inet_res.

Using The DNS Lookup Interface

Although it looks like there is a mechanism for querying the system nameservers, I couldn't figure out how it works properly so I have to start by adding a nameserver to query from:


ok = inet_db:add_ns({192,168,0,10}).

This adds the given IP to the internal database of nameservers. (Note the Erlang convention of IP addresses given as quadruples).

The next stage is to construct an appropriate query. Handily enough Erlang provides a very simple interface. The header file is "kernel/src/inet_dns.hrl" and this provides all of the macros and details required to do the lookup.

Use include_lib to add this:


-include_lib("kernel/src/inet_dns.hrl").

The query is extremely simple to achieve, just pass the domain and record type to inet_res:nslookup/3.

This returns { ok, Result } on success or {error, Reason} on failure.

Result is actually a record, named #dns_rec in inet_dns.hrl. This record has five fields, but for the purposes of this HowTo we are only interested in one, the arlist field. This field is a list of resource entries. To do the MX lookup I simply match on the record and list:


mxlookup(Domain) ->
  case inet_res:nslookup(Domain,1,?S_MX) of
    { error, Reply } -> Reply;
    { ok, #dns_rec{ arlist = Ans } } -> findmx( Ans )
  end.

Each entry in this list is a record of #dns_rr (DNS Resource Record).

findmx/1 is a function which searches through the list of resources and filters out the MX servers. We're basically interested in the host addresses (for sending email to) so findmx/1 is very simple (and naive), for this HowTo I'll simply return the first host found:


findmx( [#dns_rr{ type=?S_A, data = Addr } | T] ) -> Addr;
findmx( [H | T ]) -> findmx(T);
findmx( _Other ) -> none.

Conclusion

Extensions like handling timeouts, sorting and verifying results and so forth should be straightforward, the comments in inet_dns.hrl outline what each member of each record means.

Listing


-module(mxlookup).

-export([lookup/1, init/1]).

-include_lib("kernel/src/inet_dns.hrl").

init([NS | T]) ->
  ok = inet_db:add_ns(NS),
  init(T);
init([]) -> ok;
init(Nameserver) ->
  ok = inet_db:add_ns(Nameserver).

findmx( [#dns_rr{ type=?S_A, data = Addr } | _] ) -> Addr;
findmx( [_ | T ]) -> findmx(T);
findmx( _Other ) -> none.

lookup(Domain) ->
  case inet_res:nslookup(Domain,1,mx) of
    { error, Reply } -> Reply;
    { ok, #dns_rec{ arlist = Ans } } -> findmx( Ans )
  end.


-module(testmx).

-export([test/0]).

test() ->
  mxlookup:init( [{192,168,0,10}] ),
  Addr1 = mxlookup:lookup( "atomictiger.net" ),
  Addr2 = mxlookup:lookup( "trapexit.org" ),
  io:format("Atomic Tiger: ~p~nTrapexit: ~p~n",[Addr1,Addr2]).