Async::DNS SourceAsyncDNSDatagramHandler

class DatagramHandler

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

Definitions

def run(wrapper = ::IO::Endpoint::Wrapper.default)

Run the handler, processing incoming UDP requests.

Signature

parameter wrapper Interface(:async)

The parent task to run the handler under.

Implementation

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

def respond(socket, input_data, remote_address)

Respond to an incoming query.

Implementation

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::Event::Failure.for(error).emit "UDP response failed!"
rescue EOFError => error
	Console::Event::Failure.for(error).emit "UDP session ended prematurely!"
rescue Resolv::DNS::DecodeError => error
	Console::Event::Failure.for(error).emit "Could not decode incoming UDP data!"
end