Class: Async::DNS::Transaction
- Inherits:
-
Object
- Object
- Async::DNS::Transaction
- Defined in:
- lib/async/dns/transaction.rb
Overview
This class provides all details of a single DNS question and response. This is used by the DSL to provide DNS related functionality.
The main functions to complete the transaction are: #append! (evaluate a new query and append the results), #passthrough! (pass the query to an upstream server), #respond! (compute a specific response) and #fail! (fail with an error code).
Constant Summary collapse
- DEFAULT_TTL =
The default time used for responses (24 hours).
86400
Instance Attribute Summary collapse
-
#options ⇒ Object
readonly
Any options or configuration associated with the given transaction.
-
#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.
-
#response ⇒ Object
readonly
The current full response to the incoming query.
Instance Method Summary collapse
- #[](key) ⇒ Object
-
#add(resources, options = {}) ⇒ Object
Append a list of resources.
-
#append!(name, resource_class = nil, options = {}) ⇒ Object
Run a new query through the rules with the given name and resource type.
-
#fail!(rcode) ⇒ Object
This function indicates that there was a failure to resolve the given question.
- #failure!(*args) ⇒ Object deprecated Deprecated.
-
#initialize(server, query, question, resource_class, response, options = {}) ⇒ Transaction
constructor
A new instance of Transaction.
-
#name ⇒ Object
The name of the question, which is typically the requested hostname.
-
#passthrough(resolver, options = {}) ⇒ 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 ⇒ Object
A helper method to process the transaction on the given server.
-
#respond!(*args) ⇒ Object
The last argument can optionally be a hash of ‘options`.
-
#to_s ⇒ Object
Shows the question name and resource class.
Constructor Details
#initialize(server, query, question, resource_class, response, options = {}) ⇒ Transaction
Returns a new instance of Transaction.
30 31 32 33 34 35 36 37 38 |
# File 'lib/async/dns/transaction.rb', line 30 def initialize(server, query, question, resource_class, response, = {}) @server = server @query = query @question = question @resource_class = resource_class @response = response @options = end |
Instance Attribute Details
#options ⇒ Object (readonly)
Any options or configuration associated with the given transaction.
53 54 55 |
# File 'lib/async/dns/transaction.rb', line 53 def @options end |
#query ⇒ Object (readonly)
The incoming query which is a set of questions.
44 45 46 |
# File 'lib/async/dns/transaction.rb', line 44 def query @query end |
#question ⇒ Object (readonly)
The question that this transaction represents.
47 48 49 |
# File 'lib/async/dns/transaction.rb', line 47 def question @question end |
#resource_class ⇒ Object (readonly)
The resource_class that was requested. This is typically used to generate a response.
41 42 43 |
# File 'lib/async/dns/transaction.rb', line 41 def resource_class @resource_class end |
#response ⇒ Object (readonly)
The current full response to the incoming query.
50 51 52 |
# File 'lib/async/dns/transaction.rb', line 50 def response @response end |
Instance Method Details
#[](key) ⇒ Object
55 56 57 |
# File 'lib/async/dns/transaction.rb', line 55 def [] key @options[key] end |
#add(resources, options = {}) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/async/dns/transaction.rb', line 139 def add(resources, = {}) # Use the default options if provided: = .merge(@options) ttl = [:ttl] || DEFAULT_TTL name = [:name] || @question.to_s + "." section = ([:section] || 'answer').to_sym method = "add_#{section}".to_sym resources.each do |resource| @server.logger.debug {"#{method}: #{resource.inspect} #{resource.class::TypeValue} #{resource.class::ClassValue}"} @response.send(method, name, ttl, resource) end end |
#append!(name, resource_class = nil, options = {}) ⇒ 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 transaction’s ‘response`.
70 71 72 |
# File 'lib/async/dns/transaction.rb', line 70 def append!(name, resource_class = nil, = {}) Transaction.new(@server, @query, name, resource_class || @resource_class, @response, ).process end |
#fail!(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 [RFC2929](www.rfc-editor.org/rfc/rfc2929.txt) for more information about DNS error codes (specifically, page 3).
**This function will complete deferred transactions.**
171 172 173 174 175 176 177 178 179 |
# File 'lib/async/dns/transaction.rb', line 171 def fail!(rcode) append_question! if rcode.kind_of? Symbol @response.rcode = Resolv::DNS::RCode.const_get(rcode) else @response.rcode = rcode.to_i end end |
#failure!(*args) ⇒ Object
182 183 184 185 186 |
# File 'lib/async/dns/transaction.rb', line 182 def failure!(*args) @server.logger.warn "failure! is deprecated, use fail! instead" fail!(*args) end |
#name ⇒ Object
The name of the question, which is typically the requested hostname.
60 61 62 |
# File 'lib/async/dns/transaction.rb', line 60 def name @question.to_s end |
#passthrough(resolver, options = {}) ⇒ Object
Use the given resolver to respond to the question.
A block must be supplied, and provided a valid response is received from the upstream server, this function yields with the reply and reply_name.
If ‘options` is provided, this overrides the default query name sent to the upstream server. The same logic applies to `options`.
105 106 107 108 109 110 |
# File 'lib/async/dns/transaction.rb', line 105 def passthrough(resolver, = {}) query_name = [:name] || name query_resource_class = [:resource_class] || resource_class resolver.query(query_name, query_resource_class) end |
#passthrough!(resolver, options = {}, &block) ⇒ Object
Use the given resolver to respond to the question. Uses ‘passthrough` to do the lookup and merges the result.
If a block is supplied, this function yields with the ‘response` message if successful. This could be used, for example, to update a cache or modify the reply.
If recursion is not requested, the result is ‘fail!(:Refused)`. This check is ignored if an explicit `options` or `options` is given.
If the resolver can’t reach upstream servers, ‘fail!(:ServFail)` is invoked.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/async/dns/transaction.rb', line 81 def passthrough!(resolver, = {}, &block) if @query.rd || [:force] || [:name] response = passthrough(resolver, ) if response yield response if block_given? # Recursion is available and is being used: # See issue #26 for more details. @response.ra = 1 @response.merge!(response) else fail!(:ServFail) end else fail!(:Refused) end end |
#process ⇒ Object
A helper method to process the transaction on the given server. Unless the transaction is deferred, it will #succeed on completion.
189 190 191 |
# File 'lib/async/dns/transaction.rb', line 189 def process @server.process(name, @resource_class, self) end |
#respond!(*args) ⇒ Object
The last argument can optionally be a hash of ‘options`. If `options` is provided, it overrides the default resource class of transaction. Additional `options` are passed to #append!.
See ‘Resolv::DNS::Resource` for more information about the various `resource_classes` available (www.ruby-doc.org/stdlib/libdoc/resolv/rdoc/index.html).
119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/async/dns/transaction.rb', line 119 def respond!(*args) append_question! = args.last.kind_of?(Hash) ? args.pop : {} resource_class = [:resource_class] || @resource_class if resource_class == nil raise ArgumentError.new("Could not instantiate resource #{resource_class}!") end resource = resource_class.new(*args) add([resource], ) end |
#to_s ⇒ Object
Shows the question name and resource class. Suitable for debugging purposes.
65 66 67 |
# File 'lib/async/dns/transaction.rb', line 65 def to_s "#{name} #{@resource_class.name}" end |