internal static IAsyncResult BeginCheckEncryption(PeerId id, int bytesToReceive, AsyncCallback callback,
object state, InfoHash[] sKeys)
{
var result = new EncryptorAsyncResult(id, callback, state) {SKeys = sKeys};
var c = id.Connection;
ClientEngine.MainLoop.QueueTimeout(TimeSpan.FromSeconds(10), delegate
{
if (id.Encryptor == null || id.Decryptor == null)
id.CloseConnection();
return false;
});
try
{
// If the connection is incoming, receive the handshake before
// trying to decide what encryption to use
if (id.Connection.IsIncoming)
{
result.Buffer = new byte[bytesToReceive];
NetworkIO.EnqueueReceive(c, result.Buffer, 0, result.Buffer.Length, null, null, null,
HandshakeReceivedCallback, result);
}
else
{
var usable = CheckRc4(id);
var hasPlainText = Toolbox.HasEncryption(usable, EncryptionTypes.PlainText);
var hasRc4 = Toolbox.HasEncryption(usable, EncryptionTypes.RC4Full) ||
Toolbox.HasEncryption(usable, EncryptionTypes.RC4Header);
if (id.Engine.Settings.PreferEncryption)
{
if (hasRc4)
{
result.EncSocket = new PeerAEncryption(id.TorrentManager.InfoHash, usable);
result.EncSocket.BeginHandshake(id.Connection, CompletedEncryptedHandshakeCallback, result);
}
result.Complete();
}
else
{
if (hasPlainText)
{
result.Complete();
}
else
{
result.EncSocket = new PeerAEncryption(id.TorrentManager.InfoHash, usable);
result.EncSocket.BeginHandshake(id.Connection, CompletedEncryptedHandshakeCallback, result);
}
}
}
}
catch (Exception ex)
{
result.Complete(ex);
}
return result;
}