protected bool ShouldClose() { #endif Dictionary <Edge, bool> have_passed = new Dictionary <Edge, bool>(); Stack stack = new Stack(); stack.Push(_tunnels.GetEnumerator()); while (stack.Count > 0) { IEnumerator <Connection> cons = stack.Pop() as IEnumerator <Connection>; while (cons.MoveNext()) { TunnelEdge te = cons.Current.Edge as TunnelEdge; if (te == null) { return(false); } if (have_passed.ContainsKey(te)) { continue; } have_passed[te] = true; stack.Push(cons); cons = te.Overlap.GetEnumerator(); } } return(true); }
/// <summary>Common code to Create an outgoing edge.</summary> protected void CreateEdge(TunnelEdgeCallbackAction teca, List <Connection> overlap) { if (_connections.Contains(teca.TunnelTA.Target)) { FailedEdgeCreate(teca); return; } TunnelEdge te = null; while (true) { te = new TunnelEdge(this, (TunnelTransportAddress)_local_tas[0], teca.TunnelTA, _iasf.GetForwarderSelector(), overlap); lock (_sync) { if (!_id_to_tunnel.ContainsKey(te.LocalID)) { _id_to_tunnel[te.LocalID] = te; break; } } // Arriving here, implies another TunnelEdge will be created and this // one needs to be closed te.Close(); } te.CloseEvent += CloseHandler; teca.Success.Value = true; teca.Exception.Value = null; teca.Edge.Value = te; _node.EnqueueAction(teca); }
public void HandleRpc(ISender caller, string method, IList args, object rs) { if (method.Equals("Sync")) { TunnelEdge te = (caller as ReqrepManager.ReplyState).ReturnPath as TunnelEdge; if (te == null) { throw new Exception(String.Format( "{0} must be called from a TunnelEdge.", method)); } IDictionary dict = args[0] as IDictionary; if (dict == null) { throw new Exception(method + "\'s parameter is an IDictionary!"); } UpdateNeighborIntersection(te, dict); _node.Rpc.SendResult(rs, true); } else if (method.Equals("RequestSync")) { _node.Rpc.SendResult(rs, _ito.GetSyncMessage(null, _node.Address, _connections)); } else { throw new Exception(String.Format("No such method: {0}.", method)); } }
/// <summary>When a TunnelEdge closes, we must remove it from our /// hashtable.</summary> protected void CloseHandler(object o, EventArgs ea) { TunnelEdge te = o as TunnelEdge; lock (_sync) { _id_to_tunnel.Remove(te.LocalID); } }
public void Test() { AHAddress addr = new AHAddress(new System.Security.Cryptography.RNGCryptoServiceProvider()); TransportAddress ta = TransportAddressFactory.CreateInstance("brunet.tcp://169.0.5.1:5000"); FakeEdge fe = new FakeEdge(ta, ta); Connection fcon = new Connection(fe, addr, "structured", null, null); List <Connection> overlap = new List <Connection>(); overlap.Add(fcon); TunnelTransportAddress tta = new TunnelTransportAddress(addr, overlap); TunnelEdge te1 = new TunnelEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); Connection t1con = new Connection(te1, addr, "structured", null, null); overlap = new List <Connection>(); overlap.Add(t1con); TunnelEdge te2 = new TunnelEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); Connection t2con = new Connection(te2, addr, "structured", null, null); overlap = new List <Connection>(); overlap.Add(t2con); TunnelEdge te3 = new TunnelEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); Connection t3con = new Connection(te3, addr, "structured", null, null); overlap = new List <Connection>(); overlap.Add(t3con); TunnelEdge te4 = new TunnelEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); Connection t4con = new Connection(te4, addr, "structured", null, null); overlap = new List <Connection>(); overlap.Add(t4con); TunnelEdge te5 = new TunnelEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); Connection t5con = new Connection(te5, addr, "structured", null, null); Assert.AreEqual(te5.ShouldClose(), false, "Shouldn't close yet..."); te1.DisconnectionHandler(fcon); Assert.AreEqual(te5.ShouldClose(), true, "Should close..."); overlap.Add(t5con); overlap.Add(t3con); overlap.Add(t1con); te2.UpdateNeighborIntersection(overlap); Assert.AreEqual(te5.ShouldClose(), true, "Should close... 2"); }
/// <summary>Used to send data over the tunnel via forwarding senders /// using a randomly selected peer from our overlap list.</summary> public void HandleEdgeSend(Edge from, ICopyable data) { TunnelEdge te = from as TunnelEdge; Connection forwarder = te.NextForwarder; if (te.RemoteID == -1) { Address target = (te.RemoteTA as TunnelTransportAddress).Target; ISender sender = new ForwardingSender(_node, forwarder.Address, target); sender.Send(new CopyList(PType.Protocol.Tunneling, te.MId, data)); } else { try { forwarder.Edge.Send(new CopyList(te.Header, te.MId, data)); } catch { // We could be sending aon a closed edge... we could deal with this // better, but let's just let the system take its natural course. } } }
/// <summary>Where data packets prepended with a tunnel come. Here we /// receive data as well as create new TunnelEdges.</summary> public void HandleData(MemBlock data, ISender return_path, object state) { AHSender ah_from = return_path as AHSender; ForwardingSender fs_from = return_path as ForwardingSender; AHAddress target = null; if (ah_from == null) { if (fs_from == null) { return; } target = (AHAddress)fs_from.Destination; } else { target = (AHAddress)ah_from.Destination; } int remote_id = NumberSerializer.ReadInt(data, 0); int local_id = NumberSerializer.ReadInt(data, 4); TunnelEdge te = null; // No locally assigned ID, so we'll create a new TunnelEdge and assign it one. // This could be hit many times by the same RemoteID, but it is safe since // we'll attempt Linkers on all of them and he'll only respond to the first // one he receives back. if (local_id == -1) { if (fs_from == null) { throw new Exception("No LocalID assigned but not from a useful sender!"); } ConnectionList cons = _connections; int index = cons.IndexOf(fs_from.Forwarder); if (index < 0) { return; } List <Connection> overlap_addrs = new List <Connection>(); overlap_addrs.Add(cons[index]); while (true) { te = new TunnelEdge(this, (TunnelTransportAddress)_local_tas[0], new TunnelTransportAddress(target, overlap_addrs), _iasf.GetForwarderSelector(), overlap_addrs, remote_id); lock (_sync) { if (!_id_to_tunnel.ContainsKey(te.LocalID)) { _id_to_tunnel[te.LocalID] = te; break; } } // Arriving here, implies another TunnelEdge will be created and this // one needs to be closed te.Close(); } local_id = te.LocalID; te.CloseEvent += CloseHandler; SendEdgeEvent(te); } if (!_id_to_tunnel.TryGetValue(local_id, out te)) { // Maybe we closed this edge // throw new Exception("No such edge"); // Old behavior would ignore these packets... return; } else if (te.RemoteID == -1) { // We created this, but we haven't received a packet yet te.RemoteID = remote_id; } else if (te.RemoteID != remote_id) { // Either we closed this edge and it was reallocated or something is up! // throw new Exception("Receiving imposter packet..."); // Old behavior would ignore these packets... return; } if (te.IsClosed) { throw new Exception("Edge is closed..."); } // Chop off the Ids data = data.Slice(8); te.ReceivedPacketEvent(data); }
/// <summary>Whenever the node receives a new StatusMessage from a tunnel, /// we use this to build a consisting of the intersection of our peers /// creating a table of potential tunneling options. We close the edge if /// it is empty.</summary> protected void UpdateNeighborIntersection(TunnelEdge from, IDictionary msg) { List <Connection> overlap = _ito.EvaluateOverlap(_connections, msg); from.UpdateNeighborIntersection(overlap); }
public void Test() { AHAddress addr = new AHAddress(new System.Security.Cryptography.RNGCryptoServiceProvider()); TransportAddress ta = TransportAddressFactory.CreateInstance("brunet.tcp://169.0.5.1:5000"); FakeEdge fe = new FakeEdge(ta, ta); Connection fcon = new Connection(fe, addr, "structured", null, null); List<Connection> overlap = new List<Connection>(); overlap.Add(fcon); TunnelTransportAddress tta = new TunnelTransportAddress(addr, overlap); TunnelEdge te1 = new TunnelEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); Connection t1con = new Connection(te1, addr, "structured", null, null); overlap = new List<Connection>(); overlap.Add(t1con); TunnelEdge te2 = new TunnelEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); Connection t2con = new Connection(te2, addr, "structured", null, null); overlap = new List<Connection>(); overlap.Add(t2con); TunnelEdge te3 = new TunnelEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); Connection t3con = new Connection(te3, addr, "structured", null, null); overlap = new List<Connection>(); overlap.Add(t3con); TunnelEdge te4 = new TunnelEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); Connection t4con = new Connection(te4, addr, "structured", null, null); overlap = new List<Connection>(); overlap.Add(t4con); TunnelEdge te5 = new TunnelEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); Connection t5con = new Connection(te5, addr, "structured", null, null); Assert.AreEqual(te5.ShouldClose(), false, "Shouldn't close yet..."); te1.DisconnectionHandler(fcon); Assert.AreEqual(te5.ShouldClose(), true, "Should close..."); overlap.Add(t5con); overlap.Add(t3con); overlap.Add(t1con); te2.UpdateNeighborIntersection(overlap); Assert.AreEqual(te5.ShouldClose(), true, "Should close... 2"); }