class Scriptroute::Tulip::Train
generic train ################
Attributes
dsts[R]
num_losses[R]
numpackets[R]
packets[R]
resolution[R]
reverse_ttls[R]
shuffle[R]
ttls[R]
types[R]
Public Class Methods
new(dsts, numpackets, resolution, types, ttls, shuffle=false)
click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 312 def initialize(dsts, numpackets, resolution, types, ttls, shuffle=false) @dsts, @numpackets, @resolution, @types, @ttls, @shuffle = dsts, numpackets, resolution, types, ttls, shuffle; @reverse_ttls, @rem_srcs, @num_losses, @packets = Array.new(), Array.new(), Array.new(), Array.new(); (@dsts).each_index { |i| @packets[i], @reverse_ttls[i], @rem_srcs[i], @num_losses[i] = Array.new(), Array.new(), Array.new(), 0; } num_dsts = @dsts.length; max_train = (MAX_TRAIN/num_dsts).floor; seq_id = 0; order = 0; allResponsePackets = Array.new(); ( 0 .. (numpackets/max_train).ceil ).each { |trainnum| packetsThisRound = (numpackets < (trainnum+1)*max_train)? (numpackets - trainnum*max_train) : max_train; delayedPackets = Array.new(); ( seq_id .. seq_id + packetsThisRound-1).each { |rep| ##construct probe packets probes = Array.new(); (@dsts).each_index { |i| case types[i] when "tcp" probes[i] = Scriptroute::TCP.new(12); when "udp" probes[i] = Scriptroute::UDP.new(12); probes[i].uh_dport = 33444 ## unknown effect; five-tuple balancing may occur when "echo" probes[i] = Scriptroute::ICMP.new(0) probes[i].icmp_type = Scriptroute::ICMP::ICMP_ECHO; probes[i].icmp_code = 0; probes[i].icmp_seq = rep; when "tstamp" probes[i] = Scriptroute::ICMP.new(0) probes[i].icmp_type = Scriptroute::ICMP::ICMP_TSTAMP; probes[i].icmp_code = 0; probes[i].icmp_seq = rep; else raise("ERROR: unsupported packettype #{types[i]} in sendAndReceiveTrain\n"); end probes[i].ip_ttl = @ttls[i]; probes[i].ip_dst = @dsts[i]; @dsts[i] = probes[i].ip_dst; # accomplishes a name lookup so responses can be classified - nspring } ##insert probe packets in the order desired (@dsts).each_index { |i| delay = (i==0)? resolution : 0; #puts "delay: #{delay} (#{i})"; insert = (order + i) % num_dsts; delayedPackets.push(Struct::DelayedPacket.new(delay, probes[insert])); order = (order + 1) % num_dsts if (@shuffle); } } ##each rep #puts "before real = %.3f" % [Time.now.to_f*1000]; allResponsePackets.push(Scriptroute::send_train(delayedPackets)); #puts "after real = %.3f" % [Time.now.to_f*1000]; } ##each trainnum allResponsePackets.flatten! #allResponsePackets.sort!{ |a,b| a.probe.time <=> b.probe.time } allResponsePackets.each { |pr| if (pr and pr.probe and pr.probe.time) i = getIndex(pr); @packets[i].push(pr); if (pr.response) then @reverse_ttls[i].push(pr.response.packet.ip_ttl) if !@reverse_ttls[i].index(pr.response.packet.ip_ttl); @rem_srcs[i].push(pr.response.packet.ip_src) if !@rem_srcs[i].index(pr.response.packet.ip_src); else @num_losses[i] += 1; end end } # nspring thinks the following is a no-op. (@dsts).each_index { |i| @packets[i].sort! { |a,b| a.probe.time <=> b.probe.time } } ##check sanity of the train (@dsts).each_index { |i| if (@reverse_ttls[i].length > 1) puts "WARNING: too many reverse TTLs for index #{i}: #{@reverse_ttls[i].join(" ")}"; end if (@rem_srcs[i].length > 1) puts "WARNING: too many remote sources for index #{i}: #{@rem_srcs[i].join(" ")}"; end ##todo: should really check a pattern in losses ## to distinguish between high loss rate and rate-limiting if (@num_losses[i] > 0.2*@numpackets) #STDERR.puts "WARNING: too many losses #{@num_losses[i]} for index #{i}"; end } end
Public Instance Methods
getIndex(pr)
click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 300 def getIndex (pr) pkt = pr.probe.packet; @dsts.each_index { |i| if (pkt.ip_dst == @dsts[i] and pkt.ip_ttl == @ttls[i] and getType(pkt) == @types[i]) return i; end } raise "ERROR: could not classify packet: #{pkt.to_s}"; end
getType(pkt)
click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 285 def getType (pkt) if (pkt.is_a?(Scriptroute::TCP)) return "tcp"; elsif (pkt.is_a?(Scriptroute::UDP)) return "udp"; elsif (pkt.is_a?(Scriptroute::ICMP)) if (pkt.icmp_type == Scriptroute::ICMP::ICMP_ECHO) return "echo"; elsif (pkt.icmp_type == Scriptroute::ICMP::ICMP_TSTAMP) return "tstamp"; end end raise "ERROR: unknown packet type: #{pkt.to_s}"; end
to_s()
click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 411 def to_s str = "train: #{@dsts} #{@numpackets} #{@resolution} (#{@types}) (#{@ttls})\n"; @packets[0].each_index { |i| (@dsts).each_index { |j| pr = @packets[j][i]; stime = pr.probe.time.to_f * 1000; srcid = pr.probe.packet.ip_id; rtt = (pr.probe and pr.response) ? (pr.response.time - pr.probe.time) * 1000 : -1; str += "#{@dsts[j]} %d %.3f %d " %[rtt, stime, srcid]; if (@types[j] == "tstamp") then rem_time = (pr.response)? pr.response.packet.icmp_ttime : 0; ott = (pr.response)? stime - pr.response.packet.icmp_ttime : -1; str += "#{rem_time} %.3f " % [ott]; end } str += "\n"; } str += "losses: #{@num_losses.join(" ")}\n"; return str; end