/// <summary> /// This function contains the tie-breaking algorithm when two routes are found to the same node (with /// the same depth). /// </summary> public static bool NewRouteWinsTieBreakOriginal(AsNode newNode, AsNode oppositeNode, bool includeSibling) { // If includeSibling is true, then the first tie-break is to prefer non-sibling over sibling if (includeSibling) { // Determine sibling status bool otherRouteIsViaSiblings = oppositeNode.IsSiblingOf(oppositeNode.BfsParentNode); bool newRouteIsViaSiblings = newNode.IsSiblingOf(oppositeNode); // If other route is via siblings and new route isn't, new route wins if (otherRouteIsViaSiblings && !newRouteIsViaSiblings) { return(true); } // If other route isn't via siblings and new route is, other route wins if (!otherRouteIsViaSiblings && newRouteIsViaSiblings) { return(false); } // Other cases are a tie... continue tie-break algorithm } // Lowest node number wins if (newNode.NodeNum < oppositeNode.BfsParentNode.NodeNum) { return(true); } return(false); }
/// <summary> /// Removes a particular BFS child from the BfsParentOf list /// Parent is towards root, child towards leaves /// </summary> public void RemoveBfsChild(AsNode child) { // Try to remove the node from the list if (!Neighbors[(int)NeighborTypeIndex.BfsParentOfIdx].Remove(child)) { throw new Exception("Child not found"); } }
/// <summary> /// Returns true if the other node is a sibling of this node. /// </summary> public bool IsSiblingOf(AsNode otherNode) { if (Neighbors[(int)NeighborTypeIndex.SiblingOfIdx].Contains(otherNode)) { return(true); } return(false); }
/// <summary> /// Removes an edge from the graph. This only removes the edge in one direction, /// from the src node to the dest node. /// </summary> public void RemoveEdge(UInt32 srcNodeNum, UInt32 destNodeNum) { // Retrieve the src and dest nodes AsNode srcNode = GetOrCreateNode(srcNodeNum); AsNode destNode = GetOrCreateNode(destNodeNum); // Add the edge to the source node srcNode.RemoveNeighbor(destNode); EdgeCount--; }
/// <summary> /// Adds an edge to the graph, where an edge is defined as a relationship between 2 AS's. /// This only adds the edge in one direction, from the src node to the dest node. /// This does not check for duplicates. /// </summary> public void AddEdge(UInt32 srcNodeNum, UInt32 destNodeNum, RelationshipType relationshipType) { // Retrieve the src and dest nodes AsNode srcNode = GetOrCreateNode(srcNodeNum); AsNode destNode = GetOrCreateNode(destNodeNum); // Add the edge to the source node srcNode.AddNeighbor(destNode, relationshipType); EdgeCount++; }
/// <summary> /// Retrieves a node by node number and creates the node if it doesn't exist /// </summary> protected AsNode GetOrCreateNode(UInt32 nodeNum) { AsNode node; if (!AsNodes.TryGetValue(nodeNum, out node)) { node = new AsNode(nodeNum); AsNodes[nodeNum] = node; } return(node); }
/// <summary> /// Gets the relationship type of the given neighbor node. FYI this is /// an O(n) operation on the number of neighbors. /// </summary> public RelationshipType GetRelationshipTypeOfNeighbor(AsNode neighbor) { // Iterate through each neighbor type and inspect its list for the given neighbor for (int i = 0; i < NumNeighborTypes; i++) { if (Neighbors[i].Contains(neighbor)) { return(IndexToRelationshipType(i)); } } //throw new Exception("Neighbor not found"); return(RelationshipType.NullRelationship); }
/// <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 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> ///get the list of non stubs in the graph /// </summary> /// <returns></returns> public List <UInt32> getNonStubs() { List <UInt32> NonStubs = new List <UInt32>();//list of ASNs that are single homed stubs foreach (KeyValuePair <UInt32, AsNode> ASN in AsNodes) { AsNode curr = ASN.Value; if (curr.GetNeighborTypeCount(RelationshipType.ProviderTo) > 0) { NonStubs.Add(ASN.Key); } } return(NonStubs); }
/// <summary> /// Removes a neighbor from this node. FYI this doesn't remove this node /// from the neighbor's neighbor list. /// </summary> public void RemoveNeighbor(AsNode neighbor) { // Iterate through each nodeList foreach (List <AsNode> nodeList in Neighbors) { // Try to remove the node from the neighbor list if (nodeList.Remove(neighbor)) { // We successfully removed it. Remove the node from our ParentOf list too, if possible. // FYI this is not a good idea if there are duplicate edges b/w these two nodes, but // we are assuming there aren't duplicate edges. Neighbors[(int)NeighborTypeIndex.BfsParentOfIdx].Remove(neighbor); return; } } throw new Exception("Neighbor not found"); }
public void RemoveNode(UInt32 ASN) { if (AsNodes.ContainsKey(ASN)) { AsNode toremove = AsNodes[ASN]; var neighbors = toremove.GetAllNeighbors().ToArray(); for (int i = 0; i < neighbors.Length; i++) { RemoveEdge(neighbors[i].NodeNum, ASN); RemoveEdge(ASN, neighbors[i].NodeNum); if (neighbors[i].GetAllNeighbors().Count() == 0) { AsNodes.Remove(neighbors[i].NodeNum); } } AsNodes.Remove(ASN); } }
/// <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> /// 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> /// 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> /// Adds a particular BFS child to the BfsParentOf list /// </summary> public void AddBfsChild(AsNode child) { Neighbors[(int) NeighborTypeIndex.BfsParentOfIdx].Add(child); }
/// <summary> /// Reads and parses the cyclops file and populates the graph object /// Ignores 4-byte ASNs /// </summary> public void ProcessCyclopsFile() { Int32 numBadVertex = 0; Int32 num4byteASNs = 0; Int32 numbadReltypes = 0; using (StreamReader sr = new StreamReader(Filename)) { string line; int lineNumber = 0; // Read a single line at a time, which corresponds to a single edge while ((line = sr.ReadLine()) != null) { // Line number housekeeping and debug output lineNumber++; if (lineNumber % 1000 == 0) { // OutputLog.LogMessage(LogLevelType.LogLevelDebug, "Processing line {0}", lineNumber); } // Split the line into 3 strings using space as the delimiter string[] fields = line.Split(_cyclopsfileFieldDelimiter); // Check for comment if ((fields.Length > 0) && (fields[0].StartsWith("#"))) { continue; } // Should be 3 fields if (fields.Length != 3) { // OutputLog.LogMessage(LogLevelType.LogLevelWarning, "Line {0} does not have the proper number of fields", lineNumber); continue; } // Validate each field UInt32 vertex1, vertex2; if (!StringIsNumber(fields[0], null, out vertex1) || !StringIsNumber(fields[1], null, out vertex2)) { float junkfloat; if (float.TryParse(fields[0], out junkfloat)) { num4byteASNs++; // OutputLog.LogMessage(LogLevelType.LogLevelDebug, "Ignored 4 byte ASN at Line {0}.", lineNumber); } else { numBadVertex++; // OutputLog.LogMessage(LogLevelType.LogLevelWarning, "Line {0} has a malformed field", lineNumber); } continue; } // Decode the edge direction string edgeDescriptor = fields[2]; RelationshipType relationshipType; switch (edgeDescriptor) { case "c2p": relationshipType = RelationshipType.CustomerOf; break; case "p2p": relationshipType = RelationshipType.PeerOf; break; case "p2c": relationshipType = RelationshipType.ProviderTo; break; case "-": numbadReltypes++; // cyclops can't characterterize this relationship, so ignore. continue; default: // OutputLog.LogMessage(LogLevelType.LogLevelDebug, "Line {0} has an unknown edge type", lineNumber); continue; } //ignore vertices with too high ASNs if (vertex1 > Constants._numASNs || vertex2 > Constants._numASNs) { continue; } // Add the new edge to the graph NetGraph.AddEdge(vertex1, vertex2, relationshipType); NetGraph.AddEdge(vertex2, vertex1, AsNode.GetOppositeRelationshipType(relationshipType)); } } // OutputLog.LogMessage(LogLevelType.LogLevelWarning, // "Cyclops data has the following `bad entries' that were NOT loaded to graph:\n"+ // "{0} malformed entries\n"+ // "{1} 4-byte ASNs,\n"+ // "{2} '-' relationships", // numBadVertex, num4byteASNs, numbadReltypes); }
/// <summary> /// Add a neighboring node to this node with a specific relationship type. /// This does not check for duplicates. /// </summary> public void AddNeighbor(AsNode neighbor, RelationshipType relationshipType) { Neighbors[RelationshipTypeToIndex(relationshipType)].Add(neighbor); }
/// <summary> /// Returns true if the other node is a sibling of this node. /// </summary> public bool IsSiblingOf(AsNode otherNode) { if (Neighbors[(int) NeighborTypeIndex.SiblingOfIdx].Contains(otherNode)) { return true; } return false; }
/// <summary> /// Gets the relationship type of the given neighbor node. FYI this is /// an O(n) operation on the number of neighbors. /// </summary> public RelationshipType GetRelationshipTypeOfNeighbor(AsNode neighbor) { // Iterate through each neighbor type and inspect its list for the given neighbor for (int i = 0; i < NumNeighborTypes; i++) { if (Neighbors[i].Contains(neighbor)) { return IndexToRelationshipType(i); } } //throw new Exception("Neighbor not found"); return RelationshipType.NullRelationship; }
/// <summary> /// Removes a particular BFS child from the BfsParentOf list /// Parent is towards root, child towards leaves /// </summary> public void RemoveBfsChild(AsNode child) { // Try to remove the node from the list if (!Neighbors[(int)NeighborTypeIndex.BfsParentOfIdx].Remove(child)) { throw new Exception("Child not found"); } }
/// <summary> /// Adds a particular BFS child to the BfsParentOf list /// </summary> public void AddBfsChild(AsNode child) { Neighbors[(int)NeighborTypeIndex.BfsParentOfIdx].Add(child); }
/// <summary> /// Removes a neighbor from this node. FYI this doesn't remove this node /// from the neighbor's neighbor list. /// </summary> public void RemoveNeighbor(AsNode neighbor) { // Iterate through each nodeList foreach (List<AsNode> nodeList in Neighbors) { // Try to remove the node from the neighbor list if (nodeList.Remove(neighbor)) { // We successfully removed it. Remove the node from our ParentOf list too, if possible. // FYI this is not a good idea if there are duplicate edges b/w these two nodes, but // we are assuming there aren't duplicate edges. Neighbors[(int)NeighborTypeIndex.BfsParentOfIdx].Remove(neighbor); return; } } throw new Exception("Neighbor not found"); }
/// <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> /// tells us if this ASN is connected to one of the big 5 or content providers. /// (excluding the point ASN) /// /// returns the list of such neighbors. /// </summary> /// <param name="ASN"></param> /// <param name="g"></param> /// <returns></returns> private static List<UInt32> hasCPT1Neighbor(AsNode ASN,UInt32 pointASN) { UInt32[] CPT1 = { 15169, 8075, 22822, 20940, 32934, 1239, 7018, 701, 174, 3356 }; List<UInt32> toreturn = new List<uint>(); foreach (var neighbor in ASN.GetAllNeighbors()) { if (neighbor.NodeNum != pointASN && CPT1.Contains(neighbor.NodeNum)) toreturn.Add(neighbor.NodeNum); } return toreturn ; }
/// <summary> /// This function contains the tie-breaking algorithm when two routes are found to the same node (with /// the same depth). /// </summary> public static bool NewRouteWinsTieBreakOriginal(AsNode newNode, AsNode oppositeNode, bool includeSibling) { // If includeSibling is true, then the first tie-break is to prefer non-sibling over sibling if (includeSibling) { // Determine sibling status bool otherRouteIsViaSiblings = oppositeNode.IsSiblingOf(oppositeNode.BfsParentNode); bool newRouteIsViaSiblings = newNode.IsSiblingOf(oppositeNode); // If other route is via siblings and new route isn't, new route wins if (otherRouteIsViaSiblings && !newRouteIsViaSiblings) { return true; } // If other route isn't via siblings and new route is, other route wins if (!otherRouteIsViaSiblings && newRouteIsViaSiblings) { return false; } // Other cases are a tie... continue tie-break algorithm } // Lowest node number wins if (newNode.NodeNum < oppositeNode.BfsParentNode.NodeNum) { return true; } return false; }
/// <summary> /// Add a neighboring node to this node with a specific relationship type. /// This does not check for duplicates. /// </summary> public void AddNeighbor(AsNode neighbor, RelationshipType relationshipType) { Neighbors[RelationshipTypeToIndex(relationshipType)].Add(neighbor); }
/// <summary> /// Retrieves a node by node number and creates the node if it doesn't exist /// </summary> protected AsNode GetOrCreateNode(UInt32 nodeNum) { AsNode node; if (!AsNodes.TryGetValue(nodeNum, out node)) { node = new AsNode(nodeNum); AsNodes[nodeNum] = node; } return node; }
/// <summary> /// return to us the list of stubs connected to ASN's neighbors who were /// off in state S /// </summary> /// <param name="ASN"></param> /// <param name="g"></param> /// <param name="S"></param> private static void getOffGrandChildrenStubs(AsNode ASN,List<UInt32> stubs,bool[] S) { }