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