Class: Async::DNS::Server
- Inherits:
-
Object
- Object
- Async::DNS::Server
- Defined in:
- lib/async/dns/server.rb
Constant Summary collapse
- DEFAULT_ENDPOINTS =
The default server interfaces
[[:udp, "0.0.0.0", 53], [:tcp, "0.0.0.0", 53]]
Instance Attribute Summary collapse
-
#logger ⇒ Object
Returns the value of attribute logger.
-
#origin ⇒ Object
Records are relative to this origin:.
Instance Method Summary collapse
-
#fire(event_name) ⇒ Object
Fire the named event as part of running the server.
-
#initialize(endpoints = DEFAULT_ENDPOINTS, origin: '.', logger: Async.logger) ⇒ Server
constructor
Instantiate a server with a block.
-
#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.
-
#process_query(query, options = {}, &block) ⇒ Object
Process an incoming DNS message.
-
#run(*args) ⇒ Object
Setup all specified interfaces and begin accepting incoming connections.
Constructor Details
#initialize(endpoints = DEFAULT_ENDPOINTS, origin: '.', logger: Async.logger) ⇒ Server
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
40 41 42 43 44 |
# File 'lib/async/dns/server.rb', line 40 def initialize(endpoints = DEFAULT_ENDPOINTS, origin: '.', logger: Async.logger) @endpoints = endpoints @origin = origin @logger = logger end |
Instance Attribute Details
#logger ⇒ Object
Returns the value of attribute logger.
49 50 51 |
# File 'lib/async/dns/server.rb', line 49 def logger @logger end |
#origin ⇒ Object
Records are relative to this origin:
47 48 49 |
# File 'lib/async/dns/server.rb', line 47 def origin @origin end |
Instance Method Details
#fire(event_name) ⇒ Object
Fire the named event as part of running the server.
52 53 |
# File 'lib/async/dns/server.rb', line 52 def fire(event_name) 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.
56 57 58 |
# File 'lib/async/dns/server.rb', line 56 def process(name, resource_class, transaction) raise NotImplementedError.new end |
#process_query(query, options = {}, &block) ⇒ Object
Process an incoming DNS message. Returns a serialized message to be sent back to the client.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/async/dns/server.rb', line 61 def process_query(query, = {}, &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.id}> Processing question #{question} #{resource_class}..."} transaction = Transaction.new(self, query, question, resource_class, response, ) transaction.process rescue Resolv::DNS::OriginError # This is triggered if the question is not part of the specified @origin: @logger.debug {"<#{query.id}> Skipping question #{question} #{resource_class} because #{$!}"} end end rescue StandardError => error @logger.error "<#{query.id}> Exception thrown while processing #{transaction}!" Async::DNS.log_exception(@logger, error) response.rcode = Resolv::DNS::RCode::ServFail end end_time = Time.now @logger.debug {"<#{query.id}> Time to process request: #{end_time - start_time}s"} return response end |
#run(*args) ⇒ Object
Setup all specified interfaces and begin accepting incoming connections.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/async/dns/server.rb', line 104 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 |