using System; using System.Collections.Generic; using System.Linq; using System.Text; using Hermes.Objects; namespace Hermes.Selectors { class UniqueHighestSpeedTwoNodeSelector : UniqueRouteSelector, IRouteSelector { public UniqueHighestSpeedTwoNodeSelector() : base() {} #region IRouteSelector Members public Circuit CreateNewCircuit() { Random rand = new Random(); Circuit circuit = new Circuit(); GetPoolReaderLock(); { lock (UsedRouters) { //Try to use unused routers IEnumerable nonExits = RouterPool.Where(p => !p.Flags.Contains("Exit") && !UsedRouters.Contains(p)); if (nonExits.Count() == 0) { nonExits = RouterPool.Where(p => !p.Flags.Contains("Exit")); circuit.AddNextRouter(nonExits.ElementAt(rand.Next(nonExits.Count()))); } else circuit.AddNextRouter(nonExits.OrderByDescending(p => p.BandwidthObserved).First()); IEnumerable exits = RouterPool.Where(p => p.Flags.Contains("Exit") && !UsedRouters.Contains(p)); if (exits.Count() == 0) { exits = RouterPool.Where(p => p.Flags.Contains("Exit")); circuit.AddNextRouter(exits.ElementAt(rand.Next(exits.Count()))); } else circuit.AddNextRouter(exits.OrderByDescending(p => p.BandwidthObserved).First()); UsedRouters.AddRange(circuit.Routers.Values.ToList()); } } ReleasePoolReaderLock(); return circuit; } public Circuit CreateNewCircuit(System.Net.IPEndPoint destination) { Random rand = new Random(); Circuit circuit = new Circuit(); GetPoolReaderLock(); { lock (UsedRouters) { //Try to use unused routers IEnumerable nonExits = RouterPool.Where(p => !p.Flags.Contains("Exit") && !UsedRouters.Contains(p)); if (nonExits.Count() == 0) { nonExits = RouterPool.Where(p => !p.Flags.Contains("Exit")); circuit.AddNextRouter(nonExits.ElementAt(rand.Next(nonExits.Count()))); } else circuit.AddNextRouter(nonExits.OrderByDescending(p => p.BandwidthObserved).First()); IEnumerable exits = RouterPool.Where(p => p.Flags.Contains("Exit") && p.ExitPolicy != null && p.ExitPolicy.IsAcceptableDestination(destination) && !UsedRouters.Contains(p)); if (exits.Count() == 0) { exits = RouterPool.Where(p => p.Flags.Contains("Exit") && p.ExitPolicy != null && p.ExitPolicy.IsAcceptableDestination(destination)); circuit.AddNextRouter(exits.ElementAt(rand.Next(exits.Count()))); } else circuit.AddNextRouter(exits.OrderByDescending(p => p.BandwidthObserved).First()); UsedRouters.AddRange(circuit.Routers.Values.ToList()); } } ReleasePoolReaderLock(); return circuit; } #endregion } }