/// <summary> /// Adds a node to the -addnode collection. /// <para> /// Usually called via RPC. /// </para> /// </summary> /// <param name="ipEndpoint">The endpoint of the peer to add.</param> public void AddNodeAddress(IPEndPoint ipEndpoint, bool excludeFromIpRangeFiltering = false) { Guard.NotNull(ipEndpoint, nameof(ipEndpoint)); if (excludeFromIpRangeFiltering && !this.ipRangeFilteringEndpointExclusions.Any(ip => ip.Match(ipEndpoint))) { this.logger.LogDebug("{0} will be excluded from IP range filtering.", ipEndpoint); this.ipRangeFilteringEndpointExclusions.Add(ipEndpoint); } this.peerAddressManager.AddPeer(ipEndpoint.MapToIpv6(), IPAddress.Loopback); if (!this.ConnectionSettings.RetrieveAddNodes().Any(p => p.Match(ipEndpoint))) { this.ConnectionSettings.AddAddNode(ipEndpoint); IPeerConnector addNodeConnector = this.PeerConnectors.FirstOrDefault(pc => pc is PeerConnectorAddNode); if (addNodeConnector != null) { addNodeConnector.MaxOutboundConnections++; } } else { this.logger.LogDebug("The endpoint already exists in the add node collection."); } }
/// <inheritdoc /> public void UpdateAndAssignMyExternalAddress(IPEndPoint ipEndPoint, bool suppliedEndPointIsFinal, int ipEndPointScore = 0) { lock (this.lockObject) { if (suppliedEndPointIsFinal) { this.MyExternalAddress = ipEndPoint; this.IsMyExternalAddressFinal = true; this.logger.LogTrace("(-)[SUPPLIED_FINAL]"); return; } if (this.IsMyExternalAddressFinal) { this.logger.LogTrace("(-)[EXISTING_FINAL]"); return; } // If it was the same as value that was there we just increment the score by 1. // Only the address portion is comparable, the port will be an ephemeral port != our server port if this is an outbound connection. So we replace it later with our configured port for self endpoint tracking. if (ipEndPoint.MapToIpv6().Address.Equals(this.MyExternalAddress.MapToIpv6().Address)) { this.MyExternalAddressPeerScore += 1; this.logger.LogTrace("(-)[SUPPLIED_EXISTING]"); return; } // If it was different we decrement the score by 1. this.MyExternalAddressPeerScore -= 1; this.logger.LogDebug("Different endpoint '{0}' supplied. Score decremented to {1}.", ipEndPoint, this.MyExternalAddressPeerScore); // If the new score is 0 we replace the old one with the new one with score 1. if (this.MyExternalAddressPeerScore <= 0) { var replacementEndpoint = new IPEndPoint(ipEndPoint.MapToIpv6().Address, this.MyExternalPort); this.logger.LogDebug( "Score for old endpoint '{0}' is <= 0. Updating endpoint to '{1}' and resetting peer score to 1.", this.MyExternalAddress, replacementEndpoint); this.MyExternalAddress = replacementEndpoint; this.MyExternalAddressPeerScore = 1; } } }
/// <summary> /// Creates a new peer address instance. /// </summary> /// <param name="endPoint">The end point of the peer.</param> public static PeerAddress Create(IPEndPoint endPoint) { return(new PeerAddress { ConnectionAttempts = 0, Endpoint = endPoint.MapToIpv6(), loopback = IPAddress.Loopback.ToString() }); }
public void UpdateWithSameExternalAddress_IsNotFinal_ExternalAddressIsUnchanged_AndPeerScoreIsIncremented() { var oldIpEndpoint = new IPEndPoint(IPAddress.Parse("1.2.3.4"), 1234); const int initialPeerScore = 1; this.selfEndpointTracker.UpdateAndAssignMyExternalAddress(oldIpEndpoint, false); this.selfEndpointTracker.UpdateAndAssignMyExternalAddress(oldIpEndpoint, false); Assert.True(this.selfEndpointTracker.MyExternalAddress.Address.Equals(oldIpEndpoint.MapToIpv6().Address)); Assert.Equal(initialPeerScore + 1, this.selfEndpointTracker.MyExternalAddressPeerScore); }
private void AddPeerWithoutCleanup(IPEndPoint endPoint, IPAddress source) { if (!endPoint.Address.IsRoutable(true)) { return; } IPEndPoint ipv6EndPoint = endPoint.MapToIpv6(); PeerAddress peerToAdd = PeerAddress.Create(ipv6EndPoint, source.MapToIPv6()); this.peerInfoByPeerAddress.TryAdd(ipv6EndPoint, peerToAdd); }
public void Ensure_IPGroups_Are_Filtered() { var ipAddress100 = IPAddress.Parse("::ffff:100.50.0.3"); var endPoint100 = new IPEndPoint(ipAddress100, 80); var ipAddress100_2 = IPAddress.Parse("::ffff:100.67.0.3"); var endPoint100_2 = new IPEndPoint(ipAddress100_2, 80); byte[] endPoint100Group = endPoint100.MapToIpv6().Address.GetGroup(); byte[] endPoint100_2Group = endPoint100_2.MapToIpv6().Address.GetGroup(); Assert.False(endPoint100_2Group.SequenceEqual(endPoint100Group)); }
/// <summary> /// Adds a node to the -addnode collection. /// <para> /// Usually called via RPC. /// </para> /// </summary> /// <param name="ipEndpoint">The endpoint of the peer to add.</param> public void AddNodeAddress(IPEndPoint ipEndpoint) { Guard.NotNull(ipEndpoint, nameof(ipEndpoint)); this.peerAddressManager.AddPeer(ipEndpoint.MapToIpv6(), IPAddress.Loopback); if (!this.ConnectionSettings.AddNode.Any(p => p.Match(ipEndpoint))) { this.ConnectionSettings.AddNode.Add(ipEndpoint); this.PeerConnectors.FirstOrDefault(pc => pc is PeerConnectorAddNode).MaxOutboundConnections++; } else this.logger.LogTrace("The endpoint already exists in the add node collection."); }
/// <summary> /// Determines if the peer should be disconnected. /// Peer should be disconnected in case it's IP is from the same group in which any other peer /// is and the peer wasn't added using -connect or -addNode command line arguments. /// </summary> private bool CheckIfPeerFromSameNetworkGroup(IReadOnlyNetworkPeerCollection networkPeers, IPEndPoint ipEndpoint, List <IPEndPoint> iprangeFilteringExclusions) { // Don't disconnect if range filtering is not turned on. if (!this.connectionManagerSettings.IpRangeFiltering) { this.logger.LogTrace("(-)[IP_RANGE_FILTERING_OFF]:false"); return(false); } // Don't disconnect if this peer has a local host address. if (ipEndpoint.Address.IsLocal()) { this.logger.LogTrace("(-)[IP_IS_LOCAL]:false"); return(false); } // Don't disconnect if this peer is in -addnode or -connect. if (this.connectionManagerSettings.RetrieveAddNodes().Union(this.connectionManagerSettings.Connect).Any(ep => ipEndpoint.MatchIpOnly(ep))) { this.logger.LogTrace("(-)[ADD_NODE_OR_CONNECT]:false"); return(false); } // Don't disconnect if this peer is in the exclude from IP range filtering group. if (iprangeFilteringExclusions.Any(ip => ip.MatchIpOnly(ipEndpoint))) { this.logger.LogTrace("(-)[PEER_IN_IPRANGEFILTER_EXCLUSIONS]:false"); return(false); } byte[] peerGroup = ipEndpoint.MapToIpv6().Address.GetGroup(); foreach (INetworkPeer connectedPeer in networkPeers) { if (ipEndpoint == connectedPeer.PeerEndPoint) { continue; } byte[] group = connectedPeer.PeerEndPoint.MapToIpv6().Address.GetGroup(); if (peerGroup.SequenceEqual(group)) { this.logger.LogTrace("(-)[SAME_GROUP]:true"); return(true); } } return(false); }
public void UpdateWithDifferentExternalAddress_IsNotFinal_ExternalAddressIsChanged_AndPeerScoreIsResetTo_1() { var oldIpEndpoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); var newIpEndpoint1 = new IPEndPoint(IPAddress.Parse("0.0.0.1"), 1); var newIpEndpoint2 = new IPEndPoint(IPAddress.Parse("0.0.0.2"), 2); var newIpEndpoint3 = new IPEndPoint(IPAddress.Parse("0.0.0.3"), 3); this.selfEndpointTracker.UpdateAndAssignMyExternalAddress(oldIpEndpoint, false); // When count reaches zero external address updates and score reset to 1. this.selfEndpointTracker.UpdateAndAssignMyExternalAddress(newIpEndpoint1, false); this.selfEndpointTracker.UpdateAndAssignMyExternalAddress(newIpEndpoint2, false); this.selfEndpointTracker.UpdateAndAssignMyExternalAddress(newIpEndpoint3, false); Assert.True(this.selfEndpointTracker.MyExternalAddress.Address.Equals(newIpEndpoint3.MapToIpv6().Address)); Assert.Equal(1, this.selfEndpointTracker.MyExternalAddressPeerScore); }
/// <summary> /// Adds a node to the -addnode collection. /// <para> /// Usually called via RPC. /// </para> /// </summary> /// <param name="ipEndpoint">The endpoint of the peer to add.</param> public void AddNodeAddress(IPEndPoint ipEndpoint) { Guard.NotNull(ipEndpoint, nameof(ipEndpoint)); this.logger.LogTrace("({0}:'{1}')", nameof(ipEndpoint), ipEndpoint); this.peerAddressManager.AddPeer(new NetworkAddress(ipEndpoint.MapToIpv6()), IPAddress.Loopback); if (!this.NodeSettings.ConnectionManager.AddNode.Any(p => p.Match(ipEndpoint))) { this.NodeSettings.ConnectionManager.AddNode.Add(ipEndpoint); this.PeerConnectors.FirstOrDefault(pc => pc is PeerConnectorAddNode).MaximumNodeConnections++; } else { this.logger.LogTrace("The endpoint already exists in the add node collection."); } this.logger.LogTrace("(-)"); }
private PeerAddress AddPeerWithoutCleanup(IPEndPoint endPoint, IPAddress source) { if (!endPoint.Address.IsRoutable(true)) { this.logger.LogTrace("(-)[PEER_NOT_ADDED_ISROUTABLE]:{0}", endPoint); return(null); } IPEndPoint ipv6EndPoint = endPoint.MapToIpv6(); PeerAddress peerToAdd = PeerAddress.Create(ipv6EndPoint, source.MapToIPv6()); var added = this.peerInfoByPeerAddress.TryAdd(ipv6EndPoint, peerToAdd); if (added) { this.logger.LogTrace("(-)[PEER_ADDED]:{0}", endPoint); return(peerToAdd); } this.logger.LogTrace("(-)[PEER_NOT_ADDED_ALREADY_EXISTS]:{0}", endPoint); return(null); }
/// <inheritdoc/> public void RemovePeer(IPEndPoint endPoint) { this.peerInfoByPeerAddress.TryRemove(endPoint.MapToIpv6(), out PeerAddress addr); }
/// <summary>Match the end point with another by IP and port.</summary> public static bool Match(this IPEndPoint endPoint, IPEndPoint matchWith) { return(endPoint.Address.ToString() == matchWith.MapToIpv6().Address.ToString() && endPoint.Port == matchWith.MapToIpv6().Port); }
/// <summary>Match the IP address only (the port is ignored).</summary> public static bool MatchIpOnly(this IPEndPoint endPoint, IPEndPoint matchWith) { return(endPoint.MapToIpv6().Address.ToString() == matchWith.MapToIpv6().Address.ToString()); }