<commit_before>require 'net-dhcp'
require 'ostruct'
require 'ipaddr'

module Blondy
  module DHCPD
    class Dispatcher
      class << self
	def dispatch(data, ip, port)
	  @data = DHCP::Message.from_udp_payload(data) rescue raise(IncorrectMessage, 'Incorrect message received.')
	  raise(IncorrectMessage, 'Incorrect message received.') unless @data
	  reply
	end

	private

	def reply
	  DHCP::Message.class_eval {attr_accessor :hwaddr}
	  @data.hwaddr = @data.chaddr.take(@data.hlen).map {|x| x.to_s(16).size<2 ? '0'+x.to_s(16) : x.to_s(16)}.join(':')
	  @reply = OpenStruct.new
	  msg_class = @data.class.to_s.gsub(/^.*::/, '').downcase
	  handle(msg_class)
	end

	def handle(msg_class)
	  if %w{discover request inform release}.include?(msg_class)
	    @pool = Pool.query(@data.hwaddr, msg_class.to_sym)
	    @pool ? send("#{msg_class}_handler".to_sym) : false
	  else
	    raise NoMessageHandler, 'No appropriate handler for message.'
	  end
	end

	def discover_handler
	    @reply.data = DHCP::Offer.new
	    create_reply
	end

	def request_handler
	    @reply.data = DHCP::ACK.new
	    create_reply
	end

	def release_handler
	  @reply.data = nil
	end

	def inform_handler
	  @reply.data = DHCP::ACK.new
	  create_reply
	end

	def create_reply
	  @reply.data.yiaddr = @pool.data.yiaddr
	  @reply.data.fname = @pool.data.fname
	  @reply.data.options = @pool.data.options
	  @reply.data.siaddr = IPAddr.new(Blondy::DHCPD::CONFIG['server_ip']).to_i
	  @reply.data.xid = @data.xid if @data.xid
	  @reply.ip = '255.255.255.255'
	  set_port
	  @reply
	end

	def set_port
	  @reply.port = 68
	  if @data.giaddr == 0 and @data.ciaddr != 0
	    @reply.ip = IPAddr.new(@data.ciaddr, family = Socket::AF_INET).to_s
	  elsif @data.giaddr != 0
	    @reply.ip = IPAddr.new(@data.giaddr, family = Socket::AF_INET).to_s
	    @reply.port = 67
	  else
	    false
	  end
	end
      end
    end
  end
end

class NoMessageHandler < StandardError
end
class IncorrectMessage < StandardError
end
<commit_msg>split create_reply into few methods<commit_after>require 'net-dhcp'
require 'ostruct'
require 'ipaddr'

module Blondy
  module DHCPD
    class Dispatcher
      class << self
	def dispatch(data, ip, port)
	  @data = DHCP::Message.from_udp_payload(data) rescue raise(IncorrectMessage, 'Incorrect message received.')
	  raise(IncorrectMessage, 'Incorrect message received.') unless @data
	  reply
	end

	private

	def reply
	  DHCP::Message.class_eval {attr_accessor :hwaddr}
	  @data.hwaddr = @data.chaddr.take(@data.hlen).map {|x| x.to_s(16).size<2 ? '0'+x.to_s(16) : x.to_s(16)}.join(':')
	  @reply = OpenStruct.new
	  msg_class = @data.class.to_s.gsub(/^.*::/, '').downcase
	  handle(msg_class)
	end

	def handle(msg_class)
	  if %w{discover request inform release}.include?(msg_class)
	    @pool = Pool.query(@data.hwaddr, msg_class.to_sym)
	    @pool ? send("#{msg_class}_handler".to_sym) : false
	  else
	    raise NoMessageHandler, 'No appropriate handler for message.'
	  end
	end

	def discover_handler
	    @reply.data = DHCP::Offer.new
	    create_reply
	end

	def request_handler
	    @reply.data = DHCP::ACK.new
	    create_reply
	end

	def release_handler
	  @reply.data = nil
	end

	def inform_handler
	  @reply.data = DHCP::ACK.new
	  create_reply
	end

	def create_reply
	  set_src
	  set_pool_data
	  set_other
	  @reply
	end

	def set_src
	  if @data.giaddr == 0 and @data.ciaddr != 0
	    @reply.ip = IPAddr.new(@data.ciaddr, family = Socket::AF_INET).to_s
	    @reply.port = 68
	  elsif @data.giaddr != 0
	    @reply.ip = IPAddr.new(@data.giaddr, family = Socket::AF_INET).to_s
	    @reply.port = 67
	  else
	    @reply.ip = '255.255.255.255'
	    @reply.port = 68
	  end
	end

	def set_pool_data
	  @reply.data.yiaddr = @pool.data.yiaddr
	  @reply.data.fname = @pool.data.fname
	  @reply.data.options = @pool.data.options
	end

	def set_other
	  @reply.data.siaddr = IPAddr.new(Blondy::DHCPD::CONFIG['server_ip']).to_i
	  @reply.data.xid = @data.xid if @data.xid
	end
      end
    end
  end
end

class NoMessageHandler < StandardError
end
class IncorrectMessage < StandardError
end

{'fraction_non_alphanumeric': 0.12576312576312576, 'fraction_numerical': 0.013675213675213675, 'mean_word_length': 3.3948497854077253, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6250037', 'n_tokens_mistral': 1672, 'n_tokens_neox': 1519, 'n_words': 325}