/* * public void UpdateTopology(TopologyEntry suggested, Guid guid) * { * TopologyEntry fastest; * bool changed = false; * //remove the entry * lock (tablesLock) * { * var top = TopologyTable.FirstOrDefault(t => t.Destination.Equals(suggested.Destination) && t.Neighbor.Equals(suggested.Neighbor)); * if (top != null) * TopologyTable.Remove(top); * * fastest = TopologyTable.Where(t => t.Destination.Equals(suggested.Destination))?.OrderBy(t => t.Feasible).FirstOrDefault(); * * var route = RoutingTable.FirstOrDefault(r => r.Destination.Equals(suggested.Destination)); * if (route != null && route.Neighbor.Equals(suggested.Neighbor)) * { * //update routing table too * RoutingTable.Remove(route); * changed = true; * if (fastest != null) * RoutingTable.Add(new RouteEntry(fastest.Destination, fastest.Neighbor, DateTime.Now)); * } * * // add new topology * if (suggested.Advertised < 0) * //nothing to do here * return; * } * AddTopology(suggested, guid, false); * * * if (changed) * { * List<Task> tasks = new List<Task>(); * foreach (var neighbor in NeighborhoodTable.Where(n => !n.Address.Equals(suggested.Neighbor)).ToList()) * { * Task t = new Task(() => * { * var node = Nodes.FirstOrDefault(n => (n as RouterNode).Text.Equals(neighbor.Address)) as RouterNode; * var link = Links.FirstOrDefault(l => l.ToNode.Equals(node)) as GoLabeledLink; * if (link == null) * return; * * var newSuggested = new TopologyEntry(suggested.Destination, Text, fastest.Feasible + link.UserFlags, fastest.Feasible); * lock (link.UserObject) * { * link.PenColor = Color.Yellow; * Task t1 = Task.Delay(2000); * * node.UpdateTopology(newSuggested, guid); * * t1.Wait(); * link.PenColor = Color.Black; * } * }); * t.Start(); * tasks.Add(t); * } * Task.WaitAll(tasks.ToArray()); * } * } */ public void AddNeighbor(RouterNode neighbor, int metric) { lock (tablesLock) { NeighborhoodTable.Add(new NeighborEntry(neighbor.Text, TimeSpan.FromSeconds(15), TimeSpan.Zero)); } AddTopology(new TopologyEntry(neighbor.Text, neighbor.Text, metric, 0)); }
public async Task ReceiveHello(RouterNode sender, GoLabeledLink link) { var existing = NeighborhoodTable.FirstOrDefault(n => n.Address.Equals(sender.Text)); if (existing != null) { existing.ExtendHold(); } else { AddNeighbor(sender, link.UserFlags); sender.AddNeighbor(this, link.UserFlags); await Task.Delay(200); await SendAckTo(sender, link); } }
private void RemoveMissingNeighbors(object o) { IEnumerable <NeighborEntry> list; lock (tablesLock) { list = NeighborhoodTable.Where(n => n.Hold.CompareTo(TimeSpan.Zero) < 0).ToList(); } foreach (NeighborEntry e in list) { Guid guid = Guid.NewGuid(); lock (tablesLock) { NeighborhoodTable.Remove(e); var top = TopologyTable.FirstOrDefault(t => t.Destination.Equals(e.Address) && t.Neighbor.Equals(e.Address)); if (top != null) { AddTopology(new TopologyEntry(e.Address, e.Address, -1, -1)); } } var neighbors = NeighborhoodTable.Where(n => list.FirstOrDefault(l => l.Address.Equals(n.Address)) == null).ToList(); foreach (var neighbor in neighbors) { var node = Nodes.FirstOrDefault(n => (n as RouterNode).Text.Equals(neighbor.Address)) as RouterNode; var link = Links.FirstOrDefault(l => l.ToNode.Equals(node) || l.FromNode.Equals(node)) as GoLabeledLink; if (node == null || link == null) { continue; } TopologyEntry fastest; lock (tablesLock) { fastest = TopologyTable.Where(t => t.Destination.Equals(e.Address)).OrderBy(t => t.Feasible).FirstOrDefault(); } node.AddTopology(new TopologyEntry(e.Address, Text, fastest == null ? -1 : fastest.Feasible + link.UserFlags, fastest == null ? -1 : fastest.Feasible)); } } }
public void AddTopology(TopologyEntry entry) { /* * if(entry.Feasible == -1) * { * //remove topology * lock(tablesLock) * { * var existing = TopologyTable.FirstOrDefault(t => t.Destination.Equals(entry.Destination) && t.Neighbor.Equals(entry.Neighbor)); * if(existing != null) * { * TopologyTable.Remove(existing); * UpdateRoute(entry); * } * return; * } * } */ if (entry.Destination.Equals(Text)) { return; } if (entry.Feasible != -1) { lock (tablesLock) { var fastest = TopologyTable.Where(t => t.Destination.Equals(entry.Destination))?.OrderBy(t => t.Feasible).FirstOrDefault(); if (fastest != null && entry.Advertised >= fastest.Feasible) { return; } var existing = TopologyTable.Where(t => t.Destination.Equals(entry.Destination) && t.Neighbor.Equals(entry.Neighbor) && t.Feasible == entry.Feasible).FirstOrDefault(); if (existing != null) { return; } TopologyTable.Add(entry); } } else { lock (tablesLock) { var existing = TopologyTable.FirstOrDefault(t => t.Destination.Equals(entry.Destination) && t.Neighbor.Equals(entry.Neighbor)); if (existing != null) { TopologyTable.Remove(existing); } } } UpdateRoute(entry); var neighbors = NeighborhoodTable.Where(n => !n.Address.Equals(entry.Neighbor)).ToList(); foreach (var neighbor in neighbors) { var node = Nodes.FirstOrDefault(n => (n as RouterNode).Text.Equals(neighbor.Address)) as RouterNode; var link = Links.FirstOrDefault(l => l.ToNode.Equals(node) || l.FromNode.Equals(node)) as GoLabeledLink; if (node == null || link == null) { continue; } TopologyEntry fastest; lock (tablesLock) { fastest = TopologyTable.Where(t => t.Destination.Equals(entry.Destination)).OrderBy(t => t.Feasible).FirstOrDefault(); } node.AddTopology(new TopologyEntry(entry.Destination, Text, fastest == null ? -1 : fastest.Feasible + link.UserFlags, fastest.Feasible)); } }