Example #1
0
            public void Connect(ConnectInfo connect)
            {
                if (connect == null)
                {
                    throw new ArgumentNullException("connect");
                }
                var ch = OperationContext.Current.GetCallbackChannel <IPeerConnectorContract> ();

                connections.Add(connect.Address);
                // FIXME: check and reject if inappropriate. For example, maximum connection exceeded.
                using (var octx = new OperationContextScope((IContextChannel)ch)) {
                    OperationContext.Current.OutgoingMessageHeaders.To = new Uri(Constants.WsaAnonymousUri);
                    if (!owner.peers.Any(p => p.Address.EndpointAddress.Equals(connect.Address.EndpointAddress)))
                    {
                        owner.peers.Add(new RemotePeerConnection(connect.Address));
                    }
                    ch.Welcome(new WelcomeInfo()
                    {
                        NodeId = owner.node.NodeId
                    });
                }
            }
 void SendConnect(IPeerNeighbor neighbor)
 {
     // We do not attempt to send the message if PeerConnector is not open
     if (neighbor.State == PeerNeighborState.Connecting && this.state == State.Opened)
     {
         // Retrieve the local address. The retrieved address may be null if the node 
         // is shutdown. In that case, don't bother to send connect message since the 
         // node is closing...
         PeerNodeAddress listenAddress = this.config.GetListenAddress(true);
         if (listenAddress != null)
         {
             ConnectInfo connectInfo = new ConnectInfo(this.config.NodeId, listenAddress);
             Message message = ConnectInfoMessageConverter.ToMessage(connectInfo, MessageVersion.Soap12WSAddressing10);
             SendMessageToNeighbor(neighbor, message, OnConnectFailure);
         }
     }
 }
        //<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);
            }
        }
 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 SendConnect(IPeerNeighbor neighbor)
 {
     if ((neighbor.State == PeerNeighborState.Connecting) && (this.state == State.Opened))
     {
         PeerNodeAddress listenAddress = this.config.GetListenAddress(true);
         if (listenAddress != null)
         {
             ConnectInfo typedMessage = new ConnectInfo(this.config.NodeId, listenAddress);
             Message message = this.ConnectInfoMessageConverter.ToMessage(typedMessage, MessageVersion.Soap12WSAddressing10);
             this.SendMessageToNeighbor(neighbor, message, new PeerMessageHelpers.CleanupCallback(this.OnConnectFailure));
         }
     }
 }
Example #6
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);
            }
        }
 void IPeerServiceContract.Connect(ConnectInfo connectInfo)
 {
     IPeerNeighbor neighbor = this.GetNeighbor();
     if (neighbor != null)
     {
         this.connector.Connect(neighbor, connectInfo);
     }
 }