Example #1
0
        public bool Verify(X509Certificate certificate, ISender sender)
        {
            Address  addr     = null;
            AHSender ahsender = sender as AHSender;

            if (ahsender != null)
            {
                addr = ahsender.Destination;
            }
            else
            {
                Edge edge = sender as Edge;
                if (edge != null)
                {
                    Connection con = _ct.GetConnection(edge);
                    if (con != null)
                    {
                        addr = con.Address;
                    }
                }
            }

            if (addr == null)
            {
                return(true);
            }
            return(CertificateHandler.Verify(certificate, addr.ToString()));
        }
Example #2
0
        /**
         * Handle the notification that the other side is going to close the edge
         */
        public IDictionary Close(IDictionary close_message, ISender edge)
        {
            Edge            from = GetEdge(edge);
            ConnectionTable tab  = _node.ConnectionTable;

            /**
             * In order to make sure that we close gracefully, we simply
             * move this edge to the unconnected list.  The node will
             * close edges that have been there for some time
             */
            Connection c = tab.GetConnection(from);

            if (ProtocolLog.LinkDebug.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                      "sys:link.Close on {0} connection: {1}", from, c));
            }
            tab.Disconnect(from);

            /**
             * Release locks when the close message arrives; do not wait
             * until the edge actually closes.
             */
            CloseHandler(from, null);

            if (ProtocolLog.EdgeClose.Enabled)
            {
                String reason = String.Empty;
                if (close_message.Contains(reason))
                {
                    reason = (String)close_message["reason"];
                }
                ProtocolLog.Write(ProtocolLog.EdgeClose, String.Format(
                                      "sys:link.Close - " + from + ": " + reason));
            }

            /**
             * Try to close the edge after a small time span:
             */
            Brunet.Util.FuzzyTimer.Instance.DoAfter(delegate(DateTime now) {
                _node.EnqueueAction(new Node.GracefulCloseAction(_node, from, "CPH, delayed close"));
            }, 5000, 1000);
            return(new ListDictionary());
        }
Example #3
0
        /**
         * Get a StatusMessage for this node
         */
        public IDictionary GetStatus(IDictionary status_message, ISender edge)
        {
            //we just got s status request
            if (1 == _disconnecting)
            {
                throw new AdrException((int)ErrorMessage.ErrorCode.Disconnecting, "disconnecting");
            }

            StatusMessage sm   = new StatusMessage(status_message);
            Edge          from = GetEdge(edge);

            if (ProtocolLog.LinkDebug.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                      "{0} -start- sys:link.GetStatus({1},{2})", _node.Address, sm, edge));
            }

            CphState cphstate = null;

            if (from != null)
            {
                cphstate = _edge_to_cphstate[from] as CphState;
            }

            /**
             * StatusMessage objects are used to verify the completion
             * of the Link protocol.  If we receive a StatusMessage request
             * after we send a LinkMessage response, we know the other
             * Node got our LinkMessage response, and the connection
             * is active
             */
            StatusMessage   response = null;
            ConnectionTable tab      = _node.ConnectionTable;

            if (cphstate != null)
            {
                try {
                    LinkMessage lm_to_add = cphstate.LM;
                    //This is part of connection process:
                    response = _node.GetStatus(sm.NeighborType, lm_to_add.Local.Address);
                    Connection con = new Connection(from,
                                                    lm_to_add.Local.Address,
                                                    lm_to_add.ConTypeString,
                                                    sm,
                                                    lm_to_add);
                    tab.Add(con);
                }
                finally {
                    from.CloseEvent -= this.CloseHandler;
                    CloseHandler(from, null);
                }
            }
            else
            {
                //This is just a "regular" status request
                //update our table:
                Address    fadd = null;
                Connection c    = tab.GetConnection(from);
                if (c != null)
                {
                    fadd = c.Address;
                    tab.UpdateStatus(c, sm);
                }
                response = _node.GetStatus(sm.NeighborType, fadd);
            }

            if (ProtocolLog.LinkDebug.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                      "{0} -end- sys:link.GetStatus()->{1}", _node.Address, response));
            }

            return(response.ToDictionary());
        }
Example #4
0
        /**
         * This starts a linking operation on the given edge
         */
        public IDictionary Start(IDictionary link_message, ISender edge)
        {
            if (ProtocolLog.LinkDebug.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                      "{0} -start- sys:link.Start", _node.Address));
            }

            Edge        from = GetEdge(edge);
            LinkMessage lm   = new LinkMessage(link_message);

            if (ProtocolLog.LinkDebug.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                      "{0} -args- sys:link.Start({1},{2})", _node.Address, lm, from));
            }

            CphState cph = new CphState(from, lm);

            lock ( _sync ) {
                if (!_edge_to_cphstate.ContainsKey(from))
                {
                    _edge_to_cphstate[from] = cph;
                }
                else
                {
                    throw new AdrException((int)ErrorMessage.ErrorCode.InProgress,
                                           "Already have a link in progress on this edge");
                }
            }
            ErrorMessage err = null;

            if (CanConnect(cph, out err))
            {
                try {
                    //If the CloseEvent was already called, this throws an exception
                    from.CloseEvent += this.CloseHandler;
                }
                catch {
                    CloseHandler(from, null);
                    throw new AdrException((int)ErrorMessage.ErrorCode.EdgeClosed,
                                           "Edge Closed after receiving message");
                }
            }
            else
            {
                lock ( _sync ) {
                    _edge_to_cphstate.Remove(from);
                }
            }
            //Now we prepare our response
            LinkMessage lm_resp = null;

            if (err == null)
            {
                //We send a response:
                NodeInfo n_info      = NodeInfo.CreateInstance(_node.Address, from.LocalTA);
                NodeInfo remote_info = NodeInfo.CreateInstance(null, from.RemoteTA);
                System.Collections.Specialized.StringDictionary attrs =
                    new System.Collections.Specialized.StringDictionary();
                attrs["type"]  = String.Intern(lm.ConTypeString);
                attrs["realm"] = String.Intern(_node.Realm);
                lm_resp        = new LinkMessage(attrs, n_info, remote_info, lm.Token);
            }
            else
            {
                if (err.Ec == ErrorMessage.ErrorCode.AlreadyConnected)
                {
                    /**
                     * When we send the ErrorCode.AlreadyConnected,
                     * we could have a stale connection, lets try pinging
                     * the other node, if they are there, but have lost
                     * the Edge, this may trigger the edge to close, causing
                     * us to remove the Connection.
                     * @todo consider putting this address on a "fast track"
                     * to removal if we don't hear from it soon
                     */
                    ConnectionTable tab = _node.ConnectionTable;
                    Connection      c   = tab.GetConnection(lm.ConnectionType,
                                                            lm.Local.Address);
                    if (c != null)
                    {
                        RpcManager rpc = _node.Rpc;
                        rpc.Invoke(c.Edge, null, "sys:link.Ping", String.Empty);
                    }
                }
            }
            if (err != null)
            {
                throw new AdrException((int)err.Ec, err.Message);
            }
            if (ProtocolLog.LinkDebug.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                      "{0} -end- sys:link.Start()->{1}", _node.Address, lm_resp));
            }
            return(lm_resp.ToDictionary());
        }