private bool CanRegister(NodeConnection connection) { if (cancellationToken.IsCancellationRequested) { return false; } if (connection.Direction == NodeConnectionDirection.Incoming) { if (incomingConnectionsCount >= maxIncomingConnectionsCount) { return false; } //todo: should IsConnected be checked for incoming connections? } else if (connection.Direction == NodeConnectionDirection.Outgoing) { if (outgoingConnectionsCount >= maxOutgoingConnectionsCount) { return false; } if (IsConnected(connection.Endpoint.PeerInfo.IpEndpoint.Address)) { return false; } } else { throw new InvalidOperationException($"Unexpected connection direction: {connection.Direction}."); } return true; }
private void Remove(NodeConnection connection) { lock (lockObject) { if (!connections.Remove(connection)) { return; } if (connection.Direction == NodeConnectionDirection.Incoming) { incomingConnectionsCount--; } else if (connection.Direction == NodeConnectionDirection.Outgoing) { outgoingConnectionsCount--; } else { throw new InvalidOperationException($"Unexpected connection direction: {connection.Direction}."); } } Changed?.Invoke(); }
/// <summary> /// Adds a connection to the collection. /// <para/> /// Can reject the connection if the cancellation token was cancelled or the maximum number of connections is reached. /// </summary> /// <param name="direction">The direction of the connection.</param> /// <param name="endpoint">The connection to a Bitcoin node.</param> /// <returns>true if the connection was accepted; otherwise false.</returns> public bool Add(NodeConnectionDirection direction, BitcoinEndpoint endpoint) { NodeConnection connection = new NodeConnection(direction, endpoint); lock (lockObject) { if (!CanRegister(connection)) { return false; } if (direction == NodeConnectionDirection.Incoming) { incomingConnectionsCount++; } else if (direction == NodeConnectionDirection.Outgoing) { outgoingConnectionsCount++; } else { throw new InvalidOperationException($"Unexpected connection direction: {direction}."); } connections.Add(connection); } endpoint.CallWhenDisconnected(() => Remove(connection)); Changed?.Invoke(); return true; }