private void TryChoke(ChokeData data) { // Already choked if (data.Peer.AmChoking) { return; } if (!data.Peer.IsInterested) { // Choke him if he's not interested Choke(data.Peer); } else if (!_advertisedPieces.Exists(p => Equals(p.Peer, data.Peer))) { // If we have no free slots and peers are waiting, choke after 30 seconds. // FIXME: Choke as soon as the next piece completes *or* a larger time limit *and* // at least one piece has uploaded. data.LastChoked = DateTime.Now; Choke(data.Peer); } }
private void TryUnchoke(ChokeData data) { // Already unchoked if (!data.Peer.AmChoking) { return; } // Don't unchoke if he's not interested if (!data.Peer.IsInterested) { return; } // Don't unchoke if we are have maxed our slots if (_manager.UploadingTo >= _manager.Settings.UploadSlots) { return; } data.LastUnchoked = DateTime.Now; Unchoke(data.Peer); }
private void TryAdvertisePiece(ChokeData data) { // If we are seeding to this peer and we have a peer waiting to unchoke // don't advertise more data if (!data.Peer.AmChoking && PendingUnchoke) { return; } var advertised = _advertisedPieces.FindAll(p => Equals(p.Peer, data.Peer)).Count; int max; if (_manager.UploadingTo < _manager.Settings.UploadSlots) { max = MaxAdvertised; } else if (data.ShareRatio < 0.25) { max = 1; } else if (data.ShareRatio < 0.35) { max = 2; } else if (data.ShareRatio < 0.50) { max = 3; } else { max = MaxAdvertised; } if (advertised >= max) { return; } // List of pieces *not* in the swarm _temp.From(_bitfield).Not(); // List of pieces that he wants that aren't in the swarm _temp.NAnd(data.Peer.BitField); // Ignore all the pieces we've already started sharing foreach (var p in _advertisedPieces) { _temp[p.Index] = false; } var index = 0; while (advertised < max) { // Get the index of the first piece we can send him index = _temp.FirstTrue(index, _temp.Length); // Looks like he's not interested in us... if (index == -1) { return; } advertised++; data.TotalPieces++; data.CurrentPieces[index] = true; _advertisedPieces.Add(new SeededPiece(data.Peer, index, data.Peer.TorrentManager.Torrent.PieceLength / Piece.BlockSize)); data.Peer.Enqueue(new HaveMessage(index)); index++; } }