Provided by: erlang-manpages_16.b.3-dfsg-1ubuntu2_all bug

NAME

       inet_res - A Rudimentary DNS Client

DESCRIPTION

       Performs DNS name resolving towards recursive name servers

       See  also  ERTS User's Guide: Inet configuration  for more information on how to configure
       an Erlang runtime system for IP communication  and  how  to  enable  this  DNS  client  by
       defining  'dns'  as a lookup method. It then acts as a backend for the resolving functions
       in inet.

       This DNS client can resolve DNS records even if it is not used for normal  name  resolving
       in the node.

       This is not a full-fledged resolver. It is just a DNS client that relies on asking trusted
       recursive nameservers.

NAME RESOLVING

       UDP queries are used unless resolver option usevc is true, which forces  TCP  queries.  If
       the  query  is to large for UDP, TCP is used instead. For regular DNS queries 512 bytes is
       the size limit. When EDNS is enabled (resolver option edns is set to the EDNS version  i.e
       0  instead  of  false),  resolver  option udp_payload_size sets the limit. If a nameserver
       replies with the TC bit set (truncation), indicating the answer is incomplete,  the  query
       is  retried  to  that nameserver using TCP. The resolver option udp_payload_size also sets
       the advertised size for the max allowed reply size, if  EDNS  is  enabled,  otherwise  the
       nameserver  uses  the  limit 512 byte. If the reply is larger it gets truncated, forcing a
       TCP re-query.

       For UDP queries, the resolver options  timeout  and  retry  control  retransmission.  Each
       nameserver  in  the  nameservers list is tried with a timeout of timeout / retry. Then all
       nameservers are tried again doubling the timeout, for a total of retry times.

       For queries that not use the search list, if the  query  to  all  nameservers  results  in
       {error,nxdomain}or an empty answer, the same query is tried for the alt_nameservers.

DATA TYPES

       Resolver types:

       res_option() = {alt_nameservers, [nameserver()]}
                    | {edns, 0 | false}
                    | {inet6, boolean()}
                    | {nameservers, [nameserver()]}
                    | {recurse, boolean()}
                    | {retry, integer()}
                    | {timeout, integer()}
                    | {udp_payload_size, integer()}
                    | {usevc, boolean()}

       nameserver() = {inet:ip_address(), Port :: 1..65535}

       res_error() = formerr
                   | qfmterror
                   | servfail
                   | nxdomain
                   | notimp
                   | refused
                   | badvers
                   | timeout

       DNS types:

       dns_name() = string()

              A string with no adjacent dots.

       rr_type() = a
                 | aaaa
                 | cname
                 | gid
                 | hinfo
                 | ns
                 | mb
                 | md
                 | mg
                 | mf
                 | minfo
                 | mx
                 | naptr
                 | null
                 | ptr
                 | soa
                 | spf
                 | srv
                 | txt
                 | uid
                 | uinfo
                 | unspec
                 | wks

       dns_class() = in | chaos | hs | any

       dns_msg() = term()

              This is the start of a hiearchy of opaque data structures that can be examined with
              access functions in inet_dns that return lists of {Field,Value} tuples. The arity 2
              functions just return the value for a given field.

              dns_msg() = DnsMsg
                  inet_dns:msg(DnsMsg) ->
                      [ {header, dns_header()}
                      | {qdlist, dns_query()}
                      | {anlist, dns_rr()}
                      | {nslist, dns_rr()}
                      | {arlist, dns_rr()} ]
                  inet_dns:msg(DnsMsg, header) -> dns_header() % for example
                  inet_dns:msg(DnsMsg, Field) -> Value

              dns_header() = DnsHeader
                  inet_dns:header(DnsHeader) ->
                      [ {id, integer()}
                      | {qr, boolean()}
                      | {opcode, 'query' | iquery | status | integer()}
                      | {aa, boolean()}
                      | {tc, boolean()}
                      | {rd, boolean()}
                      | {ra, boolean()}
                      | {pr, boolean()}
                      | {rcode, integer(0..16)} ]
                  inet_dns:header(DnsHeader, Field) -> Value

              query_type() = axfr | mailb | maila | any | rr_type()

              dns_query() = DnsQuery
                  inet_dns:dns_query(DnsQuery) ->
                      [ {domain, dns_name()}
                      | {type, query_type()}
                      | {class, dns_class()} ]
                  inet_dns:dns_query(DnsQuery, Field) -> Value

              dns_rr() = DnsRr
                  inet_dns:rr(DnsRr) -> DnsRrFields | DnsRrOptFields
                  DnsRrFields = [ {domain, dns_name()}
                                | {type, rr_type()}
                                | {class, dns_class()}
                                | {ttl, integer()}
                                | {data, dns_data()} ]
                  DnsRrOptFields = [ {domain, dns_name()}
                                   | {type, opt}
                                   | {udp_payload_size, integer()}
                                   | {ext_rcode, integer()}
                                   | {version, integer()}
                                   | {z, integer()}
                                   | {data, dns_data()} ]
                  inet_dns:rr(DnsRr, Field) -> Value

              There is an info function for the types above:

              inet_dns:record_type(dns_msg()) -> msg;
              inet_dns:record_type(dns_header()) -> header;
              inet_dns:record_type(dns_query()) -> dns_query;
              inet_dns:record_type(dns_rr()) -> rr;
              inet_dns:record_type(_) -> undefined.

              So; inet_dns:(inet_dns:record_type(X))(X) will convert
              any of these data structures into a {Field,Value} list.

       dns_data() = dns_name()
                  | inet:ip4_address()
                  | inet:ip6_address()
                  | {MName :: dns_name(),
                     RName :: dns_name(),
                     Serial :: integer(),
                     Refresh :: integer(),
                     Retry :: integer(),
                     Expiry :: integer(),
                     Minimum :: integer()}
                  | {inet:ip4_address(),
                     Proto :: integer(),
                     BitMap :: binary()}
                  | {CpuString :: string(), OsString :: string()}
                  | {RM :: dns_name(), EM :: dns_name()}
                  | {Prio :: integer(), dns_name()}
                  | {Prio :: integer(),
                     Weight :: integer(),
                     Port :: integer(),
                     dns_name()}
                  | {Order :: integer(),
                     Preference :: integer(),
                     Flags :: string(),
                     Services :: string(),
                     Regexp :: string(),
                     dns_name()}
                  | [string()]
                  | binary()

              Regexp is a string with characters encoded in the UTF-8 coding standard.

EXPORTS

       getbyname(Name, Type) -> {ok, Hostent} | {error, Reason}

       getbyname(Name, Type, Timeout) -> {ok, Hostent} | {error, Reason}

              Types:

                 Name = dns_name()
                 Type = rr_type()
                 Timeout = timeout()
                 Hostent = inet:hostent()
                 Reason = inet:posix() | res_error()

              Resolve  a DNS record of the given type for the given host, of class in. On success
              returns a hostent() record with dns_data() elements in the address list field.

              This function uses the resolver option search that is a list of  domain  names.  If
              the  name  to  resolve contains no dots, it is prepended to each domain name in the
              search list, and they are tried in order. If the name contains dots,  it  is  first
              tried  as  an  absolute name and if that fails the search list is used. If the name
              has a trailing dot it is simply supposed to be an absolute name and the search list
              is not used.

       gethostbyaddr(Address) -> {ok, Hostent} | {error, Reason}

       gethostbyaddr(Address, Timeout) -> {ok, Hostent} | {error, Reason}

              Types:

                 Address = inet:ip_address()
                 Timeout = timeout()
                 Hostent = inet:hostent()
                 Reason = inet:posix() | res_error()

              Backend functions used by  inet:gethostbyaddr/1 .

       gethostbyname(Name) -> {ok, Hostent} | {error, Reason}

       gethostbyname(Name, Family) -> {ok, Hostent} | {error, Reason}

       gethostbyname(Name, Family, Timeout) ->
                        {ok, Hostent} | {error, Reason}

              Types:

                 Name = dns_name()
                 Hostent = inet:hostent()
                 Timeout = timeout()
                 Family = inet:address_family()
                 Reason = inet:posix() | res_error()

              Backend functions used by  inet:gethostbyname/1,2 .

              This function uses the resolver option search just like getbyname/2,3.

              If  the  resolver  option  inet6 is true, an IPv6 address is looked up, and if that
              fails the IPv4 address is looked up and returned on IPv6 mapped IPv4 format.

       lookup(Name, Class, Type) -> [dns_data()]

       lookup(Name, Class, Type, Opts) -> [dns_data()]

       lookup(Name, Class, Type, Opts, Timeout) -> [dns_data()]

              Types:

                 Name = dns_name() | inet:ip_address()
                 Class = dns_class()
                 Type = rr_type()
                 Opts = [res_option() | verbose]
                 Timeout = timeout()

              Resolve the DNS data for the record of the given type and class for the given name.
              On  success  filters  out  the  answer  records with the correct Class and Type and
              returns a list of their data fields. So a lookup for type any will  give  an  empty
              answer  since  the  answer  records  have specific types that are not any. An empty
              answer as well as a failed lookup returns an empty list.

              Calls resolve/2..4 with the same arguments and  filters  the  result,  so  Opts  is
              explained there.

       resolve(Name, Class, Type) -> {ok, dns_msg()} | Error

       resolve(Name, Class, Type, Opts) -> {ok, dns_msg()} | Error

       resolve(Name, Class, Type, Opts, Timeout) ->
                  {ok, dns_msg()} | Error

              Types:

                 Name = dns_name() | inet:ip_address()
                 Class = dns_class()
                 Type = rr_type()
                 Opts = [Opt]
                 Opt = res_option() | verbose | atom()
                 Timeout = timeout()
                 Error = {error, Reason} | {error, {Reason, dns_msg()}}
                 Reason = inet:posix() | res_error()

              Resolve  a  DNS record of the given type and class for the given name. The returned
              dns_msg() can be examined using access functions in inet_db  as  described  in  DNS
              types.

              If  Name  is  an  ip_address(),  the  domain  name to query for is generated as the
              standard reverse ".IN-ADDR.ARPA." name for an IPv4  address,  or  the  ".IP6.ARPA."
              name for an IPv6 address. In this case you most probably want to use Class = in and
              Type = ptr but it is not done automatically.

              Opts override the corresponding resolver options.  If  the  option  nameservers  is
              given,  it  is  also  assumed  that  it  is the complete list of nameserves, so the
              resolver option alt_nameserves is ignored. Of course, if that option is also  given
              to this function, it is used.

              The  verbose option (or rather {verbose,true}), causes diagnostics printout through
              io:format/2 of queries, replies retransmissions, etc,  similar  to  from  utilities
              like dig, nslookup et.al.

              If  Opt is an arbitrary atom it is interpreted as {Opt,true} unless the atom string
              starts with "no" making the interpretation {Opt,false}. For example:  usevc  is  an
              alias for {usevc,true}, and nousevc an alias for {usevc,false}.

              The inet6 option currently has no effect on this function. You probably want to use
              Type = a | aaaa instead.

EXAMPLES

       Access functions example: how lookup/3 could have been implemented  using  resolve/3  from
       outside the module.

           example_lookup(Name, Class, Type) ->
               case inet_res:resolve(Name, Class, Type) of
                   {ok,Msg} ->
                       [inet_dns:rr(RR, data)
                        || RR <- inet_dns:msg(Msg, anlist),
                           inet_dns:rr(RR, type) =:= Type,
                           inet_dns:rr(RR, class) =:= Class];
                   {error,_} ->
                       []
               end.

LEGACY FUNCTIONS

       These  have  been deprecated due to the annoying double meaning of the nameservers/timeout
       argument, and because they had no decent place for a resolver options list.

EXPORTS

       nslookup(Name, Class, Type) -> {ok, dns_msg()} | {error, Reason}

       nslookup(Name, Class, Type, Timeout) ->
                   {ok, dns_msg()} | {error, Reason}

       nslookup(Name, Class, Type, Nameservers) ->
                   {ok, dns_msg()} | {error, Reason}

              Types:

                 Name = dns_name() | inet:ip_address()
                 Class = dns_class()
                 Type = rr_type()
                 Timeout = timeout()
                 Nameservers = [nameserver()]
                 Reason = inet:posix() | res_error()

              Resolve a DNS record of the given type and class for the given name.

       nnslookup(Name, Class, Type, Nameservers) ->
                    {ok, dns_msg()} | {error, Reason}

       nnslookup(Name, Class, Type, Nameservers, Timeout) ->
                    {ok, dns_msg()} | {error, Reason}

              Types:

                 Name = dns_name() | inet:ip_address()
                 Class = dns_class()
                 Type = rr_type()
                 Timeout = timeout()
                 Nameservers = [nameserver()]
                 Reason = inet:posix()

              Resolve a DNS record of the given type and class for the given name.