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

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



249
250
251
252
253
254
255
256
257
258
259
# File 'lib/rubydns/server.rb', line 249

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.



261
262
263
# File 'lib/rubydns/server.rb', line 261

def logger
  @logger
end

Instance Method Details

#fire(event_name) ⇒ Object

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



283
284
285
286
287
288
289
# File 'lib/rubydns/server.rb', line 283

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



269
270
271
# File 'lib/rubydns/server.rb', line 269

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.



302
303
304
# File 'lib/rubydns/server.rb', line 302

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



278
279
280
# File 'lib/rubydns/server.rb', line 278

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



297
298
299
# File 'lib/rubydns/server.rb', line 297

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.



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
# File 'lib/rubydns/server.rb', line 307

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