Class: RubyDNS::Transaction
- Inherits:
-
Object
- Object
- RubyDNS::Transaction
- Includes:
- EventMachine::Deferrable
- Defined in:
- lib/rubydns/transaction.rb
Overview
This class provides all details of a single DNS question and answer. This is used by the DSL to provide DNS related functionality.
Instance Attribute Summary collapse
-
#answer ⇒ Object
readonly
The current full answer to the incoming query.
-
#query ⇒ Object
readonly
The incoming query which is a set of questions.
-
#question ⇒ Object
readonly
The question that this transaction represents.
-
#resource_class ⇒ Object
readonly
The resource_class that was requested.
Instance Method Summary collapse
-
#append!(*resources) ⇒ Object
Append a given set of resources to the answer.
-
#append_query!(name, resource_class = nil) ⇒ Object
Run a new query through the rules with the given name and resource type.
- #append_question! ⇒ Object
- #defer! ⇒ Object
-
#failure!(rcode) ⇒ Object
This function indicates that there was a failure to resolve the given question.
-
#initialize(server, query, question, resource_class, answer) ⇒ Transaction
constructor
A new instance of Transaction.
-
#name ⇒ Object
Return the name of the question, which is typically the requested hostname.
-
#passthrough(resolver, options = {}, &block) ⇒ Object
Use the given resolver to respond to the question.
-
#passthrough!(resolver, options = {}, &block) ⇒ Object
Use the given resolver to respond to the question.
- #process(&finished) ⇒ Object
-
#respond!(*data) ⇒ Object
Respond to the given query with a resource record.
-
#to_s ⇒ Object
Suitable for debugging purposes.
Constructor Details
#initialize(server, query, question, resource_class, answer) ⇒ Transaction
Returns a new instance of Transaction.
30 31 32 33 34 35 36 37 38 39 |
# File 'lib/rubydns/transaction.rb', line 30 def initialize(server, query, question, resource_class, answer) @server = server @query = query @question = question @resource_class = resource_class @answer = answer @deferred = false @question_appended = false end |
Instance Attribute Details
#answer ⇒ Object (readonly)
The current full answer to the incoming query.
52 53 54 |
# File 'lib/rubydns/transaction.rb', line 52 def answer @answer end |
#query ⇒ Object (readonly)
The incoming query which is a set of questions.
46 47 48 |
# File 'lib/rubydns/transaction.rb', line 46 def query @query end |
#question ⇒ Object (readonly)
The question that this transaction represents.
49 50 51 |
# File 'lib/rubydns/transaction.rb', line 49 def question @question end |
#resource_class ⇒ Object (readonly)
The resource_class that was requested. This is typically used to generate a response.
43 44 45 |
# File 'lib/rubydns/transaction.rb', line 43 def resource_class @resource_class end |
Instance Method Details
#append!(*resources) ⇒ Object
Append a given set of resources to the answer. The last argument can optionally be a hash of options.
options[:ttl]
-
Specify the TTL for the resource
options[:name]
-
Override the name (question) of the response.
This function can be used to supply multiple responses to a given question. For example, each argument is expected to be an instantiated resource from Resolv::DNS::Resource
module.
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/rubydns/transaction.rb', line 173 def append! (*resources) append_question! = resources.last.kind_of?(Hash) ? resources.pop.dup : {} [:ttl] ||= 16000 [:name] ||= @question.to_s + "." resources.each do |resource| @server.logger.debug "add_answer: #{resource.inspect} #{resource.class::TypeValue} #{resource.class::ClassValue}" @answer.add_answer([:name], [:ttl], resource) end # Raise an exception if there was something wrong with the resource @answer.encode true end |
#append_query!(name, resource_class = nil) ⇒ Object
Run a new query through the rules with the given name and resource type. The results of this query are appended to the current transactions answer
.
66 67 68 |
# File 'lib/rubydns/transaction.rb', line 66 def append_query!(name, resource_class = nil) Transaction.new(@server, @query, name, resource_class || @resource_class, @answer).process end |
#append_question! ⇒ Object
220 221 222 223 224 |
# File 'lib/rubydns/transaction.rb', line 220 def append_question! if @answer.question.size == 0 @answer.add_question(@question, @resource_class) unless @question_appended end end |
#defer! ⇒ Object
78 79 80 |
# File 'lib/rubydns/transaction.rb', line 78 def defer! @deferred = true end |
#failure!(rcode) ⇒ Object
This function indicates that there was a failure to resolve the given question. The single argument must be an integer error code, typically given by the constants in Resolv::DNS::RCode
.
The easiest way to use this function it to simply supply a symbol. Here is a list of the most commonly used ones:
:NoError
-
No error occurred.
:FormErr
:: The incoming data was not formatted correctly.
:ServFail
-
The operation caused a server failure (internal error, etc).
:NXDomain
-
Non-eXistant Domain (domain record does not exist).
:NotImp
-
The operation requested is not implemented.
:Refused
-
The operation was refused by the server.
:NotAuth
-
The server is not authoritive for the zone.
See www.rfc-editor.org/rfc/rfc2929.txt for more information about DNS error codes (specifically, page 3).
208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/rubydns/transaction.rb', line 208 def failure! (rcode) append_question! if rcode.kind_of? Symbol @answer.rcode = Resolv::DNS::RCode.const_get(rcode) else @answer.rcode = rcode.to_i end true end |
#name ⇒ Object
Return the name of the question, which is typically the requested hostname.
55 56 57 |
# File 'lib/rubydns/transaction.rb', line 55 def name @question.to_s end |
#passthrough(resolver, options = {}, &block) ⇒ Object
Use the given resolver to respond to the question. If recursion is not requested, the result is failure!(:Refused)
. If the resolver does not respond, the result is failure!(:NXDomain)
If a block is supplied, this function yields with the reply and reply_name if successful. This block is responsible for doing something useful with the reply, such as merging it or conditionally discarding it.
A second argument, options, provides some control over the passthrough process. :force => true, ensures that the query will occur even if recursion is not requested.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/rubydns/transaction.rb', line 111 def passthrough(resolver, = {}, &block) if @query.rd || [:force] # Resolver is asynchronous, so we are now deferred: defer! resolver.query(name, resource_class) do |response| case response when RubyDNS::Message yield response succeed(response) else fail(response) end end else failure!(:Refused) end true end |
#passthrough!(resolver, options = {}, &block) ⇒ Object
Use the given resolver to respond to the question. The default functionality is implemented by passthrough, and if a reply is received, it will be merged with the answer for this transaction.
If a block is supplied, this function yields with the reply and reply_name if successful. This could be used, for example, to update a cache or modify the reply.
89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/rubydns/transaction.rb', line 89 def passthrough!(resolver, = {}, &block) passthrough(resolver, ) do |response| if block_given? yield response end @answer.merge!(response) end true end |
#process(&finished) ⇒ Object
70 71 72 73 74 75 76 |
# File 'lib/rubydns/transaction.rb', line 70 def process(&finished) @server.process(name, @resource_class, self) unless @deferred succeed(self) end end |
#respond!(*data) ⇒ Object
Respond to the given query with a resource record. The arguments to this function depend on the resource_class
requested. The last argument can optionally be a hash of options.
options[:resource_class]
-
Override the default
resource_class
options[:ttl]
-
Specify the TTL for the resource
options[:name]
-
Override the name (question) of the response.
- for A records
-
respond!("1.2.3.4")
- for MX records
-
respond!("mail.blah.com", 10)
This function instantiates the resource class with the supplied arguments, and then passes it to append!
.
See Resolv::DNS::Resource
for more information about the various resource_class
s available. www.ruby-doc.org/stdlib/libdoc/resolv/rdoc/index.html
149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/rubydns/transaction.rb', line 149 def respond! (*data) = data.last.kind_of?(Hash) ? data.pop : {} resource_class = [:resource_class] || @resource_class if resource_class == nil raise ArgumentError, "Could not instantiate resource #{resource_class}!" end @server.logger.info "Resource class: #{resource_class.inspect}" resource = resource_class.new(*data) @server.logger.info "Resource: #{resource.inspect}" append!(resource, ) end |
#to_s ⇒ Object
Suitable for debugging purposes
60 61 62 |
# File 'lib/rubydns/transaction.rb', line 60 def to_s "#{name} #{@resource_class.name}" end |