Class: RubyDNS::Transaction

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

Constructor Details

#initialize(server, query, question, resource_class, answer) ⇒ Transaction

Returns a new instance of Transaction.



26
27
28
29
30
31
32
33
34
# File 'lib/rubydns/transaction.rb', line 26

def initialize(server, query, question, resource_class, answer)
	@server = server
	@query = query
	@question = question
	@resource_class = resource_class
	@answer = answer
	
	@question_appended = false
end

Instance Attribute Details

#answerObject (readonly)

The current full answer to the incoming query.



47
48
49
# File 'lib/rubydns/transaction.rb', line 47

def answer
  @answer
end

#queryObject (readonly)

The incoming query which is a set of questions.



41
42
43
# File 'lib/rubydns/transaction.rb', line 41

def query
  @query
end

#questionObject (readonly)

The question that this transaction represents.



44
45
46
# File 'lib/rubydns/transaction.rb', line 44

def question
  @question
end

#resource_classObject (readonly)

The resource_class that was requested. This is typically used to generate a response.



38
39
40
# File 'lib/rubydns/transaction.rb', line 38

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.



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/rubydns/transaction.rb', line 155

def append! (*resources)
	append_question!

	options = resources.last.kind_of?(Hash) ? resources.pop.dup : {}
	options[:ttl] ||= 16000
	options[:name] ||= @question.to_s + "."

	resources.each do |resource|
		@server.logger.debug "add_answer: #{resource.inspect} #{resource.class::TypeValue} #{resource.class::ClassValue}"
		@answer.add_answer(options[:name], options[: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.



61
62
63
# File 'lib/rubydns/transaction.rb', line 61

def append_query!(name, resource_class = nil)
	Transaction.new(@server, @query, name, resource_class || @resource_class, @answer).process
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).



190
191
192
193
194
195
196
197
198
199
200
# File 'lib/rubydns/transaction.rb', line 190

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

#nameObject

Return the name of the question, which is typically the requested hostname.



50
51
52
# File 'lib/rubydns/transaction.rb', line 50

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.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/rubydns/transaction.rb', line 98

def passthrough (resolver, options = {}, &block)
	if @query.rd || options[:force]
		reply, reply_name = resolver.query(name, resource_class)
		
		if reply
			yield reply, reply_name
		else
			failure!(:NXDomain)
		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.



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/rubydns/transaction.rb', line 76

def passthrough! (resolver, options = {}, &block)
	passthrough(resolver, options) do |reply, reply_name|
		if block_given?
			yield reply, reply_name
		end
		
		@answer.merge!(reply)
	end
	
	true
end

#processObject



65
66
67
# File 'lib/rubydns/transaction.rb', line 65

def process
	@server.process(name, @resource_class, self)
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_classs available. www.ruby-doc.org/stdlib/libdoc/resolv/rdoc/index.html



131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/rubydns/transaction.rb', line 131

def respond! (*data)
	options = data.last.kind_of?(Hash) ? data.pop : {}
	resource_class = options[: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, options)
end

#to_sObject

Suitable for debugging purposes



55
56
57
# File 'lib/rubydns/transaction.rb', line 55

def to_s
	"#{name} #{@resource_class.name}"
end