# class Resolv::DNS

`Resolv::DNS` is a `DNS` stub resolver.

Information taken from the following places:

- STD0013

- RFC 1035

- ftp.isi.edu/in-notes/iana/assignments/dns-parameters

- etc.

### Constants

Port

  Default `DNS` `Port`

UDPSize

  Default `DNS` UDP packet size

### Public Class Methods

new (config_info=nil)
Source

    # File lib/resolv.rb, line 335
    def initialize(config_info=nil)
      @mutex = Thread::Mutex.new
      @config = Config.new(config_info)
      @initialized = nil
    end

Creates a new `DNS` resolver.

`config_info` can be:

nil

  Uses /etc/resolv.conf.

`String`

  Path to a file using /etc/resolv.conf’s format.

`Hash`

  Must contain :nameserver, :search and :ndots keys.

:nameserver_port can be used to specify port number of nameserver address. :raise_timeout_errors can be used to raise timeout errors as exceptions instead of treating the same as an NXDOMAIN response.

The value of :nameserver should be an address string or an array of address strings.

- :nameserver => ‘8.8.8.8’

- :nameserver => [‘8.8.8.8’, ‘8.8.4.4’]

The value of :nameserver_port should be an array of pair of nameserver address and port number.

- :nameserver_port => [[‘8.8.8.8’, 53], [‘8.8.4.4’, 53]]

Example:

    Resolv::DNS.new(:nameserver => ['210.251.121.21'],
                    :search => ['ruby-lang.org'],
                    :ndots => 1)

open (*args) { |dns| ... }
Source

    # File lib/resolv.rb, line 298
    def self.open(*args)
      dns = new(*args)
      return dns unless block_given?
      begin
        yield dns
      ensure
        dns.close
      end
    end

Creates a new `DNS` resolver. See `Resolv::DNS.new` for argument details.

Yields the created `DNS` resolver to the block, if given, otherwise returns it.

### Public Instance Methods

close ()
Source

    # File lib/resolv.rb, line 369
    def close
      @mutex.synchronize {
        if @initialized
          @initialized = false
        end
      }
    end

Closes the `DNS` resolver.

each_address (name) { |address| ... }
Source

    # File lib/resolv.rb, line 407
    def each_address(name)
      if use_ipv6?
        each_resource(name, Resource::IN::AAAA) {|resource| yield resource.address}
      end
      each_resource(name, Resource::IN::A) {|resource| yield resource.address}
    end

Iterates over all IP addresses for `name` retrieved from the `DNS` resolver.

`name` can be a `Resolv::DNS::Name` or a `String`. Retrieved addresses will be a `Resolv::IPv4` or `Resolv::IPv6`

each_name (address) { |name| ... }
Source

    # File lib/resolv.rb, line 461
    def each_name(address)
      case address
      when Name
        ptr = address
      when IPv4, IPv6
        ptr = address.to_name
      when IPv4::Regex
        ptr = IPv4.create(address).to_name
      when IPv6::Regex
        ptr = IPv6.create(address).to_name
      else
        raise ResolvError.new("cannot interpret as address: #{address}")
      end
      each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name}
    end

Iterates over all hostnames for `address` retrieved from the `DNS` resolver.

`address` must be a `Resolv::IPv4`, `Resolv::IPv6` or a `String`. Retrieved names will be `Resolv::DNS::Name` instances.

each_resource (name, typeclass, &proc)
Source

    # File lib/resolv.rb, line 519
    def each_resource(name, typeclass, &proc)
      fetch_resource(name, typeclass) {|reply, reply_name|
        extract_resources(reply, reply_name, typeclass, &proc)
      }
    end

Iterates over all `typeclass` `DNS` resources for `name`. See `getresource` for argument details.

fetch_resource (name, typeclass) { |reply, reply_name| ... }
Source

    # File lib/resolv.rb, line 525
    def fetch_resource(name, typeclass)
      lazy_initialize
      truncated = {}
      requesters = {}
      udp_requester = begin
        make_udp_requester
      rescue Errno::EACCES
        # fall back to TCP
      end
      senders = {}

      begin
        @config.resolv(name) do |candidate, tout, nameserver, port|
          msg = Message.new
          msg.rd = 1
          msg.add_question(candidate, typeclass)

          requester = requesters.fetch([nameserver, port]) do
            if !truncated[candidate] && udp_requester
              udp_requester
            else
              requesters[[nameserver, port]] = make_tcp_requester(nameserver, port)
            end
          end

          unless sender = senders[[candidate, requester, nameserver, port]]
            sender = requester.sender(msg, candidate, nameserver, port)
            next if !sender
            senders[[candidate, requester, nameserver, port]] = sender
          end
          reply, reply_name = requester.request(sender, tout)
          case reply.rcode
          when RCode::NoError
            if reply.tc == 1 and not Requester::TCP === requester
              # Retry via TCP:
              truncated[candidate] = true
              redo
            else
              yield(reply, reply_name)
            end
            return
          when RCode::NXDomain
            raise Config::NXDomain.new(reply_name.to_s)
          else
            raise Config::OtherResolvError.new(reply_name.to_s)
          end
        end
      ensure
        udp_requester&.close
        requesters.each_value { |requester| requester&.close }
      end
    end

getaddress (name)
Source

    # File lib/resolv.rb, line 383
    def getaddress(name)
      each_address(name) {|address| return address}
      raise ResolvError.new("DNS result has no information for #{name}")
    end

Gets the IP address of `name` from the `DNS` resolver.

`name` can be a `Resolv::DNS::Name` or a `String`. Retrieved address will be a `Resolv::IPv4` or `Resolv::IPv6`

getaddresses (name)
Source

    # File lib/resolv.rb, line 394
    def getaddresses(name)
      ret = []
      each_address(name) {|address| ret << address}
      return ret
    end

Gets all IP addresses for `name` from the `DNS` resolver.

`name` can be a `Resolv::DNS::Name` or a `String`. Retrieved addresses will be a `Resolv::IPv4` or `Resolv::IPv6`

getname (address)
Source

    # File lib/resolv.rb, line 437
    def getname(address)
      each_name(address) {|name| return name}
      raise ResolvError.new("DNS result has no information for #{address}")
    end

Gets the hostname for `address` from the `DNS` resolver.

`address` must be a `Resolv::IPv4`, `Resolv::IPv6` or a `String`. Retrieved name will be a `Resolv::DNS::Name`.

getnames (address)
Source

    # File lib/resolv.rb, line 448
    def getnames(address)
      ret = []
      each_name(address) {|name| ret << name}
      return ret
    end

Gets all hostnames for `address` from the `DNS` resolver.

`address` must be a `Resolv::IPv4`, `Resolv::IPv6` or a `String`. Retrieved names will be `Resolv::DNS::Name` instances.

getresource (name, typeclass)
Source

    # File lib/resolv.rb, line 500
    def getresource(name, typeclass)
      each_resource(name, typeclass) {|resource| return resource}
      raise ResolvError.new("DNS result has no information for #{name}")
    end

Look up the `typeclass` `DNS` resource of `name`.

`name` must be a `Resolv::DNS::Name` or a `String`.

`typeclass` should be one of the following:

- `Resolv::DNS::Resource::IN::A`

- `Resolv::DNS::Resource::IN::AAAA`

- Resolv::DNS::Resource::IN::ANY

- Resolv::DNS::Resource::IN::CNAME

- Resolv::DNS::Resource::IN::HINFO

- Resolv::DNS::Resource::IN::MINFO

- Resolv::DNS::Resource::IN::MX

- Resolv::DNS::Resource::IN::NS

- Resolv::DNS::Resource::IN::PTR

- Resolv::DNS::Resource::IN::SOA

- Resolv::DNS::Resource::IN::TXT

- `Resolv::DNS::Resource::IN::WKS`

Returned resource is represented as a `Resolv::DNS::Resource` instance, i.e. `Resolv::DNS::Resource::IN::A`.

getresources (name, typeclass)
Source

    # File lib/resolv.rb, line 509
    def getresources(name, typeclass)
      ret = []
      each_resource(name, typeclass) {|resource| ret << resource}
      return ret
    end

Looks up all `typeclass` `DNS` resources for `name`. See `getresource` for argument details.

timeouts= (values)
Source

    # File lib/resolv.rb, line 352
    def timeouts=(values)
      @config.timeouts = values
    end

Sets the resolver timeouts. This may be a single positive number or an array of positive numbers representing timeouts in seconds. If an array is specified, a `DNS` request will retry and wait for each successive interval in the array until a successful response is received. Specifying `nil` reverts to the default timeouts:

5, second = 5 * 2 / nameserver_count, 2 * second, 4 * second

  Example:

      dns.timeouts = 3