module Scriptroute

Public Class Methods

DaemonConfig() click to toggle source

@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
DaemonVersion() click to toggle source

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
daemon_running_or_exit() click to toggle source

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
dns_lookup(name) click to toggle source

@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
is_daemon_running?() click to toggle source

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
nameify(addr) click to toggle source
# 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
pkt_from_string(s) click to toggle source

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
send_train(train) click to toggle source

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
with_scriptroute_connection() { |c| ... } click to toggle source

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