diff --git a/src/MonoTorrent/MonoTorrent.Client.Encryption/EncryptorFactory.cs b/src/MonoTorrent/MonoTorrent.Client.Encryption/EncryptorFactory.cs index 7035402b6..f647959fe 100644 --- a/src/MonoTorrent/MonoTorrent.Client.Encryption/EncryptorFactory.cs +++ b/src/MonoTorrent/MonoTorrent.Client.Encryption/EncryptorFactory.cs @@ -82,9 +82,8 @@ static async Task DoCheckIncomingConnectionAsync(IConnection co message.Decode(buffer, 0, buffer.Length); if (message.ProtocolString == VersionInfo.ProtocolStringV100) { - if (supportsPlainText) { + if (supportsPlainText) return new EncryptorResult (PlainTextEncryption.Instance, PlainTextEncryption.Instance, buffer); - } } else if (supportsRC4Header || supportsRC4Full) { @@ -96,7 +95,15 @@ static async Task DoCheckIncomingConnectionAsync(IConnection co if (encSocket.Decryptor is RC4 && !supportsRC4Full) throw new EncryptionException("Decryptor was RC4Full but that is not allowed"); + // As the connection was encrypted, the data we got from the initial Receive call will have + // been consumed during the crypto handshake process. Now that the encrypted handshake has + // been established, we should ensure we read the data again. var data = encSocket.InitialData?.Length > 0 ? encSocket.InitialData : null; + if (data == null && bytesToReceive > 0) { + data = buffer; + await NetworkIO.ReceiveAsync (connection, data, 0, data.Length, null, null, null); + encSocket.Decryptor.Decrypt (data); + } return new EncryptorResult (encSocket.Decryptor, encSocket.Encryptor, data); } diff --git a/src/MonoTorrent/MonoTorrent.Client/Managers/ListenManager.cs b/src/MonoTorrent/MonoTorrent.Client/Managers/ListenManager.cs index f6aa6f39f..25500159b 100644 --- a/src/MonoTorrent/MonoTorrent.Client/Managers/ListenManager.cs +++ b/src/MonoTorrent/MonoTorrent.Client/Managers/ListenManager.cs @@ -109,23 +109,9 @@ private async void ConnectionReceived(object sender, NewConnectionEventArgs e) var result = await EncryptorFactory.CheckIncomingConnectionAsync(id.Connection, id.Peer.Encryption, Engine.Settings, HandshakeMessage.HandshakeLength, skeys.ToArray()); id.Decryptor = result.Decryptor; id.Encryptor = result.Encryptor; - var initialData = result.InitialData; - if (initialData != null && initialData.Length != HandshakeMessage.HandshakeLength) - { - e.Connection.Dispose(); - return; - } - HandshakeMessage handshake; - if (initialData == null) - { - handshake = await PeerIO.ReceiveHandshakeAsync(id.Connection, id.Decryptor); - } - else - { - handshake = new HandshakeMessage(); - handshake.Decode(initialData, 0, initialData.Length); - } + var handshake = new HandshakeMessage(); + handshake.Decode(result.InitialData, 0, result.InitialData.Length); if (!await HandleHandshake(id, handshake)) e.Connection.Dispose(); }