public void OnNeighborAuthenticated(IPeerNeighbor neighbor)
 {
     if (this.state == State.Created)
     {
         throw Fx.AssertAndThrow("Connector not expected to be in Created state");
     }
     if (!PeerNeighborStateHelper.IsAuthenticatedOrClosed(neighbor.State))
     {
         throw Fx.AssertAndThrow(string.Format(CultureInfo.InvariantCulture, "Neighbor state expected to be Authenticated or Closed, actual state: {0}", new object[] { neighbor.State }));
     }
     if (!neighbor.TrySetState(PeerNeighborState.Connecting))
     {
         if (neighbor.State < PeerNeighborState.Faulted)
         {
             throw Fx.AssertAndThrow(string.Format(CultureInfo.InvariantCulture, "Neighbor state expected to be Faulted or Closed, actual state: {0}", new object[] { neighbor.State }));
         }
     }
     else if (this.AddTimer(neighbor) && neighbor.IsInitiator)
     {
         if (this.neighborManager.ConnectedNeighborCount < this.config.MaxNeighbors)
         {
             this.SendConnect(neighbor);
         }
         else
         {
             this.neighborManager.CloseNeighbor(neighbor, PeerCloseReason.NodeBusy, PeerCloseInitiator.LocalNode);
         }
     }
 }
Exemplo n.º 2
0
        public void OnNeighborOpened(object sender, EventArgs args)
        {
            IPeerNeighbor neighbor = sender as IPeerNeighbor;
            EventHandler  handler  = this.OnNeighborAuthenticated;

            if (handler == null)
            {
                neighbor.Abort(PeerCloseReason.LeavingMesh, PeerCloseInitiator.LocalNode);
                return;
            }
            if (this.authenticationMode == PeerAuthenticationMode.Password)
            {
                if (!(neighbor.Extensions.Find <PeerChannelAuthenticatorExtension>() == null))
                {
                    throw Fx.AssertAndThrow("extension already exists!");
                }
                PeerChannelAuthenticatorExtension extension = new PeerChannelAuthenticatorExtension(this, handler, args, this.MeshId);
                neighbor.Extensions.Add(extension);
                if (neighbor.IsInitiator)
                {
                    extension.InitiateHandShake();
                }
            }
            else
            {
                neighbor.TrySetState(PeerNeighborState.Authenticated);
                handler(sender, args);
            }
        }
 private void SendTerminatingMessage(IPeerNeighbor neighbor, string action, PeerCloseReason closeReason)
 {
     if ((this.state == State.Opened) && (closeReason != PeerCloseReason.InvalidNeighbor))
     {
         if (neighbor.TrySetState(PeerNeighborState.Disconnecting))
         {
             Message    message;
             Referral[] referrals = this.maintainer.GetReferrals();
             if (action == "http://schemas.microsoft.com/net/2006/05/peer/Disconnect")
             {
                 DisconnectInfo typedMessage = new DisconnectInfo((DisconnectReason)closeReason, referrals);
                 message = this.DisconnectInfoMessageConverter.ToMessage(typedMessage, MessageVersion.Soap12WSAddressing10);
             }
             else
             {
                 RefuseInfo info2 = new RefuseInfo((RefuseReason)closeReason, referrals);
                 message = this.RefuseInfoMessageConverter.ToMessage(info2, MessageVersion.Soap12WSAddressing10);
             }
             this.SendMessageToNeighbor(neighbor, message, null);
         }
         else if (neighbor.State < PeerNeighborState.Disconnecting)
         {
             throw Fx.AssertAndThrow("Neighbor state expected to be >= Disconnecting; it is " + neighbor.State.ToString());
         }
     }
 }
 public void Connect(IPeerNeighbor neighbor, ConnectInfo connectInfo)
 {
     if (this.state == State.Opened)
     {
         PeerCloseReason none = PeerCloseReason.None;
         if ((neighbor.IsInitiator || !connectInfo.HasBody()) || ((neighbor.State != PeerNeighborState.Connecting) && (neighbor.State != PeerNeighborState.Closed)))
         {
             none = PeerCloseReason.InvalidNeighbor;
         }
         else if (this.RemoveTimer(neighbor))
         {
             if (this.neighborManager.ConnectedNeighborCount >= this.config.MaxNeighbors)
             {
                 none = PeerCloseReason.NodeBusy;
             }
             else if (!PeerValidateHelper.ValidNodeAddress(connectInfo.Address))
             {
                 none = PeerCloseReason.InvalidNeighbor;
             }
             else
             {
                 PeerCloseReason reason2;
                 IPeerNeighbor   neighbor2;
                 string          action = "http://schemas.microsoft.com/net/2006/05/peer/Refuse";
                 this.ValidateNeighbor(neighbor, connectInfo.NodeId, out neighbor2, out reason2, out action);
                 if (neighbor != neighbor2)
                 {
                     this.SendWelcome(neighbor);
                     try
                     {
                         neighbor.ListenAddress = connectInfo.Address;
                     }
                     catch (ObjectDisposedException exception)
                     {
                         DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);
                     }
                     if (!neighbor.TrySetState(PeerNeighborState.Connected) && (neighbor.State < PeerNeighborState.Disconnecting))
                     {
                         throw Fx.AssertAndThrow("Neighbor state expected to be >= Disconnecting; it is " + neighbor.State.ToString());
                     }
                     if (neighbor2 != null)
                     {
                         this.SendTerminatingMessage(neighbor2, action, reason2);
                         this.neighborManager.CloseNeighbor(neighbor2, reason2, PeerCloseInitiator.LocalNode);
                     }
                 }
                 else
                 {
                     none = reason2;
                 }
             }
         }
         if (none != PeerCloseReason.None)
         {
             this.SendTerminatingMessage(neighbor, "http://schemas.microsoft.com/net/2006/05/peer/Refuse", none);
             this.neighborManager.CloseNeighbor(neighbor, none, PeerCloseInitiator.LocalNode);
         }
     }
 }
 private void CompleteTerminateMessageProcessing(IPeerNeighbor neighbor, PeerCloseReason closeReason, IList <Referral> referrals)
 {
     if (neighbor.TrySetState(PeerNeighborState.Disconnected))
     {
         this.neighborManager.CloseNeighbor(neighbor, closeReason, PeerCloseInitiator.RemoteNode);
     }
     else if (neighbor.State < PeerNeighborState.Disconnected)
     {
         throw Fx.AssertAndThrow("Unexpected neighbor state");
     }
     this.maintainer.AddReferrals(referrals, neighbor);
 }
 private void CompleteTerminateMessageProcessing(IPeerNeighbor neighbor, PeerCloseReason closeReason, IList<Referral> referrals)
 {
     if (neighbor.TrySetState(PeerNeighborState.Disconnected))
     {
         this.neighborManager.CloseNeighbor(neighbor, closeReason, PeerCloseInitiator.RemoteNode);
     }
     else if (neighbor.State < PeerNeighborState.Disconnected)
     {
         throw Fx.AssertAndThrow("Unexpected neighbor state");
     }
     this.maintainer.AddReferrals(referrals, neighbor);
 }
 public void Welcome(IPeerNeighbor neighbor, WelcomeInfo welcomeInfo)
 {
     if (this.state == State.Opened)
     {
         PeerCloseReason none = PeerCloseReason.None;
         if ((!neighbor.IsInitiator || !welcomeInfo.HasBody()) || ((neighbor.State != PeerNeighborState.Connecting) && (neighbor.State != PeerNeighborState.Closed)))
         {
             none = PeerCloseReason.InvalidNeighbor;
         }
         else if (this.RemoveTimer(neighbor))
         {
             PeerCloseReason reason2;
             IPeerNeighbor   neighbor2;
             string          action = "http://schemas.microsoft.com/net/2006/05/peer/Refuse";
             this.ValidateNeighbor(neighbor, welcomeInfo.NodeId, out neighbor2, out reason2, out action);
             if (neighbor != neighbor2)
             {
                 if (this.maintainer.AddReferrals(welcomeInfo.Referrals, neighbor))
                 {
                     if (!neighbor.TrySetState(PeerNeighborState.Connected) && (neighbor.State < PeerNeighborState.Faulted))
                     {
                         throw Fx.AssertAndThrow("Neighbor state expected to be >= Faulted; it is " + neighbor.State.ToString());
                     }
                     if (neighbor2 != null)
                     {
                         this.SendTerminatingMessage(neighbor2, action, reason2);
                         this.neighborManager.CloseNeighbor(neighbor2, reason2, PeerCloseInitiator.LocalNode);
                     }
                 }
                 else
                 {
                     none = PeerCloseReason.InvalidNeighbor;
                 }
             }
             else
             {
                 none = reason2;
             }
         }
         if (none != PeerCloseReason.None)
         {
             this.SendTerminatingMessage(neighbor, "http://schemas.microsoft.com/net/2006/05/peer/Disconnect", none);
             this.neighborManager.CloseNeighbor(neighbor, none, PeerCloseInitiator.LocalNode);
         }
     }
 }
Exemplo n.º 8
0
        // Process neighbor authenticated notification
        public void OnNeighborAuthenticated(IPeerNeighbor neighbor)
        {
            if (!(this.state != State.Created))
            {
                throw Fx.AssertAndThrow("Connector not expected to be in Created state");
            }

            if (!(PeerNeighborStateHelper.IsAuthenticatedOrClosed(neighbor.State)))
            {
                throw Fx.AssertAndThrow(string.Format(CultureInfo.InvariantCulture, "Neighbor state expected to be Authenticated or Closed, actual state: {0}", neighbor.State));
            }

            // setting the state fails if neighbor is already closed or closing
            // If so, we have nothing to do.
            if (!neighbor.TrySetState(PeerNeighborState.Connecting))
            {
                if (!(neighbor.State >= PeerNeighborState.Faulted))
                {
                    throw Fx.AssertAndThrow(string.Format(CultureInfo.InvariantCulture, "Neighbor state expected to be Faulted or Closed, actual state: {0}", neighbor.State));
                }
                return;
            }

            // Add a timer to timer table to transition the neighbor to connected state
            // within finite duration. The neighbor is closed if the timer fires and the
            // neighbor has not reached connected state.
            // The timer is not added if neighbor or connector are closed
            if (AddTimer(neighbor))
            {
                // Need to send connect message if the neighbor is the initiator
                if (neighbor.IsInitiator)
                {
                    if (this.neighborManager.ConnectedNeighborCount < this.config.MaxNeighbors)
                    {
                        SendConnect(neighbor);
                    }
                    else
                    {
                        // We have max connected neighbors already. So close this one.
                        this.neighborManager.CloseNeighbor(neighbor, PeerCloseReason.NodeBusy,
                                                           PeerCloseInitiator.LocalNode);
                    }
                }
            }
        }
Exemplo n.º 9
0
        // Complete processing of Disconnect or Refuse message from the neighbor
        void CompleteTerminateMessageProcessing(IPeerNeighbor neighbor,
                                                PeerCloseReason closeReason, IList <Referral> referrals)
        {
            // Close the neighbor after setting the neighbor state to Disconnected.
            // The set can fail if the neighbor is already being closed and that is ok.
            if (neighbor.TrySetState(PeerNeighborState.Disconnected))
            {
                this.neighborManager.CloseNeighbor(neighbor, closeReason, PeerCloseInitiator.RemoteNode);
            }
            else
            if (!(neighbor.State >= PeerNeighborState.Disconnected))
            {
                throw Fx.AssertAndThrow("Unexpected neighbor state");
            }

            // Hand over the referrals to maintainer
            this.maintainer.AddReferrals(referrals, neighbor);
        }
Exemplo n.º 10
0
        // Send Disconnect or Refuse message
        void SendTerminatingMessage(IPeerNeighbor neighbor, string action, PeerCloseReason closeReason)
        {
            // We do not attempt to send the message if Connector is not open
            // or if the close reason is InvalidNeighbor.
            if (this.state != State.Opened || closeReason == PeerCloseReason.InvalidNeighbor)
            {
                return;
            }

            // Set the neighbor state to disconnecting. TrySetState can fail if the
            // neighbor is already being closed. Disconnect/Refuse msg not sent in that case.
            if (neighbor.TrySetState(PeerNeighborState.Disconnecting))
            {
                // Get referrals from the maintainer
                Referral[] referrals = maintainer.GetReferrals();

                // Build and send the message
                Message message;
                if (action == PeerStrings.DisconnectAction)
                {
                    DisconnectInfo disconnectInfo = new DisconnectInfo((DisconnectReason)closeReason, referrals);
                    message = DisconnectInfoMessageConverter.ToMessage(disconnectInfo, MessageVersion.Soap12WSAddressing10);
                }
                else
                {
                    RefuseInfo refuseInfo = new RefuseInfo((RefuseReason)closeReason, referrals);
                    message = RefuseInfoMessageConverter.ToMessage(refuseInfo, MessageVersion.Soap12WSAddressing10);
                }
                SendMessageToNeighbor(neighbor, message, null);
            }
            else
            if (!(neighbor.State >= PeerNeighborState.Disconnecting))
            {
                throw Fx.AssertAndThrow("Neighbor state expected to be >= Disconnecting; it is " + neighbor.State.ToString());
            }
        }
Exemplo n.º 11
0
        //<Implementation of PeerConnector.IPeerConnectorContract>
        // Process Connect from the neighbor
        public void Connect(IPeerNeighbor neighbor, ConnectInfo connectInfo)
        {
            // Don't bother processing the message if Connector has closed
            if (this.state != State.Opened)
            {
                return;
            }

            PeerCloseReason closeReason = PeerCloseReason.None;

            // A connect message should only be received by a responder neighbor that is
            // in Connecting state. If not, we close the neighbor without bothering
            // to send a Refuse message
            // A malicious neighbor can format a message with a null connectInfo as an argument
            if (neighbor.IsInitiator || !connectInfo.HasBody() || (neighbor.State != PeerNeighborState.Connecting &&
                                                                   neighbor.State != PeerNeighborState.Closed))
            {
                closeReason = PeerCloseReason.InvalidNeighbor;
            }

            // Remove the timer from the timer table for this neighbor. If the timer is not
            // present, the neighbor is already being closed and the Connect message should
            // be ignored.
            else if (RemoveTimer(neighbor))
            {
                // Determine if Welcome or Refuse should be sent

                // Refuse if node has maximum allowed connected neighbors?
                if (this.neighborManager.ConnectedNeighborCount >= this.config.MaxNeighbors)
                {
                    closeReason = PeerCloseReason.NodeBusy;
                }
                else
                {
                    // Deserialization failed or connect info is invalid?
                    if (!PeerValidateHelper.ValidNodeAddress(connectInfo.Address))
                    {
                        closeReason = PeerCloseReason.InvalidNeighbor;
                    }
                    else
                    {
                        // Determine if neighbor should be accepted.
                        PeerCloseReason closeReason2;
                        IPeerNeighbor   neighborToClose;
                        string          action = PeerStrings.RefuseAction;
                        ValidateNeighbor(neighbor, connectInfo.NodeId, out neighborToClose, out closeReason2, out action);

                        if (neighbor != neighborToClose)    // new neighbor should be accepted
                        {
                            SendWelcome(neighbor);
                            try
                            {
                                neighbor.ListenAddress = connectInfo.Address;
                            }
                            catch (ObjectDisposedException e)
                            {
                                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                            }

                            if (!neighbor.TrySetState(PeerNeighborState.Connected))
                            {
                                if (!(neighbor.State >= PeerNeighborState.Disconnecting))
                                {
                                    throw Fx.AssertAndThrow("Neighbor state expected to be >= Disconnecting; it is " + neighbor.State.ToString());
                                }
                            }

                            if (neighborToClose != null)
                            {
                                // The other neighbor should be closed
                                SendTerminatingMessage(neighborToClose, action, closeReason2);
                                this.neighborManager.CloseNeighbor(neighborToClose, closeReason2, PeerCloseInitiator.LocalNode);
                            }
                        }
                        else
                        {
                            closeReason = closeReason2;
                        }
                    }
                }
            }

            if (closeReason != PeerCloseReason.None)
            {
                SendTerminatingMessage(neighbor, PeerStrings.RefuseAction, closeReason);
                this.neighborManager.CloseNeighbor(neighbor, closeReason, PeerCloseInitiator.LocalNode);
            }
        }
Exemplo n.º 12
0
        // Send Disconnect or Refuse message
        void SendTerminatingMessage(IPeerNeighbor neighbor, string action, PeerCloseReason closeReason)
        {
            // We do not attempt to send the message if Connector is not open
            // or if the close reason is InvalidNeighbor.
            if (this.state != State.Opened || closeReason == PeerCloseReason.InvalidNeighbor)
                return;

            // Set the neighbor state to disconnecting. TrySetState can fail if the 
            // neighbor is already being closed. Disconnect/Refuse msg not sent in that case.
            if (neighbor.TrySetState(PeerNeighborState.Disconnecting))
            {
                // Get referrals from the maintainer
                Referral[] referrals = maintainer.GetReferrals();

                // Build and send the message
                Message message;
                if (action == PeerStrings.DisconnectAction)
                {
                    DisconnectInfo disconnectInfo = new DisconnectInfo((DisconnectReason)closeReason, referrals);
                    message = DisconnectInfoMessageConverter.ToMessage(disconnectInfo, MessageVersion.Soap12WSAddressing10);
                }
                else
                {
                    RefuseInfo refuseInfo = new RefuseInfo((RefuseReason)closeReason, referrals);
                    message = RefuseInfoMessageConverter.ToMessage(refuseInfo, MessageVersion.Soap12WSAddressing10);
                }
                SendMessageToNeighbor(neighbor, message, null);
            }
            else
                if (!(neighbor.State >= PeerNeighborState.Disconnecting))
                {
                    throw Fx.AssertAndThrow("Neighbor state expected to be >= Disconnecting; it is " + neighbor.State.ToString());
                }
        }
Exemplo n.º 13
0
        // Process Welcome message from the neighbor
        public void Welcome(IPeerNeighbor neighbor, WelcomeInfo welcomeInfo)
        {
            // Don't bother processing the message if Connector has closed
            if (this.state != State.Opened)
                return;

            PeerCloseReason closeReason = PeerCloseReason.None;

            // Welcome message should only be received when neighbor is the initiator
            // and is in connecting state --we accept in closed state to account for
            // timeouts.
            if (!neighbor.IsInitiator || !welcomeInfo.HasBody() || (neighbor.State != PeerNeighborState.Connecting &&
                neighbor.State != PeerNeighborState.Closed))
            {
                closeReason = PeerCloseReason.InvalidNeighbor;
            }
            // Remove the entry from timer table for this neighbor. If entry is still present,
            // RemoveTimer returns true. Otherwise, neighbor is already being closed and 
            // welcome message will be ignored.
            else if (RemoveTimer(neighbor))
            {
                // It is allowed for a node to have more than MaxNeighbours when processing a welcome message
                // Determine if neighbor should be accepted.
                PeerCloseReason closeReason2;
                IPeerNeighbor neighborToClose;
                string action = PeerStrings.RefuseAction;
                ValidateNeighbor(neighbor, welcomeInfo.NodeId, out neighborToClose, out closeReason2, out action);

                if (neighbor != neighborToClose)
                {
                    // Neighbor should be accepted AddReferrals validates the referrals, 
                    // if they are valid then the neighbor is accepted.
                    if (this.maintainer.AddReferrals(welcomeInfo.Referrals, neighbor))
                    {
                        if (!neighbor.TrySetState(PeerNeighborState.Connected))
                        {
                            if (!(neighbor.State >= PeerNeighborState.Faulted))
                            {
                                throw Fx.AssertAndThrow("Neighbor state expected to be >= Faulted; it is " + neighbor.State.ToString());
                            }
                        }

                        if (neighborToClose != null)
                        {
                            // The other neighbor should be closed
                            SendTerminatingMessage(neighborToClose, action, closeReason2);
                            this.neighborManager.CloseNeighbor(neighborToClose, closeReason2, PeerCloseInitiator.LocalNode);
                        }
                    }
                    else
                    {
                        // Referrals were invalid this node is suspicous
                        closeReason = PeerCloseReason.InvalidNeighbor;
                    }
                }
                else
                {
                    closeReason = closeReason2;
                }
            }

            if (closeReason != PeerCloseReason.None)
            {
                SendTerminatingMessage(neighbor, PeerStrings.DisconnectAction, closeReason);
                this.neighborManager.CloseNeighbor(neighbor, closeReason, PeerCloseInitiator.LocalNode);
            }
        }
Exemplo n.º 14
0
        //<Implementation of PeerConnector.IPeerConnectorContract>
        // Process Connect from the neighbor
        public void Connect(IPeerNeighbor neighbor, ConnectInfo connectInfo)
        {
            // Don't bother processing the message if Connector has closed
            if (this.state != State.Opened)
                return;

            PeerCloseReason closeReason = PeerCloseReason.None;

            // A connect message should only be received by a responder neighbor that is
            // in Connecting state. If not, we close the neighbor without bothering 
            // to send a Refuse message
            // A malicious neighbor can format a message with a null connectInfo as an argument
            if (neighbor.IsInitiator || !connectInfo.HasBody() || (neighbor.State != PeerNeighborState.Connecting &&
                neighbor.State != PeerNeighborState.Closed))
            {
                closeReason = PeerCloseReason.InvalidNeighbor;
            }

            // Remove the timer from the timer table for this neighbor. If the timer is not
            // present, the neighbor is already being closed and the Connect message should 
            // be ignored.
            else if (RemoveTimer(neighbor))
            {
                // Determine if Welcome or Refuse should be sent

                // Refuse if node has maximum allowed connected neighbors?
                if (this.neighborManager.ConnectedNeighborCount >= this.config.MaxNeighbors)
                    closeReason = PeerCloseReason.NodeBusy;
                else
                {
                    // Deserialization failed or connect info is invalid?
                    if (!PeerValidateHelper.ValidNodeAddress(connectInfo.Address))
                    {
                        closeReason = PeerCloseReason.InvalidNeighbor;
                    }
                    else
                    {
                        // Determine if neighbor should be accepted.
                        PeerCloseReason closeReason2;
                        IPeerNeighbor neighborToClose;
                        string action = PeerStrings.RefuseAction;
                        ValidateNeighbor(neighbor, connectInfo.NodeId, out neighborToClose, out closeReason2, out action);

                        if (neighbor != neighborToClose)    // new neighbor should be accepted
                        {
                            SendWelcome(neighbor);
                            try
                            {
                                neighbor.ListenAddress = connectInfo.Address;
                            }
                            catch (ObjectDisposedException e)
                            {
                                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                            }

                            if (!neighbor.TrySetState(PeerNeighborState.Connected))
                                if (!(neighbor.State >= PeerNeighborState.Disconnecting))
                                {
                                    throw Fx.AssertAndThrow("Neighbor state expected to be >= Disconnecting; it is " + neighbor.State.ToString());
                                }

                            if (neighborToClose != null)
                            {
                                // The other neighbor should be closed
                                SendTerminatingMessage(neighborToClose, action, closeReason2);
                                this.neighborManager.CloseNeighbor(neighborToClose, closeReason2, PeerCloseInitiator.LocalNode);
                            }
                        }
                        else
                            closeReason = closeReason2;
                    }
                }
            }

            if (closeReason != PeerCloseReason.None)
            {
                SendTerminatingMessage(neighbor, PeerStrings.RefuseAction, closeReason);
                this.neighborManager.CloseNeighbor(neighbor, closeReason, PeerCloseInitiator.LocalNode);
            }
        }
Exemplo n.º 15
0
        // Process neighbor authenticated notification
        public void OnNeighborAuthenticated(IPeerNeighbor neighbor)
        {
            if (!(this.state != State.Created))
            {
                throw Fx.AssertAndThrow("Connector not expected to be in Created state");
            }

            if (!(PeerNeighborStateHelper.IsAuthenticatedOrClosed(neighbor.State)))
            {
                throw Fx.AssertAndThrow(string.Format(CultureInfo.InvariantCulture, "Neighbor state expected to be Authenticated or Closed, actual state: {0}", neighbor.State));
            }

            // setting the state fails if neighbor is already closed or closing
            // If so, we have nothing to do.
            if (!neighbor.TrySetState(PeerNeighborState.Connecting))
            {
                if (!(neighbor.State >= PeerNeighborState.Faulted))
                {
                    throw Fx.AssertAndThrow(string.Format(CultureInfo.InvariantCulture, "Neighbor state expected to be Faulted or Closed, actual state: {0}", neighbor.State));
                }
                return;
            }

            // Add a timer to timer table to transition the neighbor to connected state
            // within finite duration. The neighbor is closed if the timer fires and the
            // neighbor has not reached connected state.
            // The timer is not added if neighbor or connector are closed
            if (AddTimer(neighbor))
            {
                // Need to send connect message if the neighbor is the initiator
                if (neighbor.IsInitiator)
                {
                    if (this.neighborManager.ConnectedNeighborCount < this.config.MaxNeighbors)
                        SendConnect(neighbor);
                    else
                    {
                        // We have max connected neighbors already. So close this one.
                        this.neighborManager.CloseNeighbor(neighbor, PeerCloseReason.NodeBusy,
                            PeerCloseInitiator.LocalNode);
                    }
                }
            }
        }
Exemplo n.º 16
0
        // Complete processing of Disconnect or Refuse message from the neighbor
        void CompleteTerminateMessageProcessing(IPeerNeighbor neighbor,
            PeerCloseReason closeReason, IList<Referral> referrals)
        {
            // Close the neighbor after setting the neighbor state to Disconnected.
            // The set can fail if the neighbor is already being closed and that is ok.
            if (neighbor.TrySetState(PeerNeighborState.Disconnected))
                this.neighborManager.CloseNeighbor(neighbor, closeReason, PeerCloseInitiator.RemoteNode);
            else
                if (!(neighbor.State >= PeerNeighborState.Disconnected))
                {
                    throw Fx.AssertAndThrow("Unexpected neighbor state");
                }

            // Hand over the referrals to maintainer
            this.maintainer.AddReferrals(referrals, neighbor);
        }
 public void OnNeighborAuthenticated(IPeerNeighbor neighbor)
 {
     if (this.state == State.Created)
     {
         throw Fx.AssertAndThrow("Connector not expected to be in Created state");
     }
     if (!PeerNeighborStateHelper.IsAuthenticatedOrClosed(neighbor.State))
     {
         throw Fx.AssertAndThrow(string.Format(CultureInfo.InvariantCulture, "Neighbor state expected to be Authenticated or Closed, actual state: {0}", new object[] { neighbor.State }));
     }
     if (!neighbor.TrySetState(PeerNeighborState.Connecting))
     {
         if (neighbor.State < PeerNeighborState.Faulted)
         {
             throw Fx.AssertAndThrow(string.Format(CultureInfo.InvariantCulture, "Neighbor state expected to be Faulted or Closed, actual state: {0}", new object[] { neighbor.State }));
         }
     }
     else if (this.AddTimer(neighbor) && neighbor.IsInitiator)
     {
         if (this.neighborManager.ConnectedNeighborCount < this.config.MaxNeighbors)
         {
             this.SendConnect(neighbor);
         }
         else
         {
             this.neighborManager.CloseNeighbor(neighbor, PeerCloseReason.NodeBusy, PeerCloseInitiator.LocalNode);
         }
     }
 }
 private void SendTerminatingMessage(IPeerNeighbor neighbor, string action, PeerCloseReason closeReason)
 {
     if ((this.state == State.Opened) && (closeReason != PeerCloseReason.InvalidNeighbor))
     {
         if (neighbor.TrySetState(PeerNeighborState.Disconnecting))
         {
             Message message;
             Referral[] referrals = this.maintainer.GetReferrals();
             if (action == "http://schemas.microsoft.com/net/2006/05/peer/Disconnect")
             {
                 DisconnectInfo typedMessage = new DisconnectInfo((DisconnectReason) closeReason, referrals);
                 message = this.DisconnectInfoMessageConverter.ToMessage(typedMessage, MessageVersion.Soap12WSAddressing10);
             }
             else
             {
                 RefuseInfo info2 = new RefuseInfo((RefuseReason) closeReason, referrals);
                 message = this.RefuseInfoMessageConverter.ToMessage(info2, MessageVersion.Soap12WSAddressing10);
             }
             this.SendMessageToNeighbor(neighbor, message, null);
         }
         else if (neighbor.State < PeerNeighborState.Disconnecting)
         {
             throw Fx.AssertAndThrow("Neighbor state expected to be >= Disconnecting; it is " + neighbor.State.ToString());
         }
     }
 }
Exemplo n.º 19
0
        // Process Welcome message from the neighbor
        public void Welcome(IPeerNeighbor neighbor, WelcomeInfo welcomeInfo)
        {
            // Don't bother processing the message if Connector has closed
            if (this.state != State.Opened)
            {
                return;
            }

            PeerCloseReason closeReason = PeerCloseReason.None;

            // Welcome message should only be received when neighbor is the initiator
            // and is in connecting state --we accept in closed state to account for
            // timeouts.
            if (!neighbor.IsInitiator || !welcomeInfo.HasBody() || (neighbor.State != PeerNeighborState.Connecting &&
                                                                    neighbor.State != PeerNeighborState.Closed))
            {
                closeReason = PeerCloseReason.InvalidNeighbor;
            }
            // Remove the entry from timer table for this neighbor. If entry is still present,
            // RemoveTimer returns true. Otherwise, neighbor is already being closed and
            // welcome message will be ignored.
            else if (RemoveTimer(neighbor))
            {
                // It is allowed for a node to have more than MaxNeighbours when processing a welcome message
                // Determine if neighbor should be accepted.
                PeerCloseReason closeReason2;
                IPeerNeighbor   neighborToClose;
                string          action = PeerStrings.RefuseAction;
                ValidateNeighbor(neighbor, welcomeInfo.NodeId, out neighborToClose, out closeReason2, out action);

                if (neighbor != neighborToClose)
                {
                    // Neighbor should be accepted AddReferrals validates the referrals,
                    // if they are valid then the neighbor is accepted.
                    if (this.maintainer.AddReferrals(welcomeInfo.Referrals, neighbor))
                    {
                        if (!neighbor.TrySetState(PeerNeighborState.Connected))
                        {
                            if (!(neighbor.State >= PeerNeighborState.Faulted))
                            {
                                throw Fx.AssertAndThrow("Neighbor state expected to be >= Faulted; it is " + neighbor.State.ToString());
                            }
                        }

                        if (neighborToClose != null)
                        {
                            // The other neighbor should be closed
                            SendTerminatingMessage(neighborToClose, action, closeReason2);
                            this.neighborManager.CloseNeighbor(neighborToClose, closeReason2, PeerCloseInitiator.LocalNode);
                        }
                    }
                    else
                    {
                        // Referrals were invalid this node is suspicous
                        closeReason = PeerCloseReason.InvalidNeighbor;
                    }
                }
                else
                {
                    closeReason = closeReason2;
                }
            }

            if (closeReason != PeerCloseReason.None)
            {
                SendTerminatingMessage(neighbor, PeerStrings.DisconnectAction, closeReason);
                this.neighborManager.CloseNeighbor(neighbor, closeReason, PeerCloseInitiator.LocalNode);
            }
        }
 public void Welcome(IPeerNeighbor neighbor, WelcomeInfo welcomeInfo)
 {
     if (this.state == State.Opened)
     {
         PeerCloseReason none = PeerCloseReason.None;
         if ((!neighbor.IsInitiator || !welcomeInfo.HasBody()) || ((neighbor.State != PeerNeighborState.Connecting) && (neighbor.State != PeerNeighborState.Closed)))
         {
             none = PeerCloseReason.InvalidNeighbor;
         }
         else if (this.RemoveTimer(neighbor))
         {
             PeerCloseReason reason2;
             IPeerNeighbor neighbor2;
             string action = "http://schemas.microsoft.com/net/2006/05/peer/Refuse";
             this.ValidateNeighbor(neighbor, welcomeInfo.NodeId, out neighbor2, out reason2, out action);
             if (neighbor != neighbor2)
             {
                 if (this.maintainer.AddReferrals(welcomeInfo.Referrals, neighbor))
                 {
                     if (!neighbor.TrySetState(PeerNeighborState.Connected) && (neighbor.State < PeerNeighborState.Faulted))
                     {
                         throw Fx.AssertAndThrow("Neighbor state expected to be >= Faulted; it is " + neighbor.State.ToString());
                     }
                     if (neighbor2 != null)
                     {
                         this.SendTerminatingMessage(neighbor2, action, reason2);
                         this.neighborManager.CloseNeighbor(neighbor2, reason2, PeerCloseInitiator.LocalNode);
                     }
                 }
                 else
                 {
                     none = PeerCloseReason.InvalidNeighbor;
                 }
             }
             else
             {
                 none = reason2;
             }
         }
         if (none != PeerCloseReason.None)
         {
             this.SendTerminatingMessage(neighbor, "http://schemas.microsoft.com/net/2006/05/peer/Disconnect", none);
             this.neighborManager.CloseNeighbor(neighbor, none, PeerCloseInitiator.LocalNode);
         }
     }
 }
 public void Connect(IPeerNeighbor neighbor, ConnectInfo connectInfo)
 {
     if (this.state == State.Opened)
     {
         PeerCloseReason none = PeerCloseReason.None;
         if ((neighbor.IsInitiator || !connectInfo.HasBody()) || ((neighbor.State != PeerNeighborState.Connecting) && (neighbor.State != PeerNeighborState.Closed)))
         {
             none = PeerCloseReason.InvalidNeighbor;
         }
         else if (this.RemoveTimer(neighbor))
         {
             if (this.neighborManager.ConnectedNeighborCount >= this.config.MaxNeighbors)
             {
                 none = PeerCloseReason.NodeBusy;
             }
             else if (!PeerValidateHelper.ValidNodeAddress(connectInfo.Address))
             {
                 none = PeerCloseReason.InvalidNeighbor;
             }
             else
             {
                 PeerCloseReason reason2;
                 IPeerNeighbor neighbor2;
                 string action = "http://schemas.microsoft.com/net/2006/05/peer/Refuse";
                 this.ValidateNeighbor(neighbor, connectInfo.NodeId, out neighbor2, out reason2, out action);
                 if (neighbor != neighbor2)
                 {
                     this.SendWelcome(neighbor);
                     try
                     {
                         neighbor.ListenAddress = connectInfo.Address;
                     }
                     catch (ObjectDisposedException exception)
                     {
                         DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);
                     }
                     if (!neighbor.TrySetState(PeerNeighborState.Connected) && (neighbor.State < PeerNeighborState.Disconnecting))
                     {
                         throw Fx.AssertAndThrow("Neighbor state expected to be >= Disconnecting; it is " + neighbor.State.ToString());
                     }
                     if (neighbor2 != null)
                     {
                         this.SendTerminatingMessage(neighbor2, action, reason2);
                         this.neighborManager.CloseNeighbor(neighbor2, reason2, PeerCloseInitiator.LocalNode);
                     }
                 }
                 else
                 {
                     none = reason2;
                 }
             }
         }
         if (none != PeerCloseReason.None)
         {
             this.SendTerminatingMessage(neighbor, "http://schemas.microsoft.com/net/2006/05/peer/Refuse", none);
             this.neighborManager.CloseNeighbor(neighbor, none, PeerCloseInitiator.LocalNode);
         }
     }
 }