/// <inhertidoc /> public void AddLink(IMLink link, Parameters parameters) { IMNode neighbour = link.OtherEnd(this); //Add the link referenced by both its own UUID and the ID of the neighbour it connects to lock (_links) { if (!_links.ContainsKey(neighbour.ID)) { _links.Add(neighbour.ID, link); } if (!_links.ContainsKey(link.ID)) { _links.Add(link.ID, link); } } lock (_neighbours) if (!_neighbours.ContainsKey(link.ID)) { _neighbours.Add(link.ID, neighbour); } link.OnWeightChanged += _weightDelegate; if (OnLinkAdded != null) { OnLinkAdded(ID, link, parameters); Logger.Debug(Name + " triggered OnLinkAdded for '" + link.Name + "'."); } }
public void ResetHighlight(IMNodeInternal hop) { if (Equals(_globalHighlightTarget) || !Highlighting || (_highlightedLink != null && _highlightedLink.OtherEnd(this).Equals(hop))) { return; } lock (HighlightLock) { _highlightState = HighlghtState.NotHighlighting; if (_highlightedLink != null) { _highlightedLink.Reset(); _highlightedLink.OtherEnd(this).ResetHighlight(this); _highlightedLink = null; } } }
/// <summary> /// What to do when notified that it should highlight /// /// Will highlight the link and forward the packet on if necessary /// </summary> /// <param name = "packet">The packet received</param> public void Highlight(IMNodeInternal hop) { _highlightedLink = ForwardingTable.ContainsKey(_globalTargetKey) ? ForwardingTable[_globalTargetKey] : null; if (HighlightingSingle || (_highlightedLink != null && _highlightedLink.OtherEnd(this).Equals(hop))) { return; } lock (HighlightLock) { _highlightState = HighlghtState.HighlightingSingle; if (_highlightedLink != null) { _highlightedLink.Colour = _globalHighlightColour; _highlightedLink.OtherEnd(this).Highlight(this); } } }
protected override void LinkAdded(IMLink link, Parameters parameters, bool visualise) { findShortestPaths(TTL, "'" + link.Name + "' added", visualise); //If there was a packet which was received from the other end of the link that was added before //the link had been added process it. if (_unknownPacket != null && _unknownPacket.S.Equals(link.OtherEnd(ID))) { ProcessPacket(_unknownPacket); _unknownPacket = null; } }
private void RouteChangeListener(string alg, IMNodeInternal target, IMLink oldRoute, IMLink newRoute, float oldDist, float dist) { Logger.Debug(Name + " changing route to " + target.Name + ". " + (oldRoute == null ? "No old route" : "Old route: " + oldRoute.Name) + ". " + (newRoute == null ? "No new route" : "New route: " + newRoute.Name)); if (OnForwardingTableChange != null && (oldRoute == null || newRoute == null || !oldRoute.Equals(newRoute) || oldDist != dist)) { OnForwardingTableChange(ID, ForwardingTableList); } //If not highlighting or not highlighting the route that was changed quit if ((oldRoute != null && newRoute != null && oldRoute.Equals(newRoute)) || !GlobalHighlighting || !target.Equals(_globalHighlightTarget) || (GlobalHighlightingSingle && !HighlightingSingle && !Equals(_globalHighlightRoot))) { return; } if (oldRoute != null) { oldRoute.Reset(); if (HighlightingSingle) { oldRoute.OtherEnd(this).ResetHighlight(this); } } if (newRoute != null) { newRoute.Colour = _globalHighlightColour; if (GlobalHighlightingSingle) { _highlightState = HighlghtState.HighlightingSingle; newRoute.OtherEnd(this).Highlight(this); } } else { _highlightState = HighlghtState.NotHighlighting; } _highlightedLink = newRoute; }
private void RouteChangeListener(string alg, IMNodeInternal target, IMLink oldRoute, IMLink newRoute, float oldDist, float dist) { Logger.Debug(Name + " changing route to " + target.Name + ". " + (oldRoute == null ? "No old route" : "Old route: " + oldRoute.Name) + ". " + (newRoute == null ? "No new route" : "New route: " + newRoute.Name)); if (OnForwardingTableChange != null && (oldRoute == null || newRoute == null || !oldRoute.Equals(newRoute) || oldDist != dist)) OnForwardingTableChange(ID, ForwardingTableList); //If not highlighting or not highlighting the route that was changed quit if ((oldRoute != null && newRoute != null && oldRoute.Equals(newRoute)) || !GlobalHighlighting || !target.Equals(_globalHighlightTarget) || (GlobalHighlightingSingle && !HighlightingSingle && !Equals(_globalHighlightRoot))) return; if (oldRoute != null) { oldRoute.Reset(); if (HighlightingSingle) oldRoute.OtherEnd(this).ResetHighlight(this); } if (newRoute != null) { newRoute.Colour = _globalHighlightColour; if (GlobalHighlightingSingle) { _highlightState = HighlghtState.HighlightingSingle; newRoute.OtherEnd(this).Highlight(this); } } else _highlightState = HighlghtState.NotHighlighting; _highlightedLink = newRoute; }
/// <summary> /// What to do when notified that it should highlight /// /// Will highlight the link and forward the packet on if necessary /// </summary> /// <param name = "packet">The packet received</param> public void Highlight(IMNodeInternal hop) { _highlightedLink = ForwardingTable.ContainsKey(_globalTargetKey) ? ForwardingTable[_globalTargetKey] : null; if (HighlightingSingle || (_highlightedLink != null && _highlightedLink.OtherEnd(this).Equals(hop))) return; lock (HighlightLock) { _highlightState = HighlghtState.HighlightingSingle; if (_highlightedLink != null) { _highlightedLink.Colour = _globalHighlightColour; _highlightedLink.OtherEnd(this).Highlight(this); } } }
/// <inhertidoc /> public void AddLink(IMLink link, Parameters parameters) { IMNode neighbour = link.OtherEnd(this); //Add the link referenced by both its own UUID and the ID of the neighbour it connects to lock (_links) { if (!_links.ContainsKey(neighbour.ID)) _links.Add(neighbour.ID, link); if (!_links.ContainsKey(link.ID)) _links.Add(link.ID, link); } lock (_neighbours) if (!_neighbours.ContainsKey(link.ID)) _neighbours.Add(link.ID, neighbour); link.OnWeightChanged += _weightDelegate; if (OnLinkAdded != null) { OnLinkAdded(ID, link, parameters); Logger.Debug(Name + " triggered OnLinkAdded for '" + link.Name + "'."); } }
protected override void LinkRemoved(IMLink link, Parameters parameters, bool visualise) { OnChange("Link to '" + link.OtherEnd(Node).Name + "' removed", link.ID, parameters, visualise); }
/// <summary> /// Finds the shortest route to a target. /// /// To start with can be in one of two states: /// A: No route known /// B: There is a route known /// /// Can finish in one of four states /// 1. There was no route originally and one has been found /// 2. There is a new, shorter route along a different link /// 3. The target can no longer be reached but used to be reachable /// 4. The original route is still shortest but is now a different length /// 5. The original route is no longer available but a new route was found /// 6. The original route is still shortest and has not changed /// 7. The target was not reachable before and is still not reachable /// /// 1 = Update distance vector, broadcast update, trigger routing table changed event /// 2 = Update distance vector, broadcast update, trigger routing table changed event /// 3 = Update distance vector, broadcast update, trigger routing table changed event /// 4 = Update distance vector, broadcast update, trigger routing table changed event /// 5 = Update distance vector, broadcast update, trigger routing table changed event /// 6 = No events triggered /// 7 = No events triggered /// </summary> /// <param name="targetNode"></param> /// <returns></returns> private bool findShortestPath(IMNodeInternal targetNode, List <string> changes) { UUID target = targetNode.ID; //oldDist == null indicates initial state A, otherwise initial state B. Distance oldDist; lock (distanceVector) oldDist = distanceVector.ContainsKey(target) ? distanceVector[target].copy() : null; IKeyTable <DistanceVector> tmpNeighbours = neighbourVectors.Copy(); IMLink link = null; float dist = float.MaxValue; if (oldDist != null && oldDist.Link.OtherEnd(ID).Equals(target) && Links.ContainsKey(target)) { //If there was an old route and target is a neighbour and the link was the link between them use the weight of that link as the starting weight link = Links[target]; dist = link.Weight; } else if (oldDist != null && tmpNeighbours.ContainsKey(oldDist.Hop.ID) && tmpNeighbours[oldDist.Hop.ID].ContainsKey(target) && tmpNeighbours[oldDist.Hop.ID][target].Dist > 0f) { //If there was an old route and it involved routing via a neighbour and that neighbour can still route then take the starting weight as the distance to the neighbour + the distance from the neighbour to the target link = Links[oldDist.Hop.ID]; dist = tmpNeighbours[oldDist.Hop.ID][target].Dist + link.Weight; } //Check every neighbour to see if the weight of the link to that neighbour + the distance the neighbour can achieve to the target is shorter . foreach (var neighbour in Neighbours) { var neighbourLink = Links[neighbour.ID]; var neighbourVector = tmpNeighbours.ContainsKey(neighbour.ID) && tmpNeighbours[neighbour.ID].ContainsKey(target) ? tmpNeighbours[neighbour.ID][target] : null; var neighbourDist = neighbourVector != null ? neighbourLink.Weight + neighbourVector.Dist : float.MaxValue; //Neighbour vector distance of 0 or less indicates poison reverse or a link to itself //Also checks to see if the link at the other end is the neighbour and whether the weight of the link is less than the current distance if ((neighbourVector != null && neighbourVector.Dist > 0 && neighbourDist < dist) || neighbour.Equals(targetNode) && neighbourLink.Weight < dist) { link = neighbourLink; dist = neighbour.Equals(targetNode) ? link.Weight : neighbourDist; } } if (link == null && oldDist == null) { //Case 5 + 6 return(false); } if (link != null && oldDist == null) { //1. There was no route originally and one has been found UpdateRoutes(targetNode, link.OtherEnd(Node), link, dist); changes.Add("Distance Vector added route to " + targetNode.Name + " via " + link.OtherEnd(Node).Name + " with distance " + Math.Round(dist, 2) + "."); } else if (link == null && oldDist != null) { //3. The target can no longer be reached but used to be reachable lock (distanceVector) { distanceVector.Remove(target); RemoveRoute(DV.DV_NAME, target); changes.Add("Distance Vector removed route to " + targetNode.Name + ". " + oldDist.Hop.Name + " is no longer a valid first hop and no other route was found."); } } else if (oldDist != null && !link.Equals(oldDist.Link)) { //2. There is a new, shorter route along a different link UpdateRoutes(targetNode, link.OtherEnd(Node), link, dist); changes.Add("Distance Vector changed route to " + targetNode.Name + " from " + oldDist.Hop.Name + " to " + link.OtherEnd(Node).Name + " with distance " + Math.Round(dist, 2) + "."); } else if (oldDist != null && link.Equals(oldDist.Link) && dist != oldDist.Dist) { //4. The original route is still shortest but is now a different length UpdateRoutes(targetNode, link.OtherEnd(Node), link, dist); changes.Add("Distance Vector changed weight of route to " + targetNode.Name + " from " + Math.Round(oldDist.Dist, 2) + " to " + Math.Round(dist, 2) + "."); } else { return(false); } return(true); }
protected override void LinkRemoved(IMLink link, Parameters parameters, bool visualise) { lock (neighbourVectors) neighbourVectors.Remove(link.OtherEnd(ID)); findShortestPaths(TTL, "'" + link.Name + "' removed", visualise); }