public void HandleEdgeSend(Edge from, BU.ICopyable p) { FunctionEdgeListener el = null; FunctionEdge fe_from = (FunctionEdge)from; FunctionEdge fe_to = fe_from.Partner; if (fe_to != null) { el = (FunctionEdgeListener)_listener_map[fe_to.ListenerId]; try { el._queue.Enqueue(new FQEntry(fe_to, p)); } catch (System.InvalidOperationException) { //The queue other queue is closed: //Just throw the packet away. This simulates UDP, which is giving less information //to the local node. } } }
protected void StartQueueProcessing() { /* * Simulate packet loss */ Random r = new Random(); try { bool timedout; while (1 == _is_started) { FQEntry ent = (FQEntry)_queue.Dequeue(-1, out timedout); if (r.NextDouble() > _ploss_prob) { //Stop in this case if (ent.P == null) { return; } FunctionEdge fe = ent.Edge; BU.MemBlock data_to_send = ent.P as BU.MemBlock; if (data_to_send == null) { data_to_send = BU.MemBlock.Copy(ent.P); } try { fe.ReceivedPacketEvent(data_to_send); } catch (EdgeClosedException) { //The edge may have closed, just ignore it } } } } catch (InvalidOperationException) { // The queue has been closed } }
public FQEntry(FunctionEdge e, BU.ICopyable p) { Edge = e; P = p; }
/* * Implements the EdgeListener function to * create edges of this type. */ public override void CreateEdgeTo(TransportAddress ta, EdgeCreationCallback ecb) { if (!IsStarted) { // it should return null and not throw an exception // for graceful disconnect and preventing others to // connect to us after we've disconnected. ecb(false, null, new EdgeException("Not started")); return; } #if FUNCTION_DEBUG foreach (TransportAddress local_ta in LocalTAs) { Console.Error.WriteLine("Create edge local: {0} <-> remote {1}.", local_ta, ta); } #endif if (ta.TransportAddressType != this.TAType) { //Can't make an edge of this type #if FUNCTION_DEBUG Console.Error.WriteLine("Can't make edge of this type."); #endif ecb(false, null, new EdgeException("Can't make edge of this type")); return; } if (_ta_auth.Authorize(ta) == TAAuthorizer.Decision.Deny) { //Not authorized. Can't make this edge: #if FUNCTION_DEBUG Console.Error.WriteLine("Can't make edge. Remote TA {0} is not authorized locally.", ta); #endif ecb(false, null, new EdgeException(ta.ToString() + " is not authorized")); return; } int remote_id = ((IPTransportAddress)ta).Port; //Get the edgelistener: //Outbound edge: FunctionEdge fe_l = new FunctionEdge(this, _listener_id, remote_id, false); lock ( _listener_map ) { FunctionEdgeListener remote = (FunctionEdgeListener)_listener_map[remote_id]; if (remote != null) { // // Make sure that the remote listener does not deny // our TAs. // foreach (TransportAddress ta_local in LocalTAs) { if (remote.TAAuth.Authorize(ta_local) == TAAuthorizer.Decision.Deny) { //Not authorized. Can't make this edge: #if FUNCTION_DEBUG Console.Error.WriteLine("Can't make edge. local TA {0} is not authorized remotely by {1}.", ta_local, ta); #endif ecb(false, null, new EdgeException(ta_local.ToString() + " is not authorized by remote node.")); return; } } FunctionEdge fe_r = new FunctionEdge(remote, remote_id, _listener_id, true); fe_l.Partner = fe_r; fe_r.Partner = fe_l; remote.SendEdgeEvent(fe_r); } else { //There is no other edge, for now, we use "udp-like" //behavior of just making an edge that goes nowhere. } ecb(true, fe_l, null); } }