/// <summary>Common code to Create an outgoing edge.</summary> protected void CreateEdge(RelayEdgeCallbackAction teca, List <Connection> overlap) { if (_connections.Contains(teca.RelayTA.Target)) { FailedEdgeCreate(teca); return; } RelayEdge te = null; while (true) { te = new RelayEdge(this, (RelayTransportAddress)_local_tas[0], teca.RelayTA, _iasf.GetForwarderSelector(), overlap); lock (_sync) { if (!_id_to_tunnel.ContainsKey(te.LocalID)) { _id_to_tunnel[te.LocalID] = te; break; } } // Arriving here, implies another RelayEdge 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")) { RelayEdge te = (caller as ReqrepManager.ReplyState).ReturnPath as RelayEdge; if (te == null) { throw new Exception(String.Format( "{0} must be called from a RelayEdge.", 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 RelayEdge closes, we must remove it from our /// hashtable.</summary> protected void CloseHandler(object o, EventArgs ea) { RelayEdge te = o as RelayEdge; lock (_sync) { _id_to_tunnel.Remove(te.LocalID); } }
public void WrapperEdgeRegressionTest() { 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); WrapperEdge we_fe = new WrapperEdge(fe); Connection fcon = new Connection(we_fe, addr, "structured", null, null); List <Connection> overlap = new List <Connection>(); overlap.Add(fcon); RelayTransportAddress tta = new RelayTransportAddress(addr, overlap); RelayEdge te1 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); WrapperEdge we_te1 = new WrapperEdge(te1); Connection t1con = new Connection(we_te1, addr, "structured", null, null); overlap = new List <Connection>(); overlap.Add(t1con); RelayEdge te2 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); WrapperEdge we_te2 = new WrapperEdge(te2); Connection t2con = new Connection(we_te2, addr, "structured", null, null); overlap = new List <Connection>(); overlap.Add(t2con); RelayEdge te3 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); WrapperEdge we_te3 = new WrapperEdge(te3); Connection t3con = new Connection(we_te3, addr, "structured", null, null); overlap = new List <Connection>(); overlap.Add(t3con); RelayEdge te4 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); WrapperEdge we_te4 = new WrapperEdge(te4); Connection t4con = new Connection(we_te4, addr, "structured", null, null); overlap = new List <Connection>(); overlap.Add(t4con); RelayEdge te5 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); WrapperEdge we_te5 = new WrapperEdge(te5); Connection t5con = new Connection(we_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) { RelayEdge te = from as RelayEdge; Connection forwarder = te.NextForwarder; if (te.RemoteID == -1) { Address target = (te.RemoteTA as RelayTransportAddress).Target; ISender sender = new ForwardingSender(_node, forwarder.Address, target); sender.Send(new CopyList(PType.Protocol.Relaying, 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. } } }
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()) { RelayEdge re = cons.Current.Edge as RelayEdge; if (re == null) { var we = cons.Current.Edge as WrapperEdge; if (we != null) { re = we.WrappedEdge as RelayEdge; } if (re == null) { return(false); } } if (have_passed.ContainsKey(re)) { continue; } have_passed[re] = true; stack.Push(cons); cons = re.Overlap.GetEnumerator(); } } return(true); }
public void WrapperEdgeRegressionTest() { 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); WrapperEdge we_fe = new WrapperEdge(fe); Connection fcon = new Connection(we_fe, addr, "structured", null, null); List<Connection> overlap = new List<Connection>(); overlap.Add(fcon); RelayTransportAddress tta = new RelayTransportAddress(addr, overlap); RelayEdge te1 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); WrapperEdge we_te1 = new WrapperEdge(te1); Connection t1con = new Connection(we_te1, addr, "structured", null, null); overlap = new List<Connection>(); overlap.Add(t1con); RelayEdge te2 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); WrapperEdge we_te2 = new WrapperEdge(te2); Connection t2con = new Connection(we_te2, addr, "structured", null, null); overlap = new List<Connection>(); overlap.Add(t2con); RelayEdge te3 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); WrapperEdge we_te3 = new WrapperEdge(te3); Connection t3con = new Connection(we_te3, addr, "structured", null, null); overlap = new List<Connection>(); overlap.Add(t3con); RelayEdge te4 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); WrapperEdge we_te4 = new WrapperEdge(te4); Connection t4con = new Connection(we_te4, addr, "structured", null, null); overlap = new List<Connection>(); overlap.Add(t4con); RelayEdge te5 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap); WrapperEdge we_te5 = new WrapperEdge(te5); Connection t5con = new Connection(we_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>Where data packets prepended with a tunnel come. Here we /// receive data as well as create new RelayEdges.</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); RelayEdge te = null; // No locally assigned ID, so we'll create a new RelayEdge 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 RelayEdge(this, (RelayTransportAddress) _local_tas[0], new RelayTransportAddress(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 RelayEdge 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(RelayEdge from, IDictionary msg) { List<Connection> overlap = _ito.EvaluateOverlap(_connections, msg); from.UpdateNeighborIntersection(overlap); }
/// <summary>Common code to Create an outgoing edge.</summary> protected void CreateEdge(RelayEdgeCallbackAction teca, List<Connection> overlap) { if(_connections.Contains(teca.RelayTA.Target)) { FailedEdgeCreate(teca); return; } RelayEdge te = null; while(true) { te = new RelayEdge(this, (RelayTransportAddress) _local_tas[0], teca.RelayTA, _iasf.GetForwarderSelector(), overlap); lock(_sync) { if(!_id_to_tunnel.ContainsKey(te.LocalID)) { _id_to_tunnel[te.LocalID] = te; break; } } // Arriving here, implies another RelayEdge 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); }
/// <summary>Where data packets prepended with a tunnel come. Here we /// receive data as well as create new RelayEdges.</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); RelayEdge te = null; // No locally assigned ID, so we'll create a new RelayEdge 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 RelayEdge(this, (RelayTransportAddress)_local_tas[0], new RelayTransportAddress(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 RelayEdge 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(RelayEdge from, IDictionary msg) { List <Connection> overlap = _ito.EvaluateOverlap(_connections, msg); from.UpdateNeighborIntersection(overlap); }