Class: DIY::Controller

Inherits:
Object
  • Object
show all
Defined in:
lib/diy/controller.rb

Instance Method Summary collapse

Constructor Details

#initialize(client, server, offline, strategy) ⇒ Controller

Returns a new instance of Controller.



6
7
8
9
10
11
12
13
14
# File 'lib/diy/controller.rb', line 6

def initialize( client, server, offline, strategy)
  @client = client
  @server = server
  @offline = offline
  @strategy = strategy
  @before_send = nil
  @timeout = nil
  @error_on_stop = nil
end

Instance Method Details

#before_send(&block) ⇒ Object



143
144
145
# File 'lib/diy/controller.rb', line 143

def before_send(&block)
  @before_send = block
end

#client_send(client, pkts) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/diy/controller.rb', line 119

def client_send(client, pkts)
  if @before_send
    pkts = pkts.collect do |pkt| 
      content = pkt.content
      begin
        pkt.content = @before_send.call(content)
      rescue Exception => e
        DIY::Logger.warn("UserError Catch: " + error = BeforeSendCallError.new(e) )
        error.backtrace.each do |msg|
          DIY::Logger.info(msg)
        end
        raise error
      end
      pkt
    end
  end
  begin
    client.inject(pkts)
  rescue FFI::PCap::LibError =>e
    DIY::Logger.warn("SendPacketError Catch: " + e )
    raise e
  end
end

#do_trapObject



70
71
72
73
74
75
76
# File 'lib/diy/controller.rb', line 70

def do_trap
  Signal.trap("INT") do
    DIY::Logger.info "bye.."
    stop
    exit 0
  end    
end

#error_on_stopObject



151
152
153
# File 'lib/diy/controller.rb', line 151

def error_on_stop(*)
  @error_on_stop = true
end

#offline_resultObject



160
161
162
# File 'lib/diy/controller.rb', line 160

def offline_result
  sprintf "%4d files, %8d packets", @offline.files_size, @offline.now_size
end

#one_round(client, server, pkts) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/diy/controller.rb', line 83

def one_round( client, server, pkts )
  @error_flag = nil
  @round_count = 0 unless @round_count
  @round_count += 1
  DIY::Logger.info "round #{@round_count}: (c:#{client.__drburi} / s:#{server.__drburi}) #{pkts[0].pretty_print}:(queue= #{pkts.size})"
  if pkts.size >= 10
    DIY::Logger.info "queue size too big: #{pkts.size}, maybe something error"
  end
  
  recv_pkt_proc_set( pkts )
  server.ready(&@recv_pkt_proc)
  
  client_send(client, pkts)
  wait_recv_ok(pkts)
  server.terminal
end

#recv_pkt_proc_set(queue) ⇒ Object

设置回调入口, 由 worker 通过DRb 远程调用



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/diy/controller.rb', line 101

def recv_pkt_proc_set(queue)
  @queue_keeper = queue
  # 不重新赋值, 防止 DRb 回收

  @recv_pkt_proc ||= lambda do |recv_pkt|
    begin
      next if @error_flag # error accur waiting other thread do with it

      @recv_pkt_keeper = Packet.new(recv_pkt)
      @strategy.call(@queue_keeper.first, @recv_pkt_keeper, @queue_keeper)
    rescue DIY::UserError =>e
      DIY::Logger.warn("UserError Catch: " + e.inspect)
      e.backtrace.each do |msg|
        DIY::Logger.info(msg)
      end
      @error_flag = e
    end        
  end
end

#runObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
65
66
67
68
# File 'lib/diy/controller.rb', line 16

def run
  do_trap
  client = @client
  server = @server
  
  @fail_count = 0
  start_time = Time.now
  #clear

  client.terminal
  server.terminal
  
  loop do
    begin
      pkts, where = @offline.nexts
      case where
      when :A
        client, server = @client, @server
      when :B
        client, server = @server, @client
      end
      one_round( client, server, pkts )
    rescue HopePacketTimeoutError, UserError, FFI::PCap::LibError => e
      DIY::Logger.warn( "Timeout: Hope packet is #{pkts[0].pretty_print} ") if e.kind_of?(HopePacketTimeoutError)
      @fail_count += 1
      if @error_on_stop and e.kind_of?(HopePacketTimeoutError)
        client.terminal
        server.terminal
        DIY::Logger.info "Error_on_stop flag opened, stopping..."
        DIY::Logger.info "Dump mac learn table(size is #{@offline.mac_learner.size})... "
        DIY::Logger.info @offline.mac_learner.dump
        break
      end
      #~ begin

        #~ @offline.next_pcap

        #~ server.terminal

      #~ rescue EOFError

        #~ client.terminal

        #~ server.terminal

        #~ break

      #~ end

      #~ client,server = @client, @server

    rescue EOFError
      client.terminal
      server.terminal
      break
    ensure
      #~ client, server = server, client

    end
  end
  DRb.stop_service
  end_time = Time.now
  stats_result( end_time - start_time, @fail_count )
end

#stats_result(cost_time, fail_count) ⇒ Object



155
156
157
158
# File 'lib/diy/controller.rb', line 155

def stats_result( cost_time, fail_count )
  DIY::Logger.info " Finished in #{cost_time} seconds"
  DIY::Logger.info " #{offline_result}, #{fail_count} failures"
end

#stopObject



78
79
80
81
# File 'lib/diy/controller.rb', line 78

def stop
  @client.terminal
  @server.terminal
end

#timeout(timeout) ⇒ Object



147
148
149
# File 'lib/diy/controller.rb', line 147

def timeout(timeout)
  @timeout = timeout
end

#wait_recv_ok(pkts) ⇒ Object



164
165
166
167
168
169
170
171
# File 'lib/diy/controller.rb', line 164

def wait_recv_ok(pkts)
  wait_until(@timeout ||= 10) do
    if @error_flag
      raise @error_flag
    end
    pkts.empty?
  end
end

#wait_until(timeout = 10, &block) ⇒ Object



173
174
175
176
177
178
179
180
# File 'lib/diy/controller.rb', line 173

def wait_until( timeout = 10, &block )
  Timeout.timeout(timeout, DIY::HopePacketTimeoutError.new("hope packet wait timeout after #{timeout} seconds") ) do
    loop do
      break if block.call
      sleep 0.01
    end
  end
end