summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSteve Kemp <steve@steve.org.uk>2015-03-02 12:07:00 +0000
committerSteve Kemp <steve@steve.org.uk>2015-03-02 12:07:00 +0000
commitad94bfa84ed681728a97ed2c4bb537dbae6a190d (patch)
treee35f94438d9357c81883a06cbd49f4234fee587e /lib
parent5081a443f6722bf56550636dbcf3128310f856d7 (diff)
Test for IPv4 and IPv6 addresses explicitly.
If we're given an IPv4 or IPv6 address then use it, if not then attempt to resolve the name that we've been given to one/other/both of these types and test in turn.
Diffstat (limited to 'lib')
-rw-r--r--lib/custodian/protocoltest/ping.rb80
1 files changed, 75 insertions, 5 deletions
diff --git a/lib/custodian/protocoltest/ping.rb b/lib/custodian/protocoltest/ping.rb
index 3d3d0d7..8f3911d 100644
--- a/lib/custodian/protocoltest/ping.rb
+++ b/lib/custodian/protocoltest/ping.rb
@@ -10,6 +10,11 @@ require 'custodian/testfactory'
### DNSHOSTS must run ping otherwise ..
###
#
+# We take care to resolve any value we test, so that we can test explicitly
+# for the family involved. (i.e. If we're ping-testing example.com then
+# we will explicitly look for an IPv4 and IPv6 address to test, rather than
+# just using 'example.com'.)
+#
#
module Custodian
@@ -65,6 +70,7 @@ module Custodian
# Find the binary we're going to invoke.
#
binary = nil
+ binary = "./bin/multi-ping"
binary = "/usr/bin/multi-ping" if ( File.exists?( "/usr/bin/multi-ping" ) )
if ( binary.nil? )
@@ -86,15 +92,79 @@ module Custodian
#
- # Run the test: Avoiding the use of the shell.
+ # Get the timeout period.
#
- if ( system( binary, @host ) == true )
- return true
- else
- @error = "Ping failed."
+ settings = Custodian::Settings.instance()
+ period = settings.timeout()
+
+
+
+ #
+ # Perform the DNS lookups of the specified name.
+ #
+ ips = Array.new()
+
+ #
+ # Does the name look like an IP?
+ #
+ begin
+ x = IPAddr.new( @host )
+ if ( x.ipv4? or x.ipv6? )
+ ips.push( @host )
+ end
+ rescue ArgumentError
+ end
+
+
+ #
+ # OK if it didn't look like an IP address then attempt to
+ # look it up, as both IPv4 and IPv6.
+ #
+ begin
+ timeout( period ) do
+
+ Resolv::DNS.open do |dns|
+ ress = dns.getresources(@host, Resolv::DNS::Resource::IN::A)
+ ress.map { |r| ips.push( r.address.to_s ) }
+ ress = dns.getresources(@host, Resolv::DNS::Resource::IN::AAAA)
+ ress.map { |r| ips.push( r.address.to_s ) }
+ end
+ end
+ rescue Timeout::Error => e
+ @error = "Timed-out performing DNS lookups: #{e}"
+ return nil
+ end
+
+
+ #
+ # Did we fail to perform a DNS lookup?
+ #
+ if ( ips.empty? )
+ @error = "#{@host} failed to resolve to either IPv4 or IPv6"
return false
end
+
+ #
+ # Run the test, avoiding the use of the shell, for each of the
+ # IPv4 and IPv6 addresses we discovered, or the host that we
+ # were given.
+ #
+ ips.each do |ip|
+ if ( system( binary, ip ) != true )
+ @error = "Ping failed for #{ip} - from #{@host} "
+ return false
+ end
+ end
+
+ #
+ # If there was a failure then the previous loop would have
+ # set the @error value and returned false.
+ #
+ # So by the time we reach here we know that all the addresses
+ # were pingable.
+ #
+ return true
end