// /** // * File: HopMap.cs // * Author: haraldwolff // * // * This file and it's content is copyrighted by the Author and / or copyright holder. // * Any use wihtout proper permission is illegal and may lead to legal actions. // * // * // **/ using System; using System.Collections.Generic; using System.Collections; using Castle.Core.Logging; using ln.types.odb; using System.Linq; using ln.types.btree; using Castle.Components.DictionaryAdapter.Xml; using Newtonsoft.Json; using ln.types.net; using System.Net.Sockets; namespace ln.skyscanner.entities { public class HopMap : Persistent { public Node TopNode { get; private set; } public GlobalNetwork GlobalNetwork => SkyScanner.Instance.Entities.GlobalNetwork; public int MaxDepth { get; set; } = 16; private BTree hopNodes = new BTree(CompareNodes); private HashSet networks = new HashSet(); public HopMap() { } public HopMap(Node node) { Reset(node); } public void Reset(Node node) { hopNodes.Clear(); TopNode = node; HopNode hopNode = new HopNode(this, node); } public int GetHopCount(Node node) { if (!hopNodes.ContainsKey(node)) return -1; return hopNodes[node].HopCount; } public HopNode[] HopNodes { get { return hopNodes.Values.ToArray(); } } public class HopNode : IComparable { [JsonIgnore] public HopMap HopMap { get; } [JsonIgnore] public HopNode Parent { get; private set; } public Node Node; [JsonIgnore] public HopNode[] Peers => peers.ToArray(); private HashSet peers = new HashSet(); private int hopCount = 0; public HopNode(HopMap hopMap, Node node) { HopMap = hopMap; Node = node; HopMap.hopNodes.Add(node, this); FindPeers(); } public HopNode(HopNode parent, Node node) { HopMap = parent.HopMap; Node = node; Attach(parent); FindPeers(); } private void FindPeers() { foreach (Network4 network in Node.Networks) { EnsureNetwork(network); } EnsureNetwork(HopMap.GlobalNetwork.FindSubnetForIP(Node.PrimaryIP).Network); } private void EnsureNetwork(Network4 network) { if (!HopMap.networks.Contains(network)) { HopMap.networks.Add(network); FindPeers(network); } } private void FindPeers(Network4 network) { foreach (Node peerNode in HopMap.GlobalNetwork.FindHostsInSubnet(network)) { if (!HopMap.hopNodes.ContainsKey(peerNode)) { new HopNode(this, peerNode); } else { HopNode existingHopNode = HopMap.hopNodes[peerNode]; if (existingHopNode.HopCount > (HopCount + 1)) { existingHopNode.Detach(); existingHopNode.Attach(this); } } } } public int HopCount { get => hopCount; set { hopCount = value; foreach (HopNode peer in peers) { peer.HopCount = hopCount + 1; } } } public void Attach(HopNode parent) { Detach(); Parent = parent; if (!Object.ReferenceEquals(null, Parent)) { HopMap.hopNodes.Add(this.Node, this); Parent.peers.Add(this); HopCount = parent.hopCount + 1; } else { HopCount = 0; } } public void Detach() { if (!Object.ReferenceEquals(null, Parent)) { Parent.peers.Remove(this); Parent = null; HopMap.hopNodes.Remove(this.Node); } } public int CompareTo(object obj) { if (obj is HopNode) { HopNode you = obj as HopNode; return Node.ID.CompareTo(you.Node.ID); } return this.GetHashCode() - obj.GetHashCode(); } public IPv4[] Path => _path().ToArray(); private List _path() { if (Parent == null) return new List(new IPv4[] { Node.PrimaryIP }); List l = Parent._path(); l.Add(Node.PrimaryIP); return l; } } private static int CompareNodes(Node a, Node b) { return a.ID.CompareTo(b.ID); } } }