Class: RubyDNS::RuleBasedServer

Inherits:
Async::DNS::Server
  • Object
show all
Defined in:
lib/rubydns/rule_based_server.rb

Overview

Provides the core of the RubyDNS domain-specific language (DSL). It contains a list of rules which are used to match against incoming DNS questions. These rules are used to generate responses which are either DNS resource records or failures.

Defined Under Namespace

Classes: Rule

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args, &block) ⇒ RuleBasedServer

Instantiate a server with a block

server = Server.new do match(/server.mydomain.com/, IN::A) do |transaction| transaction.respond!("1.2.3.4") end end



103
104
105
106
107
108
109
110
111
112
113
# File 'lib/rubydns/rule_based_server.rb', line 103

def initialize(*args, &block)
	super(*args)
	
	@events = {}
	@rules = []
	@otherwise = nil
	
	if block_given?
		instance_eval(&block)
	end
end

Instance Attribute Details

#loggerObject

Returns the value of attribute logger.



115
116
117
# File 'lib/rubydns/rule_based_server.rb', line 115

def logger
  @logger
end

Instance Method Details

#fire(event_name) ⇒ Object

Fire the named event, which must have been registered using on.



137
138
139
140
141
142
143
# File 'lib/rubydns/rule_based_server.rb', line 137

def fire(event_name)
	callback = @events[event_name]
	
	if callback
		callback.call(self)
	end
end

#match(*pattern, &block) ⇒ Object

This function connects a pattern with a block. A pattern is either a String or a Regex instance. Optionally, a second argument can be provided which is either a String, Symbol or Array of resource record types which the rule matches against.

match("www.google.com") match("gmail.com", IN::MX) match(/g?mail.(com|org|net)/, [IN::MX, IN::A])



123
124
125
# File 'lib/rubydns/rule_based_server.rb', line 123

def match(*pattern, &block)
	@rules << Rule.new(pattern, block)
end

#next!Object

If you match a rule, but decide within the rule that it isn't the correct one to use, you can call next! to evaluate the next rule - in other words, to continue falling down through the list of rules.



156
157
158
# File 'lib/rubydns/rule_based_server.rb', line 156

def next!
	throw :next
end

#on(event_name, &block) ⇒ Object

Register a named event which may be invoked later using #fire

on(:start) do |server| Process::Daemon::Permissions.change_user(RUN_AS) end



132
133
134
# File 'lib/rubydns/rule_based_server.rb', line 132

def on(event_name, &block)
	@events[event_name] = block
end

#otherwise(&block) ⇒ Object

Specify a default block to execute if all other rules fail to match. This block is typially used to pass the request on to another server (i.e. recursive request).

otherwise do |transaction| transaction.passthrough!($R) end



151
152
153
# File 'lib/rubydns/rule_based_server.rb', line 151

def otherwise(&block)
	@otherwise = block
end

#process(name, resource_class, transaction) ⇒ Object

Give a name and a record type, try to match a rule and use it for processing the given arguments.



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/rubydns/rule_based_server.rb', line 161

def process(name, resource_class, transaction)
	@logger.debug {"<#{transaction.query.id}> Searching for #{name} #{resource_class.name}"}
	
	@rules.each do |rule|
		@logger.debug {"<#{transaction.query.id}> Checking rule #{rule}..."}
		
		catch (:next) do
			# If the rule returns true, we assume that it was successful and no further rules need to be evaluated.
			return if rule.call(self, name, resource_class, transaction)
		end
	end
	
	if @otherwise
		@otherwise.call(transaction)
	else
		@logger.warn "<#{transaction.query.id}> Failed to handle #{name} #{resource_class.name}!"
	end
end