/// <inhertidoc />
        public void TriggerHighlight(string alg, IMNodeInternal target)
        {
            if (Equals(_globalHighlightTarget) || Equals(_globalHighlightRoot))
            {
                TriggerHighlightReset();
                return;
            }

            ClearOld();

            _globalTargetKey       = target.ID;
            _globalHighlightTarget = (IMNode)target;
            _globalHighlightRoot   = this;
            _globalHighlightColour = Colour;
            _globalHighlightState  = HighlghtState.HighlightingSingle;
            _highlightState        = HighlghtState.HighlightingSingle;

            //If there is a route
            if (ForwardingTable.ContainsKey(_globalTargetKey))
            {
                lock (HighlightLock) {
                    _highlightedLink        = ForwardingTable[_globalTargetKey];
                    _highlightedLink.Colour = _globalHighlightColour;
                    IMNode node = ForwardingTable[_globalTargetKey].OtherEnd(this);
                    node.Highlight(this);
                }
            }
            else
            {
                _highlightedLink = null;
            }
        }
示例#2
0
        internal DVNode(IMNodeInternal node, ForwardDelegate forwardMethod, IAsynchQueue queue, IKeyTableFactory tableFactory, int TTL, IConfigSource config)
            : base(node, tableFactory, config)
        {
            _queue         = queue;
            _forwardMethod = forwardMethod;
            this.TTL       = TTL;

            distanceVector = new DistanceVector();

            neighbourVectors    = tableFactory.MakeKeyTable <DistanceVector>();
            highlightParameters = new Parameters(new object[] { "HColour", node.Colour });

            IConfig dvConfig = config.Configs["DV"];

            if (dvConfig == null)
            {
                dvConfig = config.Configs["DistanceVector"];
            }
            if (dvConfig == null)
            {
                dvConfig = config.Configs["Algorithm"];
            }
            if (dvConfig == null)
            {
                dvConfig = config.Configs[0];
            }

            _poison            = dvConfig.GetBoolean("PoisonReverse", true);
            _everPrint         = dvConfig.GetBoolean("EverPrint", false);
            _alwaysPrint       = dvConfig.GetBoolean("AlwaysPrint", false);
            highlightPrintText = dvConfig.GetBoolean("HighlightPrint", false);
        }
        /// <summary>
        ///   What to do when a packet relevant to the highlight flooding algorithm is received
        ///
        ///   If the node has not already received one of the highlight flooding packets flood highlight packets along all links and send a new
        ///   highlight all packet back towards the source of the received packet
        /// </summary>
        /// <param name = "packet"></param>
        public void HighlightAll(IMNodeInternal hop)
        {
            if (HighlightingAll)
            {
                return;
            }

            lock (HighlightLock) {
                _highlightedLink = ForwardingTable.ContainsKey(_globalTargetKey) ? ForwardingTable[_globalTargetKey] : null;
                _highlightState  = HighlghtState.HighlightingAll;

                if (_highlightedLink != null)
                {
                    _highlightedLink.Colour = _globalHighlightColour;
                }

                foreach (IMLink l in _links)
                {
                    IMNode neighbour = l.OtherEnd(this);
                    if (!neighbour.Equals(hop))
                    {
                        neighbour.HighlightAll(this);
                    }
                }
            }
        }
示例#4
0
        public LinkStateNode(IMNodeInternal node, IKeyTableFactory tableFactory, IAsynchQueue dijkstraQ, IAsynchQueue packetQ, ForwardDelegate forwardMethod, IConfigSource config)
            : base(node, tableFactory, dijkstraQ, config)
        {
            _eventQ          = packetQ;
            _forwardMethod   = forwardMethod;
            _processedEvents = new HashSet <int>();

            OnRouteChange += (alg, target, oldRoute, newRoute, oldDistance, distance) => {
                _changed = true;
                if (!Model.IsPaused)
                {
                    return;
                }
                if (oldRoute != null && newRoute != null)
                {
                    Say("Link State changed route to " + target.Name + " from " + oldRoute.OtherEnd(Node).Name + " to " + newRoute.OtherEnd(Node).Name + ".");
                }
                else if (oldRoute == null)
                {
                    Say("Link State added route to " + target.Name + " via " + newRoute.OtherEnd(Node).Name + " with distance " + distance + ".");
                }
                else if (newRoute == null)
                {
                    Say("Link State removed route to " + target.Name + ". " + oldRoute.OtherEnd(Node).Name + " is no longer a valid first hop and no other route was found.");
                }
                else
                {
                    Say("Link State changed weight of route to " + target.Name + " from " + oldDistance + " to " + distance + ".");
                }
            };
        }
示例#5
0
        internal DVNode(IMNodeInternal node, ForwardDelegate forwardMethod, IAsynchQueue queue, IKeyTableFactory tableFactory, int TTL, IConfigSource config)
            : base(node, tableFactory, config)
        {
            _queue = queue;
            _forwardMethod = forwardMethod;
            this.TTL = TTL;

            distanceVector = new DistanceVector();

            neighbourVectors = tableFactory.MakeKeyTable<DistanceVector>();
            highlightParameters = new Parameters(new object[] { "HColour", node.Colour });

            IConfig dvConfig = config.Configs["DV"];
            if (dvConfig == null)
                dvConfig = config.Configs["DistanceVector"];
            if (dvConfig == null)
                dvConfig = config.Configs["Algorithm"];
            if (dvConfig == null)
                dvConfig = config.Configs[0];

            _poison = dvConfig.GetBoolean("PoisonReverse", true);
            _everPrint = dvConfig.GetBoolean("EverPrint", false);
            _alwaysPrint = dvConfig.GetBoolean("AlwaysPrint", false);
            highlightPrintText = dvConfig.GetBoolean("HighlightPrint", false);
        }
示例#6
0
 /// <summary>
 ///   Initialise a Dijkstra's Packet
 /// </summary>
 /// <param name = "hop">The node this packet just came from as opposed to its original source</param>
 /// <param name = "from">The node the packet was sent from</param>
 /// <param name = "to">The node the packet is destined for</param>
 /// <param name = "evt">The AddLink along which the packet is currently travelling</param>
 /// <param name = "view">The view layer which is used to visualise the packet moving</param>
 /// <param name = "visualise">Whether the packet should be visualised</param>
 internal LinkStatePacket(IMNodeInternal hop, INode from, INode to, int evt, bool visualise)
     : base(from, to, hop, new Parameters(), LinkState.LINK_STATE_NAME, visualise)
 {
     _event   = evt;
     Name     = "Link IsOn " + Name;
     Selected = 1d;
     Parameters.Set <bool>("Visualise", visualise);
 }
示例#7
0
 public DVPacket(IMNodeInternal from, INode to, DistanceVector distanceVector, bool visualise = false, int TTL = 51)
     : base(from, to, from, new Parameters("Visualise", visualise), DV.DV_NAME, visualise)
 {
     _distanceVector = distanceVector;
     _highlighting   = false;
     _ttl            = TTL - 1;
     Name            = "Distance Vector " + Name;
     Selected        = 1d;
 }
示例#8
0
        public MPacket(INode source, INode destination, IMNodeInternal hop, Parameters parameters, string algorithm = null, bool visualise = true)
            : base("Packet from " + source.Name + " to " + destination.Name, source.Colour, 0d, parameters)
        {
            S = source.ID;
            D = destination.ID;
            Source = source;
            Destination = destination;

            Hop = hop;
            Type = algorithm == null ? PTypes.data : PTypes.Algorithm;
            Visualise = Type == PTypes.data || visualise;
            Algorithm = algorithm;
        }
示例#9
0
        private void VisualiseAlgorithm(IMNodeInternal target, Parameters parameters)
        {
            Logger.Debug("Distance vector visualising routing for " + Node.Name + ".");

            if (target == null)
            {
                Node.TriggerHighlightAll(DV.DV_NAME);
            }
            else
            {
                Node.TriggerHighlight(DV.DV_NAME, target);
            }
        }
示例#10
0
 /// <summary>
 /// Initialise the various variables, flags and collections that are used to run the algorithm.
 /// </summary>
 /// <param name="target">The target being routed to. Null means route to every target.</param>
 ///
 ///
 private void Init(IMNodeInternal target)
 {
     _target = _target != null && target == null ? _target : target;
     _confirmed.Clear();
     _tentative.Clear();
     _links.Clear();
     _tentative.AddFirst(this);
     foreach (DijkstraNode n in this.GetAllNodes <DijkstraNode>())
     {
         n.SetDistanceFromRoot(ID, float.MaxValue, null, null);
     }
     _cont = true;
 }
示例#11
0
        protected AbstractAlgorithmNode(IMNodeInternal node, IKeyTableFactory tableFactory, IConfigSource config)
        {
            AlgCollectionExtension._tableFactory = tableFactory;
            Logger     = LogManager.GetLogger(GetType());
            _node      = node;
            _table     = tableFactory.MakeKeyTable <IMLink>();
            _distances = tableFactory.MakeKeyTable <float>();
            this.RegisterAlgNode();

            Node.OnWeightChange += (link, weight) => WeightChanged(Links[link], IsCurrentAlgorithm && Links[link].Parameters.Get <bool>("Visualise"));
            Node.OnLinkAdded    += (n, link, parameters) => LinkAdded(link, parameters, IsCurrentAlgorithm && parameters.Get <bool>("Visualise"));
            Node.OnLinkRemoved  += (n, link, parameters) => LinkRemoved(link, parameters, IsCurrentAlgorithm && parameters.Get <bool>("Visualise"));
        }
示例#12
0
        public MPacket(INode source, INode destination, IMNodeInternal hop, Parameters parameters, string algorithm = null, bool visualise = true)
            : base("Packet from " + source.Name + " to " + destination.Name, source.Colour, 0d, parameters)
        {
            S           = source.ID;
            D           = destination.ID;
            Source      = source;
            Destination = destination;

            Hop       = hop;
            Type      = algorithm == null ? PTypes.data : PTypes.Algorithm;
            Visualise = Type == PTypes.data || visualise;
            Algorithm = algorithm;
        }
示例#13
0
        public DijkstraNode(IMNodeInternal node, IKeyTableFactory tableFactory, IAsynchQueue queue, IConfigSource config)
            : base(node, tableFactory, config)
        {
            _queue     = queue;
            _distances = tableFactory.MakeKeyTable <float>();
            _wipRoute  = tableFactory.MakeKeyTable <IMLink>();
            _prev      = tableFactory.MakeKeyTable <DijkstraNode>();

            _confirmed = new LinkedList <DijkstraNode>();
            _tentative = new LinkedList <DijkstraNode>();
            _links     = new LinkedList <IMLink>();

            SetDistanceFromRoot(ID, 0f, null, null);
        }
示例#14
0
 internal void RunAlgorithm(string description, IMNodeInternal to, bool visualise)
 {
     _visualise = visualise;
     ResetAlgorithm();
     if (_visualise && IsCurrentAlgorithm)
     {
         _visualiseThread      = new Thread(() => RunAlgorithm(to));
         _visualiseThread.Name = description;
         _visualiseThread.Start();
     }
     else
     {
         _queue.QWork(GetType().Name + " " + description, () => RunAlgorithm(to));
     }
 }
示例#15
0
        public Distance(IMNodeInternal target, IMNodeInternal hop, IMLink link, float distance)
        {
            if (target == null)
                throw new Exception("Target node must be set when initialising distance to target");
            if (hop == null)
                throw new Exception("First hop must be set when initialising distance to target");
            if (link == null)
                throw new Exception("First hop link must be set when initialising distance to target");
            //if (distance <= 0)
            //    throw new AlgorithmException("Distance must be positive when initialising distance to target");

            this.target = target;
            this.hop = hop;
            this.link = link;
            this.distance = distance;
        }
示例#16
0
        internal void update(IMNodeInternal hop, IMLink link, float dist)
        {
            if (hop == null)
            {
                throw new Exception("First hop must be set when updating distance to target");
            }
            if (link == null)
            {
                throw new Exception("First hop link must be set when updating distance to target");
            }
            //if (distance <= 0)
            //    throw new AlgorithmException("Distance must be positive when updating distance to target");

            this.hop  = hop;
            this.link = link;
            update(dist);
        }
示例#17
0
 private void UpdateRoutes(IMNodeInternal target, IMNodeInternal hop, IMLink link, float dist)
 {
     if (target.ID.Equals(ID))
     {
         return;
     }
     SetRoute(DV.DV_NAME, target.ID, link, dist);
     lock (distanceVector)
         if (!distanceVector.ContainsKey(target.ID))
         {
             distanceVector.Add(target.ID, new Distance(target, hop, link, dist));
         }
         else
         {
             distanceVector[target.ID].update(hop, link, dist);
         }
 }
        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);
                }
            }
        }
        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;
                }
            }
        }
示例#21
0
        public override void VisualiseAlgorithm(UUID to, Parameters parameters)
        {
            if (Equals(VisualisedNode))
            {
                ResetAlgorithm();
                _visualise     = false;
                VisualisedNode = null;
                return;
            }
            else if (VisualisedNode != null)
            {
                VisualisedNode.Stop();
            }

            IMNodeInternal target = KnownNodes.ContainsKey(to) ? KnownNodes[to] : null;

            _text          = Dijkstra.AlwaysPrint || (Dijkstra.EverPrint && parameters != null && parameters.Get <bool>("Text"));
            VisualisedNode = this;

            RunAlgorithm("Visualise Dijkstra's Algorithm", target, true);
        }
示例#22
0
        public Distance(IMNodeInternal target, IMNodeInternal hop, IMLink link, float distance)
        {
            if (target == null)
            {
                throw new Exception("Target node must be set when initialising distance to target");
            }
            if (hop == null)
            {
                throw new Exception("First hop must be set when initialising distance to target");
            }
            if (link == null)
            {
                throw new Exception("First hop link must be set when initialising distance to target");
            }
            //if (distance <= 0)
            //    throw new AlgorithmException("Distance must be positive when initialising distance to target");

            this.target   = target;
            this.hop      = hop;
            this.link     = link;
            this.distance = distance;
        }
示例#23
0
        /// <inhertidoc />
        public void RemoveLink(UUID l, Parameters parameters)
        {
            if (!Neighbours.ContainsKey(l))
            {
                throw new Exception("The link to be remove is not a known link.");
            }

            IMNodeInternal neighbour = _neighbours[l];
            IMLink         link      = _links[neighbour.ID];

            link.OnWeightChanged -= _weightDelegate;

            lock (_links) {
                _links.Remove(neighbour.ID);
                _links.Remove(l);
            } lock (_neighbours)
                _neighbours.Remove(link.ID);

            if (OnLinkRemoved != null && !parameters.Get <bool>("Clearing"))
            {
                OnLinkRemoved(ID, link, parameters);
                Logger.Debug(Name + " triggered OnLinkRemoved for '" + link.Name + "'.");
            }
        }
示例#24
0
        private void RunAlgorithm(IMNodeInternal to)
        {
            lock (_runLock) {
                Init(to);

                if (_visualise)
                {
                    Logger.Debug("Dijkstra visualising routing from " + Name);
                }

                if (_cont && _text && _visualise)
                {
                    Say("Starting Algorithm");
                    Say("1. Initialising Confirmed and Tentative lists");
                }

                DijkstraNode current = getNext(this);
                DijkstraNode prev    = current;

                if (_cont && _text && _visualise)
                {
                    Pause();
                    Say("3. Cost for root (" + Node.Name + ") = 0");
                    Pause();
                }

                MainLoop(current, prev);

                //If the algorithm didn't finish prematurely
                if (_cont)
                {
                    UpdateRoutingTable();
                }
                algorithmFinished();
            }
        }
        /// <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);
                }
            }
        }
示例#26
0
 public Distance(Distance distance, IMNodeInternal hop, IMLink link, float hopWeight)
     : this(distance.Target, hop, link, distance.Dist + hopWeight)
 {
 }
示例#27
0
        internal void update(IMNodeInternal hop, IMLink link, float dist)
        {
            if (hop == null)
                throw new Exception("First hop must be set when updating distance to target");
            if (link == null)
                throw new Exception("First hop link must be set when updating distance to target");
            //if (distance <= 0)
            //    throw new AlgorithmException("Distance must be positive when updating distance to target");

            this.hop = hop;
            this.link = link;
            update(dist);
        }
示例#28
0
 public IAlgorithmNode MakeNode(IMNodeInternal node, ForwardDelegate forwardMethod)
 {
     return(new LinkStateNode(node, _tableFactory, _dijkstraQ, _eventQ, forwardMethod, _config));
 }
示例#29
0
 public Distance(Distance distance, IMNodeInternal hop, IMLink link, float hopWeight)
     : this(distance.Target, hop, link, distance.Dist + hopWeight)
 {
 }
示例#30
0
 public IAlgorithmNode MakeNode(IMNodeInternal node, ForwardDelegate forwardMethod)
 {
     return new DVNode(node, forwardMethod, _queue, _tableFactory, TTL, _config);
 }
示例#31
0
        public DijkstraNode(IMNodeInternal node, IKeyTableFactory tableFactory, IAsynchQueue queue, IConfigSource config)
            : base(node, tableFactory, config)
        {
            _queue = queue;
            _distances = tableFactory.MakeKeyTable<float>();
            _wipRoute = tableFactory.MakeKeyTable<IMLink>();
            _prev = tableFactory.MakeKeyTable<DijkstraNode>();

            _confirmed = new LinkedList<DijkstraNode>();
            _tentative = new LinkedList<DijkstraNode>();
            _links = new LinkedList<IMLink>();

            SetDistanceFromRoot(ID, 0f, null, null);
        }
示例#32
0
 internal void RunAlgorithm(string description, IMNodeInternal to, bool visualise)
 {
     _visualise = visualise;
     ResetAlgorithm();
     if (_visualise && IsCurrentAlgorithm) {
         _visualiseThread = new Thread(() => RunAlgorithm(to));
         _visualiseThread.Name = description;
         _visualiseThread.Start();
     } else {
         _queue.QWork(GetType().Name + " " + description, () => RunAlgorithm(to));
     }
 }
示例#33
0
 /// <summary>
 /// Initialise the various variables, flags and collections that are used to run the algorithm.
 /// </summary>
 /// <param name="target">The target being routed to. Null means route to every target.</param>
 /// 
 /// 
 private void Init(IMNodeInternal target)
 {
     _target = _target != null && target == null ? _target : target;
     _confirmed.Clear();
     _tentative.Clear();
     _links.Clear();
     _tentative.AddFirst(this);
     foreach (DijkstraNode n in this.GetAllNodes<DijkstraNode>())
         n.SetDistanceFromRoot(ID, float.MaxValue, null, null);
     _cont = true;
 }
示例#34
0
 private void UpdateRoutes(IMNodeInternal target, IMNodeInternal hop, IMLink link, float dist)
 {
     if (target.ID.Equals(ID))
         return;
     SetRoute(DV.DV_NAME, target.ID, link, dist);
     lock (distanceVector)
         if (!distanceVector.ContainsKey(target.ID))
             distanceVector.Add(target.ID, new Distance(target, hop, link, dist));
         else
             distanceVector[target.ID].update(hop, link, dist);
 }
示例#35
0
        /// <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;
        }
示例#36
0
 public IAlgorithmNode MakeNode(IMNodeInternal node, ForwardDelegate forwardMethod)
 {
     return(new DVNode(node, forwardMethod, _queue, _tableFactory, TTL, _config));
 }
示例#37
0
        private void VisualiseAlgorithm(IMNodeInternal target, Parameters parameters)
        {
            Logger.Debug("Distance vector visualising routing for " + Node.Name + ".");

             if (target == null)
                Node.TriggerHighlightAll(DV.DV_NAME);
            else
                Node.TriggerHighlight(DV.DV_NAME, target);
        }
示例#38
0
        /// <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);
        }
        /// <summary>
        ///   What to do when a packet relevant to the highlight flooding algorithm is received
        /// 
        ///   If the node has not already received one of the highlight flooding packets flood highlight packets along all links and send a new
        ///   highlight all packet back towards the source of the received packet
        /// </summary>
        /// <param name = "packet"></param>
        public void HighlightAll(IMNodeInternal hop)
        {
            if (HighlightingAll) return;

            lock (HighlightLock) {
                _highlightedLink = ForwardingTable.ContainsKey(_globalTargetKey) ? ForwardingTable[_globalTargetKey] : null;
                _highlightState = HighlghtState.HighlightingAll;

                if (_highlightedLink != null)
                    _highlightedLink.Colour = _globalHighlightColour;

                foreach (IMLink l in _links) {
                    IMNode neighbour = l.OtherEnd(this);
                    if (!neighbour.Equals(hop))
                        neighbour.HighlightAll(this);
                }
            }
        }
示例#40
0
        private void RunAlgorithm(IMNodeInternal to)
        {
            lock (_runLock) {
                Init(to);

                if (_visualise)
                    Logger.Debug("Dijkstra visualising routing from " + Name);

                if (_cont && _text && _visualise) {
                    Say("Starting Algorithm");
                    Say("1. Initialising Confirmed and Tentative lists");
                }

                DijkstraNode current = getNext(this);
                DijkstraNode prev = current;

                if (_cont && _text && _visualise) {
                    Pause();
                    Say("3. Cost for root (" + Node.Name + ") = 0");
                    Pause();
                }

                MainLoop(current, prev);

                //If the algorithm didn't finish prematurely
                if (_cont)
                    UpdateRoutingTable();
                algorithmFinished();
            }
        }
        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;
                }
            }
        }
        /// <inhertidoc />
        public void TriggerHighlight(string alg, IMNodeInternal target)
        {
            if (Equals(_globalHighlightTarget) || Equals(_globalHighlightRoot)) {
                TriggerHighlightReset();
                return;
            }

            ClearOld();

            _globalTargetKey = target.ID;
            _globalHighlightTarget = (IMNode)target;
            _globalHighlightRoot = this;
            _globalHighlightColour = Colour;
            _globalHighlightState = HighlghtState.HighlightingSingle;
            _highlightState = HighlghtState.HighlightingSingle;

            //If there is a route
            if (ForwardingTable.ContainsKey(_globalTargetKey)) {
                lock (HighlightLock) {
                    _highlightedLink = ForwardingTable[_globalTargetKey];
                    _highlightedLink.Colour = _globalHighlightColour;
                    IMNode node = ForwardingTable[_globalTargetKey].OtherEnd(this);
                    node.Highlight(this);
                }
            } else
                _highlightedLink = 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;
        }
示例#44
0
 public IAlgorithmNode MakeNode(IMNodeInternal node, ForwardDelegate forwardMethod)
 {
     return new LinkStateNode(node, _tableFactory, _dijkstraQ, _eventQ, forwardMethod, _config);
 }