class Async::DNS::Server
Constants
- DEFAULT_ENDPOINTS
The default server interfaces
Attributes
logger[RW]
origin[RW]
Records are relative to this origin:
Public Class Methods
new(endpoints = DEFAULT_ENDPOINTS, origin: '.', logger: Console.logger)
click to toggle source
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/async/dns/server.rb, line 39 def initialize(endpoints = DEFAULT_ENDPOINTS, origin: '.', logger: Console.logger) @endpoints = endpoints @origin = origin @logger = logger end
Public Instance Methods
fire(event_name)
click to toggle source
Fire the named event as part of running the server.
# File lib/async/dns/server.rb, line 51 def fire(event_name) end
process(name, resource_class, transaction)
click to toggle source
Give a name and a record type, try to match a rule and use it for processing the given arguments.
# File lib/async/dns/server.rb, line 55 def process(name, resource_class, transaction) raise NotImplementedError.new end
process_query(query, options = {}, &block)
click to toggle source
Process an incoming DNS
message. Returns a serialized message to be sent back to the client.
# File lib/async/dns/server.rb, line 60 def process_query(query, options = {}, &block) start_time = Time.now # Setup response response = Resolv::DNS::Message::new(query.id) response.qr = 1 # 0 = Query, 1 = Response response.opcode = query.opcode # Type of Query; copy from query response.aa = 1 # Is this an authoritative response: 0 = No, 1 = Yes response.rd = query.rd # Is Recursion Desired, copied from query response.ra = 0 # Does name server support recursion: 0 = No, 1 = Yes response.rcode = 0 # Response code: 0 = No errors transaction = nil begin query.question.each do |question, resource_class| begin question = question.without_origin(@origin) @logger.debug(query) {"Processing question #{question} #{resource_class}..."} transaction = Transaction.new(self, query, question, resource_class, response, options) transaction.process rescue Resolv::DNS::OriginError # This is triggered if the question is not part of the specified @origin: @logger.debug(query) {"Skipping question #{question} #{resource_class} because #{$!}"} end end rescue StandardError => error @logger.error(query) {error} response.rcode = Resolv::DNS::RCode::ServFail end end_time = Time.now @logger.debug(query) {"Time to process request: #{end_time - start_time}s"} return response end
run(*args)
click to toggle source
Setup all specified interfaces and begin accepting incoming connections.
# File lib/async/dns/server.rb, line 102 def run(*args) @logger.info "Starting Async::DNS server (v#{Async::DNS::VERSION})..." Async::Reactor.run do |task| fire(:setup) Async::IO::Endpoint.each(@endpoints) do |endpoint| task.async do endpoint.bind do |socket| case socket.type when Socket::SOCK_DGRAM @logger.info "<> Listening for datagrams on #{socket.local_address.inspect}" DatagramHandler.new(self, socket).run when Socket::SOCK_STREAM @logger.info "<> Listening for connections on #{socket.local_address.inspect}" StreamHandler.new(self, socket).run else raise ArgumentError.new("Don't know how to handle #{address}") end end end end fire(:start) end end