/// <summary> /// Adds a checked-in client to the clientsByIdentityList. /// </summary> /// <param name="Client">Checked-in profile server'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(IncomingClient Client) { log.Trace("(Client.Id:{0})", Client.Id.ToHex()); 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 {1} and will now be disconnected.", identityId.ToHex(), clientToCheckOut.Client.Id.ToHex()); await clientToCheckOut.Client.CloseConnectionAsync(); } if (!res) { log.Error("peersByInternalId does not contain peer with internal ID {0}.", Client.Id.ToHex()); } log.Trace("(-):{0}", res); return(res); }
/// <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(IncomingClient Client) { log.Trace("()"); PeerListItem peer = new PeerListItem(); peer.Client = Client; lock (lockObject) { peersByInternalId.Add(Client.Id, peer); } log.Trace("Client.Id is {0}.", Client.Id.ToHex()); log.Trace("(-)"); }
/// <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(IncomingClient Client) { log.Trace("(Client.Id:{0})", Client.Id.ToHex()); 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 {0}.", Client.Id.ToHex()); } log.Trace("(-):{0}", res); return(res); }
/// <summary> /// Safely removes network client (peer) from all lists. /// </summary> /// <param name="Client">Network client to remove.</param> public void RemoveNetworkPeer(IncomingClient Client) { log.Trace("(Client.Id:{0})", Client.Id.ToHex()); 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 {0} not found in peersByInternalId list.", internalId.ToHex()); } if (peerByIdentityIdRemoveError) { log.Error("Peer Identity ID '{0}' not found in peersByIdentityId list.", identityId.ToHex()); } if (clientByIdentityIdRemoveError) { log.Error("Checked-in client Identity ID '{0}' not found in clientsByIdentityId list.", identityId.ToHex()); } log.Trace("(-)"); }