/// <summary> /// Checks the send queue of the peer to see if there are any outstanding pieces which they requested /// and rejects them as necessary /// </summary> /// <param name="Peer"> </param> private void RejectPendingRequests(PeerId Peer) { var length = Peer.QueueLength; for (var i = 0; i < length; i++) { var message = Peer.Dequeue(); var pieceMessage = message as PieceMessage; if (pieceMessage == null) { Peer.Enqueue(message); continue; } // If the peer doesn't support fast peer, then we will never requeue the message if (!(Peer.SupportsFastPeer && ClientEngine.SupportsFastPeer)) { Peer.IsRequestingPiecesCount--; continue; } // If the peer supports fast peer, queue the message if it is an AllowedFast piece // Otherwise send a reject message for the piece if (Peer.AmAllowedFastPieces.Contains(pieceMessage.PieceIndex)) { Peer.Enqueue(pieceMessage); } else { Peer.IsRequestingPiecesCount--; Peer.Enqueue(new RejectRequestMessage(pieceMessage)); } } }
internal void AddPieceRequests(PeerId id) { PeerMessage msg; int maxRequests = id.MaxPendingRequests; if (id.AmRequestingPiecesCount >= maxRequests) { return; } int count = 1; if (id.Connection is HttpConnection) { // How many whole pieces fit into 2MB count = (2 * 1024 * 1024) / id.TorrentManager.Torrent.PieceLength; // Make sure we have at least one whole piece count = Math.Max(count, 1); count *= id.TorrentManager.Torrent.PieceLength / Piece.BlockSize; } if (!id.IsChoking || id.SupportsFastPeer) { while (id.AmRequestingPiecesCount < maxRequests) { msg = Picker.ContinueExistingRequest(id); if (msg != null) { id.Enqueue(msg); } else { break; } } } if (!id.IsChoking || (id.SupportsFastPeer && id.IsAllowedFastPieces.Count > 0)) { while (id.AmRequestingPiecesCount < maxRequests) { msg = Picker.PickPiece(id, id.TorrentManager.Peers.ConnectedPeers, count); if (msg != null) { id.Enqueue(msg); } else { break; } } } }
protected virtual void HandleLtMetadataMessage(PeerId id, LTMetadata message) { if (message.MetadataMessageType == LTMetadata.eMessageType.Request) { if (id.TorrentManager.HasMetadata) { id.Enqueue(new LTMetadata(id, LTMetadata.eMessageType.Data, message.Piece, id.TorrentManager.Torrent.Metadata)); } else { id.Enqueue(new LTMetadata(id, LTMetadata.eMessageType.Reject, message.Piece)); } } }
protected virtual void SetAmInterestedStatus(PeerId id, bool interesting) { if (interesting && !id.AmInterested) { id.AmInterested = true; id.Enqueue(new InterestedMessage()); // He's interesting, so attempt to queue up any FastPieces (if that's possible) _manager.PieceManager.AddPieceRequests(id); } else if (!interesting && id.AmInterested) { id.AmInterested = false; id.Enqueue(new NotInterestedMessage()); } }
public virtual void Unchoke(PeerId id) { id.AmChoking = false; id.TorrentManager.UploadingTo++; id.Enqueue(new UnchokeMessage()); id.LastUnchoked = DateTime.Now; }
public virtual void Unchoke(PeerId id) { id.AmChoking = false; id.TorrentManager.UploadingTo++; id.Enqueue(new UnchokeMessage()); id.LastUnchoked = DateTime.Now; }
public virtual void HandlePeerConnected(PeerId id, Direction direction) { var bundle = new MessageBundle(); AppendBitfieldMessage(id, bundle); AppendExtendedHandshake(id, bundle); AppendFastPieces(id, bundle); id.Enqueue(bundle); }
private void RequestNextNeededPiece(PeerId id) { var index = _bitField.FirstFalse(); if (index == -1) { return; //throw exception or switch to regular? } var m = new LTMetadata(id, LTMetadata.eMessageType.Request, index); id.Enqueue(m); _requestTimeout = DateTime.Now.Add(Timeout); }
protected virtual void HandleCancelMessage(PeerId id, CancelMessage message) { for (var i = 0; i < id.QueueLength; i++) { var msg = id.Dequeue(); if (!(msg is PieceMessage)) { id.Enqueue(msg); continue; } var piece = msg as PieceMessage; if ( !(piece.PieceIndex == message.PieceIndex && piece.StartOffset == message.StartOffset && piece.RequestLength == message.RequestLength)) { id.Enqueue(msg); } else { id.IsRequestingPiecesCount--; } } for (var i = 0; i < id.PieceReads.Count; i++) { if (id.PieceReads[i].PieceIndex == message.PieceIndex && id.PieceReads[i].StartOffset == message.StartOffset && id.PieceReads[i].RequestLength == message.RequestLength) { id.IsRequestingPiecesCount--; id.PieceReads.RemoveAt(i); break; } } }
internal void OnTick() { if (!_id.TorrentManager.Settings.EnablePeerExchange) { return; } var len = (_addedPeers.Count <= MaxPeers) ? _addedPeers.Count : MaxPeers; var added = new byte[len * 6]; var addedDotF = new byte[len]; for (var i = 0; i < len; i++) { _addedPeers[i].CompactPeer(added, i * 6); if ((_addedPeers[i].Encryption & (EncryptionTypes.RC4Full | EncryptionTypes.RC4Header)) != EncryptionTypes.None) { addedDotF[i] = 0x01; } else { addedDotF[i] = 0x00; } addedDotF[i] |= (byte)(_addedPeers[i].IsSeeder ? 0x02 : 0x00); } _addedPeers.RemoveRange(0, len); len = Math.Min(MaxPeers - len, _droppedPeers.Count); var dropped = new byte[len * 6]; for (var i = 0; i < len; i++) { _droppedPeers[i].CompactPeer(dropped, i * 6); } _droppedPeers.RemoveRange(0, len); _id.Enqueue(new PeerExchangeMessage(_id, added, addedDotF, dropped)); }
protected virtual void HandleRequestMessage(PeerId id, RequestMessage message) { // If we are not on the last piece and the user requested a stupidly big/small amount of data // we will close the connection if (_manager.Torrent.Pieces.Count != (message.PieceIndex + 1)) { if (message.RequestLength > RequestMessage.MaxSize || message.RequestLength < RequestMessage.MinSize) { throw new MessageException(string.Format("Illegal piece request received. Peer requested {0} byte", message.RequestLength)); } } var m = new PieceMessage(message.PieceIndex, message.StartOffset, message.RequestLength); // If we're not choking the peer, enqueue the message right away if (!id.AmChoking) { id.IsRequestingPiecesCount++; id.PieceReads.Add(m); id.TryProcessAsyncReads(); } // If the peer supports fast peer and the requested piece is one of the allowed pieces, enqueue it // otherwise send back a reject request message else if (id.SupportsFastPeer && ClientEngine.SupportsFastPeer) { if (id.AmAllowedFastPieces.Contains(message.PieceIndex)) { id.IsRequestingPiecesCount++; id.PieceReads.Add(m); id.TryProcessAsyncReads(); } else { id.Enqueue(new RejectRequestMessage(m)); } } }
/// <summary> /// Checks the send queue of the peer to see if there are any outstanding pieces which they requested /// and rejects them as necessary /// </summary> /// <param name="Peer"> </param> private void RejectPendingRequests(PeerId Peer) { var length = Peer.QueueLength; for (var i = 0; i < length; i++) { var message = Peer.Dequeue(); var pieceMessage = message as PieceMessage; if (pieceMessage == null) { Peer.Enqueue(message); continue; } // If the peer doesn't support fast peer, then we will never requeue the message if (!(Peer.SupportsFastPeer && ClientEngine.SupportsFastPeer)) { Peer.IsRequestingPiecesCount--; continue; } // If the peer supports fast peer, queue the message if it is an AllowedFast piece // Otherwise send a reject message for the piece if (Peer.AmAllowedFastPieces.Contains(pieceMessage.PieceIndex)) Peer.Enqueue(pieceMessage); else { Peer.IsRequestingPiecesCount--; Peer.Enqueue(new RejectRequestMessage(pieceMessage)); } } }
public virtual void Choke(PeerId id) { id.AmChoking = true; id.TorrentManager.UploadingTo--; id.Enqueue(new ChokeMessage()); }
public virtual void HandlePeerConnected(PeerId id, Direction direction) { var bundle = new MessageBundle(); AppendBitfieldMessage(id, bundle); AppendExtendedHandshake(id, bundle); AppendFastPieces(id, bundle); id.Enqueue(bundle); }
protected virtual void HandleCancelMessage(PeerId id, CancelMessage message) { for (var i = 0; i < id.QueueLength; i++) { var msg = id.Dequeue(); if (!(msg is PieceMessage)) { id.Enqueue(msg); continue; } var piece = msg as PieceMessage; if ( !(piece.PieceIndex == message.PieceIndex && piece.StartOffset == message.StartOffset && piece.RequestLength == message.RequestLength)) { id.Enqueue(msg); } else { id.IsRequestingPiecesCount--; } } for (var i = 0; i < id.PieceReads.Count; i++) { if (id.PieceReads[i].PieceIndex == message.PieceIndex && id.PieceReads[i].StartOffset == message.StartOffset && id.PieceReads[i].RequestLength == message.RequestLength) { id.IsRequestingPiecesCount--; id.PieceReads.RemoveAt(i); break; } } }
protected virtual void HandleLtMetadataMessage(PeerId id, LTMetadata message) { if (message.MetadataMessageType == LTMetadata.eMessageType.Request) { if (id.TorrentManager.HasMetadata) id.Enqueue(new LTMetadata(id, LTMetadata.eMessageType.Data, message.Piece, id.TorrentManager.Torrent.Metadata)); else id.Enqueue(new LTMetadata(id, LTMetadata.eMessageType.Reject, message.Piece)); } }
protected virtual void HandleRequestMessage(PeerId id, RequestMessage message) { // If we are not on the last piece and the user requested a stupidly big/small amount of data // we will close the connection if (_manager.Torrent.Pieces.Count != (message.PieceIndex + 1)) if (message.RequestLength > RequestMessage.MaxSize || message.RequestLength < RequestMessage.MinSize) throw new MessageException("Illegal piece request received. Peer requested " + message.RequestLength.ToString() + " byte"); var m = new PieceMessage(message.PieceIndex, message.StartOffset, message.RequestLength); // If we're not choking the peer, enqueue the message right away if (!id.AmChoking) { id.IsRequestingPiecesCount++; id.PieceReads.Add(m); id.TryProcessAsyncReads(); } // If the peer supports fast peer and the requested piece is one of the allowed pieces, enqueue it // otherwise send back a reject request message else if (id.SupportsFastPeer && ClientEngine.SupportsFastPeer) { if (id.AmAllowedFastPieces.Contains(message.PieceIndex)) { id.IsRequestingPiecesCount++; id.PieceReads.Add(m); id.TryProcessAsyncReads(); } else id.Enqueue(new RejectRequestMessage(m)); } }
protected virtual void SetAmInterestedStatus(PeerId id, bool interesting) { if (interesting && !id.AmInterested) { id.AmInterested = true; id.Enqueue(new InterestedMessage()); // He's interesting, so attempt to queue up any FastPieces (if that's possible) _manager.PieceManager.AddPieceRequests(id); } else if (!interesting && id.AmInterested) { id.AmInterested = false; id.Enqueue(new NotInterestedMessage()); } }
internal void AddPieceRequests(PeerId id) { PeerMessage msg = null; int maxRequests = id.MaxPendingRequests; if (id.AmRequestingPiecesCount >= maxRequests) return; int count = 1; if (id.Connection is HttpConnection) { // How many whole pieces fit into 2MB count = (2 * 1024 * 1024) / id.TorrentManager.Torrent.PieceLength; // Make sure we have at least one whole piece count = Math.Max(count, 1); count *= id.TorrentManager.Torrent.PieceLength / Piece.BlockSize; } if (!id.IsChoking || id.SupportsFastPeer) { while (id.AmRequestingPiecesCount < maxRequests) { msg = Picker.ContinueExistingRequest(id); if (msg != null) id.Enqueue(msg); else break; } } if (!id.IsChoking || (id.SupportsFastPeer && id.IsAllowedFastPieces.Count > 0)) { while (id.AmRequestingPiecesCount < maxRequests) { msg = Picker.PickPiece(id, id.TorrentManager.Peers.ConnectedPeers, count); if (msg != null) id.Enqueue(msg); else break; } } }
public virtual void Choke(PeerId id) { id.AmChoking = true; id.TorrentManager.UploadingTo--; id.Enqueue(new ChokeMessage()); }