async void ConnectionReceived(object sender, NewConnectionEventArgs e) { await ClientEngine.MainLoop; try { if (Engine.ConnectionManager.ShouldBanPeer(e.Peer)) { e.Connection.Dispose(); return; } if (!e.Connection.IsIncoming) { var id = new PeerId(e.Peer, e.Connection, e.TorrentManager.Bitfield?.Clone().SetAll(false)); id.LastMessageSent.Restart(); id.LastMessageReceived.Restart(); Engine.ConnectionManager.ProcessNewOutgoingConnection(e.TorrentManager, id); return; } logger.Info(e.Connection, "ConnectionReceived"); var supportedEncryptions = EncryptionTypes.GetSupportedEncryption(e.Peer.AllowedEncryption, Engine.Settings.AllowedEncryption); EncryptorFactory.EncryptorResult result = await EncryptorFactory.CheckIncomingConnectionAsync(e.Connection, supportedEncryptions, SKeys); if (!await HandleHandshake(e.Peer, e.Connection, result.Handshake, result.Decryptor, result.Encryptor)) { e.Connection.Dispose(); } } catch { e.Connection.Dispose(); } }
async void ConnectionReceived(object?sender, PeerConnectionEventArgs e) { await ClientEngine.MainLoop; var peer = new Peer("", e.Connection.Uri, EncryptionTypes.All); try { if (Engine.ConnectionManager.ShouldBanPeer(peer)) { e.Connection.Dispose(); return; } if (!e.Connection.IsIncoming) { var manager = Engine.Torrents.FirstOrDefault(t => t.InfoHashes.Contains(e.InfoHash !)) !; var id = new PeerId(peer, e.Connection, new BitField(manager.Bitfield.Length).SetAll(false)); id.LastMessageSent.Restart(); id.LastMessageReceived.Restart(); Engine.ConnectionManager.ProcessNewOutgoingConnection(manager, id); return; } logger.Info(e.Connection, "ConnectionReceived"); var supportedEncryptions = EncryptionTypes.GetSupportedEncryption(peer.AllowedEncryption, Engine.Settings.AllowedEncryption); EncryptorFactory.EncryptorResult result = await EncryptorFactory.CheckIncomingConnectionAsync(e.Connection, supportedEncryptions, SKeys, Engine.Factories); if (!await HandleHandshake(peer, e.Connection, result.Handshake !, result.Decryptor, result.Encryptor)) { e.Connection.Dispose(); } } catch { e.Connection.Dispose(); } }
async void ConnectionReceived(object sender, NewConnectionEventArgs e) { await ClientEngine.MainLoop; try { if (Engine.ConnectionManager.ShouldBanPeer(e.Peer)) { e.Connection.Dispose(); return; } if (!e.Connection.IsIncoming) { var id = new PeerId(e.Peer, e.Connection, e.TorrentManager.Bitfield?.Clone().SetAll(false)); id.LastMessageSent.Restart(); id.LastMessageReceived.Restart(); Engine.ConnectionManager.ProcessNewOutgoingConnection(e.TorrentManager, id); return; } Logger.Log(e.Connection, "ListenManager - ConnectionReceived"); var skeys = new List <InfoHash> (); for (int i = 0; i < Engine.Torrents.Count; i++) { skeys.Add(Engine.Torrents[i].InfoHash); } IConnection2 connection = ConnectionConverter.Convert(e.Connection); EncryptorFactory.EncryptorResult result = await EncryptorFactory.CheckIncomingConnectionAsync(connection, e.Peer.AllowedEncryption, Engine.Settings, skeys.ToArray()); if (!await HandleHandshake(e.Peer, connection, result.Handshake, result.Decryptor, result.Encryptor)) { connection.Dispose(); } } catch { e.Connection.Dispose(); } }
internal async void ProcessNewOutgoingConnection(TorrentManager manager, PeerId id) { // If we have too many open connections, close the connection if (OpenConnections > MaxOpenConnections) { CleanupSocket(manager, id); return; } manager.Peers.ActivePeers.Add(id.Peer); manager.Peers.ConnectedPeers.Add(id); Interlocked.Increment(ref openConnections); try { // Create a handshake message to send to the peer var handshake = new HandshakeMessage(manager.InfoHash, LocalPeerId, VersionInfo.ProtocolStringV100); var preferredEncryption = EncryptionTypes.GetPreferredEncryption(id.Peer.AllowedEncryption, Settings.AllowedEncryption); EncryptorFactory.EncryptorResult result = await EncryptorFactory.CheckOutgoingConnectionAsync(id.Connection, preferredEncryption, manager.InfoHash, handshake); id.Decryptor = result.Decryptor; id.Encryptor = result.Encryptor; } catch { // If an exception is thrown it's because we tried to establish an encrypted connection and something went wrong if (id.Peer.AllowedEncryption.Contains(EncryptionType.PlainText)) { id.Peer.AllowedEncryption = EncryptionTypes.PlainText; } else { id.Peer.AllowedEncryption = EncryptionTypes.None; } manager.RaiseConnectionAttemptFailed(new ConnectionAttemptFailedEventArgs(id.Peer, ConnectionFailureReason.EncryptionNegiotiationFailed, manager)); CleanupSocket(manager, id); // CleanupSocket will contain the peer only if AllowedEncryption is not set to None. If // the peer was re-added, then we should try to reconnect to it immediately to try an // unencrypted connection. if (manager.Peers.AvailablePeers.Remove(id.Peer)) { ConnectToPeer(manager, id.Peer); } return; } try { // Receive their handshake HandshakeMessage handshake = await PeerIO.ReceiveHandshakeAsync(id.Connection, id.Decryptor); manager.Mode.HandleMessage(id, handshake); } catch { // If we choose plaintext and it resulted in the connection being closed, remove it from the list. id.Peer.AllowedEncryption = EncryptionTypes.Remove(id.Peer.AllowedEncryption, id.EncryptionType); manager.RaiseConnectionAttemptFailed(new ConnectionAttemptFailedEventArgs(id.Peer, ConnectionFailureReason.HandshakeFailed, manager)); CleanupSocket(manager, id); // CleanupSocket will contain the peer only if AllowedEncryption is not set to None. If // the peer was re-added, then we should try to reconnect to it immediately to try an // encrypted connection, assuming the previous connection was unencrypted and it failed. if (manager.Peers.AvailablePeers.Remove(id.Peer)) { ConnectToPeer(manager, id.Peer); } return; } try { if (id.BitField.Length != manager.Bitfield.Length) { throw new TorrentException($"The peer's bitfield was of length {id.BitField.Length} but the TorrentManager's bitfield was of length {manager.Bitfield.Length}."); } manager.HandlePeerConnected(id); id.MessageQueue.SetReady(); TryProcessQueue(manager, id); ReceiveMessagesAsync(id.Connection, id.Decryptor, manager.DownloadLimiters, id.Monitor, manager, id); id.WhenConnected.Restart(); id.LastBlockReceived.Restart(); } catch { manager.RaiseConnectionAttemptFailed(new ConnectionAttemptFailedEventArgs(id.Peer, ConnectionFailureReason.Unknown, manager)); CleanupSocket(manager, id); return; } }