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