| Class | Dnsruby::Resolver |
| In: |
lib/Dnsruby/Resolver.rb
|
| Parent: | Object |
Dnsruby::Resolver is a DNS stub resolver. 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 :
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
These methods raise an exception or return a response message with rcode==NOERROR
These methods use a response queue to return the response and the error
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)
| DefaultQueryTimeout | = | 0 |
| DefaultPacketTimeout | = | 10 |
| DefaultRetryTimes | = | 4 |
| DefaultRetryDelay | = | 5 |
| DefaultPort | = | 53 |
| DefaultUDPSize | = | 512 |
| 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 | [R] | |
| udp_size | [R] | The maximum UDP size to be used |
| use_tcp | [R] | Should TCP be used as a transport rather than UDP? |
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 :
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.
Add a new SingleResolver to the list of resolvers this Resolver object will query.
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 send a Message to the server. The send can be done using just Dnsruby, or using EventMachine.
A client_queue is supplied by the client, along with an optional client_query_id to identify the response. The client_query_id is generated, if not supplied, and returned to the client. When the response is known, a tuple of (query_id, response_message, exception) will be added to the client_queue.
The query is sent synchronously in the caller‘s thread. The select thread is then used to listen for and process the response (up to pushing it to the client_queue). The client thread is then used to retrieve the response and deal with it.
Takes :
Returns :
generated if it is not passed in by the client
id = res.send_async(msg, queue)
NOT SUPPORTED : id = res.send_async(msg, queue, use_tcp)
id = res.send_async(msg, queue, id)
id = res.send_async(msg, queue, id, use_tcp)
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_2 = res.send_async(Message.new("example.com", Types.A), query_queue)
# ...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
If EventMachine is being used (see Dnsruby::Resolver::use_eventmachine, then this method returns an EM::Deferrable object. When the response is known, then the Deferrable will complete. If a queue (and ID) is passed in, then the response will also be pushed to the Queue. Note that an ID is not automatically generated by this version.
deferrable = res.send_async(msg)
deferrable = res.send_async(msg, use_tcp)
deferrable = res.send_async(msg, q, id, use_tcp)
require 'Dnsruby'
require 'eventmachine'
res = Dnsruby::Resolver.new
Dnsruby::Resolver.use_eventmachine
Dnsruby::Resolver.start_eventmachine_loop(false)
EventMachine::run {
df = res.send_async(Dnsruby::Message.new("example.com"))
df.callback {|msg|
puts "Response : #{msg}"
EM.stop}
df.errback {|msg, err|
puts "Response : #{msg}"
puts "Error: #{err}"
EM.stop}
}
require 'Dnsruby'
res = Dnsruby::Resolver.new
Dnsruby::Resolver.use_eventmachine
Dnsruby::Resolver.start_eventmachine_loop(true) # default
q = Queue.new
id = res.send_async(Dnsruby::Message.new("example.com"),q)
id, response, error = q.pop
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
Sets the TSIG to sign outgoing messages with. Pass in either a Dnsruby::RR::TSIG, or a key_name and key (or just a key) Pass in nil to stop tsig signing. It is possible for client code to sign packets prior to sending - see Dnsruby::RR::TSIG#apply and Dnsruby::Message#sign Note that pre-signed packets will not be signed by SingleResolver.