Exemple #1
0
        /**
         * Checks that everything matches up and the protocol
         * can continue, throws and exception if anything is
         * not okay
         */
        protected void SetAndCheckLinkReply(LinkMessage lm)
        {
            /* Check that the everything matches up
             * Make sure the link message is Kosher.
             * This are critical errors.  This Link fails if these occur
             */
            if (lm.Local == null)
            {
                throw new LinkException("Bad response");
            }
            if (_node.Address.Equals(lm.Local.Address))
            {
                //Somehow, we got a response from someone claiming to be us.
                throw new LinkException("Got a LinkMessage response from our address");
            }
            if (lm.ConTypeString != _contype)
            {
                throw new LinkException("Link type mismatch: " + _contype + " != " + lm.ConTypeString);
            }
            if (!lm.Realm.Equals(_node.Realm))
            {
                throw new LinkException("Realm mismatch: " +
                                        _node.Realm + " != " + lm.Realm);
            }
            if (lm.Local.Address == null)
            {
                throw new LinkException("LinkMessage response has null Address");
            }
            if ((_linker.Target != null) && (!lm.Local.Address.Equals(_linker.Target)))
            {
                /*
                 * This is super goofy.  Somehow we got a response from some node
                 * we didn't mean to connect to.
                 * This can happen in some cases with NATs since nodes behind NATs are
                 * guessing which ports are correct, their guess may be incorrect, and
                 * the NAT may send the packet to a different node.
                 * In this case, we have a critical error, this TA is not correct, we
                 * must move on to the next TA.
                 */
                throw new LinkException(String.Format("Target mismatch: {0} != {1}",
                                                      _linker.Target, lm.Local.Address), true, null);
            }

            /*
             * Okay, this lm looks good, we'll accept it.  This can only be done
             * once, and once it happens a future attempt will throw an exception
             */
            _lm_reply.Value = lm;

            ConnectionTable tab = _node.ConnectionTable;

            /*
             * This throws an exception if:
             * 0) we can't get the lock.
             * 1) we already have set _target_lock to something else
             */
            tab.Lock(lm.Local.Address, _contype, this);
        }
Exemple #2
0
        /**
         * Set the _target_lock member variable and check for sanity
         * We only set the target if we can get a lock on the address
         * We can call this method more than once as long as we always
         * call it with the same value for target
         * If target is null we just return
         *
         * @throws LinkException if the target is already * set to a different address
         * @throws System.InvalidOperationException if we cannot get the lock
         */
        protected void SetTarget()
        {
            if (_target == null)
            {
                return;
            }
            if (_target.Equals(LocalNode.Address))
            {
                throw new LinkException("cannot connect to self");
            }

            ConnectionTable tab = LocalNode.ConnectionTable;

            /*
             * This throws an exception if:
             * 0) we can't get the lock.
             * 1) we already have set _target_lock to something else
             */
            tab.Lock(_target, _contype, this);
        }
Exemple #3
0
        /**
         * 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);
        }