Module resty.dns.client

DNS client.

Works with OpenResty only. Requires the lua-resty-dns module.

NOTES:

  1. parsing the config files upon initialization uses blocking i/o, so use with care. See init for details.
  2. All returned records are directly from the cache. So do not modify them! If you need to, copy them first.
  3. TTL for records is the TTL returned by the server at the time of fetching and won't be updated while the client serves the records from its cache.
  4. resolving IPv4 (A-type) and IPv6 (AAAA-type) addresses is explicitly supported. If the hostname to be resolved is a valid IP address, it will be cached with a ttl of 10 years. So the user doesn't have to check for ip adresses.

Info:

  • Copyright: 2016-2017 Kong Inc.
  • License: Apache 2.0
  • Author: Thijs Schreijer

Resolving

init (options) Initialize the client.
resolve (qname, r_opts, dnsCacheOnly, try_list) Resolve a name.
toip (qname, port, dnsCacheOnly, try_list) Resolves to an IP and port number.

Socket functions

connect (sock, host, port, opts) Implements tcp-connect method with dns resolution.
setpeername (sock, host, port) Implements udp-setpeername method with dns resolution.


Resolving

When resolving names, queries will be synchronized, such that only a single query will be sent. If stale data is available, the request will return stale data immediately, whilst continuing to resolve the name in the background.

The dnsCacheOnly parameter found with resolve and toip can be used in contexts where the co-socket api is unavailable. When the flag is set only cached data is returned, but it will never use blocking io.

init (options)
Initialize the client. Can be called multiple times. When called again it will clear the cache.

Parameters:

Returns:

    true on success, nil+error, or throw an error on bad input

Usage:

    -- config files to parse
    -- hosts and resolvConf can both be a filename, or a table with file-contents
    -- The contents of the hosts file will be inserted in the cache.
    -- From resolv.conf the nameserver, search, ndots, attempts and timeout values will be used.
    local hosts = {}  -- initialize without any blocking i/o
    local resolvConf = {}  -- initialize without any blocking i/o
    
    -- when getting nameservers from resolv.conf, get ipv6 servers?
    local enable_ipv6 = false
    
    -- Order in which to try different dns record types when resolving
    -- 'last'; will try the last previously successful type for a hostname.
    local order = { "last", "SRV", "A", "AAAA", "CNAME" }
    
    -- Stale ttl for how long a stale record will be served from the cache
    -- while a background lookup is in progress.
    local staleTtl = 4.0    -- in seconds (can have fractions)
    
    -- Cache ttl for empty and 'name error' (3) responses
    local emptyTtl = 30.0   -- in seconds (can have fractions)
    
    -- Cache ttl for other error responses
    local badTtl = 1.0      -- in seconds (can have fractions)
    
    -- Overriding ttl for valid queries, if given
    local validTtl = nil    -- in seconds (can have fractions)
    
    -- ndots, same as the resolv.conf option, if not given it is taken from
    -- resolv.conf or otherwise set to 1
    local ndots = 1
    
    -- no_random, if set disables randomly picking the first nameserver, if not
    -- given it is taken from resolv.conf option rotate (inverted).
    -- Defaults to true.
    local no_random = true
    
    -- search, same as the resolv.conf option, if not given it is taken from
    -- resolv.conf, or set to the domain option, or no search is performed
    local search = {
      "mydomain.com",
      "site.domain.org",
    }
    
    -- Disables synchronization between queries, resulting in each lookup for the
    -- same name being executed in it's own query to the nameservers. The default
    -- (false) will synchronize multiple queries for the same name to a single
    -- query to the nameserver.
    noSynchronisation = false
    
    assert(client.init({
             hosts = hosts,
             resolvConf = resolvConf,
             ndots = ndots,
             no_random = no_random,
             search = search,
             order = order,
             badTtl = badTtl,
             emptyTtl = emptTtl,
             staleTtl = staleTtl,
             validTtl = validTtl,
             enable_ipv6 = enable_ipv6,
             noSynchronisation = noSynchronisation,
           })
    )
resolve (qname, r_opts, dnsCacheOnly, try_list)
Resolve a name. If r_opts.qtype is given, then it will fetch that specific type only. If r_opts.qtype is not provided, then it will try to resolve the name using the record types, in the order as provided to init.

Note that unless explictly requesting a CNAME record (by setting r_opts.qtype) this function will dereference the CNAME records.

So requesting my.domain.com (assuming to be an AAAA record, and default order) will try to resolve it (the first time) as;

  • SRV,
  • then A,
  • then AAAA (success),
  • then CNAME (after AAAA success, this will not be tried)

A second lookup will now try (assuming the cached entry expired);

  • AAAA (as it was the last successful lookup),
  • then SRV,
  • then A,
  • then CNAME.

The outer loop will be based on the search and ndots options. Within each of those, the inner loop will be the query/record type.

Parameters:

  • qname Name to resolve
  • r_opts Options table, see remark about the qtype field above and OpenResty docs for more options.
  • dnsCacheOnly Only check the cache, won't do server lookups
  • try_list (optional) list of tries to add to

Returns:

    list of records + nil + try_list, or nil + err + try_list.
toip (qname, port, dnsCacheOnly, try_list)
Resolves to an IP and port number. Builds on top of resolve, but will also further dereference SRV type records.

When calling multiple times on cached records, it will apply load-balancing based on a round-robin (RR) scheme. For SRV records this will be a weighted round-robin (WRR) scheme (because of the weights it will be randomized). It will apply the round-robin schemes on each level individually.

Example;

SRV record for "my.domain.com", containing 2 entries (this is the 1st level);

  • target = 127.0.0.1, port = 80, weight = 10
  • target = "other.domain.com", port = 8080, weight = 5

A record for "other.domain.com", containing 2 entries (this is the 2nd level);

  • ip = 127.0.0.2
  • ip = 127.0.0.3

Now calling local ip, port = toip("my.domain.com", 123) in a row 6 times will result in;

  • 127.0.0.1, 80
  • 127.0.0.2, 8080 (port from SRV, 1st IP from A record)
  • 127.0.0.1, 80 (completes WRR 1st level, 1st run)
  • 127.0.0.3, 8080 (port from SRV, 2nd IP from A record, completes RR 2nd level)
  • 127.0.0.1, 80
  • 127.0.0.1, 80 (completes WRR 1st level, 2nd run, with different order as WRR is randomized)

Debugging:

This function both takes and returns a try_list. This is an internal object representing the entire resolution history for a call. To prevent unnecessary string concatenations on a hot code path, it is not logged in this module. If you need to log it, just log tostring(try_list) from the caller code.

Parameters:

  • qname hostname to resolve
  • port (optional) default port number to return if none was found in the lookup chain (only SRV records carry port information, SRV with port=0 will be ignored)
  • dnsCacheOnly Only check the cache, won't do server lookups (will not invalidate any ttl expired data and will hence possibly return expired data)
  • try_list (optional) list of tries to add to

Returns:

    ip address + port + try_list, or in case of an error nil + error + try_list

Socket functions

connect (sock, host, port, opts)
Implements tcp-connect method with dns resolution. This builds on top of toip. If the name resolves to an SRV record, the port returned by the DNS server will override the one provided.

NOTE: can also be used for other connect methods, eg. http/redis clients, as long as the argument order is the same

Parameters:

  • sock the tcp socket
  • host hostname to connect to
  • port port to connect to (will be overridden if toip returns a port)
  • opts the options table

Returns:

    success, or nil + error
setpeername (sock, host, port)
Implements udp-setpeername method with dns resolution. This builds on top of toip. If the name resolves to an SRV record, the port returned by the DNS server will override the one provided.

Parameters:

  • sock the udp socket
  • host hostname to connect to
  • port port to connect to (will be overridden if toip returns a port)

Returns:

    success, or nil + error
generated by LDoc 1.4.6 Last updated 2021-07-06 11:55:24