Module: RubyDNS::UDPHandler

Defined in:
lib/rubydns/handler.rb

Overview

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

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.process(server, data, options = {}, &block) ⇒ Object

Process a packet of data with the given server. If an exception is thrown, a failure message will be sent back.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/rubydns/handler.rb', line 37

def self.process(server, data, options = {}, &block)
	server.logger.debug "Receiving incoming query (#{data.bytesize} bytes)..."
	query = nil

	begin
		query = RubyDNS::decode_message(data)

		return server.process_query(query, options, &block)
	rescue => error
		server.logger.error "Error processing request!"
		server.logger.error "#{error.class}: #{error.message}"

		error.backtrace.each { |at| server.logger.error at }

		# Encoding may fail, so we need to handle this particular case:
		server_failure = Resolv::DNS::Message::new(query ? query.id : 0)
		server_failure.qr = 1
		server_failure.opcode = query ? query.opcode : 0
		server_failure.aa = 1
		server_failure.rd = 0
		server_failure.ra = 0

		server_failure.rcode = Resolv::DNS::RCode::ServFail

		# We can't do anything at this point...
		yield server_failure
	end
end

Instance Method Details

#initialize(server) ⇒ Object



32
33
34
# File 'lib/rubydns/handler.rb', line 32

def initialize(server)
	@server = server
end

#receive_data(data) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/rubydns/handler.rb', line 66

def receive_data(data)
	peer_port, peer_ip = RubyDNS::get_peer_details(self)
	options = {:peer => peer_ip}
	
	UDPHandler.process(@server, data, options) do |answer|
		data = answer.encode
		
		@server.logger.debug "Writing response to client (#{data.bytesize} bytes) via UDP..."
		
		if data.bytesize > UDP_TRUNCATION_SIZE
			@server.logger.warn "Response via UDP was larger than #{UDP_TRUNCATION_SIZE}!"
			
			# Reencode data with truncation flag marked as true:
			truncation_error = Resolv::DNS::Message.new(answer.id)
			truncation_error.tc = 1
			
			data = truncation_error.encode
		end
		
		# We explicitly use the ip and port given, because we found that send_data was unreliable in a callback.
		self.send_datagram(data, peer_ip, peer_port)
	end
end