public static void traverseDoD(NetworkGraph g) { //starting at 721 print out providers to DoD people. AsNode DoDMain = g.GetNode(721); List<UInt32> DoDProviders = new List<UInt32>(); List<UInt32> DoDPeers = new List<UInt32>(); List<UInt32> DoDASNs = new List<UInt32>(); Queue<UInt32> ASesToProcess = new Queue<UInt32>(); DoDASNs.Add(721); ASesToProcess.Enqueue(721); while (ASesToProcess.Count > 0) { AsNode curr = g.GetNode(ASesToProcess.Dequeue()); Console.WriteLine("Processing: " + curr.NodeNum); foreach (var provider in curr.GetNeighborsByType(RelationshipType.CustomerOf)) { if (!DoDASNs.Contains(provider.NodeNum) && !DoDProviders.Contains(provider.NodeNum)) { DoDProviders.Add(provider.NodeNum); Console.WriteLine(curr.NodeNum + " has non-DoD provider: " + provider.NodeNum); Console.ReadLine(); } } foreach (var customer in curr.GetNeighborsByType(RelationshipType.ProviderTo)) { if (!DoDASNs.Contains(customer.NodeNum) && !ASesToProcess.Contains(customer.NodeNum)) { ASesToProcess.Enqueue(customer.NodeNum); DoDASNs.Add(customer.NodeNum); } } foreach (var peer in curr.GetNeighborsByType(RelationshipType.PeerOf)) { if (!DoDASNs.Contains(peer.NodeNum)) DoDPeers.Add(peer.NodeNum); } } Console.WriteLine("DoDProviders: "); foreach (var provider in DoDProviders) { if(!DoDASNs.Contains(provider)) Console.Write(provider + ", "); } Console.WriteLine(); Console.WriteLine("DoDPeers: "); foreach (var peer in DoDPeers) Console.Write(peer + ", "); Console.WriteLine(); }
private static void printDiamond(UInt32 pointASN, UInt32 stub, List <UInt32> competitors, SecureSimulator.NetworkGraph g, StreamWriter output) { SecureSimulator.AsNode pointASNode = g.GetNode(pointASN); SecureSimulator.AsNode stubASNode = g.GetNode(stub); foreach (UInt32 c in competitors) { SecureSimulator.AsNode cASNode = g.GetNode(c); output.WriteLine("{0} {1} {2} {3} {4}", pointASN, relationshipToString(cASNode.GetRelationshipTypeOfNeighbor(pointASNode)), c, relationshipToString(stubASNode.GetRelationshipTypeOfNeighbor(cASNode)), stub); } }
/// <summary> /// ADDED BY SHARON /// Checks if a particular other node (usually the attacker) is on the path /// from the source node to the BFS root. Returns true if it is, false otherwise /// If there is no path to the BFS root, this function returns false /// </summary> public static bool isNodeOnPathFromBfsRoot(NetworkGraph graph, UInt32 srcNodeNum, UInt32 attackerNodeNum) { AsNode currNode = graph.GetNode(srcNodeNum); AsNode attackerNode = graph.GetNode(attackerNodeNum); // Check the input if ((currNode == null) || (attackerNode == null) || (currNode.BfsDepth == Int32.MaxValue)) { return(false); } //walk down path to root, checking for attacker while (currNode != null) { if (currNode.NodeNum == attackerNode.NodeNum) { return(true); } currNode = currNode.BfsParentNode; } return(false); }
/// <summary> /// debugging function to give us a string representation of the path for /// a node n. /// </summary> /// <param name="n"></param> /// <returns></returns> public string GetPath(UInt32 n, NetworkGraph g) { string toreturn = ""; if (ChosenPath[n] == null) { return("no path found for this node, are you sure it exists?"); } toreturn = Convert.ToString(ChosenPath[n][0]);//first element is this node with no annotations. UInt32 lastASN = ChosenPath[n][0]; for (int i = 1; i < ChosenPath[n].Count; i++) { UInt32 ASN; int col; unjoin(ChosenPath[n][i], out ASN, out col); RelationshipType rt = g.GetNode(ASN).GetRelationshipTypeOfNeighbor(g.GetNode(lastASN)); switch (rt) { case RelationshipType.CustomerOf: toreturn = toreturn + " <- "; break; case RelationshipType.PeerOf: toreturn = toreturn + " -- "; break; case RelationshipType.ProviderTo: toreturn = toreturn + " -> "; break; } lastASN = ASN; toreturn = toreturn + ASN; } return(toreturn); }
/// <summary> /// ADDED BY SHARON /// Looks at the path this node has in the BFS /// and returns the relationship with the first hop on this path /// /// </summary> public static RelationshipType GetPathTypeFromBfsRoot(NetworkGraph graph, UInt32 nodeNum) { AsNode node = graph.GetNode(nodeNum); // first check that the node has a path to the root if (node.BfsDepth == Int32.MaxValue) { return(RelationshipType.NullRelationship); } else // return the relationship it has with its BFS parent { return(node.BfsParentNode.GetRelationshipTypeOfNeighbor(node)); } }
/// <summary> /// Retrieves a path from the BFS root to the specified start node. /// The path is returned as a list of AsNode objects. /// If there is no path from the BFS root, this function returns null. /// </summary> public static List <AsNode> GetPathFromBfsRoot(NetworkGraph graph, UInt32 srcNodeNum) { // Check the input AsNode currNode = graph.GetNode(srcNodeNum); if ((currNode == null) || (currNode.BfsDepth == Int32.MaxValue)) { return(null); } // Start a list of nodes in the path List <AsNode> nodeList = new List <AsNode>(); nodeList.Insert(0, currNode); // Keep adding parents to the list until we get to the root while (currNode.BfsParentNode != null) { currNode = currNode.BfsParentNode; nodeList.Insert(0, currNode); } return(nodeList); }
/// <summary> /// Examines the BFS subtree rooted at the node specified by nodeNum and returns a list of the /// nodes in the tree. /// </summary> public static List <AsNode> GetNodesInBfsSubtree(NetworkGraph graph, UInt32 nodeNum) { // Make sure the node exists and is in the BFS tree AsNode rootNode = graph.GetNode(nodeNum); if ((rootNode == null) || (rootNode.BfsDepth == Int32.MaxValue)) { return(null); } // Running node count & list List <AsNode> nodeList = new List <AsNode>(); // Similar to BFS, but we're only going to follow edges that are BFS children Queue <AsNode> nodeQueue = new Queue <AsNode>(); nodeQueue.Enqueue(rootNode); // While there's still nodes in the sub-tree to be examined... while (nodeQueue.Count > 0) { // Dequeue a node and iterate through its BFS children AsNode currentNode = nodeQueue.Dequeue(); foreach (AsNode oppositeNode in currentNode.GetNeighborsByType(RelationshipType.BfsParentOf)) { nodeQueue.Enqueue(oppositeNode); nodeList.Add(oppositeNode); // Sanity check... current node should be the BFS parent of opposite node if (oppositeNode.BfsParentNode != currentNode) { throw new Exception("Expected current node to be parent of child node"); } } } return(nodeList); }
/// <summary> /// Extension method on the NetworkGraph class that performs a [modified] BFS on the /// specified graph from the specified source ndoe. The allowedRelationships specifies /// which edges may be traversed during the BFS. /// This algorithm breaks ties by picking the node with the lower node number. /// This algorithm allows you to execute multiple BFS iterations on a single graph, with the /// constraint that any previous BFS trees created in a prior BFS run will not be modified (only /// added to). /// If limitedDiscovery is true, the BFS will only find new nodes that are 1 edge away from any existing /// BFS tree. /// If includeSibling is true, then ties are broken by first taking non-siblings over siblings. /// /// Modified by PGill Oct. 2010 to take in references to the Best, BucketTable and ChosenPaths sets. The function /// was also modified to populate these for our new sims. /// </summary> public static void ExecuteBfs(NetworkGraph graph, List<UInt32> srcNodeNums, bool limitedDiscovery, bool includeSibling, RelationshipType allowedRelationships, ref List<UInt32>[] Best, ref List<UInt32>[] BestNew, ref List<UInt32>[][] BucketTable, ref List<UInt32>[] ChosenPath, ref UInt32[] ChosenParent, ref byte[] L, ref byte[] BestRelation) { Destination utility = new Destination(); // Initialize some stuff... Queue<AsNode> nodeQueue = new Queue<AsNode>(graph.NodeCount); graph.BfsTreeNodeCount = 0; // "Visit" the source nodes foreach (UInt32 srcNodeNum in srcNodeNums) { AsNode currentNode = graph.GetNode(srcNodeNum); currentNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun; currentNode.BfsDepth = 0; nodeQueue.Enqueue(currentNode); graph.BfsTreeNodeCount++; //init the destination's path to itself ChosenPath[srcNodeNum] = new List<UInt32>(); ChosenPath[srcNodeNum].Add(srcNodeNum); Best[srcNodeNum] = new List<UInt32>(); Best[srcNodeNum].Add(srcNodeNum); //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf)) if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships==RelationshipType.NullRelationship) { BucketTable[0][ Destination._CUSTOMERCOLUMN] = new List<UInt32>(); BucketTable[0][ Destination._CUSTOMERCOLUMN].Add(srcNodeNum); } } // While there's still nodes to be examined... while (nodeQueue.Count > 0) { // Dequeue a node to examine. Iterate through all of its neighbors of the specified type (plus // existing BFS children) and visit them. AsNode currentNode = nodeQueue.Dequeue(); foreach (AsNode oppositeNode in currentNode.GetNeighborsByType(allowedRelationships | RelationshipType.BfsParentOf).Distinct()) { bool addedtoBest = false; // If this is the first time we've see this node, mark it and possibly enqueue it for later examination if (oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.UnseenInCurrentRun) { // Case 1: oppositeNode is a newly discovered node, also unseen in any previous BFS runs if (oppositeNode.PriorBfsStatus == NodePriorBfsStatus.NotDiscoveredInPriorBfs) { oppositeNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun; oppositeNode.BfsDepth = currentNode.BfsDepth + 1; oppositeNode.BfsParentNode = currentNode; currentNode.AddBfsChild(oppositeNode); graph.BfsTreeDepth = Math.Max(graph.BfsTreeDepth, oppositeNode.BfsDepth); graph.BfsTreeNodeCount++; if (!oppositeNode.isStub() || !OnlyNonStubs) { L[oppositeNode.NodeNum] = (byte)oppositeNode.BfsDepth; /*** add this node to the buckettable and update its chosen path, parent and BFS depth***/ //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5 if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { //init this spot in the bucket table (if needed) if (BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN] == null) BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN] = new List<UInt32>(); BestRelation[oppositeNode.NodeNum] = Destination._CUSTOMERCOLUMN; BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN].Add(oppositeNode.NodeNum); utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._CUSTOMERCOLUMN, ref ChosenPath); } //else if (allowedRelationships.HasFlag(RelationshipType.ProviderTo)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5 else if ((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo) { //init this spot in the bucket table (if needed) if (BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN] == null) BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN] = new List<UInt32>(); BestRelation[oppositeNode.NodeNum] = Destination._PROVIDERCOLUMN; BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN].Add(oppositeNode.NodeNum); utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PROVIDERCOLUMN, ref ChosenPath); } //else if (allowedRelationships.HasFlag(RelationshipType.PeerOf)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5 else if ((allowedRelationships & RelationshipType.PeerOf) == RelationshipType.PeerOf) { //init this spot in the bucket table (if needed) if (BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN] == null) BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN] = new List<UInt32>(); BestRelation[oppositeNode.NodeNum] = Destination._PEERCOLUMN; BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN].Add(oppositeNode.NodeNum); utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PEERCOLUMN, ref ChosenPath); } /*** update this node's Best set ***/ if (Best[oppositeNode.NodeNum] == null) Best[oppositeNode.NodeNum] = new List<UInt32>(); Best[oppositeNode.NodeNum].Add(currentNode.NodeNum); ChosenParent[oppositeNode.NodeNum] = currentNode.NodeNum; if (BestNew[oppositeNode.NodeNum] == null) BestNew[oppositeNode.NodeNum] = new List<UInt32>(); UInt32 encoded = 0; UInt32 NodeNumx = currentNode.NodeNum; if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.ProviderTo) { encoded = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { encoded = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.PeerOf) { encoded = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN); } BestNew[oppositeNode.NodeNum].Add(encoded); } // If we want to continue discovering past this newly found node, enqueue it if (!limitedDiscovery) { nodeQueue.Enqueue(oppositeNode); } } // Case 2: oppositeNode was found in a prior BFS run, and the path to oppositeNode went through currentNode else if (oppositeNode.BfsParentNode == currentNode) { // Don't need to do any marking of the opposite node because it's already in the BFS tree. // Just enqueue it so we can continue our BFS from that node at some later time. oppositeNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun; nodeQueue.Enqueue(oppositeNode); graph.BfsTreeDepth = Math.Max(graph.BfsTreeDepth, oppositeNode.BfsDepth); graph.BfsTreeNodeCount++; // Sanity check... the depth should be the same, right? if (oppositeNode.BfsDepth != currentNode.BfsDepth + 1) { throw new Exception("Unexpected BFS depth during BFS re-run"); } } // Case 3: oppositeNode was found in a prior BFS run, and the path to oppositeNode did NOT go through currentNode // No action necessary. We can't process oppositeNode now because we aren't allow to follow this edge. // Eventually we will hit the already-existing edge that's part of a prior BFS run, and we'll enter Case 2 above. } // We've seen this node before... else { // Did we find an alternate route to the opposite node? // We cannot change the route if this node was found in a prior BFS run. // This is where tie-breaking happens... if ((oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.SeenInCurrentRun) && (oppositeNode.BfsDepth == (currentNode.BfsDepth + 1)) && (oppositeNode.PriorBfsStatus != NodePriorBfsStatus.DiscoveredInPriorBfs)) { // This is an alternate route... break the tie //note that current node is a potential parent of opposite node here. //equivalent to current node being one of the nodes in the tiebreak set //Console.WriteLine("Ties Breaker"); //UPDATED CONDITION TO DEAL WITH HASH FLAG if ((Hash && NewRouteWinsTieBreak(currentNode, oppositeNode, includeSibling)) || (!Hash && NewRouteWinsTieBreakOriginal(currentNode, oppositeNode, includeSibling))) { // Tie-break algorithm says we have a new, better route to this node. // We need to switch the route through the current node instead. oppositeNode.BfsParentNode.RemoveBfsChild(oppositeNode); oppositeNode.BfsParentNode = currentNode; currentNode.AddBfsChild(oppositeNode); if (!oppositeNode.isStub() || !OnlyNonStubs) { /*** update chosen parent***/ ChosenParent[oppositeNode.NodeNum] = currentNode.NodeNum; /*** update its chosen path ***/ //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf)) if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._CUSTOMERCOLUMN, ref ChosenPath); //else if (allowedRelationships.HasFlag(RelationshipType.ProviderTo)) else if ((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo) utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PROVIDERCOLUMN, ref ChosenPath); //else if (allowedRelationships.HasFlag(RelationshipType.PeerOf)) else if ((allowedRelationships & RelationshipType.PeerOf) == RelationshipType.PeerOf) utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PEERCOLUMN, ref ChosenPath); } } /*** NEED TO UPDATE BEST SET WHETHER OR NOT THIS WINS THE TIE BREAK!! **/ if (!oppositeNode.isStub() || !OnlyNonStubs) { Best[oppositeNode.NodeNum].Add(currentNode.NodeNum); addedtoBest = true; } } } if ((Best[oppositeNode.NodeNum] != null))// && addedtoBest)// && //(oppositeNode.PriorBfsStatus != NodePriorBfsStatus.DiscoveredInPriorBfs)) { if (BestNew[oppositeNode.NodeNum] == null) BestNew[oppositeNode.NodeNum] = new List<UInt32>(); UInt32 encoded = 0; UInt32 NodeNumx = currentNode.NodeNum; if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.ProviderTo) { encoded = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { encoded = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.PeerOf) { encoded = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN); } UInt32 encoded0 = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN); UInt32 encoded1 = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN); UInt32 encoded2 = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN); if (!((BestNew[oppositeNode.NodeNum].Exists(element => element == encoded0)) || (BestNew[oppositeNode.NodeNum].Exists(element => element == encoded1)) || (BestNew[oppositeNode.NodeNum].Exists(element => element == encoded2)))) { //Console.WriteLine(oppositeNode.NodeNum + "--> Entered for: " + ((UInt32)(((uint)encoded) >> 3) + " relation: " + (int)(encoded & 7))); //Console.WriteLine("encoded = " + encoded); if (encoded != 0) { //Console.WriteLine(oppositeNode.NodeNum + "--> Entered for: " + ((UInt32)(((uint)encoded) >> 3) + " relation: " + (int)(encoded & 7))); //if ((((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo) && oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.ProcessedInCurrentRun)) //{ // Console.Write("Rel: " + allowedRelationships + " & Node status: " + oppositeNode.InProcessBfsStatus + "\n"); //} //else { BestNew[oppositeNode.NodeNum].Add(encoded); } } } } } // Update the in-process BFS status currentNode.InProcessBfsStatus = NodeInProcessBfsStatus.ProcessedInCurrentRun; } // Finished the BFS... lock the discovered nodes into the BFS tree foreach (AsNode node in graph.GetAllNodes()) { // FYI In limitedDiscovery mode, some nodes may have been left in the SeenInCurrentRun state // (instead of ProcessedInCurrentRun). if (node.InProcessBfsStatus != NodeInProcessBfsStatus.UnseenInCurrentRun) { node.PriorBfsStatus = NodePriorBfsStatus.DiscoveredInPriorBfs; } node.InProcessBfsStatus = NodeInProcessBfsStatus.UnseenInCurrentRun; } }
/// <summary> /// debugging function to give us a string representation of the path for /// a node n. /// </summary> /// <param name="n"></param> /// <returns></returns> public string GetPath(UInt32 n,NetworkGraph g) { string toreturn = ""; if (ChosenPath[n] == null) return "no path found for this node, are you sure it exists?"; toreturn = Convert.ToString(ChosenPath[n][0]);//first element is this node with no annotations. UInt32 lastASN = ChosenPath[n][0]; for (int i = 1; i < ChosenPath[n].Count; i++) { UInt32 ASN; int col; unjoin(ChosenPath[n][i], out ASN, out col); RelationshipType rt = g.GetNode(ASN).GetRelationshipTypeOfNeighbor(g.GetNode(lastASN)); switch (rt) { case RelationshipType.CustomerOf: toreturn = toreturn + " <- "; break; case RelationshipType.PeerOf: toreturn = toreturn + " -- "; break; case RelationshipType.ProviderTo: toreturn = toreturn + " -> "; break; } lastASN = ASN; toreturn = toreturn + ASN; } return toreturn; }
/// <summary> /// Retrieves a path from the BFS root to the specified start node. /// The path is returned as a list of AsNode objects. /// If there is no path from the BFS root, this function returns null. /// </summary> public static List<AsNode> GetPathFromBfsRoot(NetworkGraph graph, UInt32 srcNodeNum) { // Check the input AsNode currNode = graph.GetNode(srcNodeNum); if ((currNode == null) || (currNode.BfsDepth == Int32.MaxValue)) { return null; } // Start a list of nodes in the path List<AsNode> nodeList = new List<AsNode>(); nodeList.Insert(0, currNode); // Keep adding parents to the list until we get to the root while (currNode.BfsParentNode != null) { currNode = currNode.BfsParentNode; nodeList.Insert(0, currNode); } return nodeList; }
/// <summary> /// Examines the BFS subtree rooted at the node specified by nodeNum and returns a list of the /// nodes in the tree. /// </summary> public static List<AsNode> GetNodesInBfsSubtree(NetworkGraph graph, UInt32 nodeNum) { // Make sure the node exists and is in the BFS tree AsNode rootNode = graph.GetNode(nodeNum); if ((rootNode == null) || (rootNode.BfsDepth == Int32.MaxValue)) { return null; } // Running node count & list List<AsNode> nodeList = new List<AsNode>(); // Similar to BFS, but we're only going to follow edges that are BFS children Queue<AsNode> nodeQueue = new Queue<AsNode>(); nodeQueue.Enqueue(rootNode); // While there's still nodes in the sub-tree to be examined... while (nodeQueue.Count > 0) { // Dequeue a node and iterate through its BFS children AsNode currentNode = nodeQueue.Dequeue(); foreach (AsNode oppositeNode in currentNode.GetNeighborsByType(RelationshipType.BfsParentOf)) { nodeQueue.Enqueue(oppositeNode); nodeList.Add(oppositeNode); // Sanity check... current node should be the BFS parent of opposite node if (oppositeNode.BfsParentNode != currentNode) { throw new Exception("Expected current node to be parent of child node"); } } } return nodeList; }
private bool initGlobalState(string command, ref NetworkGraph g, ref GlobalState globalState) { if (command.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Length < 2) { Console.WriteLine("usage: initglobalstate :early adopters:top x:top x%"); Console.WriteLine("e.g., initglobalstate :15169 8075:8075 22822:40 will set security true for 15169 and 8075 and assign 40 % weight total to 8075 and 22822 with remaining 60% divided across other ASs"); return false; } string [] parameters= command.Split(":".ToCharArray(),StringSplitOptions.RemoveEmptyEntries); if (parameters.Length != 4) { Console.WriteLine("usage: initglobalstate :early adopters:top x:top x%"); Console.WriteLine("e.g., initglobalstate :15169 8075:8075 22822:40 will set security true for 15169 and 8075 and assign 40 % weight total to 8075 and 22822 with remaining 60% divided across other ASs"); return false; } List<UInt32> earlyAdopters = new List<UInt32>(); string[] earlyAdopterStrings = parameters[1].Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); foreach (string eAS in earlyAdopterStrings) { UInt32 currAdopter; if (UInt32.TryParse(eAS, out currAdopter)) { if (g.GetNode(currAdopter) != null) earlyAdopters.Add(currAdopter); else Console.WriteLine(currAdopter + " was not in the graph."); } else Console.WriteLine("could not parse AS: " + eAS); } List<UInt32> topX = new List<UInt32>(); string[] topXStrings = parameters[2].Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); foreach (string tXS in topXStrings) { UInt32 currTopX; if (UInt32.TryParse(tXS, out currTopX)) { if (g.GetNode(currTopX) != null) topX.Add(currTopX); else Console.WriteLine(currTopX + " was not in the graph."); } else Console.WriteLine("could not parse AS: " + tXS); } short topXPercent; if (!short.TryParse(parameters[3], out topXPercent)) { Console.WriteLine("could not parse your top X percent value!"); return false; } Console.WriteLine("dividing " + topXPercent + " across "); foreach (UInt32 topXAS in topX) Console.Write(topXAS + ", "); Console.WriteLine(); Console.WriteLine("turning on stubs and "); foreach (UInt32 adopter in earlyAdopters) Console.Write(adopter + ", "); Console.WriteLine(); globalState = SimulatorLibrary.initGlobalState(g, earlyAdopters, topX, topXPercent); return true; }
private bool initDestination(ref NetworkGraph g, ref Destination d,string command) { string resp; if (command.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Length < 2) { Console.WriteLine("Please enter a destination ASN: "); resp = Console.ReadLine(); } else resp = command.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1]; UInt32 destNum; if (!UInt32.TryParse(resp, out destNum)) { Console.WriteLine("invalid ASN! "); return false; } if (g.GetNode(destNum) == null) { Console.WriteLine("could not retrieve destination " + d + " from the graph."); return false; } Console.WriteLine("initializing variables and running RTA"); MiniDestination miniDest = SimulatorLibrary.initMiniDestination(g, destNum, false); d = new Destination(miniDest); bool[] tempS = new bool[Constants._numASNs]; for (int i = 0; i < tempS.Length;i++) tempS[i] = false; ; d.UpdatePaths(tempS);//init paths with S = all false Console.WriteLine("done initializing. Current active destination is: " + destNum); List<UInt32> temp = new List<UInt32>(); temp.Add(d.destination); d.BestNew[d.destination] = temp; //Console.Write("Dest BestNew["+ d.destination + "] = " + d.BestNew[d.destination][0]); return true; }
private bool getproviders(ref NetworkGraph g, string command) { string resp; bool onlystubs = false; if (command.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Length < 2) { Console.WriteLine("Please enter a node to get the providers of"); resp = Console.ReadLine(); } else { resp = command.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1]; } if (command.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Length > 2) { onlystubs = true; Console.WriteLine("you have indicated you are only interested in stub networks."); } UInt32 ASN; if (!UInt32.TryParse(resp, out ASN)) { Console.WriteLine("invalid ASN."); return false; } AsNode n; List<UInt32> stubs = g.getStubs(); if ((n = g.GetNode(ASN)) != null) { Console.WriteLine("Providers of AS: " + ASN + " are: (ie. AS is a customer of)"); foreach (AsNode customer in n.GetNeighborsByType(RelationshipType.CustomerOf)) { if (!onlystubs || (stubs.Contains(customer.NodeNum))) Console.Write(customer.NodeNum + " : "); } Console.WriteLine(); } else { Console.WriteLine("AS: " + ASN + " was not found in the graph, are you sure it exists?"); return false; } return true; }
private bool getLink(string command, ref NetworkGraph g) { string[] pieces = command.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); if (pieces.Length < 3) { Console.WriteLine("usage: getLink <AS1> <AS2>"); return false; } uint as1, as2; if (uint.TryParse(pieces[1], out as1) && uint.TryParse(pieces[2], out as2)) { AsNode asnode1 = g.GetNode(as1); AsNode asnode2 = g.GetNode(as2); if (asnode1.GetAllNeighbors().Contains(asnode2)) { RelationshipType rt = asnode1.GetRelationshipTypeOfNeighbor(asnode2); Console.WriteLine("AS " + as1 + " has relationship " + rt + " with AS " + as2); return true; } else { Console.WriteLine("edge was not in graph"); } return true; } return true; }
private List<bool[]> postProcessState(List<bool[]> unprocessedState, resultObject Params) { List<UInt32> big5 = new List<uint>(); big5.Add(22822); big5.Add(8075); big5.Add(15169); big5.Add(20940); big5.Add(32934); List<bool[]> processedState = new List<bool[]>(); string graphFile = graphDirectory + Params.graphFile; if (!File.Exists(graphFile)) Console.WriteLine("I could not find the graph file: " + graphFile); NetworkGraph g = new NetworkGraph(); InputFileReader ifr = new InputFileReader(graphFile, g); ifr.ProcessFile(); List<UInt32> stubs = g.getStubs(); /*** Process and add the initial state of the simulation ***/ bool[] initialState = SimulatorLibrary.initGlobalState(g, Params.earlyAdopters).S; //walk over stubs and re-evaluate their state. foreach (UInt32 AS in stubs) { if (!big5.Contains(AS)) { AsNode node = g.GetNode(AS); initialState[AS] = false;//default to false for this stub. var parents = node.GetNeighborsByType(RelationshipType.CustomerOf).ToList<AsNode>(); // parents.AddRange(node.GetNeighborsByType(RelationshipType.PeerOf)); //don't turn on for peers foreach (AsNode parent in parents) { if (initialState[parent.NodeNum]) {//parent is true let it be true in the augmented state. initialState[AS] = true; break; } } } } foreach (var AS in Params.earlyAdopters) initialState[AS] = true;//make sure early adopters are "on" processedState.Add(initialState); for (int i = 0; i < unprocessedState.Count; i++) { bool[] currS = unprocessedState[i]; //walk over stubs and re-evaluate their state. foreach (UInt32 AS in stubs) { if (!big5.Contains(AS)) { AsNode node = g.GetNode(AS); currS[AS] = false;//default to false for this stub. var parents = node.GetNeighborsByType(RelationshipType.CustomerOf).ToList<AsNode>(); // parents.AddRange(node.GetNeighborsByType(RelationshipType.PeerOf)); //don't turn on for peers foreach (AsNode parent in parents) { if (currS[parent.NodeNum]) {//parent is true let it be true in the augmented state. currS[AS] = true; break; } } } } foreach (var AS in Params.earlyAdopters) currS[AS] = true;//make sure early adopters are "on" processedState.Add(currS); } return processedState; }
/// <summary> /// Extension method on the NetworkGraph class that performs a [modified] BFS on the /// specified graph from the specified source ndoe. The allowedRelationships specifies /// which edges may be traversed during the BFS. /// This algorithm breaks ties by picking the node with the lower node number. /// This algorithm allows you to execute multiple BFS iterations on a single graph, with the /// constraint that any previous BFS trees created in a prior BFS run will not be modified (only /// added to). /// If limitedDiscovery is true, the BFS will only find new nodes that are 1 edge away from any existing /// BFS tree. /// If includeSibling is true, then ties are broken by first taking non-siblings over siblings. /// /// Modified by PGill Oct. 2010 to take in references to the Best, BucketTable and ChosenPaths sets. The function /// was also modified to populate these for our new sims. /// </summary> public static void ExecuteBfs(NetworkGraph graph, List <UInt32> srcNodeNums, bool limitedDiscovery, bool includeSibling, RelationshipType allowedRelationships, ref List <UInt32>[] Best, ref List <UInt32>[] BestNew, ref List <UInt32>[][] BucketTable, ref List <UInt32>[] ChosenPath, ref UInt32[] ChosenParent, ref byte[] L, ref byte[] BestRelation) { Destination utility = new Destination(); // Initialize some stuff... Queue <AsNode> nodeQueue = new Queue <AsNode>(graph.NodeCount); graph.BfsTreeNodeCount = 0; // "Visit" the source nodes foreach (UInt32 srcNodeNum in srcNodeNums) { AsNode currentNode = graph.GetNode(srcNodeNum); currentNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun; currentNode.BfsDepth = 0; nodeQueue.Enqueue(currentNode); graph.BfsTreeNodeCount++; //init the destination's path to itself ChosenPath[srcNodeNum] = new List <UInt32>(); ChosenPath[srcNodeNum].Add(srcNodeNum); Best[srcNodeNum] = new List <UInt32>(); Best[srcNodeNum].Add(srcNodeNum); //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf)) if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { BucketTable[0][Destination._CUSTOMERCOLUMN] = new List <UInt32>(); BucketTable[0][Destination._CUSTOMERCOLUMN].Add(srcNodeNum); } } // While there's still nodes to be examined... while (nodeQueue.Count > 0) { // Dequeue a node to examine. Iterate through all of its neighbors of the specified type (plus // existing BFS children) and visit them. AsNode currentNode = nodeQueue.Dequeue(); foreach (AsNode oppositeNode in currentNode.GetNeighborsByType(allowedRelationships | RelationshipType.BfsParentOf).Distinct()) { bool addedtoBest = false; // If this is the first time we've see this node, mark it and possibly enqueue it for later examination if (oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.UnseenInCurrentRun) { // Case 1: oppositeNode is a newly discovered node, also unseen in any previous BFS runs if (oppositeNode.PriorBfsStatus == NodePriorBfsStatus.NotDiscoveredInPriorBfs) { oppositeNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun; oppositeNode.BfsDepth = currentNode.BfsDepth + 1; oppositeNode.BfsParentNode = currentNode; currentNode.AddBfsChild(oppositeNode); graph.BfsTreeDepth = Math.Max(graph.BfsTreeDepth, oppositeNode.BfsDepth); graph.BfsTreeNodeCount++; if (!oppositeNode.isStub() || !OnlyNonStubs) { L[oppositeNode.NodeNum] = (byte)oppositeNode.BfsDepth; /*** add this node to the buckettable and update its chosen path, parent and BFS depth***/ //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5 if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { //init this spot in the bucket table (if needed) if (BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN] == null) { BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN] = new List <UInt32>(); } BestRelation[oppositeNode.NodeNum] = Destination._CUSTOMERCOLUMN; BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN].Add(oppositeNode.NodeNum); utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._CUSTOMERCOLUMN, ref ChosenPath); } //else if (allowedRelationships.HasFlag(RelationshipType.ProviderTo)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5 else if ((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo) { //init this spot in the bucket table (if needed) if (BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN] == null) { BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN] = new List <UInt32>(); } BestRelation[oppositeNode.NodeNum] = Destination._PROVIDERCOLUMN; BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN].Add(oppositeNode.NodeNum); utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PROVIDERCOLUMN, ref ChosenPath); } //else if (allowedRelationships.HasFlag(RelationshipType.PeerOf)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5 else if ((allowedRelationships & RelationshipType.PeerOf) == RelationshipType.PeerOf) { //init this spot in the bucket table (if needed) if (BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN] == null) { BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN] = new List <UInt32>(); } BestRelation[oppositeNode.NodeNum] = Destination._PEERCOLUMN; BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN].Add(oppositeNode.NodeNum); utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PEERCOLUMN, ref ChosenPath); } /*** update this node's Best set ***/ if (Best[oppositeNode.NodeNum] == null) { Best[oppositeNode.NodeNum] = new List <UInt32>(); } Best[oppositeNode.NodeNum].Add(currentNode.NodeNum); ChosenParent[oppositeNode.NodeNum] = currentNode.NodeNum; if (BestNew[oppositeNode.NodeNum] == null) { BestNew[oppositeNode.NodeNum] = new List <UInt32>(); } UInt32 encoded = 0; UInt32 NodeNumx = currentNode.NodeNum; if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.ProviderTo) { encoded = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { encoded = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.PeerOf) { encoded = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN); } BestNew[oppositeNode.NodeNum].Add(encoded); } // If we want to continue discovering past this newly found node, enqueue it if (!limitedDiscovery) { nodeQueue.Enqueue(oppositeNode); } } // Case 2: oppositeNode was found in a prior BFS run, and the path to oppositeNode went through currentNode else if (oppositeNode.BfsParentNode == currentNode) { // Don't need to do any marking of the opposite node because it's already in the BFS tree. // Just enqueue it so we can continue our BFS from that node at some later time. oppositeNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun; nodeQueue.Enqueue(oppositeNode); graph.BfsTreeDepth = Math.Max(graph.BfsTreeDepth, oppositeNode.BfsDepth); graph.BfsTreeNodeCount++; // Sanity check... the depth should be the same, right? if (oppositeNode.BfsDepth != currentNode.BfsDepth + 1) { throw new Exception("Unexpected BFS depth during BFS re-run"); } } // Case 3: oppositeNode was found in a prior BFS run, and the path to oppositeNode did NOT go through currentNode // No action necessary. We can't process oppositeNode now because we aren't allow to follow this edge. // Eventually we will hit the already-existing edge that's part of a prior BFS run, and we'll enter Case 2 above. } // We've seen this node before... else { // Did we find an alternate route to the opposite node? // We cannot change the route if this node was found in a prior BFS run. // This is where tie-breaking happens... if ((oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.SeenInCurrentRun) && (oppositeNode.BfsDepth == (currentNode.BfsDepth + 1)) && (oppositeNode.PriorBfsStatus != NodePriorBfsStatus.DiscoveredInPriorBfs)) { // This is an alternate route... break the tie //note that current node is a potential parent of opposite node here. //equivalent to current node being one of the nodes in the tiebreak set //Console.WriteLine("Ties Breaker"); //UPDATED CONDITION TO DEAL WITH HASH FLAG if ((Hash && NewRouteWinsTieBreak(currentNode, oppositeNode, includeSibling)) || (!Hash && NewRouteWinsTieBreakOriginal(currentNode, oppositeNode, includeSibling))) { // Tie-break algorithm says we have a new, better route to this node. // We need to switch the route through the current node instead. oppositeNode.BfsParentNode.RemoveBfsChild(oppositeNode); oppositeNode.BfsParentNode = currentNode; currentNode.AddBfsChild(oppositeNode); if (!oppositeNode.isStub() || !OnlyNonStubs) { /*** update chosen parent***/ ChosenParent[oppositeNode.NodeNum] = currentNode.NodeNum; /*** update its chosen path ***/ //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf)) if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._CUSTOMERCOLUMN, ref ChosenPath); } //else if (allowedRelationships.HasFlag(RelationshipType.ProviderTo)) else if ((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo) { utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PROVIDERCOLUMN, ref ChosenPath); } //else if (allowedRelationships.HasFlag(RelationshipType.PeerOf)) else if ((allowedRelationships & RelationshipType.PeerOf) == RelationshipType.PeerOf) { utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PEERCOLUMN, ref ChosenPath); } } } /*** NEED TO UPDATE BEST SET WHETHER OR NOT THIS WINS THE TIE BREAK!! **/ if (!oppositeNode.isStub() || !OnlyNonStubs) { Best[oppositeNode.NodeNum].Add(currentNode.NodeNum); addedtoBest = true; } } } if ((Best[oppositeNode.NodeNum] != null))// && addedtoBest)// && //(oppositeNode.PriorBfsStatus != NodePriorBfsStatus.DiscoveredInPriorBfs)) { if (BestNew[oppositeNode.NodeNum] == null) { BestNew[oppositeNode.NodeNum] = new List <UInt32>(); } UInt32 encoded = 0; UInt32 NodeNumx = currentNode.NodeNum; if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.ProviderTo) { encoded = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { encoded = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.PeerOf) { encoded = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN); } UInt32 encoded0 = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN); UInt32 encoded1 = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN); UInt32 encoded2 = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN); if (!((BestNew[oppositeNode.NodeNum].Exists(element => element == encoded0)) || (BestNew[oppositeNode.NodeNum].Exists(element => element == encoded1)) || (BestNew[oppositeNode.NodeNum].Exists(element => element == encoded2)))) { //Console.WriteLine(oppositeNode.NodeNum + "--> Entered for: " + ((UInt32)(((uint)encoded) >> 3) + " relation: " + (int)(encoded & 7))); //Console.WriteLine("encoded = " + encoded); if (encoded != 0) { //Console.WriteLine(oppositeNode.NodeNum + "--> Entered for: " + ((UInt32)(((uint)encoded) >> 3) + " relation: " + (int)(encoded & 7))); //if ((((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo) && oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.ProcessedInCurrentRun)) //{ // Console.Write("Rel: " + allowedRelationships + " & Node status: " + oppositeNode.InProcessBfsStatus + "\n"); //} //else { BestNew[oppositeNode.NodeNum].Add(encoded); } } } } } // Update the in-process BFS status currentNode.InProcessBfsStatus = NodeInProcessBfsStatus.ProcessedInCurrentRun; } // Finished the BFS... lock the discovered nodes into the BFS tree foreach (AsNode node in graph.GetAllNodes()) { // FYI In limitedDiscovery mode, some nodes may have been left in the SeenInCurrentRun state // (instead of ProcessedInCurrentRun). if (node.InProcessBfsStatus != NodeInProcessBfsStatus.UnseenInCurrentRun) { node.PriorBfsStatus = NodePriorBfsStatus.DiscoveredInPriorBfs; } node.InProcessBfsStatus = NodeInProcessBfsStatus.UnseenInCurrentRun; } }
/// <summary> /// ADDED BY SHARON /// Looks at the path this node has in the BFS /// and returns the relationship with the first hop on this path /// /// </summary> public static RelationshipType GetPathTypeFromBfsRoot(NetworkGraph graph, UInt32 nodeNum) { AsNode node = graph.GetNode(nodeNum); // first check that the node has a path to the root if (node.BfsDepth == Int32.MaxValue) return RelationshipType.NullRelationship; else // return the relationship it has with its BFS parent return node.BfsParentNode.GetRelationshipTypeOfNeighbor(node); }
private static bool initDestination(ref NetworkGraph g, ref Destination d, string dest) { UInt32 destNum; if (!UInt32.TryParse(dest, out destNum)) { /* Console.WriteLine("Invalid ASN!"); */ return false; } if (g.GetNode(destNum) == null) { /* Console.WriteLine("WARNING: Could not retrieve destination " + d + " from the graph."); */ return false; } /* Console.WriteLine("Initializing variables and running RTA"); */ MiniDestination miniDest = SimulatorLibrary.initMiniDestination(g, destNum, false); d = new Destination(miniDest); bool[] tempS = new bool[Constants._numASNs]; for (int i = 0; i < tempS.Length; i++) { tempS[i] = false; } d.UpdatePaths(tempS); /* Console.WriteLine("Done initializing. Current active destination is: " + destNum); */ return true; }
/// <summary> /// ADDED BY SHARON /// Checks if a particular other node (usually the attacker) is on the path /// from the source node to the BFS root. Returns true if it is, false otherwise /// If there is no path to the BFS root, this function returns false /// </summary> public static bool isNodeOnPathFromBfsRoot(NetworkGraph graph, UInt32 srcNodeNum, UInt32 attackerNodeNum) { AsNode currNode = graph.GetNode(srcNodeNum); AsNode attackerNode = graph.GetNode(attackerNodeNum); // Check the input if ((currNode == null) || (attackerNode == null) || (currNode.BfsDepth == Int32.MaxValue)) { return false; } //walk down path to root, checking for attacker while (currNode != null) { if (currNode.NodeNum == attackerNode.NodeNum) { return true; } currNode = currNode.BfsParentNode; } return false; }