/// <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;
                }
            }
        }
示例#3
0
 /// <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));
        }
示例#7
0
        /// <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);
        }
示例#10
0
        /// <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("(-)");
        }
示例#11
0
        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);
 }
示例#13
0
 /// <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);
 }
示例#14
0
 /// <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());
 }