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