Exemplo n.º 1
0
        /// <summary>
        /// Adds a checked-in client to the clientsByIdentityList.
        /// </summary>
        /// <param name="Client">Checked-in node's client to add.</param>
        /// <returns>true if the function succeeds, false otherwise. The function may fail only
        /// if there is an asynchrony in internal peer lists, which should never happen.</returns>
        public async Task <bool> AddCheckedInClient(Client Client)
        {
            log.Trace("(Client.Id:0x{0:X16})", Client.Id);

            bool res = false;

            PeerListItem peer             = null;
            PeerListItem clientToCheckOut = null;

            byte[] identityId = Client.IdentityId;

            lock (lockObject)
            {
                // First we find the peer in the list of all peers.
                if (peersByInternalId.ContainsKey(Client.Id))
                {
                    peer = peersByInternalId[Client.Id];

                    // Then we either have this identity checked-in using different network client,
                    // in which case we want to disconnect that old identity's connection and replace it with the new one.
                    clientsByIdentityId.TryGetValue(identityId, out clientToCheckOut);
                    clientsByIdentityId[identityId] = peer;

                    if (clientToCheckOut != null)
                    {
                        clientToCheckOut.Client.IsOurCheckedInClient = false;
                    }

                    Client.IsOurCheckedInClient = true;

                    res = true;
                }
            }

            if (res && (clientToCheckOut != null))
            {
                log.Info("Identity ID '{0}' has been checked-in already via network peer internal ID 0x{1:X16} and will now be disconnected.", Crypto.ToHex(identityId), clientToCheckOut.Client.Id);
                await clientToCheckOut.Client.CloseConnection();
            }

            if (!res)
            {
                log.Error("peersByInternalId does not contain peer with internal ID 0x{0:X16}.", Client.Id);
            }

            log.Trace("(-):{0}", res);
            return(res);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Assigns ID to a new network client and safely adds it to the peersByInternalId list.
        /// </summary>
        /// <param name="Client">Network client to add.</param>
        public void AddNetworkPeer(Client Client)
        {
            log.Trace("()");

            PeerListItem peer = new PeerListItem();

            peer.Client = Client;

            lock (lockObject)
            {
                peersByInternalId.Add(Client.Id, peer);
            }
            log.Trace("Client.Id is 0x{0:X16}.", Client.Id);

            log.Trace("(-)");
        }
Exemplo n.º 3
0
        /// <summary>
        /// Adds a network client with identity to the peersByIdentityList.
        /// </summary>
        /// <param name="Client">Network client to add.</param>
        /// <returns>true if the function succeeds, false otherwise. The function may fail only
        /// if there is an asynchrony in internal peer lists, which should never happen.</returns>
        public bool AddNetworkPeerWithIdentity(Client Client)
        {
            log.Trace("(Client.Id:0x{0:X16})", Client.Id);

            bool res = false;

            PeerListItem peer = null;

            byte[] identityId = Client.IdentityId;

            lock (lockObject)
            {
                // First we find the peer in the list of all peers.
                if (peersByInternalId.TryGetValue(Client.Id, out peer))
                {
                    // Then we either have this identity in peersByIdentityId list,
                    // in which case we add another "instance" to the list,
                    // or we create a new list for this peer.
                    List <PeerListItem> list = null;
                    bool listExists          = peersByIdentityId.TryGetValue(identityId, out list);

                    if (!listExists)
                    {
                        list = new List <PeerListItem>();
                    }

                    list.Add(peer);

                    if (!listExists)
                    {
                        peersByIdentityId.Add(identityId, list);
                    }
                    res = true;
                }
            }

            if (!res)
            {
                log.Error("peersByInternalId does not contain peer with internal ID 0x{0:X16}.", Client.Id);
            }

            log.Trace("(-):{0}", res);
            return(res);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Safely removes network client (peer) from all lists.
        /// </summary>
        /// <param name="Client">Network client to remove.</param>
        public void RemoveNetworkPeer(Client Client)
        {
            log.Trace("(Client.Id:0x{0:X16})", Client.Id);

            ulong internalId = Client.Id;

            byte[] identityId = Client.IdentityId;

            bool peerByInternalIdRemoveError   = false;
            bool peerByIdentityIdRemoveError   = false;
            bool clientByIdentityIdRemoveError = false;

            lock (lockObject)
            {
                // All peers should be in peersByInternalId list.
                if (peersByInternalId.ContainsKey(internalId))
                {
                    peersByInternalId.Remove(internalId);
                }
                else
                {
                    peerByInternalIdRemoveError = true;
                }

                if (identityId != null)
                {
                    // All peers with known Identity ID should be in peersByIdentityId list.
                    peerByIdentityIdRemoveError = true;
                    List <PeerListItem> list;
                    if (peersByIdentityId.TryGetValue(identityId, out list))
                    {
                        for (int i = 0; i < list.Count; i++)
                        {
                            PeerListItem peerListItem = list[i];
                            if (peerListItem.Client.Id == internalId)
                            {
                                list.RemoveAt(i);
                                peerByIdentityIdRemoveError = false;
                                break;
                            }
                        }

                        // If the list is empty, delete it.
                        if (list.Count == 0)
                        {
                            peersByIdentityId.Remove(identityId);
                        }
                    }

                    // Only checked-in clients are in clientsByIdentityId list.
                    // If a checked-in client was replaced by a new connection, its IsOurCheckedInClient field was set to false.
                    if (Client.IsOurCheckedInClient)
                    {
                        if (clientsByIdentityId.ContainsKey(identityId))
                        {
                            clientsByIdentityId.Remove(identityId);
                        }
                        else
                        {
                            clientByIdentityIdRemoveError = true;
                        }
                    }
                }
            }

            if (peerByInternalIdRemoveError)
            {
                log.Error("Peer internal ID 0x{0:X16} not found in peersByInternalId list.", internalId);
            }

            if (peerByIdentityIdRemoveError)
            {
                log.Error("Peer Identity ID '{0}' not found in peersByIdentityId list.", Crypto.ToHex(identityId));
            }

            if (clientByIdentityIdRemoveError)
            {
                log.Error("Checked-in client Identity ID '{0}' not found in clientsByIdentityId list.", Crypto.ToHex(identityId));
            }

            log.Trace("(-)");
        }