Class: Scriptroute::Tulip::TracePath

Inherits:
Object
  • Object
show all
Defined in:
lib/scriptroute/tulip/helper.rb

Overview

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dst, resolveNames = false, start_ttl = 1, end_ttl = 30) ⇒ TracePath

Returns a new instance of TracePath.



618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
# 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

Instance Attribute Details

#dstObject (readonly)

Returns the value of attribute dst.



616
617
618
# File 'lib/scriptroute/tulip/helper.rb', line 616

def dst
  @dst
end

#pathObject (readonly)

Returns the value of attribute path.



616
617
618
# File 'lib/scriptroute/tulip/helper.rb', line 616

def path
  @path
end

#speaks_udpObject (readonly)

Returns the value of attribute speaks_udp.



616
617
618
# File 'lib/scriptroute/tulip/helper.rb', line 616

def speaks_udp
  @speaks_udp
end

#status_codeObject (readonly)

Returns the value of attribute status_code.



616
617
618
# File 'lib/scriptroute/tulip/helper.rb', line 616

def status_code
  @status_code
end

Instance Method Details

#checkValidAnchors(farindex, farpath, nearindex, nearpath, verbose = true) ⇒ Object



709
710
711
# 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) ⇒ Object



663
664
665
666
# 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) ⇒ Object



668
669
670
671
672
673
674
675
676
677
678
# 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) ⇒ Object



713
714
715
716
717
718
719
720
# 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) ⇒ Object



680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
# 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_sObject



722
723
724
# File 'lib/scriptroute/tulip/helper.rb', line 722

def to_s 
  @path[1..-1].map { |p| p.to_s }.join("\n");
end