/// <summary>Common code to signify the failure of edge creation.</summary> protected void FailedEdgeCreate(TunnelEdgeCallbackAction teca) { teca.Success.Value = false; teca.Exception.Value = new Exception("Not enough forwarders!"); teca.Edge.Value = null; _node.EnqueueAction(teca); }
/// <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); }
/// <summary>First we try to find a third party we can connect with for /// overlap, if that is successful, we attempt to connect to him, if that /// is successful, we create a new tunnel edge.</summary> protected void AttemptToCreateOverlap(TunnelEdgeCallbackAction teca) { WaitCallback create_connection = delegate(object o) { Address target = o as Address; if (o == null) { FailedEdgeCreate(teca); return; } ConnectionList cons = _connections; int index = cons.IndexOf(target); if (index < 0) { FailedEdgeCreate(teca); return; } List <Connection> overlap = new List <Connection>(1); overlap.Add(cons[index]); CreateEdge(teca, overlap); }; Channel chan = new Channel(1); chan.CloseEvent += delegate(object o, EventArgs ea) { Address target = null; try { IDictionary msg = (chan.Dequeue() as RpcResult).Result as IDictionary; target = _ito.EvaluatePotentialOverlap(msg); } catch { } if (target == null) { FailedEdgeCreate(teca); } else { _oco.ConnectTo(target, create_connection); } }; ISender s = new AHExactSender(_node, teca.TunnelTA.Target); _node.Rpc.Invoke(s, chan, "tunnel.RequestSync"); }
/// <summary>Does not immediately create an edge to a remote node, instead, /// it tells a timer to wait 5 seconds prior to attempting an edge.</summary> public override void CreateEdgeTo(TransportAddress ta, EdgeCreationCallback ecb) { TunnelTransportAddress tta = ta as TunnelTransportAddress; if (tta == null) { ecb(false, null, new Exception("TA Type is not Tunnel!")); } else { TunnelEdgeCallbackAction teca = new TunnelEdgeCallbackAction(tta, ecb); System.Action <DateTime> callback = delegate(DateTime now) { CreateEdgeTo(teca); }; Brunet.Util.FuzzyTimer.Instance.DoAfter(callback, 10000, 0); } }
/// <summary>The delayed callback for CreateEdgeTo, we create an edge if /// there is a potential non-tunnel overlap and allow the Linker to do the /// rest.</summary> protected void CreateEdgeTo(TunnelEdgeCallbackAction teca) { ConnectionList cons = _connections; List <Connection> overlap = _ito.FindOverlap(teca.TunnelTA, cons); if (overlap.Count == 0) { if (_ito == null) { FailedEdgeCreate(teca); } else { AttemptToCreateOverlap(teca); } return; } CreateEdge(teca, overlap); }
/// <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); }
/// <summary>First we try to find a third party we can connect with for /// overlap, if that is successful, we attempt to connect to him, if that /// is successful, we create a new tunnel edge.</summary> protected void AttemptToCreateOverlap(TunnelEdgeCallbackAction teca) { WaitCallback create_connection = delegate(object o) { Address target = o as Address; if(o == null) { FailedEdgeCreate(teca); return; } ConnectionList cons = _connections; int index = cons.IndexOf(target); if(index < 0) { FailedEdgeCreate(teca); return; } List<Connection> overlap = new List<Connection>(1); overlap.Add(cons[index]); CreateEdge(teca, overlap); }; Channel chan = new Channel(1); chan.CloseEvent += delegate(object o, EventArgs ea) { Address target = null; try { IDictionary msg = (chan.Dequeue() as RpcResult).Result as IDictionary; target = _ito.EvaluatePotentialOverlap(msg); } catch { } if(target == null) { FailedEdgeCreate(teca); } else { _oco.ConnectTo(target, create_connection); } }; ISender s = new AHExactSender(_node, teca.TunnelTA.Target); _node.Rpc.Invoke(s, chan, "tunnel.RequestSync"); }
/// <summary>The delayed callback for CreateEdgeTo, we create an edge if /// there is a potential non-tunnel overlap and allow the Linker to do the /// rest.</summary> protected void CreateEdgeTo(TunnelEdgeCallbackAction teca) { ConnectionList cons = _connections; List<Connection> overlap = _ito.FindOverlap(teca.TunnelTA, cons); if(overlap.Count == 0) { if(_ito == null) { FailedEdgeCreate(teca); } else { AttemptToCreateOverlap(teca); } return; } CreateEdge(teca, overlap); }
/// <summary>Does not immediately create an edge to a remote node, instead, /// it tells a timer to wait 5 seconds prior to attempting an edge.</summary> public override void CreateEdgeTo(TransportAddress ta, EdgeCreationCallback ecb) { TunnelTransportAddress tta = ta as TunnelTransportAddress; if(tta == null) { ecb(false, null, new Exception("TA Type is not Tunnel!")); } else { TunnelEdgeCallbackAction teca = new TunnelEdgeCallbackAction(tta, ecb); System.Action<DateTime> callback = delegate(DateTime now) { CreateEdgeTo(teca); }; Brunet.Util.FuzzyTimer.Instance.DoAfter(callback, 10000, 0); } }