21
21
import java .net .InetSocketAddress ;
22
22
import java .nio .ByteBuffer ;
23
23
import java .util .*;
24
+ import java .util .concurrent .ConcurrentHashMap ;
25
+ import java .util .concurrent .CountDownLatch ;
26
+ import java .util .concurrent .TimeUnit ;
24
27
import org .scion .jpan .*;
25
28
import org .scion .jpan .internal .PathRawParser ;
26
29
import org .scion .multiping .util .*;
@@ -47,6 +50,9 @@ public class PingAll {
47
50
private static final boolean SHOW_ONLY_ICMP = false ;
48
51
private static final Config config = new Config ();
49
52
53
+ private static final int localPort = 30041 ;
54
+ private static final boolean STOP_SHIM = true ;
55
+
50
56
static {
51
57
config .tryICMP = false ;
52
58
if (SHOW_ONLY_ICMP ) {
@@ -71,20 +77,22 @@ public class PingAll {
71
77
private enum Policy {
72
78
/** Fastest path using SCMP traceroute */
73
79
FASTEST_TR ,
80
+ /** Fastest path using SCMP async traceroute */
81
+ FASTEST_ECHO ,
82
+ FASTEST_TR_ASYNC ,
74
83
/** Shortest path using SCMP traceroute */
75
84
SHORTEST_TR ,
76
85
/** Fastest path using SCMP echo */
77
- FASTEST_ECHO ,
78
- /** Fastest path using SCMP echo */
79
86
SHORTEST_ECHO
80
87
}
81
88
82
- private static final Policy POLICY = Policy .SHORTEST_TR ; // Policy.FASTEST_TR; // SHORTEST_TR ;
89
+ private static final Policy POLICY = Policy .FASTEST_TR_ASYNC ;
83
90
private static final boolean SHOW_PATH = !true ;
84
91
85
92
public static void main (String [] args ) throws IOException {
86
93
PRINT = true ;
87
94
// System.setProperty(Constants.PROPERTY_DNS_SEARCH_DOMAINS, "ethz.ch.");
95
+ System .setProperty (Constants .PROPERTY_SHIM , STOP_SHIM ? "false" : "true" ); // disable SHIM
88
96
89
97
println ("Settings:" );
90
98
println (" Path policy = " + POLICY );
@@ -142,7 +150,7 @@ private void runDemo(ParseAssignments.HostEntry remote) throws IOException {
142
150
ScionService service = Scion .defaultService ();
143
151
// Dummy address. The traceroute will contact the control service IP instead.
144
152
InetSocketAddress destinationAddress =
145
- new InetSocketAddress (InetAddress .getByAddress (new byte [] {1 , 2 , 3 , 4 }), 12345 );
153
+ new InetSocketAddress (InetAddress .getByAddress (new byte [] {0 , 0 , 0 , 0 }), 30041 );
146
154
int nPaths ;
147
155
Scmp .TimedMessage [] msg = new Scmp .TimedMessage [REPEAT ];
148
156
Ref <Path > bestPath = Ref .empty ();
@@ -161,7 +169,7 @@ private void runDemo(ParseAssignments.HostEntry remote) throws IOException {
161
169
nPaths = paths .size ();
162
170
msg [0 ] = findPaths (paths , bestPath );
163
171
if (msg [0 ] != null && REPEAT > 1 ) {
164
- try (ScmpSender sender = Scmp .newSenderBuilder ().build ()) {
172
+ try (ScmpSender sender = Scmp .newSenderBuilder ().setLocalPort ( localPort ). build ()) {
165
173
for (int i = 1 ; i < msg .length ; i ++) {
166
174
List <Scmp .TracerouteMessage > messages = sender .sendTracerouteRequest (bestPath .get ());
167
175
msg [i ] = messages .get (messages .size () - 1 );
@@ -221,6 +229,8 @@ private Scmp.TimedMessage findPaths(List<Path> paths, Ref<Path> bestOut) {
221
229
switch (POLICY ) {
222
230
case FASTEST_TR :
223
231
return findFastestTR (paths , bestOut );
232
+ case FASTEST_TR_ASYNC :
233
+ return findFastestTRasync (paths , bestOut );
224
234
case SHORTEST_TR :
225
235
return findShortestTR (paths , bestOut );
226
236
case SHORTEST_ECHO :
@@ -234,7 +244,7 @@ private Scmp.EchoMessage findShortestEcho(List<Path> paths, Ref<Path> refBest) {
234
244
Path path = PathPolicy .MIN_HOPS .filter (paths ).get (0 );
235
245
refBest .set (path );
236
246
ByteBuffer bb = ByteBuffer .allocate (0 );
237
- try (ScmpSender sender = Scmp .newSenderBuilder ().build ()) {
247
+ try (ScmpSender sender = Scmp .newSenderBuilder ().setLocalPort ( localPort ). build ()) {
238
248
nPathTried ++;
239
249
Scmp .EchoMessage msg = sender .sendEchoRequest (path , bb );
240
250
if (msg == null ) {
@@ -261,7 +271,7 @@ private Scmp.EchoMessage findShortestEcho(List<Path> paths, Ref<Path> refBest) {
261
271
private Scmp .TracerouteMessage findShortestTR (List <Path > paths , Ref <Path > refBest ) {
262
272
Path path = PathPolicy .MIN_HOPS .filter (paths ).get (0 );
263
273
refBest .set (path );
264
- try (ScmpSender sender = Scmp .newSenderBuilder ().build ()) {
274
+ try (ScmpSender sender = Scmp .newSenderBuilder ().setLocalPort ( localPort ). build ()) {
265
275
nPathTried ++;
266
276
List <Scmp .TracerouteMessage > messages = sender .sendTracerouteRequest (path );
267
277
if (messages .isEmpty ()) {
@@ -292,7 +302,7 @@ private Scmp.TracerouteMessage findShortestTR(List<Path> paths, Ref<Path> refBes
292
302
293
303
private Scmp .TracerouteMessage findFastestTR (List <Path > paths , Ref <Path > refBest ) {
294
304
Scmp .TracerouteMessage best = null ;
295
- try (ScmpSender sender = Scmp .newSenderBuilder ().build ()) {
305
+ try (ScmpSender sender = Scmp .newSenderBuilder ().setLocalPort ( localPort ). build ()) {
296
306
for (Path path : paths ) {
297
307
nPathTried ++;
298
308
List <Scmp .TracerouteMessage > messages = sender .sendTracerouteRequest (path );
@@ -327,4 +337,84 @@ private Scmp.TracerouteMessage findFastestTR(List<Path> paths, Ref<Path> refBest
327
337
return null ;
328
338
}
329
339
}
340
+
341
+ private Scmp .TracerouteMessage findFastestTRasync (List <Path > paths , Ref <Path > refBest ) {
342
+ ConcurrentHashMap <Integer , Scmp .TimedMessage > messages = new ConcurrentHashMap <>();
343
+ CountDownLatch barrier = new CountDownLatch (paths .size ());
344
+ ScmpSenderAsync .ResponseHandler handler =
345
+ new ScmpSenderAsync .ResponseHandler () {
346
+ @ Override
347
+ public void onResponse (Scmp .TimedMessage msg ) {
348
+ barrier .countDown ();
349
+ messages .put (msg .getIdentifier (), msg );
350
+ }
351
+
352
+ @ Override
353
+ public void onTimeout (Scmp .TimedMessage msg ) {
354
+ barrier .countDown ();
355
+ messages .put (msg .getIdentifier (), msg );
356
+ }
357
+
358
+ @ Override
359
+ public void onError (Scmp .ErrorMessage msg ) {
360
+ barrier .countDown ();
361
+ }
362
+
363
+ @ Override
364
+ public void onException (Throwable t ) {
365
+ barrier .countDown ();
366
+ }
367
+ };
368
+
369
+ Scmp .TracerouteMessage best = null ;
370
+ try (ScmpSenderAsync sender =
371
+ Scmp .newSenderAsyncBuilder (handler ).setLocalPort (localPort ).build ()) {
372
+ for (Path path : paths ) {
373
+ nPathTried ++;
374
+ int id = sender .sendTracerouteLast (path );
375
+ if (id == -1 ) {
376
+ println (" -> local AS, no timing available" );
377
+ nPathSuccess ++;
378
+ nAsSuccess ++;
379
+ return null ;
380
+ }
381
+ }
382
+
383
+ // Wait for all messages to be received
384
+ try {
385
+ if (!barrier .await (1100 , TimeUnit .MILLISECONDS )) {
386
+ throw new IllegalStateException ("Missing messages: " + barrier .getCount () + "/" + paths .size ());
387
+ }
388
+ } catch (InterruptedException e ) {
389
+ Thread .currentThread ().interrupt ();
390
+ throw new IllegalStateException (e );
391
+ }
392
+
393
+ } catch (IOException e ) {
394
+ println ("ERROR: " + e .getMessage ());
395
+ nAsError ++;
396
+ return null ;
397
+ }
398
+
399
+ for (Scmp .TimedMessage tm : messages .values ()) {
400
+ Scmp .TracerouteMessage msg = (Scmp .TracerouteMessage ) tm ;
401
+ seenAs .add (msg .getIsdAs ());
402
+
403
+ if (msg .isTimedOut ()) {
404
+ nPathTimeout ++;
405
+ if (best == null ) {
406
+ best = msg ;
407
+ }
408
+ continue ;
409
+ }
410
+
411
+ nPathSuccess ++;
412
+
413
+ if (best == null || msg .getNanoSeconds () < best .getNanoSeconds ()) {
414
+ best = msg ;
415
+ refBest .set (msg .getRequest ().getPath ());
416
+ }
417
+ }
418
+ return best ;
419
+ }
330
420
}
0 commit comments