class RubyDNS::RuleBasedServer
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.
Attributes
Public Class Methods
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
# 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
Public Instance Methods
Fire the named event, which must have been registered using on.
# File lib/rubydns/rule_based_server.rb, line 137 def fire(event_name) callback = @events[event_name] if callback callback.call(self) end end
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])
# File lib/rubydns/rule_based_server.rb, line 123 def match(*pattern, &block) @rules << Rule.new(pattern, block) end
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.
# File lib/rubydns/rule_based_server.rb, line 156 def next! throw :next end
Register a named event which may be invoked later using fire
on(:start) do |server| Process::Daemon::Permissions.change_user(RUN_AS) end
# File lib/rubydns/rule_based_server.rb, line 132 def on(event_name, &block) @events[event_name] = block end
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
# File lib/rubydns/rule_based_server.rb, line 151 def otherwise(&block) @otherwise = block end
Give a name and a record type, try to match a rule and use it for processing the given arguments.
# 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