Class Dnsruby::Resolver
In: lib/Dnsruby/Resolver.rb
Parent: Object

Description

 This class uses a set of SingleResolvers to perform queries with retries across multiple nameservers.

 The retry policy is a combination of the Net::DNS and dnsjava approach, and has the option of :
  • A total timeout for the query (defaults to 0, meaning "no total timeout")
  • A retransmission system that targets the namervers concurrently once the first query round is complete, but in which the total time per query round is split between the number of nameservers targetted for the first round. and total time for query round is doubled for each query round

    Note that, if a total timeout is specified, then that will apply regardless of the retry policy (i.e. it may cut retries short).

    Note also that these timeouts are distinct from the SingleResolver‘s packet_timeout

Methods

Synchronous

These methods raise an exception or return a response message with rcode==NOERROR

Asynchronous

These methods use a response queue to return the response and the error

Event Loop

Dnsruby runs a pure Ruby event loop to handle I/O in a single thread. It is also possible to configure Dnsruby to use EventMachine instead. See the Dnsruby::Resolver::use_eventmachine method for details.

Note that, if using Dnsruby from an EventMachine loop, you will need to tell Dnsruby not to start the event loop itself :

   Dnsruby::Resolver::use_eventmachine(true)
   Dnsruby::Resolver::start_eventmachine_loop(false)

Methods

Constants

DefaultQueryTimeout = 0
DefaultPacketTimeout = 10
DefaultRetryTimes = 4
DefaultRetryDelay = 5
DefaultPort = 53
DefaultUDPSize = 512

Attributes

config  [R]  The current Config
ignore_truncation  [R]  Should truncation be ignored? i.e. the TC bit is ignored and thus the resolver will not requery over TCP if TC is set
packet_timeout  [R]  The timeout for any individual packet. This is the timeout used by SingleResolver
persistent_tcp  [R]  Should TCP queries be sent on a persistent socket?
persistent_udp  [R]  Should UDP queries be sent on a persistent socket?
port  [R]  The port to send queries to on the resolver
query_timeout  [RW]  Note that this timeout represents the total time a query may run for - multiple packets can be sent to multiple nameservers in this time. This is distinct from the SingleResolver per-packet timeout The query_timeout is not required - it will default to 0, which means "do not use query_timeout". If this is the case then the timeout will be dictated by the retry_times and retry_delay attributes
recurse  [R]  Should the Recursion Desired bit be set?
retry_delay  [RW]  The query will be tried across nameservers retry_times times, with a delay of retry_delay seconds between each retry. The first time round, retry_delay will be divided by the number of nameservers being targetted, and a new nameserver will be queried with the resultant delay.
retry_times  [RW]  The query will be tried across nameservers retry_times times, with a delay of retry_delay seconds between each retry. The first time round, retry_delay will be divided by the number of nameservers being targetted, and a new nameserver will be queried with the resultant delay.
single_resolvers  [R]  The array of SingleResolvers used for sending query messages
src_address  [R]  The source address to send queries from
src_port  [R]  The source port to send queries from
tsig_key  [R] 
udp_size  [R]  The maximum UDP size to be used
use_tcp  [R]  Should TCP be used as a transport rather than UDP?

Public Class methods

Check whether EventMachine will be used by Dnsruby

Create a new Resolver object. If no parameters are passed in, then the default system configuration will be used. Otherwise, a Hash may be passed in with the following optional elements :

  • :port
  • :use_tcp
  • :tsig_key
  • :ignore_truncation
  • :src_address
  • :src_port
  • :persistent_tcp
  • :persistent_udp
  • :recurse
  • :udp_size
  • :config_info - see Config
  • :nameserver - can be either a String or an array of Strings
  • :packet_timeout
  • :query_timeout
  • :retry_times
  • :retry_delay

If EventMachine is being used, then this method tells Dnsruby whether or not to start the EventMachine loop. If you want to use Dnsruby client code as is, but using EventMachine for I/O, then Dnsruby must start the EventMachine loop for you. This is the default behaviour. If you want to use EventMachine-style code, where everything is wrapped up in an EventMachine::run{} call, then this method should be called with false as the parameter.

Takes a bool argument to say whether or not to start the event loop when required.

Checks whether Dnsruby will start the EventMachine loop when required.

Tell Dnsruby to use EventMachine for I/O.

If EventMachine is not used, then the pure Ruby event loop in Dnsruby will be used instead.

If EventMachine is not available on the platform, then a RuntimeError will be raised.

Takes a bool to say whether or not to use EventMachine.

Public Instance methods

Add a new SingleResolver to the list of resolvers this Resolver object will query.

Close the Resolver. Unfinished queries are terminated with OtherResolvError.

Query for a n. If a valid Message is received, then it is returned to the caller. Otherwise an exception (a Dnsruby::ResolvError or Dnsruby::ResolvTimeout) is raised.

  require 'Dnsruby'
  res = Dnsruby::Resolver.new
  response = res.query("example.com") # defaults to Types.A, Classes.IN
  response = res.query("example.com", Types.MX)
  response = res.query("208.77.188.166") # IPv4 address so PTR query will be made
  response = res.query("208.77.188.166", Types.PTR)

Asynchronously sends a DNS packet (Dnsruby::Message). The client must pass in the Message to be sent, a client_query_id to identify the message and a client_queue (of class Queue) to pass the response back in.

A tuple of (query_id, response_message, exception) will be added to the client_queue.

example :

  require 'Dnsruby'
  res = Dnsruby::Resolver.new
  query_id = 10 # can be any object you like
  query_queue = Queue.new
  res.send_async(Message.new("example.com", Types.MX),  query_queue, query_id)
  query_id += 1
  res.send_async(Message.new("example.com", Types.A), query_queue, query_id)
  # ...do a load of other stuff here...
  2.times do
    response_id, response, exception = query_queue.pop
    # You can check the ID to see which query has been answered
    if (exception == nil)
        # deal with good response
    else
        # deal with problem
    end
  end

@TODO@ Sort out RDoc arguments to send_async!

Send a message, and wait for the response. If a valid Message is received, then it is returned to the caller. Otherwise an exception (a Dnsruby::ResolvError or Dnsruby::ResolvTimeout) is raised.

send_async is called internally.

example :

  require 'Dnsruby'
  res = Dnsruby::Resolver.new
  begin
  response = res.send_message(Message.new("example.com", Types.MX))
  rescue ResolvError
    # ...
  rescue ResolvTimeout
    # ...
  end

[Validate]