class Scriptroute::Tulip::TracePath

the traceroute path ############

Attributes

dst[R]
path[R]
speaks_udp[R]
status_code[R]

Public Class Methods

new(dst, resolveNames=false, start_ttl=1, end_ttl=30) click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 618
def initialize (dst, resolveNames=false, start_ttl=1, end_ttl=30)
  @path = Array.new;
  @dst = dst;
  @speaks_udp = (LangChecker.udp(@dst)) ? true : false;
  @status_code = "incomplete";

  #make self as first hop; simplifies binary search.
  @path.push(TraceHop.new(0, "0", dst));

  probe = Scriptroute::UDP.new(12)
  probe.ip_dst = dst
  port_unreach = false

  catch :port_unreachable do 
    (start_ttl..end_ttl).each { |ttl|
      probe.ip_ttl = ttl
      #puts "before trace: %.3f" % [Time.now.to_f];
      packets = Scriptroute::send_train([ Struct::DelayedPacket.new(0, probe) ]);
      #puts "after trace: %.3f" % [Time.now.to_f];
      if (!packets[0]) then 
        STDERR.puts("WARNING: scriptrouted err'd. sleeping and retrying"); 
        Kernel::sleep(5); 
        redo; 
      end;
      response = (packets[0].response) ?  packets[0].response.packet : nil
      if (response.is_a?(Scriptroute::ICMP)) then
        name = response.ip_src;
        if (resolveNames) then
          begin 
            name = Socket.gethostbyname(response.ip_src)[0];
          rescue 
          end
        end
        @path.push(TraceHop.new(ttl, response.ip_src, dst, name)) if (!containsIP(response.ip_src));
        port_unreach = true if (response.icmp_type == 3)
        @status_code = "complete" if (response.icmp_type == 3 && response.icmp_code == 3) 
      else
        port_unreach = true if (ttl - @path.last.hop >=2 and !@speaks_udp);
      end
      throw :port_unreachable if(port_unreach)
    }
  end
  
end

Public Instance Methods

checkValidAnchors(farindex, farpath, nearindex, nearpath, verbose=true) click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 709
def checkValidAnchors(farindex, farpath, nearindex, nearpath, verbose=true) 
  return (farpath.subset(nearpath) and subset(farpath, path[nearindex].hop));     
end
containsIP(ip) click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 663
def containsIP(ip) 
  @path[1..-1].map { |p| return true if (p.ip == ip) };
  return false;
end
getClosestTSNode(starthop, delta, minhop, maxhop) click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 668
def getClosestTSNode(starthop, delta, minhop, maxhop) 
  while (starthop >= minhop && starthop <= maxhop) 
    if LangChecker.probeResponse(@path[starthop].ip, 
                                 Scriptroute::ICMP::ICMP_TSTAMP, 
                                 Scriptroute::ICMP::ICMP_TSTAMPREPLY) then
       return starthop;
     end
     starthop += delta;
   end
   return nil;
 end
getIndex(ip) click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 713
def getIndex(ip)
  (1..@path.length-1).each { |i|
    if (@path[i].ip == ip) 
      return i;
    end
  }
  return -1;
end
subset(another, minhop = 1) click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 680
def subset (another, minhop = 1) 
  lasthop = another.path.last.hop;
  matches = Array.new();
  mismatches = Array.new();
  empties = Array.new();
  (minhop..lasthop).each { |hop|
    myhop = @path[hop];
    hishop = another.path[hop];
    if (myhop and hishop) 
      (myhop == hishop)? matches.push(hop) : mismatches.push(hop);
    elsif (myhop or hishop) 
      empties.push(hop);
    end
  }
  lastMatch = true;
  if (another.status_code == "incomplete")
    index = getIndex(another.dst);
    if (index < 0 or lasthop + 1 < index) then
      lastMatch = false;
    end
  end

  #puts "subset results. matches: #{matches.join(" ")} mismatches: #{mismatches.join(" ")} empties: #{empties.join(" ")} lastMatch: #{lastMatch}";

  return true if ((mismatches.length == 0 or mismatches.last <= $prefixpath) && ##let go for local load balancing
                  lastMatch and matches.index(lasthop));   ##the last hop has to match
  return false;
end
to_s() click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 722
def to_s 
  @path[1..-1].map { |p| p.to_s }.join("\n");
end