lib/phut/vhost_daemon.rb in phut-0.7.7 vs lib/phut/vhost_daemon.rb in phut-0.7.8

- old
+ new

@@ -1,5 +1,7 @@ +# frozen_string_literal: true + require 'drb' require 'logger' require 'phut/raw_socket' require 'pio' @@ -14,26 +16,59 @@ def self.process(name, socket_dir) DRbObject.new_with_uri(unix_domain_socket(name, socket_dir)) end def initialize(options) - @options = options + @options = options.dup + @options[:device] = @options.fetch(:interface) + @options[:log_dir] = File.expand_path(@options[:log_dir]) + @options[:pid_dir] = File.expand_path(@options[:pid_dir]) + @options[:socket_dir] = File.expand_path(@options[:socket_dir]) reset_stats end + def name + @options.fetch :name + end + + def ip_address + @options.fetch :ip_address + end + + def mac_address + @options.fetch :mac_address + end + + def device + @options[:device] + end + + def device=(name) + @options[:device] = name + end + def run start_logging create_pid_file start_daemon + @stop = false rescue shutdown end + def running? + FileTest.exists?(pid_file) + end + def stop @stop = true end + def kill + @kill = true + end + def send_packets(dest, npackets) return unless lookup_arp_table(dest.ip_address) udp = create_udp_packet(dest) npackets.times do write_to_raw_socket udp @@ -48,23 +83,27 @@ def reset_stats @packets_sent = [] @packets_received = [] end + def arp_table=(arp_table) + @options[:arp_table] = arp_table + end + private def start_logging @logger = Logger.new(File.open(log_file, 'a')) @logger.info("#{@options.fetch(:name)} started " \ - "(interface = #{@options.fetch(:interface)}," \ + "(interface = #{@options.fetch(:device)}," \ " IP address = #{@options.fetch(:ip_address)}," \ " MAC address = #{@options.fetch(:mac_address)}," \ " arp_entries = #{@options.fetch(:arp_entries)})") end def raw_socket - @raw_socket ||= RawSocket.new(@options.fetch(:interface)) + @raw_socket ||= RawSocket.new(@options.fetch(:device)) end def lookup_arp_table(ip_address) @options.fetch(:arp_table)[ip_address] end @@ -87,15 +126,21 @@ def log_file "#{@options.fetch(:log_dir)}/vhost.#{@options.fetch(:name)}.log" end # rubocop:disable MethodLength + # rubocop:disable AbcSize def read_loop loop do + unless @options.fetch(:device) + sleep 0.1 + next + end begin raw_data, = raw_socket.recvfrom(8192) udp = Pio::Udp.read(raw_data) + next if @stop unless @options[:promisc] next if udp.destination_ip_address != @options.fetch(:ip_address) end @logger.info "Received: #{udp}" @packets_received << udp.snapshot @@ -104,10 +149,11 @@ sleep 1 end end end # rubocop:enable MethodLength + # rubocop:enable AbcSize def start_daemon Process.daemon trap_sigint update_pid_file @@ -116,46 +162,42 @@ def start_threads_and_join unix_domain_socket = self.class.unix_domain_socket(@options.fetch(:name), @options.fetch(:socket_dir)) - DRb.start_service(unix_domain_socket, self, UNIXFileMode: 0666) + DRb.start_service(unix_domain_socket, self, UNIXFileMode: 0o666) Thread.start { read_loop }.abort_on_exception = true DRb.thread.join end def shutdown @logger.error $ERROR_INFO if $ERROR_INFO @logger.info 'Shutting down...' FileUtils.rm pid_file if running? DRb.stop_service - fail $ERROR_INFO if $ERROR_INFO + raise $ERROR_INFO if $ERROR_INFO end def trap_sigint Thread.start { shutdown_loop }.abort_on_exception = true Signal.trap(:INT) { stop } end def shutdown_loop loop do - break if @stop + break if @kill sleep 0.1 end shutdown end def create_pid_file - fail "#{@options.fetch(:name)} is already running." if running? + raise "#{@options.fetch(:name)} is already running." if running? update_pid_file end def update_pid_file File.open(pid_file, 'w') { |file| file << Process.pid } - end - - def running? - FileTest.exists?(pid_file) end def pid_file File.join @options.fetch(:pid_dir), "vhost.#{@options.fetch(:name)}.pid" end