Example #1
0
        /**
         * @param e Edge to close
         * @param cm message to send to other node
         * This method is used if we want to use a particular CloseMessage
         * If not, we can use the method with the same name with one fewer
         * parameters
         */
        public void GracefullyClose(Edge e, string message)
        {
            /**
             * Close any connection on this edge, and
             * put the edge into the list of unconnected edges
             */
            _connection_table.Disconnect(e);

            ListDictionary close_info = new ListDictionary();
            string         reason     = message;

            if (reason != String.Empty)
            {
                close_info["reason"] = reason;
            }
            ProtocolLog.WriteIf(ProtocolLog.EdgeClose, String.Format(
                                    "GracefulCLose - " + e + ": " + reason));

            var          results  = new BCon.Channel(1);
            EventHandler close_eh = delegate(object o, EventArgs args) {
                e.Close();
            };

            results.CloseEvent += close_eh;
            try {
                _rpc.Invoke(e, results, "sys:link.Close", close_info);
            }
            catch { Close(e); }
        }
Example #2
0
        /*
         * Start sending packets
         */
        public void Run()
        {
            byte[] buf     = new byte[UInt16.MaxValue];
            Random ran_obj = new Random();

            for (int counter = 0; counter < count; counter++)
            {
                try {
                    int size = ran_obj.Next(4, Int16.MaxValue);
                    ran_obj.NextBytes(buf);
                    NumberSerializer.WriteInt(counter, buf, 0);
                    MemBlock cp = MemBlock.Copy(buf, 0, Math.Max(4, counter));
                    lock (_sync) { _sent_blocks[cp] = counter; }
                    _e.Send(cp);
                    Thread.Sleep(10);
                    Console.WriteLine("Sending Packet #: " + counter);
                }
                catch (Exception x) {
                    Console.WriteLine("send: {0} caused exception: {1}", counter, x);
                    break;
                }
            }
            //Let all the responses get back
            Thread.Sleep(5000);
            Check();
            _e.Close();
        }
Example #3
0
 protected void Close(Edge e)
 {
     try {
         //This can throw an exception if the _packet_queue is closed
         EnqueueAction(new EdgeCloseAction(e));
     }
     catch {
         e.Close();
     }
 }
Example #4
0
 public override bool Close()
 {
     if (Interlocked.Exchange(ref _weclosed, 1) == 1)
     {
         return(false);
     }
     base.Close();
     _edge.Close();
     return(true);
 }
Example #5
0
        public void CreationCallback(bool success, Edge e, Exception x)
        {
            if (!success && _edge != null)
            {
                _edge.Close();
            }
            if (System.Threading.Interlocked.Exchange(ref _called, 1) == 1)
            {
                return;
            }

            ExternalECB(success, e, x);
        }
Example #6
0
        /*** Gracefully close this connection, if it is not already disconnected.
         * Idempotent (calling it twice is the same as once).
         * @return the old state, new state pair.
         */
        public Pair <ConnectionState, ConnectionState> Close(RpcManager rpc, string reason)
        {
            var old_new = Abort();

            if (old_new.First.Disconnected != true)
            {
                //Now try to tell the other node:
                var close_info = new ListDictionary();
                if (reason != String.Empty)
                {
                    close_info["reason"] = reason;
                }
                Edge e       = old_new.Second.Edge;
                var  results = new Channel(1);
                //Either the RPC call times out, or we get a response.
                results.CloseEvent += delegate(object o, EventArgs args) {
                    e.Close();
                };
                try { rpc.Invoke(e, results, "sys:link.Close", close_info); }
                catch { e.Close(); }
            }
            return(old_new);
        }
Example #7
0
        /**
         * This Handler should be connected to incoming EdgeEvent
         * events.  If it is not, it cannot hear the new edges.
         *
         * When a new edge is created, we make sure we can hear
         * the packets from it.  Also, we make sure we can hear
         * the CloseEvent.
         *
         * @param edge the new Edge
         */
        protected void EdgeHandler(object edge, EventArgs args)
        {
            Edge e = (Edge)edge;

            try {
                _connection_table.AddUnconnected(e);
                e.Subscribe(this, e);
            }
            catch (TableClosedException) {
                /*
                 * Close this edge immediately, before any packets
                 * have a chance to be received.  We are shutting down,
                 * and it is best that we stop getting new packets
                 */
                e.Close();
            }
        }
Example #8
0
        /** Watch this incoming Edge
         */
        protected void HandleEdge(object newedge, System.EventArgs args)
        {
            Edge e = (Edge)newedge;

            try {
                e.CloseEvent += this.HandleEdgeClose;
                e.Subscribe(this, null);
                lock ( _sync ) {
                    _edges.Add(e);
                }
            }
            catch (Exception x) {
                //Didn't work out, make sure the edges is closed
                Console.WriteLine("Closing ({0}) due to: {1}", e, x);
                e.Close();
            }
        }
        ///<summary>When a SecurityAssociation changes amongst inactive, active,
        ///or closed this gets notified.</summary>
        protected void AnnounceSA(SecurityAssociation sa,
                                  SecurityAssociation.States state)
        {
            Edge e = sa.Sender as Edge;

            // if e is an edge, let's see if he's creating a SE
            // or maybe it isn't our edge!
            if (e == null)
            {
                return;
            }
            else if (e.TAType != this.TAType)
            {
                return;
            }

            if (state == SecurityAssociation.States.Active)
            {
                SecurityAssociation stored_sa = null;
                if (!RemoveFromDictionary(e, out stored_sa))
                {
                    // May have already been here
                    return;
                }
                else if (stored_sa != null && stored_sa != sa)
                {
                    throw new Exception("Cannot have the same edge used in multiple SAs");
                }

                SecureEdge se = new SecureEdge(e, sa);
                sa.Subscribe(se, null);
                try {
                    Finalize(se);
                } catch {
                    se.Close();
                }
            }
            else if (state == SecurityAssociation.States.Closed)
            {
                e.Close();
            }
        }
Example #10
0
        ///<summary>When a SecurityAssociation changes amongst inactive, active,
        ///or closed this gets notified.</summary>
        protected void AnnounceSA(object o, EventArgs ea)
        {
            SecurityAssociation sa = o as SecurityAssociation;

            if (sa == null)
            {
                throw new Exception("Needs to be a SecurityAssociation");
            }

            Edge e = sa.Sender as Edge;

            // if e is an edge, let's see if he's creating a SE
            // or maybe it isn't our edge!
            if (e == null)
            {
                return;
            }
            else if (e.TAType != this.TAType)
            {
                return;
            }

            if (sa.Active)
            {
                SecureEdge se = new SecureEdge(e, sa);
                sa.Subscribe(se, null);
                try {
                    Finalize(se);
                } catch {
                    se.Close();
                }
            }
            else
            {
                e.Close();
            }
        }
Example #11
0
 public void Start()
 {
     EdgeToClose.Close();
 }
Example #12
0
        /**
         * There are only four ways we can get here:
         *
         * 1) We got some exception in Start and never made the first request
         * 2) There was some problem in LinkCloseHandler
         * 3) We either got a response or had a problem in StatusCloseHandler
         * 4) The Edge closed, and the CloseHandler was called.
         *
         * The only possibility for a race is between the CloseHandler and
         * the others.
         *
         * When this state machine reaches an end point, it calls this method,
         * which fires the FinishEvent
         */
        protected void Finish(Result res)
        {
            /*
             * No matter what, we are done here:
             */
            if (ProtocolLog.LinkDebug.Enabled)
            {
                string    message;
                Exception x;
                if (_x.TryGet(out x))
                {
                    message = String.Format(
                        "LPS: {0} finished: {2}, with exception: {1}",
                        _node.Address, x, res);
                }
                else
                {
                    message = String.Format("LPS: {0} finished: {1}",
                                            _node.Address, res);
                }
                ProtocolLog.Write(ProtocolLog.LinkDebug, message);
            }

            int already_finished = Interlocked.Exchange(ref _is_finished, 1);

            if (already_finished == 1)
            {
                //We already got here.
                //This is a barrier.  Only one Finish call will make
                //it past this point.  Only two could happen in a race:
                //Edge closing or some other failure/success.
                return;
            }
            //We don't care about close event's anymore
            _e.CloseEvent -= this.CloseHandler;

            //Set the result:
            _result = res;

            try {
                //Check to see if we need to close the edge
                if (_con.IsSet == false)
                {
                    /*
                     * We didn't get a complete connection,
                     * but we may have heard some response.  If so
                     * close the edge gracefully.
                     */
                    if (LinkMessageReply != null)
                    {
                        //Let's be nice:
                        _node.GracefullyClose(_e, "From LPS, did not complete a connection.");
                    }
                    else
                    {
                        /*
                         * We never heard from the other side, so we will assume that further
                         * packets will only waste bandwidth
                         */
                        _e.Close();
                    }
                    if (ProtocolLog.LinkDebug.Enabled)
                    {
                        ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                              "LPS: {0} got no connection", _node.Address));
                    }
                }
                else
                {
                    if (ProtocolLog.LinkDebug.Enabled)
                    {
                        ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                              "LPS: {0} got connection: {1}", _node.Address, _con.Value));
                    }
                }
                //This could throw an exception, but make sure we unlock if it does.
                FireFinished();
            }
            finally {
                /**
                 * We have to make sure the lock is eventually released:
                 */
                this.Unlock();
            }
        }
Example #13
0
 public override bool Close()
 {
     _e.Close();
     return(base.Close());
 }
Example #14
0
        /**
         * This informs all the ConnectionOverlord objects
         * to not respond to loss of edges, then to issue
         * close messages to all the edges
         *
         */
        protected void Leave()
        {
            if (ProtocolLog.NodeLog.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.NodeLog, String.Format(
                                      "In StructuredNode.Leave: {0}", this.Address));
            }

#if !BRUNET_SIMULATOR
            _iphandler.Stop();
#endif
            StopConnectionOverlords();
            //Stop notifying neighbors of disconnection, we are the one leaving
            _connection_table.DisconnectionEvent -= this.UpdateNeighborStatus;

            //Gracefully close all the edges:
            _connection_table.Close(); //This makes sure we can't add any new connections.
            ArrayList edges_to_close = new ArrayList();
            foreach (Edge e in _connection_table.GetUnconnectedEdges())
            {
                edges_to_close.Add(e);
            }
            //There is no way unconnected edges could have become Connections,
            //so we should put the connections in last.
            foreach (Connection c in _connection_table)
            {
                edges_to_close.Add(c.State.Edge);
            }
            //edges_to_close has all the connections and unconnected edges.
            IList copy = edges_to_close.ToArray();

            //Make sure multiple readers and writers won't have problems:
            edges_to_close = ArrayList.Synchronized(edges_to_close);

            EventHandler ch = delegate(object o, EventArgs a) {
                if (ProtocolLog.NodeLog.Enabled)
                {
                    ProtocolLog.Write(ProtocolLog.NodeLog, String.Format(
                                          "{1} Handling Close of: {0}", o, this.Address));
                }
                edges_to_close.Remove(o);
                if (edges_to_close.Count == 0)
                {
                    if (ProtocolLog.NodeLog.Enabled)
                    {
                        ProtocolLog.Write(ProtocolLog.NodeLog, String.Format(
                                              "Node({0}) Stopping all EdgeListeners", Address));
                    }
                    StopAllEdgeListeners();
                }
            };
            if (ProtocolLog.NodeLog.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.NodeLog, String.Format(
                                      "{0} About to gracefully close all edges", this.Address));
            }
            //Use just one of these for all the calls:
            IDictionary carg = new ListDictionary();
            carg["reason"] = "disconnecting";
            for (int i = 0; i < copy.Count; i++)
            {
                Edge e = (Edge)copy[i];
                if (ProtocolLog.NodeLog.Enabled)
                {
                    ProtocolLog.Write(ProtocolLog.NodeLog, String.Format(
                                          "{0} Closing: [{1} of {2}]: {3}", this.Address, i, copy.Count, e));
                }
                try {
                    e.CloseEvent += ch;
                    Channel  res_q      = new Channel(1);
                    DateTime start_time = DateTime.UtcNow;
                    res_q.CloseEvent += delegate(object o, EventArgs arg) {
                        if (ProtocolLog.NodeLog.Enabled)
                        {
                            ProtocolLog.Write(ProtocolLog.NodeLog, String.Format(
                                                  "Close on edge: {0} took: {1}", e, (DateTime.UtcNow - start_time)));
                        }
                        e.Close();
                    };
                    try {
                        _rpc.Invoke(e, res_q, "sys:link.Close", carg);
                    }
                    catch (EdgeException) {
                        /*
                         * It is not strange for the other side to have potentially
                         * closed, or some other error be in progress which is why
                         * we might have been shutting down in the first place
                         * No need to print a message
                         */
                        e.Close();
                    }
                    catch (Exception x) {
                        if (ProtocolLog.Exceptions.Enabled)
                        {
                            ProtocolLog.Write(ProtocolLog.Exceptions, String.Format(
                                                  "sys:link.Close({0}) threw: {1}", e, x));
                        }
                        e.Close();
                    }
                }
                catch {
                    ch(e, null);
                }
            }
            if (copy.Count == 0)
            {
                //There were no edges, go ahead an Stop
                if (ProtocolLog.NodeLog.Enabled)
                {
                    ProtocolLog.Write(ProtocolLog.NodeLog, String.Format(
                                          "Node({0}) Stopping all EdgeListeners", Address));
                }
                StopAllEdgeListeners();
            }
        }
Example #15
0
 protected void RequestClose(Edge e) {
   EventHandler eh = EdgeCloseRequestEvent;
   if( eh == null ) {
     //We have to close the edge:
     e.Close();
   }
   else {
     try {
       eh(this, new EdgeCloseRequestArgs(e));
     }
     catch(Exception x) {
       Console.Error.WriteLine("ERROR: closing: {0} -- {1}", e, x);
       e.Close();
     }
   }
 }
Example #16
0
File: Node.cs Project: hseom/brunet
 protected void Close(Edge e) {
   try {
     //This can throw an exception if the _packet_queue is closed
     EnqueueAction(new Edge.CloseAction(e));
   }
   catch {
     e.Close();
   }
 }
Example #17
0
        /**
         * Check all the edges in the ConnectionTable and see if any of them
         * need to be pinged or closed.
         * This method is connected to the heartbeat event.
         */
        virtual protected void CheckEdgesCallback(object node, EventArgs args)
        {
            DateTime now = DateTime.UtcNow;

            //_connection_timeout = ComputeDynamicTimeout();
            _connection_timeout = MAX_CONNECTION_TIMEOUT;

            /*
             * If we haven't heard from any of these people in this time,
             * we ping them, and if we don't get a response, we close them
             */
            foreach (Connection c in _connection_table)
            {
                Edge     e             = c.Edge;
                TimeSpan since_last_in = now - e.LastInPacketDateTime;
                if ((1 == _send_pings) && (since_last_in > _connection_timeout))
                {
                    object       ping_arg = String.Empty;
                    DateTime     start    = DateTime.UtcNow;
                    EventHandler on_close = delegate(object q, EventArgs cargs) {
                        BCon.Channel qu = (BCon.Channel)q;
                        if (qu.Count == 0)
                        {
                            /* we never got a response! */
                            if (!e.IsClosed)
                            {
                                //We are going to close it after waiting:
                                ProtocolLog.WriteIf(ProtocolLog.NodeLog, String.Format(
                                                        "On an edge timeout({1}), closing connection: {0}",
                                                        c, DateTime.UtcNow - start));
                                //Make sure it is indeed closed.
                                e.Close();
                            }
                            else
                            {
                                //The edge was closed somewhere else, so it
                                //didn't timeout.
                            }
                        }
                        else
                        {
                            //We got a response, let's make sure it's not an exception:
                            bool close = false;
                            try {
                                RpcResult r = (RpcResult)qu.Dequeue();
                                object    o = r.Result; //This will throw an exception if there was a problem
                                if (!o.Equals(ping_arg))
                                {
                                    //Something is wrong with the other node:
                                    ProtocolLog.WriteIf(ProtocolLog.NodeLog, String.Format(
                                                            "Ping({0}) != {1} on {2}", ping_arg, o, c));
                                    close = true;
                                }
                            }
                            catch (Exception x) {
                                ProtocolLog.WriteIf(ProtocolLog.Exceptions, String.Format(
                                                        "Ping on {0}: resulted in: {1}", c, x));
                                close = true;
                            }
                            if (close)
                            {
                                e.Close();
                            }
                        }
                    };
                    BCon.Channel tmp_queue = new BCon.Channel(1);
                    tmp_queue.CloseEvent += on_close;
                    //Do the ping
                    try {
                        _rpc.Invoke(e, tmp_queue, "sys:link.Ping", ping_arg);
                    }
                    catch (EdgeClosedException) {
                        //Just ignore closed edges, clearly we can't ping them
                    }
                    catch (EdgeException x) {
                        if (!x.IsTransient)
                        {
                            //Go ahead and close the Edge
                            e.Close();
                        }
                    }
                }
            }
            foreach (Edge e in _connection_table.GetUnconnectedEdges())
            {
                if (now - e.LastInPacketDateTime > _unconnected_timeout)
                {
                    if (ProtocolLog.Connections.Enabled)
                    {
                        ProtocolLog.Write(ProtocolLog.Connections, String.Format(
                                              "Closed an unconnected edge: {0}", e));
                    }
                    e.Close();
                }
            }
        }
Example #18
0
        /** Handle incoming data on an Edge
         */
        public void HandleData(MemBlock data, ISender retpath, object state)
        {
            MemBlock rest_of_data;
            PType    p;

            if (state == null)
            {
                p = PType.Parse(data, out rest_of_data);
            }
            else
            {
                //a demux has already happened:
                p            = (PType)state;
                rest_of_data = data;
            }
            if (PType.Protocol.Pathing.Equals(p))
            {
                /*
                 * We use a special PType to denote this transaction so
                 * we don't confuse it with other RepRep communication
                 */
                _rrm.HandleData(rest_of_data, retpath, null);
            }
            else if (PType.Protocol.Rpc.Equals(p))
            {
                /*
                 * Send this to the RpcHandler
                 */
                Rpc.HandleData(rest_of_data, retpath, null);
            }
            else
            {
                /*
                 * This is some other data
                 * It is either:
                 * 1) Time to announce an already created edge.
                 * 2) Assume this is a "default path" edge creation, to be backwards
                 * compatible
                 */
                Edge     e  = null;
                PathEdge pe = null;
                try {
                    e = (Edge)retpath;
                    PathEdgeListener pel = null;
                    lock ( _sync ) {
                        if (_unannounced.TryGetValue(e, out pe))
                        {
                            //
                            _unannounced.Remove(e);
                            pel = _pel_map[pe.LocalPath];
                        }
                    }
                    if (pe == null)
                    {
                        /*
                         * This must be a "default path" incoming connection
                         */
                        pel = _pel_map[Root];
                        pe  = new PathEdge(e, Root, Root);
                    }
                    pel.SendPathEdgeEvent(pe);
                    pe.Subscribe();
                    pe.ReceivedPacketEvent(data);
                }
                catch (Exception x) {
                    if (pe != null)
                    {
                        //This closes both edges:
                        pe.Close();
                    }
                    else if (e != null)
                    {
                        Console.WriteLine("Closing ({0}) due to: {1}", e, x);
                        e.Close();
                    }
                }
            }
        }