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); } } }
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); } } }
// 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); } } } }
// 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); }
// 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()); } }
//<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); } }
// 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()); } }
// 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); } }
//<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); } }
// 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); } } } }
// 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); }
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()); } } }
// 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); } }