Next: , Previous: , Up: Library   [Contents][Index]

5.24 DNS Functions

MFL offers two sets of functions for querying the Domain Name System. The dns_query function and associated dns_reply_ functions provide a generalized DNS API.

Other functions provide a simplified API.


Next: , Up: DNS functions   [Contents][Index]

5.24.1 dns_query

Built-in Function: number dns_query (number type, string domain; number sort, number resolve)

This function looks up the domain name name. The type argument specifies type of the query to perform. On success, the function returns DNS reply descriptor, a non-negative integer number identifying the reply. It can then be passed to any of the ‘dns_reply_’ functions discussed below in order to retrieve the information from it.

If no matching records were found, the function returns ‘-1’.

On error, it throws a corresponding exception.

The type argument is one of the following constants (defined in the module ‘dns’):

DNS_TYPE_A

Query the ‘A’ record. The domain should be the hostname to look up.

DNS_TYPE_NS

Query the ‘NS’ records.

DNS_TYPE_PTR

Query the ‘PTR’ record. The domain address should be the IP address in dotted-quad form.

DNS_TYPE_MX

Query the ‘MX’ records.

DNS_TYPE_TXT

Query the ‘TXT’ records.

If the query returns multiple RR sets, the optional argument sort controls whether they should be returned in the same order as obtained from the DNS (0, the default), or should be sorted (1).

Optional argument resolve is consulted if type is DNS_TYPE_MX or DNS_TYPE_NS. By default, queries for these types return hostnames. The resolve argument controls whether to return IP addresses instead. Its possible values (defined in module status.mfl are:

RESOLVE_NONE

Don’t resolve hostnames to IP addresses. This is the default.

RESOLVE_DFL

Resolve hostnames to IP addresses according to the address family of the SMTP session. That is, use ‘A’ records if the client connected using the INET family (i.e. connected to the IPv4 address), and use ‘AAAA’ records if the client connected to the IPv6 address.

RESOLVE_IP4

Resolve hostnames to IPv4 addresses (‘A’ records).

RESOLVE_IP6

Resolve hostnames to IPv6 addresses (‘AAAA’ records).

To extract actual data from the dns_query return value, use the functions dns_reply_count and dns_reply_string. The usual processing sequence is:

  require dns

  # Send the query and save the reply descriptor
  set n dns_query(DNS_TYPE_NS, domain_name)

  if n >= 0
    # If non-empty set is returned, iterate over each value in it:
    loop for set i 0,
         while i < dns_reply_count(n),
         set i i + 1
    do
      # Get the actual data:
      echo dns_reply_string(n, i)
    done
    # Release the memory associated with the reply.
    dns_reply_release(n)
  fi
Built-in Function: void dns_reply_release (number rd)

Release the memory associated with the reply rd. If rd is -1, the function does nothing.

Built-in Function: number dns_reply_count (number rd)

Return the number of records in the reply rd. For convenience, if rd is -1, the function returns 0. If rd is negative (excepting -1), a ‘e_failure’ exception is thrown.

Built-in Function: string dns_reply_string (number rd, number n)

Returns nth record from the DNS reply rd.

Built-in Function: number dns_reply_ip (number rd, number n)

Returns nth record from the DNS reply rd, if the reply contains IPv4 addresses.


Previous: , Up: DNS functions   [Contents][Index]

5.24.2 Simplified DNS functions

These functions are implemented in two layers: primitive built-in functions which raise exceptions if the lookup fails, and library calls that are warranted to always return meaningful value without throwing exceptions.

The built-in layer is always available. The library calls become available after requesting the dns module (see Modules):

require dns
Library Function: string dns_getaddr (string domain)

Returns a whitespace-separated list of IP addresses (A records) for domain.

Library Function: string dns_getname (string ipstr)

Returns a whitespace-separated list of domain names (PTR records) for the IPv4 address ipstr.

Library Function: string getmx (string domain [, boolean ip])

Returns a whitespace-separated list of ‘MX’ names (if ip is not given or if it is 0) or ‘MXIP addresses (if ip!=0)) for domain. Within the returned string, items are sorted in order of increasing ‘MX’ priority. If domain has no ‘MX’ records, an empty string is returned. If the DNS query fails, getmx raises an appropriate exception.

Examples:

getmx("mafra.cz") ⇒ "smtp1.mafra.cz smtp2.mafra.cz relay.iol.cz"
getmx("idnes.cz") ⇒ "smtp1.mafra.cz smtp2.mafra.cz relay.iol.cz"
getmx("gnu.org")  ⇒ "mx10.gnu.org mx20.gnu.org"
getmx("org.pl") ⇒ ""

Notes:

  1. Number of items returned by getmx(domain) can differ from that obtained from getmx(domain, 1), e.g.:
    getmx("aol.com")
      ⇒ mailin-01.mx.aol.com mailin-02.mx.aol.com
                mailin-03.mx.aol.com mailin-04.mx.aol.com
    getmx("aol.com", 1)
      ⇒ 64.12.137.89 64.12.137.168 64.12.137.184
                64.12.137.249 64.12.138.57 64.12.138.88
                64.12.138.120 64.12.138.185 205.188.155.89
                205.188.156.185 205.188.156.249 205.188.157.25
                205.188.157.217 205.188.158.121 205.188.159.57
                205.188.159.217
    
  2. This function is a wrapper over dns_query.

    If you intend to iterate over returned values, better use dns_query directly, e.g. instead of doing

    string_list_iterate(getmx(domain), ` ', MX, `do_something(MX)')
    

    use

      set n dns_query(DNS_TYPE_MX, domain)
      if n >= 0
        loop for set i 0,
             while i < dns_reply_count(n),
             set i i + 1
        do
          do_something(dns_reply_string(n, i))
        done
        dns_reply_release(n)
      fi
    

    See dns_query, for details about the dns_query function and associated dns_reply_* calls.

  3. This interface is semi-deprecated.

    It will most probably be removed in future releases, when array data types are implemented.

Built-in Function: boolean primitive_hasmx (string domain)

Returns true if the domain name given by its argument has any ‘MX’ records.

If the DNS query fails, this function throws failure or temp_failure.

Library Function: boolean hasmx (string domain)

Returns true if the domain name given by its argument has any ‘MX’ records.

Otherwise, if domain has no ‘MX’s or if the DNS query fails, hasmx returns false.

Built-in Function: string primitive_hostname (string ip)

The ip argument should be a string representing an IP address in dotted-quad notation. The function returns the canonical name of the host with this IP address obtained from DNS lookup. For example

primitive_hostname (${client_addr})

returns the fully qualified domain name of the host represented by Sendmail variable ‘client_addr’.

If there is no ‘PTR’ record for ip, primitive_hostname raises the exception e_not_found.

If DNS query fails, the function raises failure or temp_failure, depending on the character of the failure.

Library Function: string hostname (string ip)

The ip argument should be a string representing an IP address in dotted-quad notation. The function returns the canonical name of the host with this IP address obtained from DNS lookup.

If there is no ‘PTR’ record for ip, or if the lookup fails, the function returns ip unchanged.

The previous mailfromd versions used the following paradigm to check if an IP address resolves:

  if hostname(ip) != ip
    ...
Built-in Function: boolean primitive_ismx (string domain, string host)

The domain argument is any valid domain name, the host is a host name or IP address.

The function returns true if host is one of the ‘MX’ records for the domain.

If domain has no ‘MX’ records, primitive_ismx raises exception e_not_found.

If DNS query fails, the function raises failure or temp_failure, depending on the character of the failure.

Library Function: boolean ismx (string domain, string host)

The domain argument is any valid domain name, the host is a host name or IP address.

The function returns true if host is one of the ‘MX’ records for the domain. Otherwise it returns false.

If domain has no ‘MX’ records, or if the DNS query fails, the function returns false.

Built-in Function: string primitive_resolve (string host, [string domain, number family])

Reverse of primitive_hostname. The primitive_resolve function returns the IP address for the host name specified by its host argument. If the SMTP session uses IPv4 protocol, ‘A’ record is queried. It it uses IPv6, ‘AAAA’ record is queried. A particular record type can be requested via optional family, which can have one of the following values (defined in status.mfl):

RESOLVE_DFL

Look for ‘A’ or ‘AAAA’, depending on the connection type. This is the default.

RESOLVE_IP4

Resolve to IPv4 addresses (‘A’ records).

RESOLVE_IP6

Resolve to IPv6 addresses (‘AAAA’ records).

If host has no records of the requested type, the function raises the exception e_not_found.

If DNS lookup fails, the function raises failure or temp_failure, depending on the character of the failure.

Optional domain argument is deprecated. If a non-empty string is given as domain, the function works as follows:

  1. If domain is ‘in-addr.arpa’ (case-insensitive)

    The host must be a string representation of an IPv4 address in dotted-quad form. If it is not, a e_inval exception is thrown. The octets in the IPv4 are reversed, a dot and ‘domain’ are appended to it, and a ‘PTR’ record is queried for the resulting name.

    Thus, the call

    primitive_resolve("192.0.2.1", "in-addr.arpa")
    

    is equivalent to

    primitive_hostname("192.0.2.1")
    
  2. domain is ‘ip6.arpa’ (case-insensitive)

    The host must be a string representation of an IPv6. If it is not, a e_inval exception is thrown. The octets of this IPv6 address are reversed, a dot and ‘domain’ are appended to it, and a ‘PTR’ record is queried for the resulting name.

    Thus, the call

    primitive_resolve("2001:DB8::1", "ip6.arpa")
    

    is equivalent to

    primitive_hostname("2001:DB8::1")
    
  3. host is a string representation of an IPv4 address

    The address is reversed as in (1), then a dot and ‘domain’ are appended to it. Finally, the DNS is queried for an ‘A’ record of the resulting name.

    Thus,

    primitive_resolve("192.0.2.1", "rev.example.com")
    

    is equivalent to

    primitive_resolve("1.2.0.192.rev.example.com")
    
  4. host is a string representation of an IPv6 address

    The address is reversed as in (2), then a dot and ‘domain’ are appended to it. Finally, the DNS is queried for an ‘AAAA’ record of the resulting name.

  5. None of the above. Same as primitive_hostname(‘host.domain’,'',resolve).
Library Function: string resolve (string host, [string domain, number family])

Reverse of hostname. The resolve function returns IP address for the host name specified by host argument. If the host name cannot be resolved, or a DNS failure occurs, the function returns ‘"0"’.

This function is entirely equivalent to primitive_resolve (see above), except that it never raises exceptions.

Built-in Function: string ptr_validate (string ip)

Tests whether the DNS reverse-mapping for ip exists and correctly points to a domain name within a particular domain.

First, it obtains all ‘PTR’ records for ip. Then, for each record returned, a look up for ‘A’ (or ‘AAAA’, if ip is an IPv6 address) records is performed and IP addresses of each record are compared against ip. The function returns true if a matching ‘A’ (or ‘AAAA’) record is found.

This function can raise the following exceptions:

e_not_found

Unable to resolve IP address or hostname.

e_failure

Fatal error while resolving.

e_temp_failure

Temporary error in DNS resolution.

e_too_many

Too many CNAME records (see CNAME chains).

Built-in Function: boolean primitive_hasns (string domain)

Returns ‘True’ if the domain domain has at least one ‘NS’ record. Throws exception if DNS lookup fails.

Library Function: boolean hasns (string domain)

Returns ‘True’ if the domain domain has at least one ‘NS’ record. Returns ‘False’ if there are no ‘NS’ records or if the DNS lookup fails.

Library Function: string getns (string domain ; boolean resolve, boolean sort)

Returns a whitespace-separated list of all the ‘NS’ records for the domain domain. Optional parameters resolve and sort control the formatting. If resolve is 0 (the default), the resulting string will contain IP addresses of the NS servers. If resolve is not 0, hostnames will be returned instead. If sort is 1, the returned items will be sorted.

If the DNS query fails, getns raises an appropriate exception.

Notes:

  1. This function is a wrapper over dns_query.

    If you intend to iterate over returned values, better use dns_query directly, e.g. instead of doing

    string_list_iterate(getns(domain), ` ', NS, `do_something(NS)')
    

    use

      set n dns_query(DNS_TYPE_NS, domain)
      if n >= 0
        loop for set i 0,
             while i < dns_reply_count(n),
             set i i + 1
        do
          do_something(dns_reply_string(n, i))
        done
        dns_reply_release(n)
      fi
    

    See dns_query, for details about the dns_query function and associated dns_reply_* calls.

  2. This interface is semi-deprecated.

    It will most probably be removed in future releases, when array data types are implemented.


Previous: , Up: DNS functions   [Contents][Index]