Provided by: erlang-manpages_18.3-dfsg-1ubuntu3.1_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.

RESOLVER TYPES

       The following data types concern the resolver:

DATA 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

       The following data types concern the DNS client:

DATA 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.