/**
     * When we get a new link message from an edge, we must
     * check several conditions to see if we can proceed with
     * the Link protocol.
     * This function checks those conditions and returns true
     * if we can proceed.
     * If we cannot proceed, it gives an ErrorMessage to send
     * back to the other side.
     * @param cph The CphState
     * @param err ErrorMessage to return.  Is null if there is no error
     * @return true if we can connect, if false, err != null
     */
    protected bool CanConnect(CphState cph, out ErrorMessage err)
    {
      ConnectionTable tab = _node.ConnectionTable;
      Address local_add = _node.Address;
      LinkMessage lm = cph.LM;
      err = null;
      /* We lock the connection table so it doesn't change between
       * the call to Contains and the call to Lock
       */
      if( lm.Attributes["realm"] != _node.Realm ) {
        err = new ErrorMessage(ErrorMessage.ErrorCode.RealmMismatch,
                               "We are not in the same realm");
      }
      else if( (lm.Remote.Address != null ) && !local_add.Equals( lm.Remote.Address ) ) {
        /*
         * They are trying to reach a specific node, but it's not
         * us
         */
        err = new ErrorMessage(ErrorMessage.ErrorCode.TargetMismatch,
                               String.Format("target is {0}, but reached {1}",
                                             lm.Remote.Address, local_add));
      }
      else if( lm.Local.Address.Equals( local_add ) ) {
        //You are me!!!
        err = new ErrorMessage(ErrorMessage.ErrorCode.ConnectToSelf,
                               "You are me: ");
      }
      else if( 1 == _disconnecting ) {
        err = new ErrorMessage(ErrorMessage.ErrorCode.Disconnecting,
                               String.Format("I am disconnecting. local: {0}", local_add));
      }
      else {
        /*
         * Now we go to the ConnectionTable and try to
         * get a lock on the address so we can go forward
         * with the linking
         */
        try {
          if(ProtocolLog.LinkDebug.Enabled)
            ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
              "ConnectionPacketHandler - Trying to lock connection table: {0},{1}",
                                  lm.Local.Address, lm.ConTypeString));

          tab.Lock( lm.Local.Address, lm.ConTypeString, cph );
          if(ProtocolLog.LinkDebug.Enabled)
            ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
              "ConnectionPacketHandler - Successfully locked connection table: {0},{1}",
              lm.Local.Address, lm.ConTypeString));
        }
        catch(ConnectionExistsException) {
          //We already have a connection of this type to this address
          err = new ErrorMessage(ErrorMessage.ErrorCode.AlreadyConnected,
                               String.Format("We are already connected: {0}", local_add));
        }
        catch(CTLockException) {
          if(ProtocolLog.LinkDebug.Enabled)
            ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
              "ConnectionPacketHandler - Cannot lock connection table: {0},{1}",
              lm.Local.Address, lm.ConTypeString));
          //Lock can throw this type of exception
          err = new ErrorMessage(ErrorMessage.ErrorCode.InProgress,
                                 "Address: " + lm.Local.Address.ToString() +
                                 " is locked");
        }
      }
      return ( err == null );
    }
Exemple #2
0
 public LinkException(string message, bool crit, ErrorMessage em) : base(message) {
   _critical = crit;
   _em = em;
 }
Exemple #3
0
    public void EMTest()
    {
      ErrorMessage em1 = new ErrorMessage(ErrorMessage.ErrorCode.UnexpectedRequest,
		                          "Who are you???");

      ErrorMessage em2 = new ErrorMessage(ErrorMessage.ErrorCode.AlreadyConnected, "We are BFF");
    }
Exemple #4
0
 /**
  * @param ec The ErrorCode for this message
  * @param message the string in the message
  */
 public ErrorMessage(ErrorMessage.ErrorCode ec, string message)
 {
   _ec = ec;;
   _message = message;
 }
Exemple #5
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);
                lm_resp = new LinkMessage(lm.ConTypeString, n_info, remote_info, _node.Realm, lm.Token);
            }
            else
            {
                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());
        }