Class: Celluloid::DNS::UDPSocketHandler

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

Overview

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

Direct Known Subclasses

UDPHandler

Instance Method Summary collapse

Methods inherited from GenericHandler

#error_response, #process_query, #stop

Constructor Details

#initialize(server, socket) ⇒ UDPSocketHandler

Returns a new instance of UDPSocketHandler.



84
85
86
87
88
89
90
# File 'lib/celluloid/dns/handler.rb', line 84

def initialize(server, socket)
  super(server)
  
  @socket = socket
  
  async.run
end

Instance Method Details

#handle_connectionObject



128
129
130
131
132
133
134
135
136
137
138
# File 'lib/celluloid/dns/handler.rb', line 128

def handle_connection
  # @logger.debug "Waiting for incoming UDP packet #{@socket.inspect}..."
  
  input_data, (_, remote_port, remote_host) = @socket.recvfrom(UDP_TRUNCATION_SIZE)
  
  async.respond(input_data, remote_host, remote_port)
rescue IOError => error
  @logger.warn "<> UDP connection failed: #{error.inspect}!"
rescue EOFError => error
  @logger.warn "<> UDP session ended prematurely!"
end

#respond(input_data, remote_host, remote_port) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/celluloid/dns/handler.rb', line 100

def respond(input_data, remote_host, remote_port)
  options = {peer: remote_host, port: remote_port, proto: :udp}
  
  response = process_query(input_data, options)
  
  output_data = response.encode
  
  @logger.debug "<#{response.id}> Writing #{output_data.bytesize} bytes response to client via UDP..."
  
  if output_data.bytesize > UDP_TRUNCATION_SIZE
    @logger.warn "<#{response.id}>Response via UDP was larger than #{UDP_TRUNCATION_SIZE}!"
    
    # 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.send(output_data, 0, remote_host, remote_port)
rescue IOError => error
  @logger.warn "<> UDP response failed: #{error.inspect}!"
rescue EOFError => error
  @logger.warn "<> UDP session ended prematurely: #{error.inspect}!"
rescue DecodeError
  @logger.warn "<> Could not decode incoming UDP data!"
end

#runObject



92
93
94
95
96
97
98
# File 'lib/celluloid/dns/handler.rb', line 92

def run
  Celluloid.logger.debug(self.class.name) {"-> Run..."}

  handle_connection while @socket
  
  Celluloid.logger.debug(self.class.name) {"<- Run..."}
end