예제 #1
0
        // Returns whether or not a peer is connected already
        private bool IsPeerConnected(PeerCandidate Peer)
        {
            // Check whether the peer candidate is this node
            if (Peer.Id == Id)
            {
                return(true);
            }

            // Lock peer list to prevent race conditions
            lock (PeerList)
            {
                // Check if the connected peer list contains this peer
                if (PeerList.Any(x => x.Id == Peer.Id))
                {
                    return(true);
                }

                // Check if any incoming connections have this address + port
                if (P2pServer.PendingConnections.Any(x => x.Client.RemoteEndPoint.ToString() == $"{Peer.Address}:{Peer.Port}"))
                {
                    return(true);
                }
            }

            // Peer is not connected
            return(false);
        }
예제 #2
0
        // Adds a peer to the candidate list or updates an existing candidate
        private void AddPeerCandidate(PeerCandidate Peer)
        {
            // Lock peer candidate list to prevent race conditions
            lock (PeerCandidatesGreyList)
            {
                // Peer exists in the list already
                if (PeerCandidatesGreyList.Any(x => x.Id == Peer.Id))
                {
                    // Find peer in the list
                    var LocalPeer = PeerCandidatesGreyList.First(x => x.Id == Peer.Id);

                    // Update peer's last seen time
                    if (LocalPeer.LastSeen < Peer.LastSeen)
                    {
                        LocalPeer.LastSeen = Peer.LastSeen;
                    }
                }

                // Peer has not yet been added
                else
                {
                    // Add peer to the candidate list
                    PeerCandidatesGreyList.Add(Peer);
                }
            }
        }
예제 #3
0
 // Returns whether or not a peer is blacklisted
 private bool IsPeerAllowed(PeerCandidate Peer)
 {
     // Lock list to prevent race conditions
     lock (RecentlyTriedPeerCandidates)
     {
         // Return whether or not the recently tried peer list contains this peer
         return(RecentlyTriedPeerCandidates.Contains(Peer.Id));
     }
 }
예제 #4
0
 // Adds a peer to the list of recently tried peers
 private void AddRecentlyTriedPeer(PeerCandidate Peer)
 {
     // Lock list to prevent race conditions
     lock (RecentlyTriedPeerCandidates)
     {
         // Add the peer id to the list
         RecentlyTriedPeerCandidates.Add(Peer.Id);
     }
 }
예제 #5
0
        // Attempts to connect to a new peer on the peer candidate list
        private void DiscoverNewPeer()
        {
            // Do nothing if not running
            if (Stopped)
            {
                return;
            }

            // Check if discovery is enabled
            if (!Globals.P2P_DISCOVERY_ENABLED)
            {
                return;
            }

            // Check if discovery is already active
            if (DiscoveryActive)
            {
                return;
            }
            DiscoveryActive = true;

            // Check if the peer list has space for a new peer
            if (GetPeerCount() >= Globals.P2P_MAX_PEER_CONNECTIONS)
            {
                return;
            }

            // Get the peer candidate list
            List <PeerCandidate> Candidates = GetPeerCandidates();

            // Check if there are candidates in the list
            if (Candidates.Count == 0)
            {
                return;
            }

            // Setup variables
            int        TryCount     = 0;
            int        RandomCount  = 0;
            int        MaxIndex     = Math.Min(Candidates.Count - 1, 50);
            List <int> TriedIndexes = new List <int>();

            // Loop to try a selection of candidates
            while (RandomCount < (MaxIndex + 1) * 3 && TryCount < 10 && !Stopped)
            {
                // Increment random count and get net random index
                RandomCount++;
                int RandomIndex = SecureRandom.Integer(0, MaxIndex + 1);
                RandomIndex = (RandomIndex * RandomIndex * RandomIndex) / (MaxIndex * MaxIndex);

                // Check if this index has been tried previously
                if (TriedIndexes.Contains(RandomIndex))
                {
                    continue;
                }

                // Add this index to the tried indexes list
                TriedIndexes.Add(RandomIndex);

                // Get the peer candidate
                PeerCandidate Peer = Candidates[RandomIndex];

                // Increment try count
                TryCount++;

                // Check if this peer is already connected
                if (IsPeerConnected(Peer))
                {
                    continue;
                }

                // TODO - check if we are allowing remote connections??

                // Check if this peer has previously been blacklists
                if (IsPeerAllowed(Peer))
                {
                    return;
                }

                // Attempt to add this peer candidate
                Logger.Debug($"[{TryCount}/10] Trying candidate #{RandomIndex} {Peer.Address}:{Peer.Port}, last seen {GetTimeDelta(Peer.LastSeen)} seconds ago");
                if (!AddPeer(Peer.Address, (int)Peer.Port))
                {
                    // Add to failed connection list
                    AddRecentlyTriedPeer(Peer);
                }
            }

            // Discovery process finished
            DiscoveryActive = false;
        }