class TFTP::ListeningConnection

UDP socket (really EM::Connection) on TFTP server which waits for incoming RRQ/WRQ When an incoming transfer request arrives, calls get/put on its listener

and starts the transfer if get passes true,<file data> (or put passes true) to the block

If the data must be read from hard disk, EM.defer { File.read(…) } is recommended,

so as not to block the EM reactor from handling events

Public Instance Methods

listener() click to toggle source
# File lib/em-tftp.rb, line 299
def listener
  self.class.instance_eval { @listener_klass }
end
receive_data(data) click to toggle source
# File lib/em-tftp.rb, line 303
def receive_data(data)
  peer_port, peer_addr = Socket.unpack_sockaddr_in(get_peername)
  $stderr.puts "Received: #{data} (#{data[0..3].bytes.to_a.join(',')}) from #{peer_addr}:#{peer_port}" if $DEBUG
  packet = Packet.new(data.encode!(Encoding::BINARY))
  send(packet.opcode, peer_addr, peer_port, packet)
rescue TFTP::Error
  if listener.respond_to?(:error)
    listener.error($!.message)
  end
end

Private Instance Methods

ack(addr, port, packet) click to toggle source
# File lib/em-tftp.rb, line 341
def ack(addr, port, packet)
  # It's not a good idea to send an error back for unexpected ACK;
  # some TFTP clients may send an "eager" ACK to try to make file come faster
end
data(addr, port, packet) click to toggle source
# File lib/em-tftp.rb, line 338
def data(addr, port, packet)
  send_error(addr, port, 5, "Unknown transfer ID")
end
rrq(addr, port, packet) click to toggle source
# File lib/em-tftp.rb, line 316
def rrq(addr, port, packet)
  listener.get(addr, port, packet.filename) do |aye_nay, str_data|
    if aye_nay
      connection = EM.open_datagram_socket('0.0.0.0', 0, TFTP::TransferConnection)
      connection.transfer = ServerSend.new(connection, addr, port, listener.new, str_data)
    else
      send_error(addr, port, 0, str_data || "Denied")
    end
  end
end
wrq(addr, port, packet) click to toggle source
# File lib/em-tftp.rb, line 327
def wrq(addr, port, packet)
  listener.put(addr, port, packet.filename) do |aye_nay, str_data|
    if aye_nay
      connection = EM.open_datagram_socket('0.0.0.0', 0, TFTP::TransferConnection)
      connection.transfer = ServerReceive.new(connection, addr, port, listener.new)
    else
      send_error(addr, port, 0, "Denied")
    end
  end
end