Sovite.DNS.MX (sovite v0.6.0)

Copy Markdown View Source

Finds the hosts that accept mail for a domain (RFC 5321 §5.1).

{:ok, hosts} = Sovite.DNS.MX.resolve(resolver, "example.com")
#=> [{"mx1.example.com", [{192, 0, 2, 25}, {8193, 3512, 0, 0, 0, 0, 0, 25}]}, ...]

hosts/2 looks up the MX records:

  • Hosts are ordered by preference. Hosts with the same preference are shuffled, to spread load as the RFC asks.
  • A domain with no MX records but with address records is its own mail host (implicit MX).
  • A Null MX (RFC 7505), a single record with exchange ".", means the domain accepts no mail: {:error, :null_mx}.

resolve/3 also looks up each host's addresses, and resolve_secure/3 also says for each host whether DNSSEC authenticated all of it, as DANE requires (RFC 7672 §2.2).

Summary

Types

Why there are no mail hosts.

An MX host and its preference.

Functions

Looks up the addresses of host for each record type in families, and returns them in that order. An address literal such as "[192.0.2.1]" is returned as is, without a lookup.

Returns the MX hosts for domain, best first.

Returns the mail hosts for domain with their addresses, best first.

Like resolve/3, and also says for each host whether DNSSEC authenticated its MX records (or, for an implicit MX, the domain's missing MX records) and all its address lookups. Only then may DANE be used for the host (RFC 7672 §2.2.1, §2.2.2).

Like addresses/3, through Sovite.DNS.lookup_secure/3, and also says whether DNSSEC authenticated every lookup that answered. Address literals are never secure.

Types

error()

@type error() ::
  :null_mx
  | :nxdomain
  | :no_hosts
  | :loops_back
  | :no_addresses
  | {:temporary, Sovite.DNS.Resolver.error()}

Why there are no mail hosts.

  • :null_mx - the domain publishes a Null MX. Permanent.
  • :nxdomain - the domain does not exist. Permanent.
  • :no_hosts - the domain exists but has neither MX nor address records. Permanent.
  • :loops_back - this server is the best MX host (see :exclude). Permanent.
  • :no_addresses - none of the MX hosts has an address. Permanent.
  • {:temporary, reason} - a DNS error; try again later.

mx()

@type mx() :: {preference :: non_neg_integer(), host :: String.t()}

An MX host and its preference.

Functions

addresses(resolver, host, families \\ [:aaaa, :a])

@spec addresses(Sovite.DNS.resolver(), String.t(), [:a | :aaaa]) ::
  {:ok, [:inet.ip_address()]} | {:error, Sovite.DNS.Resolver.error()}

Looks up the addresses of host for each record type in families, and returns them in that order. An address literal such as "[192.0.2.1]" is returned as is, without a lookup.

Returns the addresses found, even if another lookup failed, so a host with only IPv4 addresses gives {:ok, ipv4s}. Without any address, a DNS error other than NXDOMAIN is returned, since a retry might find one; otherwise {:ok, []} (NODATA) or {:error, :nxdomain}.

hosts(resolver, domain, opts \\ [])

@spec hosts(Sovite.DNS.resolver(), String.t(), keyword()) ::
  {:ok, [mx(), ...]} | {:error, error()}

Returns the MX hosts for domain, best first.

Options

  • :exclude - host names that are this server. If one of them is an MX host, it and every host with the same or a worse preference are removed (RFC 5321 §5.1), so a backup MX never relays to itself or to a worse backup.

resolve(resolver, domain, opts \\ [])

@spec resolve(Sovite.DNS.resolver(), String.t(), keyword()) ::
  {:ok, [{String.t(), [:inet.ip_address(), ...]}, ...]} | {:error, error()}

Returns the mail hosts for domain with their addresses, best first.

Hosts without addresses are left out. If no host has an address, the result is {:error, :no_addresses}, or {:error, {:temporary, reason}} if some lookups failed with a DNS error.

Options

  • :exclude - see hosts/3.
  • :families - address types to look up, in order of preference: [:aaaa, :a] (default), [:a, :aaaa], [:a], or [:aaaa].

resolve_secure(resolver, domain, opts \\ [])

@spec resolve_secure(Sovite.DNS.resolver(), String.t(), keyword()) ::
  {:ok, [{String.t(), [:inet.ip_address(), ...], boolean()}, ...]}
  | {:error, error()}

Like resolve/3, and also says for each host whether DNSSEC authenticated its MX records (or, for an implicit MX, the domain's missing MX records) and all its address lookups. Only then may DANE be used for the host (RFC 7672 §2.2.1, §2.2.2).

Takes the same options, and :dnssec: with false, lookups go through Sovite.DNS.lookup/3 and no host is secure. Defaults to true, for Sovite.DNS.lookup_secure/3.

secure_addresses(resolver, host, families \\ [:aaaa, :a])

@spec secure_addresses(Sovite.DNS.resolver(), String.t(), [:a | :aaaa]) ::
  {:ok, [:inet.ip_address()], boolean()} | {:error, Sovite.DNS.Resolver.error()}

Like addresses/3, through Sovite.DNS.lookup_secure/3, and also says whether DNSSEC authenticated every lookup that answered. Address literals are never secure.