module Scriptroute
Public Class Methods
@return [Hash] the configuration of the running daemon,
useful for checking rate limiting parameters or filters if a specially configured daemon is needed.
# File lib/scriptroute.rb, line 234 def Scriptroute::DaemonConfig ret = nil unless @@config then with_scriptroute_connection do |c| @@config = c.get_config end end @@config end
Query for the version of the daemon; useful if there’s a feature only supported in a particular version. @return @return [String] the version string provided by of the running daemon
# File lib/scriptroute.rb, line 218 def Scriptroute::DaemonVersion with_scriptroute_connection do |c| puts c.one_line_command("version\n") end end
Exit failure if the scriptroute daemon does not appear to be running. This is useful at the beginning of scripts that expect the daemon to run, to avoid adding extra error checking later. @return [true] if the script does ot exit because the daemon
is not running.
# File lib/scriptroute.rb, line 205 def Scriptroute::daemon_running_or_exit begin with_scriptroute_connection do |c| end return true rescue Errno::ECONNREFUSED puts "Ensure that the scriptroute daemon is running and try again" exit 1 end end
@return [String] An IP
address associated with the
hostname. Currently just invokes Resolv.getaddress.
# File lib/scriptroute.rb, line 225 def Scriptroute::dns_lookup(name) Resolv.getaddress name end
Check if the daemon is running by making a connection or checking the pool for an unused but working connection. @return [Boolean]
# File lib/scriptroute.rb, line 190 def Scriptroute::is_daemon_running? begin with_scriptroute_connection do |c| end return true rescue Errno::ECONNREFUSED return false end end
# File lib/scriptroute/nameify.rb, line 44 def Scriptroute::nameify(addr) unless addr.is_a?(Scriptroute::IPaddress) then # if not a known IP address, validate. if addr == nil or addr == '' then # empty string. usually a mistake somewhere. $stderr.puts "nameify('') called from:\n " + Kernel.caller.join("\n ") return addr end if(! /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.match(addr)) then # not an ip address looking thing. $stderr.puts "nameify(#{addr}) called from:\n " + Kernel.caller.join("\n ") return addr end end name = if($have_resolv) then begin Resolv.getnames(addr.to_s)[0] rescue ArgumentError => boom # seems to happen for RFC1918 space, but probably just for those # addresses without a name. $stderr.puts "argument error resolving '#{addr}' to name using resolv: " + boom nil rescue SocketError => boom nil end elsif($have_socket) then begin name = (Socket.gethostbyname(addr.to_s)[0]).gsub(/\"/,'') name rescue ArgumentError => boom # seems to happen for RFC1918 space, but probably just for those # addresses without a name. $stderr.puts "argument error resolving '#{addr}' to name: " + boom nil rescue SocketError => boom nil end else nil end attributes = if($have_undns) then if(name) then asn = Undns.get_asn_bydns(name) if($have_origins) then " [%d/%d]" % [ asn, Undns.origin_for_address_str(addr) ] elsif(asn > 0) then " [%d]" % [ asn ] else "" end + if(asn > 0) then " {%s}" % [ Undns.get_loc(asn, name) ] else "" end elsif($have_origins) then # don't have a name. " [/%d]" % [ Undns.origin_for_address_str(addr) ] else "" end else "" end if(name) then name + ' (' + addr.to_s + ')' + attributes else addr.to_s + attributes end end
no op for backward compatibility with the srinterpreter version that had a dedicated packet instance @param s [String] A marshaled packet. @return [String] The input parameter, which is sufficient for this implementation of {Scriptroute::send_train}.
# File lib/scriptroute.rb, line 247 def Scriptroute::pkt_from_string(s) s end
This is the nut. @param train [Array<Struct::DelayedPacket,Array>] an array of Struct::DelayedPacket entries or arrays containing delay, packet pairs. @return [Array<Scriptroute::ProbeResponse>] an array of Scriptroute::ProbeResponse
entries, comprising a probe and response.
# File lib/scriptroute.rb, line 253 def Scriptroute::send_train(train) ret = nil return [] if train.empty? # easy? with_scriptroute_connection do |c| # issue the send train command. i = 1; total_delay = 0 train.map! { |boxcar| raise ArgumentError, 'nil entry' unless boxcar if boxcar.is_a?(Array) then Struct::DelayedPacket.new(*boxcar) else raise ArgumentError, 'not a boxcar or an array' unless boxcar.is_a?(Struct::DelayedPacket) boxcar end } train.each { |boxcar| # needs validation. delay = boxcar[:delay] packet = boxcar[:packet] raise "no packet" unless packet if packet.is_a?(Scriptroute::IP) then packet = packet.marshal end raise "packet is #{packet.class}, not a string" unless packet.is_a?(String) encoded_packet = Base64.strict_encode64(packet) # strict_encode means no line feeds added. c.issue_command "sendtrain %d/%d %f %d %s\n" % [ i, train.length, delay<0 ? 0 : delay, encoded_packet.length, encoded_packet ] i+=1 total_delay += delay } # allocate space for the responses, array of probe response pairs, each of which will be a time/packet pair. ret = Array.new(i-1) { ProbeResponse.new } # collect, waiting maybe 5 minutes more than needed just in case the daemon hangs on us. begin timeout(total_delay + 300) do while l = c.get_reply and l !~ /^done/ and l =~ /\S+/ do if l =~ /^ERROR/ then # have to throw an exception, although individual packet errors are possible, that's # not communicated by the daemon. $stderr.puts l if l=~ /disjoint train \missing packet #(\d+)/ then ret[ $1.to_i ].probe = nil ret[ $1.to_i ].response = nil end raise ScriptrouteError, l else if l =~ /^(-?\d+\.\d+)\/(\d+) (\d+)([<>]) \d+ (\S+)$/ then tv_s = $1.to_f rdtsc = $2 pk = $3.to_i - 1 io = ($4 == '>') ? 0 : 1 st = $5 packet_string = Base64.strict_decode64(st) p = IP.creator(packet_string) tv_s = nil if tv_s < 0 # didn't see it leave. tp = TimedPacket.new(tv_s, rdtsc, p) if io == 0 then ret[ pk ].probe = tp else ret[ pk ].response = tp end else puts "unparsed send_train response: #{l}" end end end # while end # timeout rescue TimeoutError $stderr.puts "timed out parsing responses for send_train" end end return ret end
Take a block to be executed with a ScriptrouteConnection
from the pool. This is the function to use, since it manages the pooled connections explicitly. A leak in connections would be bad. @yield [ScriptrouteConnection] the connection for this block. @return the output of the block
# File lib/scriptroute.rb, line 181 def Scriptroute::with_scriptroute_connection c = ConnectionPool.get_idle_connection r = yield c ConnectionPool.return_idle_connection(c) r end