using System; using System.Collections.Generic; using System.Collections; using System.Security; using ln.types; using System.Linq; using System.Threading; using ln.skyscanner.crawl; using ln.snmp.rfc1213; using ln.types.odb; using ln.types.sync; using ln.logging; namespace ln.skyscanner.entities { public class GlobalNetwork : Persistent { [Unsynced] public SkyScanner SkyScanner => SkyScanner.Instance; [Unsynced] public SkyEntities SkyEntities { get; private set; } public IEnumerable Subnets => subnets; public IEnumerable Nodes => nodes; public HopMap DefaultHopMap { get; private set; } = new HopMap(); private List nodes = new List(); private List subnets = new List(); private object _updateLock = new object(); public GlobalNetwork() { } public GlobalNetwork(SkyEntities skyEntities) { SkyEntities = skyEntities; } public Node GetNode(Guid id) { //foreach (Node node in nodes) //{ // if (node.PersistenceID.Equals(persistenceID)) // return node; //} //throw new KeyNotFoundException(); return SkyEntities.nodeCollection.FindOne(n => n.ID.Equals(id)); } public Subnet FindSubnetForHost(CIDR host) { //foreach (Subnet subnet in subnets) //{ // if (subnet.Network.Contains(host.Host)) // return subnet; //} //return null; return SkyEntities.subnetCollection.FindOne(net => net.Network.Contains(host)); } public IEnumerable FindHostsInSubnet(CIDR network) { //HashSet result = new HashSet(); //foreach (Node node in nodes.ToArray()) //{ // foreach (NetworkInterface networkInterface in node.Interfaces.ToArray()) // { // foreach (CIDR ip in networkInterface.IPs) // { // if (network.Contains(ip)) // { // result.Add(node); // break; // } // } // } //} //return result; return SkyEntities.nodeCollection.Find(node => network.Contains(node.IPAdresses)); } public IEnumerable FindNeighbors(Node node) { return node.Interfaces.SelectMany((intf) => intf.IPs).SelectMany((arg) => FindHostsInSubnet(arg)).Distinct(); } public Node FindNodeByIP(IEnumerable ips) { foreach (CIDR ip in ips) { Node node = FindNodeByIP(ip); if (node != null) return node; } return null; } public Node FindNodeByIP(CIDR ip) { return SkyEntities.nodeCollection.FindOne(node => node.IPAdresses.Contains(ip) || node.PrimaryIP.Equals(ip)); } [Unsynced] private Queue updateQueue = new Queue(); public void EnqueueUpdate(CrawledHost crawledHost) { lock (updateQueue) { if (!updateQueue.Contains(crawledHost)) updateQueue.Enqueue(crawledHost); } } public void Update() { lock (updateQueue) { if (updateQueue.Count == 0) return; } while (true) { CrawledHost crawledHost = null; lock (updateQueue) { if (updateQueue.Count > 0) crawledHost = updateQueue.Dequeue(); else break; } Update(crawledHost); } //SkyScanner.Entities.DBGlobalNetwork.SavePersistent(SkyScanner.Entities.DBGlobalNetwork.Root); } private void Update(CrawledHost crawledHost) { Logging.Log(LogLevel.DEBUG, "Entity: update {0}", crawledHost.PrimaryIP); Node node = FindNodeByIP(crawledHost.PrimaryIP); if (node == null) node = FindNodeByIP(crawledHost.IPAddresses); if (node == null) { node = new Node(crawledHost.PrimaryIP); node.Name = crawledHost.Name; node.PrimaryMac = crawledHost.PrimaryHWAddr; } //foreach (String si in crawledHost.GetHint("rfc1213.interfaces",) //{ // NetworkInterface networkInterface = node.GetInterface(intf.Name); // if (networkInterface == null) // networkInterface = new NetworkInterface(node, intf.Name); // networkInterface.IPs = intf.IPAddresses.ToArray(); //} node.RemoveURI("ssh"); if (crawledHost.GetHint("ssh.port", -1) != -1) { node.AddURI( new URI( String.Format("ssh://{0}:{1}@{2}:{3}", crawledHost.GetHint("ssh.login"), crawledHost.GetHint("ssh.password"), crawledHost.GetHint("ssh.ip"), crawledHost.GetHint("ssh.port") ) ) ); } node.LastUpdate = DateTime.Now; SkyEntities.nodeCollection.Upsert(node); } } }