Example #1
0
        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();
            }
        }
Example #3
0
        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;
            }
        }