Class: ICMP4EM::ICMPv4

Inherits:
Object
  • Object
show all
Includes:
Common, HostCommon
Defined in:
lib/icmp4em/icmpv4.rb

Constant Summary

Constants included from Common

Common::ICMP_ECHO, Common::ICMP_ECHOREPLY, Common::ICMP_SUBCODE

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from HostCommon

#failures_required=, #on_expire, #on_failure, #on_recovery, #on_success, #recoveries_required=

Constructor Details

#initialize(host, options = {}) ⇒ ICMPv4

Create a new ICMP object (host). This takes a host and an optional hash of options for modifying the behavior. They are:

  • :bind_host

Bind the socket to this address. The operating system will figure this out on it’s own unless you need to set it for a special situation.

  • :timeout

Timeout, in seconds, before the ping is considered expired and the appropriate callbacks are executed. This should be a numeric class.

  • :block

True or false, default is false. True enables a blocking receive mode, for when accurate latency measurement is important. Due to the nature of event loop architecture, a noticable delay in latency can be added when other things are going on in the reactor.

  • :interval

Interval, in seconds, for how often the ping should be sent. Should be a numeric class.

  • :stateful

True or false, default is false. Indicates whether or not this ping object should keep track of it’s successes and failures and execute the on_failure/on_recovery callbacks when the specified limits are hit.

  • :failures_required

Indicates how many consequtive failures are required to switch to the ‘failed’ state and execute the on_failure callback. Applies only when :stateful => true

  • :recoveries_required

Indicates how many consequtive successes are required to switch to the ‘recovered’ state and execute the on_recovery callback. Applies only when :stateful => true



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/icmp4em/icmpv4.rb', line 38

def initialize(host, options = {})
  raise 'requires root privileges' if Process.euid > 0
  @host = host
  @ipv4_sockaddr = Socket.pack_sockaddr_in(0, @host)
  @interval   =   options[:interval] || 1
  @timeout    =   options[:timeout] || 1
  @stateful   =   options[:stateful] || false
  @bind_host  =   options[:bind_host] || nil
  @block      =   options[:block] || false
  @recoveries_required = options[:recoveries_required] || 5
  @failures_required   = options[:failures_required] || 5
  @up = true
  @waiting = {}
  set_id
  @seq, @failcount = 0, 0
  @data = "Ping from EventMachine"
end

Class Attribute Details

.handlerObject

Returns the value of attribute handler.



14
15
16
# File 'lib/icmp4em/icmpv4.rb', line 14

def handler
  @handler
end

.instancesObject (readonly)

Returns the value of attribute instances.



13
14
15
# File 'lib/icmp4em/icmpv4.rb', line 13

def instances
  @instances
end

.recvsocketObject

Returns the value of attribute recvsocket.



14
15
16
# File 'lib/icmp4em/icmpv4.rb', line 14

def recvsocket
  @recvsocket
end

Instance Attribute Details

#bind_hostObject

Returns the value of attribute bind_host.



18
19
20
# File 'lib/icmp4em/icmpv4.rb', line 18

def bind_host
  @bind_host
end

#blockObject

Returns the value of attribute block.



18
19
20
# File 'lib/icmp4em/icmpv4.rb', line 18

def block
  @block
end

#dataObject

Returns the value of attribute data.



18
19
20
# File 'lib/icmp4em/icmpv4.rb', line 18

def data
  @data
end

#failures_requiredObject (readonly)

Returns the value of attribute failures_required.



19
20
21
# File 'lib/icmp4em/icmpv4.rb', line 19

def failures_required
  @failures_required
end

#idObject (readonly)

Returns the value of attribute id.



19
20
21
# File 'lib/icmp4em/icmpv4.rb', line 19

def id
  @id
end

#intervalObject

Returns the value of attribute interval.



18
19
20
# File 'lib/icmp4em/icmpv4.rb', line 18

def interval
  @interval
end

#recoveries_requiredObject (readonly)

Returns the value of attribute recoveries_required.



19
20
21
# File 'lib/icmp4em/icmpv4.rb', line 19

def recoveries_required
  @recoveries_required
end

#seqObject (readonly)

Returns the value of attribute seq.



19
20
21
# File 'lib/icmp4em/icmpv4.rb', line 19

def seq
  @seq
end

#thresholdObject

Returns the value of attribute threshold.



18
19
20
# File 'lib/icmp4em/icmpv4.rb', line 18

def threshold
  @threshold
end

#timeoutObject

Returns the value of attribute timeout.



18
19
20
# File 'lib/icmp4em/icmpv4.rb', line 18

def timeout
  @timeout
end

Instance Method Details

#pingObject

Send the echo request to @host and add sequence number to the waiting queue.



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/icmp4em/icmpv4.rb', line 65

def ping
  raise "EM not running" unless EM.reactor_running?
  init_handler if self.class.recvsocket.nil?
  @seq = ping_send
  if @block
    blocking_receive
  else
    EM.add_timer(@timeout) { self.send(:expire, @seq, Timeout.new("Ping timed out")) } unless @timeout == 0
  end
  @seq
end

#scheduleObject

Uses a periodic timer to ping the host at @interval.



78
79
80
81
# File 'lib/icmp4em/icmpv4.rb', line 78

def schedule
  raise "EM not running" unless EM.reactor_running?
  @ptimer = EM::PeriodicTimer.new(@interval) { self.ping }
end

#stopObject

This must be called when the object will no longer be used, to remove the object from the class variable hash that is searched for recipients when an ICMP echo comes in. Also cancels the periodic timer. Better way to do this whole thing?…



59
60
61
62
# File 'lib/icmp4em/icmpv4.rb', line 59

def stop
  @ptimer.cancel if @ptimer
  self.class.instances[@id] = nil
end