private void PeerHandshakeReceived(bool succeeded, PeerMessage message, object state) { PeerId id = (PeerId)state; if (!succeeded) { CleanupSocket(id, "Handshaking failed"); return; } try { message.Handle(id); // If there are any pending messages, send them otherwise set the queue // processing as finished. if (id.QueueLength > 0) { id.ConnectionManager.ProcessQueue(id); } else { id.ProcessingQueue = false; } PeerIO.EnqueueReceiveMessage(id.Connection, id.Decryptor, id.TorrentManager.DownloadLimiter, id.Monitor, id.TorrentManager, messageReceivedCallback, id); // Alert the engine that there is a new usable connection id.TorrentManager.HandlePeerConnected(id, Direction.Outgoing); } catch (TorrentException ex) { CleanupSocket(id, ex.Message); } }
private void MessageReceived(bool successful, PeerMessage message, object state) { PeerId id = (PeerId)state; if (!successful) { id.ConnectionManager.CleanupSocket(id, "Could not receive a message"); return; } try { PeerMessageEventArgs e = new PeerMessageEventArgs(id.TorrentManager, (PeerMessage)message, Direction.Incoming, id); id.ConnectionManager.RaisePeerMessageTransferred(e); message.Handle(id); id.LastMessageReceived = DateTime.Now; PeerIO.EnqueueReceiveMessage(id.Connection, id.Decryptor, id.TorrentManager.DownloadLimiter, id.Monitor, id.TorrentManager, messageReceivedCallback, id); } catch (TorrentException ex) { id.ConnectionManager.CleanupSocket(id, ex.Message); } }
void DownloadLogic(int counter) { // FIXME: Hardcoded 15kB/sec - is this ok? if ((DateTime.Now - manager.StartTime) > TimeSpan.FromSeconds(20)) { foreach (string s in manager.Torrent.GetRightHttpSeeds) { string peerId = "-WebSeed-"; peerId = peerId + (webseedCount++).ToString().PadLeft(20 - peerId.Length, '0'); Uri uri = new Uri(s); // HACK: Don't want to add more than 10 same webseed (sometimes webseeds stuck) if (manager.Peers.ConnectedPeers.FindAll(p => p.Uri.Host.Equals(uri.Host)).Count > 9) { continue; } // Dont' want to add more than 2 same webseed if current webseeds is active (speed more than 5Kbs. if (manager.Peers.ConnectedPeers.FindAll(p => p.Uri.Host.Equals(uri.Host) && p.Monitor.DownloadSpeed > 5 * 1024 ).Count > 1 ) { continue; } Peer peer = new Peer(peerId, uri); PeerId id = new PeerId(peer, manager); HttpConnection connection = new HttpConnection(new Uri(s)); connection.Manager = this.manager; peer.IsSeeder = true; id.BitField.SetAll(true); id.Encryptor = new PlainTextEncryption(); id.Decryptor = new PlainTextEncryption(); id.IsChoking = false; id.AmInterested = !manager.Complete; id.Connection = connection; id.ClientApp = new Software(id.PeerID); manager.Peers.ConnectedPeers.Add(id); manager.RaisePeerConnected(new PeerConnectionEventArgs(manager, id, Direction.Outgoing)); PeerIO.EnqueueReceiveMessage(id.Connection, id.Decryptor, Manager.DownloadLimiter, id.Monitor, id.TorrentManager, id.ConnectionManager.messageReceivedCallback, id); } } // Remove inactive peers we haven't heard from if we're downloading if (manager.State == TorrentState.Downloading && manager.lastCalledInactivePeerManager + TimeSpan.FromSeconds(5) < DateTime.Now) { manager.InactivePeerManager.TimePassed(); manager.lastCalledInactivePeerManager = DateTime.Now; } // Now choke/unchoke peers; first instantiate the choke/unchoke manager if we haven't done so already if (manager.chokeUnchoker == null) { manager.chokeUnchoker = new ChokeUnchokeManager(manager, manager.Settings.MinimumTimeBetweenReviews, manager.Settings.PercentOfMaxRateToSkipReview); } manager.chokeUnchoker.UnchokeReview(); }
void DownloadLogic(int counter) { // FIXME: Hardcoded 15kB/sec - is this ok? if ((DateTime.Now - manager.StartTime) > TimeSpan.FromMinutes(1) && manager.Monitor.DownloadSpeed < 15 * 1024) { foreach (string s in manager.Torrent.GetRightHttpSeeds) { try { string peerId = "-WebSeed-"; peerId = peerId + (webseedCount++).ToString().PadLeft(20 - peerId.Length, '0'); Uri uri = new Uri(s); Peer peer = new Peer(peerId, uri); PeerId id = new PeerId(peer, manager); HttpConnection connection = new HttpConnection(new Uri(s)); connection.Manager = this.manager; peer.IsSeeder = true; id.BitField.SetAll(true); id.Encryptor = new PlainTextEncryption(); id.Decryptor = new PlainTextEncryption(); id.IsChoking = false; id.AmInterested = !manager.Complete; id.Connection = connection; id.ClientApp = new Software(id.PeerID); manager.Peers.ConnectedPeers.Add(id); manager.RaisePeerConnected(new PeerConnectionEventArgs(manager, id, Direction.Outgoing)); PeerIO.EnqueueReceiveMessage(id.Connection, id.Decryptor, Manager.DownloadLimiter, id.Monitor, id.TorrentManager, id.ConnectionManager.messageReceivedCallback, id); } catch (UriFormatException) { logger.Info("Invalid web seed uri '{0}'", s); } } // FIXME: In future, don't clear out this list. It may be useful to keep the list of HTTP seeds // Add a boolean or something so that we don't add them twice. manager.Torrent.GetRightHttpSeeds.Clear(); } // Remove inactive peers we haven't heard from if we're downloading if (manager.State == TorrentState.Downloading && manager.lastCalledInactivePeerManager + TimeSpan.FromSeconds(5) < DateTime.Now) { manager.InactivePeerManager.TimePassed(); manager.lastCalledInactivePeerManager = DateTime.Now; } // Now choke/unchoke peers; first instantiate the choke/unchoke manager if we haven't done so already if (manager.chokeUnchoker == null) { manager.chokeUnchoker = new ChokeUnchokeManager(manager, manager.Settings.MinimumTimeBetweenReviews, manager.Settings.PercentOfMaxRateToSkipReview); } manager.chokeUnchoker.UnchokeReview(); }
/// <summary> /// This method is called when the ClientEngine recieves a valid incoming connection /// </summary> /// <param name="result"></param> private void IncomingConnectionAccepted(bool succeeded, int count, object state) { PeerId id = (PeerId)state; try { if (!succeeded) { var args = new PeerConnectionFailedEventArgs(id.TorrentManager, id.Peer, Direction.Incoming, "Incoming connection coult not be accepted"); id.TorrentManager.RaiseConnectionAttemptFailed(args); } bool maxAlreadyOpen = (OpenConnections >= this.MaxOpenConnections) || (id.TorrentManager.OpenConnections >= id.TorrentManager.Settings.MaxConnections); if (!succeeded || id.Peer.PeerId == engine.PeerId || maxAlreadyOpen) { CleanupSocket(id, "Connection was not accepted"); return; } if (id.TorrentManager.Peers.ActivePeers.Contains(id.Peer)) { logger.Error("Already connected to peer {0}", id.Peer); id.Connection.Dispose(); return; } logger.Info("Incoming connection fully accepted {0}, total {1}", id.Peer, OpenConnections); id.TorrentManager.Peers.AvailablePeers.Remove(id.Peer); id.TorrentManager.Peers.ActivePeers.Add(id.Peer); id.TorrentManager.Peers.ConnectedPeers.Add(id); id.WhenConnected = DateTime.Now; // Baseline the time the last block was received id.LastBlockReceived = DateTime.Now; id.TorrentManager.HandlePeerConnected(id, Direction.Incoming); // We've sent our handshake so begin our looping to receive incoming message PeerIO.EnqueueReceiveMessage(id.Connection, id.Decryptor, id.TorrentManager.DownloadLimiter, id.Monitor, id.TorrentManager, messageReceivedCallback, id); } catch (Exception e) { CleanupSocket(id, e.Message); } }
public void InvalidMessage() { bool success = true; ManualResetEvent handle = new ManualResetEvent(false); Buffer.BlockCopy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(16)), 0, data, 0, 4); for (int i = 4; i < 16; i++) { data [i] = byte.MaxValue; } PeerIO.EnqueueReceiveMessage(Incoming, new PlainTextEncryption(), null, null, null, (successful, count, state) => { success = successful; handle.Set(); }, null); NetworkIO.EnqueueSend(Outgoing, data, 0, 20, null, null, null, delegate { }, null); Assert.IsTrue(handle.WaitOne(TimeSpan.FromSeconds(4)), "#Should have closed");; Assert.IsFalse(success, "#1"); }
public void ReceiveTwoKeepAlives() { var message = new KeepAliveMessage(); var buffer = message.Encode(); var handle = new AutoResetEvent(false); NetworkIO.EnqueueSend(Outgoing, buffer, 0, buffer.Length, null, null, null, delegate { }, null); NetworkIO.EnqueueSend(Outgoing, buffer, 0, buffer.Length, null, null, null, delegate { }, null); AsyncMessageReceivedCallback callback = (s, m, state) => { if (s && m is KeepAliveMessage) { handle.Set(); } }; PeerIO.EnqueueReceiveMessage(Incoming, new PlainTextEncryption(), null, null, null, callback, null); Assert.IsTrue(handle.WaitOne(TimeSpan.FromSeconds(2)), "#Should receive first message"); PeerIO.EnqueueReceiveMessage(Incoming, new PlainTextEncryption(), null, null, null, callback, null); Assert.IsTrue(handle.WaitOne(TimeSpan.FromSeconds(2)), "#Should receive second message"); }