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