diff options
-rw-r--r-- | lib/custodian/protocoltest/ping.rb | 80 |
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 |