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. 
- 
  
    
      #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. 
Instance Method Summary collapse
- 
  
    
      #append!(*resources)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Append a given set of resources to the answer. 
- 
  
    
      #append_query!(name, resource_class = nil, options = {})  ⇒ 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, options = {})  ⇒ 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, options = {}) ⇒ Transaction
Returns a new instance of Transaction.
| 30 31 32 33 34 35 36 37 38 39 40 41 | # 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 @options = @deferred = false @question_appended = false end | 
Instance Attribute Details
#answer ⇒ Object (readonly)
The current full answer to the incoming query.
| 54 55 56 | # File 'lib/rubydns/transaction.rb', line 54 def answer @answer end | 
#options ⇒ Object (readonly)
Any options or configuration associated with the given transaction.
| 57 58 59 | # File 'lib/rubydns/transaction.rb', line 57 def @options end | 
#query ⇒ Object (readonly)
The incoming query which is a set of questions.
| 48 49 50 | # File 'lib/rubydns/transaction.rb', line 48 def query @query end | 
#question ⇒ Object (readonly)
The question that this transaction represents.
| 51 52 53 | # File 'lib/rubydns/transaction.rb', line 51 def question @question end | 
#resource_class ⇒ Object (readonly)
The resource_class that was requested. This is typically used to generate a response.
| 45 46 47 | # File 'lib/rubydns/transaction.rb', line 45 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. 
- options[:section]
- 
Specify whether the response should go in the ‘:answer` 
`:authority` or `:additional` section.
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.
| 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | # File 'lib/rubydns/transaction.rb', line 191 def append! (*resources) append_question! if resources.last.kind_of?(Hash) = resources.pop else = {} end # Use the default options if provided: = .merge(@options) [:ttl] ||= 16000 [:name] ||= @question.to_s + "." method = ("add_" + ([:section] || 'answer').to_s).to_sym resources.each do |resource| @server.logger.debug "#{method}: #{resource.inspect} #{resource.class::TypeValue} #{resource.class::ClassValue}" @answer.send(method, [:name], [:ttl], resource) end succeed if @deferred true end | 
#append_query!(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 transactions answer.
| 71 72 73 | # File 'lib/rubydns/transaction.rb', line 71 def append_query!(name, resource_class = nil, = {}) Transaction.new(@server, @query, name, resource_class || @resource_class, @answer, ).process end | 
#append_question! ⇒ Object
| 251 252 253 254 255 | # File 'lib/rubydns/transaction.rb', line 251 def append_question! if @answer.question.size == 0 @answer.add_question(@question, @resource_class) unless @question_appended end end | 
#defer! ⇒ Object
| 83 84 85 | # File 'lib/rubydns/transaction.rb', line 83 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).
| 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | # File 'lib/rubydns/transaction.rb', line 236 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 # The transaction itself has completed, but contains a failure: succeed(rcode) if @deferred true end | 
#name ⇒ Object
Return the name of the question, which is typically the requested hostname.
| 60 61 62 | # File 'lib/rubydns/transaction.rb', line 60 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. :name => resource_name, override the name for the request as it is passed to the resolver. Implies :force. :resource_class => class, overried the resource class for a request as it is passed to the resolver.
| 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | # File 'lib/rubydns/transaction.rb', line 122 def passthrough(resolver, = {}, &block) if @query.rd || [:force] || [:name] # Resolver is asynchronous, so we are now deferred: defer! query_name = [:name] || name query_resource_class = [:resource_class] || resource_class resolver.query(query_name, query_resource_class) do |response| case response when RubyDNS::Message yield response when RubyDNS::ResolutionFailure failure!(:ServFail) else # This shouldn't ever happen, but if it does for some reason we shouldn't hang. 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.
| 94 95 96 97 98 99 100 101 102 103 104 105 106 | # File 'lib/rubydns/transaction.rb', line 94 def passthrough!(resolver, = {}, &block) passthrough(resolver, ) do |response| if block_given? yield response end @answer.merge!(response) succeed if @deferred end true end | 
#process(&finished) ⇒ Object
| 75 76 77 78 79 80 81 | # File 'lib/rubydns/transaction.rb', line 75 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!(10, Name.create("mail.blah.com"))
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_classs available. www.ruby-doc.org/stdlib/libdoc/resolv/rdoc/index.html
| 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | # File 'lib/rubydns/transaction.rb', line 165 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
| 65 66 67 | # File 'lib/rubydns/transaction.rb', line 65 def to_s "#{name} #{@resource_class.name}" end |