200 lines
5.3 KiB
C#
200 lines
5.3 KiB
C#
// /**
|
|
// * 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 ln.types.odb;
|
|
using System.Linq;
|
|
using ln.types.btree;
|
|
using ln.types.net;
|
|
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<Node, HopNode> hopNodes = new BTree<Node, HopNode>(CompareNodes);
|
|
|
|
private HashSet<Network4> networks = new HashSet<Network4>();
|
|
|
|
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
|
|
{
|
|
public HopMap HopMap { get; }
|
|
public HopNode Parent { get; private set; }
|
|
|
|
public Node Node;
|
|
|
|
public HopNode[] Peers => peers.ToArray();
|
|
private HashSet<HopNode> peers = new HashSet<HopNode>();
|
|
|
|
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<IPv4> _path()
|
|
{
|
|
if (Parent == null)
|
|
return new List<IPv4>(new IPv4[] { Node.PrimaryIP });
|
|
List<IPv4> l = Parent._path();
|
|
l.Add(Node.PrimaryIP);
|
|
return l;
|
|
}
|
|
|
|
}
|
|
|
|
private static int CompareNodes(Node a, Node b)
|
|
{
|
|
return a.ID.CompareTo(b.ID);
|
|
}
|
|
|
|
}
|
|
}
|