private void HandleHandshake(PeerId id, HandshakeMessage message) { TorrentManager man = null; try { if (message.ProtocolString != VersionInfo.ProtocolStringV100) { throw new ProtocolException("Invalid protocol string in handshake"); } } catch (Exception ex) { Debug.WriteLine(id.Connection, ex.Message); id.Connection.Dispose(); return; } man = Engine.Torrents.FirstOrDefault(t => message.InfoHash == t.InfoHash); ClientEngine.MainLoop.QueueWait(delegate { foreach (var t in Engine.Torrents.Where(t => message.InfoHash == t.InfoHash)) { man = t; } }); //FIXME: #warning FIXME: Don't stop the message loop until Dispose() and track all incoming connections if (man == null) // We're not hosting that torrent { //Debug.WriteLine("ListenManager - Handshake requested nonexistant torrent"); id.Connection.Dispose(); return; } if (man.State == TorrentState.Stopped) { Debug.WriteLine("ListenManager - Handshake requested for torrent which is not running"); id.Connection.Dispose(); return; } if (!man.Mode.CanAcceptConnections) { Debug.WriteLine("ListenManager - Current mode does not support connections"); id.Connection.Dispose(); return; } id.Peer.PeerId = message.PeerId; id.TorrentManager = man; // If the handshake was parsed properly without encryption, then it definitely was not encrypted. If this is not allowed, abort if ((id.Encryptor is PlainTextEncryption && !Toolbox.HasEncryption(Engine.Settings.AllowedEncryption, EncryptionTypes.PlainText)) && ClientEngine.SupportsEncryption) { Debug.WriteLine("ListenManager - Encryption is required but was not active"); id.Connection.Dispose(); return; } message.Handle(id); Debug.WriteLine("ListenManager - Handshake successful handled"); id.ClientApp = new Software(message.PeerId); message = new HandshakeMessage(id.TorrentManager.InfoHash, Engine.PeerId, VersionInfo.ProtocolStringV100); var callback = Engine.ConnectionManager.IncomingConnectionAcceptedCallback; PeerIO.EnqueueSendMessage(id.Connection, id.Encryptor, message, id.TorrentManager.UploadLimiter, id.Monitor, id.TorrentManager.Monitor, callback, id); }
/// <summary> /// Creates a new inactive peer manager for a torrent manager /// </summary> /// <param name="torrentManager">The torrent manager this choke/unchoke manager belongs to</param> public InactivePeerManager(TorrentManager torrentManager) { _owningTorrent = torrentManager; }