Class: Async::DNS::DatagramHandler

Inherits:
GenericHandler show all
Defined in:
lib/async/dns/handler.rb

Overview

Handle incoming UDP requests, which are single data packets, and pass them on to the given server.

Instance Attribute Summary

Attributes inherited from GenericHandler

#The server that will process incoming queries., #server, #socket

Instance Method Summary collapse

Methods inherited from GenericHandler

#The socket to read/write data from/to.=, #error_response, #initialize, #process_query

Constructor Details

This class inherits a constructor from Async::DNS::GenericHandler

Instance Method Details

#respond(socket, input_data, remote_address) ⇒ Object

Respond to an incoming query.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/async/dns/handler.rb', line 92

def respond(socket, input_data, remote_address)
  response = process_query(input_data, remote_address: remote_address)
  
  output_data = response.encode
  
  Console.debug "Writing #{output_data.bytesize} bytes response to client via UDP...", response_id: response.id
  
  if output_data.bytesize > UDP_REASONABLE_SIZE
    Console.warn "Response via UDP was larger than #{UDP_REASONABLE_SIZE}!", response_id: response.id
    
    # Reencode data with truncation flag marked as true:
    truncation_error = Resolv::DNS::Message.new(response.id)
    truncation_error.tc = 1
    
    output_data = truncation_error.encode
  end
  
  socket.sendmsg(output_data, 0, remote_address)
rescue IOError => error
  Console.error(self, "UDP response failed!", error: error)
rescue EOFError => error
  Console.error(self, "UDP session ended prematurely!", error: error)
rescue Resolv::DNS::DecodeError => error
  Console.error(self, "Could not decode incoming UDP data!", error: error)
end

#run(wrapper = ::IO::Endpoint::Wrapper.default) ⇒ Object

Run the handler, processing incoming UDP requests.



81
82
83
84
85
86
87
88
89
# File 'lib/async/dns/handler.rb', line 81

def run(wrapper = ::IO::Endpoint::Wrapper.default)
  while true
    input_data, remote_address = @socket.recvmsg(UDP_MAXIMUM_SIZE)
    
    wrapper.async do
      respond(@socket, input_data, remote_address)
    end
  end
end