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