The default server interfaces
Process a block with the current fiber. To resume processing from the block, call `fiber.resume`. You shouldn't call `fiber.resume` until after the top level block has returned.
# File lib/rubydns/server.rb, line 56 def defer(&block) fiber = Fiber.current yield(fiber) Fiber.yield end
Fire the named event as part of running the server.
# File lib/rubydns/server.rb, line 47 def fire(event_name) end
Give a name and a record type, try to match a rule and use it for processing the given arguments.
# File lib/rubydns/server.rb, line 51 def process(name, resource_class, transaction) raise NotImplementedError.new end
Process an incoming DNS message. Returns a serialized message to be sent back to the client.
# File lib/rubydns/server.rb, line 65 def process_query(query, options = {}, &block) # Setup answer answer = Resolv::DNS::Message::new(query.id) answer.qr = 1 # 0 = Query, 1 = Response answer.opcode = query.opcode # Type of Query; copy from query answer.aa = 1 # Is this an authoritative response: 0 = No, 1 = Yes answer.rd = query.rd # Is Recursion Desired, copied from query answer.ra = 0 # Does name server support recursion: 0 = No, 1 = Yes answer.rcode = 0 # Response code: 0 = No errors Fiber.new do transaction = nil begin query.question.each do |question, resource_class| @logger.debug "Processing question #{question} #{resource_class}..." transaction = Transaction.new(self, query, question, resource_class, answer, options) transaction.process end rescue @logger.error "Exception thrown while processing #{transaction}!" RubyDNS.log_exception(@logger, $!) answer.rcode = Resolv::DNS::RCode::ServFail end yield answer end.resume end
By default the server runs on port 53, both TCP and UDP, which is usually a priviledged port and requires root access to bind. You can change this by specifying `options` which should contain an array of `[protocol, interface address, port]` specifications.
INTERFACES = [[:udp, "0.0.0.0", 5300]] RubyDNS::run_server(:listen => INTERFACES) do ... end
You can specify already connected sockets if need be:
socket = UDPSocket.new; socket.bind("0.0.0.0", 53) Process::Sys.setuid(server_uid) INTERFACES = [socket]
# File lib/rubydns/server.rb, line 111 def run(options = {}) @logger.info "Starting RubyDNS server (v#{RubyDNS::VERSION})..." interfaces = options[:listen] || DEFAULT_INTERFACES fire(:setup) # Setup server sockets interfaces.each do |spec| @logger.info "Listening on #{spec.join(':')}" if spec[0] == :udp EventMachine.open_datagram_socket(spec[1], spec[2], UDPHandler, self) elsif spec[0] == :tcp EventMachine.start_server(spec[1], spec[2], TCPHandler, self) end end fire(:start) end
Generated with the Darkfish Rdoc Generator 2.