scriptroute 0.4.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/sr-ally +21 -0
- data/bin/sr-liveness +11 -0
- data/bin/sr-ping-T +69 -0
- data/bin/sr-rockettrace +51 -0
- data/bin/sr-traceroute +35 -0
- data/bin/tulip +183 -0
- data/lib/scriptroute.rb +327 -0
- data/lib/scriptroute/ally.rb +449 -0
- data/lib/scriptroute/commando.rb +228 -0
- data/lib/scriptroute/fixclock +1260 -0
- data/lib/scriptroute/liveness.rb +129 -0
- data/lib/scriptroute/nameify.rb +127 -0
- data/lib/scriptroute/packets.rb +800 -0
- data/lib/scriptroute/rockettrace.rb +181 -0
- data/lib/scriptroute/tulip/helper.rb +730 -0
- data/lib/scriptroute/tulip/loss.rb +145 -0
- data/lib/scriptroute/tulip/queuing.rb +248 -0
- data/lib/scriptroute/tulip/reordering.rb +129 -0
- data/test/test_bins.rb +20 -0
- data/test/test_scriptroute.rb +155 -0
- metadata +71 -0
@@ -0,0 +1,145 @@
|
|
1
|
+
module Scriptroute
|
2
|
+
module Tulip
|
3
|
+
|
4
|
+
class LossTrain
|
5
|
+
attr_reader :train;
|
6
|
+
|
7
|
+
def initialize(destination, intra_train, type, ttl)
|
8
|
+
@destination, @intra_train, @type, @ttl = destination, intra_train, type, ttl;
|
9
|
+
#(dsts, numpackets, intratrain, types, ttls, psizes, numtrains, intertrain)
|
10
|
+
@train = Train2.new([destination], 3, @intra_train, [type], [ttl], [-1, 1000, -1], 1, 0);
|
11
|
+
end
|
12
|
+
|
13
|
+
def isLossy?
|
14
|
+
return (@train.num_losses[0] > 0);
|
15
|
+
end
|
16
|
+
|
17
|
+
##todo: principled treatment of pcapping
|
18
|
+
def wasPcapped?
|
19
|
+
@train.packets.each_index { |j|
|
20
|
+
@train.packets[0].each_index { |k|
|
21
|
+
pr = @train.packets[j][k];
|
22
|
+
return true if (!pr or !pr.probe or !pr.probe.time);
|
23
|
+
}
|
24
|
+
}
|
25
|
+
return false;
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
str = "";
|
30
|
+
str += "losstrain #{@destination} #{@intra_train} #{@type} #{@ttl}\n";
|
31
|
+
@train.packets.each_index { |j|
|
32
|
+
@train.packets[0].each_index { |k|
|
33
|
+
pr = @train.packets[j][k];
|
34
|
+
if (pr and pr.probe and pr.probe.time) then
|
35
|
+
stime, sid = pr.probe.time.to_f * 1000, pr.probe.packet.ip_id;
|
36
|
+
rtime = (pr.response) ? pr.response.time.to_f * 1000 : -1;
|
37
|
+
rid = (pr.response) ? pr.response.packet.ip_id : -1;
|
38
|
+
src = (pr.response)? pr.response.packet.ip_src : -1;
|
39
|
+
str += "#{src} %.3f +%.3fms %d %d\n" %[stime, rtime-stime, rid, sid];
|
40
|
+
else
|
41
|
+
str += "pcap overload\n";
|
42
|
+
end
|
43
|
+
}
|
44
|
+
}
|
45
|
+
return str;
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
class LossDoctor
|
51
|
+
|
52
|
+
def analyze (hopDetails)
|
53
|
+
|
54
|
+
hopDetails.each_index { |hop|
|
55
|
+
next if (!hopDetails[hop]);
|
56
|
+
details = hopDetails[hop];
|
57
|
+
|
58
|
+
valid = @total[hop] - @undesiredLosses[hop];
|
59
|
+
# printf("%d. %s ", $global_tpath.path[hop].hop, details[4]);
|
60
|
+
printf("%s ", $global_tpath.path[hop]);
|
61
|
+
printf("(ejected) ") if (@ejected.has_key?(hop));
|
62
|
+
rt = @total[hop] - @undesiredLosses[hop] - @noLosses[hop];
|
63
|
+
printf("rt=%.3f (%d/%d) ",(valid==0)? 0 : rt.to_f/valid, rt, valid);
|
64
|
+
if (details[3]) then
|
65
|
+
printf("fw=%.3f (%d/%d) ", @forwardLosses[hop].to_f/valid, @forwardLosses[hop], valid);
|
66
|
+
consec = @noLosses[hop] - @reorderedResponses[hop];
|
67
|
+
consecR = (consec==0)? 0 : @consecutiveIPIDs[hop].to_f/consec;
|
68
|
+
printf("co=%.3f (%d/%d) ", consecR, @consecutiveIPIDs[hop], consec);
|
69
|
+
printf("ro=%.3f (%d/%d)", @reorderedResponses[hop].to_f/@noLosses[hop], @reorderedResponses[hop], @noLosses[hop]);
|
70
|
+
end
|
71
|
+
puts "";
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def initialize (hopDetails)
|
76
|
+
@total = Hash.new(0);
|
77
|
+
@noLosses = Hash.new(0);
|
78
|
+
@undesiredLosses = Hash.new(0);
|
79
|
+
@forwardLosses = Hash.new(0);
|
80
|
+
@reorderedResponses = Hash.new(0);
|
81
|
+
@consecutiveIPIDs = Hash.new(0);
|
82
|
+
@ejected = Hash.new(0);
|
83
|
+
|
84
|
+
|
85
|
+
(0..$count-1).each { |num|
|
86
|
+
startTime = Time.now;
|
87
|
+
hopDetails.each_index { |i|
|
88
|
+
|
89
|
+
next if (!hopDetails[i] or @ejected.has_key?(i));
|
90
|
+
details = hopDetails[i];
|
91
|
+
|
92
|
+
#(destination, intra_train, type, ttl)
|
93
|
+
train = LossTrain.new(details[0], $spread/1000.0, details[2], details[1]);
|
94
|
+
puts "#{train}\n" if ($verbose>=10);
|
95
|
+
|
96
|
+
@total[i] += 1;
|
97
|
+
pkts = train.train.packets[0];
|
98
|
+
|
99
|
+
next if (train.wasPcapped?);
|
100
|
+
|
101
|
+
if (!train.isLossy?) then
|
102
|
+
@noLosses[i] += 1;
|
103
|
+
if (details[3]) then
|
104
|
+
ids = pkts.map { |p| p.response.packet.ip_id };
|
105
|
+
if (ids[1] < ids[0] or ids[2] < ids[1]) then
|
106
|
+
@reorderedResponses[i] += 1 if (ids[1] != 0); #don't count routers that return 0 for big probes
|
107
|
+
end
|
108
|
+
if (ids[0] + 1 == ids[1] and ids[1] + 1 == ids[2]) then
|
109
|
+
@consecutiveIPIDs[i] += 1;
|
110
|
+
end
|
111
|
+
end
|
112
|
+
else
|
113
|
+
if (!pkts[0].response or !pkts[2].response) then
|
114
|
+
@undesiredLosses[i] += 1;
|
115
|
+
else
|
116
|
+
id0 = pkts[0].response.packet.ip_id;
|
117
|
+
id2 = pkts[2].response.packet.ip_id;
|
118
|
+
if (id0 == id2 - 1) then
|
119
|
+
@forwardLosses[i] += 1;
|
120
|
+
end
|
121
|
+
end
|
122
|
+
if (@noLosses[i] <= 0.25*@total[i] and @total[i] >= 10) then
|
123
|
+
@ejected[i] = 1;
|
124
|
+
end
|
125
|
+
end
|
126
|
+
}
|
127
|
+
|
128
|
+
if ($printFrequency > 0 and (num+1) % $printFrequency == 0 and num != $count-1 ) then
|
129
|
+
puts " ---- after #{num+1} measurements ----";
|
130
|
+
analyze(hopDetails);
|
131
|
+
end
|
132
|
+
|
133
|
+
sleepTime = startTime + $lag/1000.0 - Time.now;
|
134
|
+
if (sleepTime > 0) then Kernel.sleep(sleepTime); end
|
135
|
+
}
|
136
|
+
|
137
|
+
puts " ---- after #{$count} measurements ----";
|
138
|
+
analyze(hopDetails);
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,248 @@
|
|
1
|
+
module Scriptroute
|
2
|
+
module Tulip
|
3
|
+
|
4
|
+
|
5
|
+
class QueueTrain
|
6
|
+
attr_reader :train;
|
7
|
+
|
8
|
+
def initialize(dst, type, ttl)
|
9
|
+
#(dsts, numpackets, resolution, types, ttls, shuffle=false)
|
10
|
+
#@train = Train.new([dst], 2, 0, [type], [ttl]);
|
11
|
+
@train = Train.new([dst], 1, 0, [type], [ttl]);
|
12
|
+
end
|
13
|
+
|
14
|
+
def isLossy?
|
15
|
+
##losing one of the two timestamps all the time is ok.
|
16
|
+
return (@train.num_losses[0] > 1);
|
17
|
+
end
|
18
|
+
|
19
|
+
# def to_s
|
20
|
+
# return @train.to_s;
|
21
|
+
# end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
str = "queuetrain: #{@train.dsts} (#{@train.types})\n";
|
25
|
+
@train.packets[0].each_index { |i|
|
26
|
+
(@train.dsts).each_index { |j|
|
27
|
+
pr = @train.packets[j][i];
|
28
|
+
stime = pr.probe.time.to_f * 1000;
|
29
|
+
rtt = (pr.probe and pr.response) ? (pr.response.time - pr.probe.time) * 1000 : -1;
|
30
|
+
str += "#{@train.dsts[j]} %.3fms %.3f " %[rtt, stime];
|
31
|
+
if (@train.types[j] == "tstamp") then
|
32
|
+
rem_time = (pr.response)? pr.response.packet.icmp_ttime : 0;
|
33
|
+
str += "#{rem_time}";
|
34
|
+
end
|
35
|
+
}
|
36
|
+
str += "\n";
|
37
|
+
}
|
38
|
+
return str;
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def convertByteOrder(wrong)
|
44
|
+
right = Array.new();
|
45
|
+
right[0], right[1], right[2], right[3] = wrong & 255,
|
46
|
+
(wrong & (255 << 8)) >> 8,
|
47
|
+
(wrong & (255 << 16)) >> 16,
|
48
|
+
(wrong & (255 << 24)) >> 24;
|
49
|
+
out = ( (right[0] << 24) + (right[1] << 16) + (right[2] << 8) + right[3]);
|
50
|
+
#puts "#{wrong} #{out} #{right.join(" ")}\n";
|
51
|
+
return out;
|
52
|
+
end
|
53
|
+
|
54
|
+
def fixByteOrder (stamps)
|
55
|
+
if (stamps.length > 4 and
|
56
|
+
(stamps[0][1] > stamps[1][1] or
|
57
|
+
stamps[1][1] > stamps[2][1] or
|
58
|
+
stamps[2][1] > stamps[3][1] or
|
59
|
+
stamps[3][1] > stamps[4][1]
|
60
|
+
)
|
61
|
+
) then
|
62
|
+
triplets = Array.new();
|
63
|
+
stamps.each_index { |i|
|
64
|
+
triplets[i] = Array.new();
|
65
|
+
triplets[i][0] = stamps[i][0];
|
66
|
+
triplets[i][1] = convertByteOrder(stamps[i][1]);
|
67
|
+
triplets[i][2] = stamps[i][2]; ## a better way to do this would be to insert in converted byte order
|
68
|
+
}
|
69
|
+
return triplets;
|
70
|
+
end
|
71
|
+
return stamps;
|
72
|
+
end
|
73
|
+
|
74
|
+
def computeRTMed (stamps)
|
75
|
+
rtts = Array.new();
|
76
|
+
stamps.each { |stamp|
|
77
|
+
rtts.push(stamp[2] - stamp[0]);
|
78
|
+
}
|
79
|
+
rtts.sort!;
|
80
|
+
if (rtts.length > 0)
|
81
|
+
medianDiff = rtts[rtts.length/2] - rtts[0];
|
82
|
+
return [medianDiff, rtts.first, rtts.last];
|
83
|
+
else
|
84
|
+
return -100;
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def computeFWMedCing (triplets)
|
89
|
+
# triplets = Array.new();
|
90
|
+
oldsend, oldrcv = 0,0;
|
91
|
+
# stamps.each { |stamp|
|
92
|
+
# triplets.push(stamp);
|
93
|
+
# }
|
94
|
+
|
95
|
+
ENV['datalinepattern'] ="newexp";
|
96
|
+
ENV['fieldseparator'] = ":";
|
97
|
+
ENV['hostfieldnum'] = "3";
|
98
|
+
ENV['sentfieldnum'] = "6";
|
99
|
+
ENV['receivedfieldnum'] = "7";
|
100
|
+
ENV['bouncedfieldnum'] = "9";
|
101
|
+
ENV['segmentsecs'] = "12";
|
102
|
+
ENV['writefixeddir'] = "./";
|
103
|
+
ENV['sourceskew'] = "-";
|
104
|
+
ENV['target'] = "1.1.1.1";
|
105
|
+
ENV['showquality'] = "1";
|
106
|
+
|
107
|
+
pid = Process.pid;
|
108
|
+
tmp = File.new("/tmp/fixLC.#{pid}", "w");
|
109
|
+
|
110
|
+
if (triplets.length == 0) then
|
111
|
+
return -100;
|
112
|
+
end
|
113
|
+
|
114
|
+
base = triplets[0][0];
|
115
|
+
triplets.each_index { |j|
|
116
|
+
tup = triplets[j];
|
117
|
+
tmp.puts "0.000:newexp:1.1.1.1:%u:0:%u:%u:0:%u" %[j, tup[0] - base, tup[1], tup[2] - base];
|
118
|
+
}
|
119
|
+
tmp.close();
|
120
|
+
cmd = sprintf("#{FIXCLOCK} /tmp/fixLC.#{pid}");
|
121
|
+
output = `#{cmd}`.split("\n");
|
122
|
+
match = nil;
|
123
|
+
quality = [nil, nil];
|
124
|
+
output.each { |o|
|
125
|
+
if ( o =~ "inferred stdroundtrip" ) then
|
126
|
+
words = o.split;
|
127
|
+
quality = [words[4], words[6]];
|
128
|
+
end
|
129
|
+
}
|
130
|
+
|
131
|
+
otts = Array.new();
|
132
|
+
rejected = 0;
|
133
|
+
tmp = File.new("./fixLC.#{pid}.fix");
|
134
|
+
tmp.each { |line|
|
135
|
+
words = line.split(":");
|
136
|
+
snd,rem,zero,rcv = words[5..8].map { |i| i.to_i; }
|
137
|
+
# if (snd <= rem and rem <= rcv) then
|
138
|
+
otts.push(rem - snd);
|
139
|
+
# else
|
140
|
+
# rejected += 1;
|
141
|
+
# end
|
142
|
+
}
|
143
|
+
tmp.close();
|
144
|
+
File.delete("/tmp/fixLC.#{pid}", "./fixLC.#{pid}.fix", "./fixLC.#{pid}.rej");
|
145
|
+
|
146
|
+
#puts "conglib-warning: rejected #{rejected} cing corrections\n" if (rejected > 0);
|
147
|
+
|
148
|
+
otts.sort!;
|
149
|
+
#STDERR.puts "WARNING: too few ott samples: #{otts.length}" if (otts.length < 5);
|
150
|
+
|
151
|
+
medianDiff = (otts.length > 0)? (otts[otts.length/2] - otts[0]) : -100;
|
152
|
+
#puts "otts (#{otts.length}, #{medianDiff}): #{otts.join(" ")}";
|
153
|
+
return [[medianDiff, otts.last], quality];
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
class QueuingDoctor
|
158
|
+
|
159
|
+
def validOTT (ott, rtt)
|
160
|
+
return false if (ott < 0);
|
161
|
+
#return false if (ott > 3 and rtt < 1);
|
162
|
+
#return false if (ott > rtt/2);
|
163
|
+
return true;
|
164
|
+
end
|
165
|
+
|
166
|
+
def analyze (hopDetails)
|
167
|
+
|
168
|
+
hopDetails.each_index { |hop|
|
169
|
+
next if (!hopDetails[hop]);
|
170
|
+
details = hopDetails[hop];
|
171
|
+
|
172
|
+
valid = @total[hop] - @ratelimited[hop];
|
173
|
+
# printf("%d. %s ", $global_tpath.path[hop].hop, details[4]);
|
174
|
+
printf("%s ", $global_tpath.path[hop]);
|
175
|
+
printf("(ejected) ") if (@ejected.has_key?(hop));
|
176
|
+
round = computeRTMed(@stamps[hop]);
|
177
|
+
printf("rt: median=%.3f min=%.3f max=%.3f ", round[0]+round[1], round[1], round[2]);
|
178
|
+
if (details[3]) then
|
179
|
+
triplets = fixByteOrder(@stamps[hop]);
|
180
|
+
cing = computeFWMedCing(triplets);
|
181
|
+
q = (cing[1][1].to_f==0)? 1 : cing[1][0].to_f/cing[1][1].to_f;
|
182
|
+
if (validOTT(cing[0][0], round[0])) then
|
183
|
+
printf("fw: median=%.3f max=%s quality=%.3f (%s/%s)", cing[0][0], cing[0][1], q, cing[1][0], cing[1][1]);
|
184
|
+
else
|
185
|
+
printf("fw: median=-1 max=-1 quality=-1");
|
186
|
+
end
|
187
|
+
end
|
188
|
+
puts "";
|
189
|
+
}
|
190
|
+
end
|
191
|
+
|
192
|
+
def initialize (hopDetails)
|
193
|
+
|
194
|
+
@total = Hash.new(0);
|
195
|
+
@ratelimited = Hash.new(0)
|
196
|
+
@stamps = Hash.new();
|
197
|
+
hopDetails.each_index { |i| @stamps[i] = Array.new() if (hopDetails[i]);}
|
198
|
+
@ejected = Hash.new();
|
199
|
+
|
200
|
+
##todo: implement the correlation thingy
|
201
|
+
@pairs = Hash.new();
|
202
|
+
|
203
|
+
(0..$count-1).each { |num|
|
204
|
+
startTime = Time.now;
|
205
|
+
hopDetails.each_index { |i|
|
206
|
+
|
207
|
+
next if (!hopDetails[i] or @ejected.has_key?(i));
|
208
|
+
details = hopDetails[i];
|
209
|
+
|
210
|
+
#(dst, types, ttl)
|
211
|
+
|
212
|
+
#puts "before train = %.3f" % [Time.now.to_f*1000];
|
213
|
+
train = QueueTrain.new(details[0], details[2], details[1]);
|
214
|
+
#puts "after train = %.3f" % [Time.now.to_f*1000];
|
215
|
+
|
216
|
+
puts "#{train}\n" if ($verbose>=10);
|
217
|
+
|
218
|
+
@total[i] += 1;
|
219
|
+
if (train.isLossy?) then
|
220
|
+
@ratelimited[i] += 1;
|
221
|
+
@ejected[i] = 1 if (@ratelimited[i] >= 0.5*@total[i] and @total[i] >= 10);
|
222
|
+
else
|
223
|
+
p = train.train.packets[0][0];
|
224
|
+
if (p and p.probe and p.response and p.probe.time and p.response.time) then
|
225
|
+
@stamps[i].push([p.probe.time.to_f * 1000.0, p.response.packet.icmp_ttime, p.response.time.to_f*1000.0]);
|
226
|
+
else
|
227
|
+
@total[i] -= 1;
|
228
|
+
end
|
229
|
+
end
|
230
|
+
}
|
231
|
+
|
232
|
+
if ($printFrequency > 0 and (num+1) % $printFrequency == 0 and num != $count-1) then
|
233
|
+
puts " ---- after #{num+1} measurements ----";
|
234
|
+
analyze(hopDetails);
|
235
|
+
end
|
236
|
+
|
237
|
+
sleepTime = startTime + $lag/1000.0 - Time.now;
|
238
|
+
#puts "sleep = #{sleepTime} %.3f" % [Time.now.to_f*1000];
|
239
|
+
if (sleepTime > 0 and num != $count-1) then Kernel.sleep(sleepTime); end
|
240
|
+
}
|
241
|
+
|
242
|
+
puts " ---- after #{$count} measurements ----";
|
243
|
+
analyze(hopDetails);
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|
248
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module Scriptroute
|
2
|
+
module Tulip
|
3
|
+
|
4
|
+
|
5
|
+
class ReordTrain
|
6
|
+
attr_reader :destination,:intra_train, :type, :ttl, :train;
|
7
|
+
|
8
|
+
def initialize(destination, intra_train, type, ttl)
|
9
|
+
@destination, @intra_train, @type, @ttl =
|
10
|
+
destination, intra_train, type, ttl;
|
11
|
+
|
12
|
+
#(dsts, numpackets, resolution, types, ttls, shuffle=false)
|
13
|
+
@train = Train.new([@destination], 2, @intra_train, [@type], [@ttl]);
|
14
|
+
end
|
15
|
+
|
16
|
+
def isLossy?
|
17
|
+
return (@train.num_losses[0] > 0);
|
18
|
+
end
|
19
|
+
|
20
|
+
def isRTro?
|
21
|
+
return false if (isLossy?);
|
22
|
+
rt1, rt2 = [0,1].map { |v| @train.packets[0][v].response.time; }
|
23
|
+
(rt1 > rt2)? true : false;
|
24
|
+
end
|
25
|
+
|
26
|
+
def isFWro?
|
27
|
+
return false if (isLossy?);
|
28
|
+
id1, id2 = [0,1].map { |v| @train.packets[0][v].response.packet.ip_id; }
|
29
|
+
(id1 > id2)? true : false;
|
30
|
+
end
|
31
|
+
|
32
|
+
def wasPcapped?
|
33
|
+
@train.packets[0].each_index { |k|
|
34
|
+
pr = @train.packets[0][k];
|
35
|
+
return true if (!pr or !pr.probe or !pr.probe.time)
|
36
|
+
}
|
37
|
+
return false;
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
str = "";
|
42
|
+
str += "reordtrain %s %s %s %s\n" % [@destination, @ttl, @type, @intra_train];
|
43
|
+
@train.packets[0].each_index { |k|
|
44
|
+
pr = @train.packets[0][k];
|
45
|
+
stime, sid = pr.probe.time.to_f * 1000, pr.probe.packet.ip_id;
|
46
|
+
rtime = (pr.response) ? pr.response.time.to_f * 1000 : -1;
|
47
|
+
sid = pr.probe.packet.ip_id;
|
48
|
+
rid = (pr.response) ? pr.response.packet.ip_id : -1;
|
49
|
+
src = (pr.response)? pr.response.packet.ip_src : -1;
|
50
|
+
str += "#{src} %.3f +%.3fms %d %d" %[stime, rtime-stime, rid, sid];
|
51
|
+
str += "\n";
|
52
|
+
}
|
53
|
+
return str;
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
class ReorderingDoctor
|
59
|
+
|
60
|
+
def analyze (hopDetails)
|
61
|
+
|
62
|
+
hopDetails.each_index { |hop|
|
63
|
+
next if (!hopDetails[hop]);
|
64
|
+
details = hopDetails[hop];
|
65
|
+
|
66
|
+
valid = 1.0*@total[hop] - @ratelimited[hop];
|
67
|
+
# printf("%d. %s ", $global_tpath.path[hop].hop, details[4]);
|
68
|
+
printf("%s ", $global_tpath.path[hop]);
|
69
|
+
# printf("%d. %s %s ", $global_tpath.path[hop].hop, IPSocket.getname($global_tpath.path[hop].hop), details[4]);
|
70
|
+
printf("(ejected) ") if (@ejected.has_key?(hop));
|
71
|
+
printf("rt=%.3f (%d/%d) ", @rtreord[hop].to_f/valid, @rtreord[hop], valid);
|
72
|
+
if (details[3]) then
|
73
|
+
printf("fw=%.3f (%d/%d)\n", @fwreord[hop].to_f/valid, @fwreord[hop], valid)
|
74
|
+
else
|
75
|
+
printf("\n")
|
76
|
+
end
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def initialize (hopDetails)
|
81
|
+
|
82
|
+
@total = Hash.new(0);
|
83
|
+
@fwreord = Hash.new(0);
|
84
|
+
@rtreord = Hash.new(0);
|
85
|
+
@ratelimited = Hash.new(0)
|
86
|
+
@ejected = Hash.new(0);
|
87
|
+
|
88
|
+
(0..$count-1).each { |num|
|
89
|
+
startTime = Time.now;
|
90
|
+
hopDetails.each_index { |i|
|
91
|
+
|
92
|
+
next if (!hopDetails[i] or @ejected.has_key?(i));
|
93
|
+
details = hopDetails[i];
|
94
|
+
|
95
|
+
#(destination, intra_train, type, ttl)
|
96
|
+
train = ReordTrain.new(details[0], $spread/1000.0, details[2], details[1]);
|
97
|
+
puts "#{train}\n" if ($verbose>=10);
|
98
|
+
|
99
|
+
next if (train.wasPcapped?);
|
100
|
+
|
101
|
+
@total[i] += 1;
|
102
|
+
if (train.isLossy?) then
|
103
|
+
@ratelimited[i] += 1;
|
104
|
+
if ($skipRTrtrs and @ratelimited[i] >= 0.5*@total[i] and @total[i] >= 10) then
|
105
|
+
@ejected[i] = 1;
|
106
|
+
end
|
107
|
+
else
|
108
|
+
@fwreord[i] += (train.isFWro?)? 1 : 0
|
109
|
+
@rtreord[i] += (train.isRTro?)? 1 : 0
|
110
|
+
end
|
111
|
+
}
|
112
|
+
|
113
|
+
if ($printFrequency > 0 and (num+1) % $printFrequency == 0 and num != $count-1) then
|
114
|
+
puts " ---- after #{num+1} measurements ----";
|
115
|
+
analyze(hopDetails);
|
116
|
+
end
|
117
|
+
|
118
|
+
sleepTime = startTime + $lag/1000.0 - Time.now;
|
119
|
+
if (sleepTime > 0) then Kernel.sleep(sleepTime); end
|
120
|
+
}
|
121
|
+
|
122
|
+
puts " ---- after #{$count} measurements ----";
|
123
|
+
analyze(hopDetails);
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|