@@ -284,6 +284,17 @@ private static void combineTwoSegments(
284284 buildPath (paths , localAS , dstIsdAs , pathSegment0 , pathSegment1 );
285285 }
286286 }
287+
288+ // TODO
289+ // TODO
290+ // TODO
291+ // TODO
292+ // TODO
293+ // TODO
294+ // TODO
295+ // for (Peering peering: detectPeerings(segments0, segments1)) {
296+ // buildPeeringPath(paths, peering, srcIsdAs, dstIsdAs, localAS);
297+ // }
287298 }
288299
289300 private static void combineThreeSegments (
@@ -404,6 +415,76 @@ private static void buildPath(
404415 checkDuplicatePaths (paths , path );
405416 }
406417
418+ private static void buildPeeringPath (MultiMap <Integer , Daemon .Path > paths , Peering peering , long srcIsdAs ,
419+ long dstIsdAs ,
420+ LocalTopology localAS ) {
421+ PathSegment [] segments = new PathSegment []{peering .segmentUp , peering .segmentDown };
422+
423+ Daemon .Path .Builder path = Daemon .Path .newBuilder ();
424+ ByteBuffer raw = ByteBuffer .allocate (1000 );
425+
426+ int [][] ranges = new int [segments .length ][]; // [start (inclusive), end (exclusive), increment]
427+ long startIA = localAS .getIsdAs ();
428+ final ByteUtil .MutLong endingIA = new ByteUtil .MutLong (-1 );
429+ for (int i = 0 ; i < segments .length ; i ++) {
430+ ranges [i ] = createRange (segments [i ], startIA , endingIA );
431+ startIA = endingIA .get ();
432+ }
433+
434+ // // Search for on-path and shortcuts.
435+ // if (detectOnPathUp(segments, dstIsdAs, ranges)) {
436+ // segments = new PathSegment[] {segments[0]};
437+ // ranges = new int[][] {ranges[0]};
438+ // LOG.debug("Found on-path AS on UP segment.");
439+ // } else if (detectOnPathDown(segments, localAS.getIsdAs(), ranges)) {
440+ // segments = new PathSegment[] {segments[segments.length - 1]};
441+ // ranges = new int[][] {ranges[ranges.length - 1]};
442+ // LOG.debug("Found on-path AS on DOWN segment.");
443+ // } else if (detectShortcut(segments, ranges)) {
444+ // // The following is a no-op if there is no CORE segment
445+ // segments = new PathSegment[] {segments[0], segments[segments.length - 1]};
446+ // ranges = new int[][] {ranges[0], ranges[ranges.length - 1]};
447+ // LOG.debug("Found shortcut at hop {}:", ranges[0][1]);
448+ // }
449+
450+ // path meta header
451+ int pathMetaHeader = 0 ;
452+ for (int i = 0 ; i < segments .length ; i ++) {
453+ int hopCount = Math .abs (ranges [i ][1 ] - ranges [i ][0 ]);
454+ pathMetaHeader |= hopCount << (6 * (2 - i ));
455+ }
456+ raw .putInt (pathMetaHeader );
457+
458+ // info fields
459+ for (int i = 0 ; i < segments .length ; i ++) {
460+ writeInfoField (raw , segments [i ].info , ranges [i ][2 ]);
461+ calcBetaCorrection (raw , 6 + i * 8 , segments [i ], ranges [i ]);
462+ }
463+
464+ // hop fields
465+ path .setMtu (localAS .getMtu ());
466+ for (int i = 0 ; i < segments .length ; i ++) {
467+ // bytePosSegID: 6 = 4 bytes path head + 2 byte flag in first info field
468+ writeHopFields (path , raw , 6 + i * 8 , segments [i ], ranges [i ]);
469+ }
470+
471+ raw .flip ();
472+ path .setRaw (ByteString .copyFrom (raw ));
473+
474+ // TODO where do we get these?
475+ // segUp.getSegmentInfo();
476+ // path.setLatency();
477+ // path.setInternalHops();
478+ // path.setNotes();
479+ // First hop
480+ String firstHop = localAS .getBorderRouterAddress ((int ) path .getInterfaces (0 ).getId ());
481+ Daemon .Underlay underlay = Daemon .Underlay .newBuilder ().setAddress (firstHop ).build ();
482+ Daemon .Interface interfaceAddr = Daemon .Interface .newBuilder ().setAddress (underlay ).build ();
483+ path .setInterface (interfaceAddr );
484+
485+ checkDuplicatePaths (paths , path );
486+ }
487+
407488 private static void calcBetaCorrection (
408489 ByteBuffer raw , int bytePosSegID , PathSegment segment , int [] range ) {
409490 // When we create a shortcut or on-path, we need to remove the MACs from the segID / beta.
@@ -609,6 +690,22 @@ private static boolean detectOnPathDown(PathSegment[] segments, long srcIA, int[
609690 return false ;
610691 }
611692
693+ private static List <Peering > detectPeerings (List <PathSegment > segments0 , List <PathSegment > segments1 ) {
694+ List <Peering > peerings = new ArrayList <>();
695+ for (PathSegment seg0 : segments0 ) {
696+ Map <Long , PeeringLink > peers0 = seg0 .peers ;
697+ for (PathSegment seg1 : segments1 ) {
698+ for (PeeringLink pe1 : seg1 .peers .values ()) {
699+ PeeringLink pe0 = peers0 .get (pe1 .body .getIsdAs ());
700+ if (pe0 != null ) {
701+ peerings .add (new Peering (seg0 , seg1 , pe0 , pe1 ));
702+ }
703+ }
704+ }
705+ }
706+ return peerings ;
707+ }
708+
612709 private static MultiMap <Long , PathSegment > createSegmentsMap (
613710 List <PathSegment > pathSegments , long knownIsdAs ) {
614711 MultiMap <Long , PathSegment > map = new MultiMap <>();
@@ -718,6 +815,7 @@ private static class PathSegment {
718815 final List <Seg .ASEntrySignedBody > bodies ;
719816 final Seg .SegmentInformation info ;
720817 final SegmentType type ; //
818+ final Map <Long , PeeringLink > peers = new HashMap <>();
721819
722820 PathSegment (Seg .PathSegment segment , SegmentType type ) {
723821 this .segment = segment ;
@@ -728,6 +826,12 @@ private static class PathSegment {
728826 .collect (Collectors .toList ()));
729827 this .info = getInfo (segment );
730828 this .type = type ;
829+ for (int i = 0 ; i < bodies .size (); i ++) {
830+ Seg .ASEntrySignedBody body = bodies .get (i );
831+ for (Seg .PeerEntry pe : body .getPeerEntriesList ()) {
832+ peers .put (pe .getPeerIsdAs (), new PeeringLink (body , pe , i ));
833+ }
834+ }
731835 }
732836
733837 public Seg .ASEntrySignedBody getAsEntriesFirst () {
@@ -758,4 +862,30 @@ public boolean isCore() {
758862 return type == SegmentType .CORE ;
759863 }
760864 }
865+
866+ private static class Peering {
867+ final PathSegment segmentUp ;
868+ final PathSegment segmentDown ;
869+ final PeeringLink linkUp ;
870+ final PeeringLink linkDown ;
871+
872+ private Peering (PathSegment segmentUp , PathSegment segmentDown , PeeringLink linkUp , PeeringLink linkDown ) {
873+ this .segmentUp = segmentUp ;
874+ this .segmentDown = segmentDown ;
875+ this .linkUp = linkUp ;
876+ this .linkDown = linkDown ;
877+ }
878+ }
879+
880+ private static class PeeringLink {
881+ final Seg .ASEntrySignedBody body ;
882+ final Seg .PeerEntry peerEntry ;
883+ final int pos ; // position in segment
884+
885+ private PeeringLink (Seg .ASEntrySignedBody body , Seg .PeerEntry peerEntry , int pos ) {
886+ this .body = body ;
887+ this .peerEntry = peerEntry ;
888+ this .pos = pos ;
889+ }
890+ }
761891}
0 commit comments