/// <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>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); }