Class: RubyDNS::RuleBasedServer

Inherits:
Server
  • Object
show all
Defined in:
lib/rubydns/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

Constant Summary

Constants inherited from Server

Server::DEFAULT_INTERFACES

Instance Attribute Summary collapse

Attributes inherited from Server

#origin

Instance Method Summary collapse

Methods inherited from Server

#process_query, #run, #shutdown

Constructor Details

#initialize(options = {}, &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



261
262
263
264
265
266
267
268
269
270
271
# File 'lib/rubydns/server.rb', line 261

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

Instance Attribute Details

#loggerObject

Returns the value of attribute logger.



273
274
275
# File 'lib/rubydns/server.rb', line 273

def logger
  @logger
end

Instance Method Details

#fire(event_name) ⇒ Object

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



295
296
297
298
299
300
301
# File 'lib/rubydns/server.rb', line 295

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])



281
282
283
# File 'lib/rubydns/server.rb', line 281

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.



314
315
316
# File 'lib/rubydns/server.rb', line 314

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



290
291
292
# File 'lib/rubydns/server.rb', line 290

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



309
310
311
# File 'lib/rubydns/server.rb', line 309

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.



319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# File 'lib/rubydns/server.rb', line 319

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